-- ---------------------------------------------------------------------------- -- Localized Lua globals. -- ---------------------------------------------------------------------------- -- Libraries local table = _G.table -- ---------------------------------------------------------------------------- -- AddOn namespace. -- ---------------------------------------------------------------------------- local AddOnFolderName, private = ... local LibStub = _G.LibStub local TargetButtonManager = LibStub("AceEvent-3.0"):Embed({}) local EventMessage = private.EventMessage -- ---------------------------------------------------------------------------- -- Constants. -- ---------------------------------------------------------------------------- local ActiveTargetButtons = {} local QueuedData = {} local TargetButtonHeap = {} local ActiveTargetButtonByNPCID = {} local POINT_TRANSLATION = { CENTER = private.DEFAULT_OS_SPAWN_POINT, BOTTOM = "BOTTOMRIGHT", BOTTOMLEFT = "BOTTOMLEFT", BOTTOMRIGHT = "BOTTOMRIGHT", LEFT = "TOPLEFT", RIGHT = "TOPRIGHT", TOP = "TOPRIGHT", TOPLEFT = "TOPLEFT", TOPRIGHT = "TOPRIGHT", } local SIBLING_ANCHORS = { TOPRIGHT = "BOTTOMRIGHT", TOPLEFT = "BOTTOMLEFT", BOTTOMRIGHT = "TOPRIGHT", BOTTOMLEFT = "TOPLEFT", } local SIBLING_OFFSET_Y = { TOPRIGHT = -10, TOPLEFT = -10, BOTTOMRIGHT = 10, BOTTOMLEFT = 10, } -- ---------------------------------------------------------------------------- -- Helpers. -- ---------------------------------------------------------------------------- local function ResetTargetButtonPoints() for index = 1, #ActiveTargetButtons do local indexedButton = ActiveTargetButtons[index] indexedButton:ClearAllPoints() if index == 1 then indexedButton:SetPoint("CENTER", private.TargetButtonAnchor, "CENTER") else local spawnPoint = POINT_TRANSLATION[ActiveTargetButtons[1]:GetEffectiveSpawnPoint()] indexedButton:SetPoint(spawnPoint, ActiveTargetButtons[index - 1], SIBLING_ANCHORS[spawnPoint], 0, SIBLING_OFFSET_Y[spawnPoint]) end end end local function AcquireTargetButton(unitClassification) local heap = TargetButtonHeap[unitClassification] if not heap then heap = {} TargetButtonHeap[unitClassification] = heap end local targetButton = table.remove(heap) if not targetButton then targetButton = private.CreateTargetButton(unitClassification) end return targetButton end -- ---------------------------------------------------------------------------- -- TargetButtonManager methods. -- ---------------------------------------------------------------------------- function TargetButtonManager:DismissAll() for index = 1, #ActiveTargetButtons do ActiveTargetButtons[index].dismissAnimationGroup:Play() end end LibStub("HereBeDragons-2.0").RegisterCallback(TargetButtonManager, "PlayerZoneChanged", "DismissAll") function TargetButtonManager:ProcessQueue(eventName) if #ActiveTargetButtons < private.NUM_RAID_ICONS and not _G.InCombatLockdown() then local targetButtonData = table.remove(QueuedData, 1) if targetButtonData then self:Spawn(eventName, targetButtonData) end end end TargetButtonManager:RegisterEvent("PLAYER_REGEN_ENABLED", "ProcessQueue") function TargetButtonManager:Reclaim(eventName, targetButton) ActiveTargetButtonByNPCID[targetButton.npcID] = nil targetButton:Deactivate() table.insert(TargetButtonHeap[targetButton.__classification], targetButton) local removalIndex for index = 1, #ActiveTargetButtons do if ActiveTargetButtons[index] == targetButton then removalIndex = index break end end if removalIndex then table.remove(ActiveTargetButtons, removalIndex):ClearAllPoints() end ResetTargetButtonPoints() self:ProcessQueue("Reclaim") if #ActiveTargetButtons == 0 then _G.NPCScan_RecentTargetButton:ResetMacroText() end end TargetButtonManager:RegisterMessage(EventMessage.TargetButtonRequestDeactivate, "Reclaim") function TargetButtonManager:ReclaimByNPCID(eventName, npcID) for index = 1, #ActiveTargetButtons do local targetButton = ActiveTargetButtons[index] if targetButton.npcID == npcID then targetButton.dismissAnimationGroup:Play() end end end TargetButtonManager:RegisterMessage(EventMessage.DismissTargetButtonByID, "ReclaimByNPCID") function TargetButtonManager:RespawnAsClassification(eventName, targetButton, data) local targetButtonIndex for index = 1, #ActiveTargetButtons do if ActiveTargetButtons[index] == targetButton then targetButtonIndex = index break end end targetButton:Deactivate() table.insert(TargetButtonHeap[targetButton.__classification], targetButton) table.remove(ActiveTargetButtons, targetButtonIndex):ClearAllPoints() local newButton = AcquireTargetButton(data.unitClassification) table.insert(ActiveTargetButtons, targetButtonIndex, newButton) ResetTargetButtonPoints() newButton:Activate(data) newButton.needsUnitData = nil end TargetButtonManager:RegisterMessage(EventMessage.TargetButtonNeedsReclassified, "RespawnAsClassification") function TargetButtonManager:SetScale() for index = 1, #ActiveTargetButtons do ActiveTargetButtons[index]:SetScale(private.db.profile.targetButtonGroup.scale) end end TargetButtonManager:RegisterMessage(EventMessage.TargetButtonScaleChanged, "SetScale") function TargetButtonManager:Spawn(eventName, data) if (not private.db.profile.targetButtonGroup.isEnabled) or ActiveTargetButtonByNPCID[data.npcID] then return end if #ActiveTargetButtons >= private.NUM_RAID_ICONS or _G.InCombatLockdown() then data.sourceText = ("%s %s"):format(data.sourceText, _G.PARENS_TEMPLATE:format(_G.QUEUED_STATUS_QUEUED)) table.insert(QueuedData, data) return end local targetButton = AcquireTargetButton(data.unitClassification) if #ActiveTargetButtons == 0 then targetButton:SetPoint("CENTER", private.TargetButtonAnchor, "CENTER") else local spawnPoint = POINT_TRANSLATION[ActiveTargetButtons[1]:GetEffectiveSpawnPoint()] targetButton:SetPoint(spawnPoint, ActiveTargetButtons[#ActiveTargetButtons], SIBLING_ANCHORS[spawnPoint], 0, SIBLING_OFFSET_Y[spawnPoint]) end ActiveTargetButtons[#ActiveTargetButtons + 1] = targetButton ActiveTargetButtonByNPCID[data.npcID] = true data.isFromQueue = eventName == "Reclaim" targetButton:Activate(data) end TargetButtonManager:RegisterMessage(EventMessage.DetectedNPC, "Spawn")