Compare with Previous | Blame | View Log
-- TODO: Handle colors local RW = LibStub("AceAddon-3.0"):GetAddon("Raid Watch") local L = LibStub("AceLocale-3.0"):GetLocale("RW2-Plugin-Base") local Boss = RW.BossPrototype local timerProt = {} local mt = {__index = timerProt} local Party = RW.Party local Utils = RW.Utils local RoleBits = Utils.Constants.RoleBits -- If text is a number this warning is considered not a custom one -- If text is not a number then it is custom and it can be possibly sent as a table, -- then the first value in the table will be the actual text, and the second oen will be the option text as its show in the GUI -- 3rd value in the table will be the tooltip text local spell function Boss:_Timer(tType, time, text, icon, optionName, default, color, endMessage, displayText) if type(text) == "number" then spell = text return self:_Timer(tType, time, GetSpellInfo(text), icon or text, optionName or text, default, color, endMessage, displayText) end if type(icon) == "number" then spell = icon return self:_Timer(tType, time, text, select(3, GetSpellInfo(icon)), optionName or icon, default, color, endMessage, displayText) end optionName = type(optionName) == "number" and Utils.SpellName[optionName] or optionName -- 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) default = Utils:BuildRoleDefaults(default) local defaults = self:AddDefaults(optionName, "BAR", tType ~= "CUSTOM" and tType or text[2], default) defaults.color = color defaults.endMessage = endMessage defaults.Anchor = "Default" local base = self:GetBaseAlertObject(optionName) if not base then base = { icon = icon, id = optionName, spell = spell, displayText = displayText, mod = self, scheduled = {}, } tinsert(self.BaseAlertObjects, base) end local obj = setmetatable({ mainType = "BAR", type = tType, time = time, running = {}, text = type(text) == "table" and text[1] or text, optText = type(text) == "table" and text[2] or nil, base = base, }, mt) self.AlertObjects.BAR = self.AlertObjects.BAR or {} tinsert(self.AlertObjects.BAR, obj) spell = nil return obj end -------------------------------------- -- API function Boss:Timer(...) return self:_Timer("NORMAL", ...) end function Boss:CDTimer(...) return self:_Timer("CD", ...) end function Boss:DurTimer(...) return self:_Timer("DUR", ...) end function Boss:DurTargetTimer(...) return self:_Timer("DUR_TARGET", ...) end function Boss:DurTargetStackTimer(...) return self:_Timer("DUR_TARGET_STACK", ...) end function Boss:DurStackTimer(...) return self:_Timer("DUR_STACK", ...) end function Boss:BerserkTimer(time, text, icon, option, default, color, endMessage) local dispText = text and text or L.BERSKER_OPTION:format(Utils:TimeToStringShort(time)) return self:_Timer("BERSERK", time, text or 35595, icon, option, default, color, endMessage, dispText) end function Boss:AchievementTimer(time, achievementID, text, icon, default, ...) local IDNumber, Name, Points, Completed, Month, Day, Year, Description, Flags, Image, RewardText = GetAchievementInfo(achievementID) Name = Name:gsub("%(.*%)", "") return self:_Timer("NORMAL", time, text or Name, icon or Image, Name, default) end function Boss:CustomTimer(time, text, optText, ...) --@debug assert(type(text) == "string", self:GetName()..": CustomTimer, variable \"text\" is not of type text") assert(type(optText) == "string", self:GetName()..": CustomTimer, variable \"optText\" is not of type text") --@end-debug return self:_Timer("CUSTOM", time, {text, optText}, ...) end function Boss:CastTimer(time, ...) if time > 1000 then local castTime = select(7, GetSpellInfo(time)) local spellHaste = select(7, GetSpellInfo(53142)) / 10000 local spell = time time = castTime/spellHaste/1000 return self:CastTimer(time, spell, ...) end return self:_Timer("CAST", time, ...) end function Boss:StopAllTimers() if not self.AlertObjects.BAR then return end for i, timer in pairs(self.AlertObjects.BAR) do for j, runningID in pairs(timer.running) do RW.Callbacks:Fire("BarStop", runningID) timer.running[j] = nil end end end ------------------------------------ -- Interaction function Boss:BarFinished(event, id, text, icon) if not self.AlertObjects.BAR then return end for i, timer in pairs(self.AlertObjects.BAR) do for j, runningID in pairs(timer.running) do if runningID == id then if self.db.profile[timer.base.id].endMessage then local c = timer.mod.db.profile[timer.base.id].Colors[timer.customOptName or "BAR"..timer..base.id] if not c then c = {1, 1, 1, 1} end RW.Callbacks:Fire("MessageShow", text, c[1], c[2], c[3], c[4], icon) end timer.running[j] = nil end end end end function timerProt:SetIcon(icon) self.base.icon = icon end local function BuildID(bar, info) return bar.type..bar.base.id..bar.text..(info or "") end function timerProt:Start(time, info, ...) if not self.base.mod.DB[self.base.id].enabled then return end if not Utils:EvaluateRoleOption(self.base.mod.DB[self.base.id].BAR[self.optText or self.type].enabled) then return end if time and type(time) ~= "number" then return self:Start(nil, time, info, ...) end local text if self.optText then text = Utils:Format(self.text, info, ...) else text = Utils:Format(L["FORMAT_BAR_"..self.type], self.text, info, ...) end local c = self.base.mod.DB[self.base.id].BAR[self.optText or self.type].color local anchor = self.base.mod.DB[self.base.id].BAR[self.optText or self.type].Anchor RW.Callbacks:Fire("BarStart", BuildID(self, info), time or self.time, text, self.base.icon, c, anchor) tinsert(self.running, self.type..self.base.id..self.text..(info or "")) end function timerProt:Stop(extraID) if extraID then RW.Callbacks:Fire("BarStop", BuildID(self, extraID)) else for i, id in pairs(self.running) do RW.Callbacks:Fire("BarStop", id) end end end timerProt.Cancel = timerProt.Stop ----------------------------------- -- Scheduling local function startTimer(timer, ...) timer:Start(...) end function timerProt:Schedule(stime, time, info, ...) if time and type(time) ~= "number" then return self:Schedule(stime, nil, time, info, ...) end self.base.mod:Schedule("BAR"..BuildID(self, info), stime, startTimer, self, time, info, ...) tinsert(self.base.scheduled, "BAR"..BuildID(self, info)) end function timerProt:ScheduleRepeating(stime, now, time, info, ...) if time and type(time) ~= "number" then return self:ScheduleRepeating(stime, now, nil, time, info, ...) end self.base.mod:ScheduleRepeating("BAR"..BuildID(self, info), stime, startTimer, now, self, time, info, ...) tinsert(self.base.scheduled, "BAR"..BuildID(self, info)) end function timerProt:Unschedule(extraID) if not extraID then for i, scheduleID in pairs(self.base.scheduled) do self.base.mod:Unschedule(scheduleID) end wipe(self.base.scheduled) else self.base.mod:Unschedule("BAR"..BuildID(self, extraID)) Utils:TRemove(self.base.scheduled, "BAR"..BuildID(self, extraID)) end end ------------------------------------ -- Options function timerProt: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 BarsPlugin = RW:GetPlugin("Bars2") local Anchorlist if BarsPlugin then Anchorlist = BarsPlugin:GetAnchorList() end local subGroup = UIF:InlineGroup("") subGroup:SetLayout("flow") -- Workaround for old non-default values if type(boss.DB[self.base.id].BAR[self.optText or self.type].enabled) ~= "table" then boss.DB[self.base.id].BAR[self.optText or self.type].enabled = boss.defaults[self.base.id].BAR[self.optText or self.type].enabled end -- End workaroudn local enabledDrop = UIF:MultiSelectDropdown(L.ENABLED, boss.DB[self.base.id].BAR[self.optText or self.type].enabled, nil, Utils.Constants.EnableList, 0.5) local anchorDrop = UIF:Dropdown("Anchor", boss.DB[self.base.id].BAR[self.optText or self.type], "Anchor", nil, Anchorlist, 0.5) if self.type == "CUSTOM" then subGroup:SetTitle(self.optText) else subGroup:SetTitle(L["BAR_"..self.type]) end local color = UIF:ColorSelect(L.COLOR, boss.DB[self.base.id].BAR[self.optText or self.type], "color") color:SetRelativeWidth(0.5) local reset = UIF:Button(L.RESET, function() boss.DB[self.base.id].BAR[self.optText or self.type].color = boss.defaults[self.base.id].BAR[self.optText or self.type].color if type(boss.defaults[self.base.id].BAR[self.optText or self.type].enabled) == "table" then for i, v in pairs(boss.defaults[self.base.id].BAR[self.optText or self.type].enabled) do boss.DB[self.base.id].BAR[self.optText or self.type].enabled[i] = v enabledDrop:SetItemValue(i, v) end else boss.DB[self.base.id].BAR[self.optText or self.type].enabled = boss.defaults[self.base.id].BAR[self.optText or self.type].enabled end enabledDrop:SetValue(boss.DB[self.base.id].BAR[self.optText or self.type].enabled) anchorDrop:SetValue(boss.DB[self.base.id].BAR[self.optText or self.type].Anchor) local colorvalue = boss.DB[self.base.id].BAR[self.optText or self.type].color or nil if colorvalue then color:SetColor(unpack(colorvalue)) else color:SetColor("") end end) reset:SetRelativeWidth(0.33) subGroup:AddChild(enabledDrop) subGroup:AddChild(anchorDrop) subGroup:AddChild(color) subGroup:AddChild(reset) return subGroup end