Bastion aims to serve as a highly performant, simplisitic, and expandable World of Warcraft data visualization framework.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Bastion/src/MissileManager/MissileManager.lua

137 lines
4.0 KiB

---@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<string, {list: Bastion.List, cb:fun(missile: Tinkr.Missile): any}>
---@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()