local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local Map = ____lualib.Map local __TS__New = ____lualib.__TS__New local __TS__StringIncludes = ____lualib.__TS__StringIncludes local __TS__Iterator = ____lualib.__TS__Iterator local ____exports = {} local ____entity_radius = require("utils.entity_radius") local findAllByClassnameInRadius = ____entity_radius.findAllByClassnameInRadius ____exports.ItemDetector = __TS__Class() local ItemDetector = ____exports.ItemDetector ItemDetector.name = "ItemDetector" ItemDetector.____file_path = "scripts/vscripts/item_detector.lua" function ItemDetector.prototype.____constructor(self) self.lastKnownItems = __TS__New(Map) self.lastKnownItems = __TS__New(Map) self:InitializeItemDetection() ListenToGameEvent( "entity_killed", function(event) return self:OnItemPickup(event) end, nil ) end function ItemDetector.Initialize(self) if not ____exports.ItemDetector.instance then ____exports.ItemDetector.instance = __TS__New(____exports.ItemDetector) end end function ItemDetector.prototype.InitializeItemDetection(self) GameRules:GetGameModeEntity():SetThink( function() self:ScanForNearbyItems() return 0.25 end, "ScanForNearbyItemsThink", "0", nil ) end function ItemDetector.prototype.snapshotFromUpdate(self, u) return { distanceRounded = math.floor(u.distance + 0.5), cost = u.cost, currencyType = u.currencyType, rarity = u.rarity } end function ItemDetector.prototype.snapshotsEqual(self, a, b) return a.distanceRounded == b.distanceRounded and a.cost == b.cost and a.currencyType == b.currencyType and a.rarity == b.rarity end function ItemDetector.prototype.tryBuildNearbyUpdate(self, heroPos, itemEntity, detectionRadius) local containedItem = itemEntity:GetContainedItem() if containedItem == nil or containedItem == nil then return nil end local itemName = containedItem:GetAbilityName() local itemPos = itemEntity:GetAbsOrigin() local distance = (heroPos - itemPos):Length2D() if distance > detectionRadius then return nil end local itemCost = containedItem:GetCost() local currencyType local rarity if __TS__StringIncludes(itemName, "item_blackshop_") then local blackShop = require("blackshop").BlackShop:getInstance() local shopItem = blackShop:getItemInfo(itemName) if shopItem then itemCost = shopItem.cost currencyType = "crystal" repeat local ____switch15 = shopItem.quality local ____cond15 = ____switch15 == 0 if ____cond15 then rarity = "common" break end ____cond15 = ____cond15 or ____switch15 == 1 if ____cond15 then rarity = "rare" break end ____cond15 = ____cond15 or ____switch15 == 2 if ____cond15 then rarity = "epic" break end ____cond15 = ____cond15 or ____switch15 == 3 if ____cond15 then rarity = "legendary" break end ____cond15 = ____cond15 or ____switch15 == 4 if ____cond15 then rarity = "cursed" break end ____cond15 = ____cond15 or ____switch15 == 5 if ____cond15 then rarity = "heavenly" break end do rarity = "common" break end until true end else currencyType = "gold" end return { itemName = itemName, distance = distance, cost = itemCost, currencyType = currencyType, rarity = rarity } end function ItemDetector.prototype.ScanForNearbyItems(self) local heroes = HeroList:GetAllHeroes() local detectionRadius = 400 for ____, hero in ipairs(heroes) do do if not IsValidEntity(hero) or not hero:IsRealHero() then goto __continue18 end local heroPos = hero:GetAbsOrigin() local playerID = hero:GetPlayerOwnerID() if playerID == -1 then goto __continue18 end local player = PlayerResource:GetPlayer(playerID) if not player then goto __continue18 end local nearbyItems = findAllByClassnameInRadius("dota_item_drop", heroPos, detectionRadius) local currentMap = __TS__New(Map) for ____, item in ipairs(nearbyItems) do do if not IsValidEntity(item) then goto __continue22 end local itemEntity = item if not itemEntity then goto __continue22 end local update = self:tryBuildNearbyUpdate(heroPos, itemEntity, detectionRadius) if update then currentMap:set(update.itemName, update) end end ::__continue22:: end local lastMap = self.lastKnownItems:get(playerID) or __TS__New(Map) for ____, ____value in __TS__Iterator(lastMap) do local name = ____value[1] if not currentMap:has(name) then CustomGameEventManager:Send_ServerToPlayer(player, "nearby_item_remove", {itemName = name}) end end for ____, ____value in __TS__Iterator(currentMap) do local name = ____value[1] local update = ____value[2] local nextSnap = self:snapshotFromUpdate(update) local prev = lastMap:get(name) if prev == nil then CustomGameEventManager:Send_ServerToPlayer(player, "nearby_item_update", update) elseif not self:snapshotsEqual(prev, nextSnap) then CustomGameEventManager:Send_ServerToPlayer(player, "nearby_item_update", update) end end local nextKnown = __TS__New(Map) for ____, ____value in __TS__Iterator(currentMap) do local u = ____value[2] nextKnown:set( u.itemName, self:snapshotFromUpdate(u) ) end self.lastKnownItems:set(playerID, nextKnown) end ::__continue18:: end end function ItemDetector.prototype.OnItemPickup(self, event) local killedUnit = EntIndexToHScript(event.entindex_killed) if killedUnit and killedUnit:GetClassname() == "dota_item_drop" then local itemEntity = killedUnit local containedItem = itemEntity:GetContainedItem() if containedItem ~= nil and containedItem ~= nil then local itemName = containedItem:GetAbilityName() for ____, ____value in __TS__Iterator(self.lastKnownItems) do local playerID = ____value[1] local map = ____value[2] do if not map:has(itemName) then goto __continue40 end map:delete(itemName) local player = PlayerResource:GetPlayer(playerID) if player then CustomGameEventManager:Send_ServerToPlayer(player, "nearby_item_remove", {itemName = itemName}) end end ::__continue40:: end end end end function ItemDetector.getInstance(self) if not ____exports.ItemDetector.instance then ____exports.ItemDetector.instance = __TS__New(____exports.ItemDetector) end return ____exports.ItemDetector.instance end return ____exports