Compare with Previous | Blame | View Log
local RW = LibStub("AceAddon-3.0"):GetAddon("Raid Watch") local L = LibStub("AceLocale-3.0"):GetLocale("RW2-Plugin-Base") local Boss = RW.BossPrototype local iconProt = {} local mt = {__index = iconProt} local Party = RW.Party local Utils = RW.Utils function Boss:_Icon(defaultIcon, optionName, timeOut, ...) local icons = {} icons[1] = defaultIcon for i = 1, select("#", ...) do local ic = select(i, ...) icons[i + 1] = ic end local base = self:GetBaseAlertObject(optionName) if not base then base = { id = optionName, mod = self, scheduled = {}, } tinsert(self.BaseAlertObjects, base) end -- create a local metatable for insertion -- Ordering thoughts and how to keep it consistent -- table: orderedMarks (i-based index as listed in the call) -- table: usedMarks (name based, marks that have been used so far) -- integer: lastIndex calling next doesnt guarntee order, so we can use an index to traverse forward -- integer: maxIndex top end of the list -- table: oMarks table of original marks the targets had before we set a new icon -- table: base Base alert object -- timeOut: timerout for the mark to be removed -- mainType: ICON -- type: Key for the database -- -- Timer handles are handled by the Boss prototype local obj = setmetatable({ mainType = "ICON", type = defaultIcon, timeOut = timeOut, base = base, orderedMarks = icons, usedMarks = {}, oMarks = {}, lastIndex = 1, maxIndex = #icons, }, mt) self.AlertObjects.ICON = self.AlertObjects.ICON or {} tinsert(self.AlertObjects.ICON, obj) return obj end function Boss:Icon(defaultIcon, optionName, default, timeOut, ...) local spell local icon if type(optionName) == "number" then spell = optionName icon = select(3, GetSpellInfo(optionName)) optionName = Utils.SpellName[optionName] end -- If no option name is found by now we use the text as default if not optionName then optionName = type(text) == "table" and text[1] or text end self:AddToCategory(nil, optionName) local defaults = self:AddDefaults(optionName, "ICON", defaultIcon, default) local obj = self:_Icon(defaultIcon, optionName, timeOut, ...) obj.base.icon = icon obj.base.spell = obj.base.spell or spell self.icons = self.icons or {} tinsert(self.icons,obj) return obj end -- Reset the icon pointer local function resetIcons(self) self.lastIndex = 1 end -- Reset all icons, both reset the cache and put old marks back on people function Boss:ResetAllIcons() if self.icons then for i, icon in pairs(self.icons) do -- cleanup any left over icons still set form a wipe/etc.. for target, icn in pairs(icon.usedMarks) do SetRaidTarget(target,0) end -- turn back on any marks they previously had set for target, oldIcon in pairs(icon.oMarks) do SetRaidTarget(target, oldIcon) end wipe(icon.oMarks) resetIcons(icon) end end end -- Puts the old mark back on people or just hides it if they did not have one when they got marked -- Old mark will not be put back if it is used by someone else at that point local function hideIcon(self, target) local used = self.oMarks[target] if used then -- Do doesone else have that mark right now? local iconIndex = used for k,v in pairs(self.usedMarks) do if v == used and k ~= target then -- someone else using that mark right now? if so dont reset it iconIndex = 0 end end SetRaidTarget(target, iconIndex) else SetRaidTarget(target, 0) end self.usedMarks[target] = nil self.oMarks[target] = nil end function iconProt:Show(target, time, icon, ...) if not self.base.mod.DB[self.base.id].enabled then return end if not self.base.mod.DB[self.base.id].ICON[self.optText or self.type].enabled then return end if self.base.mod.Party.group[self.base.mod.pName] and self.base.mod.Party.group[self.base.mod.pName].rank < 1 and self.base.mod.Party:GetPartyType() == "raid" then return end local targetID = Boss:UIDFromRandom(target) if targetID and self.lastIndex <= self.maxIndex then self.oMarks[targetID] = GetRaidTargetIndex(targetID) or 0 local icn = self.orderedMarks[self.lastIndex] self.lastIndex = self.lastIndex + 1 if icn then local icon = Utils.Constants.RaidIconNameToNumber[icn] if GetRaidTargetIndex(targetID) ~= icon then SetRaidTarget(targetID, Utils.Constants.RaidIconNameToNumber[icn] or 0) self.usedMarks[targetID] = GetRaidTargetIndex(targetID) if time or self.timeOut then self.base.mod:Schedule("ICON"..self.base.id, time or self.timeOut, hideIcon, self, targetID) end end self.base.mod:Schedule(self.base.id.."ResetIcons", 2, resetIcons, self) else resetIcons(self) end end end iconProt.Start = iconProt.Show function iconProt:Hide(extraID) if not extraID then -- we got asked to hide all the marks for this icon object -- reset the old marks back for id, icon in pairs(self.oMarks) do SetRaidTarget(id, icon) self.usedMarks[id] = nil end wipe(self.oMarks) -- now remove any marks we have left on for id, icon in pairs(self.usedMarks) do SetRaidTarget(id,0) end wipe(self.usedMarks) resetIcons(self) return end local targetID = Boss:UIDFromRandom(extraID) -- if the person died, we wont find thier ID since they are dead. if targetID and UnitExists(targetID) and UnitIsConnected(targetID) then hideIcon(self,targetID) end -- We dont need repeat outselves, just ask it todo the same thing as when we run the hide schedule --for id, icon in pairs(self.oMarks) do -- if targetID == id then -- SetRaidTarget(id, icon) -- self.oMarks[id] = nil -- self.usedMarks[id] = nil -- break -- end --end end function iconProt:Schedule(stime, info, ...) self.base.mod:Schedule("ICON"..self.base.id..(info or ""), stime, showMessage, self, info, ...) tinsert(self.base.scheduled, "ICON"..self.base.id..(info or "")) end function iconProt:ScheduleRepeating(stime, now, info, ...) self.base.mod:ScheduleRepeating("ICON"..self.base.id..(info or ""), stime, showMessage, now, self, info, ...) tinsert(self.base.scheduled, "ICON"..self.base.id..(info or "")) end function iconProt:Unschedule(extraID) self.base.mod:Unschedule("ICON"..self.base.id..(extraID or "")) Utils:TRemove(self.base.scheduled, "ICON"..self.base.id..(extraID or "")) end -- Options function iconProt:GetOption() local Options = RW:GetPlugin("Options") local boss = self.base.mod local AceGUI = LibStub("AceGUI-3.0") local UIF = LibStub("LibGUIFactory-1.0"):GetFactory("RW") local subGroup = UIF:InlineGroup("") local check = UIF:CheckBox(L.ENABLED, boss.DB[self.base.id].ICON[self.optText or self.type], "enabled") local sg = AceGUI:Create("SimpleGroup") sg:SetFullWidth(true) sg:SetLayout("Flow") for index,icn in ipairs(self.orderedMarks) do local iconWidget = AceGUI:Create("Icon") iconWidget:SetImage("Interface\\TargetingFrame\\UI-RaidTargetingIcons.blp", unpack(Utils.Constants.IconCoords[icn])) iconWidget:SetImageSize(45, 45) iconWidget:SetHeight(50) iconWidget:SetRelativeWidth(0.24) iconWidget:SetLabel("") iconWidget:SetUserData("name",icn) sg:AddChild(iconWidget) end subGroup:AddChild(check) subGroup:AddChild(sg) return subGroup end