MaxDps.Spells = {}; MaxDps.Flags = {}; MaxDps.SpellsGlowing = {}; MaxDps.FramePool = {}; MaxDps.Frames = {}; --- Creates frame overlay over a specific frame, it doesn't need to be a button. -- @param parent - frame that is suppose to be attached to -- @param id - string id of overlay because frame can have multiple overlays -- @param texture - optional custom texture -- @param type - optional type of overlay, standard types are 'normal' and 'cooldown' - used to select overlay color -- @param color - optional custom color in standard structure {r = 1, g = 1, b = 1, a = 1} function MaxDps:CreateOverlay(parent, id, texture, type, color) local frame = tremove(self.FramePool); if not frame then frame = CreateFrame('Frame', 'MaxDps_Overlay_' .. id, parent); end local sizeMult = self.db.global.sizeMult or 1.4; frame:SetParent(parent); frame:SetFrameStrata('HIGH'); frame:SetPoint('CENTER', 0, 0); frame:SetWidth(parent:GetWidth() * sizeMult); frame:SetHeight(parent:GetHeight() * sizeMult); local t = frame.texture; if not t then t = frame:CreateTexture('GlowOverlay', 'OVERLAY'); t:SetTexture(texture or MaxDps:GetTexture()); t:SetBlendMode('ADD'); frame.texture = t; end t:SetAllPoints(frame); if type then frame.ovType = type; if type == 'normal' then local c = self.db.global.highlightColor; t:SetVertexColor(c.r, c.g, c.b, c.a); elseif type == 'cooldown' then local c = self.db.global.cooldownColor; t:SetVertexColor(c.r, c.g, c.b, c.a); else t:SetVertexColor(color.r, color.r, color.r, color.r); end else t:SetVertexColor(color.r, color.g, color.b, color.a); end tinsert(self.Frames, frame); return frame; end function MaxDps:DestroyAllOverlays() local frame; for key, frame in pairs(self.Frames) do frame:GetParent().MaxDpsOverlays = nil; frame:ClearAllPoints(); frame:Hide(); frame:SetParent(UIParent); frame.width = nil; frame.height = nil; end for key, frame in pairs(self.Frames) do tinsert(self.FramePool, frame); self.Frames[key] = nil; end end function MaxDps:ApplyOverlayChanges() for key, frame in pairs(self.Frames) do local sizeMult = self.db.global.sizeMult or 1.4; frame:SetWidth(frame:GetParent():GetWidth() * sizeMult); frame:SetHeight(frame:GetParent():GetHeight() * sizeMult); frame.texture:SetTexture(MaxDps:GetTexture()); frame.texture:SetAllPoints(frame); if frame.ovType == 'normal' then local c = self.db.global.highlightColor; frame.texture:SetVertexColor(c.r, c.g, c.b, c.a); elseif frame.ovType == 'cooldown' then local c = self.db.global.cooldownColor; frame.texture:SetVertexColor(c.r, c.g, c.b, c.a); end end end function MaxDps:UpdateButtonGlow() local LAB; local LBG; local origShow; local noFunction = function() end; if IsAddOnLoaded('ElvUI') then LAB = LibStub:GetLibrary('LibActionButton-1.0-ElvUI'); LBG = LibStub:GetLibrary('LibButtonGlow-1.0'); origShow = LBG.ShowOverlayGlow; elseif IsAddOnLoaded('Bartender4') then LAB = LibStub:GetLibrary('LibActionButton-1.0'); end if self.db.global.disableButtonGlow then ActionBarActionEventsFrame:UnregisterEvent('SPELL_ACTIVATION_OVERLAY_GLOW_SHOW'); if LAB then LAB.eventFrame:UnregisterEvent('SPELL_ACTIVATION_OVERLAY_GLOW_SHOW'); end if LBG then LBG.ShowOverlayGlow = noFunction; end else ActionBarActionEventsFrame:RegisterEvent('SPELL_ACTIVATION_OVERLAY_GLOW_SHOW'); if LAB then LAB.eventFrame:RegisterEvent('SPELL_ACTIVATION_OVERLAY_GLOW_SHOW'); end if LBG then LBG.ShowOverlayGlow = origShow; end end end function MaxDps:Glow(button, id, texture, type, color) if button.MaxDpsOverlays and button.MaxDpsOverlays[id] then button.MaxDpsOverlays[id]:Show(); else if not button.MaxDpsOverlays then button.MaxDpsOverlays = {}; end button.MaxDpsOverlays[id] = self:CreateOverlay(button, id, texture, type, color); button.MaxDpsOverlays[id]:Show(); end end function MaxDps:HideGlow(button, id) if button.MaxDpsOverlays and button.MaxDpsOverlays[id] then button.MaxDpsOverlays[id]:Hide(); end end function MaxDps:AddButton(actionName, button) if actionName then if self.Spells[actionName] == nil then self.Spells[actionName] = {}; end tinsert(self.Spells[actionName], button); end end function MaxDps:AddStandardButton(button) local type = button:GetAttribute('type'); if type then local actionType = button:GetAttribute(type); local id; local actionName; if type == 'action' then local slot = button:GetAttribute('action') or ActionButton_GetPagedID(button) or ActionButton_CalculateAction(button) or 0; if HasAction(slot) then type, actionType = GetActionInfo(slot); else return; end end if type == 'macro' then local name, rank, spellId = GetMacroSpell(actionType); if spellId then actionName = GetSpellInfo(spellId); else return; end elseif type == 'item' then actionName = GetItemInfo(actionType); elseif type == 'spell' then actionName = GetSpellInfo(actionType); end self:AddButton(actionName, button) end end function MaxDps:Fetch() self = MaxDps; if self.rotationEnabled then self:DisableRotationTimer(); end self.Spell = nil; self:GlowClear(); self.Spells = {}; self.Flags = {}; self.SpellsGlowing = {}; self:FetchLibActionButton(); self:FetchBlizzard(); -- It does not alter original button frames so it needs to be fetched too if IsAddOnLoaded('ButtonForge') then self:FetchButtonForge(); end if IsAddOnLoaded('G15Buttons') then self:FetchG15Buttons(); end if IsAddOnLoaded('SyncUI') then self:FetchSyncUI(); end if IsAddOnLoaded('LUI') then self:FetchLUI(); end if IsAddOnLoaded('Dominos') then self:FetchDominos(); end if self.rotationEnabled then self:EnableRotationTimer(); self:InvokeNextSpell(); end end function MaxDps:FetchDominos() -- Dominos is using half of the blizzard frames so we just fetch the missing one for i = 1, 60 do local button = _G['DominosActionButton' .. i]; if button then self:AddStandardButton(button); end end end function MaxDps:FetchLUI() local luiBars = { 'LUIBarBottom1', 'LUIBarBottom2', 'LUIBarBottom3', 'LUIBarBottom4', 'LUIBarBottom5', 'LUIBarBottom6', 'LUIBarRight1', 'LUIBarRight2', 'LUIBarLeft1', 'LUIBarLeft2' }; for _, bar in pairs(luiBars) do for i = 1, 12 do local button = _G[bar .. 'Button' .. i]; if button then self:AddStandardButton(button); end end end end function MaxDps:FetchSyncUI() local syncbars = {}; syncbars[1] = SyncUI_ActionBar; syncbars[2] = SyncUI_MultiBar; syncbars[3] = SyncUI_SideBar.Bar1; syncbars[4] = SyncUI_SideBar.Bar2; syncbars[5] = SyncUI_SideBar.Bar3; syncbars[6] = SyncUI_PetBar; for _, bar in pairs(syncbars) do for i = 1, 12 do local button = bar['Button' .. i]; if button then self:AddStandardButton(button); end end end end function MaxDps:FetchLibActionButton() local LAB = { original = LibStub:GetLibrary('LibActionButton-1.0', true), elvui = LibStub:GetLibrary('LibActionButton-1.0-ElvUI', true), } for _, lib in pairs(LAB) do if lib and lib.GetAllButtons then for button in pairs(lib:GetAllButtons()) do local spellId = button:GetSpellId(); if spellId then local actionName, _ = GetSpellInfo(spellId); self:AddButton(actionName, button); end end end end end function MaxDps:FetchBlizzard() local BlizzardBars = {'Action', 'MultiBarBottomLeft', 'MultiBarBottomRight', 'MultiBarRight', 'MultiBarLeft'}; for _, barName in pairs(BlizzardBars) do for i = 1, 12 do local button = _G[barName .. 'Button' .. i]; self:AddStandardButton(button); end end end function MaxDps:FetchG15Buttons() local i = 2; -- it starts from 2 while true do local button = _G['objG15_btn_' .. i]; if not button then break; end i = i + 1; self:AddStandardButton(button); end end function MaxDps:FetchButtonForge() local i = 1; while true do local button = _G['ButtonForge' .. i]; if not button then break; end i = i + 1; MaxDps:AddStandardButton(button) end end function MaxDps:Dump() local s = ''; for k, v in pairs(self.Spells) do print(k); end end function MaxDps:FindSpell(spellName) local name = GetSpellInfo(spellName) or spellName; return self.Spells[name]; end function MaxDps:GlowIndependent(spellName, id, texture, color) local name = GetSpellInfo(spellName) or spellName; if self.Spells[name] ~= nil then for k, button in pairs(self.Spells[name]) do self:Glow(button, id, texture, 'cooldown', color); end end end function MaxDps:ClearGlowIndependent(spellName, id) local name = GetSpellInfo(spellName) or spellName; if self.Spells[name] ~= nil then for k, button in pairs(self.Spells[name]) do self:HideGlow(button, id); end end end function MaxDps:GlowCooldown(spell, condition) if self.Flags[spell] == nil then self.Flags[spell] = false; end if condition and not self.Flags[spell] then self.Flags[spell] = true; self:GlowIndependent(spell, spell); end if not condition and self.Flags[spell] then self.Flags[spell] = false; self:ClearGlowIndependent(spell, spell); end end function MaxDps:GlowSpell(spellName) if self.Spells[spellName] ~= nil then for k, button in pairs(self.Spells[spellName]) do self:Glow(button, 'next', nil, 'normal'); end self.SpellsGlowing[spellName] = 1; else self:Print(self.Colors.Error .. 'Spell not found on action bars: ' .. spellName); end end function MaxDps:GlowSpellId(spellId) local name = GetSpellInfo(spellId); self:GlowSpell(name); end function MaxDps:GlowNextSpell(spellName) self:GlowClear(); self:GlowSpell(spellName); end function MaxDps:GlowNextSpellId(spellId) local spellName = GetSpellInfo(spellId); self:GlowClear(); self:GlowSpell(spellName); end function MaxDps:GlowClear() for spellName, v in pairs(self.SpellsGlowing) do if v == 1 then for k, button in pairs(self.Spells[spellName]) do self:HideGlow(button, 'next'); end self.SpellsGlowing[spellName] = 0; end end end