---@type Tinkr local Tinkr, ---@class Bastion Bastion = ... ---@class Bastion.MissileManager.TrackingParams ---@field source? Bastion.Unit ---@field target? Bastion.Unit ---@field spellId? number ---@field spellVisualId? number ---@field callback fun(self: Bastion.Missile) ---@class Bastion.MissileManager ---@field _lists table ---@field trackingParams Bastion.MissileManager.TrackingParams[] ---@field missiles Tinkr.Missile[] local MissileManager = {} MissileManager.__index = MissileManager function MissileManager:New() ---@class Bastion.MissileManager local self = setmetatable({}, MissileManager) self.missiles = {} self._lists = {} self.trackedMissiles = Bastion.List:New() self.allMissiles = Bastion.List:New() self.trackingParams = {} return self end -- Register a custom list with a callback ---@param name string ---@param cb fun(missile: Tinkr.Missile): boolean | any ---@return Bastion.List | false function MissileManager:RegisterList(name, cb) if self._lists[name] then return false end self._lists[name] = { list = Bastion.List:New(), cb = cb, } return self._lists[name].list end -- reset custom lists ---@return nil function MissileManager:ResetLists() for _, list in pairs(self._lists) do list.list:clear() end end function MissileManager:Reset() self.missiles = {} self.trackedMissiles:clear() self.allMissiles:clear() self:ResetLists() end -- Refresh custom lists ---@param missile Tinkr.Missile ---@return nil function MissileManager:EnumLists(missile) for _, list in pairs(self._lists) do local r = list.cb(missile) if r then list.list:push(r) end end end ---@param params Bastion.MissileManager.TrackingParams function MissileManager:TrackMissile(params) table.insert(self.trackingParams, params) end ---@param missileObj Bastion.Missile function MissileManager:EnumTrackingParams(missileObj) local tracked = false for i, trackingParam in ipairs(self.trackingParams) do if (not trackingParam.source or missileObj:GetSourceUnit():IsUnit(trackingParam.source)) and (not trackingParam.target or missileObj:GetTargetUnit():IsUnit(trackingParam.target)) and (not trackingParam.spellId or missileObj.spellId == trackingParam.spellId) and (not trackingParam.spellVisualId or missileObj.spellVisualId == trackingParam.spellVisualId) then tracked = true trackingParam.callback(missileObj) end end return tracked end -- Get a list ---@param name string ---@return Bastion.List function MissileManager:GetList(name) return self._lists[name].list end function MissileManager:Refresh() self:Reset() local missiles = Missiles() if type(missiles) == "table" then for _, missile in ipairs(missiles) do table.insert(self.missiles, missile) self:EnumLists(missile) local missileObj = Bastion.Missile:New(missile) self.allMissiles:push(missileObj) if self:EnumTrackingParams(missileObj) then self.trackedMissiles:push(missileObj) end end end end ---@param params { source?: Bastion.Unit, target?: Bastion.Unit, spellId?: number, spellVisualId?: number } function MissileManager:GetMissiles(params) ---@type Bastion.Missile[] local missiles = {} for _, missile in ipairs(self.trackedMissiles) do if (not params.source or missile:GetSourceUnit():IsUnit(params.source)) and (not params.target or missile:GetTargetUnit():IsUnit(params.target)) and (not params.spellId or missile.spellId == params.spellId) and (not params.spellVisualId or missile.spellVisualId == params.spellVisualId) then table.insert(missiles, missile) end end return missiles end Bastion.MissileManager = MissileManager:New()