From 4c239cd599f220287b01017ee302ea3f14b6f055 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 13:33:43 +0200 Subject: [PATCH 001/268] configurable DR duration --- Lang.lua | 2 ++ Modules/Diminishings.lua | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Lang.lua b/Lang.lua index 473b243..45e8808 100644 --- a/Lang.lua +++ b/Lang.lua @@ -406,6 +406,8 @@ elseif GetLocale() == "deDE" then L["Categories"] = "Kategorien" L["Force Icon"] = "Erzwinge Symbol" L["Icon of the DR"] = "Symbol des DR" + L["DR Duration"] = "DR Dauer" + L["Change the DR Duration in seconds (DR is dynamic between 15-20s)"] = "Verändere die DR Dauer in Sekunden (DR ist dynamisch zwischen 15-20s)" -- ExportImport.lua L["Export Import"] = "Exportieren Importieren" diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 9c3b00b..db48ad6 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -1,8 +1,6 @@ local select = select local pairs,ipairs,tbl_sort,tinsert,format = pairs,ipairs,table.sort,tinsert,format -local drDuration = 18 - local GetSpellInfo = GetSpellInfo local CreateFrame = CreateFrame local GetTime = GetTime @@ -47,7 +45,8 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { drQuarterColor = {r = 1, g = 0.7, b = 0, a = 1 }, drNullColor = {r = 1, g = 0, b = 0, a = 1 }, drWidthFactor = 1, - drCategories = defaultCategories() + drCategories = defaultCategories(), + drDuration = 18 }) local function getDiminishColor(dr) @@ -296,14 +295,14 @@ function Diminishings:AuraFade(unit, spellID) end end lastIcon.dr = drCat - lastIcon.timeLeft = drDuration + lastIcon.timeLeft = Gladdy.db.drDuration lastIcon.diminishing = DRData:NextDR(lastIcon.diminishing) if Gladdy.db.drBorderColorsEnabled then lastIcon.border:SetVertexColor(getDiminishColor(lastIcon.diminishing)) else lastIcon.border:SetVertexColor(Gladdy.db.drBorderColor.r, Gladdy.db.drBorderColor.g, Gladdy.db.drBorderColor.b, Gladdy.db.drBorderColor.a) end - lastIcon.cooldown:SetCooldown(GetTime(), drDuration) + lastIcon.cooldown:SetCooldown(GetTime(), Gladdy.db.drDuration) if Gladdy.db.drCategories[drCat].forceIcon then lastIcon.texture:SetTexture(Gladdy.db.drCategories[drCat].icon) else @@ -359,11 +358,20 @@ function Diminishings:GetOptions() desc = L["Enabled DR module"], order = 3, }), + drDuration = Gladdy:option({ + type = "range", + name = L["DR Duration"], + desc = L["Change the DR Duration in seconds (DR is dynamic between 15-20s)"], + order = 4, + min = 15, + max = 20, + step = .1, + }), group = { type = "group", childGroups = "tree", name = L["Frame"], - order = 4, + order = 5, args = { icon = { type = "group", -- 2.39.5 From b73bc33630ca8e50f4cfb27ac1dc9e395220a594 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 13:34:10 +0200 Subject: [PATCH 002/268] scale in 0.01 percent steps --- Options.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Options.lua b/Options.lua index 8fd249c..b2da325 100644 --- a/Options.lua +++ b/Options.lua @@ -270,7 +270,7 @@ function Gladdy:SetupOptions() order = 4, min = .1, max = 2, - step = .1, + step = .01, }, padding = { type = "range", -- 2.39.5 From 79371b72b075c7fc6af8ce0879d487941aeb2c1b Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 14:05:37 +0200 Subject: [PATCH 003/268] fix shadowsight timer showing when not in arena or testmode --- Modules/ShadowsightTimer.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/ShadowsightTimer.lua b/Modules/ShadowsightTimer.lua index 097d238..1785e4e 100644 --- a/Modules/ShadowsightTimer.lua +++ b/Modules/ShadowsightTimer.lua @@ -101,7 +101,9 @@ function ShadowsightTimer:UpdateFrameOnce() self.timerFrame:SetScale(Gladdy.db.shadowsightTimerScale) self.timerFrame:ClearAllPoints() self.timerFrame:SetPoint(Gladdy.db.shadowsightTimerRelPoint1, nil, Gladdy.db.shadowsightTimerRelPoint2, Gladdy.db.shadowsightTimerX, Gladdy.db.shadowsightTimerY) - self.timerFrame:Show() + if Gladdy.frame.testing or Gladdy.curBracket then + self.timerFrame:Show() + end else self.timerFrame:SetScale(Gladdy.db.shadowsightTimerScale) self.timerFrame:ClearAllPoints() -- 2.39.5 From d53f89c6d42b46f41fc827a78775f21be3f75ef8 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 14:06:15 +0200 Subject: [PATCH 004/268] hide blizzard arena pets as well --- Frame.lua | 11 +++++++++++ Gladdy.lua | 46 +++++++++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/Frame.lua b/Frame.lua index e4a9fd0..5ed139a 100644 --- a/Frame.lua +++ b/Frame.lua @@ -275,6 +275,17 @@ function Gladdy:UpdateFrame() for _, v in self:IterModules() do self:Call(v, "UpdateFrameOnce") end + if Gladdy.db.hideBlizzard == "always" then + Gladdy:BlizzArenaSetAlpha(0) + elseif Gladdy.db.hideBlizzard == "arena" then + if Gladdy.curBracket then + Gladdy:BlizzArenaSetAlpha(0) + else + Gladdy:BlizzArenaSetAlpha(1) + end + elseif Gladdy.db.hideBlizzard == "never" then + Gladdy:BlizzArenaSetAlpha(1) + end end function Gladdy:HideFrame() diff --git a/Gladdy.lua b/Gladdy.lua index 252c270..32b0e1f 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -229,13 +229,7 @@ function Gladdy:OnInitialize() end self:DeleteUnknownOptions(self.db, self.defaults.profile) if Gladdy.db.hideBlizzard == "always" then - if IsAddOnLoaded("Blizzard_ArenaUI") then - ArenaEnemyFrame1:SetAlpha(0) - ArenaEnemyFrame2:SetAlpha(0) - ArenaEnemyFrame3:SetAlpha(0) - ArenaEnemyFrame4:SetAlpha(0) - ArenaEnemyFrame5:SetAlpha(0) - end + Gladdy:BlizzArenaSetAlpha(0) end end @@ -391,13 +385,7 @@ function Gladdy:Reset() self:ResetUnit(unit) end if Gladdy.db.hideBlizzard == "never" or Gladdy.db.hideBlizzard == "arena" then - if IsAddOnLoaded("Blizzard_ArenaUI") then - ArenaEnemyFrame1:SetAlpha(1) - ArenaEnemyFrame2:SetAlpha(1) - ArenaEnemyFrame3:SetAlpha(1) - ArenaEnemyFrame4:SetAlpha(1) - ArenaEnemyFrame5:SetAlpha(1) - end + Gladdy:BlizzArenaSetAlpha(1) end end @@ -462,12 +450,28 @@ function Gladdy:JoinedArena() self.buttons["arena" .. i]:SetAlpha(1) end if Gladdy.db.hideBlizzard == "arena" or Gladdy.db.hideBlizzard == "always" then - if IsAddOnLoaded("Blizzard_ArenaUI") then - ArenaEnemyFrame1:SetAlpha(0) - ArenaEnemyFrame2:SetAlpha(0) - ArenaEnemyFrame3:SetAlpha(0) - ArenaEnemyFrame4:SetAlpha(0) - ArenaEnemyFrame5:SetAlpha(0) - end + Gladdy:BlizzArenaSetAlpha(0) end end + +--------------------------- + +-- BLIZZARD FRAMES + +--------------------------- + +function Gladdy:BlizzArenaSetAlpha(alpha) + if IsAddOnLoaded("Blizzard_ArenaUI") then + ArenaEnemyFrames:SetAlpha(alpha) + ArenaEnemyFrame1:SetAlpha(alpha) + ArenaEnemyFrame1PetFrame:SetAlpha(alpha) + ArenaEnemyFrame2:SetAlpha(alpha) + ArenaEnemyFrame2PetFrame:SetAlpha(alpha) + ArenaEnemyFrame3:SetAlpha(alpha) + ArenaEnemyFrame3PetFrame:SetAlpha(alpha) + ArenaEnemyFrame4:SetAlpha(alpha) + ArenaEnemyFrame4PetFrame:SetAlpha(alpha) + ArenaEnemyFrame5:SetAlpha(alpha) + ArenaEnemyFrame5PetFrame:SetAlpha(alpha) + end +end \ No newline at end of file -- 2.39.5 From 0d5b5644a9a7f3366ca00a3f058e9e0eb72a924f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 14:19:13 +0200 Subject: [PATCH 005/268] testmode DR only with enabled DRs --- Modules/Diminishings.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index db48ad6..0541109 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -257,17 +257,17 @@ end function Diminishings:Test(unit) if Gladdy.db.drEnabled then - local spells = { 33786, 118, 8643, 8983 } - for i = 1, 4 do - if i == 1 then - self:AuraFade(unit, spells[i]) - elseif i == 2 then - self:AuraFade(unit, spells[i]) - self:AuraFade(unit, spells[i]) - else - self:AuraFade(unit, spells[i]) - self:AuraFade(unit, spells[i]) - self:AuraFade(unit, spells[i]) + local limit = {} + for spellID,category in pairs(DRData:GetSpells()) do + if Gladdy.db.drCategories[category].enabled then + if not limit[category] then + limit[category] = { count = 1, limit = math.random(1,3) } + else + limit[category].count = limit[category].count + 1 + end + if limit[category].count <= limit[category].limit then + self:AuraFade(unit, spellID) + end end end end -- 2.39.5 From 74753e327c8dc62ff7585fcf2f4b0530ea90c4e3 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 15:13:19 +0200 Subject: [PATCH 006/268] testmode random Auras + Interrupts only with enabled Auras + Interrupts --- EventListener.lua | 6 +-- Modules/Auras.lua | 79 +++++++++++++++++++++++++++++----------- Modules/Diminishings.lua | 4 +- 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 2f73d8d..8734d44 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -167,7 +167,7 @@ function EventListener:ARENA_OPPONENT_UPDATE(unit, updateReason) end end -local exceptionNames = { -- TODO MOVE ME TO CLASSBUFFS LIB +Gladdy.exceptionNames = { -- TODO MOVE ME TO CLASSBUFFS LIB [31117] = GetSpellInfo(30405) .. " Silence", -- Unstable Affliction Silence [43523] = GetSpellInfo(30405) .. " Silence", [24131] = select(1, GetSpellInfo(19386)) .. " Dot", -- Wyvern Sting Dot @@ -207,8 +207,8 @@ function EventListener:UNIT_AURA(unit) Gladdy:DetectSpec(unit, Gladdy.specBuffs[spellName]) end end - if exceptionNames[spellID] then - spellName = exceptionNames[spellID] + if Gladdy.exceptionNames[spellID] then + spellName = Gladdy.exceptionNames[spellID] end Gladdy:SendMessage("AURA_GAIN", unit, auraType, spellID, spellName, texture, duration, expirationTime, count, debuffType, i) Gladdy:Call("Announcements", "CheckDrink", unit, spellName) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 50e65cc..5813418 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -1,4 +1,4 @@ -local pairs, ipairs, select, tinsert, tbl_sort, tostring = pairs, ipairs, select, tinsert, table.sort, tostring +local pairs, ipairs, select, tinsert, tbl_sort, tostring, tonumber, rand = pairs, ipairs, select, tinsert, table.sort, tostring, tonumber, math.random local GetSpellInfo = GetSpellInfo local CreateFrame, GetTime = CreateFrame, GetTime @@ -266,28 +266,63 @@ function Auras:ResetUnit(unit) end function Auras:Test(unit) - local spellName, _, icon + local spellName, spellid, icon, limit, i - if (unit == "arena1") then - spellName, _, icon = GetSpellInfo(7922) - self:AURA_FADE(unit, AURA_TYPE_BUFF) - self:AURA_FADE(unit, AURA_TYPE_DEBUFF) - self:AURA_GAIN(unit,AURA_TYPE_DEBUFF, 7922, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) - self:SPELL_INTERRUPT(unit,19244, select(1, GetSpellInfo(19244)), "physical", 25396, select(1, GetSpellInfo(25396)), 64) - elseif (unit == "arena2") then - spellName = select(1, GetSpellInfo(27010)) .. " " .. select(1, GetSpellInfo(16689)) - _, _, icon = GetSpellInfo(27010) - self:AURA_FADE(unit, AURA_TYPE_BUFF) - self:AURA_FADE(unit,AURA_TYPE_DEBUFF) - self:AURA_GAIN(unit,AURA_TYPE_DEBUFF, 27010, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) - self:SPELL_INTERRUPT(unit,19244, select(1, GetSpellInfo(19244)), "physical", 25396, select(1, GetSpellInfo(25396)), 64) - elseif (unit == "arena3") then - spellName, _, icon = GetSpellInfo(34709) - self:AURA_FADE(unit, AURA_TYPE_BUFF) - self:AURA_GAIN(unit,AURA_TYPE_BUFF, 34709, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) - spellName, _, icon = GetSpellInfo(18425) - --self:AURA_FADE(unit, AURA_TYPE_DEBUFF) - --self:AURA_GAIN(unit,AURA_TYPE_DEBUFF, 18425, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) + self:AURA_FADE(unit, AURA_TYPE_BUFF) + self:AURA_FADE(unit, AURA_TYPE_DEBUFF) + + --Auras + local enabledAuras = 0 + for _,value in pairs(Gladdy.db.auraListDefault) do + if value.enabled then + enabledAuras = enabledAuras + 1 + end + end + if enabledAuras > 0 then + limit, i = rand(1, enabledAuras), 1 + for spellIdStr,value in pairs(Gladdy.db.auraListDefault) do + if i > limit then break end + if value.enabled then + spellid = tonumber(spellIdStr) + spellName = select(1, GetSpellInfo(tonumber(spellIdStr))) + icon = select(3, GetSpellInfo(tonumber(spellIdStr))) + if Gladdy.exceptionNames[spellid] then + spellName = Gladdy.exceptionNames[spellid] + end + self:AURA_GAIN(unit,value.track, spellid, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) + i = i + 1 + end + end + end + + --Interrupts + local spellSchools = {} + for k,_ in pairs(Gladdy:GetSpellSchoolColors()) do + tinsert(spellSchools, k) + end + enabledAuras = 0 + for _, value in pairs(Gladdy.db.auraListInterrupts) do + if value.enabled then + enabledAuras = enabledAuras + 1 + end + end + if enabledAuras > 0 then + limit, i = rand(1, enabledAuras), 1 + local extraSpellSchool + for spellIdStr, value in pairs(Gladdy.db.auraListInterrupts) do + if i > limit then break end + if value.enabled then + enabledAuras = enabledAuras + 1 + end + spellid = tonumber(spellIdStr) + if (unit == "arena1" or unit == "arena2") then + extraSpellSchool = spellSchools[rand(1, #spellSchools)] + spellName = select(1, GetSpellInfo(spellid)) + Gladdy:Print(spellName, extraSpellSchool) + self:SPELL_INTERRUPT(unit,spellid, spellName, "physical", spellid, spellName, extraSpellSchool) + end + i = i + 1 + end end end diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 0541109..915f138 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -1,5 +1,5 @@ local select = select -local pairs,ipairs,tbl_sort,tinsert,format = pairs,ipairs,table.sort,tinsert,format +local pairs,ipairs,tbl_sort,tinsert,format,rand = pairs,ipairs,table.sort,tinsert,format,math.random local GetSpellInfo = GetSpellInfo local CreateFrame = CreateFrame @@ -261,7 +261,7 @@ function Diminishings:Test(unit) for spellID,category in pairs(DRData:GetSpells()) do if Gladdy.db.drCategories[category].enabled then if not limit[category] then - limit[category] = { count = 1, limit = math.random(1,3) } + limit[category] = { count = 1, limit = rand(1,3) } else limit[category].count = limit[category].count + 1 end -- 2.39.5 From 720e5b63ec6162c273dcb3e6b677eebf8b1e4563 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 15:53:13 +0200 Subject: [PATCH 007/268] totemplates fix option to alter all colors/alphas --- Modules/TotemPlates.lua | 87 ++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 45 deletions(-) diff --git a/Modules/TotemPlates.lua b/Modules/TotemPlates.lua index 189a28f..77a8f3e 100644 --- a/Modules/TotemPlates.lua +++ b/Modules/TotemPlates.lua @@ -3,7 +3,7 @@ local UnitExists, UnitIsUnit, UnitName, UnitIsEnemy = UnitExists, UnitIsUnit, Un local C_NamePlate = C_NamePlate local Gladdy = LibStub("Gladdy") local L = Gladdy.L -local GetSpellInfo, CreateFrame, GetCVar = GetSpellInfo, CreateFrame, GetCVar +local GetSpellInfo, CreateFrame = GetSpellInfo, CreateFrame --------------------------------------------------- @@ -117,8 +117,8 @@ local function GetTotemColorDefaultOptions() desc = "Enable " .. format("|T%s:20|t %s", indexedList[i].texture, select(1, GetSpellInfo(indexedList[i].id))), type = "toggle", width = "full", - get = function(info) return Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].enabled end, - set = function(info, value) + get = function() return Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].enabled end, + set = function(_, value) Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].enabled = value Gladdy:UpdateFrame() end @@ -130,15 +130,13 @@ local function GetTotemColorDefaultOptions() order = 3, hasAlpha = true, width = "full", - get = function(info) - local key = info.arg or info[#info] + get = function() return Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].color.r, Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].color.g, Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].color.b, Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].color.a end, - set = function(info, r, g, b, a) - local key = info.arg or info[#info] + set = function(_, r, g, b, a) Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].color.r, Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].color.g, Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].color.b, @@ -154,10 +152,10 @@ local function GetTotemColorDefaultOptions() max = 1, step = 0.1, width = "full", - get = function(info) + get = function() return Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].alpha end, - set = function(info, value) + set = function(_, value) Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id].alpha = value Gladdy:UpdateFrame() end @@ -167,8 +165,8 @@ local function GetTotemColorDefaultOptions() name = L["Custom totem name"], order = 5, width = "full", - get = function(info) return Gladdy.db.npTotemColors["totem" .. indexedList[i].id].customText end, - set = function(info, value) Gladdy.db.npTotemColors["totem" .. indexedList[i].id].customText = value Gladdy:UpdateFrame() end + get = function() return Gladdy.db.npTotemColors["totem" .. indexedList[i].id].customText end, + set = function(_, value) Gladdy.db.npTotemColors["totem" .. indexedList[i].id].customText = value Gladdy:UpdateFrame() end }, } } @@ -176,15 +174,6 @@ local function GetTotemColorDefaultOptions() return defaultDB, options, indexedList end -local function GetTotemOptions() - local indexedList = select(3, GetTotemColorDefaultOptions()) - local colorList = {} - for i=1, #indexedList do - tinsert(colorList, Gladdy.dbi.profile.npTotemColors["totem" .. indexedList[i].id]) - end - return colorList -end - function Gladdy:GetTotemColors() return GetTotemColorDefaultOptions() end @@ -394,11 +383,11 @@ function TotemPlates:ToggleAddon(nameplate, show) local addonFrames = { self:GetAddonFrame(nameplate) } if addonFrames and #addonFrames > 0 then if show then - for i,v in ipairs(addonFrames) do + for _,v in ipairs(addonFrames) do v:Show() end else - for i,v in ipairs(addonFrames) do + for _,v in ipairs(addonFrames) do v:Hide() end end @@ -665,19 +654,23 @@ function TotemPlates:GetOptions() step = 0.1, width = "full", order = 23, - get = function(info) - local alphas = GetTotemOptions() - for i=2, #alphas do - if alphas[i].alpha ~= alphas[1].alpha then - return "" + get = function() + local alpha, i = nil, 1 + for _,v in pairs(Gladdy.dbi.profile.npTotemColors) do + if i == 1 then + alpha = v.alpha + i = i + 1 + else + if v.alpha ~= alpha then + return "" + end end end - return alphas[1].alpha + return alpha end, - set = function(info, value) - local alphas = GetTotemOptions() - for i=1, #alphas do - alphas[i].alpha = value + set = function(_, value) + for _,v in pairs(Gladdy.dbi.profile.npTotemColors) do + v.alpha = value end Gladdy:UpdateFrame() end, @@ -705,23 +698,27 @@ function TotemPlates:GetOptions() name = L["All totem border color"], order = 42, hasAlpha = true, - get = function(info) - local colors = GetTotemOptions() - local color = colors[1].color - for i=2, #colors do - if colors[i].r ~= color.r or colors[i].color.r ~= color.r or colors[i].color.r ~= color.r or colors[i].color.r ~= color.r then - return 0, 0, 0, 0 + get = function() + local color + local i = 1 + for _,v in pairs(Gladdy.dbi.profile.npTotemColors) do + if i == 1 then + color = v.color + i = i + 1 + else + if v.color.r ~= color.r or v.color.g ~= color.g or v.color.b ~= color.b or v.color.a ~= color.a then + return 0, 0, 0, 0 + end end end return color.r, color.g, color.b, color.a end, - set = function(info, r, g, b, a) - local colors = GetTotemOptions() - for i=1, #colors do - colors[i].color.r = r - colors[i].color.g = g - colors[i].color.b = b - colors[i].color.a = a + set = function(_, r, g, b, a) + for _,v in pairs(Gladdy.dbi.profile.npTotemColors) do + v.color.r = r + v.color.g = g + v.color.b = b + v.color.a = a end Gladdy:UpdateFrame() end, -- 2.39.5 From 51cd2b73111fb800b41ab7986a40b84d94aef6d9 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 15:53:34 +0200 Subject: [PATCH 008/268] clean up --- Gladdy.lua | 22 +++++++------- Modules/ArenaCountDown.lua | 1 - Modules/Auras.lua | 50 ++++++++++++++++---------------- Modules/Classicon.lua | 4 +-- Modules/Clicks.lua | 4 +-- Modules/Cooldowns.lua | 56 +++++++++++++++++------------------- Modules/Diminishings.lua | 18 ++++++------ Modules/Healthbar.lua | 2 -- Modules/Pets.lua | 4 +-- Modules/Racial.lua | 5 +--- Modules/ShadowsightTimer.lua | 2 +- Modules/Trinket.lua | 2 +- Modules/VersionCheck.lua | 4 +-- 13 files changed, 83 insertions(+), 91 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 32b0e1f..1957227 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -131,8 +131,8 @@ function Gladdy:Call(module, func, ...) end end function Gladdy:SendMessage(message, ...) - for k, v in self:IterModules() do - self:Call(v, v.messages[message], ...) + for _, module in self:IterModules() do + self:Call(module, module.messages[message], ...) end end @@ -224,8 +224,8 @@ function Gladdy:OnInitialize() self:SetupOptions() - for k, v in self:IterModules() do - self:Call(v, "Initialize") -- B.E > A.E :D + for _, module in self:IterModules() do + self:Call(module, "Initialize") -- B.E > A.E :D end self:DeleteUnknownOptions(self.db, self.defaults.profile) if Gladdy.db.hideBlizzard == "always" then @@ -304,8 +304,8 @@ function Gladdy:Test() button[k] = v end - for k, v in self:IterModules() do - self:Call(v, "Test", unit) + for _, module in self:IterModules() do + self:Call(module, "Test", unit) end button:SetAlpha(1) @@ -369,7 +369,7 @@ end function Gladdy:Reset() if type(self.guids) == "table" then - for k, v in pairs(self.guids) do + for k,_ in pairs(self.guids) do self.guids[k] = nil end end @@ -377,8 +377,8 @@ function Gladdy:Reset() self.curBracket = nil self.curUnit = 1 - for k1, v1 in self:IterModules() do - self:Call(v1, "Reset") + for _, module in self:IterModules() do + self:Call(module, "Reset") end for unit in pairs(self.buttons) do @@ -398,8 +398,8 @@ function Gladdy:ResetUnit(unit) button:SetAlpha(0) self:ResetButton(unit) - for k2, v2 in self:IterModules() do - self:Call(v2, "ResetUnit", unit) + for _, module in self:IterModules() do + self:Call(module, "ResetUnit", unit) end end diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index 8a38b5e..ca404d1 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -1,6 +1,5 @@ local floor, str_len, tostring, str_sub, str_find, pairs = math.floor, string.len, tostring, string.sub, string.find, pairs local CreateFrame = CreateFrame -local GetLocale = GetLocale local GetTime = GetTime local Gladdy = LibStub("Gladdy") diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 5813418..3f88fd6 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -8,7 +8,7 @@ local Gladdy = LibStub("Gladdy") local L = Gladdy.L local function defaultSpells(auraType) local spells = {} - for k,v in pairs(Gladdy:GetImportantAuras()) do + for _,v in pairs(Gladdy:GetImportantAuras()) do if not auraType or auraType == v.track then spells[tostring(v.spellID)] = {} spells[tostring(v.spellID)].enabled = true @@ -20,7 +20,7 @@ local function defaultSpells(auraType) end local function defaultInterrupts() local spells = {} - for k,v in pairs(Gladdy:GetInterrupts()) do + for _,v in pairs(Gladdy:GetInterrupts()) do spells[tostring(v.spellID)] = {} spells[tostring(v.spellID)].enabled = true spells[tostring(v.spellID)].priority = v.priority @@ -327,10 +327,10 @@ function Auras:Test(unit) end function Auras:JOINED_ARENA() - for i=1, Gladdy.curBracket do - --self.frames["arena" .. i]:RegisterUnitEvent("UNIT_AURA", "arena" .. i) - --self.frames["arena" .. i]:SetScript("OnEvent", Auras.OnEvent) - end + --[[for i=1, Gladdy.curBracket do + self.frames["arena" .. i]:RegisterUnitEvent("UNIT_AURA", "arena" .. i) + self.frames["arena" .. i]:SetScript("OnEvent", Auras.OnEvent) + end--]] end function Auras:AURA_GAIN(unit, auraType, spellID, spellName, icon, duration, expirationTime, count, debuffType) @@ -498,7 +498,7 @@ function Auras:GetOptions() order = i + 13, hasAlpha = true, width = "0.8", - set = function(info, r, g, b, a) + set = function(_, r, g, b, a) Gladdy.db.auraInterruptColors[v.key].r = r Gladdy.db.auraInterruptColors[v.key].g = g Gladdy.db.auraInterruptColors[v.key].b = b @@ -626,8 +626,8 @@ function Auras:GetAuraOptions(auraType) width = "0.7", name = L["Check All"], type = "execute", - func = function(info) - for k,v in pairs(defaultSpells(auraType)) do + func = function() + for k,_ in pairs(defaultSpells(auraType)) do Gladdy.db.auraListDefault[k].enabled = true end end, @@ -637,15 +637,15 @@ function Auras:GetAuraOptions(auraType) width = "0.7", name = L["Uncheck All"], type = "execute", - func = function(info) - for k,v in pairs(defaultSpells(auraType)) do + func = function() + for k,_ in pairs(defaultSpells(auraType)) do Gladdy.db.auraListDefault[k].enabled = false end end, }, } local auras = {} - for k,v in pairs(Gladdy:GetImportantAuras()) do + for _,v in pairs(Gladdy:GetImportantAuras()) do if v.track == auraType then tinsert(auras, v.spellID) end @@ -670,10 +670,10 @@ function Auras:GetAuraOptions(auraType) type = "toggle", image = Gladdy:GetImportantAuras()[GetSpellInfo(k)] and Gladdy:GetImportantAuras()[GetSpellInfo(k)].texture or select(3, GetSpellInfo(k)), width = "2", - set = function(info, value) + set = function(_, value) Gladdy.db.auraListDefault[tostring(k)].enabled = value end, - get = function(info) + get = function() return Gladdy.db.auraListDefault[tostring(k)].enabled end }, @@ -685,10 +685,10 @@ function Auras:GetAuraOptions(auraType) max = 50, width = "2", step = 1, - get = function(info) + get = function() return Gladdy.db.auraListDefault[tostring(k)].priority end, - set = function(info, value) + set = function(_, value) Gladdy.db.auraListDefault[tostring(k)].priority = value end, width = "full", @@ -706,8 +706,8 @@ function Auras:GetInterruptOptions() width = "0.7", name = L["Check All"], type = "execute", - func = function(info) - for k,v in pairs(defaultInterrupts()) do + func = function() + for k,_ in pairs(defaultInterrupts()) do Gladdy.db.auraListInterrupts[k].enabled = true end end, @@ -717,15 +717,15 @@ function Auras:GetInterruptOptions() width = "0.7", name = L["Uncheck All"], type = "execute", - func = function(info) - for k,v in pairs(defaultInterrupts()) do + func = function() + for k,_ in pairs(defaultInterrupts()) do Gladdy.db.auraListInterrupts[k].enabled = false end end, }, } local auras = {} - for k,v in pairs(Gladdy:GetInterrupts()) do + for _,v in pairs(Gladdy:GetInterrupts()) do tinsert(auras, v.spellID) end tbl_sort(auras, function(a, b) return GetSpellInfo(a) < GetSpellInfo(b) end) @@ -745,10 +745,10 @@ function Auras:GetInterruptOptions() type = "toggle", image = Gladdy:GetInterrupts()[GetSpellInfo(k)] and Gladdy:GetInterrupts()[GetSpellInfo(k)].texture or select(3, GetSpellInfo(k)), width = "2", - set = function(info, value) + set = function(_, value) Gladdy.db.auraListInterrupts[tostring(k)].enabled = value end, - get = function(info) + get = function() return Gladdy.db.auraListInterrupts[tostring(k)].enabled end }, @@ -760,10 +760,10 @@ function Auras:GetInterruptOptions() max = 50, width = "2", step = 1, - get = function(info) + get = function() return Gladdy.db.auraListInterrupts[tostring(k)].priority end, - set = function(info, value) + set = function(_, value) Gladdy.db.auraListInterrupts[tostring(k)].priority = value end, width = "full", diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index 7f44842..839b52f 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -178,8 +178,8 @@ function Classicon:GetOptions() name = L["Show Spec Icon"], desc = L["Shows Spec Icon once spec is detected"], order = 3, - get = function(info) return Gladdy.db.classIconSpecIcon end, - set = function(info, value) + get = function() return Gladdy.db.classIconSpecIcon end, + set = function(_, value) Gladdy.db.classIconSpecIcon = value if Gladdy.curBracket and Gladdy.curBracket > 0 then for i=1,Gladdy.curBracket do diff --git a/Modules/Clicks.lua b/Modules/Clicks.lua index ae9b9a3..2e20924 100644 --- a/Modules/Clicks.lua +++ b/Modules/Clicks.lua @@ -70,7 +70,7 @@ function Clicks:UpdateFrame(unit) end function Clicks:UpdateFrameOnce() - for k, v in pairs(Gladdy.buttons) do + for _, v in pairs(Gladdy.buttons) do local left = GetBindingKey(("GLADDYBUTTON%d_LEFT"):format(v.id)) local right = GetBindingKey(("GLADDYBUTTON%d_RIGHT"):format(v.id)) local middle = GetBindingKey(("GLADDYBUTTON%d_MIDDLE"):format(v.id)) @@ -107,7 +107,7 @@ function Clicks:SetupAttributes(unit) return end - for k, v in pairs(Gladdy.db.attributes) do + for _, v in pairs(Gladdy.db.attributes) do self:SetupAttribute(button, v.button, v.modifier, v.action, v.spell) end end diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index aa6b984..181c029 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -36,9 +36,9 @@ local L = Gladdy.L local function getDefaultCooldown() local cooldowns = {} - for class, t in pairs(Gladdy:GetCooldownList()) do - for spellId, v in pairs(t) do - local spellName, _, texture = GetSpellInfo(spellId) + for _,spellTable in pairs(Gladdy:GetCooldownList()) do + for spellId,_ in pairs(spellTable) do + local spellName = GetSpellInfo(spellId) if spellName then cooldowns[tostring(spellId)] = true else @@ -72,14 +72,14 @@ local Cooldowns = Gladdy:NewModule("Cooldowns", nil, { function Cooldowns:Initialize() self.cooldownSpellIds = {} self.spellTextures = {} - for class, t in pairs(Gladdy:GetCooldownList()) do - for k, v in pairs(t) do - local spellName, _, texture = GetSpellInfo(k) + for _,spellTable in pairs(Gladdy:GetCooldownList()) do + for spellId,_ in pairs(spellTable) do + local spellName, _, texture = GetSpellInfo(spellId) if spellName then - self.cooldownSpellIds[spellName] = k - self.spellTextures[k] = texture + self.cooldownSpellIds[spellName] = spellId + self.spellTextures[spellId] = texture else - Gladdy:Print("spellid does not exist " .. k) + Gladdy:Print("spellid does not exist " .. spellId) end end end @@ -261,13 +261,12 @@ function Cooldowns:UpdateTestCooldowns(unit) button.test = true -- use class spells - for k, v in pairs(Gladdy:GetCooldownList()[button.class]) do - --k is spellId - self:CooldownUsed(unit, button.class, k, nil) + for spellId,_ in pairs(Gladdy:GetCooldownList()[button.class]) do + self:CooldownUsed(unit, button.class, spellId) end -- use race spells - for k, v in pairs(Gladdy:GetCooldownList()[button.race]) do - self:CooldownUsed(unit, button.race, k, nil) + for spellId,_ in pairs(Gladdy:GetCooldownList()[button.race]) do + self:CooldownUsed(unit, button.race, spellId) end end end @@ -353,7 +352,6 @@ function Cooldowns:DetectSpec(unit, spec) ]] if (Gladdy.db.cooldown) then local class = Gladdy.buttons[unit].class - local race = Gladdy.buttons[unit].race for k, v in pairs(Gladdy:GetCooldownList()[class]) do if Gladdy.db.cooldownCooldowns[tostring(k)] then --if (self.db.cooldownList[k] ~= false and self.db.cooldownList[class] ~= false) then @@ -484,7 +482,7 @@ function Cooldowns:UpdateCooldowns(button) end end -function Cooldowns:CooldownUsed(unit, unitClass, spellId, spellName) +function Cooldowns:CooldownUsed(unit, unitClass, spellId) local button = Gladdy.buttons[unit] if not button then return @@ -502,8 +500,8 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId, spellName) -- check if we need to reset other cooldowns because of this spell if (cooldown.resetCD ~= nil) then - for k, v in pairs(cooldown.resetCD) do - self:CooldownReady(button, k, false) + for spellID,_ in pairs(cooldown.resetCD) do + self:CooldownReady(button, spellID, false) end end @@ -519,9 +517,9 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId, spellName) if (cooldown.sharedCD ~= nil) then local sharedCD = cooldown.sharedCD.cd and cooldown.sharedCD.cd or cd - for k, v in pairs(cooldown.sharedCD) do - if (k ~= "cd") then - self:CooldownStart(button, k, sharedCD) + for spellID,_ in pairs(cooldown.sharedCD) do + if (spellID ~= "cd") then + self:CooldownStart(button, spellID, sharedCD) end end end @@ -816,10 +814,10 @@ function Cooldowns:GetCooldownOptions() order = o, width = "full", image = select(3, GetSpellInfo(spellId)), - get = function(info) + get = function() return Gladdy.db.cooldownCooldowns[tostring(spellId)] end, - set = function(info, value) + set = function(_, value) Gladdy.db.cooldownCooldowns[tostring(spellId)] = value Gladdy:UpdateFrame() end @@ -845,10 +843,10 @@ function Cooldowns:GetCooldownOptions() order = o, width = "full", image = select(3, GetSpellInfo(spellId)), - get = function(info) + get = function() return Gladdy.db.cooldownCooldowns[tostring(spellId)] end, - set = function(info, value) + set = function(_, value) Gladdy.db.cooldownCooldowns[tostring(spellId)] = value Gladdy:UpdateFrame() end @@ -870,13 +868,13 @@ function Gladdy:UpdateTestCooldowns(i) Cooldowns:DetectSpec(unit, button.testSpec) -- use class spells - for k, v in pairs(Gladdy:GetCooldownList()[button.class]) do + for spellID,_ in pairs(Gladdy:GetCooldownList()[button.class]) do --k is spellId - Cooldowns:CooldownUsed(unit, button.class, k, nil) + Cooldowns:CooldownUsed(unit, button.class, spellID) end -- use race spells - for k, v in pairs(Gladdy:GetCooldownList()[button.race]) do - Cooldowns:CooldownUsed(unit, button.race, k, nil) + for spellID,_ in pairs(Gladdy:GetCooldownList()[button.race]) do + Cooldowns:CooldownUsed(unit, button.race, spellID) end end end \ No newline at end of file diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 915f138..7cb8903 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -15,7 +15,7 @@ local function defaultCategories() tinsert(indexList, {spellID = k, category = v}) end tbl_sort(indexList, function(a, b) return a.spellID < b.spellID end) - for i,v in ipairs(indexList) do + for _,v in ipairs(indexList) do if not categories[v.category] then categories[v.category] = { enabled = true, @@ -596,11 +596,11 @@ end function Diminishings:CategoryOptions() local categories = {} local indexList = {} - for k,v in pairs(DRData:GetCategories()) do + for k,_ in pairs(DRData:GetCategories()) do tinsert(indexList, k) end tbl_sort(indexList) - for i, k in ipairs(indexList) do + for i,k in ipairs(indexList) do categories[k] = { type = "group", name = DRData:GetCategoryName(k), @@ -611,10 +611,10 @@ function Diminishings:CategoryOptions() type = "toggle", name = L["Enabled"], order = 1, - get = function(info) + get = function() return Gladdy.db.drCategories[k].enabled end, - set = function(info, value) + set = function(_, value) Gladdy.db.drCategories[k].enabled = value end, }, @@ -622,10 +622,10 @@ function Diminishings:CategoryOptions() type = "toggle", name = L["Force Icon"], order = 2, - get = function(info) + get = function() return Gladdy.db.drCategories[k].forceIcon end, - set = function(info, value) + set = function(_, value) Gladdy.db.drCategories[k].forceIcon = value end, }, @@ -635,10 +635,10 @@ function Diminishings:CategoryOptions() desc = L["Icon of the DR"], order = 4, values = Diminishings:GetDRIcons(k), - get = function(info) + get = function() return Gladdy.db.drCategories[k].icon end, - set = function(info, value) + set = function(_, value) Gladdy.db.drCategories[k].icon = value Gladdy.options.args.Diminishings.args.categories.args[k].icon = value end, diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index a9d9d96..870bee4 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -167,8 +167,6 @@ function Healthbar:UpdateFrame(unit) return end - local iconSize = Gladdy.db.healthBarHeight + Gladdy.db.powerBarHeight - healthBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.healthBarTexture)) healthBar.bg:SetVertexColor(Gladdy.db.healthBarBgColor.r, Gladdy.db.healthBarBgColor.g, Gladdy.db.healthBarBgColor.b, Gladdy.db.healthBarBgColor.a) diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 7ab729f..3994492 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -35,12 +35,12 @@ function Pets:Initialize() end function Pets:JOINED_ARENA() - for k,v in pairs(self.frames) do + for _,v in pairs(self.frames) do v.healthBar:SetAlpha(0) end if Gladdy.db.petEnabled then self:RegisterEvent("UNIT_PET") - self:SetScript("OnEvent", function(self, event, unitId) + self:SetScript("OnEvent", function(_, event, unitId) if event == "UNIT_PET" then local unit = Gladdy.guids[UnitGUID(unitId)] if unit then diff --git a/Modules/Racial.lua b/Modules/Racial.lua index cf988c6..acfcaa1 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -1,10 +1,8 @@ -local ceil, floor, string_format, tonumber = ceil, floor, string.format, tonumber +local ceil = ceil local CreateFrame = CreateFrame local GetTime = GetTime - - local Gladdy = LibStub("Gladdy") local L = Gladdy.L local Racial = Gladdy:NewModule("Racial", nil, { @@ -123,7 +121,6 @@ function Racial:UpdateFrame(unit) racial.texture.overlay:SetVertexColor(Gladdy.db.racialBorderColor.r, Gladdy.db.racialBorderColor.g, Gladdy.db.racialBorderColor.b, Gladdy.db.racialBorderColor.a) racial:ClearAllPoints() - local margin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding local parent = Gladdy.buttons[unit][Gladdy.db.racialAnchor] if (Gladdy.db.racialPos == "RIGHT") then racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, Gladdy.db.padding + Gladdy.db.racialXOffset, Gladdy.db.racialYOffset) diff --git a/Modules/ShadowsightTimer.lua b/Modules/ShadowsightTimer.lua index 1785e4e..1a3d542 100644 --- a/Modules/ShadowsightTimer.lua +++ b/Modules/ShadowsightTimer.lua @@ -1,4 +1,4 @@ -local floor, str_len, tostring, str_sub, str_find, pairs = math.floor, string.len, tostring, string.sub, string.find, pairs +local floor, str_find, pairs = math.floor, string.find, pairs local CreateFrame = CreateFrame local Gladdy = LibStub("Gladdy") diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 2b4bd2d..28e24c1 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -1,4 +1,4 @@ -local ceil, floor, string_format, tonumber = ceil, floor, string.format, tonumber +local ceil = ceil local C_PvP = C_PvP local CreateFrame = CreateFrame diff --git a/Modules/VersionCheck.lua b/Modules/VersionCheck.lua index 45bd3da..9bbe922 100644 --- a/Modules/VersionCheck.lua +++ b/Modules/VersionCheck.lua @@ -1,11 +1,11 @@ -local str_match, tonumber, tostring = string.match, tonumber, tostring +local tonumber, tostring = tonumber, tostring local UnitName = UnitName local IsInGroup, IsInRaid = IsInGroup, IsInRaid local LE_PARTY_CATEGORY_HOME, LE_PARTY_CATEGORY_INSTANCE = LE_PARTY_CATEGORY_HOME, LE_PARTY_CATEGORY_INSTANCE local Gladdy = LibStub("Gladdy") -local L = Gladdy.L + local VersionCheck = Gladdy:NewModule("VersionCheck", 1, { }) LibStub("AceComm-3.0"):Embed(VersionCheck) -- 2.39.5 From 8a175928420e4ddfd6188e66a20d13dbc2a29ef6 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 17:11:54 +0200 Subject: [PATCH 009/268] optimize and randomize DR and Aura test mode --- Modules/Auras.lua | 77 ++++++++++++++++++++-------------------- Modules/Diminishings.lua | 38 ++++++++++++++------ 2 files changed, 66 insertions(+), 49 deletions(-) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 3f88fd6..a41c275 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -272,56 +272,57 @@ function Auras:Test(unit) self:AURA_FADE(unit, AURA_TYPE_DEBUFF) --Auras - local enabledAuras = 0 - for _,value in pairs(Gladdy.db.auraListDefault) do + local enabledDebuffs, enabledBuffs, testauras = {}, {} + for spellIdStr,value in pairs(Gladdy.db.auraListDefault) do if value.enabled then - enabledAuras = enabledAuras + 1 + if value.track == AURA_TYPE_BUFF then + tinsert(enabledBuffs, {value = value, spellIdStr = spellIdStr}) + else + tinsert(enabledDebuffs, {value = value, spellIdStr = spellIdStr}) + end end end - if enabledAuras > 0 then - limit, i = rand(1, enabledAuras), 1 - for spellIdStr,value in pairs(Gladdy.db.auraListDefault) do - if i > limit then break end - if value.enabled then - spellid = tonumber(spellIdStr) - spellName = select(1, GetSpellInfo(tonumber(spellIdStr))) - icon = select(3, GetSpellInfo(tonumber(spellIdStr))) - if Gladdy.exceptionNames[spellid] then - spellName = Gladdy.exceptionNames[spellid] - end - self:AURA_GAIN(unit,value.track, spellid, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) - i = i + 1 + if unit == "arena2" then + testauras = enabledBuffs + else + testauras = enabledDebuffs + end + + if #testauras > 0 then + limit = rand(1, #testauras) + local v = testauras[rand(1, #testauras)] + spellid = tonumber(v.spellIdStr) + spellName = select(1, GetSpellInfo(tonumber(v.spellIdStr))) + icon = select(3, GetSpellInfo(tonumber(v.spellIdStr))) + if Gladdy.exceptionNames[spellid] then + spellName = Gladdy.exceptionNames[spellid] + end + if (unit == "arena2") then + if (v.value.track == AURA_TYPE_BUFF) then + self:AURA_GAIN(unit,v.value.track, spellid, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) end + else + self:AURA_GAIN(unit,v.value.track, spellid, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) end end --Interrupts - local spellSchools = {} - for k,_ in pairs(Gladdy:GetSpellSchoolColors()) do - tinsert(spellSchools, k) - end - enabledAuras = 0 - for _, value in pairs(Gladdy.db.auraListInterrupts) do - if value.enabled then - enabledAuras = enabledAuras + 1 + if (unit == "arena1" or unit == "arena3") then + local enabledInterrupts = {} + local spellSchools = {} + for k,_ in pairs(Gladdy:GetSpellSchoolColors()) do + tinsert(spellSchools, k) end - end - if enabledAuras > 0 then - limit, i = rand(1, enabledAuras), 1 - local extraSpellSchool for spellIdStr, value in pairs(Gladdy.db.auraListInterrupts) do - if i > limit then break end if value.enabled then - enabledAuras = enabledAuras + 1 + tinsert(enabledInterrupts, spellIdStr) end - spellid = tonumber(spellIdStr) - if (unit == "arena1" or unit == "arena2") then - extraSpellSchool = spellSchools[rand(1, #spellSchools)] - spellName = select(1, GetSpellInfo(spellid)) - Gladdy:Print(spellName, extraSpellSchool) - self:SPELL_INTERRUPT(unit,spellid, spellName, "physical", spellid, spellName, extraSpellSchool) - end - i = i + 1 + end + if #enabledInterrupts > 0 then + local extraSpellSchool = spellSchools[rand(1, #spellSchools)] + spellid = tonumber(enabledInterrupts[rand(1, #enabledInterrupts)]) + spellName = select(1, GetSpellInfo(spellid)) + self:SPELL_INTERRUPT(unit,spellid, spellName, "physical", spellid, spellName, extraSpellSchool) end end end diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 7cb8903..4f24a19 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -257,17 +257,32 @@ end function Diminishings:Test(unit) if Gladdy.db.drEnabled then - local limit = {} - for spellID,category in pairs(DRData:GetSpells()) do - if Gladdy.db.drCategories[category].enabled then - if not limit[category] then - limit[category] = { count = 1, limit = rand(1,3) } - else - limit[category].count = limit[category].count + 1 - end - if limit[category].count <= limit[category].limit then - self:AuraFade(unit, spellID) - end + local enabledCategories = {} + for cat,val in pairs(Gladdy.db.drCategories) do + if (val.enabled) then + tinsert(enabledCategories, {cat = cat , spellIDs = {}}) + enabledCategories[cat] = #enabledCategories + end + end + for spellId,cat in pairs(DRData:GetSpells()) do + if enabledCategories[cat] then + tinsert(enabledCategories[enabledCategories[cat]].spellIDs, spellId) + end + end + + --shuffle + for i = #enabledCategories, 2, -1 do + local j = rand(i) + enabledCategories[i], enabledCategories[j] = enabledCategories[j], enabledCategories[i] + end + + --execute test + local index, amount = 0,0 + for i=1, (#enabledCategories < 4 and #enabledCategories) or 4 do + amount = rand(1,3) + index = rand(1, #enabledCategories[i].spellIDs) + for _=1, amount do + self:AuraFade(unit, enabledCategories[i].spellIDs[index]) end end end @@ -294,6 +309,7 @@ function Diminishings:AuraFade(unit, spellID) lastIcon.diminishing = 1.0 end end + if not lastIcon then return end lastIcon.dr = drCat lastIcon.timeLeft = Gladdy.db.drDuration lastIcon.diminishing = DRData:NextDR(lastIcon.diminishing) -- 2.39.5 From 5da6d1d7c905775405bf7f2cbb831397ab0dbe19 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 17:23:09 +0200 Subject: [PATCH 010/268] added (un)checkAll button in DR-Categories in Diminishing Module --- Modules/Auras.lua | 2 +- Modules/Diminishings.lua | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index a41c275..34ddf5b 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -702,7 +702,7 @@ end function Auras:GetInterruptOptions() local options = { - ckeckAll = { + checkAll = { order = 1, width = "0.7", name = L["Check All"], diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 4f24a19..da9cf1d 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -610,7 +610,30 @@ function Diminishings:GetOptions() end function Diminishings:CategoryOptions() - local categories = {} + local categories = { + checkAll = { + order = 1, + width = "0.7", + name = L["Check All"], + type = "execute", + func = function() + for k,_ in pairs(defaultCategories()) do + Gladdy.db.drCategories[k].enabled = true + end + end, + }, + uncheckAll = { + order = 2, + width = "0.7", + name = L["Uncheck All"], + type = "execute", + func = function() + for k,_ in pairs(defaultCategories()) do + Gladdy.db.drCategories[k].enabled = false + end + end, + }, + } local indexList = {} for k,_ in pairs(DRData:GetCategories()) do tinsert(indexList, k) -- 2.39.5 From 2c73188e1511eba63a383e4916539dd334bf65f9 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 17:24:33 +0200 Subject: [PATCH 011/268] cleanup --- Modules/Auras.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 34ddf5b..b71cc0a 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -266,7 +266,7 @@ function Auras:ResetUnit(unit) end function Auras:Test(unit) - local spellName, spellid, icon, limit, i + local spellName, spellid, icon, limit self:AURA_FADE(unit, AURA_TYPE_BUFF) self:AURA_FADE(unit, AURA_TYPE_DEBUFF) -- 2.39.5 From 237130e3cefbf5d0fdf4f6296a52b8a0ee18271b Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 29 Jul 2021 17:27:37 +0200 Subject: [PATCH 012/268] announcement show MSBT option only when MSBT is loaded --- Modules/Announcements.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Modules/Announcements.lua b/Modules/Announcements.lua index afeca6a..aeb5fd5 100644 --- a/Modules/Announcements.lua +++ b/Modules/Announcements.lua @@ -210,10 +210,15 @@ function Announcements:GetOptions() ["self"] = L["Self"], ["party"] = L["Party"], ["rw"] = L["Raid Warning"], - ["fct"] = L["Blizzard's Floating Combat Text"], - ["msbt"] = L["MikScrollingBattleText"], } + if IsAddOnLoaded("Blizzard_CombatText") then + destValues["fct"] = L["Blizzard's Floating Combat Text"] + end + if IsAddOnLoaded("MikScrollingBattleText") then + destValues["msbt"] = L["MikScrollingBattleText"] + end + return { headerAnnouncements = { type = "header", -- 2.39.5 From 7ca2df2dc41c4a5aaf71784c30bfdf7d1a8d2298 Mon Sep 17 00:00:00 2001 From: Alex Folland Date: Sat, 31 Jul 2021 15:58:47 -0700 Subject: [PATCH 013/268] prevent errors from nil DR icons --- Modules/Diminishings.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 9c3b00b..ddfaf75 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -645,7 +645,12 @@ function Diminishings:GetDRIcons(category) local icons = {} for k,v in pairs(DRData:GetSpells()) do if v == category then - icons[select(3, GetSpellInfo(k))] = format("|T%s:20|t %s", select(3, GetSpellInfo(k)), select(1, GetSpellInfo(k))) + local icon = select(3, GetSpellInfo(k)) + if icon then + icons[icon] = format("|T%s:20|t %s", tostring(icon or "nil"), tostring(select(1, GetSpellInfo(k)) or "nil")) + else + print("Gladdy Diminishings.lua: nil icon for key: "..tostring(k or "nil").."; value: "..tostring(v or "nil")) + end end end return icons -- 2.39.5 From 3ed26e6d9fee1f11b66d5629771be806fb7c36be Mon Sep 17 00:00:00 2001 From: Alex Folland Date: Mon, 2 Aug 2021 11:31:56 -0700 Subject: [PATCH 014/268] improve DRData nil-checking error message --- Modules/Diminishings.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index ddfaf75..d7558a4 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -650,6 +650,7 @@ function Diminishings:GetDRIcons(category) icons[icon] = format("|T%s:20|t %s", tostring(icon or "nil"), tostring(select(1, GetSpellInfo(k)) or "nil")) else print("Gladdy Diminishings.lua: nil icon for key: "..tostring(k or "nil").."; value: "..tostring(v or "nil")) + print("Gladdy: Do you have a conflicting and incorrect copy of DRData?") end end end -- 2.39.5 From a7cdacb55df14dedadf3f81ef7f68f1106cf2595 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 10 Aug 2021 13:17:46 +0200 Subject: [PATCH 015/268] ArenaCountDown update --- Images/Countdown/0.blp | Bin 44900 -> 88580 bytes Images/Countdown/1.blp | Bin 44900 -> 88580 bytes Images/Countdown/2.blp | Bin 44900 -> 88580 bytes Images/Countdown/3.blp | Bin 44900 -> 88580 bytes Images/Countdown/4.blp | Bin 44900 -> 88580 bytes Images/Countdown/5.blp | Bin 44900 -> 88580 bytes Images/Countdown/6.blp | Bin 44900 -> 88580 bytes Images/Countdown/7.blp | Bin 44900 -> 88580 bytes Images/Countdown/8.blp | Bin 44900 -> 88580 bytes Images/Countdown/9.blp | Bin 44900 -> 88580 bytes Images/Countdown/Alliance.blp | Bin 0 -> 88580 bytes Images/Countdown/Horde.blp | Bin 0 -> 88580 bytes Modules/ArenaCountDown.lua | 47 +++++++++++++++++++--------------- 13 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 Images/Countdown/Alliance.blp create mode 100644 Images/Countdown/Horde.blp diff --git a/Images/Countdown/0.blp b/Images/Countdown/0.blp index d8ad7775c1f960f57b4733d88504b38e83b6737a..3c4a50c967ba691861cf76f14a68b4660c3bfe25 100644 GIT binary patch literal 88580 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 WHWzK!xF!^$8i%Dxmah+mLjNC}bG#V< literal 44900 zcmeHw4RjRcz4s)Pw}G6zO{kp9d*5^JnIxvi;!UIZXzlI2btDN@``&YC-PujKF^rbo z1m2$B)Jn1h!2y+Q2x{nQAW_g=tdb2zF6kS=)R4L9wL(xh2OE_{mZ_{HY;<;ZPEHP^@i8Z-u&{{JMMf!QG^jEZ2cr!_mff6| z9kT4HdydgE&ea9Oq5oPc2>4urlb$zXCt@q320fS31Z5okjq~_3=|&qJdOmbQ>@&{m zvh0*sd%}InEe7q9%j9woj6TK--mNSI$6A=n$l+>>dr3*sLBuI?(Ow1B$ zYvUw2Po5x3t<%NmQKH3!jI(DMtr2}%J=f5{XfY;Eb#%mJ5;Bj7)BY`r+Ic?G91YVW z+8HTRt`!z~oI9!`J4i?w1uZ+3vNC5`wY041Ii69 z%?~I?__WIm{u5jH^Ug04Yx5USz&n-j>=#VwZj<-Pcn8`Gv9aq-wA9lm4YzYzh~WH?%xT~~pc0GrPx*r#ovZkHWz@g-RPEYT?DzbGQgH6>vD-O)M&G-0 z&yXByj)q7SqvaJb%~`7o9(jdxdv&N;dc@#gl?FE`cb4<^$Tc(u-aZ%dgCzYRB`bxt zIs3l3=VChX@Lxd9;6JhPu3-FU!kNOy+r{usB|K}b9N?WIp3xWJU3R$Tt?q;DeBJQ= za5xqr{|vkjm1NAay8;ez_?7S9GT1uMl(>Wc~+thbT z`Th01YTMke5B0F~!YfMP+Wxb0^azPiexM%{GHbQexi#`;=aHJoX8$1N2d)q12N$&$ z=2`tAfFEFE?fFUVXYilcl26t4{B}s zPj=l7eqiVaz(4qbI=9Bz;N0#xvO-;9@B;_*gJSp-66^(PF|hW7Z7`4e5Ez}zk3T7Y z!3_Rc3!D2Z2>+Lq_t}OupHs+MhwAo_@!VfmN(Zmo!TodYLmS7p0`Zf75Yyz=l01g@ z5V>wM6C54X=dd)tFPUtK*r|3;+q zaC@h(UBUNZ9>_5giH$^h$Ms<`b3=Y>9N#gb4vOo^IdwgIUZGQJo9I2y>qGU4ReSE_ z_J|tL+NvsFdzoFYj`{;V`P0+U?a>32BS<4sW<{;C!C78SEe0oho-+6fC{JK?E_{bj zux$8G@)wx;0M`%L_de==2LFjIcE#X7S>7Ac-X`x2{oW?;%Ss)kjxz55mN&Yeav%4M zMb{Yi?)-7WME0!zm61M+<71k9FM<}<7#>^`dPi+V75C4n141CUdv`j+yE3M4`Bi%A zA`*!ni9Y@EBhrWb)G_-s)|nBi_v!8jU!xNsrPy6 zp|5cM)jsG8Hnw>h+4T`J9vh4V-_W7I&&jj+fjFwRpH}n~Rv&FpZP4)GQ6uc``fIsA#vGLOw)P@L#L`~ZD` zPPBgxYwP&F*zwp{tZ!oH z0*Lzzb956j0U_6e!svI2643NoE+2(n#n)3}omWToy?Oic^I<)QqJ5F4DIPSXqT=bM zN4-teO&sslPKtI*UzW?uDZIJ9Oh41Yp3fvL{TZ}z0Y493K#wunQ%AXhgY%QN!N%w6 z68J$lHWE7&q5NppoV*fNKmVA}z3%io+zSYs*zVaH#>KD{68`Hsms&`%K7tMOdpts8AbN|bnXz_NA?fQ;Geai zxxZ}jZw!wFe?FD?*{t@ab)O*b4T;ar!SF-W`azyb}R9f?KVz0ktsHBzp@2EtKs$>53*X~*Q-II?VY3lNB_i7mb z4glTjtd^@~%YSa5z1YHgaZyojk!^lGmpasQtogJ!$?<{u(bHU?E-Edg>NV$gWzcTG zA-H|xu9xfNI?KN4m~IhhnG6Yg=z*H0BrD(=*b))L(sMMWi9RS%LS{>8z-r=9M#X{vbEWKVWDCtbZ=_ z53n&JDITgP{W_mRJQTTE+( zz-Qz4JYcLV3YUK`6LF`eDSW&Oor>>Oc@EbHq*qkm?yiLeP!o#b;p ztoM4n+#Yt8%Vp(dmOX6X9f)VW1u)N}6=3wdH~<)(j0f;Kqp+9O;+T4w9ZXZk$XanTAurMNKX5?A=fHvq4HfWWnSo^3!sipQ@f5!d%Qo=k1u(ub+8@2HbEvhN>^4MW=>Bj-q9K}mjwP2Yc! zcq=QpJ^w!@RG(67>HDycTh31Be}j#8ZBpvZn^TZZwuhQSn~pXqqj26=Ih{3B-j`eU zFJkKw#ygeukn!`_^IU-Ulq|ynX6KXl(0sCtVDb2g%v!e!ZKQEnTQ8)|heAN>NA)4)jDJh)-01IEeFe-v`VYLipV3M{@;%$3dl{_-Mc=l6 zXgzDp9!5zN^98pknzmt$vl;e4SG74`AiJn^1c z-?aDN7ypL7j~P8ydt{6$pz|HnLSSEmE@Wr~jIKXacc^ZE zT?eBvyNDJF6U;9Psk74Ou=)!l{-A5wIf2obA8c7h)}3RtzE^1(8tN%9tRWl}N0dNU zetPZ3JBYL2XycEUgCbXL;XLfS&?e$;q@1;pFOoE@U+ z;{$-zj@tT3_P#NM*mipbcG-vDo9$!qN7_0l><1{kD34^c(K@#HW$;H>19p30ij2WSsE;WNGBPr_ zeWac7AFEnw#S`e@hp`5)&e}`tmI6bqqugJpjlmyUklz<-2sMy3WDV7iswyigDE1TZ zPrU)y*z+0fgNOk}o6$la><^s5KWi~_f5qV6K))s5Fun~4veu{@tDCHwY@C_}e_!kT z`SaO){wN7VQdEVHUp?l3MUzfTY&#@3JT!cGBy?RjN*T_ z(`#(3^^@^W?OVFB^U3)Cu>LLf{SVq-fPcdq@c#Y)>K&mQ``v?Nf0%CKTVfiumsksk z?@E7O=k;=XUz*aMTM72Z&Lf_pGHI2{DH~%XYHjupV(f~ zls}Z;*Vo0`Lzz;7if+k&e^Bx*Q^IH2d4I3kl3&u*g}D)9^A8AVfd35s;{)UKj?Yi~ z`5AsbG5jM}i(Q^cM4QI&)!2B|rq$7!m8ZG{FJ=E~cZl?8}jy4}U&{8)P> z>lYs=|2>!?#m2tR@GmCmOW>E|RaI4|S$pWyO0WSA07lc*%R@tX9RE_c1o>Z*Z{Qy` zfd817=0$wOjQ(%7^yeL)pZ4>!@koO~jV*qF#=6-3|3>s1oNVm+i`f5D^^^5u(gwu4 zp_t

tUv(F~M)?|Nb-TUcKWqw`auxf6IRV1Ru}Jh|t@Y|1T$ucvtuUK~w*qz8dS{ z8a!(_ev<9~Ps;zd^;JASRtB(ozTf`h__yMRll_0D{%`sJOzVGtO#FjD?SJn7(G;eZSihnb;EUob%!uNFSHH~VSSvr!9Tqzb=G}+ z{fjWFcbqyE^6~MD_?D#)eeG+E#`?IHSzW2AM(_Y)05rt6NCTSIT)i3Fb{^kv&i`5S z{|5eT^V@Oth5NIO>iuQw;S**6lJRfE4`0InkJzXL|NlYw{xJg(D~*b2cK`nX^_QOV zbNxt)>HgYU%O5CoD=n`*_U2C3Uebs^(7LTPpKK;;LTf?|!Yhc6s;I1TAr_d%NU;7h zqa&>O{|n+HjBEij^M9W<-u~8ppN$V=wGSQP@nT4S401*%$N$jz?IJ|Lv-5Qa-TU49 z+`AY}$0v<%LA>rwvu366_!e{ch(i z&8fXzHGSTG?@_OYczTx;$$^Y$cPrkX#=6su-5>a;>*4M5+XiIW`H#Fe@*7zJ1g3Um z*1${!Qr|BUDe-rel73-)yU z&d7hOS^n1W{868W*MuYAJaU12yI8!def2w#|C-s%to1-fcoJ4bu;2A; z^Xx+W-yzYAkIb6_Z=^92?~yNLWBoIakNgwaNou`S9Pf)FYOvC_9!eWjgFSiqC2{^3 zkw%s8Z9srjSM?6)N6jvw!OU+UC&m9#>|bhr)Kvdw@c&Wq^Lf9XjnCvg#S0zt>^Svr z(J{|xtbf6ZI4d3i*iVQDI7Ifv_Jy~Ni_k~&@_Jeso|Q2~_|;nTf69OwT&Z?w?7Y;i z1oE3F3K)(2J>55!oRFhkG#ZG6q)`F>E#=L6>JRiZb9=zdj$`S&81FRV&8`nnjetLY zGJg{U^9ZY7oaFU4&f4-D(Y4Q1;d>Jf)*gt5>h0<4GuA_q{%Dszsfu@E{lq4; zM~z&=^8uLr(5ioYy`!ZM#T$SYj{^u90nk0TQ*1u4p5HA$_c7Gt% zb+Peyw=#EW!uq$yDfj~r@h(ChvGuRWnM2f3WXw*T#r*-uf7czWdZUAlZwc%D1;Nkb zUl8x=^LLPCI8WFA690g>{?@_t{O#3U^+#8SHtAd7pLaPcozMrM5!m$s#0Qjf`^3nO zgPfYIKBx}3K_Wj$qG@_!&M)X^JKibpqnKyEhwK1wNm%QB+;#4HPrZlRL;J`e^!;%x z+8bDa^ao6TM~(hFAz$g;$N-|)^nL%J(EVI%KFfE4{KDF?y!?VMk?qmuP{UELiuD7C z_H|N!zdha;wh)bow&H!MHH0o?&wC;NV`nbCpTU1(`&_Q_AIMMicO|cfrP9y7{>@ko zZ|T2S3)D#0z_He%_P{VAUWGrah=*Sz)s0hem$jZ`GJs+9Ei8_f5?#b?m7>zZ{5NA;cZhL;fmjYKMm1%NVAHui7(xg zGRuRTx#)pVRMK&&E5&f28W%6r+VLlJDMiu04!K z{!Cx%*}S!;Hh|XuwcfHjKR>U}8`=aLA>>Cs441P)sfO_NR&TQSLAev$z{>AehP6YO z=Hv5xG&vAG!k(AX^a4)PeB`$G4^X_LaJ+l!>$U;$;iGHJd?&*(Gvmoxyk8`L&MbjF zKOyfX$oqPt?M3<`Cp+&S(1Q8>uWe(rc19h5e=r?&+fLU%3scGhnjeMg`gZ?*8TEeJ zyC{vlcb?mo5Git0~0o0nQaJIzIpz%D!e~$FcbbS0(8K zVZ%GPKTP9Q=Vat@|A5-7`c8RkbvFLhcD02}pZyn3ck3-f{XgXK1Bid|&3y*;fngoc zeA>EtYkGQq7v%>plZZ9|JUYD^+wh+FK7!Q*EBv)u?%xXx=zD+L)5GWg{b$7P zv#tGfeQ$`IjCN7~Db$0CuA1iRO+Y=nKh{1P84nn3%6qH*sji>k-#6#?+2tR5KZF0o zrn^$`Z&(Aiswc}6(>rL*hsEQCZ2ke7AIGwnw~cQcuG{Z!r1^APAy_GP!pM<>_*E>3 zpTqH>4yr8^Rh2v*hRT1}kjwH9Y!Q4z;fL?#{2?Hy>8)12eQ8wMa&5s`IdXtn3&)SgcNLcU^K|W%L{rbkv!x5Z+kF3Z0dxiwxNF-uv z@PP$#YpOtV8_*J(P#4U>BbyZcKbaukx00I%kglA|_usrB4mgHrJ}|T3{Xhf#mB3vJ?FPzy&oX&FP-m%-u1(j8T==< z(iMaM#A=)RfIVIy&JfsT7>~w`0i)?!7<+yUd85NaIRZQXT)1sy;~`I*`V-4v7$$GT z`~!%f!wGZ{@)0}3Erq(^hJfo?s zr-jk@XkJwcxk1lAum=5v_A~fTY{(h>$J@iE3(zBUFjAhtTFaO{#1Tf**@J}n1Mma8e&9wt zL8)BC^@Fyt#-Il?3hevHo)rm(eL>+c@@tov@|GSm>}4UH%WHko-+Q|&mdfy|!=EOv zCD$+-`SpR%0Y3kz4XA<64Gn&FUK{WSs?K-KWwbu128OU^kJHp%C;jGmymG`pCW>?C zLLZ>-A9?!eCKd1hRG|-qHa+U~Ro6S&`$xP^Pl7)Gfp~{6k4kt}f7-gVa2gXfpBCoX zJ?MT0|Mu1}+rxh3^TrSC&;E&iPRO45VfjHqd=YhNae0UN1UkdW=NIaHltWnW7YUC0 z+UpwK+$IMUG9;ET|LMqeOJ39^9eE%0b zik?Pu_x*w&vk-V=ZQ5)|Um6Y_Is8Sm5P z{xssCBh%(?Ir_JT|Y5e_j zA6Z1*j`=gXK8Cf#C*9tEYrn_pdBL9QS9X1hzE8O@oA-AieOtPt>;d*Y$5X4u55i^& zkvs5yHS7JUClFCFOVBEe&c?r1;%^gR&@g(#TVn7(WO*5*^$~xIFum+vMhhcCdk2|z zA&|)^+OTkgGI!x_SJ~$B=nu$a`Y^_WtMV>78ZbtR+4E$jB)*S~9;Y#fA5^aJ{^#>; zz&f?4xjaO?d1;X?-@N1XRa3tqe#=^+2q=L!J{BBlY(syi`SVTr7$akty%I7z{2MaZc+i4M z+qB$&keoD+=!3$RTlz|#tSG*xyx$pJAsnXs!cmbs46y;=bPM{Aj<0PpQWT~66>Gtm>P7rhKA5T zUC~WPYVf|}Ole7_V^g))34a5}r&GooQ*8Q)VShQS_@|EP#$k7dyipqv)8<2f(BG%y z!9OY9aK7`2CU!reR|=e~ddy4Kl09@x_=oX6(?x@whhX$@n>ed7`#jLeK=e`!x&G{HzCdosm;#r=U7$hE^-udfAn#(E4FdE z?zD*aQ_jwt-^%)59njj&VZoY33u-~Zjc3=EKeqU&^Q23{{GQ8ESqXkH5Bz}hv-ewn za)tFj=l7J?W8?C@XnE%n+SF!$^hUA&V+r2d8pS=$YMA-9b zXY`hnv2*9hL*#Ktgnn%h`Ftg5QF-p-BD%5f8_$Cg$!NB}Qv2WReM`Sb-@i_`->o$B zE3@`ZK|WPo^VTq$uBZ5i8(T|G)?jm;bos|Hzkov5|6}9*XU+~@(A=!qFW4L0$R-a; z-R8zFJPlcN9GeuT>pkai{S*GymU9)52l0Ha(tvc$qD6~tb%Gzcu(9t`W=A(hv;9o} zn=N7XzT2)7xw=Q{#koc z{Db3i`A>PjH->-ue&Mg>4fUL?iLQXmU8zl?|ErcR zHTi$J)&B=LGFRJwS(-@@qYRxwY7Ir`-^g1_I=YElbgVA6Z|ozKElsu znfeHq*RVh999tbv!5ePqqf>Ex^f2*UZ-3v19#*J6`WktVtc|XTuGHXffI7P5V)_V` zN$mO9{)*{;R^j-b^4rX8%l>^ykwi{z=8GA3m%;R94XblAVS>1|B;0d$7NNKx@9m@Hb%*6g!`T_1<=W zllw*Y>#NRhgxle!G;@8E$$?%ah~UQiT1*P||CoPoPhUa7$(p0CJ6;tzpOm@C4Q}r5j6EfghAIdYYUDKiD`;S%di(boboGsbTar!LrMn(&lHR^7w~oa>szG@bybkX;f|Mzjp4TXv4{h9g7>v zG2fbo;UJg8_OSb#5X%5=&xbdw#s&K;w*Qk_A|74G#{}gD)L>$lxsN-xm98pssMo+g zKnGG^%yF_UjPa1^zi&3T7vK+6F?-G9T@atro`2(6HatiG@vG^GmuCmCT5Yc&+{@{@ z387o7H2uH0=A<&|U$VP%;hp3_bj<-*L%B2xe^Z4^b`_T!9!BUP^9OG56n_zk7lD3_hI=du$F}qGFWK zV!qp`f0jV?SFS%6zHr<5yU7dSN+RYb^B$yigNE?XH;CeWXX@UyB+})pk;{vuZe;&} zf)FDe)9%+x9}v35v<)TDZ;aN6A^(TJrKkVY=*_u5zPi68`W?(KVSQia(iA{p9@>P} zlkNXn_0L?CeH*sB>HAOtkD&?J#?)VbbYlJLo9_7OU1VkSJN=9IlwiI!?fXkB9mP4h zS$KZ-*h1m*?9$A_%5ukVpi1LQlJZ}d0*rDDCr61<=6;o@~yuerUH%)tl`5D=b(!nA%ZZOv8i$(zdwfaBVekp9lXei9gRz%ak7=!)zz*Ol*tgcA& z&nb!PABV$gOsgp%Bu*cBbRJO@mD2sul@FFI&Q(!gX^BfNf&Ga2D>l5|SDXAa>Mx<7 zZx?0$GJE2iu!q3j=l}FDmX!1zUHqr8a@~`o_bhw*>*Vn%L|2KOuz$2`XQv2X7H&wX zO4YVde7pEOJ|P=2XQ8l)d>Hvm?|=Q&_hNUE4a5_Zu6go>7hbsc%m144t(1RCq48Hv zyij-1WcGykR_1Rt*n>ToFnE04(Jx1@ie4qc|5mlMqQbi0$GiUqau@kNxoH~ny=f0T z@Z^*KguDN1%DrFKaDNwGK%M#9%-@UeUjN?8KTv=5{1STaqhEe}9_$h1tE#B{OYfik z9`10bkgWx1J`q_yT28i4lPAN<8R@!Z_ZIXlpFU2=o+CGe-w+nezVFnss?=|$T!m4h zbb{Yvz0HTef7&7qMLfRcvC+Rj`^6V`OPP7M{N#HNrk?-1f&4As)^Y#JpRTyY{(Gq? z7Hxk2>=#G>KJd_WV+!j3lb?i3wtTxg|J;JdQaxBpu;PxNCbWm~{a*?{!1iD8pk4R6 zx1!=7g^k$0B~(VW8)na*{l!{r^dA5GcHo+;u9A5m&(}kOuoMc%7vc{oBq9l^at+Fjzcb-C}0|6}k~xF7ufH7{-{I_zU_%^A0^=uSIU zOb1eV?&qx3J>VE5$v=P86j-q64iPum^%a8F|^|-082dX_H0pJ|66Zc&sj;q6R9-arz^-;M2Y_? zaw%s0rdz*^GX#ApB8;#bEBkzeSZ<}lgKYpZbHi&O6L3dTp-IgXFE^eaiQ{D|cAoXU|NuuD9xq^~jg3JO60W5B*%EPtOtPG;v1p137Rt z=!3$)tMgZbyxr1X9r~@x>vG^i`aOjB&yf2IeqV-%&HyKeXD}~~A0Eo#nCqdYvHYt2 zzqmfQp{jnk5MJH`{)8z_J3q!y(tv*_zKi0`?|1PFzhyjIgoN+QrF|^J2i{H3F7QS3 z2hR)?uJBKqBd#Mvznx5}{5Y(zejq=>;OOo^`aOi?BxAt#p5h}ZEBq5D#8u&c z1~e)?kD-Il*Maa7>HAW)Evp56~+TJ?*kKEN7*!eQ* zKXFRoA2~1@>c30Izn}RD4`Q_LY0t5V?H})ecEETsy^mN&M>PBlhYh2gXrtVCt>Vqs zdeI`BVYC*$$$N1bk)P#0HVG_|Sp@t$$uAt_ImcIHelH3C(3`(#e;(R*dAyFTyWD>dhAg~?2~Qy- zTn-qoAiDgCivN1L?R;{3H;&)y#}nRr0RNM~XdmJIJWo6q*CQoFN7^He(+;-Iu+aZd z+e3u^*#);1lopga^$U&#z`OkcYjz-zN$CspEBs%Lc(~f?gF)gST6^a9kFj+J=ins^ z#_uqKC)(=I1Lldwu{vU&=#UXA2gJWXbomQUym>C!#Sdcp-kLLk>|7q|7Un_;-<gzj? zCK2QNxyD*^#!2nD*#sO*5T4I*eLc{vM0ayD%Hr{rM6+XB?aDVw4Wbh*(Ylu==YATn zzZyN;EBgPXvnwo5`GL8BAbO$^`yTw;1*CA2;y|>*KXFQ275+y)KL&???C*Ql>%8rK zKJ@UPfBxXBKV#{JVN4D-Z)$4;P)_wI*{0j6d{40Epe0<6|91eL62LFhCoDe7cWHiq_nDL{G?8xKLU!QCk2l+v8q4HOt zy`2y3E4EFC=WV*P>(EPG`ccilc}Km2=XkH#WboK# z2j9JB?aGx^5r$!mAh_yW@c@+*}9S>nJ?mo?s^$=KI3MVR!zo zd~x|=13ZN{0QS+xU-jZYkz}1KN|rBo@ZDq9#=#LC->I27&rXXG9XT3l`DAWxF5zES z_?OjbRJ2EOhDSsDIok6(DE!-nB)p2zfHWS!*#K!i5c>k?>G@)q{YOtUV7~(T1I~J1 z!=Y7{XTS8~-{g_brSp4E5We-KzOAaVveKcqMeD|;m7FCy0{#DKTbk<$|7@>j?f+Bl zzYw6plZ@8U(La}SJRI`76#QEUG(yG*&-Qe=Gd}>xw{`$fIIRC!p6D>F{-GyYpnugN zy$}8qr>f^xR};R?Uba=&E2|uOyX4#i1|N-e}#YKz;NJ4 zaCY?a_mc2$7n<-ZRtNfw2b}!?!Qy<&)AQl-kmZSX@W0F3{wKQGv5qrmoCSkuPh>rQ zPfU1^tY>D^#HyExj<+Q0P8H@j{r~t*h5ym6pDO<@2Zp2m8XEkI8A8Id*iPr}2LklN z{=a-@y?kiDoCw#_he+o%TQau4?}kK3xusMtr)tAD;SkB;h}G{-1I4z~;?o zHWR+1z41MIWyi0HPV9^}-Tc#+ze#lbU9+XoH!+{u|AfN7tUhY|3;R!Hr|N?tvj35~ zKUk~>I^%!Q`yaUdPo4iy@M!0e<@25Szj!jfKVG$t@W}xGp;){wEqp! zdpF%k;gR-e)3rI%o&7)b{f`>|3%ykM9DVqdb37dK8%g+2o&Q_kZNmJ2&kDkKv?mJt zf86~cd2Id)cm2=oVU6wg|`EBq_`dlX{m+W!>$K(PLAeF0>j_X+F&p8fy*?*C2s{zvELspZSv?|)ctv`+s1 zSKpRsNc-+HUvb+11JS0U?c1I8e+}%5TxkB^{v6TSk8D~00t;r&{$=}vCZdUH1JTG& zb^aG|>*^d&yQLo;HB~FB>!>p$H~{Yj{E-{`(GVgJ6#$%ksy3)+-#|;s&eqp8kuR# z)mKt@qEV~Mn=vDguj50TXWc*9#|D@t275~<0eJ}$+c%kqAHJl%S^ZQ;;b|l~7onRkWOE1hBKY{Sv z#S?Ftrs?24%HwtM8rR;p{)kpAp1c4B`J-t~FNAM|;A;=^M;CZajSl(UC^Ye1ji#_6KUPAF#FiIup=u zxkL+FGb8WDqDPJ2-FEyRjz5+Fdmu(xcwWe|{x8}87UO^S{13YVp!z`JUugMg)bG)b z&*9GhW#HfG52v=5(EjIVZYX&Cwn=91k$*pnZPdJH2e`gjg&_c-Gq| z`eP>cON5KGn`>HMHcg_VE$k^AQWCB0H5<#0Omo)%wf1;FT4oC+isa13}qJtG$;o?FFse6&j0Px z{)+-r{_WyB^&iow4{H67xFN=uE~V&^SYHeU{w;gJ@_4|q2JD^>04D(=#2ouT#UZc| zjynYG{Q)5ZtOMg6n>LIP(5}4zLA&RJ_d~ny&khyH@d0HG@F{*EG9f!oelk<=Zk_)L zMvdrs(&2$d+;a0>5}AH3mn@jlq~K8lZYO5vY4q419!7!CEyP_+Lf zbq5a@t`D5{RNzkl%zIulUr(I9_UIx4?PUa~eQeNg(K^g-r;(g&Fvs(w)Vp!7lJfYJw< z8>)U#`k?ed=77=%nH#EpQ2L)U#`k?ed=77=%nH#EpQ2L)U#`k?ed=77=%nH#EpQ2Lof za_DJHudvXY9#N|PxzhS}_i=Gv4N2hQ->bX!F2wV${hGnO&lskc1CE}*(&Zid>22_{ zWLX*U7x~R%E}m2A&%6!tzsCyqvkcchieK0-aqJx-nH31k(jYo8U-&Z8AI^jERPyU>y&v=DGH)g2CeA z5YhR+EPiKg@(q3>sZTNLH$Ac<@M!kB>~#e?oS%*MJTkyw4jSB}=leUqLdl;bbA{y( z@bt(#3*?>e${Ws02o;AzV7 z;aVYmkUyMviS56Tet}c}EBp^n{XS^;(+CeE(h6{cP#ACzLz3@ zI6Z{$zbU$v$?u^&vezLHT&eH1(a~>gi|7*A27%vH1^TT+L#mw5~ zRwMU#+3`F1e7;U^(fsr0ePIFC{VDao56`rs_=!Vm{f9Uqu0yRKgOz{Q_p**;ZOWPz zjcMt|WWz{;Y+u?{zPP1bOWy!1`Y7vNyOu18oY&H0QI}5aXX!BvZ-elc7M0@p#wO68 z46F!zHuIyI=0C&wLfA0yY$Nna{=+NpRQ>5!{y6>zNAj>v%arze1Ve#*I597a!o!9* z0gGs3wwDeS;E8tb`IUIK9XJQ?xc)1rXA$sE;h#7muBr07T)JQR+sTqV0h*R08ij{9 zWE$^WjP^Wl#pXV5lg|4@EBO;A#PxFJ-S_?USxG4g&eLb%`PJl7=^fpS-9v$J#rT}f zpTj~w>~}VQ+VM-tzvum@zWkJP_ulvKRQ{AaWDY2Okh!7osq{hVgUkV?4>C7Y{h;(g z>4VGxr4KSUMne5C6J}&tgmPue#~G3hOk3|yNO_;g5jwt#Io~T``67`jQC?|&3JUC*ehn*2rS z`<6e^8=X2{l7Hfeu2tVZ_VmBM^6OB3DE@dy|NpFm{@*|L>YMC~PQ~X-rT)<3}ni5roDhe&yULXA2Q8( z_jafAXVI^J>IfCaqA$LFk-DD2x&K>E=g)dyicHZXwEyqQD7AmAXqPwmYhZqS{wwfU ziT#$JbFc?-X1)!vfDhMSWqS~ugFTkCapUag2N6F#DXx9<^RT}J9JFL>XP$3O-f^1w zjnraulG#o9MM3h6Js)Nqmhtg|k7lZS;xf z(Ate`?`C+?x6+366URL1k2Ci``uE%;+1nYu^s~hx{J6r)cjx9jr?cKpD*^CaI_y_Y-ZU$u^$A-r-lKWMs3IW2fpm{r4cy<`sYMt z{kVL68YsSvQ(y;Fjd;oj`NtOd+JWuc%w+$|TG(?v+?*2Lw{PEv*oQ6O)*aPv9E^RO z=NS5y^IV?-ukXXRKhAO)?~dz(vae(924ZYo_ssM#WS%6jqg!K6=Hb4Fe-T#A`HyC@ zcy%?F_xgoi9T!SS0!SPpa@%a$mH;uaqE}VbvfvGp# gFctTPp=@f~jZ+k)oY>5gh*WY5M{0FkD>WXk+ha$ZLt23hLC8#`ItG1hPHagw zXm@(w%-%P%3o=3x$pY`)vzob@k2mk$_j~uf`@YJ)vEH9W2w9Syl||r0f%CmzfZwz5 z`w{&91%8JJ`Ql+hO5j%kzaacRHz;sbfL}KJmRRqktjqC(Qy#bkxCFQa=9GY8q+a6u z)ypFYA@!+i#?j*43T~I12F99P8t?IV?du*d4al2}*Xw7z-|G+T47@AAKU!K=we0#BM zJb7G0{9g(0HXc3hOY!aZ2T)o7^#BdX`^y96fr^U91^7n`gy7)b@t-EfjgAQ+yQMuR zD^?wQ80Z;cR>`Y^knat6OMvkCTv{GLiGX~1d5}fiCgJt@9y$I~CB^Zc`SMsa{DV!$ z)LPa(-JZJ{{w!;rV!tW8%kg=Wsi>%6Je*fZQZ4coCm$a?7(bo((nlmuYAMJ`7*^Of z^WM>i)>j2%&sd~?ESvZ*$*;_>3{T`|)(3Lkx$OJhSr%b@^F4C>r%HWMFS!3hnvi0}R!F#~8=QiFe%1wl$v?_u@Kzr@Ck(Ul`K7BAgnE33Mgh&IWIq@Xk zFBrGnw|ogvlC1Hfq4igX!&2-8i{uf}MeRSueq~9h1mBnMr4(T0QL;W@r-$Mn0^UF0 zBgcQLq&WUFUmgp=zw7etcMqo4<4tR?2fQZY@p^#bJy;C6u-cP@dKAifP_*iaxKADfmt zs;fg`BIkD>B#Y)Dj|;l z%$LW!@DKK$5~d~{AJpE1#b^F_t9Bn~$NS5r;HiT{A0+ZVqIhpvemY?xym5wP7c8~w z?-z_;bP=LUi06}F-w7FD{I3nQRnfLHUh5N@->;UidSIwgZOJNSv_wkMl~qj-ICva_?bjqwwclRug0oe&QYa!bpq zRfuObPL4`rod=NDXT`|&dRauCyi6Kn!m8EC1K!())~zl^{Hw|K|K;!x4H91e=k`AZ z5I1A_FdzJzo#E66kPK#f-{BwkmqTmcZ;#grO69>ox!r%id8~`TM*NFo zR{K94{}lTi|J)wljCe=P(IZX&yzuXQ2+nEyKgAzF9q7;|z}u+rkCq6?mj{6WaLCtg zl}tjub=)HTyM(NQ!0eq*NrLBp%n>)QJQjj~vp(QXsSlVgL6oNH|96bnO`2QQ-!E;JHU~Ec*?6Aa z;})rBQtiJuqfFd?VVL1xObEy8>gwtl-h1`dCF|o;$W#Acwr?%Nzuqrf{y&a?Q#Bm# zm_u(~ygMbZQ2TEq-+G$~e)xm$w)z9?_5k$%mHUD4dJy{mC?Svd*V6E>%*a!H!@~^k zYFzCT>*^V=b;!+szkP!P|6;Sxx9%;p|9XGY|IhJnikjmebDVYL@>p2?KUIn_Z!^7r z&>T=>j|cF>=pRb>Tt%%#$nQR5kv5)c|Ai@ivY=o!Yu`ite-BjuS^Hm($jvLZoh(HA zuSB)h(gGjz|8xAKgsmgb?_3^E2`t$DJ6}T2t?4q%{?oBQl<>Cs;-CCeYWrW9l4GyG zbz~jlTbtFQA_U|~r`T5W*=HXhulI>N*cJ`{a+?2Nn-(W(noeIpd@FJC&U>=R?7tcnB8T_2FU9NX80n1rN?HFOnYG6M za{S-C`P-RQd3ooQ#=`yosc!*pk?g;g=KmKAGI8Pl3p*IT6WZ9eZI3YgD+R z;FQZFv+DmsTK}IirH~he{D+sq(N78hVM8zUSDsI|B<6Y_n)mQ%)#sOnB3>{Eo1e6^&;>8 zcjkDGf2TCK{ipe1ar}SQ2w;@%VvYZkr{u{}2#9ZeR*gdYUqoJw>RmrhjM1gT%pi=A z?qZk#fc1aw|3{5jM~;6k52pkc3;**R|IgmSr$JYZ3gJ^mlo1Dap^-&_zppN&^epU-5;?8^IrPFFNy!q7L!=~Y3qMj>w(XWf4cFVx%nNwV2&flf2v?IF~2*%kbmFe)c@1% zWjg-p{9j5a`#I+S#^nKX{103IL!Qy5o@p9xM0{&;t*gGyw*RC}P@X@#pRNC^N3=bq zumDKxka3t286l*x;n7De^lu4a{OR+5IQ}ika6DiRxq0NV81{cY_;=3#r|W;yIsi(0 zcYGhv>+!E06SHCYAJ*PKZ>R~mK~@m|s-c4aua33<<%rNcel8SZ*V}~VyY4DpZX7X= z86OyvN>s>eXpn0frAFx~AdK(I_@}!8+4})m)}Kvp#MfMMxS6Y z7;>y1+$<_nKUUty>oU{_ii%!q0X_y~C{gvEva%gTO`-3EUI-luskhPf$3wv@;XgMm zJ!#XMFqxMeIsQ{c!ttN^@>mf5E%eVD|5p3o{}@Umcxn^u=XECW$os@a_xG`O12Bxe zGX>vYsx-3t{PWXdTUFS`yKq3+BOQ7S{3uo+opQ5e^!zj9yJh9%A1a;5t5LbFVC`Ln zA5_KuHg?!JM%M!gS69h&?f=q16@f#igdhC z`|n);BXDXj><+LuA;bFMQcI46c$cAl4*UB^h*x=xWGfC{93d`PVw_!9qh_Rxhy6cN z?kC5E>_W%=dVlhMs0+|Qjzet%uK#1nCe_4AT7TY`@a?TrU4odC~QDF`i75-}U}IpQC@!cFKNAply4- zM7nz#^p~*x(qOOiV6eS*bl^=7?5`rhh9{#2EkkcNwDr5*9{$y#5}?u}mE@?9P0Mpy z_~t{2hI*ZAKXa~sl#q2??EIFde^y^k;+w6P?V-EnIo8K4uMIvC{Q1Ge4`u|=_dvnB zuoor`|2Z>~w+y8DCl!{T!i+}@=n~)EIgw|vh?tF)c3TJ)uzA$$P3-1 z`F3Bi??}iZt=H0jiPs_)Uvhy4N%o|3;wNTFjrd@`lK(WL1L>R;<84TpWNtuVD8J`%?ApX>kH z=<{mxM_T#MGMn4u^3X98_z&tI@d6=Vd&(jO) z0o_xA@lU4x=laiV{hP%xEfbQ#TkZ*X{2o8@n@$Ezk{?Z74?~@X6|Wi^S%0|DtM2(y z&mZ4~`d7NS{!xbXc(r(4?EB}!KWN^fTT%Z4_&;d|*QlYTx&p>Ywh1;ncq{BY(1O)W*L&CPr8P!M`0r{Zs!J z*MAaJHvs;XwDSM$gwU_+=h%7(dOz%UerstD>L1&G9RD{4{z;ntmAEk2*jQhO^+COl zyxh{VuN3vK^7fw%{u==QbUw7R{FkT1LAmanhWdx~&YFEig@vepUjC=3|N5%`1w5=j z8tZ@Q?LTdrj5k6+{p)>lq_F6%eW-u#|G7@|pXQK-)}KlE^``z$1<%PfspFwFX#auw zb<{uUmYa*$_4FJI9}E8sNa+<^tp1l@l8^68Mt8{sCR(56{XZzB#cwapS^vL`{=H88 zp9`MfbYWBc<6jEd11!CJ?q%eAz?B05 z<4lh)qj>O0Vfx*EcbRAJj(8>bA0R*aHeEbv_BWq4#Cu9}IyV>(nDp>HvqWfY+WvHY zmPMFOJQ~JzlK!M87Sq48*AsM?x%?E5ap;d3G+s9j8tsM}S8i$FwQHI2utlVskQ!N* zulw{T6^7||`GMBB)}S8SA?=jJgd*&Mfa%w}ApIbK8!r8j_RFPTk1N8mWp?`2K0;)< zrsifzzcMc8(fRGDe-Xyx!Svi4QU4SH{ww7FM@X-!|9YzbF9YHIc)V`PzvKs};NR~$ zpg(2WyMZ2Kz@VEjollV4a(;TzFdi{pGJa+lS_g5}-@Ai+*-U?7mimx+KeeA`_}!;} zhig3q;&E+U^U)8D#}i^644;~)&3bXk{@nd5zxoqGHdI$XXn${ZSr!DF$204A_4e9| z|M81!J{4w!88RWdXnSk_N{jR^fk5=t7>i+CoA_zm$@uB~Iu^guPe}EHzm@nu^?Y`B zV&jAW@t1zMf92toZ>@}dkwEzg@!$U&r+*DOLH>($%^G4}@WhD|dE}4CSAbqINcL(7 z_WSY7Ix>BB5la0R;dyxc1by}^D4C1=%^Xo|ikqN9zy5sH!2){>u-z39$`;O%h jZd-cW7ibKIA-e9oQ<88XXG;$u>!CieB>5SX4+8)H(0H8y diff --git a/Images/Countdown/2.blp b/Images/Countdown/2.blp index b74cce10d91df32016bf70efec61bf3d311169ca..10aba5edfb8b745c386a518c1aa8b43d0432ca71 100644 GIT binary patch literal 88580 zcmeHw4R}=5x$c@Eb%0VQp}BJJ)8{!m37ms)5SyQ?z0YmkkO}qZx%Z|rdlE3fXw3w* zJtsYuB!WL%tuj&3*vFJ41-hfvl2D*f6*9B$_pLqO z{+av`5R}5&^CUCxUTd$t_qV=xt#5tnZ`!{W=eihUX>ON`;SczG>Jt2Ov8TN7=Yzje z_?zisZ^7S3@OK#gE}4aq2Ra~3hA` z!AI9VdtK<_Xjwi_sdIPSbc5N7*>1Tu(z&# zVwe#=F`0U0a7n`xzhrFTHLURHeRRvuu1$m2=BWOL(fIxC5$qcL_U_yA8~ncgTdrSV ze8SG_`Ne4%UYv~2u360E&TEbPCetaNGKu5hH;n5kU1|9@czia0@?(clc**VNp_Gx(m*9X9kw z`S~-?A^yXT>$v>C^RDq-`Vr&!smX>OB)(@{PtSemzIGn|`SDTw`+IU@J<26(=6f99 z^Lyj|6hB|qxV%#D&yvsgjg8De;jl2GbBSRtl_P!3?{t@Sf5a~4#4u0g@4WmJ{KtH? zj*FqZ`x5zY<1h1gZ2Us5;X(W{P%6&OwufhBJ1|09IHJLDM!GXRy${AS_WJ=I@cE3= z!g^jqgVO)*$^*fFi~IOX@c)eMUk^+7n0!I5@)@uf4~k#Nkyjy%(5EO43~+E<vO<7G8UKl${6XC>+az)bhb$Kk(APDi2ZXu#BMVNejPhEcj27 zH@-#vKWP1Lw%7Zu-v{G6XM0{D={M*5j2RCRMlLGzxAhQ4Zf}ft#kc8_8-7k!l!x15 z+jV_E$DJ$~+zp|+zLn!ifUy+Q^{G08_{_x7go*d)dvslmBi2|@d8xMRpss7Zi03dx z2?irgkuJHH!EdETf#(VOx8Fw3gXN9l^_%63Q92aa%LlL?Y~=$l4f5>vPCAqk&hpV_ zA7N<#<-wQUeh~Z@{72r96iDCuU|!n~Qr~B18K0y-3@gW6_)vO44P{3Cj84KEBD?fB ze5UELM;Yx(dp)^OO{<>9M#0VTneg~TFFXn>J;??_z6Uy(q#h^yVS=^5k~wn;yY%P^ zt+n+Y!dfD*QEhEKX5x7CW!Bnygs|Eh-N@YgXqg;c?v1Wxt$OF4gL(|(gbzucGL^M1 z^v4&%PcQ+lz8*8e6ZOMP#S4E?gLvSg69I=Y;0+G8Hxo;l`{tN!29+MPEA5*cRpH}-7xew;7S)XO+8Xvko&zGm$_)Ej+GKelFK633z^)iy=B zBxw(H^+?^!tx0T-5#G}iILX|tK*1#LlDnB_1!J9*UU-M}zEpu^Wqf3Y#j>?%Rat`u-2wEH2m#kHDR_(tDC(3<4&*^40~Y*^T>>iyu-gK7`Z+2 zM0f|52fk8oUJ)-5NFHDwp}*1eFM=r1gD{{!(a4Xp-~TB1PnvFgTTHlc@sR6(4>Q~Q zefZB6*1>O`dGZ}U}IaT5&2jESl18g@pwm9bO*$66(q|GD1Uaa+8>9*pAo;KElk~Y`|jNq zmO|U+D@O>c&8*>nJu&xV6K@GOT)U}rzW#<$B81;(o=RCA=`Xrt`aRQ^1=&>oIR1Rz zI!J9FQ?-R9E;F;ww-) z2&c{VLl96A_~0o0U=RXRun*3d;nfhM+-KU~aH~bZ>hdZIZ+*X^E!488f$o=p@?clI zttSe6y<&J~J@HxE8LpdqZ_NtA(Uw3+DcKydupCOf^UPGjY@HO!Io{hvIJ`q{ylnCn z!@4T;d67FJKMsKZ!0#(7EdqO>DBo{BFZu@XL(i81-a`BkhSmW85GJktqFC^sBx!sL z{`c?yPv`A_hyO1N%LLND?2ocv%kH`5b!{E5?>iHbp00xn7c1BvexTB)Y_DBVft02A z)j_4GDBtQoLo#EZ0EHW<4>tM1`w#Lge*?rXbX@QAdJEwkrKj-H!0JD&4h0?MLCb-L z{SB`zYN7H#ht>*yq`lHu?ScDU#OEmRd9L1Jl?NSK-A!}W{EfopwrE4aV=wd&hWO1_ zPMNYw|95@4zFJ=m{sM;fm){GYBEQw&*oXgyfkn>`z5v00pye^Ckl(EZRC z(8nKO?=R%uz_afU6!pKIZ5K!Raz^}5iiz|!9jhZ~Az0Wb5xz1EWsk!iG5nEMc>sfX z@I%iBZ3F%xT-{K`KZJJ!`_bta1%Kk`(Id?IUpu7jD7m-hPsH!=4y`#Fz2#Sg<+gA` zc33z430jBLIAP)>7u5bwL>5OLQ+fSgT2@lTEdcX*lKeNHH|bt6%R^EB8wz+X>O*@8 za51ERHuz66BffajjWdLyeCXppz!+9I#Bg9^3Yr;iKr=qZ#e>4(erS&j=$|y~1*`ry z*l+RQV82pM=~cZ@^W>WhkU*g1=+87i_G!KM(f}5|KV66(f+?U z>SIH*jsIUp`ExG#PwzndIp>&gx_&~`G-4(-$ztDfN_p|8nS%kyy2kIobvXZdYBGpZN;@S0t18r)#A3a^>R{k5xQUQRAokqxTOD62dt!ItV|6Gm;G~!s){Q&sFNn;0Nh0eqV_9 zJDdEE9Fw4X%@rk?p}Z8OcqHM4pYZ;!w+Mgd6O6Bv5+?l~5(dsw{66E4`RGH-pMYZz zaRd^@_xf;np3kiB%NGTIQ}vEj-(v?K4DZv!@xX-9t_M}(v(&4;AJtaOBdqR_LS$5}pqGl`6{YV!{LJEBG7w8GmTjmwfb*qrS)5 z-fPzPzH+6iygF!(7pU%f6>9t4dKAVZ)@Kek{d?g!`=~f@`~>k??u}|uTYV4XgF^F9 zerWppqg&)qeC0&+2lDz}h5pTvP~W%LEUtLeR^J=ezRljx$#c~AhP7|`GjZ%6w)qE? zM^a#4G+gkXG|%|H7|MsU$^XmlmY83eZSp<#6!3ZGOcU$6#D>3tGjfdMYj-d<4h#Uo z1L`lf?t$|ZPUbLSoNWMy>EGwIz0JP|wLSRvEdPGhhN|OL2R0>XG^Z?8^ z8a~=(@?A>=dPDp6XA__0xVkn_?DrF9JEL05rX@bY(q6SrYuhvhYWukUMr0ZA-MvLF zE?rjhNJYqBV~#iSgKw|M*1kvop1pnFr@l`&JpA;$Ly{Ln`l9g#|4Guux8VQj@qa0_ z?>|;D&HDT&>lw@Zh0nyue;B@N;sN!QD)=P70rD9J6d&t)^ym>b{CO$%eN}J~g)aj8 z{si>lrNR7Qu@xcqZLsYAAoa}D-;~fV~uaZ@x9QeXO&lItqj_}$I-oCoX_EJU^vxelkfB+xsxz%}3a# zkDT#@`}*&PVBdpJAM|`)#$|1%PPDn3T zmSWGoacJGq*A7nphS}d2?hWrh^2|!ZzJD{aOojPK;Xtu(X-!i_EqL+ieuh8KT2Bmo z`P{;%aIEW*^MpD1ZS#4_;ZEWG$cvvk*WrTyBzfao@c;De{}*Aso#x^avwoLQj6f|z zn%4LnWAy+>{g-Or1A%Pog}~YY*rq4_=l=Vu;1a@%dR~opLkIg`;QsXmmVMu>M|XQx z9PcH5s|l%1jh2=XX4?V{?D41ngK)T8-m>wpxRMZ`ueV2n`HCz}uI#GaT=Q6Us6v|w z<8`=wAB5gJ%f83DKE=KtwExbi?N41F)B7dmciQ&Y>0U4RPm(siP0dZ7z7X-*tp91g z3`x<{Kk(%t=Lz%rFV((>7CnW-+#O)NH9pVit@oMZ^P#TqUKD#Z(RvKl4^c8r`~Hu5 zc!7&)W_vvv*EE%d1H^B6r=+fE`|&-5+0Jmo{teGgPU1-PWcaSu%PuR7t?qfOt7cUV zgZai_-YYf13h1%7=I0orbq2QYajYI5^gi$tdhfn^`<|YsPyX2STlD{vbg=5Oe&eqT z5uZ)|+w{v}-*Yn9`H(U`$5{PyVE;YX_e)@W&TdM-8wiV)^f>V64R@tMz8D8f1YTxL zi<P0>S=TQ2tbAFa5n1pDmh zemFK4IZqhtdWZiW?0d)fT;qkm^7TCFc}a^;g;Bo+|4CXGCf}{MGv4nk^4}bP-;aF{ z4Pa|Np5eVuvG1MZbD+1r{5jIsB|Y!NaZDZqzGsdfZqC1P>49EWV=n)vM|-8ZaG=!e zpM&wZp`ulLn~Cqy9a>%e9`?^KY44S^8$}V-@Jbqx*sP-m3uP33Kb->A&YK zdJ6ATzQGW>bFn@L-H-C{Y-7QHlC1H4A=dZyH^lclEBxp7y~ExGU|SCeo!@r*p05UI zx9`EohB0}h&*kq{@A{4YZXDL@#r1;5V_lC&SdV_xvhUtG1_Ioxs!WxO2?O6%-;wzg z9p>W(>N-0+zstiTdO|t`{dFU^1bUXfQM(NK>on-EH`?NH}X;c!&)I)0X`fD#6W?1*zYgMrCi_84bUl*#V3D%hY1oY+Mhu#+wSv zxo=;u7mOKxP&mFno^xP`VaMsviD}1}fCHyo4=Fmr@gDa04vgyo*uqJRDgIEg;6F*q z_(plyj|&l>QT>m~1_$X^a&(TVuQ)cx;lJnJdx!r%SpIPN3v~U4#HV~jUKGaPW{w|i z+V_D(V7GkyxY+-4=2L(P zd%ZbqTCy3E%TuOC*F zePCSAxTWJ{cwZP_QIgKvBPrtxY~{0|)u--%5d0VX$GS8r1)D$5s9;F{(b#qP^KiI} zt-rp|XIS_YA7tygM<95DOuqTs*pEt_TTzac-#)Ppz7HL=tA5yROle^Q>vN@UH zj1-sMC6FKt2jnrpx^OERW1C)t$`lSc!8}TWjcjT>$k*r$C*-j>I=QjY2$%SHMhj~R z8Tbl#qY>`nd}R!hL;C9X!+1kw4P!mY=lL~+cf$RX5cV&cxC%BXO2fE#yrMTBgkae~ zy8hfT)~E)`%=dHc)U-=RO`4=X9=kU-tEU9l3&iyUpf@t7D93B<7l5OU2Ic?I`XdDY zAvbJ?SraDDU5L2f_CKzt1x-leZ?bu5VxxVUYVYTnblW{x} zt{BAE8y=Y^%k3riPG2~E-gL^3{2W{@#I|3E;6G>Rg~(4^aRhd<9i1Kj!~pyU_7B2; zoPB5S&$~5mecpRBx-{M%RWgmy_c))PT{q&veddfB^#JgDZhW(zJXo6+QdUla_c9J` zOCVI;`iP0cu)emUud!jZF|HjqvDO`4`_8eIPt*0`?&#Y3*j|lrU~hEoT)o{aKiIBl zbBlgbqHuL@xJ6mL5ZCMAN3=t0R`ioAY`8_a^21ib(4W}oKl&>(z6^Z*!OAPm=Ly4p zAIie}%;$-&l|xFR)eKj+sC7!`L38{O?my;_uQBZbty^vB+^}gPtPlKnWO3{^*dM@M zSzP9;@cQ%pFoT%*kIgN6etVuvI>Sep^_vFvDjX)3A>59&laj~Up9}i)p?@yT z79ZEoaKul+GK|l)hvRr%I|h5efuXwUT>*y5|H;qd(S z_ksOG9O(mgTrb<>NA!rwpHEe~<}E9^N4cvgd>8Bw0`?HD9pG3W%rL+*NdA4+2Ry^| zf&~A0ewqKyMSW`~4nNL^^!w#Mw*KKD{YvFOFyHV1Ci(9T7AkpOYdqhghG4Z)ZuR#y zHo^uzu;B-#*VqyYK@1ba?p(OVkLhnaH8xVD^jcd}@#&^_j^o4bWVqo8JumK7X2-_< zMpl1735+*}EfdW4ec$=R#tdRgFExM8biE+Ke>*$R4}RL8=vKg>8F# zfUmA^_5VX#0Lue&zCLX4VeG&`-n~)>_{eUWG3ZK<{I$7GUlFnVr#RJ`txp#RmY{bL##*icdO~iUt2k zGRF70;G6vp=R^8K;Xm&UfCndiG3uL?@c?j=!g22(j6)dBRVW`E7|+?Npi;b`M^*66P=6a84~}K4`J#T zZyi|rhx-9yi-E!ob+zXE8`$Fi7sgPQ;NiUA-#G?C+ujH1ZDI~=IGG)0_}RjO|0GG{ z`&{tNeuwiR{WIc!@+C-L>79m*`;;F>3Us}(8<3^{fA9FTmF-{%8A z?N4+ro~PJ$15Dpsya&z;eDTSHYzxp_#yN`=!0DXLLcnX5aol=2cZvk2?%|#OGA_oLLY=a*d-wJ!7dF^J_vmf`e2uU z&?TM?9veBgU|<|4|WL%eXvVIln+85gg)3MAoRg54N*P_eGvL! zmw=%UJ|CSkFs?9e92Y)*0A_+06gc0P(8W<+_~4*7rupwf!nXA<81wMuFwE;YwARzX zK>L1j#(tDmIAGX6&RRbf?++_Vnd@s9&-2CCmolF(`GT`!jE#pQ2`|d|X@lgyx&A7H z^;O_7*H`122^)lwJYj7iSY6E8ZwV2sIcBamh-;4lv@k@lW4JsA_B=E9GlIQMGhn|% zbNxX>JFNAKFuy=QPJ4ebdS1$Jk^hYKoBtqO+(Vn>#rN8=t+x$(%lQhsf0p?0DDEFq zKi;dX=*Bhn|D@jx`)Q@Ihg)KN$^CJ-AH_trqBXgKHSBjGDa_s4dRL6^ccJ#mk`iSP zC`$VR9nP>`*`t(1TfKRTccBtnDDC3=)0E=gm)<;UKWr>3veR?S^=EN+8C-#mo|p3X zR9NJH|M_pQ-Qqilzc9Nn_fC@MR@h18By4yVjjQtT#UK2Q)+c{D5$LE<6xwd22i6mB zo?9KOOosP_-;b*I=`2F=16#DZXYV+!5@zcHAvW=!?!dhV@L;<%Rlc%4GSj=dC^k!9 zt#wFD@s|ejvh%a^VFwa=9^7jXcSI&E^52kvVZV_y`nPBL<3Ha|6AS$0`kA@E&;3j8 z$r}@aoxsQX%<(*P_Uu`}4yzL;xC4H@XV20{s)I@x*4I{HKZ!S9tOext$`b5{1?xw* zZmSLjgI=IMV@CiVOtc(aw6Usz!Ftz|JB|G(5_-3;z0a=Mzwd*^Jbm~l!+u+n;;{aH z%s8WVXzC54ul%Qy{G0Oc&0k&=Jqh}tl=yLRznqlvU?}@d3I6xbe_T%uS6rq1e|pc( zyKnSnWovDWJ#>$vEc7e+u$-#7J|eCsiVF-=azRzEx zi2NUVd2iJQMt#s<`A>046w}|-mj^o7*tCvmm3I`(%P+~F zZni&ip!~-b$tgWrLx^yn=S!Xt{2ze-N%{Qq4<)vK{Cv|Nbl3K$J*D$AP5j%167$WU zOW5Q)*pFG5B_w~a9lg+EF!^4-Z+`D{iG8p?kL>P*4Y!HkfwS+K!o5$r#epPgsg|FB*y?l@tVKLh1AJr9M8{2x63|MG3d=4WPR zlDxiuz2xq!zq2pjxxHYu7l7-~V#qby^T77!%HN$I&&KuLl+J=)&URf_6Vgmqni{73 zW^rw;uLQO;<7|&Dfc*yDq3bJ47ZjD|`|~V&KPSV~zgO;d5dSbyL09k>p8PVz>sL!O)aZ$1xP$4%;9J_`P}5mxywC8Gaz{PMci8W|e1FLIY7`0tC?4vc*FWVoI)nYxVS8oMpQj#HL%`=w$p4tWU0)XcP`YZ$ zwrRzyN*4NSiYki29gIQo&dYc7=#jo5+rh(Y@*ljra9G&rZnCfuZrT6b9}GQ8l%C+f zA%XtjBJ<{j54z zQ}M=25dWwI>6O5_VDQBkalcjx^UuJ$b$u$oUnk&)H)4-c@EBe{l9g}l<&QA^7#pjM zQlmY%Tk&T7-urvm*r)$=`-1Oe6u>9nv={m7_0wM{^54jR^!D2O`>?ks`_Ak?27bW# zQ@>R|Vfbef;lS|w@1*S4<-^g2O2}?HWY`aT?wpa9|E8NYj@CCnVul}<+aLo8>fs}S zwuznA2`M41V{9o8DkI*)AD?}(MYIemEn*b|-`%Y1&r zA874gmCXM>?L(3OR{moNKzz^rG&i2@%PQ2?F_yXBkoTgHuUy^<^+RWrOg76rW?zAO}tj zKf4%jZ{3e03n!r&J`fi9@1E96!hvsHcTcl#32-ssDUSEI0WJ@L?Gos({V2jM2?+UE zvcO+L9zq^=2?%|#OGEHO=!4J)y99(j*rg%L2cZwA(uZ5nZ&O0ClJcVQSY&^lLp&8m zbh8mD_a{jAKWF&ZCdT}5@Edq6|0T{Z%gW9*#~UJo9weXXpI{m3Fry@&FwQ2*aEu?v z6i+>VSl6@MBjBJH{Id0x-rtku$xY8qpGNOfxa4E*vELhq`8Ok;Y2DUkc+6c#<@@8> zT>Yin46GiKubHc^IpNK@J3n^4z9!It^KXi;2Whx+(yjgzdOu2^@cHuo=|4~3oBpaN zS9(NZotgEDzP)|k_rd=d?q)0s^AVa_lydN4=E{=cAMVzd#OI&5b)U3Oa@Q7QWKSu6{6 zgr0xKz8Rn2+WSy~eI&8^%mQP)HH^Q4`8lB%UV6TK_Lv(ouFLqJ87lOj;`pn9#@n1P z`A_=TJ!`7_wR+_qj-forxdQr|;rW3XGje}A?UkFC8vR+XB>S@hN7yxsUyf?}6Z(&0 z-(ORp?O^Wf|D)75Els%^ZO20$hE01OBv>Sgk?z%Ar89C|lzd(LN|C-@FKea#gym^1fYrB3! zUcWu##Lx7=$B^GJKq1*-`DXJG)>vHj_Wa2AA1|1dQ<9^ulUOOdFy?ii`N!bYCixlp z-FLj4=RiG<@zI$S{Pryi;Z0{ z%b(`Y_j@apJzeUfoDVEJ8)oA^d{F=O9*#!>uJ4HHn=jFuuY%cHHR)2h@1%w6!%s$~E0qL8|UN&7~!Bo2k59n75uufT<)1MUVX zwzd+kiSA-D(*fV7m+9A3jDy~4_jR`vE4(!5XMFirmjArBjxoyrtXwGJp+|=Fwa|;R zuPp3670!3Y&&z<(mXOJm-uYVo>-wRk2~tM*#{P=dFBM5GUl#i|`w6@G z(rFClcfR%3^9SSl>gxR5oBxxsVQQJO>1ut=34N;`T`P|*4PPYRG=LAa;3Tb__vu=TI{gf(OS zPukV#D$IW^o>P*v&-=4a&hY+IJr8*Hde;A8;m@qzn{VK-N%r~Ovle*i` zpJ%a4t4roCcbypi`6cZxwu`yv+;meJ$ph0*gTunfU+X-_2U0L)5_ k9CLkV!Z*J;A&VIr@b;$sRjYs7+DZaS#Ea`!wzjtZe~>>2umAu6 literal 44900 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 diff --git a/Images/Countdown/3.blp b/Images/Countdown/3.blp index c4157cb1e04c4caeb154f38278f15e877027deeb..3627fa612c5bf3b231c4394f9549ce31f73124f7 100644 GIT binary patch literal 88580 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 diff --git a/Images/Countdown/4.blp b/Images/Countdown/4.blp index 6480f0d503d5505b86fc075c56cee3b74afd2641..dd3c6cc961d1b27a9f7a75d93bf2b3b1d18d7cda 100644 GIT binary patch literal 88580 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 literal 44900 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 diff --git a/Images/Countdown/6.blp b/Images/Countdown/6.blp index 4d34be045375363f69a1469e18754b530ef1b3b9..a19c292748bb4cb7d62af5af78cc05e856673123 100644 GIT binary patch literal 88580 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 WHFmi-Z|Z1orviqevsMDx{{I0pXeQJE literal 44900 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 X%G#zUo@#6){b=o2_Q*4hjg9{wMslCt literal 44900 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 diff --git a/Images/Countdown/8.blp b/Images/Countdown/8.blp index fb4c555c8050f0ecead2481d5b7fdcdfdf84c581..8d4eebc7a8df72eedaaab66b476aecbb5b6f6be9 100644 GIT binary patch literal 88580 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 diff --git a/Images/Countdown/9.blp b/Images/Countdown/9.blp index 7a4bbb99ede604bbce5d84d4577867abd0929ab9..290049bdd8f627ed10b3967a0faab0d1bba0fd8e 100644 GIT binary patch literal 88580 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 literal 44900 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�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 literal 0 HcmV?d00001 diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index ca404d1..274721c 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -21,33 +21,34 @@ function ACDFrame:Initialize() local ACDNumFrame = CreateFrame("Frame", "ACDNumFrame", UIParent) ACDNumFrame:EnableMouse(false) - ACDNumFrame:SetHeight(256) - ACDNumFrame:SetWidth(256) - ACDNumFrame:SetPoint("CENTER", 0, 128) + ACDNumFrame:SetHeight(512) + ACDNumFrame:SetWidth(512) + ACDNumFrame:SetPoint("CENTER", 0, 256) ACDNumFrame:Show() self.ACDNumFrame = ACDNumFrame local ACDNumTens = ACDNumFrame:CreateTexture("ACDNumTens", "HIGH") ACDNumTens:SetWidth(256) - ACDNumTens:SetHeight(128) + ACDNumTens:SetHeight(256) ACDNumTens:SetPoint("CENTER", ACDNumFrame, "CENTER", -48, 0) self.ACDNumTens = ACDNumTens local ACDNumOnes = ACDNumFrame:CreateTexture("ACDNumOnes", "HIGH") ACDNumOnes:SetWidth(256) - ACDNumOnes:SetHeight(128) + ACDNumOnes:SetHeight(256) ACDNumOnes:SetPoint("CENTER", ACDNumFrame, "CENTER", 48, 0) self.ACDNumOnes = ACDNumOnes local ACDNumOne = ACDNumFrame:CreateTexture("ACDNumOne", "HIGH") ACDNumOne:SetWidth(256) - ACDNumOne:SetHeight(128) + ACDNumOne:SetHeight(256) ACDNumOne:SetPoint("CENTER", ACDNumFrame, "CENTER", 0, 0) self.ACDNumOne = ACDNumOne self:RegisterMessage("JOINED_ARENA") self:RegisterMessage("ENEMY_SPOTTED") self:RegisterMessage("UNIT_SPEC") + self.faction = UnitFactionGroup("player") end function ACDFrame.OnUpdate(self, elapse) @@ -57,11 +58,7 @@ function ACDFrame.OnUpdate(self, elapse) if ((floor(self.countdown) ~= floor(self.countdown - elapse)) and (floor(self.countdown - elapse) >= 0)) then local str = tostring(floor(self.countdown - elapse)); - if (floor(self.countdown - elapse) == 0) then - self.ACDNumTens:Hide(); - self.ACDNumOnes:Hide(); - self.ACDNumOne:Hide(); - elseif (str_len(str) == 2) then + if (str_len(str) == 2) then -- Display has 2 digits self.ACDNumOne:Hide(); self.ACDNumTens:Show(); @@ -72,8 +69,10 @@ function ACDFrame.OnUpdate(self, elapse) self.ACDNumFrame:SetScale(0.7) elseif (str_len(str) == 1) then -- Display has 1 digit + local numStr = str_sub(str, 0, 1) + local path = numStr == "0" and self.faction or numStr self.ACDNumOne:Show(); - self.ACDNumOne:SetTexture(self.texturePath .. str_sub(str, 0, 1)); + self.ACDNumOne:SetTexture(self.texturePath .. path); self.ACDNumOnes:Hide(); self.ACDNumTens:Hide(); self.ACDNumFrame:SetScale(1.0) @@ -92,18 +91,24 @@ function ACDFrame.OnUpdate(self, elapse) end function ACDFrame:JOINED_ARENA() - self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") - self:SetScript("OnEvent", ACDFrame.OnEvent) - self.endTime = GetTime() + 70 - self:SetScript("OnUpdate", ACDFrame.OnUpdate) + if Gladdy.db.countdown then + self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") + self:SetScript("OnEvent", ACDFrame.OnEvent) + self.endTime = GetTime() + 70 + self:SetScript("OnUpdate", ACDFrame.OnUpdate) + end end function ACDFrame:ENEMY_SPOTTED() - ACDFrame:Reset() + if not Gladdy.frame.testing then + ACDFrame:Reset() + end end function ACDFrame:UNIT_SPEC() - ACDFrame:Reset() + if not Gladdy.frame.testing then + ACDFrame:Reset() + end end function ACDFrame:CHAT_MSG_BG_SYSTEM_NEUTRAL(msg) @@ -124,15 +129,15 @@ function ACDFrame:UpdateFrame() self.ACDNumFrame:SetPoint("CENTER", 0, 128) self.ACDNumTens:SetWidth(Gladdy.db.arenaCountdownSize) - self.ACDNumTens:SetHeight(Gladdy.db.arenaCountdownSize/2) + self.ACDNumTens:SetHeight(Gladdy.db.arenaCountdownSize) self.ACDNumTens:SetPoint("CENTER", self.ACDNumFrame, "CENTER", -(Gladdy.db.arenaCountdownSize/8 + Gladdy.db.arenaCountdownSize/8/2), 0) self.ACDNumOnes:SetWidth(Gladdy.db.arenaCountdownSize) - self.ACDNumOnes:SetHeight(Gladdy.db.arenaCountdownSize/2) + self.ACDNumOnes:SetHeight(Gladdy.db.arenaCountdownSize) self.ACDNumOnes:SetPoint("CENTER", self.ACDNumFrame, "CENTER", (Gladdy.db.arenaCountdownSize/8 + Gladdy.db.arenaCountdownSize/8/2), 0) self.ACDNumOne:SetWidth(Gladdy.db.arenaCountdownSize) - self.ACDNumOne:SetHeight(Gladdy.db.arenaCountdownSize/2) + self.ACDNumOne:SetHeight(Gladdy.db.arenaCountdownSize) self.ACDNumOne:SetPoint("CENTER", self.ACDNumFrame, "CENTER", 0, 0) end -- 2.39.5 From f7f703d33ae0e6c605ea6a4a50d5d5b137f0dd9a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 10 Aug 2021 13:18:02 +0200 Subject: [PATCH 016/268] Auras description --- Modules/Auras.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index b71cc0a..29ff0f1 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -1,6 +1,7 @@ local pairs, ipairs, select, tinsert, tbl_sort, tostring, tonumber, rand = pairs, ipairs, select, tinsert, table.sort, tostring, tonumber, math.random local GetSpellInfo = GetSpellInfo +local GetSpellDescription = GetSpellDescription local CreateFrame, GetTime = CreateFrame, GetTime local AURA_TYPE_DEBUFF, AURA_TYPE_BUFF = AURA_TYPE_DEBUFF, AURA_TYPE_BUFF @@ -668,6 +669,7 @@ function Auras:GetAuraOptions(auraType) enabled = { order = 1, name = L["Enabled"], + desc = GetSpellDescription(k), type = "toggle", image = Gladdy:GetImportantAuras()[GetSpellInfo(k)] and Gladdy:GetImportantAuras()[GetSpellInfo(k)].texture or select(3, GetSpellInfo(k)), width = "2", -- 2.39.5 From 890cf80531f320b0db4a6f563065b1e59e0ec9f7 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 10 Aug 2021 13:18:25 +0200 Subject: [PATCH 017/268] LibClassAuras update --- Libs/LibClassAuras-1.0/ClassBuffs.lua | 5 ++++- Libs/LibClassAuras-1.0/ClassDebuffs.lua | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Libs/LibClassAuras-1.0/ClassBuffs.lua b/Libs/LibClassAuras-1.0/ClassBuffs.lua index e8bcbfe..48de7aa 100644 --- a/Libs/LibClassAuras-1.0/ClassBuffs.lua +++ b/Libs/LibClassAuras-1.0/ClassBuffs.lua @@ -140,7 +140,8 @@ Buff( { 25782 }, { buffType = "magic"}, "PALADIN") -- Greater Blessing of Might Buff( { 25895 }, { buffType = "magic"}, "PALADIN") -- Greater Blessing of Salvation Buff( { 25899 }, { buffType = "magic"}, "PALADIN") -- Greater Blessing of Sanctuary Buff( { 25894 }, { buffType = "magic"}, "PALADIN") -- Greater Blessing of Wisdom -Buff( { 642 }, { buffType = "magic"}, "PALADIN") -- Divine Shield +Buff( { 642 }, { buffType = "immune"}, "PALADIN") -- Divine Shield +Buff( { 31884 }, { buffType = "magic"}, "PALADIN") -- Avenging Wrath --Auras Buff( { 465, 10290, 643, 10291, 1032, 10292, 10293, 27149 }, { buffType = "aura"}, "PALADIN") -- Devotion Aura Buff( { 7294 }, { buffType = "aura"}, "PALADIN") -- Retribution Aura @@ -167,6 +168,8 @@ Buff( { 21082 }, { buffType = "magic"}, "PALADIN") -- Seal of the Crusade ------------- Buff( { 5384 }, { buffType = "physical"}, "HUNTER") -- Feign Death +Buff( { 19263 }, { buffType = "physical"}, "HUNTER") -- Deterrence +Buff( { 3045 }, { buffType = "physical"}, "HUNTER") -- Rapid Fire --local FEIGN_DEATH = GetSpellInfo(5384) -- Localized name for Feign Death diff --git a/Libs/LibClassAuras-1.0/ClassDebuffs.lua b/Libs/LibClassAuras-1.0/ClassDebuffs.lua index 8d4a166..f488982 100644 --- a/Libs/LibClassAuras-1.0/ClassDebuffs.lua +++ b/Libs/LibClassAuras-1.0/ClassDebuffs.lua @@ -20,7 +20,8 @@ Debuff({ 15286 } ,{ buffType = "magic" }, "PRIEST") -- Vampiric Embrace Debuff({ 15407, 17311, 17312, 17313, 17314, 18807, 25387 }, { buffType = "magic" }, "PRIEST") -- Mind Flay Debuff({ 605, 10911, 10912 }, { buffType = "magic" }, "PRIEST") -- Mind Control Debuff({ 8122, 8124, 10888, 10890 }, { buffType = "magic", }, "PRIEST") -- Psychic Scream -Debuff({ 15269 }, { buffType = "magic"}, "PRIEST") +Debuff({ 15269 }, { buffType = "magic"}, "PRIEST") -- Blackout +Debuff({ 44041, 44043, 44044, 44045, 44046, 44047 }, { buffType = "magic"}, "PRIEST") -- Chastise --------------- -- DRUID -- 2.39.5 From bb7b820cbbe83616277c07d73af02d24b7872888 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 10 Aug 2021 13:19:17 +0200 Subject: [PATCH 018/268] add Net-o-Matic, Nigh Invulnerablility Shield & Nigh Invulnerablility Backfire to Auras --- Constants.lua | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/Constants.lua b/Constants.lua index 3cc8507..bd91dbe 100644 --- a/Constants.lua +++ b/Constants.lua @@ -1,6 +1,7 @@ local tbl_sort, select = table.sort, select local GetSpellInfo = GetSpellInfo +local GetItemInfo = GetItemInfo local GetLocale = GetLocale local Gladdy = LibStub("Gladdy") @@ -711,6 +712,28 @@ local importantAuras = { magic = true, spellID = 34709, }, + -- Net-o-Matic + [GetSpellInfo(13120)] = { + track = AURA_TYPE_DEBUFF, + duration = 10, + priority = 30, + spellID = 13120, + }, + -- Nigh Invulnerability Shield + [GetSpellInfo(30458)] = { + track = AURA_TYPE_BUFF, + duration = 8, + priority = 15, + spellID = 30458, + texture = select(10, GetItemInfo(23825)) + }, + -- Nigh Invulnerability Belt Backfire + [GetSpellInfo(30457)] = { + track = AURA_TYPE_DEBUFF, + duration = 8, + priority = 15, + spellID = 30457, + }, } function Gladdy:GetImportantAuras() return importantAuras @@ -1063,9 +1086,9 @@ local arenaTimer = { [0] = "Der Arenakampf hat begonnen!", }, ["frFR"] = { - [60] = "Le combat d'arène commence dans une minute\194\160!", - [30] = "Le combat d'arène commence dans trente secondes\194\160!", - [15] = "Le combat d'arène commence dans quinze secondes\194\160!", + [61] = "Le combat d'arène commence dans une minute\194\160!", + [31] = "Le combat d'arène commence dans trente secondes\194\160!", + [16] = "Le combat d'arène commence dans quinze secondes\194\160!", [0] = "Le combat d'arène commence\194\160!", }, ["ruRU"] = { -- 2.39.5 From 9c8c78bb8369a7a1de06c20cc1167202d6b628e1 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 10 Aug 2021 13:19:52 +0200 Subject: [PATCH 019/268] DRData update add Nature's Grasp and Pyroclasm --- Libs/DRData-1.0/DRData-1.0.lua | 14 +++++++++++++- Modules/Diminishings.lua | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Libs/DRData-1.0/DRData-1.0.lua b/Libs/DRData-1.0/DRData-1.0.lua index 92523a6..f1f5ff8 100644 --- a/Libs/DRData-1.0/DRData-1.0.lua +++ b/Libs/DRData-1.0/DRData-1.0.lua @@ -1,4 +1,4 @@ -local major = "DRData-1.0" +local major = "DRData-1.0-BCC" local minor = tonumber(string.match("$Revision: 793$", "(%d+)") or 1) assert(LibStub, string.format("%s requires LibStub.", major)) @@ -139,6 +139,9 @@ Data.spells = { -- Revenge Stun [12798] = "rndstun", + + -- Pyroclasm + [18093] = "rndstun", --[[ CYCLONE ]]-- -- Blind @@ -167,6 +170,15 @@ Data.spells = { [9853] = "root", [26989] = "root", + -- Nature's Grasp + [19975] = "root", + [19974] = "root", + [19973] = "root", + [19972] = "root", + [19971] = "root", + [19970] = "root", + [27010] = "root", + --[[ RANDOM ROOTS ]]-- -- Improved Hamstring [23694] = "rndroot", diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index da9cf1d..f926077 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -6,7 +6,7 @@ local CreateFrame = CreateFrame local GetTime = GetTime local Gladdy = LibStub("Gladdy") -local DRData = LibStub("DRData-1.0") +local DRData = LibStub("DRData-1.0-BCC") local L = Gladdy.L local function defaultCategories() local categories = {} -- 2.39.5 From fad4321bf67aa26fcbebcfb6a8d658903b67abaf Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 19 Aug 2021 18:56:52 +0200 Subject: [PATCH 020/268] add mangle --- Libs/LibClassAuras-1.0/ClassDebuffs.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Libs/LibClassAuras-1.0/ClassDebuffs.lua b/Libs/LibClassAuras-1.0/ClassDebuffs.lua index f488982..12ca9f8 100644 --- a/Libs/LibClassAuras-1.0/ClassDebuffs.lua +++ b/Libs/LibClassAuras-1.0/ClassDebuffs.lua @@ -45,6 +45,8 @@ Debuff({ 1822, 1823, 1824, 9904, 27003 }, { stacking = true, buffType = "physica Debuff({ 1079, 9492, 9493, 9752, 9894, 9896, 27008 }, { stacking = true, buffType = "physical", preEvent = "SPELL_CAST_SUCCESS" }, "DRUID") -- Rip Debuff({ 5570, 24974, 24975, 24976, 24977, 27013 }, { stacking = true, buffType = "magic", preEvent = "SPELL_CAST_SUCCESS" }, "DRUID") -- Insect Swarm Debuff({ 33745 }, { stacking = true, buffType = "physical", preEvent = "SPELL_CAST_SUCCESS" }, "DRUID") -- Lacerate +Debuff({ 33878, 33986, 33987 }, { buffType = "physical" }, "DRUID") -- Mangle (Bear) +Debuff({ 33876, 33982, 33983 }, { buffType = "physical" }, "DRUID") -- Mangle (Cat) ------------- -- WARRIOR -- 2.39.5 From 9e81455ec510be7a565ac94509259e953081ec84 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 19 Aug 2021 18:57:27 +0200 Subject: [PATCH 021/268] fix SpotEnemy --- EventListener.lua | 15 ++++++++++----- Modules/Racial.lua | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 8734d44..4d87a28 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -48,6 +48,9 @@ end function Gladdy:SpotEnemy(unit, auraScan) local button = self.buttons[unit] + if not unit or not button then + return + end button.raceLoc = UnitRace(unit) button.race = select(2, UnitRace(unit)) button.classLoc = select(1, UnitClass(unit)) @@ -55,7 +58,9 @@ function Gladdy:SpotEnemy(unit, auraScan) button.name = UnitName(unit) button.stealthed = false Gladdy.guids[UnitGUID(unit)] = unit - Gladdy:SendMessage("ENEMY_SPOTTED", unit) + if button.class and button.race then + Gladdy:SendMessage("ENEMY_SPOTTED", unit) + end if auraScan and not button.spec then for n = 1, 30 do local spellName,_,_,_,_,_,unitCaster = UnitAura(unit, n, "HELPFUL") @@ -88,7 +93,7 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() Gladdy:SendMessage("UNIT_DEATH", destUnit) end -- spec detection - if not Gladdy.buttons[destUnit].class then + if not Gladdy.buttons[destUnit].class or not Gladdy.buttons[destUnit].race then Gladdy:SpotEnemy(destUnit, true) end --interrupt detection @@ -119,7 +124,7 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() end end - if not Gladdy.buttons[srcUnit].class then + if not Gladdy.buttons[srcUnit].class or not Gladdy.buttons[srcUnit].race then Gladdy:SpotEnemy(srcUnit, true) end if not Gladdy.buttons[srcUnit].spec then @@ -138,7 +143,7 @@ function EventListener:ARENA_OPPONENT_UPDATE(unit, updateReason) -- ENEMY_SPOTTED if button then Gladdy:SendMessage("ENEMY_STEALTH", unit, false) - if not button.class then + if not button.class or not button.race then Gladdy:SpotEnemy(unit, true) end end @@ -189,7 +194,7 @@ function EventListener:UNIT_AURA(unit) return end for i = 1, 2 do - if not Gladdy.buttons[unit].class then + if not Gladdy.buttons[unit].class or not Gladdy.buttons[unit].race then Gladdy:SpotEnemy(unit, false) end local filter = (i == 1 and "HELPFUL" or "HARMFUL") diff --git a/Modules/Racial.lua b/Modules/Racial.lua index acfcaa1..caf37b7 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -171,7 +171,7 @@ end function Racial:ENEMY_SPOTTED(unit) local racial = self.frames[unit] - if (not racial) then + if (not racial or not Gladdy.buttons[unit].race) then return end racial.texture:SetTexture(Gladdy:Racials()[Gladdy.buttons[unit].race].texture) -- 2.39.5 From e2d0af1e2bf28f6377cc354dbf9e41e7018dfcbb Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 19 Aug 2021 18:58:05 +0200 Subject: [PATCH 022/268] fix paladin spec detect to discipline --- Modules/Cooldowns.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 181c029..12f14aa 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -338,6 +338,9 @@ function Cooldowns:DetectSpec(unit, spec) if (not button or not spec or button.spec) then return end + if button.class == "PALADIN" and (spec ~= L["Holy"] or spec ~= L["Retribution"]) then + return + end button.spec = spec if not button.test then -- 2.39.5 From 1c93e4ce4de1aa935b17260e395f074038d61ac0 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 19 Aug 2021 18:58:17 +0200 Subject: [PATCH 023/268] cleanup --- Modules/RangeCheck.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/RangeCheck.lua b/Modules/RangeCheck.lua index eccb1a6..5fac117 100644 --- a/Modules/RangeCheck.lua +++ b/Modules/RangeCheck.lua @@ -211,12 +211,12 @@ function RangeCheck.CheckRange(self) local spell = Gladdy.db.rangeCheckDefaultSpells[RangeCheck.playerClass].min - if( not UnitIsConnected(button.unit) or not UnitInPhase(button.unit) ) then + if (not UnitIsConnected(button.unit) or not UnitInPhase(button.unit)) then RangeCheck:SetRangeAlpha(button, false) - elseif( spell ) then + elseif (spell) then RangeCheck:SetRangeAlpha(button, LSR.IsSpellInRange(spell, button.unit) == 1) -- That didn't work, but they are grouped lets try the actual API for this, it's a bit flaky though and not that useful generally - elseif( UnitInRaid(button.unit) or UnitInParty(button.unit) ) then + elseif (UnitInRaid(button.unit) or UnitInParty(button.unit)) then RangeCheck:SetRangeAlpha(button, UnitInRange(button.unit, "player")) -- Nope, fall back to interaction :( else -- 2.39.5 From dd8a35857db5368dfbdc33da12515793e24b0525 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 1 Sep 2021 08:16:37 +0200 Subject: [PATCH 024/268] shadowsight register AURA_GAIN --- Modules/ShadowsightTimer.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Modules/ShadowsightTimer.lua b/Modules/ShadowsightTimer.lua index 1a3d542..edd280e 100644 --- a/Modules/ShadowsightTimer.lua +++ b/Modules/ShadowsightTimer.lua @@ -21,6 +21,7 @@ end function ShadowsightTimer:Initialize() self.locale = Gladdy:GetArenaTimer() self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("AURA_GAIN") self:CreateTimerFrame() end @@ -32,6 +33,12 @@ function ShadowsightTimer:JOINED_ARENA() self.timerFrame:Show() end +function ShadowsightTimer:AURA_GAIN(unit, auraType, spellID) + if (spellID == 34709) then + --TODO reset timer after 15s + end +end + function ShadowsightTimer:CHAT_MSG_BG_SYSTEM_NEUTRAL(msg) for k,v in pairs(self.locale) do if str_find(msg, v) then -- 2.39.5 From 776464f5517e038a973f1ee563c7c4806cd99fe6 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 3 Sep 2021 01:38:46 +0200 Subject: [PATCH 025/268] add Aura Flee - Skull of Impending Doom --- Constants.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Constants.lua b/Constants.lua index bd91dbe..2b04c1d 100644 --- a/Constants.lua +++ b/Constants.lua @@ -734,6 +734,14 @@ local importantAuras = { priority = 15, spellID = 30457, }, + -- Flee (Skull of impending Doom) -- 5024 + [GetSpellInfo(5024)] = { + track = AURA_TYPE_BUFF, + duration = 8, + priority = 15, + spellID = 5024, + altName = select(1, GetSpellInfo(5024)) .. " - " .. select(1, GetItemInfo(4984)), + }, } function Gladdy:GetImportantAuras() return importantAuras -- 2.39.5 From 75d4dfe9febfb76160533157abccff9c3ed5300f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 3 Sep 2021 01:39:21 +0200 Subject: [PATCH 026/268] adjust countdown numbers --- Modules/ArenaCountDown.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index 274721c..38b6076 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -30,13 +30,13 @@ function ACDFrame:Initialize() local ACDNumTens = ACDNumFrame:CreateTexture("ACDNumTens", "HIGH") ACDNumTens:SetWidth(256) ACDNumTens:SetHeight(256) - ACDNumTens:SetPoint("CENTER", ACDNumFrame, "CENTER", -48, 0) + ACDNumTens:SetPoint("CENTER", ACDNumFrame, "CENTER", -50, 0) self.ACDNumTens = ACDNumTens local ACDNumOnes = ACDNumFrame:CreateTexture("ACDNumOnes", "HIGH") ACDNumOnes:SetWidth(256) ACDNumOnes:SetHeight(256) - ACDNumOnes:SetPoint("CENTER", ACDNumFrame, "CENTER", 48, 0) + ACDNumOnes:SetPoint("CENTER", ACDNumFrame, "CENTER", 50, 0) self.ACDNumOnes = ACDNumOnes local ACDNumOne = ACDNumFrame:CreateTexture("ACDNumOne", "HIGH") -- 2.39.5 From 6b4c35c66b494c6f0418b88461b1023b364e4704 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 3 Sep 2021 01:42:35 +0200 Subject: [PATCH 027/268] error handling for font/statusbar/border not found added --- Gladdy.lua | 22 ++++++++++++++++++++++ Modules/Auras.lua | 9 +++++---- Modules/BuffsDebuffs.lua | 4 ++-- Modules/Castbar.lua | 21 ++++++++++----------- Modules/Cooldowns.lua | 12 ++++++------ Modules/Diminishings.lua | 8 ++++---- Modules/Healthbar.lua | 28 ++++++++++++++-------------- Modules/Highlight.lua | 12 ++++++------ Modules/Pets.lua | 28 ++++++++++++++-------------- Modules/Powerbar.lua | 20 ++++++++++---------- Modules/Racial.lua | 12 ++++++------ Modules/TotemPlates.lua | 6 +++--- Modules/Trinket.lua | 12 ++++++------ 13 files changed, 108 insertions(+), 86 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 1957227..9926240 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -5,6 +5,7 @@ local select = select local pairs = pairs local tinsert = table.insert local tsort = table.sort +local GetTime = GetTime local CreateFrame = CreateFrame local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME local IsAddOnLoaded = IsAddOnLoaded @@ -474,4 +475,25 @@ function Gladdy:BlizzArenaSetAlpha(alpha) ArenaEnemyFrame5:SetAlpha(alpha) ArenaEnemyFrame5PetFrame:SetAlpha(alpha) end +end + +--------------------------- + +-- FONT/STATUSBAR/BORDER + +--------------------------- + +local defaults = {["statusbar"] = "Smooth", ["border"] = "Gladdy Tooltip round", ["font"] = "DorisPP"} + +local lastWarning = {} +function Gladdy:SMFetch(lsmType, key, dbEntry) + local smMediaType = self.LSM:Fetch(lsmType, key) + if (smMediaType == nil and key ~= "None") then + if not lastWarning[dbEntry] or GetTime() - lastWarning[dbEntry] > 120 then + lastWarning[dbEntry] = GetTime() + Gladdy:Warn("Could not find", "\"" .. lsmType .. "\"", key, "for", "\"" .. dbEntry .. "\"", "- setting it to", "\"" .. defaults[lsmType] .. "\"") + end + return self.LSM:Fetch(lsmType, defaults[lsmType]) + end + return smMediaType end \ No newline at end of file diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 29ff0f1..eed66a6 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -88,7 +88,7 @@ function Auras:CreateFrame(unit) auraFrame:SetAllPoints(classIcon) auraFrame.text = auraFrame.cooldownFrame:CreateFontString(nil, "OVERLAY") - auraFrame.text:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.auraFont), 10, "OUTLINE") + auraFrame.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), 10, "OUTLINE") auraFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) --auraFrame.text:SetShadowOffset(1, -1) --auraFrame.text:SetShadowColor(0, 0, 0, 1) @@ -152,7 +152,7 @@ function Auras:CreateInterrupt(unit) interruptFrame:SetAllPoints(classIcon) interruptFrame.text = interruptFrame.cooldownFrame:CreateFontString(nil, "OVERLAY") - interruptFrame.text:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.auraFont), 10, "OUTLINE") + interruptFrame.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), 10, "OUTLINE") interruptFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) --auraFrame.text:SetShadowOffset(1, -1) --auraFrame.text:SetShadowColor(0, 0, 0, 1) @@ -205,7 +205,7 @@ function Auras:UpdateFrame(unit) auraFrame.cooldown:SetPoint("CENTER", auraFrame, "CENTER") auraFrame.cooldown:SetAlpha(Gladdy.db.auraCooldownAlpha) - auraFrame.text:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.auraFont), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") + auraFrame.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") auraFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) auraFrame.icon.overlay:SetTexture(Gladdy.db.auraBorderStyle) @@ -243,7 +243,7 @@ function Auras:UpdateInterruptFrame(unit) interruptFrame.cooldown:SetPoint("CENTER", interruptFrame, "CENTER") interruptFrame.cooldown:SetAlpha(Gladdy.db.auraCooldownAlpha) - interruptFrame.text:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.auraFont), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") + interruptFrame.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") interruptFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) interruptFrame.icon.overlay:SetTexture(Gladdy.db.auraBorderStyle) @@ -662,6 +662,7 @@ function Auras:GetAuraOptions(auraType) or (Gladdy:GetImportantAuras()[select(1, GetSpellInfo(27010)) .. " " .. select(1, GetSpellInfo(16689))] and Gladdy:GetImportantAuras()[select(1, GetSpellInfo(27010)) .. " " .. select(1, GetSpellInfo(16689))].spellID == k and Gladdy:GetImportantAuras()[select(1, GetSpellInfo(27010)) .. " " .. select(1, GetSpellInfo(16689))].altName) + or Gladdy:GetImportantAuras()[GetSpellInfo(k)].altName or GetSpellInfo(k), order = i+2, icon = Gladdy:GetImportantAuras()[GetSpellInfo(k)] and Gladdy:GetImportantAuras()[GetSpellInfo(k)].texture or select(3, GetSpellInfo(k)), diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index a1f7fa7..4f0c6e8 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -264,9 +264,9 @@ local function styleIcon(aura, auraType) aura.border:SetTexture(Gladdy.db.buffsBorderStyle) aura.border:SetVertexColor(spellSchoolToOptionValue(aura.spellSchool)) - aura.cooldown:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.buffsFont), (Gladdy.db.buffsIconSize/2 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") + aura.cooldown:SetFont(Gladdy:SMFetch("font", Gladdy.db.buffsFont, "buffsFont"), (Gladdy.db.buffsIconSize/2 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") aura.cooldown:SetTextColor(Gladdy.db.buffsFontColor.r, Gladdy.db.buffsFontColor.g, Gladdy.db.buffsFontColor.b, Gladdy.db.buffsFontColor.a) - aura.stacks:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.buffsFont), (Gladdy.db.buffsIconSize/3 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") + aura.stacks:SetFont(Gladdy:SMFetch("font", Gladdy.db.buffsFont, "buffsFont"), (Gladdy.db.buffsIconSize/3 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") aura.stacks:SetTextColor(Gladdy.db.buffsFontColor.r, Gladdy.db.buffsFontColor.g, Gladdy.db.buffsFontColor.b, Gladdy.db.buffsFontColor.a) end diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 847d6d6..96c4c98 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -61,13 +61,13 @@ function Castbar:CreateFrame(unit) castBar:EnableMouse(false) castBar.unit = unit - castBar:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.castBarBorderStyle), + castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.castBarBorderStyle, "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) castBar:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) castBar:SetFrameLevel(1) castBar.bar = CreateFrame("StatusBar", nil, castBar) - castBar.bar:SetStatusBarTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.castBarTexture)) + castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.castBarTexture, "castBarTexture")) castBar.bar:SetStatusBarColor(Gladdy.db.castBarColor.r, Gladdy.db.castBarColor.g, Gladdy.db.castBarColor.b, Gladdy.db.castBarColor.a) castBar.bar:SetMinMaxValues(0, 100) castBar.bar:SetFrameLevel(0) @@ -81,7 +81,7 @@ function Castbar:CreateFrame(unit) castBar.bg = castBar.bar:CreateTexture(nil, "BACKGROUND") castBar.bg:SetAlpha(1) - castBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.castBarTexture)) + castBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.castBarTexture, "castBarTexture")) castBar.bg:SetVertexColor(Gladdy.db.castBarBgColor.r, Gladdy.db.castBarBgColor.g, Gladdy.db.castBarBgColor.b, Gladdy.db.castBarBgColor.a) castBar.bg:SetAllPoints(castBar.bar) @@ -101,7 +101,7 @@ function Castbar:CreateFrame(unit) end castBar.spellText = castBar:CreateFontString(nil, "LOW") - castBar.spellText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.auraFont), Gladdy.db.castBarFontSize) + castBar.spellText:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), Gladdy.db.castBarFontSize) castBar.spellText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) castBar.spellText:SetShadowOffset(1, -1) castBar.spellText:SetShadowColor(0, 0, 0, 1) @@ -109,7 +109,7 @@ function Castbar:CreateFrame(unit) castBar.spellText:SetPoint("LEFT", 7, 0) -- Text of the spell castBar.timeText = castBar:CreateFontString(nil, "LOW") - castBar.timeText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.auraFont), Gladdy.db.castBarFontSize) + castBar.timeText:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), Gladdy.db.castBarFontSize) castBar.timeText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) castBar.timeText:SetShadowOffset(1, -1) castBar.timeText:SetShadowColor(0, 0, 0, 1) @@ -122,7 +122,6 @@ function Castbar:CreateFrame(unit) end function Castbar:UpdateFrame(unit) - local button = Gladdy.buttons[unit] local castBar = self.frames[unit] if (not castBar) then return @@ -130,17 +129,17 @@ function Castbar:UpdateFrame(unit) castBar:SetWidth(Gladdy.db.castBarWidth) castBar:SetHeight(Gladdy.db.castBarHeight) - castBar:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.castBarBorderStyle), + castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.castBarBorderStyle, "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) castBar:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) - castBar.bar:SetStatusBarTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.castBarTexture)) + castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.castBarTexture, "castBarTexture")) castBar.bar:ClearAllPoints() castBar.bar:SetStatusBarColor(Gladdy.db.castBarColor.r, Gladdy.db.castBarColor.g, Gladdy.db.castBarColor.b, Gladdy.db.castBarColor.a) castBar.bar:SetPoint("TOPLEFT", castBar, "TOPLEFT", (Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset)) castBar.bar:SetPoint("BOTTOMRIGHT", castBar, "BOTTOMRIGHT", -(Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset)) - castBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.castBarTexture)) + castBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.castBarTexture, "castBarTexture")) castBar.bg:SetVertexColor(Gladdy.db.castBarBgColor.r, Gladdy.db.castBarBgColor.g, Gladdy.db.castBarBgColor.b, Gladdy.db.castBarBgColor.a) if Gladdy.db.castBarSparkEnabled then @@ -184,10 +183,10 @@ function Castbar:UpdateFrame(unit) end end - castBar.spellText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.castBarFont), Gladdy.db.castBarFontSize) + castBar.spellText:SetFont(Gladdy:SMFetch("font", Gladdy.db.castBarFont, "castBarFont"), Gladdy.db.castBarFontSize) castBar.spellText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) - castBar.timeText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.castBarFont), Gladdy.db.castBarFontSize) + castBar.timeText:SetFont(Gladdy:SMFetch("font", Gladdy.db.castBarFont, "castBarFont"), Gladdy.db.castBarFontSize) castBar.timeText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) castBar.icon.texture.overlay:SetTexture(Gladdy.db.castBarIconStyle) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 12f14aa..622dd5b 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -120,7 +120,7 @@ function Cooldowns:CreateFrame(unit) icon.border:SetVertexColor(Gladdy.db.cooldownBorderColor.r, Gladdy.db.cooldownBorderColor.g, Gladdy.db.cooldownBorderColor.b, Gladdy.db.cooldownBorderColor.a) icon.cooldownFont = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") - icon.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.cooldownFont), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") + icon.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) icon.cooldownFont:SetAllPoints(icon) @@ -172,7 +172,7 @@ function Cooldowns:UpdateFrame(unit) local icon = button.spellCooldownFrame["icon" .. j] icon:SetHeight(Gladdy.db.cooldownSize) icon:SetWidth(Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor) - icon.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.cooldownFont), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") + icon.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) icon:ClearAllPoints() if (Gladdy.db.cooldownXPos == "RIGHT") then @@ -220,7 +220,7 @@ function Cooldowns:UpdateFrame(unit) icon.cooldown:SetPoint("CENTER", icon, "CENTER") icon.cooldown:SetAlpha(Gladdy.db.cooldownCooldownAlpha) - icon.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.cooldownFont), (icon:GetWidth()/2 - 1) * Gladdy.db.cooldownFontScale, "OUTLINE") + icon.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), (icon:GetWidth()/2 - 1) * Gladdy.db.cooldownFontScale, "OUTLINE") icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) icon.border:SetTexture(Gladdy.db.cooldownBorderStyle) @@ -294,11 +294,11 @@ function Cooldowns:CooldownStart(button, spellId, duration) self.timeLeft = self.timeLeft - elapsed local timeLeft = ceil(self.timeLeft) if timeLeft >= 540 then - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.cooldownFont), Gladdy.db.cooldownSize / 3.1 * Gladdy.db.cooldownFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 3.1 * Gladdy.db.cooldownFontScale, "OUTLINE") elseif timeLeft < 540 and timeLeft >= 60 then - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.cooldownFont), Gladdy.db.cooldownSize / 2.15 * Gladdy.db.cooldownFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 2.15 * Gladdy.db.cooldownFontScale, "OUTLINE") elseif timeLeft < 60 and timeLeft > 0 then - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.cooldownFont), Gladdy.db.cooldownSize / 2.15 * Gladdy.db.cooldownFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 2.15 * Gladdy.db.cooldownFontScale, "OUTLINE") end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 0) if (self.timeLeft <= 0) then diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index f926077..9cb5e9c 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -116,7 +116,7 @@ function Diminishings:CreateFrame(unit) icon.text = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") icon.text:SetDrawLayer("OVERLAY") - icon.text:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.drFont), 10, "OUTLINE") + icon.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.drFont, "drFont"), 10, "OUTLINE") icon.text:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) icon.text:SetShadowOffset(1, -1) icon.text:SetShadowColor(0, 0, 0, 1) @@ -125,7 +125,7 @@ function Diminishings:CreateFrame(unit) icon.timeText = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") icon.timeText:SetDrawLayer("OVERLAY") - icon.timeText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.drFont), 10, "OUTLINE") + icon.timeText:SetFont(Gladdy:SMFetch("font", Gladdy.db.drFont, "drFont"), 10, "OUTLINE") icon.timeText:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) icon.timeText:SetShadowOffset(1, -1) icon.timeText:SetShadowColor(0, 0, 0, 1) @@ -184,9 +184,9 @@ function Diminishings:UpdateFrame(unit) icon:SetWidth(Gladdy.db.drIconSize * Gladdy.db.drWidthFactor) icon:SetHeight(Gladdy.db.drIconSize) - icon.text:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.drFont), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") + icon.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.drFont, "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") icon.text:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) - icon.timeText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.drFont), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") + icon.timeText:SetFont(Gladdy:SMFetch("font", Gladdy.db.drFont, "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") icon.timeText:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) icon.cooldown:SetWidth(icon:GetWidth() - icon:GetWidth()/16) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 870bee4..ea3f95c 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -39,18 +39,18 @@ function Healthbar:CreateFrame(unit) local healthBar = CreateFrame("Frame", nil, Gladdy.buttons[unit], BackdropTemplateMixin and "BackdropTemplate") healthBar:EnableMouse(false) - healthBar:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.healthBarBorderStyle), + healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.healthBarBorderStyle, "healthBarBorderStyle"), edgeSize = Gladdy.db.healthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.healthBarBorderColor.r, Gladdy.db.healthBarBorderColor.g, Gladdy.db.healthBarBorderColor.b, Gladdy.db.healthBarBorderColor.a) healthBar:SetFrameLevel(1) healthBar.hp = CreateFrame("StatusBar", nil, healthBar) - healthBar.hp:SetStatusBarTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.healthBarTexture)) + healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.healthBarTexture, "healthBarTexture")) healthBar.hp:SetMinMaxValues(0, 100) healthBar.hp:SetFrameLevel(0) healthBar.bg = healthBar.hp:CreateTexture(nil, "BACKGROUND") - healthBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.healthBarTexture)) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.healthBarTexture, "healthBarTexture")) healthBar.bg:ClearAllPoints() healthBar.bg:SetAllPoints(healthBar.hp) healthBar.bg:SetAlpha(1) @@ -58,10 +58,10 @@ function Healthbar:CreateFrame(unit) healthBar.nameText = healthBar:CreateFontString(nil, "LOW", "GameFontNormalSmall") if (Gladdy.db.healthBarNameFontSize < 1) then - healthBar.nameText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.healthBarNameFont), 1) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarNameFont, "healthBarNameFont"), 1) healthBar.nameText:Hide() else - healthBar.nameText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.healthBarFont), Gladdy.db.healthBarNameFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), Gladdy.db.healthBarNameFontSize) healthBar.nameText:Show() end healthBar.nameText:SetTextColor(Gladdy.db.healthBarFontColor.r, Gladdy.db.healthBarFontColor.g, Gladdy.db.healthBarFontColor.b, Gladdy.db.healthBarFontColor.a) @@ -72,10 +72,10 @@ function Healthbar:CreateFrame(unit) healthBar.healthText = healthBar:CreateFontString(nil, "LOW") if (Gladdy.db.healthBarHealthFontSize < 1) then - healthBar.healthText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.healthBarFont), 1) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), 1) healthBar.healthText:Hide() else - healthBar.healthText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.healthBarFont), Gladdy.db.healthBarHealthFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), Gladdy.db.healthBarHealthFontSize) healthBar.healthText:Hide() end healthBar.healthText:SetTextColor(Gladdy.db.healthBarFontColor.r, Gladdy.db.healthBarFontColor.g, Gladdy.db.healthBarFontColor.b, Gladdy.db.healthBarFontColor.a) @@ -167,33 +167,33 @@ function Healthbar:UpdateFrame(unit) return end - healthBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.healthBarTexture)) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.healthBarTexture, "healthBarTexture")) healthBar.bg:SetVertexColor(Gladdy.db.healthBarBgColor.r, Gladdy.db.healthBarBgColor.g, Gladdy.db.healthBarBgColor.b, Gladdy.db.healthBarBgColor.a) - healthBar:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.healthBarBorderStyle), + healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.healthBarBorderStyle, "healthBarBorderStyle"), edgeSize = Gladdy.db.healthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.healthBarBorderColor.r, Gladdy.db.healthBarBorderColor.g, Gladdy.db.healthBarBorderColor.b, Gladdy.db.healthBarBorderColor.a) healthBar:ClearAllPoints() healthBar:SetPoint("TOPLEFT", Gladdy.buttons[unit], "TOPLEFT", 0, 0) healthBar:SetPoint("BOTTOMRIGHT", Gladdy.buttons[unit], "BOTTOMRIGHT") - healthBar.hp:SetStatusBarTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.healthBarTexture)) + healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.healthBarTexture, "healthBarTexture")) healthBar.hp:ClearAllPoints() healthBar.hp:SetPoint("TOPLEFT", healthBar, "TOPLEFT", (Gladdy.db.healthBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.healthBarBorderSize/Gladdy.db.statusbarBorderOffset)) healthBar.hp:SetPoint("BOTTOMRIGHT", healthBar, "BOTTOMRIGHT", -(Gladdy.db.healthBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.healthBarBorderSize/Gladdy.db.statusbarBorderOffset)) if (Gladdy.db.healthBarHealthFontSize < 1) then - healthBar.healthText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.healthBarFont), 1) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), 1) healthBar.healthText:Hide() else - healthBar.healthText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.healthBarFont), Gladdy.db.healthBarHealthFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), Gladdy.db.healthBarHealthFontSize) healthBar.healthText:Show() end if (Gladdy.db.healthBarNameFontSize < 1) then - healthBar.nameText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.healthBarNameFont), 1) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarNameFont, "healthBarNameFont"), 1) healthBar.nameText:Hide() else - healthBar.nameText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.healthBarFont), Gladdy.db.healthBarNameFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), Gladdy.db.healthBarNameFontSize) if Gladdy.db.healthName then healthBar.nameText:Show() else diff --git a/Modules/Highlight.lua b/Modules/Highlight.lua index e48a4c2..92f3356 100644 --- a/Modules/Highlight.lua +++ b/Modules/Highlight.lua @@ -55,17 +55,17 @@ function Highlight:CreateFrame(unit) local healthBar = Gladdy.modules["Health Bar"].frames[unit] local targetBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") - targetBorder:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.highlightBorderStyle), edgeSize = Gladdy.db.highlightBorderSize }) + targetBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) --targetBorder:SetFrameStrata("MEDIUM") targetBorder:Hide() local focusBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") - focusBorder:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.highlightBorderStyle), edgeSize = Gladdy.db.highlightBorderSize }) + focusBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) --focusBorder:SetFrameStrata("MEDIUM") focusBorder:Hide() local leaderBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") - leaderBorder:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.highlightBorderStyle), edgeSize = Gladdy.db.highlightBorderSize }) + leaderBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) --leaderBorder:SetFrameStrata("MEDIUM") leaderBorder:Hide() @@ -106,7 +106,7 @@ function Highlight:UpdateFrame(unit) button.targetBorder:SetPoint("TOP", button.healthBar, "TOP", 0, (Gladdy.db.highlightInset and 0 or borderSize)) end - button.targetBorder:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.highlightBorderStyle), edgeSize = borderSize }) + button.targetBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = borderSize }) button.targetBorder:SetBackdropBorderColor(Gladdy.db.targetBorderColor.r, Gladdy.db.targetBorderColor.g, Gladdy.db.targetBorderColor.b, Gladdy.db.targetBorderColor.a) button.focusBorder:SetWidth(width) @@ -119,7 +119,7 @@ function Highlight:UpdateFrame(unit) button.focusBorder:SetPoint("TOP", button.healthBar, "TOP", 0, (Gladdy.db.highlightInset and 0 or borderSize)) end - button.focusBorder:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.highlightBorderStyle), edgeSize = borderSize }) + button.focusBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = borderSize }) button.focusBorder:SetBackdropBorderColor(Gladdy.db.focusBorderColor.r, Gladdy.db.focusBorderColor.g, Gladdy.db.focusBorderColor.b, Gladdy.db.focusBorderColor.a) button.leaderBorder:SetWidth(width) @@ -132,7 +132,7 @@ function Highlight:UpdateFrame(unit) button.leaderBorder:SetPoint("TOP", button.healthBar, "TOP", 0, (Gladdy.db.highlightInset and 0 or borderSize)) end - button.leaderBorder:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.highlightBorderStyle), edgeSize = borderSize }) + button.leaderBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = borderSize }) button.leaderBorder:SetBackdropBorderColor(Gladdy.db.leaderBorderColor.r, Gladdy.db.leaderBorderColor.g, Gladdy.db.leaderBorderColor.b, Gladdy.db.leaderBorderColor.a) if Gladdy.frame.testing then Highlight:Test(unit) diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 3994492..2eabfab 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -149,7 +149,7 @@ function Pets:CreateFrame(unitId) button.secure = secure local healthBar = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") - healthBar:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.petHealthBarBorderStyle), + healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.petHealthBarBorderStyle, "petHealthBarBorderStyle"), edgeSize = Gladdy.db.petHealthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) healthBar:SetFrameLevel(1) @@ -167,14 +167,14 @@ function Pets:CreateFrame(unitId) healthBar.hp = CreateFrame("StatusBar", nil, healthBar) - healthBar.hp:SetStatusBarTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.petHealthBarTexture)) + healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.petHealthBarTexture, "petHealthBarTexture")) healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) healthBar.hp:SetMinMaxValues(0, 100) healthBar.hp:SetFrameLevel(0) healthBar.hp:SetAllPoints(healthBar) healthBar.bg = healthBar.hp:CreateTexture(nil, "BACKGROUND") - healthBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.petHealthBarTexture)) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.petHealthBarTexture, "petHealthBarTexture")) healthBar.bg:ClearAllPoints() healthBar.bg:SetAllPoints(healthBar.hp) healthBar.bg:SetAlpha(1) @@ -182,10 +182,10 @@ function Pets:CreateFrame(unitId) healthBar.nameText = healthBar:CreateFontString(nil, "LOW", "GameFontNormalSmall") if (Gladdy.db.petHealthBarFontSize < 1) then - healthBar.nameText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.petHealthBarFont), 1) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), 1) healthBar.nameText:Hide() else - healthBar.nameText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.petHealthBarFont), Gladdy.db.petHealthBarFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.nameText:Show() end healthBar.nameText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) @@ -196,10 +196,10 @@ function Pets:CreateFrame(unitId) healthBar.healthText = healthBar:CreateFontString(nil, "LOW") if (Gladdy.db.petHealthBarFontSize < 1) then - healthBar.healthText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.petHealthBarFont), 1) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), 1) healthBar.healthText:Hide() else - healthBar.healthText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.petHealthBarFont), Gladdy.db.petHealthBarFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.healthText:Hide() end healthBar.healthText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) @@ -263,28 +263,28 @@ function Pets:UpdateFrame(unitId) healthBar.portrait.border:SetTexture(Gladdy.db.petPortraitBorderStyle) healthBar.portrait.border:SetVertexColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) - healthBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.petHealthBarTexture)) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.petHealthBarTexture, "petHealthBarTexture")) healthBar.bg:SetVertexColor(Gladdy.db.petHealthBarBgColor.r, Gladdy.db.petHealthBarBgColor.g, Gladdy.db.petHealthBarBgColor.b, Gladdy.db.petHealthBarBgColor.a) - healthBar:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.petHealthBarBorderStyle), + healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.petHealthBarBorderStyle, "petHealthBarBorderStyle"), edgeSize = Gladdy.db.petHealthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) - healthBar.hp:SetStatusBarTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.petHealthBarTexture)) + healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.petHealthBarTexture, "petHealthBarTexture")) healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) healthBar.hp:ClearAllPoints() healthBar.hp:SetPoint("TOPLEFT", healthBar, "TOPLEFT", (Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset)) healthBar.hp:SetPoint("BOTTOMRIGHT", healthBar, "BOTTOMRIGHT", -(Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset)) if (Gladdy.db.petHealthBarFontSize < 1) then - healthBar.nameText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.petHealthBarFont), 1) - healthBar.healthText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.petHealthBarFont), 1) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), 1) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), 1) healthBar.nameText:Hide() healthBar.healthText:Hide() else - healthBar.nameText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.petHealthBarFont), Gladdy.db.petHealthBarFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.nameText:Show() - healthBar.healthText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.petHealthBarFont), Gladdy.db.petHealthBarFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.healthText:Show() end healthBar.nameText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) diff --git a/Modules/Powerbar.lua b/Modules/Powerbar.lua index 01b608c..686a1b6 100644 --- a/Modules/Powerbar.lua +++ b/Modules/Powerbar.lua @@ -38,24 +38,24 @@ function Powerbar:CreateFrame(unit) local powerBar = CreateFrame("Frame", nil, Gladdy.buttons[unit], BackdropTemplateMixin and "BackdropTemplate") powerBar:EnableMouse(false) - powerBar:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.powerBarBorderStyle), + powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.powerBarBorderStyle, "powerBarBorderStyle"), edgeSize = Gladdy.db.powerBarBorderSize }) powerBar:SetBackdropBorderColor(Gladdy.db.powerBarBorderColor.r, Gladdy.db.powerBarBorderColor.g, Gladdy.db.powerBarBorderColor.b, Gladdy.db.powerBarBorderColor.a) powerBar:SetFrameLevel(1) powerBar.energy = CreateFrame("StatusBar", nil, powerBar) - powerBar.energy:SetStatusBarTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.powerBarTexture)) + powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.powerBarTexture, "powerBarTexture")) powerBar.energy:SetMinMaxValues(0, 100) powerBar.energy:SetFrameLevel(0) powerBar.bg = powerBar.energy:CreateTexture(nil, "BACKGROUND") - powerBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.powerBarTexture)) + powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.powerBarTexture, "powerBarTexture")) powerBar.bg:ClearAllPoints() powerBar.bg:SetAllPoints(powerBar.energy) powerBar.bg:SetVertexColor(Gladdy.db.powerBarBgColor.r, Gladdy.db.powerBarBgColor.g, Gladdy.db.powerBarBgColor.b, Gladdy.db.powerBarBgColor.a) powerBar.raceText = powerBar:CreateFontString(nil, "LOW") - powerBar.raceText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.powerBarFont), Gladdy.db.powerBarFontSize) + powerBar.raceText:SetFont(Gladdy:SMFetch("font", Gladdy.db.powerBarFont, "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.raceText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) powerBar.raceText:SetShadowOffset(1, -1) powerBar.raceText:SetShadowColor(0, 0, 0, 1) @@ -63,7 +63,7 @@ function Powerbar:CreateFrame(unit) powerBar.raceText:SetPoint("LEFT", 5, 1) powerBar.powerText = powerBar:CreateFontString(nil, "LOW") - powerBar.powerText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.powerBarFont), Gladdy.db.powerBarFontSize) + powerBar.powerText:SetFont(Gladdy:SMFetch("font", Gladdy.db.powerBarFont, "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.powerText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) powerBar.powerText:SetShadowOffset(1, -1) powerBar.powerText:SetShadowColor(0, 0, 0, 1) @@ -149,7 +149,7 @@ function Powerbar:UpdateFrame(unit) else powerBar:Show() end - powerBar.bg:SetTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.powerBarTexture)) + powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.powerBarTexture, "powerBarTexture")) powerBar.bg:SetVertexColor(Gladdy.db.powerBarBgColor.r, Gladdy.db.powerBarBgColor.g, Gladdy.db.powerBarBgColor.b, Gladdy.db.powerBarBgColor.a) powerBar:SetWidth(healthBar:GetWidth()) @@ -158,18 +158,18 @@ function Powerbar:UpdateFrame(unit) powerBar:ClearAllPoints() powerBar:SetPoint("TOPLEFT", healthBar, "BOTTOMLEFT", 0, -1) - powerBar:SetBackdrop({ edgeFile = Gladdy.LSM:Fetch("border", Gladdy.db.powerBarBorderStyle), + powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.powerBarBorderStyle, "powerBarBorderStyle"), edgeSize = Gladdy.db.powerBarBorderSize }) powerBar:SetBackdropBorderColor(Gladdy.db.powerBarBorderColor.r, Gladdy.db.powerBarBorderColor.g, Gladdy.db.powerBarBorderColor.b, Gladdy.db.powerBarBorderColor.a) - powerBar.energy:SetStatusBarTexture(Gladdy.LSM:Fetch("statusbar", Gladdy.db.powerBarTexture)) + powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.powerBarTexture, "powerBarTexture")) powerBar.energy:ClearAllPoints() powerBar.energy:SetPoint("TOPLEFT", powerBar, "TOPLEFT", (Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset)) powerBar.energy:SetPoint("BOTTOMRIGHT", powerBar, "BOTTOMRIGHT", -(Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset)) - powerBar.raceText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.powerBarFont), Gladdy.db.powerBarFontSize) + powerBar.raceText:SetFont(Gladdy:SMFetch("font", Gladdy.db.powerBarFont, "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.raceText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) - powerBar.powerText:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.powerBarFont), Gladdy.db.powerBarFontSize) + powerBar.powerText:SetFont(Gladdy:SMFetch("font", Gladdy.db.powerBarFont, "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.powerText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) end diff --git a/Modules/Racial.lua b/Modules/Racial.lua index caf37b7..ad62474 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -44,19 +44,19 @@ local function iconTimer(self,elapsed) if timeLeft >= 60 then self.cooldownFont:SetTextColor(1, 1, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.racialFont), (self:GetWidth()/2 - 0.15* self:GetWidth()) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 0.15* self:GetWidth()) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 60 and timeLeft >= 30 then self.cooldownFont:SetTextColor(1, 1, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.racialFont), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 30 and timeLeft >= 11 then self.cooldownFont:SetTextColor(1, 0.7, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.racialFont), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 10 and timeLeft >= 5 then self.cooldownFont:SetTextColor(1, 0.7, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.racialFont), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 5 and timeLeft > 0 then self.cooldownFont:SetTextColor(1, 0, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.racialFont), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 10, true) end @@ -80,7 +80,7 @@ function Racial:CreateFrame(unit) racial.cooldownFrame:SetPoint("BOTTOMRIGHT", racial, "BOTTOMRIGHT") racial.cooldownFont = racial.cooldownFrame:CreateFontString(nil, "OVERLAY") - racial.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.racialFont), 20, "OUTLINE") + racial.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), 20, "OUTLINE") --trinket.cooldownFont:SetAllPoints(trinket.cooldown) racial.cooldownFont:SetJustifyH("CENTER") racial.cooldownFont:SetPoint("CENTER") diff --git a/Modules/TotemPlates.lua b/Modules/TotemPlates.lua index 77a8f3e..ad72893 100644 --- a/Modules/TotemPlates.lua +++ b/Modules/TotemPlates.lua @@ -269,7 +269,7 @@ function TotemPlates:UpdateFrameOnce() Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].color.b, Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].color.a) nameplate.gladdyTotemFrame.totemName:SetPoint("TOP", nameplate.gladdyTotemFrame, "BOTTOM", Gladdy.db.npTremorFontXOffset, Gladdy.db.npTremorFontYOffset) - nameplate.gladdyTotemFrame.totemName:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.npTremorFont), Gladdy.db.npTremorFontSize, "OUTLINE") + nameplate.gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", Gladdy.db.npTremorFont, "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") nameplate.gladdyTotemFrame.totemName:SetText(Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].customText or "") self:SetTotemAlpha(nameplate.gladdyTotemFrame, k) @@ -300,7 +300,7 @@ function TotemPlates:UpdateFrameOnce() gladdyTotemFrame:SetWidth(Gladdy.db.npTotemPlatesSize * Gladdy.db.npTotemPlatesWidthFactor) gladdyTotemFrame:SetHeight(Gladdy.db.npTotemPlatesSize) gladdyTotemFrame.totemBorder:SetTexture(Gladdy.db.npTotemPlatesBorderStyle) - gladdyTotemFrame.totemName:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.npTremorFont), Gladdy.db.npTremorFontSize, "OUTLINE") + gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", Gladdy.db.npTremorFont, "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") gladdyTotemFrame.totemName:SetPoint("TOP", gladdyTotemFrame, "BOTTOM", Gladdy.db.npTremorFontXOffset, Gladdy.db.npTremorFontYOffset) end end @@ -327,7 +327,7 @@ function TotemPlates:CreateTotemFrame(nameplate) nameplate.gladdyTotemFrame.totemBorder:SetPoint("BOTTOMRIGHT", nameplate.gladdyTotemFrame, "BOTTOMRIGHT") nameplate.gladdyTotemFrame.totemBorder:SetTexture(Gladdy.db.npTotemPlatesBorderStyle) nameplate.gladdyTotemFrame.totemName = nameplate.gladdyTotemFrame:CreateFontString(nil, "OVERLAY") - nameplate.gladdyTotemFrame.totemName:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.npTremorFont), Gladdy.db.npTremorFontSize, "OUTLINE") + nameplate.gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", Gladdy.db.npTremorFont, "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") nameplate.gladdyTotemFrame.totemName:SetPoint("TOP", nameplate.gladdyTotemFrame, "BOTTOM", Gladdy.db.npTremorFontXOffset, Gladdy.db.npTremorFontYOffset) nameplate.gladdyTotemFrame.selectionHighlight = nameplate.gladdyTotemFrame:CreateTexture(nil, "OVERLAY") nameplate.gladdyTotemFrame.selectionHighlight:SetTexture("Interface/TargetingFrame/UI-TargetingFrame-BarFill") diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 28e24c1..db940bd 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -40,19 +40,19 @@ local function iconTimer(self, elapsed) if timeLeft >= 60 then self.cooldownFont:SetTextColor(1, 1, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.trinketFont), (self:GetWidth()/2 - 0.15*self:GetWidth()) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 0.15*self:GetWidth()) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 60 and timeLeft >= 30 then self.cooldownFont:SetTextColor(1, 1, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.trinketFont), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 30 and timeLeft >= 11 then self.cooldownFont:SetTextColor(1, 0.7, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.trinketFont), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft <= 10 and timeLeft >= 5 then self.cooldownFont:SetTextColor(1, 0.7, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.trinketFont), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 5 and timeLeft > 0 then self.cooldownFont:SetTextColor(1, 0, 0) - self.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.trinketFont), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 10, true) end @@ -76,7 +76,7 @@ function Trinket:CreateFrame(unit) trinket.cooldownFrame:SetPoint("BOTTOMRIGHT", trinket, "BOTTOMRIGHT") trinket.cooldownFont = trinket.cooldownFrame:CreateFontString(nil, "OVERLAY") - trinket.cooldownFont:SetFont(Gladdy.LSM:Fetch("font", Gladdy.db.trinketFont), 20, "OUTLINE") + trinket.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), 20, "OUTLINE") --trinket.cooldownFont:SetAllPoints(trinket.cooldown) trinket.cooldownFont:SetJustifyH("CENTER") trinket.cooldownFont:SetPoint("CENTER") -- 2.39.5 From 7108598603ef3c69807aa5a3f1b6ea234b6520a4 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 3 Sep 2021 01:56:10 +0200 Subject: [PATCH 028/268] update Klimp profile --- ImportStrings.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ImportStrings.lua b/ImportStrings.lua index 091a8af..d04bdce 100644 --- a/ImportStrings.lua +++ b/ImportStrings.lua @@ -1,7 +1,7 @@ local Gladdy = LibStub("Gladdy") function Gladdy:GetKlimpProfile() - return "4XzT8KTCBJRSFm3NJlqacqWhTtIsCDtC81YPMZu1uAcLeTfprl(qsDZ48q(2p9cajiPKIywErIIeDJEd9cqtnlA29ZMUS8QDLlZlF5U17kXBKn7MOztNtF(i9zj(z9SPvRYwU7lvfpUQ((In5L3LV(2DfBRHHC)hUfGz)dpuDf(XLRFAfJN))8YQIDB)7nz)7DL)929BO7UOyAXxZNDJuaxNvvFv2rPcbrfcIkeiv80UVKxcamz326WHlomr7q))6dazLxdtPkAiN8VMnXie6irIn2iKrrYOzp8cnmYNYRFBE266vUzC20xTRSO6wGDlZwuKT(L72TgW12wwUmB7J5VCv(IpFFzX2pdt6C)GzMCA9ZRZNn96T15LpKTi)VUC5YpST6VEZ6SLlF(VUEt2J5v)fp2)UC3(TlZx(3Zx)uOeUHFeOk8vfvzZxN)YIYfaMN3kuFSJe6I4dlsRz6CiwC8MNhRqejtKs1SRMnfKwPj4fQOuLMVWyIOlew3yKwrkDHo2sdoksj4bhhrJ1KyO7BmwAK2uRdurmFrQoHbnX6UqehZOa0A8eBT0DIuUHOSQeh0kRXnMyjEHwgZZOWMk4PoYDrQwX4nwXad3XYtDuedKnrq3XkySHKjDHmsLYZJus0Imf4jMOszyaSjy8MWprjbXctlcdrcsJMKksrQJHs0mTjKj8qLYuEMtLgNIqX4xbCnl)JmS0g4eM1KsBK0XSEQYPAuI4iEUIvSkrASSUagSLN04iRMP8uPJmItKUh50kWYggHkPGMIyDSYn40egCR2qqzCcnGVzjHrRjIWACADBCAktmgdtmsKtQDRcUEXUT3cRxk26SLPfyVElAbVenEZ2xMrlXk3)e7OOY)uazR8lQVjBtoUWMDibYOPBF6(D15BUDDwDo7j7Y1Fj75Q7ZkFmVMrorctxT7lxcZYRYPFI3)yUiLoxKlk(JIL1RMKTOEh5HA6d7wSV6CC(rEZyU82DvZME31V5T37ChIuYDGNKoC295)t9(sWrZ7l2wSjBDrvn6RGy2fzRZPjX7(Fu(KEZ6DvvnUn6ZrRaUFnkbAeuE)heD)UxpbzXY8TzVe8TvJpWfnqB8U4ALhVp7XIfhiUK4cd7a7cjkyA4A2BDxnARBtpL8MYDF5vfL5lQHGtEAYhzjWiArX5OAebbA(tVJ5xOWH0DEU6d3F)hEpzIvMVzx)ikOj7aNWqeipoNOJbFIGxeT0ghBbFFqqkLlifjXVr5z3MaeGRLo2LxUDli2zBfCcFhyx8Q8hY2VUgzqtsIa)oVDTYtLfafw)8SBIfOwpBXNbI(1x9XjtqgNdimkqIKkTECGOIta3vhdKiDdinZb5vCuZHwRgjVZr8gfisLbCTpkqa3YrjNdVhkHTNqCDyLcfIEuZIecgECzS6W6XOJlWIeduJu6aJAga2yKY3yyz1X58dojukiJHnGW2JJOsIgPTiyw1bI5Dij5WfiqUUN1kQaUMsMAuufLT1OMevSESSUmwQhlRyvJ1PfK)4XDAD41hs9y9Mgzn6r62IZ48yGihAmYzMocRxoX1rrurM0KJRso4AkPj1owqe64X6MljzKMWrQtew4W6DXyDXZP3pgvcvgWzqvbreKJLX1Yt4H4WRePe6hfiqvCNGtoK5RnzSkeLqEIWihHSWsNg1Safqn6GUqzoNqVFOzXigzQtqu6t4q9WH3avYiJxPujJn2axz)OarQsLhNx0dnws(byev6XLWh2nKwMmYf8CrYJybpxm9iwMGLypMHRgBCNuXyTePI7hherNWT4H8nq7wWieR6e74SpQXBrf(gSDcUI)6VNKhzJu7xJ71B2SFBEhyexKM6QZviBH0nZdkkDIwdveIQqiH8umPCUYWtuOkx75KYIV(Tp9)TpBzzwD23(0933Sbi8EMG4Vg)PkzG5xgVNNuP4l2xvVBdUNdZMI7C43RE5AhAJWDD93aETrdCTmk0EbetIL)OCShYvIKblEhf2pkrpiKZVe0Av9xO(RaTM4b(j)vG2iH(3cE1QbjL9RaTwP8NYq7iOvoSk2rH2l0EZx32KPdTFvgtFhXJc7h1(9NJOpMMZK87WGaQzCWoe9RaV2Obr5gfAVWVdNPno(BqTiP)UNmkuFmb8WeQ)vGwRoQFS1rH2lGidby(IutOnSoTFG(rH8Jh343IOiY(7qXPKPdsF5xbE5Je7NaVxez6yeJ6sBxd5FhlPTd3yJFfOns)loakmWWtwU5OAMUz3U6vh)mOApk5)SZba)syCpcjTMt5RvTop)Pq6DoEotLlYXdnd)rb(9nrkJiLtjSUCDv9(TNdm6ui0bat52LNniwdpnRYk3CoayWAJaa(C15mAjSiahD1IS668YZdgqLIWSSOcfBBR7PEpI4kHYcF5IZzkmrXym3PpKNvEuSFv44TSGfmb6n(2HGhMt4SXkI(GCCfrmDAzL5pbSCgEkqNduPmuqjcpUBB18Y8mWg9mam2jK3NDoJwJNrmkVkZZ)Aou21zzcRTQyeQInpb35SumnMJpVy9UT5NLUriL8YwQ2Toh5PeLmDpe0lubRVVnhqiiTFKoYToRS)bo71o9dYY2(A5fy9LnDEYTUJYK8jbZQRMp)PeIfo3Vi0j741Mh2R1f0kmhXxrOCDwfDk8)CfJw07i7)bejv)N9zLErs4rRg6JeCnuwmFFn5H8gkwC1t5RxJES3MTbMm(89NbUGxw8qrEj(eaGAWcykirYCNHBnpmukEaKmbpo)dJdzloOd9hrH6aO4sAqF7t)pQdJNw0SKpR4LiMIpfMIhdM0Nct6XGjZPWKzmyk5uykzmyYEkmzhdMspfMshdM4DN9yOc30QZgx1HEbChR)ueXuuX3(XBU)13HxTPa8RHBmmTU(pU8U7U(dbpqi1Kl)BV8Dx(QRVP5b8HQdp49x(Mx3Exgl3E31VE69n3vjvjPoS)Up8Y)3MhqB5gC)xD3hV(vTdN2)y4239H38XwCZngeC7PV9Y3FziLGDTeNjvGZUbn8syAwoFluFHOrFpD7IUoTuu0qpKyV(898q67OIMopIK7apCYZQPg3lC5PorzAmulM9DqtYPozp3mnSC6(JH6UTtpKKV3auYKtCQ6r6UkpFOj7SU9m0L(8SThuxYXj4WcF7t3davx803(efLKsmEq7z6JHH9m1R3MV5zIUcAQu2(4Gt3z0gqeMEF2)GXZ4MsY9doT9ED8JVdlB6WhRwi0XXYuJbYhes64HxeNI5eb(eA7ARwC1EpsQfgXRV5By7V5N3JVjWTErUJMSwwOtQou9DRoYcSGEBJM0IFGG7DY3PF719UDl(mN6qN0Qyci2ldW11UomdlwR4YTlwb0ElzJgkbcN22fRFRTrNfq(sFd)DpUqrlW5NBg254r(NQtP7GAV5((9bUib7Dc4BS1NMJh8GHGuMgROX7)owQJWlsfkAGyXkwcbe(OojbHlcRxyU7eUqegPOH5Eo3Rg485NqStmMt97PBIsJictksykreXxOIzeHTiXC6yGzmzsSwgdQyEayhrm33Nd4DIObgz0repiTjmQaIJFo)tQFcqmjDePrXeLkwqspBQKqaDA9etKettL1p30ztZ8PW4MBMnInXmXO1jmvOttPXgh5iyoydCH2spWyD4cDncxKiCYqqDsxOW2NLyzPHgbD4x0SfPykvYtQ0lUXMjBojv5PIpACeullLPU6IaXYmTwYFZDI1C68YsC3qWxKghXy1Ysse7S8aOl(I0uMh42LMiENTPHf6sJI(zIdvPjeGAVYdmL5Hz4lsyW4(fcUiwqtn8uEEmodWiGnAmLjuAGkN4Hy10uQ92jsqZtCOMHamGyfrcRjC6l(PGSMGwHT7nn6yEjvuseReG8v41ccNHPu6S3mKYjHx7aZIZIq4qGmj1zRhN6STJy2J7PichkJZalITILjs2Af(YHhELIBLoQuCgRAhKs3clSNcM7oSvA(LEoHxdhZAtkfj82PU1po4GrZ(syXOr400kdDBvKZEgwDWtGs55bgaE1ei34o(o1rOulUWYdADxDNWhJYHDNQX8Xvp7WNUcvjhVWGsPeZGitL1hf8jXGpbRk1GjTA1WcwUCt3wNtPKnmnaI9E1ZqU2flyedYJ15zaz6IynFyi0otoVl9rTtuyMftWnvA56NrS8mewhOlulHb3HvjAmSE8W4zTrZXgh(JpHq3gi(L(kUXBV6a7TWW6)X72p68PtzYNzaX(DveTik81kzc4vj2cr50rcHqjfNQA)G0ooMXqGanZ1QYBawKpiA(4VVdutKKfkzAbYI5uECZBgWhR4i5mfJpyzovmayh9mU9xv7lDnLnTxglrWQAH4(vWqwb0kTvjbe(p76bN593TsfF2WqeTo7OHRN2fnykOL690iKVjAKub2gVRylMiKZqoifN2eJdqanOEjOUMZW6kI88LlnXOTG6oowRfYuWQgnNtAPG(fsTQyz(vRl(6xZkblmQ1)dnw)aWBn7CME2HEZnM53Zg2yP(5NaH3TREUQawX4myCgpZzBnE3zch(B3T(5GHczUk8hwHwG2B8EOecYKcujfaIwemdMbJ)YYfzBpme0ey7dWnzSDaLjTsidzc63Cl93dQPKBdhu0emyQMUF7N3IlJ7b6hD3Mxs6wE6zOiZabq5o00SZe1ojT(RjVx4oiMv38gEaAXJxEH3u5qVUdDEH7od)Un2TNHlLWftHv)7YS)kFE9q8qouP0k9PyWHiXs5PiLUewHKZ5Bi4SGGmzjatCr2tn(CH855N4sp14Y6KF3SOW3g3ymwoGoMGrt(jCcsPm0jUK2CjIiI40sLq2loCbPqtqgB5SYGmcykk2n0ulxWGw5sHmoXn9khkW(kg)TooHFGGHarLp9thHkXJwGOpodJull)W4E0nO(vLarX5NcPx6y2io)kze(YHXecxcuIpR7yFQyrC(4kyemVqDfhDbifzSaIkprYzDrVnIoQ1PuDjQM4ZSmMRxbNzMktTUrq)Y4u6Iyx2ACjhj8GCi1WjT7EMmXWeemx8nGC4ySjsDvhbuixRG1vwusSlFXyPVwnR0puMRe(QbnmF7QcIEbcN7Ayo8gqg2S21K6QcGHp1vsHnIRcWxRH2vQJX9T1LPmGqMMIno73uxzfa1Y2jsPx(kBKxS4ul5Xc1BzCPoBSEToZ0jkFTwXCDr(YrCvnPSUuuJLoolL1VkPlNxRiILeCroUQQKXwofypn4sbwf70hGiZHpblPs9LAAtzwhmuzHl9UosmyeB2XDVjbSLzdG4Cfh4ZD3e7Qks7Scf8YkJRgfw)bw0EeL6Y8(FG8fPcdmgHnbFNKPaSQUohpTZorVu4Pr3eW8OPGZBIznMSu7PgHPn95ZXp8U66DBEFw5J0EiFWx8U(PBCv)DTcyXB3vcUJlc7VsFWem)N2KK5JI57uBbUXHHLcGZ45uocbWQrgkYjXEZ(8QQCkHsxgPHVYMnB6x4n9C4zedB5j6DZLL3SF96ZGZ68A33SJDHfaDUgyN8DQS5LbnCII6jypmR0u74JdOKjwd(EYOIfXAO03e6egPgE7ypP8ypPvuC425T9TiTZ2bFEVy9mxIVIXDlpRbpCU4VnB9dNHENX2LlQ3ZBhRJkPT3CmvKCG)sbAv4qcz5zv5hCLuSZjHP15s39xvXlGdKKpf8kA3KNMBfmT0KRdFqwGD23GVtjRdBwgMi9R9gw8FOJdwZGBS9r))pOjrr81Ximt3AOW0vvdfIVCFzpryuhVSMaZUGDNweCQ6T7HDZT6VB0oeCalNlKd99fmD)GNvVtCgESdyJoeC7JKRFqyKbBZEq0PDfv72EqdptlrS8iUIhSAPRdUtBb5yHENBqJXDyTS93YM)C2KxazqzTci75uC3FH8B4)7qw4F92dpXLJ4BDcKhBQjMYfXG)DwG4iM8ODKNuESN0XVZ97Uel3(6LH2ZDxq09Tkxd5VZMalkO4t8)BbTgpbrWx1F7kqr3b8Y10fkEl5WDTOi4nMhLV1qjXvZ9ko)Zm9(NQjCZmA(lqyQB7G6h0Hv(tPnI5BFAceG8BF6pwvuN7GT1LkP3dpYXvJ(aazFjH1w6f79x)wg8FcZzG4GmJ(b2gQoo97xKDBqU(M3D2ZOW80AvZH)Dj4DygOGdpA1teOV7ozgUrHnrlmCws8PVD25O0j6qFvWYa3VktO7xWuYVvR9cgrdM6R(oVno)uAd)2ScfI0W70enjbkO3OGL4WkCn(h(cujG1B74pjthHmRFtz9JttnlHUEBv4)GrUdhh9Uv0epTE2S)7kZXZ0d" + return "4XzT8S0CBJZK)y2ZJlcacqWJ2jXjU2ehV2o1mtvtPjus0wCJSOxsQDgphYV9V(bajeFOiMK5senjq3n63DZMzHyX9lUB5(hEO(c8FUAv5UBYwVUy3JlUwS4UvLLBxx(x7UOSADE1Rk3wwHBiJEy1Il1XQutSinsAnkH1U4HFrhV4UhN8jlN6jnaYYQBUiRAuCTCX1riCX)Tc)3U1)BFei88MfxlvWcxx96I6SLBZFvr1QT5lw2b3hdHz0zXJd1MQIDFjVzauEoV5D5zBB2aG6D5fpUbWOb23UNVVSj)PB2M1KxF(2N3KD(2)k7L67ZQEmVjFnU3QSvfzBVPSEXD3E1BF39bq7M8Qv57AYEmFXfTiFal4sT2ghBuABK1MgXmn14hGQSDpM)Qn5R(sl9IGUti)kNq9TvL)1RlQYx1uuUBXDV)nxc46)pVQg(Z)8PS)3YQ)C3(Ni2)JhU0l(493)XpqN9Q8NkRUSChG4xxwvuFZn0H73DcfqAhfRePATeoa2OihHNTVk79f1nVo)HS9BBWtPjjjc)nFhY4xJ08ZvfamBEzX1XriZjB1xa08Ml(0LxINuzIuQM3wesLwpVTOItIsNClcD7wAXrKkYopCO1QzE2vcJrmVTivM045TfLqisoLZEih2Ee214cfDSDMyrQLjZ9SelMMHjIgigvrX6PfJJi3TP2P1gvJk2JTZ8qedMttZQgfjIO4PrYiNBRqkNhrLiMPYlOhEWowEajjhArzJnNKjyWPovznZJQ0Y4P3X4iXKoxELmwQN7rXQMRxolGLzIKy1SnBTMJyGmH)ePCALr5qLrzk4NBoAVqOMO5YTmPjtF0h1MsAsTZDlr645YGtsMPkSqDK4iJ7inAUXeaLR0tYVyymbz602jJ4kvgfDeX(eU31Z1neeQsotSiIKjh5Wpwue5rIkmoos1jt7JFIiOYJ4GCIKNW0iNNkSnzUQxQ440zUfb4Ky6TmkHHHQNzcekiIY0QKJ5jkj6i6xJZVK65MsRsLm3WwkLmAwUiLQ0JWG1d3Go6ioThX61enZuStMDyuLsLonsgvAedfEoTc)isCt8SuqWQZM3HinAUmkRjEMotSIJ4VAm1CJ5yPAnIYrIDEYoypRk4kCVR5fO467UAxtE1dzRY)JZxV(J7Q)J3UnB96x(JREcklU(p41(NvL73ToF9FUC7ZloOA87Z)7M9vaCU7PYYMntxsoMNP7z1iDUABwn1YJFO6T99iPTKxRgKRXXYuGvkSGM9d)ce5)USgO6(L7bscWX1uPi1pNVD7I7aQk7jG(5wgSaogRlEOiVcFcSHgSKBOi8mx13n8YWoEmcqUSC1(6XHHSdgpqRcaHAeqCoTOV(5)l14WPdmR5UKSgHu8XGu8CGK(yqsphizogKmZbsjhdsjZbs2Jbj7CGu6XGu6CGehzBkqHw9NmSAWEW1VpICZN6SYoFFvgBPnwZ9oZIq55Y)kVkOzBaRzZiTmZB(57QfAD56m0fy(AjPj4fkOGqnFb24e8IiRBnuhlUW3hc8cHkIxm2ZGlWEtzO7BmwALuP(0wJI5lOC2WlsSUlWYUjqyIIyeBT0Dek3suwvIB3yXQ8AGGox4QfLGc4(HrTWDrQwXWnwXBgUJLrTqWBYc52rKzednKmPlKcvkJhSoSl81xrevkVhUakcC8tusGTW0sKHibPrtCfQ2bAVjAM2OSJVWNWpbnPXjium8vWPM5)cdZT5Cer4jTcP7W6PkNObYWtW4kwXIePXYYcyXwgPXcRMP8uPJmItKUh5KkcHKbiL10f(0cOfNMWB3Qn0UmoMgvmcUhJwtebfgMwzCAktmyutci4jP5WauNChTR3KbQW1O((9fpLxDB(2Bkl21aoUV)J3m0mQ(nDbDROEm)RfRB2CjywwsgsPCNwPaSv7FUH3vB8hMsAE5zWA)MnVuxSkBlrncIY8uPpst4YFx52xcwkGQi3Yptdx5JheULllWG0bBrhfGbZG1FE1QSDJVdrRJ0WnCDgNhaD0HcVcpe0FJX7gCsUJy6UDriyaQUB)UVSd8T0FRFYDBwa6eM(dKWmGbuvw30drDiHYl68DR2aIoNNoS19G30aPCxx8pqslCPzLV(150squBJaRYLlC(aXlahg4pyojl99dgUib9(a)ITgFjMrNH2NmnMxV)3yjy3VeZBvPz4jfwcae8OghI7tiS0gO06racMX065)K92H4ZJq0z3sYi3HOubryYOeMsIe8fQygqw3jrlzizsSwgcQyEbydWw6lbJWLnH3l48Iofs)naYJ(LplS)pChshzAumzPIbFr45mvsaGApdb6Kyczwp2PQX5tAKHHTJLgBIzzIwNWuHonLwBSWrYCjGWfAl9aJ1bltc98Kihxe8XsxOqVM0HgCmJxq1vqydQLMEIKrQ0ZWXx3WsIVYOIDXTKzt0fPwMTrVaaAVw(0RL8VCWYLKZWe3nI4lsJfm4TmlfrdZyacKVinLpmy)Szsu5usnm3hcBK4ous(gPj0w1yqo8bGwnVqdFrsKt7oMz(XreYHNYkRgN2OaoiT61eincLtkjyvbTtPbyymYTAEhG2eltsyHIt0Xpfy7mjlyURcd8J)QCcqm8e9Cdl6JKoW6orkLt3qQzZk2UcqQtxjk1XgtsD2bX8fkHtzbIPQjIauo08DyGqvNI3pw5asIGvNeTQcoLyTJziDMCy0z8g(FbqZUnyMevaiD(y7jJh(kdBeNgZ)Miz7itKJnOyDooLjI2KAh7LnaIz1gvKGLLantXFtIC8H4wgczsgK143Dm3boBNaqTUVRCXi8vwE3MY)6YQI8DRHiKl53D6NEgVQ7nZ(kFLNhE7BCepICocaKd(EiM8YU8CXRBJoCW70(sW0jgYPfCWfffb53CcfTIV52PysbNT1v(0RPxIn)QIj2ZG3tEFM2R2xvNpcNZNRVbHFhl4JLvTb1oJATe9gXVR4FY52jeMy14u)ysM2xtD70caG6fOwDRwIAQyf7GFbnwRouR6FdpH0ZnMiiz6eBmYmJvdpETPn9nQMzzjuZ0tFakDVyhKoLS9KXV7CqH5F(6N)F2NTUkRj7RF((7pyb3byih5ikF5)Fd9BaPThFmdqmLHtXKq0M7kx0fKUeKvsitdH2jQ1S8BoTbTwRpoC2sSg8fmbbDb3RqigQfmAA2sM4jlN6j9th)0gee2i7ASu4lqlG3LT9Ht4q7M2e04(7V9wd7GfBQ4H(i0XzYHs(aA57S5wdu3llQl3nQgNPBxRNWYCCnKx)YUSNkwXl)c030(DnKRUr8b)HShlwnM7ep(pt2j8c6Ea66yKjJb7DiIgNTwGZFs1e9Ld6oRihYaG2Ia7GExE3)3(SQ8V(5l3VD7x)8VUPOj3r0TInRV4SqZiVd4(PXZR8umv7nSpEspiuXVf4S(anQ(iTTrO4z1hw6WiPSd4i0Lmylraa2kuMDl2OvCjKoH1OsJG83W0GvOBZwgGV6gh3oGNE1oKXSmSahh)tmme9VHH6IGOCGFzteuUbe8huHdpihEYB9()7bsGLq9spswDh4oyC(mXm6cgZhNaw(ivz3prcuxc77LVcTLb6y3cEhyVmVcKppwcPpqLWvVnp)z8I8ou9qz1QCVqQa)9AitQOuoUEt126M97oL9OtbXdQdTB9jVfRHrZMSQNoLnyWUSaB4l1NYQHiUuWYhQYZ)NCOI2t6SRTkA(bxdUMW8UAc30ftYWs4mBwDkOWiIPWipKNv1d6Dlbk6ny3uxGQkl7tnDRhQo4aSXII(Bz6tDm5PB1lR2wUlFkSeHPA0JQGCmESCx9YQ8mWk(eWvSqtAkfp9mCNtIJ51uQxL1aMfNM43HM9zNYQ1yjKipl)zSBW7wLFA7IyBH(EilXG8doECROEHxWlOu0ihK4Wl5DCg4EGx)hY(BVVIPgs1whu)c(ompCWCzm0D)Uyex90t73L3lFaO2uoWi2iS2u7qA7WgOVCq3KK0y0cujLQ21qr8dW4LLS9)Xs5DvrphKFhV0VAk8QlROaI47hiEPt)muIw8nRQ7n7YF6fKLLTBhe3yv(taxK0SDb0UnpBnvZxTlNHCAhlBxWNQzZtwFaFW6CSLGpNv1GTtnVEFLlf5AoEaST6UDC)gyjBG4T07UTXhiQ383(qfK0QVKHW10DpIvggnCZHnRM1109YB47G3FqAT9dK)(sSLLiB4a00vSNZQGwmQYL14JQJ6t(sl6YuOVAkyMLN1R8tF(QXlcka1HOW8)g0aF35MpMqjAa2BkE(RFMoIy(ev(0IGyXGOdQMRQzYS4UeQ3uzvPGhATeQcn1Lf(yfT68T0XqcsVXN(f4CbDsudg3VVyhY)CSJ(5H0tzztX68l2w8p)twfCia7KDzDaDGBQ1vxdj6Ec1qgwLkLupt4OM(xoHs2xvWNzAcfqteYy4K7fZWwQ4t0pKogTV6Hgft9(yeU3hJVwyKw7STo8JMywwlh6PQxNoceAE7c)Kp8HIDfpLTTOUtv(T7ZRRZRDQY(spU0abM1I4yTosMcPhG5NNemedHFKcHLY2knwxnDhliFRUOCDTmQZ8Cl4Fm)B0AoryXnOJRd8s1Rgm2UWVYP8hG)tyTxH1ynlXZboZCChFbMYdIxps7Y2COSCm(xNA79UkKwgy060WOckBbg2FIEPFCqzST1c6p)D9uRFvGRRo8oyZME2)s8ddrmQAhRx0zf0R8XJ778Gp9N2ypo6COyDD13HW7TBlRR9c)bo2ihFVY35bN6U2m0hqGDUVyZbLtxCY1V3v5DxmVIGKajO1h(bK05UmrOSsAlU8KTWwoHUQtEmTM6YdSPOszcBPCRQQPVS946bU0a4cOPeRW)uLmyW9Yc7j2(6MYNih83HKX3IP34aRa7GW)cW1kgm(UZcSNL6BLNlFGqGRIsgmTNZc6ts0dMt3FkG1Q6pIJ)maRjEW0F(ZaSIi9)kWvRgmK9)maRvk)Hu0MaSYHFvsZcSNP9QVUmS1H6VkJP)iSolOpP(7pgrpLKdFP7)8bRuNo4te8NbCTIbZh8Sa7zcNOlTnx6wqJnm7ha0tXGh(jf8ZaSwTO)ujplWEgeziSHgPMqDyDA)rKEwaF64g)RWke2)neCkz6Gb)(NbC5bD8haUNjmhOeJYs7HkY)BysBh(HQ9ZaSc9p5aOWcdYURRSH(55(7lU8xITjwBuCsCko6qwL7TSSU7BU)xeUCbdks0e(UtVV8CmZ6R4pYZGIXhw3AbLakvyDqLNbzLoslz8LkCqISHV5n)hAE7lNHsR0O1h97rRbhNf5X(UzP1qJt73amjh77x0HPHbz6VgAsEp(ss(wlqjtoY3oSWfLoS)Om7f4I1nzn7Rx6z7EPVPTgTVJ6XoOy6UkFD)pcWD4SOtYQ39PRV)n3Ix9en6ejrcQ9Y)653E7vFm4byJ0WhCZ5V)8xF11TpGh9y4bF483(MU7Yq5MBV6n3DF7DvsvsQd6V)JV6)U9b0uob3)13(PRED3YPz1dU9TF8TFQd28Gcd3(U3D(hopKsWPyMTb7n26So7H)3LGgI64Akyl75wQ8v(1Bag)DnyBZSN24Wc2gVkVahfNqt3c7UJ7DQCtzvtvwXpS6r)wH152QFFRpP(me2N2TCpOVOJF0)Jxi0IyI(E1DsdA9IV7GhPc6tCmjCZ2l1zjCLkOkqEUnTUXCnsYZoi6xBjnzCUzyv4goViPBmaJ9Z5zkplVg)mq6h23e3eQACdEkpv(4DCJNOX6gSVyv3yiYJdzIBWa5j1KHOmsWJLQueXeJsytzigB5rXuQT8K8f7wAQLhzyTYn5OqqiM(uoqGFad4FRJt4heX7abLFQtD0PeFvP4zmLN3Wu3mUIJ(fDd6RvG2IIhlvJXbu6drGOD8BcGjeEiOt8CLy3CwsFzbiPbRGpl0xwaDbWczOaCkprYtxzep6W8hJIJQDIwM1KO459L(uuCeaDJ0e30tsR24e8rXUPVKh8y(JobpRUb91yDJvRF2W5jReqg)84uEiwLrPUXKgivMeDmCqiZJfTBYGHJGthZk4z21HBqPKN)xTHhT3eJBcSBfuUbJn22oUT8k4jMvBDRx4NU7iw67h9yL0nCWirXZGUBsztTUjj34EEQBetbAGwHBiHrA0Zaz2RwYRu7gVAChSGWbsrS0X4DZ7RmLha6e3CXkvw3G(sF(j8jKpPXYe386AJy0H)3GeTPyR29idRP7jKydlXOV(MLOUj9VPX(zSUDk05ZkebZPrsF7n0HuWAK8h9c9ilZsb6Hh5zJ74AIDABEfc)49A4zUL(Esj2G0dPu3O3Uo4nfaBoma1P8cJcFhFn57A2uJG8Gj2XNO5nJ1v6tmkLlHLdEphh(DG(9hMI7TSlRjrV3yv4lIBvrBZSBwS4)893Ro1a" end function Gladdy:GetClassicProfile() -- 2.39.5 From dd75f267f43306c5c8ae2312566c419639b1a62a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 3 Sep 2021 01:56:38 +0200 Subject: [PATCH 029/268] add Test & Hide Button --- Options.lua | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Options.lua b/Options.lua index b2da325..69f5a6a 100644 --- a/Options.lua +++ b/Options.lua @@ -213,12 +213,31 @@ function Gladdy:SetupOptions() get = getOpt, set = setOpt, args = { + test = { + order = 1, + width = "0.7", + name = L["Test"], + type = "execute", + func = function() + Gladdy:ToggleFrame(3) + end, + }, + hide = { + order = 2, + width = "0.7", + name = L["Hide"], + type = "execute", + func = function() + Gladdy:Reset() + Gladdy:HideFrame() + end, + }, general = { type = "group", name = L["General"], desc = L["General settings"], childGroups = "tab", - order = 1, + order = 3, args = { locked = { type = "toggle", @@ -699,7 +718,7 @@ function Gladdy:SetupOptions() }, } - local order = 2 + local order = 4 for k, v in pairsByKeys(self.modules) do self:SetupModule(k, v, order) order = order + 1 -- 2.39.5 From 73b01c28d785ef0b3442fe5dfec796cc057122ee Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 3 Sep 2021 01:57:04 +0200 Subject: [PATCH 030/268] add duration for grounding effect (still needs testing) --- Constants.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Constants.lua b/Constants.lua index 2b04c1d..e6458a5 100644 --- a/Constants.lua +++ b/Constants.lua @@ -649,7 +649,7 @@ local importantAuras = { -- Grounding Totem Effect [GetSpellInfo(8178)] = { track = AURA_TYPE_BUFF, - duration = 0, + duration = 4, priority = 20, spellID = 8178 }, -- 2.39.5 From b651eb39ce0ee60e7115734d58566901a9153277 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 3 Sep 2021 02:01:17 +0200 Subject: [PATCH 031/268] add reload ui button --- Options.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Options.lua b/Options.lua index 69f5a6a..68c3abe 100644 --- a/Options.lua +++ b/Options.lua @@ -1,6 +1,7 @@ local type, pairs, tinsert, tsort = type, pairs, table.insert, table.sort local tostring, str_match, tonumber, string_format = tostring, string.match, tonumber, string.format local ceil, floor = ceil, floor +local ReloadUI = ReloadUI local InterfaceOptionsFrame_OpenToFrame = InterfaceOptionsFrame_OpenToFrame local GetSpellInfo = GetSpellInfo @@ -232,12 +233,21 @@ function Gladdy:SetupOptions() Gladdy:HideFrame() end, }, + reload = { + order = 3, + width = "0.7", + name = L["ReloadUI"], + type = "execute", + func = function() + ReloadUI() + end, + }, general = { type = "group", name = L["General"], desc = L["General settings"], childGroups = "tab", - order = 3, + order = 4, args = { locked = { type = "toggle", @@ -718,7 +728,7 @@ function Gladdy:SetupOptions() }, } - local order = 4 + local order = 5 for k, v in pairsByKeys(self.modules) do self:SetupModule(k, v, order) order = order + 1 -- 2.39.5 From d2884e777af0f77286ab86beb9c8312c31861572 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 14 Sep 2021 23:52:13 +0200 Subject: [PATCH 032/268] - Repentance, Freezing Trap & Wyvern Sting are now disorients - import string now ignores errors on deleted options --- Libs/DRData-1.0/DRData-1.0.lua | 16 +++---- Modules/ExportImport.lua | 83 +++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 25 deletions(-) diff --git a/Libs/DRData-1.0/DRData-1.0.lua b/Libs/DRData-1.0/DRData-1.0.lua index f1f5ff8..e6bd775 100644 --- a/Libs/DRData-1.0/DRData-1.0.lua +++ b/Libs/DRData-1.0/DRData-1.0.lua @@ -193,10 +193,10 @@ Data.spells = { [18658] = "sleep", -- Wyvern Sting - [19386] = "sleep", - [24132] = "sleep", - [24133] = "sleep", - [27068] = "sleep", + [19386] = "disorient", + [24132] = "disorient", + [24133] = "disorient", + [27068] = "disorient", --[[ MISC ]]-- -- Chastise (Maybe this shares DR with Imp HS?) @@ -213,15 +213,15 @@ Data.spells = { [33042] = "dragonsbreath", -- Dragon's Breath [33043] = "dragonsbreath", -- Dragon's Breath -- Repentance - [20066] = "repentance", + [20066] = "disorient", -- Scatter Shot [19503] = "scatters", -- Freezing Trap - [3355] = "freezetrap", - [14308] = "freezetrap", - [14309] = "freezetrap", + [3355] = "disorient", + [14308] = "disorient", + [14309] = "disorient", -- Improved Conc Shot [19410] = "impconc", diff --git a/Modules/ExportImport.lua b/Modules/ExportImport.lua index 9d9110a..1bafaaa 100644 --- a/Modules/ExportImport.lua +++ b/Modules/ExportImport.lua @@ -1,4 +1,4 @@ -local type, pairs = type, pairs +local type, pairs, str_match = type, pairs, string.match local Gladdy = LibStub("Gladdy") local AceSerializer = LibStub("AceSerializer-3.0") @@ -6,12 +6,23 @@ local L = Gladdy.L local AceGUI = LibStub("AceGUI-3.0") local LibDeflate = LibStub:GetLibrary("LibDeflate") -local function table_copy(t) + +local function table_copy(t, str) local t2 = {}; + if str == nil then + str = "Gladdy.db" + end for k,v in pairs(t) do if type(v) == "table" then - t2[k] = table_copy(v); + if k == "drCategories" then + for key,val in pairs(v) do + --Gladdy:Print("TableCopy", str .. "." .. key) + end + end + + t2[k] = table_copy(v, str .. "." .. k); else + t2[k] = v; end end @@ -84,9 +95,27 @@ import:AddChild(importClearButton) import.clearButton = importClearButton local deletedOptions = { --TODO backward compatibility Imports on deleted options - growUp = true + growUp = true, + freezetrap = true, + repentance = true } +local function checkIsDeletedOption(k, str, msg, errorFound, errorMsg) + local isDeleted + for key, _ in pairs(deletedOptions) do + if str_match(k, key) then + isDeleted = true + Gladdy:Warn("found deleted option =", str .. "." .. k) + end + end + if errorFound then + return errorFound, errorMsg + end + if not isDeleted then + return true, msg or str .. "." .. k .. " does not exist" + end +end + function ExportImport:CheckDeserializedOptions(tbl, refTbl, str) if str == nil and not tbl.version_major_num then return false, "Version conflict: version_major_num not seen" @@ -98,17 +127,29 @@ function ExportImport:CheckDeserializedOptions(tbl, refTbl, str) str = "Gladdy.db" tbl.version_major_num = nil end - for k,v in pairs(tbl) do - if refTbl[k] == nil then - --return false, str .. "." .. k .. " does not exist" - else - if type(v) ~= type(refTbl[k]) then - return false, str .. "." .. k .. " type error. Expected " .. type(refTbl[k]) .. " found " .. type(v) + local res, msg + local errorFound, errorMsg + if refTbl == nil then + return false, str .. "does not exist" + else + for k,v in pairs(tbl) do + if refTbl[k] == nil then + errorFound, errorMsg = checkIsDeletedOption(k, str, nil, errorFound, errorMsg) + elseif type(v) ~= type(refTbl[k]) then + errorFound = true + errorMsg = str .. "." .. k .. " type error. Expected " .. type(refTbl[k]) .. " found " .. type(v) elseif type(v) == "table" then - ExportImport:CheckDeserializedOptions(v, refTbl[k], str .. "." .. k) + res, msg = ExportImport:CheckDeserializedOptions(v, refTbl[k], str .. "." .. k) + if not res then + errorFound, errorMsg = checkIsDeletedOption(msg, str, msg, errorFound, errorMsg) + end end end end + + if errorFound then + return false, errorMsg + end return true end @@ -135,8 +176,8 @@ function ExportImport:GetOptions() export.eb:HighlightText(0, export.eb.editBox:GetNumLetters()) export:SetStatusText("Copy this string to share your configuration with others.") end, - name = "Export", - desc = "Export your current profile to share with others or your various accounts.", + name = L["Export"], + desc = L["Export your current profile to share with others or your various accounts."], order = 3, }, import = { @@ -159,17 +200,25 @@ function ExportImport:GetOptions() import.deserializedTable = deserialized end) end, - name = "Import", - desc = "This will overwrite your current profile!", + name = L["Import"], + desc = L["This will overwrite your current profile!"], order = 4, }, } end -function ExportImport:ApplyImport(t, table) +function ExportImport:ApplyImport(t, table, str) + if str == nil then + str = "Gladdy.db" + end for k,v in pairs(t) do if type(v) == "table" then - ExportImport:ApplyImport(v, table[k]) + if (table[k] ~= nil) then + ExportImport:ApplyImport(v, table[k], str .. "." .. k) + else + Gladdy:Warn("ApplyImport failed for", str .. "." .. k) + end + else table[k] = v end -- 2.39.5 From f1e1ee4e0b4ed3b992cf885007a16475a96ffbc9 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 14 Sep 2021 23:53:12 +0200 Subject: [PATCH 033/268] added Mir's profile --- Images/BasicProfiles/Mir1.blp | Bin 0 -> 175956 bytes ImportStrings.lua | 16 ++++++++++------ Modules/XiconProfiles.lua | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 Images/BasicProfiles/Mir1.blp diff --git a/Images/BasicProfiles/Mir1.blp b/Images/BasicProfiles/Mir1.blp new file mode 100644 index 0000000000000000000000000000000000000000..faed7351402059e9a88d0d19d6c3732313c8a509 GIT binary patch literal 175956 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

cfkJl(I-FpG5Nb`ZIN~9 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 literal 0 HcmV?d00001 diff --git a/ImportStrings.lua b/ImportStrings.lua index d04bdce..80e7914 100644 --- a/ImportStrings.lua +++ b/ImportStrings.lua @@ -1,25 +1,29 @@ local Gladdy = LibStub("Gladdy") function Gladdy:GetKlimpProfile() - return "4XzT8S0CBJZK)y2ZJlcacqWJ2jXjU2ehV2o1mtvtPjus0wCJSOxsQDgphYV9V(bajeFOiMK5senjq3n63DZMzHyX9lUB5(hEO(c8FUAv5UBYwVUy3JlUwS4UvLLBxx(x7UOSADE1Rk3wwHBiJEy1Il1XQutSinsAnkH1U4HFrhV4UhN8jlN6jnaYYQBUiRAuCTCX1riCX)Tc)3U1)BFei88MfxlvWcxx96I6SLBZFvr1QT5lw2b3hdHz0zXJd1MQIDFjVzauEoV5D5zBB2aG6D5fpUbWOb23UNVVSj)PB2M1KxF(2N3KD(2)k7L67ZQEmVjFnU3QSvfzBVPSEXD3E1BF39bq7M8Qv57AYEmFXfTiFal4sT2ghBuABK1MgXmn14hGQSDpM)Qn5R(sl9IGUti)kNq9TvL)1RlQYx1uuUBXDV)nxc46)pVQg(Z)8PS)3YQ)C3(Ni2)JhU0l(493)XpqN9Q8NkRUSChG4xxwvuFZn0H73DcfqAhfRePATeoa2OihHNTVk79f1nVo)HS9BBWtPjjjc)nFhY4xJ08ZvfamBEzX1XriZjB1xa08Ml(0LxINuzIuQM3wesLwpVTOItIsNClcD7wAXrKkYopCO1QzE2vcJrmVTivM045TfLqisoLZEih2Ee214cfDSDMyrQLjZ9SelMMHjIgigvrX6PfJJi3TP2P1gvJk2JTZ8qedMttZQgfjIO4PrYiNBRqkNhrLiMPYlOhEWowEajjhArzJnNKjyWPovznZJQ0Y4P3X4iXKoxELmwQN7rXQMRxolGLzIKy1SnBTMJyGmH)ePCALr5qLrzk4NBoAVqOMO5YTmPjtF0h1MsAsTZDlr645YGtsMPkSqDK4iJ7inAUXeaLR0tYVyymbz602jJ4kvgfDeX(eU31Z1neeQsotSiIKjh5Wpwue5rIkmoos1jt7JFIiOYJ4GCIKNW0iNNkSnzUQxQ440zUfb4Ky6TmkHHHQNzcekiIY0QKJ5jkj6i6xJZVK65MsRsLm3WwkLmAwUiLQ0JWG1d3Go6ioThX61enZuStMDyuLsLonsgvAedfEoTc)isCt8SuqWQZM3HinAUmkRjEMotSIJ4VAm1CJ5yPAnIYrIDEYoypRk4kCVR5fO467UAxtE1dzRY)JZxV(J7Q)J3UnB96x(JREcklU(p41(NvL73ToF9FUC7ZloOA87Z)7M9vaCU7PYYMntxsoMNP7z1iDUABwn1YJFO6T99iPTKxRgKRXXYuGvkSGM9d)ce5)USgO6(L7bscWX1uPi1pNVD7I7aQk7jG(5wgSaogRlEOiVcFcSHgSKBOi8mx13n8YWoEmcqUSC1(6XHHSdgpqRcaHAeqCoTOV(5)l14WPdmR5UKSgHu8XGu8CGK(yqsphizogKmZbsjhdsjZbs2Jbj7CGu6XGu6CGehzBkqHw9NmSAWEW1VpICZN6SYoFFvgBPnwZ9oZIq55Y)kVkOzBaRzZiTmZB(57QfAD56m0fy(AjPj4fkOGqnFb24e8IiRBnuhlUW3hc8cHkIxm2ZGlWEtzO7BmwALuP(0wJI5lOC2WlsSUlWYUjqyIIyeBT0Dek3suwvIB3yXQ8AGGox4QfLGc4(HrTWDrQwXWnwXBgUJLrTqWBYc52rKzednKmPlKcvkJhSoSl81xrevkVhUakcC8tusGTW0sKHibPrtCfQ2bAVjAM2OSJVWNWpbnPXjium8vWPM5)cdZT5Cer4jTcP7W6PkNObYWtW4kwXIePXYYcyXwgPXcRMP8uPJmItKUh5KkcHKbiL10f(0cOfNMWB3Qn0UmoMgvmcUhJwtebfgMwzCAktmyutci4jP5WauNChTR3KbQW1O((9fpLxDB(2Bkl21aoUV)J3m0mQ(nDbDROEm)RfRB2CjywwsgsPCNwPaSv7FUH3vB8hMsAE5zWA)MnVuxSkBlrncIY8uPpst4YFx52xcwkGQi3Yptdx5JheULllWG0bBrhfGbZG1FE1QSDJVdrRJ0WnCDgNhaD0HcVcpe0FJX7gCsUJy6UDriyaQUB)UVSd8T0FRFYDBwa6eM(dKWmGbuvw30drDiHYl68DR2aIoNNoS19G30aPCxx8pqslCPzLV(150squBJaRYLlC(aXlahg4pyojl99dgUib9(a)ITgFjMrNH2NmnMxV)3yjy3VeZBvPz4jfwcae8OghI7tiS0gO06racMX065)K92H4ZJq0z3sYi3HOubryYOeMsIe8fQygqw3jrlzizsSwgcQyEbydWw6lbJWLnH3l48Iofs)naYJ(LplS)pChshzAumzPIbFr45mvsaGApdb6Kyczwp2PQX5tAKHHTJLgBIzzIwNWuHonLwBSWrYCjGWfAl9aJ1bltc98Kihxe8XsxOqVM0HgCmJxq1vqydQLMEIKrQ0ZWXx3WsIVYOIDXTKzt0fPwMTrVaaAVw(0RL8VCWYLKZWe3nI4lsJfm4TmlfrdZyacKVinLpmy)Szsu5usnm3hcBK4ous(gPj0w1yqo8bGwnVqdFrsKt7oMz(XreYHNYkRgN2OaoiT61eincLtkjyvbTtPbyymYTAEhG2eltsyHIt0Xpfy7mjlyURcd8J)QCcqm8e9Cdl6JKoW6orkLt3qQzZk2UcqQtxjk1XgtsD2bX8fkHtzbIPQjIauo08DyGqvNI3pw5asIGvNeTQcoLyTJziDMCy0z8g(FbqZUnyMevaiD(y7jJh(kdBeNgZ)Miz7itKJnOyDooLjI2KAh7LnaIz1gvKGLLantXFtIC8H4wgczsgK143Dm3boBNaqTUVRCXi8vwE3MY)6YQI8DRHiKl53D6NEgVQ7nZ(kFLNhE7BCepICocaKd(EiM8YU8CXRBJoCW70(sW0jgYPfCWfffb53CcfTIV52PysbNT1v(0RPxIn)QIj2ZG3tEFM2R2xvNpcNZNRVbHFhl4JLvTb1oJATe9gXVR4FY52jeMy14u)ysM2xtD70caG6fOwDRwIAQyf7GFbnwRouR6FdpH0ZnMiiz6eBmYmJvdpETPn9nQMzzjuZ0tFakDVyhKoLS9KXV7CqH5F(6N)F2NTUkRj7RF((7pyb3byih5ikF5)Fd9BaPThFmdqmLHtXKq0M7kx0fKUeKvsitdH2jQ1S8BoTbTwRpoC2sSg8fmbbDb3RqigQfmAA2sM4jlN6j9th)0gee2i7ASu4lqlG3LT9Ht4q7M2e04(7V9wd7GfBQ4H(i0XzYHs(aA57S5wdu3llQl3nQgNPBxRNWYCCnKx)YUSNkwXl)c030(DnKRUr8b)HShlwnM7ep(pt2j8c6Ea66yKjJb7DiIgNTwGZFs1e9Ld6oRihYaG2Ia7GExE3)3(SQ8V(5l3VD7x)8VUPOj3r0TInRV4SqZiVd4(PXZR8umv7nSpEspiuXVf4S(anQ(iTTrO4z1hw6WiPSd4i0Lmylraa2kuMDl2OvCjKoH1OsJG83W0GvOBZwgGV6gh3oGNE1oKXSmSahh)tmme9VHH6IGOCGFzteuUbe8huHdpihEYB9()7bsGLq9spswDh4oyC(mXm6cgZhNaw(ivz3prcuxc77LVcTLb6y3cEhyVmVcKppwcPpqLWvVnp)z8I8ou9qz1QCVqQa)9AitQOuoUEt126M97oL9OtbXdQdTB9jVfRHrZMSQNoLnyWUSaB4l1NYQHiUuWYhQYZ)NCOI2t6SRTkA(bxdUMW8UAc30ftYWs4mBwDkOWiIPWipKNv1d6Dlbk6ny3uxGQkl7tnDRhQo4aSXII(Bz6tDm5PB1lR2wUlFkSeHPA0JQGCmESCx9YQ8mWk(eWvSqtAkfp9mCNtIJ51uQxL1aMfNM43HM9zNYQ1yjKipl)zSBW7wLFA7IyBH(EilXG8doECROEHxWlOu0ihK4Wl5DCg4EGx)hY(BVVIPgs1whu)c(ompCWCzm0D)Uyex90t73L3lFaO2uoWi2iS2u7qA7WgOVCq3KK0y0cujLQ21qr8dW4LLS9)Xs5DvrphKFhV0VAk8QlROaI47hiEPt)muIw8nRQ7n7YF6fKLLTBhe3yv(taxK0SDb0UnpBnvZxTlNHCAhlBxWNQzZtwFaFW6CSLGpNv1GTtnVEFLlf5AoEaST6UDC)gyjBG4T07UTXhiQ383(qfK0QVKHW10DpIvggnCZHnRM1109YB47G3FqAT9dK)(sSLLiB4a00vSNZQGwmQYL14JQJ6t(sl6YuOVAkyMLN1R8tF(QXlcka1HOW8)g0aF35MpMqjAa2BkE(RFMoIy(ev(0IGyXGOdQMRQzYS4UeQ3uzvPGhATeQcn1Lf(yfT68T0XqcsVXN(f4CbDsudg3VVyhY)CSJ(5H0tzztX68l2w8p)twfCia7KDzDaDGBQ1vxdj6Ec1qgwLkLupt4OM(xoHs2xvWNzAcfqteYy4K7fZWwQ4t0pKogTV6Hgft9(yeU3hJVwyKw7STo8JMywwlh6PQxNoceAE7c)Kp8HIDfpLTTOUtv(T7ZRRZRDQY(spU0abM1I4yTosMcPhG5NNemedHFKcHLY2knwxnDhliFRUOCDTmQZ8Cl4Fm)B0AoryXnOJRd8s1Rgm2UWVYP8hG)tyTxH1ynlXZboZCChFbMYdIxps7Y2COSCm(xNA79UkKwgy060WOckBbg2FIEPFCqzST1c6p)D9uRFvGRRo8oyZME2)s8ddrmQAhRx0zf0R8XJ778Gp9N2ypo6COyDD13HW7TBlRR9c)bo2ihFVY35bN6U2m0hqGDUVyZbLtxCY1V3v5DxmVIGKajO1h(bK05UmrOSsAlU8KTWwoHUQtEmTM6YdSPOszcBPCRQQPVS946bU0a4cOPeRW)uLmyW9Yc7j2(6MYNih83HKX3IP34aRa7GW)cW1kgm(UZcSNL6BLNlFGqGRIsgmTNZc6ts0dMt3FkG1Q6pIJ)maRjEW0F(ZaSIi9)kWvRgmK9)maRvk)Hu0MaSYHFvsZcSNP9QVUmS1H6VkJP)iSolOpP(7pgrpLKdFP7)8bRuNo4te8NbCTIbZh8Sa7zcNOlTnx6wqJnm7ha0tXGh(jf8ZaSwTO)ujplWEgeziSHgPMqDyDA)rKEwaF64g)RWke2)neCkz6Gb)(NbC5bD8haUNjmhOeJYs7HkY)BysBh(HQ9ZaSc9p5aOWcdYURRSH(55(7lU8xITjwBuCsCko6qwL7TSSU7BU)xeUCbdks0e(UtVV8CmZ6R4pYZGIXhw3AbLakvyDqLNbzLoslz8LkCqISHV5n)hAE7lNHsR0O1h97rRbhNf5X(UzP1qJt73amjh77x0HPHbz6VgAsEp(ss(wlqjtoY3oSWfLoS)Om7f4I1nzn7Rx6z7EPVPTgTVJ6XoOy6UkFD)pcWD4SOtYQ39PRV)n3Ix9en6ejrcQ9Y)653E7vFm4byJ0WhCZ5V)8xF11TpGh9y4bF483(MU7Yq5MBV6n3DF7DvsvsQd6V)JV6)U9b0uob3)13(PRED3YPz1dU9TF8TFQd28Gcd3(U3D(hopKsWPyMTb7n26So7H)3LGgI64Akyl75wQ8v(1Bag)DnyBZSN24Wc2gVkVahfNqt3c7UJ7DQCtzvtvwXpS6r)wH152QFFRpP(me2N2TCpOVOJF0)Jxi0IyI(E1DsdA9IV7GhPc6tCmjCZ2l1zjCLkOkqEUnTUXCnsYZoi6xBjnzCUzyv4goViPBmaJ9Z5zkplVg)mq6h23e3eQACdEkpv(4DCJNOX6gSVyv3yiYJdzIBWa5j1KHOmsWJLQueXeJsytzigB5rXuQT8K8f7wAQLhzyTYn5OqqiM(uoqGFad4FRJt4heX7abLFQtD0PeFvP4zmLN3Wu3mUIJ(fDd6RvG2IIhlvJXbu6drGOD8BcGjeEiOt8CLy3CwsFzbiPbRGpl0xwaDbWczOaCkprYtxzep6W8hJIJQDIwM1KO459L(uuCeaDJ0e30tsR24e8rXUPVKh8y(JobpRUb91yDJvRF2W5jReqg)84uEiwLrPUXKgivMeDmCqiZJfTBYGHJGthZk4z21HBqPKN)xTHhT3eJBcSBfuUbJn22oUT8k4jMvBDRx4NU7iw67h9yL0nCWirXZGUBsztTUjj34EEQBetbAGwHBiHrA0Zaz2RwYRu7gVAChSGWbsrS0X4DZ7RmLha6e3CXkvw3G(sF(j8jKpPXYe386AJy0H)3GeTPyR29idRP7jKydlXOV(MLOUj9VPX(zSUDk05ZkebZPrsF7n0HuWAK8h9c9ilZsb6Hh5zJ74AIDABEfc)49A4zUL(Esj2G0dPu3O3Uo4nfaBoma1P8cJcFhFn57A2uJG8Gj2XNO5nJ1v6tmkLlHLdEphh(DG(9hMI7TSlRjrV3yv4lIBvrBZSBwS4)893Ro1a" + return "4XzTCTTCBJZK(HzVoUiaibbV0kjoX1M44FlNAMPQP0ekjAlUrh8ssTZ45I8SV9jEMurmX5IzmdjqJgnA0N(A7fQf3Vy(6SzhYwNK96dBpKHViEXnQfZxs))hP)Fg()lGFgV)XKxVjz1xV9WFNKnlo7(K)PyXSfZxfNxa)ZXOKhrjpIsEiLwdd6W21h(79xU9Pn84wN9M084LBtEDA2QTjlwwt2hBssVl8hMOfzP7)AsrpQ8usX7tI3wSbi17tsFCtXIBSW82)09hks2D724IKCIpUC7Fh)C(9XzpMuKSgNBw8Q04T3EiFX87U(DV)(gu72KSvj7lIFmbLaYI3tcCvqGZ33AcCEoxe8FlE4vbMH3a1Y3k(fj9YJp8q(m8)vk0Ex2H)(nPzjRkspSFX8p82RG16)ljlh(N)1U4)Ndz)1(J74tW2dD2NU)(p9rAVNLS7q2vh2dl8BoKLMF7T0M7p(eSqjfaJ775BurbbAyd488egp(yw8hsZlEtYdXh3wG7sByOh(ZK9OGFnYZpLLc0S45f347HcN4vFfwM3o7ZxDfUt1HATzAtrPnbbtBkg)qVOrNIkOAkvRHNXZnT1iiWmX9UrzTQPnfTXg5pTPyukv45S3BkHDNqCn8HsGVBIRIoqho19IVACbMYR3XOXZpy8JXbo3DrUX1gndES77M4MWhUonUOAWfr55p(ImW(2P06PXuHQjQ8c6HTMXYwSKU)nkNV9SUc2yxhzC2PXvbA)XNXWlInAQYkTVoyQBfNzQw5CWQmXfX3m5RTo7jUGmI9eTECLrDFLrDeyNBkAVGRgVPkTSrHJV1h8oL2g5M6u8c8NQaomCIQWkZj8JmSHuVP6tauUIol7In9jOJg)EYaMs1EEN4yFeZ7bt1me4QspXvr5PdpXMFiVi6t4vy41ikiCCB8J4bvFcdKJe8egg50uHDHtv9Y47hnXPOaJeJpLbzm0v9edGWaEugxLCilrHENq)Ay5LoyQH0AmHt1TLXO9MKjsTj6ec4G(tiW7egTh42R1BIHyhoz3OgJjA8fzWtd)aFZ4k8dCIB9NKccMD202erEtvq5S(t0yItDc7vdPMBTNkuRbuocDt7SROkJCoTXRYs)3V9L)ZX41zXfXF7l3deRzY2y1boMLSy(8DhouSz8mURZ0Um7tmT4vBJZZVE1H9)ujvVsYzUkVwxaC457RJa5LYbQVp8kW9(84cif(LhbgdwJBO8nYFkz72fZb(oEhSl46cSa2mRtFinjd)cmHcmVAit7yjf7cEyWEqparU6WQJ5dtdDnnEGgfqcZaK4sAqF7l)xMHPtnzwZLcznsj)trj)PqPGtrPGPqj7POKDkuk8uukCkuYDkk5McLIofLIMcLy3xJrk8Q9ztRcSqB4LQBJxVoDpxGpUct13YU8ywmFtBOc4DHdPYtsjalROgiA2mqDXkhgAXyE6)MqdSPrIZUMH5BIH7X54QDF6UKS7s2E7H09fW1M7)0T93e5VT2UgBC53sxxS5kqOCG2grCXSUEFrsw2XNk4zvD7N5KINFcK13U5580vXBLAHk1fDjZz898Md)9h2(CJHclLNm8lc8uv3gBoLRsrdLnMsGxJvW2B8xMTkE)WZqvPg3Cc3eZ2IPToeBBZnb9VrRn92jZjHUmlAb6TuZpU)R7bdSDN6NLxZhGYHz5gsz7jaYoKx0zHQxe0qE6L7xTbo6e9mS6OGUCJt56cL26KwjEYsw)MeAi4s78GWLwIPfegfIpaj6aP3JVb9jSSSOBWdHy9iGFI1FCj620sZuhbE0XXl)Kkj0sm2adnoLrRC08jYrfNbNMs5OXtHoHZtzOHjFNl)bUCLRhwCJLuOY865hPOfs7fYmINIFW4ZecR6Wsk1cMs2qNJPGXNhawKHLLH5sRLlKNRnqPOpv(cG9OFY7fojDCgAHnTgMTm(EK4ZfPjcqPatKo0Nwmx5Qtz8W7upltBrI6B95dLGGqMlcIIOX6RewMdZgEiWrFW6eAzdPVh6jsr48KEWacEEtRT0iOy3OvdYxH(IMxuDPahlP7ssUYlfNt7swmrpe5yXgvKvAUoE3hO5FYfgDjf3xO8cp6bltbTJfO4IWIfG94hII4TcwXqMbnIoQLL9ARju2sA(frH0uHZowGck18aT8dH8e5QXHK2ZX8seRQAfDrfSnQuQjsAvg5msXkcbIkdiU4f3fWZa0L4tKq(iro44VccDMLvwAlzSEcv8LlzE0pGKdig3tlufo2vcdPyzoKmhRkAmIYIoqeLrIKmmsUi4ZpWLUdFtOlu4ddFKQ47k6qnRgd)qOsOILnHgRCDt5ef5arKOLRDyMYepgwEtMPbfHnU5erMmUs7kQs7iSK2WBdRNSU8jI1fqCSrjA8GCMVCekJqoZdbRcZqMqytylkI4q6gzdF2)W(CBySf8HF7HmWWAQa6fyhFlyhNCN(q8QK)8Y1R)0(8)8DBHinE(pVEherq(FYJ9VYoCC)6K1)1YTpvLwq(8nh(BiNIK9Rb3NlzSR(8t4t1iJ96YKcA)6sajroBt7qle(IzdijfiFGI0N(2xiwOo)aKE1ZSjIJxbx78DG7GaLNNhKZ(PY2GZpI8)asv48UbwNemImyDKFOEiv2neMxFmlpP1jKQvGywCjRfcF6qwLpVlc4OBoVm1WrDgaa3e1WFVrMApdzv5c04vfm3kWisaMvfKvX)aFHUoyTEUqVqNpk98n93RvHy9DI7C5bi62DFesYkDpe6fb5ab96470gdaoGarniEmLjQ9DUlalA12hLNy4fNZ1hAcKiMdpgcTcIGPPqR80zm60qUV87c(B1n7h7rURCwSE)G)zWwm4nIswoaxIX(s2yFPOtO7NhU88TQBWKwMHxhEF82hoJnTCvcVR)tBAPrfh47nLuFa(4cD)t(g8Ypyzi6PUFin)W(b14SlA0Netrd5npdzgMUIh(m002X9fKTTz125A34fTr5piYkBHnDBycSEqd0FcLnaICfRP)buJeTOdQmRiZYaH2IeRLz55)VhJZs(2xU642TF7l)2M0Iez3uDA5kZFR5TNYTt3i95rEo3q70YfLS(YAA)7nmy3srQ7IwvPkCVw6CQTZwo3xp0SmCfQ0)G2vVA0iUcckWznrEqmEyGYg0AzLaOmbirA3qME9EuWSSzoq1DwtxV4)o6sZd8MbMJTEqcjq8bWXEL0RFV50uQ(JFzCjKe2J0BAz3y4tgs8D5QIJGlHLLCqJdPbsDVBQGO2hwkJY0(w2qR8oGZBfSqvXk)y6(0DXBtZBkFP52W03PVs2WShDfcFOUaiim5Lkhn2qIgwvviMxG)ttyVsFh30m2XCWBiDlCoQk99u4leYQWt)Fb01P6ba2Ki7frLwFrRqDiUbs4TlEjtI6JY09q66fHSotxqcEjiR1Vh(jVeKv5f8lHUbMEWu)sqwi13FkfTriRUFF9mjYErqP6ReZAqt9xiNZUGanjQpQ(7phtp2jhwsLxEYcPI3Rj7EjORt1dHTjr2luYrxuvyvvK2lSBdOnjspMaUpO8VeK1fO6IR3Ki7fGNHMPDfzBQdhe1fKXjr8X9B8lruOC)ko4m6OEqN(sqxL9N0t0fkBlLy8S01wr(xXvAx)w96LGSQGxyhOWaXWghRpZRaF(vyBiuhjnfzpf6w97RtW46D7oUpPZ5aCjHphqGweRjCqFTHhBvA3CjwNvLMZRu9xTRoKTB8DjxIKvPDIt(hiW9CkVmjW9YE(UkEBk(ulK0yNJNwnxsbwms9PAHvAmAL5KTvjsMWt1kHYk13Bv3X48orFHWdj87naJo8eTXRsC33e1Z(56OAKQqzD1Qka6B3NS7zsvF)EivPvj7aTfoFaoRV7sIxtLhnxsSoHMXYQb85CMT4eqWpSobtM5P4ScewYK8Jzs5JYXXTgNwE9mUFdmKnqkGuBMatKZ9QZVQapKfVlPSCAnht97iD3MD0r3kZs3PcK2DGFhYgDZx9dhqW7AKJeNfopDSWeY9xAW4fK4IY02rn3(PZ29sfyqijUtLwL7vyrTYydofvlu7YG)(PvV56oO5mQ466S)dCpSy0AzCLVZZ4mrqA8bAxGosQFtdnRQk2kzFwlVAuEJYIq8X4)bT2LdwP(q6Eu8ksRU5w3rByt66KzBt)3)nod2JGLJ9X1eTN921z3CC72ZOaQvl1zucmbJ3zLi8AG0ffO2e0o90mIiODlcyeb5sTIHPr5XOGznmIRQiFgNViBjyyLGe5ce4sf8h1AbMrJYkW0ADcUr(MA4OyeYI8fuxdTc0Xmz9umeLALNtOMlIznFhdmNvW10xgzKJrpoWiWi6hkRVrOa2324)oWpK)GhpdDGlQecsMtvEEwbGkz)lWDIL2NEb1nW0ummgLwRquRIXttRcSchhYi3fwcaRVGbNsXBbdmcAD5(7JEaeJmvazvjtkW(XOiBajtLWsoEfildfmgPFDreoGw5OqbHmA4w503ZxW5JbHge1SeuOQ1jySY9jGo0YSgSA8a8J4Lt7fjqMd8kZJIepkK1JSckXWEqu0CkgbxJUebxpPzbm(c9H1JwofJPiOG5ZhOgxKaBTrZ9xaVbWLVsMXmadMAju0bsxaqDDk(VTmQYbLqL7BfSFJyqsdzuLfmJrwSucYmqGMhNG(mkIy1zPbgqWYycWKZWyZRJeiXlXN0xaYmYxWYpuUFOCEc4VE8wvBCUk9EM3zwa0BKdzFTacBKw2oEEsByisfyiSad0Hz0XDLAubvhCch5yzgqtg9BDjKUwzewfpchJjRLHXwXhEGME5fPibc26coFh5Xe)Crt)wfG7(n5Dd)Sx3AvhtQUgnd0f)xhSHyA6fUmAdkidbekKu1oUlnC)Zg3yxigB4WO0L9qvDTQC6DJngOxzWXxzbTSaLVFqGNgUYqWkgwZ6)rZFNnBcLelZ8kXwzyed7gbsdrdtQQy01MgYRQ3g0iwhe4R2f)Tlsi8hASVBJ7qLd8wnhlZhLWZOhiXKpg)y6QbcVOcHPlWM(A(wiEYKVtlbOQsIQEF9DXBT7PxLZCrAsi7SoR9WqGzFQfqsRZEneT3JGId1AUZZ3MK8uZiWxIbqcjvvc8sk(ZBuGoreJjFr228IJ7pN5eaU6PRP7xF2tXz5LztmNA23Bcw0(lUghou0jtIHhpybdh)xZphQdgZ5KaFE12dCEPdUaZAkO0KMq(Q4c4o(5TmqY5uaQP54jZ(ZBNG1rdM0X4ZzjcW(GIIbo(riK0LzjXq6mNXe9fEdoe7kJh)q0NebRxDoJgIdK4S0DpbV5SMsPwYdjXzN1zc2LGs762oRQ1z)aMLF32d55ykGIBepji9xxcrSyxmWUOD3g0WuuhanpR0C6KONyzOFgzfygQZktJSxcdSrhi5e8FSkTrHAqZMPNnCVnSRFPKEnvfMk8BRsPKecv2ZXBGvRZKe8TaaDvAT7NAFZnH1M3)sJsxAZSLfsDT7Mw2sT0Fbfa35uBHCJY19m4SoVOiioJ8sBPJ0eP(UEo)Jfx9ki(tNZdsmjc7XsNPcS5YqHUxWZEzlNytso3REvmOVNTBTgPLx7OEvkP(tTxEJyig4oXGXXmqTbkViSLlPXSk6(UJj55j5sjfk7SUwUbBSxA3B7LIr5pjdZXFpbiJ4V)Z3C)BVdFAh1SuHEkY3WVD5D3D9NA8bS6b4hU9YpC5BU(MQpW)bra(WhV8DVT(TmvU9URF787RERbINosO(h(0R)VR(afYmg73DF(63upCQrEHxF3NE3NRPTXgabHdVE(7V8Jx2Kt8v(Sbr2yqDRbm2VyaQYtUoD(cjA4)cumBH0a4ZWSnImb8d4FGgMvMRjogQ9EXhOCPWhGKx4bJjBoJBRx89ubbMj)jfGMk2224d0VBO4dupOsRSVptcSzyNvMck(fJmeJZekZgB3AEmGNQzsBHtubZqMwAL8quGHPRVHNm8ghV0yZIIp4c9O3qLevyt6bQASZkRBa(c63JBIPI45W9aoro(lgniwyEblGWmjfXzl4wYLMByaZB0VfU0cILsGOgMNg9jdtFidxdl)vwwAZDy7Sfszw4nBjxjhngsbbFJVHpsGu45Zcojn6tyVXsCEKwydm5t(tYPcvEIzL5jpRS8e0GXisWhCyroMXzbsBtprsqAVZKFD)OrI18Hyg83opIi4oPOxXqpdVxKXgXjyDt1D)Hlrp5xtXESoRzscI72b)ZxtpJDTQT6pGf42E6ALbz)EseePrwFkVElQ2JUe8PcAoYxYg7lOZO2nCB5A3nV5MfLF4exAMkuhNrNHpXMULhjXOgDCkQlSUrkPgBR6GFgfhT1FYH(5pQoZYSUSxjjQv06e(0SrcKSZVyN)4S(Mj2)Y5fXfhZxwELR8McwaL0QyrlwS4)FtekbA" end function Gladdy:GetClassicProfile() - return "4XzTC19CBJRR)pM7ZBg(nPEmPTPnZTTj340z3Zm74TY2kX6u)rosY3UPp0)2pGeG6dBjhRMn7d1kIKGGGGGa4h0oLp9UPtwuCX2IfzfVz7QTf(xKo9Z8PtMf(3hc)BH)FRGFt38q2BwMn)B3S97zfxKwCx2Fxn9cO37U)(Yl8)Z5RECjsH5PLvqxgI6Sa1zbQZ8uFb0PTRwS97BiAWoZnDs5Yu4vL5pSS6U81zf)boM055PR2R)847XPCs1tRYMo5Qnvzf3Nop7ppFXIR3u(NVFv6Ifp9NxTo9HSY)e77FvSD3Mfzl(RzRE0ZjVnVmD2QS3KxmhOXSPtE0VGpFE1U0v(1Bvr(MVLvDq3()ZkkZ3U5VwN(V3w8xB2ToWvLvPv7kNfLfxdIPSQPF2e533TXtLfEcNUzdWjZZwNTPQ0lVOz62S0fp5NHYhZM7)nBt26WlOo8LsKalZsxvT03WISsqQ(yAr1tWeLvUROiBEfWDL((TWpSYMrC3sOllb550plcBh4RHnWpNUo7YTBQMK)Jmy5iMozZJ3TTkB9nRsRYWn8Zx990NkVlT4HSkGpMrAetwU97NVRi9TzH)miiZQ(qKYEQoDYB3wKxEZntNC)257krrKNVqzZ)kkTQ31VzB50j3E17)qq593ZxuT8Y05vBdAPETiGREaOzwq(vUkl7r)dznc573wmp7Q5B34zOC)VFMlnSKW6EEvXQYQDBoLXOtmYWbJnlo5H4m40SmTy9PmaJGz8d4BLNsVfIeNV3LZtRa9(tBmCDyvSiV0l2G9KtyqgMnytyX8tQ3CL2377ZsloL(l48WYOy72tIB0oLJ2igXqeHHK9iSKtHZCN0OsWrTOi9b4K0SISu402jmqfjK3LEk9wNyr5vrw2pYQkspjvyTtQ8JkF9JWBoPnMA1XNMVA7Mtsey4bEliec2fMNcg)aR1j1gJ61MFX0lnkHZySwMu6KwJD69)givG7bgQLzd1cm7P1gwo(vm8MRywcxJSYFvsTfQ4vibJkF8DxExWcvWOcmsg7WlGOLlVLfs0GwxBKn3igNI3xS97VnNSbxpz0fPTUcyE(jFL588Z3mFj0RgEb6s355IRV7UR)uWODr26T7B0nif3)AS551MD)nHQJL5JZvOjHcVkdkkKqFslavQ3axRv5fd47fAtBzuZa4jTF)FuZg8UxD4D8yxbC9(NY3KVoDvU)UoCCnS5vRxVd1PBy2Zssq(9mMOppBUnChtqiG(VGYRllY)Xp)6)3Uu4GFv6p)6D3rt3(3)m7a2EOBl9Zb1w4E45KEIxwCd4Is(gu5DE((ZrSNDo9zibuq9oigBwu3HhldEfu0H5649xzlTq6K8ZS6Bn4l3I3N1V26zUUI56nYWkFvAzqfyq7gAtsI2YzsL2bgTAz3O)wMnulvnsVAvCodpg8l42y5)zhODtUnsBMOOm47M)pLwPBpZQPr)BH9m4Gv121b)ON45TN7mFfrwUMZSVc01XTViYEwIGoF53h2J4sMfCM5fq9bzAW3TxbY6a1M)5jRrL8Aqwot)QqxTmr9kqwNq8Iu0gGScL7fXTNPJQVKHlDB9xPbC4)fq9b1FFzm9q7Cg7RHcHqNWEnmP54QxKW9moT1LuFXEnP9rR8ci9qcyR8vXUJg8G8fq2ZGBgAF3BIPToSg8a6fq8HV34vruWDVgBCsim5xKiEiBWMx4nrNXnDuI97LUUkYVghPDCZRX9YqmV)ZYTqhB5wEt0wr3y)1DEB5rJSieMMpBwq4bz(Lr4f3KbHhVPcOj6z9(EUVVlY(uHn8ceDrU1y(1xmXOk9cPtiVUKiTjMpPQTV6Vn7(0DRQGWlwTk4x7h(YNV7D36FAD(giwoldZwZVF(T3E11TAGj0HSLCZ5F883E1NRBaCkNfgXNo)9VR5TivU52RE3K7QFRuiTje1)41V5)TUbT1fi(BV9lx92MUlTUq(YU963)LgAlnADi3it(W5F682CIIRqfRhBLt7duaq1JwB4x0vkhufVuBvoM0bUGWssaFDHyoujDdC9GqCUegIXkeovIZOTchfcde2JgCrYcN)zcRMBGnL6WEgOLzd1s1H5X42Sv3SnFtfC65nVlSF2dFINWQtu9E5oy125FJsuur66SMmJ007M3fuSBLwb2HNpAh)zNSZ0gqGiScp0wgAfmT1WyEXV15s8RAvqgAmkMb0pHWat0sbRvOJ93YSHAPkUU2pC8L9jZu7f4)VWr6oys0oM)JNPRWr62z7PDk07WteNY8uNYotiCCuch0s8r1NwfZw1II93HUOVCGubYjqXiM1FyGoMM5hdeZAI1)GqKOtcVbIdi8cPbcZaEacx24)vQ1(F8BRH2taNd99p(RsO5(hsyYqh9jn2fiqGEoorxWQsya2e8fAUm0nQDEsC(ItOqH)nlorj8aJj8hOd)YXhKkKqoj2rTaPKb0arkivyhaEfx0ACKCEOJCJMhwdcNfjfWCy74FMOzH)gSbsKwImLemWewLjIabGG2PfHvfMkxCU1ctcTozgAUXLHc0YXUOTixaEgg6RItmmAmfEq7cnyCeT8bwapyzKme2odpibXoUKfMqpsymCPR4sKtf4KkIIBTmkvXPsWyMWdjoukZ5CloehUO1c8xUw5cT4mkl9cg(qIIJu1Hssp1r5bWx4djj4AGBDwCqss30GcDHrAP1IaFrInmuDC7duMXoAWhS4aHPcL5kwyYHwXzYqQGGLLKAL5ajnCjPr40Hjvh1uesCYDACeGkeUvyX9cAhdBfK2HrlbtH4AJtNnIczb2rldfcC89wl9dEKrBjfcwcj0SjKQUIEaC0nmrmoUgfGgtcrsdPNXrLzHssKbpNiScujMoWd2gObiOJvQKWdgPoEsLiaYFAfUxgCaW)6e60dnoO30bwUlS8nOoOLtcfPj0UKtQ1WHeCMKss2ImKLtQkeD4cvTajCURQXUC3RQUe0evs48lytqP0qay4LlrxgoLCPtGIxB921mzdLNuniQnkieeWsKK7C01GpmylZgQLECyOnefTUm6yzhoMA)2ofdozCZ2c4kI8QFH7e7lHRbyMV0JC5IvpfyV8)O1vEZZjih8c3ITF)lp69wVX923eZ(CRK(3HZqgbwxWQUk)XF(vIjM2tbr4N(ECJ65iuuGg4(MaCobF3BC(OJdrgLtdxmbQPW)b2yB5q0)O5sh5vcVmVn)jRYsHvmbJ)SoajeDg8m50AuUg1UFxpIYBPr22FhkSqwn71cCVOG(tP)TFlVe8O)J5B8avr6STOztbP0IaHoTNFWH3DyjJevd2lQHSQgeyG719OsUi7Iv5)4hPfGQqaTS2QwxdRQOVv(SsslQgiZ8k277d6ZPWr7kKhG2gbZWlJtxNSkuhinvYr7nNoNmXvIVgv(2jq2)E6Lqynj(7E8Oue85bcWs2At5e8mE)GoUz5tL5GI5ZfyELVCAUGmHdQp(NNTTQA76pblxFSKQ9ws96RCteqkrq42U4F2vKgvGBcCQT0CWBm8rgfxHbSSEwyXz9yd5e3FPf573LvwMfWUKuNAxAo1WS1(LXv4jSpT4iiV2wNmI4j4vBG8FeIxNYyHFc8voWEPG6XIC4KB1t4owiyf4W87U4lxEPFIbNXpiRUndbCO6WHGEZoQzrQSS9ZdBVZs9CeYzYOMdmWJtyoAT4Tm3WZISx5viQMrYyg9ixly8HJAiE3(g1aWqpg1qGqp2hZINBJhCND4fIGDWgpga0O2fXqLgjBzm7NP9NBxmeE64gsiKTXTwcrWoQzrOf2rQRaXMzhEw6vVxQ4dlW4hUpcld3iNcbtRg5Apep9Ogr4E0Xnc5ynq6sCdRPmWsFSh31hI87ZmcfeK2WAJ9Yw(yr3h4ONXSTAyUQpTKqG0NWe0XmFYWwthYaHyKB6HeQnQrivMJiR6XsxiG(rnfHK6nQriHy8h(AH(3ZnJFwc5WyuBjHSDmQjbZZ0OMeotypIQYHBjy6rhfBHjnCudjKZ1rTqewFs5g1KiKjIH3t09CXRsZhPTuPuCqboDC5Rp5XJAka3GoIML4GzqPvhuaAh9uOrnQdTGxahuXypZsiKu4rncjtCKlqgWE1r007zDabwEeN)6BRtjhPtwvDZoYjuWYZE2ciUUKMBd(eFVy6gikQyYi7M5ijdCRZdFPd8wtOQZCegKzmyZz1bg7d66WVeN6qYXazJKvzDsW7)KyYL6KRS28bqDv)Pefxz(VkfVeVBc7IqVTO4dPRU)eIYmSfLT4IiqvGNnyYFHlirGlycmh5AnMSzk51E0MWxWWK6BKiUrwkz1jMyQ9Jaxzvy(NnemkcbHwc47n1hJdtnTpN51zChZjDIIYrpM7BCacghXzrWzoIwUeKVuoeKbH2HCKI6k4lwG2AjHjIYstVKiHpcLlcERBXgy4i8KkINcXOc)NrrG)WCMN4q5NwerTrG8JGjraxmgIOgoIuGGRnelBrm9SryKurqf4iatquZi8nOvTWdGuePciQImjcKaisQLs0MkH7IncuIcbGZpZHzmjM6)q3n0Eotr4pGqOzrefjAACemrieNcRbziyUWoaUcGKJLqW9bCic(LJW5ZQiiquIi4JorSR4QIfH30GRBeIjjJjj8ojqqesr4bhIHdhH0aukjUKJOAfXottq3jIOPOnecTafrMszif4ecOmGDrffrezmMOwIHZkebgkGLwdH6JXf32XvTvgrpuHi9fHxJWbu6iuxucAPLGBWsbbFJJXrrbcBhHtOq5q0CI8abYLurBiCgJOhtqW(4sWnMeKhfGQkQ4jueMymoQ4H3WhgTdxha3HaDzirPbLoKYcmBiGRgcZndHGMisMKiusTsS7yYkEhmr2p9MDm)DqM8AbgtB4DqgP1BEmcGdlA)L(wid19eCTsr1XsoPT1m2bbSNnp1h(XtmfRDmkJJdCXtlbWBZlZslZ6LVI3RfkyOIqXDCq(Vp8d5PnCcrSJA9UffFE3QvNqAxJziToL48weKUkZD4c6n7k2B5W7KTAtlDPb4IlTkTe0ODAPh6Eztnh1jbVE(4aqgrX2dTUG(SaCH1C(bFTku5K0xzv1fqZ)506VzBE52n9UNBAdU6jMlAeGNN2KUoFo2D4mXttVeUnmX6uq0EAwI3U59)gCtrDwU73TR9Xv9FfMWzrSsjmDK1cUA1dbyXUL3p3T9Cpurx18522sa8P0hYN3NssC9FwO25MNhuCV76B6SP3sBE5(5z3hICpFhpXVeCIkXEhkZRAac9fhB8K7HFRr)ckbDaeSUinN4)gPV4qFJrkpjO48ZVEjCk9NF93xMxLfmewJmJWsYZgJklhS89q1KlTwlC7o4wHIb3QysAqEFGwMnul1wI6GugDoz)ZwfT(E3pKPmYejeeRulLW9Y22q92FlZgQLA3UjGV2huWMkXDOYmK3uMHit3a9yJ2upLyWF0(lZSvbx2)zR9RgJGp9yUccxftv4JKNGfngM17lA5RyDvgvxDr(IKb7m5SyS8qoWpEUiwZyHyI9puxCrKlKqqcmQSMCK33sQl(pVvA0XssJtoxhRjnWj)ekgco9qcwqpGjiQk0G3GoyyJLPKZI(74yQA2KQno05WAh(XyGdmvcRBjObodI8KqtL9w0VMOpF1vle48evSFrh3IXau7oL)B5fL78O7Zkj5kEmSG66asgQr3qFOcXb85MQCNOZKqtKGweRRlzCJ0MiixUIrre9HZf93lwZz1Hvq(WXteMyeqKqKcvdlO4aVyOkSlu(svDpCCcX4h1QR)0nn752ZHLxzWC5b3Zw76ay(lwpl75Uvm(40kGiZ2vf()rcFoaJrPV8U91H)gFK1tW)F5W0jR3Ui)(8ScFlWaQ8zEaMSukjei40t9wn7Hix6)UH7NgIgAe(6I9Kq2djop0PF(1)hz)0PHmlqp3w4PK6yusngkPpgL0JHsMJrjZyOK9yuYogk5ogLCJHsjhJsjJHsyoxhIu(eXDY0QQLFvD(KQPRhWQ23cMvHR9GRGLEWg91kL3VB8AQ4hypDOB6(FSY)6URu7DYvBkXVn721Z27c))3Ll8UOv7gs10P)3)Iv9L9b" + return "4XzT8S1CBBZS)yopxp4cbiWJw2XjEoj2(y5m9RZ0rn0s0w8l6I)iPoPUpKF7FlWUG3PIyJBFiIMayXIf79DzxWx8WI5pE4PNkM5(NRxUF3DjRwLT75f3WPrCVCE2FLU4gHCX8LjfLZsYNTpFvA(f73Sp3bIeC6lUHTy(Z()n39VLvZ)FDlaP0sagM4fZxLFzwrYJBsVilF5M0fpwd3NBaZRIfmvSMXImmzSXyx80VOIC7ZvADetZ4W7JSkPG5gr627XgjFSraCSmpB3xtl7HtRtt2uUgWQBs2ME1(DLizGlwmF3lpSVmD7DBsktloFZlRtoFZ3sET4HK8Ntltx5wEEYYSKn3TVyX87V(9F4b352dLLja8VHDM19gKsoV8v4DZVExzA(tjlt)9ZxT62Df)(73axhV(7xVn550IFhN7Fu8FoKKNU6pECZllMxSoz1(VvK986YhY2cqcHoV596f73VbM0U3NV)BxMLNUSmB)UfZ)47UcqQ))08c4p)JTj)795)XUdB9l(52tD2Tp8WTFYFUZt3U3Fowm)Y95zf3DhC7L9BHl4Fra3qjhYt(ywr5LPpLCytP76uhhZC)MUZrKxTy2I5VKNbaO81f3eXC3cjl)kaZ3n7ZxDL7ArelaoUjTeUqQutBjYOyMD0LWvvlPApysMzA7HsjN4zxY1A(0wIqQTrtBjsoNhFkN9MuyZrixdFPOImtCxekr8uplr8XjyCwVRrjlsn(14a37gRzCUr5Gx7rMjEiIIyrJtQgCt4SOX3Kbo3gUqmnKkMprMxGpC8v40E2vIYePpjrWgNAR0ONgwPerJVIH3eTDQ0krKqn1JIrovTCgyxM4MejNSyRrFebKr0NieJZmk6ZmkSGEUPW9YTk2uPwAB84h9bLPeARzQlHPIMkbooEISWC5rSJmSIu2uTjamx2tsVytBcc74YjdOkvWyh5AFe17QPQgcmvjM4UWzI4JC4hYkI4iwfgEpSQ4X1XpIfuXruqoIZtmZ4NKHzHnXtL9sgfzN4s4GsIXxYGiMZu9eDGqcwugNLCinrXSJWFnm9sOMQlTsimMjYskHivMKksH0EecSQ)cuSJO0EaPxnBIUyhpzZOsP0o(Mm4TrKksood)a346OjXGOLt1AOLnvcLrhnrLjg(r0xneBUwFmxTgG5i2mT7Usx0G)ncQnF)HDRcb1(sA5hcbF)q6FwEihGZNY2LTnzdewPBlOusayWsk62wXwRH3VjPWN9IrswXvAL2ckJHa6Gqb4svJKim8i5JnsPlA)DpNEX60LF9bmDcnYQr7ChSkFW8S0alphcFUjM2oTkNzC73l7)wAoa7pK6c9hMOoKWI7sZxMUReiUUBRa1jKdGchGXqRN5m4fBJDpibpQv4dUipDpWm0C8H8nleiN7bUKHt2f01mxW9A)71AJFM(yL8lLfHp4n65Ei2qp4IBXdcnJHBSX4FdxstrAKX0QDE7JZbKANroZ7HIXYWTMtpyvseUrsCXWBm4wZ54ImGXrpAYqO5qt)dcU0I7JZr2zbhu9iLfxd6bQhC4isbqwqCHP9OGqR8ufVZx(1gRqCZ7EXSGhtEOj00fHeHVeo1i9NRrQnAK1bpbe8gDydyfD1aMi54EfjXReH2G3fWKn4MgXnkeZTccnIIf0q0TcNlqa6n7mlOx1pzBmUCJs7xLMiAEV5CRrRuEKWRhZpZiRfrgNAhpqCNKY2s49KpVkYW0alQZvuTkgqwu(dKzvcrCml2ausfxlJQLzhzK8Xgjid9PK)0HzDLblExTgVCFM8(1SvLRVkzzjGMo5sxsU862Yp8sjUga9VHxl5w(6lGER7w)ArgOxYl9Y9sYbPAxcr7o9pSFZRnMk7mlJM(zk4jyjrDxYvzo9JnwII1yh09M)55lt2n8k8BGP7cUjbvb7v)a(828q4)ByrYENK5(utsRYVb92Q5h291DGwPUl9Z0RX8itk)chiUUhbiFVZQqRnQEt82loF3Y1WfxDsDDkIBChxNT0U3ZElCPRUm1pf3wByb5zs7jioRq(BJaLj8jJdEioO5s5LDCPZ2pUnOxe)1NQOzoFgqTWCPG7L6q5tFsBClJZrfRExQCRJheoj1jHTlSFKEszqpCKf1tiyXiIW44dssjMH0AQeiK0XO2djyXdNGl5dZcU)63ldPvd07H6EcVaqp)V82QoLccnbHrsznJSBi8aWhASh0Xr(nZe2DFKq4jf1pb60XdsKocVuuG5z)Buwu7dOAerz09B4bfQAKSwXTAuZwmlOugvccexsHlejPFgEF687gh1sJk0OeppJs17mpDf3QATJazY)G1q27CjF1VwsjUs0XolOhnMEbZ)azNfSdycBcswa0dFWskPDzserqjXJQrApyVjMosO5DqTUFPQG1rGPgNOgFiMfuMJK(i0qfmkYQQjEroCmQyQ9GuZL0DehzeueldqUWn3Oi)eu4EbCB(FPloCuGOtgNiptipgaZxKqgdDLanElyccQW1oNqiosZHG8qwrPKywekIus2QfXwsqicFatPN7nvUUahlY8lsbJfiBm8dbLyozPvQjXnY2lO6GijcsSlk43sTRb49HZZB3HJiz08c6v4b9iiLwIhdnJ2xYpbJI8UJ44b6mkCetZGUZJjVhSbxe4e9boBU53WHZtU0FDRmvdLTG1)72NdkwZk)BeQqR6FrvIRy(69F7Q8S0DRaZNZWcy95xW6Wf8m)IqebTF9D0jZTm08W5llpagSFS2956X6vLsDKrbQnbcf8FG8FJQu(wgGrZWCgJ6ZjB6LoJBbp(9vGeR1N3cwV6C211NloKxK2c68wXFOBhVZT7ZRSwEMpDb(4FWaEafyT81BySN3f7BwNXQAhd7)RlUcITaevanmrkMvd62E6xazG5)jmcdCx35Uly(WBbbgr2)4v5p2picRh3xwUF7NsYFoBxiwx)jdl(jWS9xF)l)FhswLNuM89V8WdTMqOoSNbyqPVQW)abhytRo(oxlD(ICkYA8k3PPabTo3DAs0Cq7e5AE8hwU4k1aTLbGaczsRf8YgmwjIQKbWZvJZxi81M()3euWeIgwFck(5QfVtyCv(hs280jCKOyW9TXWpRwMg17FbLKbe6JGhxbUVa2CuGzoNpfstLCEpCBai4iept)MJ)woa78(SI97gKJsxt8wnIK3WCax(6UKTzlXPpZP75WUYGAWUzuajhxb(OaXEAvGJJGOPvth1kLMb(tx27QvE0knpoOtIqnnw444CQ3bMMLE9WaG24awlBhZ93xF)lxDyZMV)LFDDwzkDAO7lEiqUMYgHdtxN(XzoAMJKwjOFwQKqmV84Mk2hEK8XgPLM0gh6ggppF3oG8V0Z13IpSloxLWlhHkyMRTzBsPSx(ZVCyHSgKb)4xbwFma6YaFfDoC7SOfzc0KqGu0fvF17lQ7lK6GQQVd66wW)YFp0sXtLaMPTLGFRXf3Jqqzp7tAylLhdR6WteiJ6ZchKgu7bcLVBOHogqxE5cHb(ydgZ7tws6KUaUxEgo9P(4el2KM(I7Hgzp9P95ltdxozUFVbCNKzXULQmFtr5HDNYAarmK9z3QtEjgnUnRtY3Eklq7scKBp2VV8uMVYe51U)1Itz2Ggr)Sx(6Yn73LEklr7eCC(wUmPeUUoTTHJYzRa9KohepPtIMfJ5Ni5uMTYIOf4kWZ73v8yEAciADclmIWn4sCc0yHFVwEkZwZJ8yw22xG3CsljWL8uAs(PmFxsjw4ZYsLIzV0rd1ch3UtdR7E7eUhANY8GsSgcL48PK35KFhRLcR7mnz0Ion7iTd2(wvVE72d7s7ypgIkfnS6YawLRxoCRro3dou3v78Q6MG8x493WR2JIKhZJ0LzD0z9Zg8uOp9Q095fO0Gn8ox8TkiyPlqrXXA7i)C8jt)haM4J1(h0o5soZXNJpp(hFkX)OjifXhP1R8ZPSMr80dJPk403TlDRpY0eYE(wGHXtVjlP3NMS6vh7tHZpNhDyIBfpwnHpx0K13nWQuxApFjjV0LY40Id5K36fO5iyzf1R4H1WuwdMy91nRmyhSJn7NYbpSR7I0650PZsB0XNSMXg32pJwoS83GDTvzb766Wh37smRJq0ABOnNvPcWpzNawszimghNFh3ngqOe0PKM0jwywhNY9giPnQDko6uGd6CJhtiEry3lZE57FHKiBvTWtG3Avoe7zE5XIOmE4aQjTE10Ngzii4iiOy1PGSauS9Xmqr4nHaP76xuhUN1zRsNTj7V(RKC4ebNRDj1aTNk6v53aERFcX32mcA3wtiUJ1)RNeTAKk7u2KZOeeixx0z2hhWHt2ybkOIKwDehCLgCO2vhomU4NhDK8XgPS9HEWkxulsgjgKd0FXRRZiG7f1I1TpmtsmTLvLk3aUExrR6GpCP8XXE)H0II0cs0P2uPacAUcZ(TMDtFZa7RAgGv5JNDMMkVXaDuXUpTaWP1iMl3fUpjGiBZCN1msKasuHBajd8cnp7XdLP1L(d0EVzZI5GiNltfZXViGfZ3UFv2tza37C3nwzj470ChaOKRGm4lcfeSdqUA)YdfdddrnmEYplxi2daIZ9t67F5)romCQbZkukD1IqPghdsrtbsQJbj1uGK(yqspfifFmifpfizogKmtbs2Jbj7uGe2pBJbkN6)tgwL9t6cAdj4FqFtPntGYKuL0YIpjJhYDKtcVPATW71SWg2mfbRBNvIHtyRV2UZcv2vkzHsSrv5KjWkH48jEMVMtujm5y5z4mS6xAj1rk2iS(EwDOiyHIdzO(qj0Lmv9ZHKhAycTHQxeydOQmuyLXSru1wJ1ujJrWY4yPjfCMHGMHAUKidwqonvpZiAMwdw1yLKkFyumT)sccu7VWvrXH2tblgMYydLEeX0QUErBPZpvMtLiuEtQxxemjwBsTMaAOnwGi01eghJvSlou41iQ2Bv9Lcmd)(w1xkrkGmIqbOvbKKk3hw94QwzYH101lvQYyQ2IHozYHb(D2sT0ewFFnD7tnTeSSq)iHuqcQuh7Wny)biI1iQb7goHilUDcMLkvoGRiosuCBmYhPPQddNbIrZWXk3kfHk3YOMeqgrWh2p)2XXAj66Gg8cvASu5QLyR)qha32xrZOMvcRfnvcAfv9)q7aP0y1KvHsKhr9VK1IfhngRMmvRyhkgOGicOe48OQo7iri7m14cmgYdgPrWjXAYlSuPWd1Lm05s2iQg(XK8b3WOI(YWJk4bHPIVhXDefa(g6sok0xw1TJfJA)cIQatbjyapmwvCtGJsvDXryKbPzamXQElcLYLAyQQoYYG1IvJLVMJxEaNEqqYsLETYrB0xTq1wIaCGB02qsMx1Wxij3RPSHBIRY7MrI1hTflR0Z2UFcFj03ISQ4shnl5rGhSUV7pxpTfRJBKL8HhjFSrkPqjUiuhcYHpLUxcUpXGS6eMkDsgjIWbQKkATPxanDJq9(0n3TpBxjaPlE3np8U7hFkI6PqrZIrR4ZqG7pLX9AW5KMvI6qr5(T(YOm35S6XIPIH209GLR4SUj(4TaUUQW(Za2ZSckmwQIznboyMUxxXpjOpks377z4nbSgz3Cy9wawDuVUK)TaSCM6Fe4QK9(yKElaRri(Py0gbSI(F9MtcSUwH4z63C83g8VsTUBR(pjOpk)7phsp2nx)CW(wawHY27tP(TaUgEVVJIjb2Z40vNTktpvG2vxOFcqpgbU)NE1BbynkE38EpjWEgyzOzviS6M8WkB387pjGpUDJ)rifG)Z)dawj4u5pfjEmDW6FslrN5(GqAWe7UlnTzK)NqK20)d69TaSC1BSb0sY1Uw1KRUbkq)cnEVGRsPayMP6BB645SgRYEiFH9CBSU1463eIH(GPrXago1fJ9)csQ7OV(NVw(((d9uoRFjmV8aGaz(6(A67k7V5p)vuXbkRqfT0L(P6g66H9N7CV)6vDAhXjL4Ow5GEzMF3F427w0mrXnqPxAqWhk4NqdQ267ajCBDV)E0HTHuPp8Lurzs5HIhd08WPx3j2PjDoBLGSAuI()1kZD57Zh0Wh(SpAc4PTUgy09fU6RI8VE(93F9TngGju(ok4UZ)45xE9nvdGFtsWaF683)U63Iq5U7V(DZFO6TsiWylb9pE7f)Vvd4J9fE)L3)5RVSE6(oXhE993((pxdB8licE98pC(NoVjM4(8M8sT0Lj18sU2YF(Jv)PtN58Mnk7W3kRh9lpIICngca16YnueZ1fu26Y2mYi5JncGbBWQuoBrVYl(PKNZw2sjsWXdnPZ2t6sQA7OJR7HxR7XxkG6YL1TfTQ7SIQulCcTg4aDTNd4BstGTH2ShRP)D)khBw(LrYgRRC2dqNgGe1aTcfz3TYULH(hPJJKc7QORb57ekoztcWjC3SEI9c9JHUvPjXSsjB)Vwj)jQvHYA)HW(3xzZQ6MPX00iZa5hzzwvoukxS4)UX05ig" end function Gladdy:GetClassicProfileNoPet() - return "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OoO1qcPS7NT6usGnqU(xfDN6lv0qvXsNnAGYIsBB1eWxykwXaTjkHOvrOVWuC2wDm6Lm8sLQFbrjAz41sP8W(u(I(JUJ4C1dBH5)g0uKyIZboLiJBOYsKYoqzbc1hpqFfPnjU)vPt)EaIA)kmzB7iigUbUeq6vZaL9OOJe8QBrpoEGo9qT7dmaPlX1VNspI(q3Uh1UV7VWmmga(3WylyZBYHTT7fcBB6NR6YlbczFs5f2lmFs)rt7laHAGgDhi6dBgAJ9i6QoI05HrnOLiozWmLw36mQEjBUD4RIX0QlSVGjXQhAkrWUFKiJDB3fQ4J4Q02Kit0Ub6OqWEh0uIuM(Nrp4uuQbM7rPtu9BtI6iXRjsoWyPATQ1XlFC9RtpqXaGbDeplvRvWezAD8)hDxO1mOnTakGwNx)licjIHImtluhjbspXRoINEhYHkP9jqCCtNrpqqwLydQsxLXxtgzZQyQFMV6(gxdor7Me08qhQlo(EQqnS0mUA9Qg9c10ewSEVxpnlWYF4Z71w5)gTByVg3uZM32O4wuaM37rm8pAlD2tAiPeTrl3m7BKICw(5RNTayHAvcYCnu11hKWHkrVLoBE4kgccHtarugHrCJtIXFaahGe74tCq2KrHkAGFeJHyH)I1qocZcA9ZuLaLwGJp8xazGe)rIq7hi22xNNaE65tqJZtcbv8poHEqKu7hg)EkKoUEHfeJ(I)BryHsKEgtHTnW)xj9dTHieg0AKhAorjBSZruqBObGfEokuBi(ePFGsBK0ldGdjrkG5O3t)tFjfiLumtA1etPncV2ZLO8eWJA1leXg)s5cRTVEbsofwETjXWyneZefftCrusIFSgjZWuYl4hro)lSoMw4fza(rSG1HG50)dnO2jrg7a4io4MF1KAItv0IQcQBeH(iVwLwkQStCQosl7l4Zpfhj0rk6Vu5tJ8LDgZpqq)iXijQ6injsDsFa8f9JKesgGaJX0K0SVPLu6kRoMLff9GKy)uJcMpWzMgOL(rmnrcjc8dJWV4WBPvYYUGsqqQCM9K0k1ShHlYVOrbpfLMwCxendWfImfXKTGTy0BbTTF2AyFpjBsEVrqjRObgliLGKEECm)hAldKcJCiejSsloHD1n8pKw)i0cjjJeqDIKw2ptsoZkJMjdTpbaRqoX8gEi2apbfVTcrloIXa6xEftaI)8L2mIbiJpoH39WZdgnVHv68IVL8bJLSsrB9Vxlz3AytcTsaAy)4PntG2JDvy6ivMkfIFFxzDV93)6CFj4jA0W(xiMGXeLy5qYHgt(l5yKNxFuNo(a29rK)LKG5W(z28ATZQQFj8XZGckbmxAnehhCWfAf27xZeSDQ3UPaYvLx(3iD(ENEqZMqFjEiOZxw3h6gxJ(P1dfFnEdj(8t7FJCViCYunaUCIhQvBqfEEODxJFjcfmqEJv9z)CcNlsn8P9ozeJ1boM6yrcuYLWfoLd0wRK2yneVsJ1WinnT1gHesPhPLqQB4H12ATsfdzjIG6laBUO15S1)LyyzwkOai1qJU53eY5zAe8tBin(bU)TlU6ESWNkMOsD144mdm1Ns)l0SUfCh(T81z4NUabHkqZPn)Oxo88qpO1((N166YmlV5Dzam813qdaabEjWNNnAz(p(rAXC(EW00R5gqycsmI4LLLgFRqOaMx)BwPWWhJRL1UUipvoHNORe9zIWMQd03nftgS5Oautivhf(w5yuxcfLLdcgZrXzqvso)HGsldGR8tmMt3KydjNdqpJzetwgiKsX4DGOo8ySok5cM1RkNjLvjXWzzPSx0eGKuesjfKjLPfeWYptJJGjazNioYWdnXryyJ0mQgtmV8AMeyx1X)DKjMEHGMbsQaIiMrv4vzWZFuwVehP)IubCxkIFGyNeKjaVdlSskxVsgzzwoMqLhhacAcWcKeernmcsw8vI7)bOfjQaQQatsqbavsLwInQmYP4auhdbHgxz)kMesE7hULT5cdJGGabht1eW006yGEurkQylXqWArdaawqKdcGjdCibF1Xi1JnmigJku(GtfgkjvIqbkwsUjqIAHqZvSWWyaiF(F4iuyscuc4uYCPKWLgq)gXGVvb8qrwUglGIetzSSdCcd1fyxYrrfW2kuvAmAvJu0ybifwg3M1fm7KuhRd4)new9aazgjV2X4Mmkw0sidSwXaWCcjPkiG3msFLXr4Xc8adtfsHZWKfcMEcfdCZLqgMeIhvGRk54PmmQwHKC8OUs5NTJKdG7iOQwwvAjTd7SaRgvYKLrnBzmWQazsyWG)1KlbKYyEjna2m23InaSHUkw6h2LTDBMp5)HDX42fpVnhYbTxurr7R7qjEoZJQV7hdc1YEnHy6MYYnR(eeN1FNaQVeG4Py)ToR0VUrmGgcyHgdcXxgYfw3(M9X6niE9dl3SDlFpz(vHADXats5ZRXFLv1FLxn)0XQU7pnFyqxDc3MX5h5kzwLvD)VutpQt(IA2eWZXxn)Tqy6l(Dwv9HK1SbzQd0C9WUHIFEC)VNybyhWlLHd2GQmv3AgVdpD)vDe3sBaAILiO8TIg4KiVVaHHAJG4mwiCnxcwt8Wn5eG(M2B6Q9kWp6wuLs)l(J)1dA7JPlF4emLpvJFC6(ORgY2I9k8GjIVcl8EYLwgStOlw7pX4Mc)j4o8u4Qzj2RCPM1YrmqJNSFjUVCTg7vIdHKSAJuBbyEb4tvuEK7)9zX1ACQhVTqJEyOxyazPBZ6KAbxrB12Jrh7ElEI7QdrfQaYIHkdv(XAbhkTxVB5Yt4QUZAXwJ8YyaNew9lumveIMI3DHnuqaz)K(9CrqUY4QAY2JIi)8ghZTsUBDVVzN7UU2xnRoOFxb3KdU27ns3UjF7M1DolB9gG59KiOLbLki751PRYNrdF0Evx2DeXdzQl2vCGBOCpaa2U6SY)2)(qkLUxOMj2pH0A1b8UFZ5yzIxnVR9nFk9X8zDXUbv4z(7b4SC)UK7V529CRAS1zXHXZXtEUJVs5WHKu5Y0GgnRpS5NAW2Y0YDBNgcXeEJTY883aAYEWO8b8Wo)mgVRGJANIKO8yFeVF(1lHD0)8R)(I8YSk1rqSRoDR6aEl(L(LNqbm)shFPghU5SOX)R14noarLc(oWU4tXCq3eQVuYZlETwZd3D180jd(JD0lZV0WtS5Tp9faU1x4ns72UXk79)wbShCmEhAIM3O1n69sWaoQHwmEq6AstoPvBT9TwHUMb(kI4JkrltOtFJUWCJAuYE1X1uDmn4PnqdMRzp0N9wTtrQch(M)40XFuDknCL8AdFgha4oUjiAEiANM7pr1z7j5ECeoCpPG7Wa9bcsRe1viJHpop4juDEXHZ7XftLD6eMk2KpKrQg9Q(UqhFUNPse7FwEqn5epPI4ZpmuEzO07QJDbQHLp10q9ZHwXuvvlu4lDUAGbG1YWEAjlA8kfoqfT)ov7hdFIgkRJpcKqn9WRyfTkCaz6GHmorXv(gAMtOuAxOS7WH3v1DhUuAzIYgAefRe5oMrxaCpVy5JQ0FoqHKQh(jce8mP71nuMTZc6yG64rDIDj2u9)4FcNGnhOFYHF2h)9JsCyeOgTMTX3OikmZYRILxozY)5)uvaqQ" + return "4XzVCTTCBJZK(HzVECHZe8sR44exBIJxlNAMPQP0ekjABUrs0lj1MXZf5z)Vb6gKu8GIyItUjHreOrJUB0h(AWSGV4UfZxU)(7lN5(JRwLV7MK1RZ29WIR50BC)48S)nDX1c5I5RskRMLumlVyDAXRY3Kx4irYIlnslJzTmU1AemlFX9)MwbKyXLwESkYQfmLKlLrk3B0lM)WOVPyS3uTy(AyrZ3So)l7oFZtpMS4A2zw3VErwzYYnPVkRy1M0flBy0hAZKrcMoYWykltgzTXnmPXOygG5zsvSwkyU3i9m5iVPyS3amzvr2UpNw1JNEkT6TPjBQEeyS3MM9WJvlU2WwmF3t3LxLU9MnjvPL(915B(sYZL3Lu8qAv6A3ClswLLS5M8YfZV9Q3827ArTBslwLURk5H0fZQx8EAiVcfyAy3hfhRzsUHzm8wB0HFtXyVb2OLpMaQIs3o5USTPfGuh2P1MoEJQG(6nf5F5ISI0vvz57wm)DV(sGT()tlkH)5FVn5)nV4V3TFRFYpC4qN9H7U7dV3lMks3MxCz(oyTViViR8MB8YH)8dWcLcstreSv3xK8USYQlsVpz)Mk3U3efXC)D6oNczTtm9urgqGQNxCTI5eAjR(mqZxp7JxEPBNjIeG5(KMcxibB0jnfPkIfp6u466PuVgmjZoT1qRLtCVdAzdFAtrinXQPnfjNZJoL9EBjS9iIRHvkALDIRIqlIM6ErXhxGXz9uJsMspUACa9Un2oU1OCq1UYoXnHsbNYN2IWzQXxKb23wUqmnMkIprJxWoC8zWf9przvMt6iyRDDS0AMgxPfQXNXWlIjEQYkHsON6wXkNQxolSktCruYjFS1AoYbKr8NieJBmk6BmkIb)CtX6L7IaonMc0IrJV1h8mLWeBN6uyA1ufWrrt0egYd7ihSg0rkBQXeaJR4tYVy7ycI4XpNmGRubJDe1(iU31t1neeQsmXvHZerhzZpuueXrIkm8AeRJg3h)irqfhXb5ijpbvcmrtyB0unVKkv8eNchCsm(ugKXCHQNycesiIY4MKd5jkIDe7RHLxc9utPfQJAQHTKqvntYfPqgFebSU)e0SJ40EGtVg2etXoAYHrLsz84lYGAdLwjh3GFanUrnjdeJCQrdJztvqznQj6mXYpI)QHmZnMJLQ1aghr2PP7QQR7hRr8YIS)9RF6)zFY6IKQKV(P7UJQm9pcfm(Bq5MRYi8nakUIQw1nFQAw2zg433Ku6Hc5xsD1bUOUUwNWP1od5xx2SRlge0MwC55q5WT50RzoUY9Nfi6jW69u(xslAbkbh2Xpoa2cb(kutFPJWyPYZCbWIIJCpiHmK14dUDL7bMLgJVeUzHcZCpWLmCWUIOM5kw34)DJX6hPV2h)uzk8bFqm3drw6bxDiEsaIuCHTw)VWL0qKwzenBx274yGtHZOKZ9uXgZWLMtpeRLiDvsCYWVyXLMZXjzHGDE2KHuZXM(heCzmUoUetNfs40ZuX4CWmk9KdFJuaIfKxygplimAVuXNmLFUrAK38PlmlKbKNAcdPiKi9LWUgL)CdkTXGMo6jGIXOnBGRivdeYJJRLsIQeHXI6cyWwCrvCRg58ybXgQib9ksRW5cKG(WiZc(j9doocNUvB8ZYqcnF2zU5y0Apt49l5hPkogzgNBeprC7eN5BlC1g785lkkK(ZlVp5FCCr3ZBLVUXBvHh0UFpBD1JxMSQcyjh34aO6QDvPff7FQcNdWQxZB43QNFkDX8BE85YmWhK)Kk3FQnCc2b1v3H)28np3AOSZIz0Wptdpbtr1DkxMvKEWu0SwRGP34pVyvYUHNHFbSDNW1jv7PLGDgKVA7nH)Fdts2BNm3dRinl)c0BPMVF3N3bEG6o1ps)SFUbhDHne30tauKxw1zHAweNN4SZ3T6rqXr(dblmNt3w64gKo7QN9rNsxFrQFiUL2YcNDjpLWrxnAlBfO9Vhin4HOGxkT)CId2A)7Jd(aX)2dZZmx8E0Jlxk4(ty4zrpGlUPX5OtuF6qU5XdhejxhHLlSEKprzWNRkg9jiyriJW44dsYHLL8qQfiLmrONcjtIot8ahmlK6QFTSKhmWhh6Nj8da75)B(HUjLcInnsf5yMrXieEc4lR1t6iLFXSHv3xfdUtrFrG)BCJOmkuPO1rixOJrpnGBqKLXuNHh0OBqkYep2GEXIybhWOdpq4soxHQa9JWNpMF14Ohz05fbA8mcM2zE5kUunEcbXK)HylfBZbCQFUKdBWd1HXubFMr0pW8pqXubF(2WIGIfG9WhIjhYouargus2Ogu2dXwIOTegkhCH7NQoejemQXbAWhIybh3OOxHbLG3IMQgYwKdBJAJApjnCjPJ4OHGMmzaXfU4wnLtGgxlWAZ)3KIdFli0Paruwiu2bqOk6qgdtBadulycIQGANtmehL5qbAOPOusglcnjkP4YIOy6GGcFaHJZ9l1PPaBlkulkbJeOzm8xevI4uuvPHoUrXzbxhKirqh7uHCuAsda1hUSMDBosKrJl4xHh8JGsAjUnmmADPCcSAktoYIhKZ4HJiAeKopIYuioKoaNKpWEZn(wjx(ljYC3os1Zr9VI03P(5vo)X8VaLGKUBnezEg2xRp(e2nVDpK(Qhtx95xfkS4WF(gsO5Mgg558vv7HCbw2KfEZ761OtLbs3vjJyXqAImBOPLUnQuiIaxlAiPmG5B3OtMIXHOhAPlNo4hB2OcUjscNEKUC95QM6uWss8b(GmsaxDTAqRVxLyB(8I(ETdTRc5v7lktpOuf(bLQyClzJi6d5f1bBptJPvnEzFTZr0nQEManzyvqPy0UFJ1fmcmZZG9xmijKsiOiCEaelGebopn)FwCj4fWjALW5SipyiWBK93R1529nQmBzEvv(23Nu8q2oqc7ZQW3F3X3PTgqOFSNbCqLVzYJy)hwAxZ0dBFN80LxZVKJmE1dv8zSlTR2c8GMDm2ULoB53SLZ1UJE4WRVaKAMeopezHGMcv9ndaLjTKnHsMBxZrBsbdq1xB6McEw96KT(APxx82Kn3FcBj6qM)Eyu9mOpN7lE4(KvP)15Rx)HDL)1B2KSE9Z)1vBH60l)luH93L)F7tksx)3l380qxXGfeWgi17REHWhmNro4vq7kFNKio3YmRfsKWjN0rAijHG6Th)(t2OP3HQ8SY8DdAxBAudRh58)W2sx88UKTzRWHpZ58D)UQG33UmW7tEiB1qEWcR)zIgdHw4T4avSXXwTD1DP)tLBz6xFlcaKHSMDXzGbTYhqaO4ghvPbIwmZ92cF9txUFZMV(PF)XSQuI7jBbEOy12N7cbA6wydoYFj(fAKkTIKh4R)OviMdmW7YW1O35KsHGThMxcbPMxytXZ4SwYa)7Ve8QBnYygKmSRIcxmsLniqcvksoGBPlUANtKoRDXInY9UPS8hOSpWYhUhRdi9NT0tlH6mHCl2VB9b(Hg2lKFBtjtmlW6TeUdGor3KOC2Boyfdv2U0DOQRmhseaufpKd5)4R9TCtA6tUhAHM795fRsd6Jm3FFnKIml2ZORQk2uwTF3PmhDSbnx2T(KNI1GlZJjfBpLjyCGy5wJ88Qtz8ARYhP4ZLNYOHS39JE1ZR2KVl9uMIHhH58UkPc0xN2YWXZvRbpLUmtpPDIHfHyUKCkJwhhrxvVKhY3vUSinbonDctur8gOeNGm27rD9Qtz0gUYZzzBFc(LtAkbRK7ttkoLX7aAzHh5O6d)DV5FhpYdRtac3dhc5FWVvRtL44jajDhGh76qw7143KQfDU5N0ke3pS2vB3UF3HzMZodQ0gdT5q1leY0ZBT6zGBLZ67zODqMUl2L54XXJLv8QSooSoiy3PLEK3Fzi9OWDgS2XN)WKrRp6vlOYv4R4yxbk)y8nc4BqMOJDvuOvYb20XhJVhehFirFRba14DKRbMFmvngHNEPu1ve)6DPB9LdNSBhOdwLUfmw8YBkW5TPjRF2z6u6YPzPJtCZyz9a(yzBZEF4NuhmUpLuu5GapTCFbL1FPBCRDtRSzg39imKhH46(E(vfcc25ELEFbKPEZnATzmDULRnNPCnq8XHsuJ5Qp9(8v7jdDhR0nS)7YDGf72mhKkdsavt))8d2DijPkKxGZ6TZ1IM3)Gf4tinPtb2H0JvlAvInTqToInqcO4rn8Kfu3jS6vzp91prfD4YjjalGRxAGkaksTO6yLEgnCL3KBPgbqReIcjNbE(CEWkbppVld8uDDOI7WEiG2qhv8JzRtNTj7F)3KcGLbgFxsdr75dDDX1q6ZJUbAy)2LA7eFuJaMfAdGuYc4XsqIZeiSzohoZ8aus4DZrS84meQuJKAvzScbdgY7HqmnGKOLAqzO9P1n6dsTMWY3yjWfvYgmlryuJve08rgQ)cizzCehBbNzjQzPUoQSi6Tgc8BfnYyl2IbTKWAwfrRVKOa1xuOqYOqFlrKt124ao1iNw3outmT)jmX1Iaw4utqfmjcKTXqen0Fti1hdXXri8Urbu6veqT1nSegHFDRByPsdIrKkGSkWKe2WyRgQ7XTJRj1lHRDebeDOf3ooWVYXuVUXMbziTp1nByAHgvJsqIQuRC5wSzsIidYAWQHdqfJlNGft9vb4vKhjjECeAhzOwja7bYqZYry(Hesd7gQJssfrFy98lhhbEgmWWE3kL2yQ3gsSNW0gWT81YmQl2yJlO(vOPwff6tS2GTEqh6NIIASDCmIKEe26bQXcowmibrgqlWXrTOWjIqZzQlxmgAdQmi5KydCeXuFtcGyhAPDSIA4teD(GBzuhcy4wviT2A7EK3rwaSBiLSk0W(M(0ZOE1rsfyiOadSHXwOydwu6AfhXrwuMb0eBrIiG7p1j96w1BrG7nyVo4OYdS0dhKIjC6BGN6U8ZDUcVY73SQD8Mkiu9JLoxH)sQ(p4k(xZIHHxCzr85b7VBtGELOpGYTcReWR0f6QjzHd3mtkx13SjVSSMdRZEwaNEAs44etfJiYB2NwwM6tkc2jn3hkWoU19pQ93BuBCiRVVuRpYnTQb7M7ierwgsJQF2k1y6uFLNQt377qGDqY9DHedz(dHX67N6KyjaLNtO0n1UBt3CtE2Ukyl9QxF9DV(2wAn35TdRVJ219kVB2XUvBTnEpbJG6KHqZZa83kWFd3AGyf4XfIv6wa3tnC3YwqqEli3oGDD4x6V(hVpBx22KnzUK0rlM67wxSlTD62RXACS89Rp8zX9QakTKYwB6H333kb2d(shPSWRLiJKT9aT(cnYgP3xU)4GRIyBNkdk9OAdqC581m5(NYOEx)0K2y8VVSkFRhn55UtAhlbwgwFNNSCnN1TuWxc6A59Ue6tISNflOAgO(o0M4qU19UZYtI6JY09UT5ViK1k7wv)lbznQE3H5xcYYz6Fk0vl79PI8sqwRq8dzOnczf9)26MezpthmFPYU1TTFLgt3lI9KO(O2V)ym9yAU(Os9sqwHoU3h66lbDT8E3Y9jr2Z4KQlUoyAnPDOK)dq6XeW9)WyEjiRvZ7Ie4Ki7zqKH24YgBABdRJ7I45Ki(4Xn(PikGIE)jqwjuj4pKiEmFWMFWirN5UE)TmID6s7HgY)mosB7)5w(sqwU(foakmWvzTa1fY6RP)XyEG1T8L(3rhKZ)5eU2owPEMdKd9n5fvfjzFp13CWD7yv23bfoiN5X(pGIMc2A3U5dg9p6sFyA2FRKYxo09SU93SZjCTo6wD2FIQ)(x)cN(BDXfqX8(7p01CqTNu327Fjys0cd)jjI7yF4Rh5UpCZI2fX39(5n0)XQ06Bo6eQQmPckpA5(Q0MVNHYNs3SXDYBN7Apnh)F0KfZ3MVo7(S0c3BGjubI35aHsOBQfcG(IWx5qhICPRrkdtdrdn8TBXrc5aK4C)G(6N(VKdtNgYSgRCB9IW3pXyusnfkPpgL0tHsMJrjZuOu0XOu0uOK9yuYofkfFmkfpfkHFGTJrkx7LozAv1GLWG1OxwLuTVCzWPwWZPPdSPh(Hcf8(q)VwZChJ6lW)TF0Jye80w)vanI5VHbZ)9ZV92R(qRxWeA)DH4MZF35xC111Va)AWGx8(ZFZRB(vKk3C7vVE(D1)Q7IRgtu)DF4v)31VWdUm87xC7hV6IMH7)UiGF(2p8Mp2qB8B3c(55V983FEBoX9HL5fG9VPZ1x2TwDwgV0v6i3)FnzHIUyUlOP)k1gpokBIbqzBmN1VO398UT(9BfmR7xtj649sTYr5yTwyvknKxngMyDZL3W20qDVeRds0nqj2oY4i4gM9ljo2M0eyrOoIUSHX6(XR2w5FuGoh8G3gSf6ZQHPRj9SAappHeew3cJBj)Gg3Fkn)1DveMDqcED7MWWFYUJaGiTvoaj(d)yKNuMbhK8vB1YjCTKAo0ERpPq869uJbA1If)NNPuI(h" end function Gladdy:GetKnallProfile() - return "4XzRB01CBJJ7xuZWVj1J1TBA7mBtZTo3CxNPJ7QyRKOR2w5KKVUzFy)TFGeG6lBfPSXVyRidcaIVbiZk(QBwTCt5IIYnzLVRyBrP)fPRUIVA5THpVp8zP)ZA4DhU7UQpTUy)Y8)mB1vsn9Qf(pE72hFax660Q6fPJIwwaTSaAzE0UbaQy7MIFUhXXLgjtZKjkRtYDMe9Q7EJwcWNUopDBFydSx49i5ww)02Svl)0(6SY7sxN9T3UzZx2x9TpSnDZMN(2N2LEFw13qy)EzXH9BY289B3(ONlEFEv6TBZExE5Aah32UrUV7MGDH60Bdc6pMLF)d1RUsyIC2VS3J2nRwSA5dzPBRFaG6Q0DzxwSVgLKC2fGSC)J3uuNT76TP1zO48TB)z6tv3KwEFwnGGBj59Yhk(5BpuM((SWF6FpsPRlQwT83(0h(yqV(VY3u)WLPRRlckWwIFt2FuFOeetl3vuu)WQLpMv)XWpEDw56S91GqYZTrtJxKq9dBlQaU4bqkSnijwqCDuXfyYB(Y1DyiK4DKhIUwwXf(HYIF((8YS115f7B2NRZNTHgiGlZ2vu6j0QLVVOmV6AGns9IYH6EqK81VaepduLVrZrO(18Q63NDx6HT1EkzSwM)7Swf8JL5aARFA1vQajfoRCCy4ApmCHuRNapCMK5McgNsmoEqAj5gdFs8y0trljxiuJcJGGHZTtWpIeGHghgKFsGObtXZALBsAzzUX3xsepMeBYuWiCSXHH07Me3u4rW0QPWJuktgxNs8J1oUiKepYjTcDjUXfYrgozCDosiqnmfikftnUQkkIfjIPCByQXjvJLJDCsHSJZOM04s4etjHDalpLUuzEMnf6ZWvYjTT4mHDC7yCNl0c7ukcbeUyCArXluQKPSCewHysrOd28tPqDQKNzFHWKiDtPkmSPIMQfQNjOJMcemPcviteJlC0iPSUPqJukytfdukTtVVLtg2wPvYXHbnbnQPmsfc9Kj(sytQfKmXZeYj6w9mM6e3WyptkKO5NCckvhR4OTyIpTB3H9z(L1wsXfjjyvfxWeTfghRb5fvOuVQpd0(F3uWHq5RJohRgc2MXAdR8CEa2Hf39)YkRGYI((U0)tr533Fyx4TBkBWjGeOMMRlkRltZR7utkw6iskqqEKy4YIYD9fcDRR6cNxa0RjIQoiF920QqldZUiT1u1EFTdJ7R961kH7S5FTOIQ0VF9QBkB4yolkv)AFPFqP5)D8pBAvG5xUxkDnq689GarCSEWxX)u6HoR5fT9Q(VhslBKuf)mRStNm8U9o0d5iU(RF)gqNvN)4F97bX0QL3vS(q1C04bVN6Y89)GeorlAWrls0o9KCBlZ1k8DaU3Vhi86SDaCvEIrO83Ys38KFvvpMT2)D2(SDHxqa8pRqZuKs(FytwfWs3Tg(OmR6qj1UrWXBJFrvTWFZdaipaMRXqrbM7ZP)HheqEUp9DaBv7TMjpzDttHd6bjSY(707kHEebBnqqJIJ2fsVLtk82gvKNW)TR7ytJENQlqkgdUOGu0)NslMXy90UUPyl5SlmDJ0wtiIR5m7zbtqsHXq0fqfwy85WedMf6KmlM)9mWyyXsVEe5K6ZcImQKZdI4m9zctAj2fXRgroH48ypjOMwoL9KoAorHz1tJoP0yKNfgZXhLXEzisBSNhLh0Xa78eoWXvJjKUGtc9K2KetGmMLFw4knnUMxnICAUySThegSBM7eZ0OtQtsop8f3EM2GC35rKlfjUXevVmmXnJh)9cUPNrLxl4MgLGH15XXXrZ56vJiU(vNAOowlXyLC1wNhwHLp6xNA68vs0By1)nQ4SFb1un)9kbMpGiiVanR1z0WThgHq7By6T7x)aSxA3g(I26u)t7kh2)e0yW6FKTjosDqU6yqh8l8JBXMy9piej6KWBGmpHxinqQm4bRFOeW3(54UW3ZVjSsrceIZdF8BLqZ9pKWKba5sb3fqqaFHzi5xhh6xn86e8fAUmag974qq80lsq)8m8)nlsOeEGXeqPn43C8bPcrKVFy)3AbIjJ15qmivia(zjVi2RV)n8aGCJMh2dcNfrfWC4VJ)zyyTEmjiM0irMsQybPNlreqqySLHnHvfiLlsBTWKq7tMHOnUnugfYmATf5ciUyawfNyyCsjWdAx4hmocx(uGWdwgjdb1z4bji2XTSWeGim6Ia14sKtfirfrXTwgLQiPWrq4xQdLYHjFhwId30Ab(noN6fHXoAPxWWhsuCeRous6Xokpa(cFijb3dCRZIlss2MguOlmslTxe4lsSHLQJQpWygb0GpyXfIZNdEqXceh(vKsgYeKdBKgJ5aknCjzr40bIQJwkcjsCNgxbycHQclQling(RG0oSAPHHR2YjFJOqwGaAzOqGJV3APVqxgTLmiyjKqZMqM6k6bi9qGqmoUhX5FIO0q2zC0ywOKeAq)eHvGgXKdpeBGwGGCR8JjDbndUa5fecq(lmx8f04a9VoH8EO1bqtoSCxy7BqBqlNekst43LCYSgCsqkjLKSfzilNmvi8WfQgbsWVRUz(fX2gV8nGtKwbriyYeiKMrS6U3aXjA61EoDYJZUjFyy1yK94z4fISIdmEXQ2qRsWvh9EdNpL)bMJGj6c1464TaqGvyOO4E3q(6cr0LwedigoiGG8j65WqbUur2DsUJC3Keish07lU6y8wFyr)dXaUGLeQ)Wspqkrr7uuiw4nos1q(GolAa6yQg2Kc8Jkt8018ViC8ybMkH1p(k3I)IuOPy6qqi0wYO77kiTXmzcBJ1jrzfAFkHnlk3b3zuaPKO0f2AeLIg5qAgYktrwzcJJmlnChzyZjbTig0sgvKqAnYJKJXGXjGVGoeQfDcOIdSEbov6W2hcXH7fjjenu6fJgJscH2O0hbFtFDqhktp(AdG1i4NwZTnP)xet(dbFqJkHp(H)bTokXqo0HHdHSBuwmxcMB3edpgZfBXvkO92XMPGcdXTKSLCgk2bkvS4crjILcOtyNrsHemym4TJHt1u6nnQo0s04guDuaihNsvOSiQSgkFUcT6BC3qBsUcf8axRICnAMbleJKJsmTaZ9bjIXveMHVhdjmuVRrVPgJpeEOlCDFdzLH4qswd2MiRQfOTLGRnK5lza5L2rRwYq0sjy4kmAVaChOW(krmSpzhcRMkOdRsa8xWecn2HGbpYBqLtnBFmkeLFIeJCe3gSsG6JNlxVqPyhV82(DJd83FxpUSmpB)MTp5Xx37Wq3Pl3mO9W1R4x)LlbSFFzXp)Np25MS09WaOjGE8fFOZawNbFIErVDD9H0Tbkr(zEE920Y4eVH6I60BXmVqneQoX11yKx5BfOD2OXDY4x3LH950x8gVBonIVoI2iVbHp8c9QRZk)189e4bnDNUoAVGtDWqaOb7JTf(Gq(Le4DsQUWNy9OMyAnKE3HYQStOLIZxW0y9niiO)qdwUnlfq0ZNIN3Qu637v3M1idQ2dskkJo1DRPr(ptZSgP1ZZIrxNgDyxlEslU8X0YFmds(hRU05VnignuFHkbcAB81fj7yipq9nuXC9dpvLdMJJx0eEQn1(ZCyXXflrxhoOdbixCcKaYPGyyg66WDBrDDXUpNwEF(E)O)193HNSR3HhQg2U7Sv(KkU)rqe56)gdbGURyHJ3Bs(GnmOZ8TEAcoE8apaBXgBer7M5RT3snsO2zudgVl9aDFFPWm4PnL)JdPL1pZ(9cBNDaH(gELpWLEWLJdJX0Cj86gLJFYaGp)b610jWGi3wKFVqsCmDMlW3TTzCt(USWHiNwh5RJP)mAUO3I6Yhxcn3QmgwsscxQHMpJoiNajOLJ)2x24y8(N2NUlFnIWq06pMU9UzeNPBKZojzdgkVeVGEJcJCX6Etoxhperk)F7iX6CjrdXvJrJz9LwZWZU3D2TjBy)gaNWg5yodt(e3shxbo9dhDxeg7I4glMWeoU9RoSD7mIvC89iniBx8LBU5lF(4y2aTZshKon6pQ6MqTjMsBcV6Wf1TDgPeBFcM8I4Pu664I3A(8c9gIhuVH1NhgpYYXK9dhYQQYQov9fxxKxbXuofEmTm0MrcgFKBtFtTN3Mkwy3mq7J9mKcwU(AN)nW7Rzt1M4AS7yogryO9xBuJBkER)C9)u7LXUJG6ZP3NV(ufIfLtGA3laYpzYLo1g(Wqnl0vsVYHNH8yD(jQ95OsHRQtRpuDBuDexrRx7FJS69V2nrfXs)vWiukBNRRaVxnfdlLAyV6VKSfyKKEIas(nCevD)3hygi(jOSqMbs3aLIPuq)0qV6qzHQJlRT7Dd6DqqX7Hnxwy6cvBZYE0)qN7J2DfLRZ82bElRC)3xXLqsnm8CD52Q6d7NZAGkedPFl3Vz2lXzqY8qkExVMAbgF72Wc(r1CGwisc15wToTgmGM3A46WUyde7X3(B9CwKXFmW(fTEwqZvHtZ)US0Y5aV)yzccwW1zoWRDkhPiEbljeIOm7r)fbA)6SzTQeCvBktVh6f92YSuW3Eglurc5dPZbATFqEE5vzw2FMvxMoltyTtQ8RkF3JWBMLIPXC8P1Bl2plrGHh4TM8qn3Bk3GizZWdVPw7orK7ovKUv93EtaNrj)DG(eDomKT7vp1WGwB60pI)sF1wnceMniCwCu5BbG1D(pnkmCPFjCL4Izi73uVh2i7r0IfdygpQvs6UA4v98vKYyqC0J6W2)rVi75nzkQxT6))I8c73a" + return "4XzTC91CBJRR)dZ95nJiPif1JXnnTzUTj5gNoBpZSJBvSvI1P2s5ijF7M9H(z)asakrR)4kTn7ljk2KaGGG4p)avwXwD)QLpC4XhRwy(XvRlYVnzZMS8NwDnJ(gZhUm7VsxDTqUA56KQ6fjLlkk3Kw(MIDfLgsKGdF11bRw(K9NLMFwVA5gyqf72u898Z3982KvxQebYarCyKwW0Qy5Qh)nPWmUlYQsEyx6BYkxVlD1dTS6jF2eCw4WmQUml)BP19OYZP1Vpnzx9wGuVpn7PT1RUwbZl)57lQt3F7UK60kRSD(UVN8s19jLpLwNUXm3YK1zj7UTOA1Y7U6DV)EpQDBA56086KNsxTOH5twRuTnbujvgP5(S9PLWAfK2gvUDZWP3ExzX3ViRmDDDwrEJG8)Nwwb)9x2N8Vlk)s(H92z)0XJDXn3F)nF0Uwlt3xuEzroW8lkkZQU9w7I5FDdWPuqL8Bsy6jhkt(qwv9fPpMCyxTznOIIcm)on3Ow3ywSpxMbuO(Lvxhgyw6jR)gq03U4txEPzTXJ4CX8McJlKY5nfryuq8OtHjBMsdpceb65XdPumZ1UGPuS5nfUqfhoVPiymw0uw7(Ay9juxdVPid1ZKlCjpAURLq24kmwqVTrrqOC8TXb231X6XTgfdUThQN5IimmiCCv1GmHfeootgyDRzC(8eQi2mnEb7WXNbJ3)eLounPJGER6yHwnpPsYdhFgdZev8C1v8qUCUlfTyUE50axMjtcfZ(yRwDIdiJ4pHZh3yK33yKhd(5MJ1llgI5ppHc2fJgFPp4zkUkwp3PeidNRcokAMMWmXjIJmSJ0G5gtamUINKFr)yc84XpNmGRuEqWj22hX9UCUUHGqv8zYfwap6el(HIIWpruHH5rSmACF8JebLFchKJK8uGE8vYWMW6O5AEjcdJN5uyGtIXNYGcMju9mtGqarug3KCiprrbNW(Ay9fxo3uAfIO5g2si4bZYfjxeFcfSS)eKbNWP9aNEvbZmf7OzhgvieXJZKb3ncLHIXn4hyhxfoldeLyUrdJdMRIsRcNPZen7e(RgYmxPovQwdyCePN3ExDt92Dks0wq6NBktKhc1jUodbeWiPRPYuntJkJn4mn857sQSyhm5IIDuQPM0GJKjKLM8q3uEeqfCxvZTm6COq2XzgiEa7EU47PLEGca1HSCB3A7FOvSC1JxzimwK7ctONO4iZdci3wj(GPgqZdbAAm2IVw4kPY8ateGd2u(Zctz2k7NRuA7iTvTyNAqi(Gn8J5Hin9GPccljubbiJ1A7NWe0qeArenBtE34yGZplO0QTurhhGSMrpelfiDdf4KHprJSMXWjPHWuwXmaPMrmTpWzIyKpMukx4sv0kuX4CWCbTKd)gbhulOSeOSIaxjTAfBAq25gjrzZgOFHl3fl14kAJqG0xaRAu)ZuO2gd3zOhhkJIwSoPI2AGGvmKxHcClHR04EbmynY0qMwIsEmNeJWio9v0UcJXrcAdaSW5HZo44iC6APYolfP0S5vzMJskTcH1JIDKHXXOWyCayjIzLymF9W1AYhXS28Fm5pnuQ7zMQ326RO0c81VNTPE7LjRRlSNAIraIUkVoTS8WZ14SagEnRLR1V8C6QL3U9LQmWzGLZmRu4KOAZb2od)9f7EXBOaRcOHFMeEcMsy3PCzwz6rtrg4XbvVXFE56K8HNHLb6Ut46K6delcodYx0Fry)BysIERKLwG9OzzzqpwT8q(3Yb)iDN6NOpg3SOno3cIP6PaklQQ7WOwMyCNMDE(6TWwh5vdStmUo92LBXA8ODAgfDiDZfP2HyyToWDcK83bhaLOfPMJwXwGSGhIC(AKwRDzeDOo25jd)TfMLfM4TOFtMGZSNtWtuwapmtJXqxH20rmZJ5ooroaCSZXpYZMW55mmgpzZdIqbjGHpii3oAYpNKJusfHN3fbc0LGTW9fUuhT8st(HapvO3c3haIN93SJD2j4KyQeHK71aYtp3saBzLwshfAzM2XDBve4kf9OaEHXfsOke3uKYiukKXO)cWzgkYyQRWds0zgfFHfRqFrrbo3OOBlq5sUiHQWSJWMpKLBm0Vk6cIaTDbbt6cREfzvR)mqnzFiwtrOmaxANl52vY7eze88frFqG9bkYi45w7ycQwaXdFiMCRAqHdfqbzJQqDpeHiIwsyazWrSDQsx8mWOghOcFikW5(fv9HyOf4BrtvfzlYGLrJrTLKkMG2JyOHGKmza1fYCTKISlrEbwB2FtBC43ckDkCcLlbfJhc4qhYcWG)y4wEaNOkSTZibIH6COaj0uuiiJfUKuLu0vEumDqieFaHdZ8jnjBallkGjQbJ4Ozm8lIkrmk2Oqrh3OOLGRdsLWPJDHUmnAdMJ7hMSwnlosLrJZ5xH58JGAAbUmubeFPi7AjLpgzXd6z8WrencAppII3h7cQZi9dS2mJ3lfXjhFTBFD65SDec14(UKIrqDNQA52IVFzzwA(gic5cSbpF6zS3u5pL(MTPR)2BCzAF8hFlj8MPHraoFD9biMSxoTTF30B0gLsUnKHjWe3VjF2EL9H3E590cUx746QgEZHYQ0b0fUu1vgw2UOUPOSjm1zsmHK(D1QjXiZxnnTDt)X(Sx1hVS6sn4ktfekbJoiGcyz)4VbMFl)t4BmauQKG)PWyWRQY8nI(lWMuH(jLJ8qrDDX(pMu(uwouNLWwaVTRIDwFEFABBdRTDT8NyNAklZTKnkotO)PyAZAY3eRuYw2xMVIYTnmgD801pCIEBIgonN66ypg5s(IwncxYz9sh2FIxco5dHTqiWitibNWudNhY0gpkCDYEBtD3u((KDpoHLeDIW2O86xGDKL2CKFmzD6FC(Mn3Kx9hVBhuT6l)Xv7HIkR(duP)LYId5Bs38Lh298q9Jgn)DuFa54mE)9vpzzc(R6zSwKvvKpOTJALxp9NZE9fVKNSpBno8fgFphYRDoF6kaFm5PS1d5oWX)Z4TBuEfVdPc45LOXs4(0)S2WM(flHOjOjRnJBwyqRT(dbkUZqvAG4o6Y)ZHKY0F81lpSB3p(6VVnRoLKEAVI5QAY)CHZpB38RXroLZEbh7)ZlGIJ2F2ZN7rgrDzAdImMvQnEXIUH4qTI04zfuzox8bERe6MGe4wdUAmiVsEQVRYnAHh8lZOvv1nq5Nr1LtcpEj14B2hzOhGkuEYEc6iVedRaTRsk83cNO7PlhOU2UHUnMigyLC1e9G5Cqxvmeie08pbUQtTvnvTln9zZdE4W9yr56ux46mZVVgsUkigdUwxURQ(q(uMJmwzD9vMVzYtrRq2SnPC)uMGYaIHHhff1tz8sDOnA23QMYOH8(SJE9lR3vKNoLPOyqY(MmTwNud7xtJnmPvrTbCUzYLAsRevqewTEYugTmgfRnLjpvKx9qzAcC0zctmKKnytCg6yRtWnRNYOvSqRKLT)z4tM0uCwjpMMuoLXBkrFLfZHMd)DD6E6GfbD8PBE4yiFDUP8ovIJ3aM1d4b4XUazoVgx(Bq1XYqO4)arSqfRmPcaMRDUaCe02Y(bNUA)(d5PDIbdLTHbOmqe1KSKrC7aJCwFNf(Hk6YSllWtONkNX1zD8HDuiR)gjH4Uayn(cTNVus5j7tCTPkk(PUpl2XyXg(NqMOtDVciozqU40JXcl9Phs0pBacE0jUtp2Xu3Axo9cnAkR7T5P7T10LKNd7bRt3dglw9nfl9U0KnVymDQmzM8GrsmZ4HMb8Pk)tc2isPgmbFCTXHsA1HskZ6kZO2yMuv74VFlmKTquDBc91UOIDQ24XsiB4M(6e7pQoxAX2RsOq5xvPF6wMelESy9bYq3imDZe4dfgKhnlMJsMbjGPZv0PA7GnhssQDPkySEp(2M2iCEhSa3ePjDQ50LKB4kVQojg5DeBG0iXJA4jRF817bUxN98p(Q9uLjjLM6K1bMTG)pilY6tvIw0WvLsEcBx(Ezi5sndCfA8Fvb(D(qwonC7QVBUmD2J3MTjDXUS)6VskbzgsZnpPLQ98QUP8Aih4juXOFnPgwtGkVWbPSqe4W2JGxnGJqWy83SWc2fHDkdXfIfGWUPeuZRIdrGfHmHi03COsPPww5AOwtRFemxVvuAcOQqrl(xiKCXHemVrkcRAKSbmetuolqtutt9HkuJibQiGudPrgRr4QLcc3YWiI)cIcuNYyYWixNSqu4K6yhMNOK20Gmi4fU(j8vLChUQuBX4bceuuLIiQRJxqYqksIJqOcJCi(gsG(10clyew(20cRqjOgrQa6kNqs4mIWw301tJutBVegPreOMUMEAKalNJPUFInwqr7(u)nHP5ADjQbjQsn3JPXgtWJuOObCdhqymYoEqmHrpiROmsA84i0osrWsdRbYqtZqiJHuuDRgQ7eIqI(a)SSJHGycgyy38ecDmHtUa7siTamSVrNr91ebbNW(wsTDW15qPcHXw6WMpKA1zCmIkBecJnbsTreDAquaKCCCeC3gveAotDmbseIJeajNaBgapMWG3biQRjNXHuZdIOZhGxncT5aCPYfADJDpk7Oia2n0MCORfUTDUnG67dPvGHGkmWggHJx7SOKnBCKePrDgqteUDUddzQ3QnnVvJGaRqCZz4MhyP7oifty(2Ib09fNBCfELnyuTF4MAis92kJRWjdORZD60Na6NF5ZjLFBWE25xmCxmp9CU7GMZebPnI9XIZSsy8D7kQQAKp)uy3otyxjs8UdPvvP2mtG1rdb5E3ieB0U7V52JXAdtux5aKYBr3cyY9eUep4YCPFccnaP44mRjdR)gQNJYNUlwsyu8JX)5Vp1jDrdSSQ(ztDx6UBlYYRbE(M3E99V9oVDjJnUFUfN1c5CVYS6Bx5BFoH96M8oqBWXEnGi(3)Mh88rcvdOD3bkSJKsdIF2(2VCpuo9wNTH)nt6z3fhkO9e8S2eOta2eLEJdntxzJQEyQD6uep6fQQbvsspms2Sh1Tf7Xc0GAKUTy(XNhXBrp9fL1nccMTAeZFkI6Dl9s8XO(qvDXElARlnhO(ziAwtKLjzbDlY61GUAwV7Q7Si7zXoO1LIEehsBT3v7CwuFuHU3LY9vHSAr36LFniRkS3v981GSSa5)i0vk6DJ6FniRMZ)Lm0gHS8(VcsZISgx5pr)Ue)TN9RqP6EFvNf1h1(9xtOhBNRpEpVgKLlJ79(a(AqxnR3LbEwK9mgT1f3e8SH0giP)fi9yk4(V)aVgKvlzDXyBwK9miYGpINXkFByzCxSeNfXhpUX)iQcOEY)biRakY6xsfpMpy1VyKOZyQJmIn7L6JnK)N4iTU)BL2RbzzYx5aOWaxN5bxkmU2EZAZaewhukDT)TxQ9NtigBeLMzoyoZ3wuwxMK9lxiZ6SFvkm27BFBLz(f0E0O)vz9XPy)tqSDORdR)74WeU2dDlc7FHB)9VEcM9VnLxavOBV)lxZGm)tA6X8PVEaSgdkFeUNLsQYENgA2HhSi7UxORovKGVQhTVKgtOsWKAO4MhouN2E1XREoD3oZPNCZvVzj(VGHvqfjBYEmlT08nWeQbv0sGqj0TfcXxEL7cL3HixAAZWW0G3sdBZimKqmajo3oOF81)hXW0PLmBWcV2SYDv1hJsHZHsYtrj5COK6uusnhkfDkkfnhkPpfL0ZHsXNIsXZHs47s4yKY0pLjtR6wCa6vJDvDs9HQhCUKC(9uDqu843idN3d6FohlncPTa93)jlWoWt7nxDqZRePT7W)(53D3v349fsoEjfU98pC(fxDDZxGV6mWx8XZF3BB)uKk3E3vVD59nFQGlIIjQ)HBEZ)BZxyXDf(8lU7txDr7WTx)C4JV7M39PwAJVOlWhV89N)XZ9LeZBHJv51)IS2CzU865AdGjJb8fFaGVoTJ12i19AI5pbjNoVOy0)WBKHbHcwSuY1HHs79ef)hEtt8owBaphkOhHMB71GWpqKpwCztEjTlnbgi1uoVBcC3)1)4RK7J6xpl6DyxBx0GCvBElni)nHiNB8a210fzVEfpLgoA6(9IJY7PlY5hVmpR5sE0dvn3)6COLJ))dG68MnoRqUhLxI)EXecZ3EI4oB(s4TkPbAW6vR(V)5Bbjy" end function Gladdy:GetBlizzardProfile() - return "4XzVC1TCBJRK(jACH)b4L2X2jU2eBVwo1KPQP0eAjglUrwYlj9MXZf5zFBGUb)N5io2jNlgRqc0OrJgD)1aF8SKV82LlU7PV8LYt8)NlwTF31PRxNV7(LxYxUOCt669FRm)(nv3M)qwXnzBVEF(Uk4vV5SlV9SBA35J3(4M0q3wLwwDsAXj7lwNv8M9B3x4hg8D3T8CJHPf2eLwQSgRWU8l)MwUCX9t(MIPEt1YfRHby)wql31m(9v7pT8CRuXsukJJP1mfJ57pdKC6Q80TdLa(CCcSO65TzlxCXUQSIVKUk7ppE96R2v(NVDlyPE(pV4H07Zk)tST)vX(N2ToB9FD32h962P5LP3Tn7n5fRazC3YfpU)BzfhVQ6P0T()zvr(UVMvnOz44F2o)txV8KLl()YkkZ3V7VEi9)zFXFT7PhcQ5JzvVllDB1gWA)Um)8D5LgyAT7XB3xL9W1BtRYW1LJ3(T0NlVnT4(SkqI3rlCl2S)Bh)ur6PzH)zqdBjtYaK)pzWWDKg03GaMCHfwDmWce8hzIwjRxydM0LN7ScLrWuALori066fXnGQV1R(xSRmRYpFrdW17lxU4KRU92R(G3A(75RR2CE6QkyC9Iew7Hj497lYZk9ks52SSh9)iRXW9L9fRY8(1(5wU)VxYLgwcZpURQk2ww90UdPp6etqxl2T(G7IZGdZM0IhoKoaghJVdFT8qATqK48TUCvAf4BEy9HtBBYl9MTDvhsNmmlp0PvhuR5kTV1FjlT4qAVGZdtJI97piTr7uoAHygDre6s2JWuoD3QSdQxjyVwxKE)(DL3vKLwT5q6OImYpLEiTwNyr7vrw2)KvvKEqUWANu57v(dpcp5GwyQDhFE1297oitGHh0TGr4897QGq7BZO9EV0OJROOU)XvqKhyx)LCBRibyuWD3N9MnzR(ADejVMg7ymSDWXxyfcP)TCMnX6)HKNi14pmgE4hmh1gHJLe(Hw5cnMZLmSXkEOTgRj8CJXfAPq44cSVmfkKeTf7R1r)GPuOmmqgMWi7CHNWLutKoPL6T0zO2OccwdbhrP4sy4yZPFKOLOCvsSZWtC4qZ5yNCww4joMQwnd)qWLj44iebDrKatkuPsW(asJHY1IVrka7cQlmtqfegDWSiGSOyFTAu3ycl2uiCenYkB4hsyYI2DUHSYkjADHPgnskfohLmfhLSI704q6qtp0yNJEfzOf(9mb1iUqAteyB4WlXr3hm1BrsCsu1z4yc5FKH2AitvIWqUosYiAWLyPrRrBMXyWXr412Qg))rYcYSALsjyGdO1Pcz5ui8MXFtXuVXNzSj9U)hH9Gy6yrBSxXTcVTy)3onViBvfawy5IBU4TV7wc0biJw4jq5(H0)Ms5hsTgcsaAAxHeZ)cGkkYEyFioWYfNcPpkV(AyE7Hp0h)cHaSER9VjTn7B)Ly46Jb8S2r6w9u5ekH))c4vyOWDAHgIpZGmGGhSOgVsxeZ4cc4yaofn)ByN6I0cia7BGGEv(5n1oTjkGgv4IhE4jmICTIWokjb1LJycV6CzihCyTKw3iRmUGaU3qZkRsREQ8Ui0TO93sd5NQxqutJsSbaA96hRlUWBZ(7QNkGW(NSn)F(N0I1F)Z3KMd)xFeACK6JvZ7M8(8YQtZ(s6tBdzTnwlRxsOhlYb)QQNxEPI5rhNU6RGR2zN8XZp3p5foRC6UW1J0fUqcanN1OGHbMxxGy4tpkJQyywPzokg9mvmmQ)uDr00LMoWH8WZAMGjuMSldhdbKRA65HC0PEif1SM6yU9zntqCbZAueqzPtBGhxXmj2PhLrN(bujZXcBsCZCiemTAMZDWRpz61XXTWw70UkJpiY5ULpKWFMZ9KzUgc(wZShkftnT744o9bivhWCVjYLAATAe3KaoNznlqquZQlWMkXm7ca1E6594X5uMFGPAK4CcHEUzFmjQFGNOyKWC(ssM1qGqtNX0aXpFaUiT31kNPwb7ZnthAy8bjuwWmCfX6HMLAjLYKPt6o6oQqnwZBIa(vZ0xuitetVMOho31w3mhcdBMyAKs78nV(cOMXsOaWant3eFfyZWB3iNl(Ne2STumXpi9XeHR(b(6JmnGYGNlmd8WgMtxQAk46tHZrLkgCvSCeViwx8PUq8BQytL4pW3Aru)C(WQxoFpE8Mn1U0uefu(s406Ot6(xsTFR2MwgQm7xYO1Ckv3IZrF9t(YDEXhqw(Ve9VvvKnhTWi3caopq1(7F(wWXOk)XV)5GkxxmzqxdhixL)FkTdsNLIxYc7iOmyOo8Q9p4RMC5cVVw)IX74hH(0bXY1Cw)DdVgY1XhSjBwI9iadcwYoETvDeUKzhepDwsFsLEacGxfX6K9JC(AiwJAqo7xdXYz6FkYvlhuzWRHyDcXlYrBcXkgwvYSeRpI)90FlW)2Y)vAm9tmolPpP)7ltPNALZy)z4qaqCgC4qVgY1Xhuk2Se7r0bxEus9zfwlA)139ce9ug4HNf3RHyDAEFmHZsShbzgAJ(iX02hwN0h41Se(05n(Pyk4UFglCsrYG6nEnKlEFvVa5Ee30Xj2Vw666i)ZylTB4Xx(AiwU(vobAvRRd6Y0hYAHyJVSgPE7BdaVpI2m6Pp0Dp5pMEyrO7T6Z)EWSX7GkstfUCOYCAEzwAz2y6ZrksJc8Jiimp3vUb0Hw3esu4(AUqt11zfR8x5)9zHkMiLOLLJngw3FYCwAkAvjAOvvtrf0fMaA52TbG1V7JHMa)6H8DWC1Yq(t87hFZnxCvRxWe6a)fU(43F8PxCz9lW73aEXho(TN18uukxFZfNT426NkfsBcj93F1B(VQFr4mlGNF6nF8ItBAE4ygGhFZvV9JnYgVhv4XlE3XF442AI)sFdE2fHlCQX597F(eWFUzj7hFLtFPa2p0qoHgH18SGZwD5T(75SV7xzR7ie8jUEFbutDEv8Pn01IUGpvCG6FxxBgJ)uIEx42lDdvKKD33Yz9CTKRekRorO90DJroJJeoPPi52hoqhne1B)zl04nEDRLdVDI0IGBS)yasbj)(Zo)wFSNwMZMlmTVTkCSfzRJeq7wpdgImlGiYHqKOXlFhGnhEG0GSqWg5qHoWgaTLiRqsKHg0FvcK9cjmjrBabpCr)irfch3SVFWEGqhSj4d0CzKBdO8IJxCajkBiJucrLGKyqa16H)LJ)qs8PWre4qlqjzSi1gKmjY(HWfjEs88P9pHi4HrJuNq4i(wakh((UC4a2XsIwsKyqHuKWLiqUxyT0KWQcdLlo2AbrYHejsDcySXPHYOqLrRTOwaaPcTvXjfg36d)qJS2G4ndpXGu1WYIKTa5NbyAjc14eMqlcNvxy04iVrqYwqxHRxYAz0QIdvnLosCeFB8xEzOleVq0IEe9Xzuw6bm8hjkokvhAj9shThGEH)ijs3KAM(ijFtdA0fgPLMlidJej2qx1XLpWzgBOb)HLyCt4O1HFOqMNaVfhjd5cYHjsTZCqKgUK8iC6WGQJEkcjo4onXYjnowGtw4V0kg(wWAJmsI4Qe3YP9grJSaBOLHgbo(CRL(dULrBTDjgeKXJC1v0p4r2xXX5iEoXOijMib)p0SPKr(fH)BRaDIPn8qSbQdcABfrFOWjdhgEbjau)c3t3j0rS7FCcT7H6h0AAdlX6id6dA5KrrAqkDXj3AytcossjzBrfYsSxkHKdxOQniH9Dv1blJCTbcjuNE7xcUdA8F7tzLLzLELRFkWpKEF(Qo4VILvAi8xHK((t3CiPPtRjs8uZgBcS(WGyjkUrza3yqZ04SXtTdRdcdkb)DWXPE2OHaF(a7m)wklMsRbeyl8D3nC601u(AEOPuIYabQp3tK21BF2RbXN7nUeAHHyA8eS6Jp2LHJVjMoUEE0LArdtb7hI(in(XNrBSeHWkFJFOhluJGAJNaXDpk6HwvBmKevyZ51NerlT)MaIPwy27O5nG7ofA1(7xUyBwk8ASrT61a4GD5Nwd4EQ9DVbeu3)q6F7TXLGp07Z35r0rw(waxA(8cAlHqRAxO129Eqm(o0600NICzTSlRYBrrUrkp7npv0REiEN6ZmDnUxbZ(i0QWT3KpaUvlc87vx)E22tKOTz4hUqRIKoWjxTv6aCqAV41(kPiZ5Ihtl(6bmK)neJXa1DR8FJbaaiTXhVasHalKx(02TtPjSEADRLGR38CzoufX)PQKbaZiI4826)D7RGQ8)ay19178BcB3P0OqKJUeNRSqwnisPdY(eakctftnK5tIaMHqMysiHJWoYeyUAToYixcAiNYcYqWfGfk0rlL0mXeHyebqBjCFdObTKtCKfGHGPi95URZ8J5gtuewbmhSI4HlhX7ja8aKSCe1HvoeSdKJf1if10ehIexljSzqQaC4LKii2nd46SrY86IIkIRJuubX4AtcM7oXH2pTiIEKOYme3hb(bO2OjlXBzbSIqQSfRTWgHZQIGBIergAboxI8owbO)rqtEtvujjAqtuu3RT0IkH)ZgbSrmu3pYHrmjcbj0CdTMtCrNBrO8wSYgsMr(y7WsTewdQqWyHnaGhHIJLqLDaAiccN4In4AqqXuIyrqorSP4SIflZYGZBeQRKXKuDxrQJlrYB7qSKeJ1bNssl5i66igEnvcHiIQtBOkfbjIkLIy0nGC3gvx0rrerOZe1wmCubqtObwAne6tJlUSJZARmwfJcR4icZNQhr6i0FQiR4tWfyPGGr6yC0uGLpq1RiuoevzuhiW2sfTGWzrQ6Zee8txcUWeP3o4QsuuN4Fp4cHoE1uHh80X5bODiGBdzkjQWtol10(3qy)nesErumjeK2y(dFc3MZAPltV)3FghHBr)hGNCmSHTo9)ZbZleA0a1nk8HRC1iH3mZuz1hwsN8PHZPMq5ngaJ)i8q84qOO(Ta1jIFunlJ5EZBG7fV7))92U2aN6aPBqcywDAVj(mcWzq9NMt7t1s6v12NBwSEMEWiT4OEKKkNGUE8JcRg1yl6EATRl(VFkTOAmw6hpvyBZsuNtXTZHIzfSGtcSLfkXaYJHW7hdwl6x4pCDVc06dfa1N3LU9lhayguknFLNTx7)xVE2fUCF8TJF0LVuFOhBDZbnMMB3FS)7A4I19Xf(JnnS6I2o06vg(bkGyEJ75gwckOnTSe4PZoakBnUukGvyB8WVLMoF8PDcySS(6vM40JRdxGRtww3cgpBx2dphAhU4nsGnnarZbfYlsGKLqoMMcLHuCcOKnaKRZjCS6cLPavnUA)KRaog5)a2paRkT4pMuFeN8BORcsmcQ795L73n6EEtJ306jIFpqdcI)0N3L(q(kS5N0P(8wPUqdyuFp3QchiH0Pbqas8BAMp8kC(d)ry4zLKdqLPTqpcFTqGI88YZDEOrkguqcKgYJfcWXRIkvFVZ1fT)QB6)To26JSpp4GE7vx3zvVDEOn9)2W9jhh5JQmEy(TlcRTs0j3qJgq2Vw(9Di53liSt869aVKvE52p1dk5f)Vq6HSV)5ZHc7((N)9n5vWdt3Tde1QShG8iip0qD6giDy4eAkjzMf2e2CPoFSeNdOrlSs4ROZxMw1ZGzlR8PckJyjMna6wztpUDd0Kn(Z3XNap6Z1yT28l9kgXqFFAepP(NiqrR)V6GFYHm2CyF)y9pQHqq0Z9xTchemGPfaJhc8bqRhSrmUt(iBp)2oHZB2e0oQn1Y(3zE7BnEzVZjPBWd0w2C9GnjvQxj6)D3n8(WcEJ9FCtgfW9nEmH9sMgVMX267bGTT(WgBpNJZp02BuqHqqjm(BLiuRfy7DXP7X7wTbgJOMVSp9BFbXb65iSSZPOUkpoY1(vHhg3XvTC5))Oi6pdb" + return "4XzV801CBBSR)yUpF8SFVlF0kooXZnXXhlNPTZ0rnus0w8gzjFPOoPUpKF7hSlWYVePQyTtMP1MwAxaSyX3amZ4ZUB2057V)(Dt8)4QfB3Ct6YL5BEy218ztls38q2BwLT4R3S9BzftslUl7plNnz20fP7kH)CY2ILzfVz76TfEiLg218zxAmmTWMO0sL1yf2z3)V0YztFyWVPyOVPC20Lac2UE52VT581pTcXXYIlY3LoFD2BYlwSoB28As6HgKZLAjxjuwDIqZsukgHU5ZUM5jh)pl8)eqtzr(MVMvEaCxLLUUCfa5RtFm7YTBkNM)xzarauXMNUBBz2J3SoTmBxG4oF93sFE3DPfpKvMT0V9I0f5PRVz7UztN8P7U7tF0t8bWSiDDw4WqyEqMjZQvkLGj5jwNs7pdkKz2)3um03aNYDRsbo5U8hwvEx(JzfrQ4mBtbHid)DfB)2f5fzlkZ3Uz20BV6DVhOS)twXo4V)Jht))2w8hB2)yGsFO9AJhwGhvK942WrE20l2wKV7MBMn9PSYF7taMYkND9)sLCMgoW7ls)q(UYlYUpD)6sppWyTm)VZ24Vtw6L8EQihGr5ZZUgUnbwx6IVcG9Tt(8Lx6pFcRqih3w4cPwpUTaIOSKb3cxxTLkCWKm34WHwlh5zxYng(42IqAsuJBlsoNBpLZEtoS7iSR(Vu0k3iXIamFm2ZIIpmdJZo4AuYu6HVg75E3L4gwAu271UYnYdbywtnmRQxKWzQHrspNBhxighrz5Ju4fKdhEhCXHAuoL5KubBCQtKoZ4OkTqn8o6hjMKXYRekHEShfNCSw5CawgjsuYrR26mhrbza7jcXWcJIdfgfjGDUXi9Yt0SXYTmj2Hp69QtjmjUXUfMwnwgS1osryU8i(r63qkBS(eaHRKtYUytFcIKH1t6XuQGXoY1(aM31J1me4QsmsSWzc7ro895frCeVc9JJeTDyB8d4bvCedKde8eZn8jPFryNDSIxsLkzKBHdgjgEl9syEx1Jmacj4rzyrY(Sezzhr(QF(Lqp2qALs7yDBjLc2OmrkKjhHbRpCdA2rmA3J2lKC34oc2r7gvkLjdJKEVnuALCyb(EUXnQrjGyKJ1BycBSmkNrnsJjo(rSx1NyUXCSqT6r4W6g3DhSNf5y(VtlFgsiD6vBkZkUpDr2VF(YLFAZUF)DRtxU85F)QhtFiB3VJR9pk2UFZYSL)X81prPV(R1jvoC(5(8YPVBNN4wSoDxO4h)usbFbLCDv(Vq6uXQx0O(ccFHc6wrgmf9AQ8CiN5MuA7YACMZJVNOA38(mFw)WcLXIACtwXISnLahnWfi6kM8)opGX8PN49YztS(hGJJuJp4t30)aZrRjKN3Ky2B(h4sgUyFMwt8z0BcFUX4cRmKGuyRmf(qWtN)bRJEWNSsaeggdrSZf(eUKwI0jT0U9H4JRbuvNqrWhGIlHHOMtpKOLiCvsCZWN4quZ54MCGhXazYqO5jZWdcUmbXJp61jXOsdevcUhmSZa4WVrka2cslmtGeegDGReI4kSxRgPTqmftIHjfGMWqxese(s4uJ8FUb52ONvp8eqgB0Hnsv0vd4xKJ4sjXReHXH3fWIDisvCNgP8ebrgkRG(k6wHZfiad(AMenMgwCIf3UtBc7YqmTqiC(9y06aremEfwPkjbjgVTMaq8NeV4Bw57JLG7Ns9gd6lFm9p9wj6QVT7T1M0kcv27xYxwU6Y0fLaj5PgFvScgVk2)ujUhGuVMxtVLp)eyG7MvpVlFr66GMkpO1g1GbDur3L)(TRFUXszNLWOLFMgEc2IQ7wUmViR1w0SgyWCW6pVyr6M(3rabUUB460Y9ekyNbb128qe(BytYdojtdvGK2vabhGQP7381nGfOUB9Z0hJ1SLm0fpqCZbmGIT7k7GOAKe85C(MfRGlU6I86n624oUUKODVNdUWYwErwyjEu7yrDxYsjO6QrzzNaL)dvBdEWgTsPd6jAlzoijAde)DOwqt8bfGwC5sbpOHH6IHQY43gNJgrdXm53hpQisMoIOlIpYMOmAZvLG2eemlsimo(GKmy5ilKAbcjJfTuizs0ysO6ctIX3gWLJSGb24q7mXpaiVWV5TntkfezAKkYWmJ8ricaiK7Ba0wvazUi2dP6GNu0wey)gpikJcVu0Alsf6e0sdygejzm(A4bnAgK8mXtmOvmllAagn4bmxY4kKQyyfHG2cyJJwKrJxuLLNq1YDsGVIOQ2siWMcpK4iFB(QRg2lzWwl64tfSzAPpGfEG8Pc28DrKGSfG8WhsidY(sfIeOKKrniVh8TyPJe6khmHh2Qo6jeeQXfAWhSSOHBK1RqNsW3IIQgswKdhJkH6ainCjDhXrbbnjYaSle5onftGgXfiTf(nDXHFlW0jhruuiu0bGRksjJHHnGoQfmbbv4ANteeh55qwCOOOusclcnXkj)YGJcsrqHpG1SZ)jvHPahlYvlYbTcumg(fbflN8QknK6g5NfmDqSebP2PIXOuhgaEF4dT2F4iwgTUODfE0ocYPL4XWWi8sXe40uKCKepWNrLdlTc6o3srkKedhGt8h4S5xFJGl)P4zUBZRoWq9pJW3JjomD12VDzrE2MLGN55y)V(8tyl)ITn9nXelA)XXUP6jC0ZZ5lk3dXcmVok86VRBtnbVzQ(BHzCV(SioGlqlNto4lB2y1q7jPU7TER3VwF803SVyxwlqYBLTHXd06t5N2wu5Vm2FpSlGG1pr7a76NI5DP4MntSktpa9pp7sh4mZPa9iWhjyq0b3xGsW0)C2LwJwcxLAf8DW)77bSsE4PRkGS)M0PMVTSC7JFmT4H8nqAMG45uQbU1hUV)LjaJT1x0ODVHUdpOSki1d0Pf(LmbIOUsHb5dx6aZkgile44awy16kLdp71hPYqawd(H9bAW8M2TQqRWT1hVlnCWgVbcm3Za9rYxfpS)EIsDu4dAQjNpEPEcIBZpsNL)WBV8Uggt6iUBJXusXkkJXCEq(bTA(VvWchyfeNG1NJdQC3NMdQP57WVxWFzX7txF)jCKOS29A4)ZRBXHvPavMIqVNRsnKFOdmtkaNGqWq(dMgTN5aJ8CiQdWYVdIGOYO6b07pyRKhODTnF32n9PB5pPXRHLdyiOFzPlEEt6J5lWLpXB(B)MYOTZUvZOE2rQSQgLQ9Qb1MTQeMIZ6cPe3Wztqo1B)he(wemudaAThyTQH10))9PfzF)lxUF96V)LFzvEzgr51edMeztnQiH3nHdCL)uCXvZmACOJ01V20zrlz3UuCvz18SPOxW2bmG16cDge2oSrixNkKf((lnkdKaceDneuP2K4diaYlH4iXu4ORPgxgxTXZtN0mlUAgF3yj(vWEHpHdfGlMwZuSGYdRJDRAa00x0V14(BoKx4dbf8wgX63UtGBu78hprny69unHUb94Ld9LbmMj68gYN3cgI8Fa4PhUGEyleUsiv1DRZYEY)qJk0E)2IfzXBPC)VHRcdlbJSOSy9UY9BoL9OtmbdZfBwEYBXzq0SkT4XtzdgFnN84y72Ytz9ANk48(R7oLvdbBhw9INxSE7MStzlgoKHLpe1fPLW11PHgonGBGPrFGKN0jbuAXsKKEkRwNGK1YI0h2Uz38ISuqh7e2OIOn4sCe8yraxloLvB4QaLL)4tWNCsBjkLCFwAXPSEFDrMfk0tLjHG2rJagoURMgHgeCx4FODf6JwZAOuIRNQFOx)DOjvSE(3KTg(UGft0Ui7qhPx94J730okC2zqIXOVuFC1rFKOXeessfbPU2OxwCbqIHGWUg4whGUl3IkKhlI4f5DSy9s7KtCsaRS8fuNGqtp6adu6ZuvCSbBkSMqL7)BaJ9ydycHjF1Ho(Acnn44lX(3TaPWEKH7kSMYAXWtpnQQuyF7MShFoCXTzdChSi7rWquGFtouVnlDzib3DuWozHDmVAbFExtb)G7MmFDxFkTO0xZ6SD7lOa9dDBBPFB7Q3XDRGLSYNVKxGVsW9WSPUVaIpVopQ6Lv)zbX3kflFKeRA37GQaoUF7I9KGUNu6goWhWSGN3jehC7(wyskXHf7vsslJzX4LEpmCHUkwGvHS0oPthJiwnRrc1eIAg(5bDeHu1qnRV)L7aSxM)03)sqRYhssrZGRww8VHatl7jmYkkW2Fo3KHV6JFZybJXSbM(8MW2DdWfZ34n(qN(UrU0SyaRYxMnzD(F9xPfabdHnVjTgIhybDzX1qm1ds(DYt4eZPGosE52VEckrp1yK4dTbjs(F)l3MMd)m0nHYMYhLGQ1QDEY)Nsy8DLPVnBnKg2MsavV5TxF3BVT9zU32Ee1LUuzb)VCJYj56q1)HyWnv2a6RlyrbMATZ495l1)q3kh12mXQrwuPQ0uADiaNQvNU(KY)TWhIA8nldaAFreZLnkFVSOzoc0gIP9DP1pPLYePtZnCjw0Ng8R6HAOYSxpP12jhu0VFZK5UJYqAE7Kj)NFpqhJyE0(Wv6jp6UMSIlhcMR9DvvHb9AwnMnH5n0JjHj62j0cUjXgWjLSyNqOMrXeybR9romj0AaQttCSk6Cg2KcJKgsGef2ggifgQxfXA47Ordio4cvTyxYJ9W24OY6RK1DlaBGrIIAkM1qD2dblJJDqsWzocAoQF)kh23ed12jfTYeh2CpTK6YJYs4xsqGMibUwzJtma2ZcTlj2HiKsRgebtcD(PUrPfXUqrJFayDbBHKXqanozbqwmgIITyJvSX(JPOwKunQaWkc4TAubuAGnIqb4vrIK6kd2KVQPlXt101l1rjl1cO4WL4PGaMtOPmbBdRHU9P5ib2wCerqoibvAik4oSnUcRbjnaB4cuji6eSeQJMaTI0iXXtSOCKHAINVM0uxW4yd2GClJNgQxUsfbFFrRNqtN1KGago1esPlH6QOeNgd6a4rFfpJMFeSLHuNc1utAJtOrO2j(Fh7KPIgPKKeShwwSPFul98KyKdIeGwGRJAoONfHIZu)LzmuguzqWjXwNksOowgBFuCyssuuRwTK(b3XOEZXWJQq6CvY9iTJKai3qxYQ4OYupHmmQl5exbwcYWazyS5LUOeLU6IJOihYZayInNue74gndlvdjJdBzMb7YihV8aj9OIusSdzTkD4YIM16BzrxhNRAw9XHdR4PgZewLT12JZ1YIxQ59oLQ74Xy26ncSoorYd6HURcH49MyfBj3MAt010bH81QkCTED6wKFqHhZRZFooxH)GJ1QUwNbmBRDYFIrHqPzG14lK(L)pL2dMp10MDiy)UYTpgku9uF4chlEygMQyaSCnN1nRYxd464hmL6JcSNLiOeqOUw0e4G39dgQ5rb9bj6dgh9xfW6KDlqWRbynQdgY5xdWYz6FiWvlp4Dj51aSoH4fjOnayfh(Y3nkWEMok(szWRBk)knMUtQ9OG(GYVVmIEOBUdlW1Rbyf6KdEtyFnGRJFWyWpkWEgNU6sQSjxbAFj3FbGEig8HV5mVgGfYHSBrfhfypJzBvI3ettzyDs3INokGpSFJFiSciS7FaGvcXI(IyXdzd28c9eDg30si2Fx6Ali)JqL2D47J5Rby56xzhOLTkj25u9U9WTz5joEG3PLqeTZ3xMvpv37EkB9ApnSXp(itX)XFy20h3Um)(8Sc)3aBOC7giTaaa0eVGtb0S4SE3bix6RoD)WqudJqnS9Gq2diopSOV)L)hz)WPgmlXyTxolof5dbj1yGK(yqspgizogKmJbs2Jbj7yGK7yqYngiLCmiLmgiHVlIdbkF2yNmSa53gPVmJkm3I8g9SKhtvRNcB2kJXA9OlGvV9Hz1jl1SWQnAqY)8uw7wY7Fdszt4t2XPSATnrcjyGt1rRAW3S1e7ktl3VBE8qepCTMrOBdh8UntUvUV(qaxKhoG39PBM1SgXnp1nhgqp2PLfBxJFmx62bRJNhEZwbwNg(t(IyxuwKMxvmI6g49sz618f6F6wM6fbdjX((ph6Za80J(PL0)cZgAz8VC(T3E1NA8fmHom8a3C(ho)IRUU6lW32j4l(45V7T1FkcLBU9Q3o9UQpvkK2ec6F4tV5)T6lcLWb(8lU9ZxDr9YdZ9p8X3(P395AyJVBsWhp99N)XZBsj(xCQUErA1yfrDJvA11WxkdUBVd)y6d5lA5Slg8knlDNfoUR(P(AtLwndsdHoBcxiyg)7GGrzKMgJTO)1i36KmzOpiUA013uRgU0WjaSBvIAiN)sz6nhM66wy1T1t4aQ5F)z4wTId)NZfg7sfy6EDwkaws5UwFREKmaO1O3osTpjKiE7(QF2uXUYGCdAm(z19UR)QLr9TUBuon3yfnPIVdQejlB138HQQfdfuCAbebxctAygNvujO0KRm0iYXRcBBAPFycMqKxxMs7ok(JUgFiR7D7Z2TlRVxC4)5cBZpCWFQhj572EUVyPxfSzViVQgQLZM9F)tpTWLf" end function Gladdy:GetRukkProfile() - return "4XzTCf1CBJ7J)dZ98MrKuII6X4KM2mxBAU40z3DMDCxfBLyD12kNK81n7d7N9)GaGsuYYosBA7dnksKaGGGa)iiywiwC)I5RkNvuUkR8IInfL2xKU4gXI5pG))t4)xA))6fZxwuSzvX33n6o8W(hFSAM9)oFZZRP29)NvwLxS7RBt)Flk)6U9BX3MUVm9YmB7pgXd8iEaknPv1ZspQ0tTpOT9px89SsOd3N9x17lZwmFEXM8vn053(miMz1lUrQvlMxTofgPv5pTU((8TzL)2IRcJ1rkHqjKbAJoWS4XFjmbiBw9hYs3uVgOXvf7agDzrzE1T3cCoDzE6MlyTwRkOmD3tzxSoB53UdBXIhwmF3Z3xMTTajXV7efq6t3TRy)ULzBZ2vxzhG1L57(ww9DzPREX2XQNZwA)z2UST4l4g8LQSv2FDnkC2NwLvzvdPL1VaYqw1(YYSL1WCrf(vB3QA7X9RHMSgeDqJG6VvLxMxL(WMSlYlxUjZ2s3uWt(Q)GZchEcGfSdPcRGCkkCykJLs1IzlMlcuGUgEqjsur22ldc0A7dWh42inbj4drHMy6njXryVcfcBB1XyxeATjbjI0iKuldcv4NsIIP(gB4hccdjAOdcqgkmMqSTkBtSVXOIjrirz0CBcrchjd1evmjb4dAb)qsKIOBOIyn8gdXAHG6KjMg1MGWgXuIcUqLqQdPeLozcmOWMOsG(qJKasOIPVOKGEb)cO6qrqQJeKUmjK6BCejBbYysuKYeIZHGvp9P4eAqdJAbnw1g6n6OisXycts4bRtQSZn4SvOG4LmmwscHX4ASHyAID1h0ytIHgbHctenusKuteWCljfWcr7BcJcvgwFYkytKg5GMuEGCQrbgihnVz08KUqfqgvATgjlOOHFuJlS)18vWsNBaZl3I53TZA7UYsuRlRR3vNvwU)5ACbqL3xx78jCt62m7I655)DMLu4s9I6ST3UjToJCmE(MVN(s19PLpLvtRArpNZxx89ZBCmwzj7YChpEO1J2hYS(PaIhTy(Jfl3xngFIOdAAqDBr1I5Z(893)5pXe1YzW3eU8Cv5fGG(e4uldxzwTjl7z7dzTsYJfLlZUEzXo7VKB)5ncLoiHCuxxUPQE)UX0NOey(3ky7wn6UaoJr2SoTCRFhMDm5YA3aD4BvJH8WYaJT1vltRHj7X1hreokwLxzvBqqHr0jDqmoNSA5OATimY26hZsl7nOBBc4SQtVTk2IIrjnrMqdprmHUiXUK9mmKtHGwJQxjuVwvM(eek6HYSuyn3i6yiRK3NoMwhzJhy1xLzz)DwDz6OmHJmQqBVY3(m8MrnX0yo(YYnf7gLkqlqzdvcORILPBYW1SoWzZRFbEZC0DZJW6Y)48vR(8UQ)49BsxT6L)46TPpLv9huB)A1)3(0YSvF9HnpBPGLBKZNqyL)AWvXg0DXdSxgxyx0lW9FgWTa9Ex6faSJA77P(kJ0wVp8Ve45GJq)01fxlWph1FFzX3VmNbCSy(Dx)(pCFRhmphNS3rYHkc4X(RquwtpZ8ucpvWzwbBFvDXwlYUfZTakEnWG1mzfrqqTFc01ydZ8gi7zqOxKYNb249jUkigCG9gO(rfAWF9pbYAayB)4jRom5Nbzfbr)uOBKcaA9JNSgP8nzODeYkdnVjP9SiN5lr6ZI8TFvAii)BG6h1(9Tj0hBMth)ZWGqgzrR)JNUgaV(BHSNj4PUKgyInK2Iq5nq6JPGJv)u87ebrIEdK9miYGhLplr7BdhbBZ5nq8Jh34NIQqy(zmXPaOXVjv8X8bRFJrIod2eTVrSDU001q(NXsAJDlV)4jlGZ9hR0wZaVUndaJci1FkZsZN6Iqdrc6NvkVeBHzRRFACG9l3K4QFr7abIBH(Q0L1fOZKJU5xlf8s625CAVSV2YTpMxvFz2JP73GBfrhFW6KNlZbXR(fcMlaWF53aj(DZ(YvxzhWu(KMuxesvuFf)R0fvyCqF)cTDXU)CUln8aZU1K4ru0bUlFnPct)XK6IuPpaVYRYfHOpwKbh7(AyZjuxdpPGz4BsCrghyoUown88O44kmrWbtJy6QMehIoeH1RmYdddcp(iFqMGjWCkddHSV)8xBspuNC8UipKfXjtLfaQo9Owt51fmzStIly2ANetIIpi43RTOkea9nnMimQP61YaCzAmrkJMQ7uHrhnr)wucRNGPcLy7jy(s59EscLqNeF8PKbxuj1jMP2LGOWP6NloEIwWc1jIlm88EWu9XtNoWuMsWtryesLxib5eh405bnPUab3oHUsEOPO5W9O8ARCdvtn2gD(ftIlQa5jI8CKiOYt4pDy1vWeXbbHCfhFKmCSk9KJmOuXt1npDOrtWawQsKhFKenqhIKXtCvLsPoiNtVI2sfgDcf8WZ745BoPUqNS2eCzBpVTP0C1udIKemvtr8K(MwpeNWh3qXPWJoCc2u2dj9eErhyDETlF7NVSEpvWaUtn3VybO0U3E4FxVD7E6ii82BCscV34aztgECNKF7g4aabZxM)wp9bhfgt5z4vhf9lrJs8ykPJxqf7(D)roPD(u6FHQM8(76SF5C4oHfBYUwFmUUQSpzw1wLi4SkwpdJEeA3G9xE2oz3FE6Qc6KlhUVNHhehUJDVP)nPvv2J2z0SVTQtUNeC3ERFZtYKTJ7uOb0NZtRbLZd7RXtm(gCRuvpNTzJndf7s3c8HoS7fZ3wSk)X8Ss7xGouBt9amas5SqutnZs2biYv2d7EyAiBPbEK4wsOgGeNJn6F(Z)l1W0PLmROeESYsPWtrPWPqPOtrPOPqj9POKEkuk(uukEkuYCkkzMcLsofLsMcLO4MhJuw31JMwDwvXPNAULW4bx(HVCZ9V7o7tBZ3bgWaMiCL8VE(D3D9N9(qaGzW(HBp)JNF51308bk5qWh(05V)DTVLOYT3D97MFFZBvsfSrgI6F8Zx8F38bCBQW7V8UVC9LTnhHobV(Up)(V0sBQoEGxp)dN)PZ9LeBT7qPK03R3)ENg(U7zAHU3tCE3FRmGo47BHMLV7jYPypVU2sR51866Y9ytH(GZSGw6KBQbrBjpvUxW2GLY1RqM4tTfyMthEav9BdwfzNUjXVwduaU2tM5T2elZLc5iQquk4B3er3eAdRiHp(URU3liDhZIBSfyHlLYy5s9oSkiN1vo46siyiRUre4Sp4H7Y2CBr(UAjNK8vLdvINwB4EPn)H0sxfLz34WJLGRN2A9OTlTVdnzpfcp)soR)3(u6t5lhq9JNAaAIZfEtlQVM6CRdYh8yu6pdG6u9zDl5mlKIwpI36vXTwbCGkMBHdEajJ1V8mmHE76xQYbDaBMWMmpqtheqa)M)HInV41uqAdCyDJcSwzu4A)UCvUfNNxxIc84G(G2FE5Y0Dd3drtCo)oCtkbLe1EQaP)Ga)DlCKdgjZrlnUxidoGvZ3V7B7atT(D9l8RjRw2c2nGe6duaLf2IbUdJAzsDVZPHlFOOJVwqWRfwMF(ULRbJMw7fRf2bwPdD0q4MEYw5Q2X7TUTCfLQTYtNzZuzsevXOgjvcP45uapeBZ4l8t7r2mZMCwUoxtc5YZL)zOmclM1KafvxPkPalEuQKuXmGB7heLf7aMVAlbfkxzXs0ZXphd5Q9vf4yucvTRYGyssce0dQqIq2m7odthdrjDmvdSQafvMSyICN5spR9nCTbRJOcYvA4s1feo67Cr0YL)lGjGjTkKl4yQmPnjsQIETjzeheXHiRmoEJ5iIgNur2c8MggH6qsyIIIjPikHk53qblWe4c4HiQ8E1Cv(IbQGhIdyDimDIpOC1ITrQXwGBZh5MqrsQKyQ0PUThc2muRsSIscOTRgslJNgf2fU2WJK9QrCJomMFra9qsOGOQH0KwQZLSSoIEiHRR82IexX2MAsPl1QyESqfNUmjg7AKB6dmMPgQPhI5I1gpNd4HqQYVHVsCsZMGcyG0ymJKuluSfHjczAKZsrQiMBI4cKpI4fyKH)KNXOVcABS3kBzUJJnbV2WPKLudJdiLGGEFCm)dAjtumBq4QPCzCcBQhYpi0ylubcAmsNicrsUCXH)rQTqLR00PFpwsgX8cEW3a3bjVSIl(BmPsi7Lmbi5dpXTz852yFDcV6H7h0AEblxY5AYgmwWkfLMUnac2SgwKqCsPyDljqXCzUN4kDDzyJcbx3v3jw9)EiUomoJgjJp8h3211bT5sQpIzBa7dX205I30bj2QJa7lOpSpqqUTOeC4N)M3iHp6VRSfB9Qn41G5LfxbRZ1bs7j8eidnjA7n2jSr(X4x2mVKw7qz2hb1L5vzPvzdPuTxYLsclvNDbEHd8kxsenjmsmeYiRvXa7eYxN6MBSnLL8jHTE83phhN6HAfLpo1obKnHduDlqvNoTxk08MN7wIVnvvsl2CMeEG(Dc0Ns)lRgTc2MWhZ3XnhNR8UmeTOWrkWfym2QEdOnfwygO(m)3ob26xr7MVkB2M8)(VtlHbkwY0(ZWFggEoOnwqYTWE8zjpM90n82RBZ1Ptjmu9205INnczMYMwluD)jIUz2erInZHddIdq(2KggssGKcby3im5IJrCiyNRbumla5b2Xy2xCI2f5YHllMHtOzucnxmlLqZTrBipV2qcnbuixUjHCiiY1o1bWdobJqcHzyAzCxMjdfdfCDtsui30edbWlsXH8dJz2RysW33kaUqS7MPzCKYbxGfujFhW0juiHedP)IKoqj8LRsgOi8eayaEWY3BkPGVdtGGqqwJDOKcDXmfe(jf0cAS4UjuHaOskwSvv5eskoP7sZzLwEsLHve7WbeYx4lGUihtCr2WMR55C(2XjIjeIXeGzMMA(E4zie8YynjqaVOgarDjYfKWOzbjKW25UlyX8fOdWv6WwBKUMsJQah6DnnUjeuQGafdN3Dz2u0ThZqqu47qhyuYsPGaT5GggXitLoWcrAEdiafjHkuZgWjmoqqCjdfPd4xGSrJrCnssTfaiRzqnAJBANg1Xkh44qciRd9idZvzyqfHU7PxcnbRKm6etGGufeQuggmeaKaR4KbgdNkKNqebbm9cKmQgtcnXW3fpjyQsgEnxGVabz41Cx8alDACashHJtZQs(Q4XglnxerndPuZaeLoYKWiL(RfxfbdkegFuiG4nUxC8HU5jToXBYLWrbgrj6R2hnqD2U61vD9xEu4vNzADW(qrDDX2pbDdtSByJ)8(zcQjAGFYDwv()aaBQpfVI9CM3szV4WDUI2)7rvHNl0REBSdgaSXidfXtEVFFwvvgE1g5XZaX))9oxqrUNTxRjisdJ88anCR0FX(YEa5eDmc0EcLFgUmTIXbyfo9DBQ5Mw5toHttzVwO2rDdg(Ey0ID5kIN4vUCj1S7HdeNtIqyKyaxFKRY(QYB2VzZiSdwv(H0npoITa0GmBeT1FkFkM0Lf73TYzs3zkRD3mo8SDr86FlB7Fec9wXrYM9E1)Try33DpBdLhBVsJMmmDRmo6oXqE7HHKsH7bMdBYsbwE6v0IwtHwFudEqkTR)uE7kymtMUDir9gG)0(Q(PeKhGdq1ZKh691ZmzeBg(W7Oyh3m12)AjmZU6NVhK2F5GOlf5vf7g0tTULt(k(gQC5l7s3MVKe0zD391i0IDmw(x4TVZsJ(z193xC1VaOCJIT3(EaPwsIg)ZDrCxX8Gfb8PBidI8DZDFX52DhD9k)YwzaJ582BGQ3m5qhcKB)OwlV2TC1P8rqvAlabVv38QjV1lv1P17REWTO05xv37pok(N1sZTKFU9p)gZo0BpnxmhJP(p)5vGZZ)5p)1151zEUL7ESxOvrR6y9KpNkAzFNTxYk5(lR8pH1rq4UEcAx03FhOTOW6Bq5P5wM3ECtkH)8NFJCHC9M99prVf()rw5G5FlfCPfcNF7jnFSjbaDwfD45rGgkhEuyTEWGj)MC901Xo5BZUZFFT0yD723JRtFWaEAoKC3HTWI6I(Lf0KCj0bayJ9817QOsfchGnvyvJHA9If)N)p8ugma" + return "4XzTC12CBB7K)dZ966HaGea8LwjXjEUehFwotBNPJAPKOT4fzjFKuxQ7l6N9)7IDbjeFqrSX9nrYKalwSyX(0VvzHyX9lMVUC2(Y15LVz)29L4dYwCJyX8LU)9r3)wI)Bn8z2UhZFZM8vF929FlVCww595)z9IzlMVkRQg(ZXOuKJsrokfHuAnmO9BxV)B7UC7ZBOXTU8Tfvzl3M)MIYvBZxSSLSpgsYOlIhMO1Lf7(AEDpQ8CE9hYZ2wVbi1hYlECt9IB0W829897RZF62Tz15vo(4YTFl7LQ7ZkFmVoFno3YSvfzBVDF1I5Z(893)5pfqUBZlxLVRo7XCueWR(zlcAfMnmhsMLhE4HQz4)4LqVVC)3EBrz(Q6I97wm)URF)hac))Nxwb)9V)u2)7(YFF3HNOZRJh79F(w32Sm)P9LxTFhSSVDFzr1T362g)6NHLjhKg)KwcS6HYSpwuv)28hYoSTg5ETXeHFMVdLORr(75YcGc1VS4M4iCtNT6RarF3SVC1v4UsAKs10MIqQssM2uuXMO0rNIiPzknRrKkYoT1ijrnX9UsO1IPnfPsNgpTPOecH5C27Hsy7jexdFOKeBN4QitKMPUxIfJlWer9ogvrXjJFmoW5Un1oU2OAWJ9y7e3eXXrXJlQgCrerXJVidSVTcPCAmLrmrLxqpC8ziK9VrzJ1N1vWGDDQYQNgxLiJhFgdVi60PkRKXYKPUvSQPALZcRYexKy1KV2A1N4cYi2tKYXvgL9vgLPGDUPO9kstIMQ0sNAgFRp4DkPo1o1PeLepvbSXmrvyH6e(rg2qA0u9jakxPNLDXqFcY0XVNmGPuzu0jo2hX8EYundbUQKtCversZj28d5frEcVcdVgPjMXTXpIhu5jmqosWtr2X3jdRcBntv9sfhNoXPiaJeJpLbzm0v9edGqbEugxLCilrMOtOFnS8sMm1qAvkZuDBPuYOjzIuQspHaoP)esIoHr7bU9QJMyi2Mj7gvPuPJVidEAeNeRgxHFGtCD8Kuq0QP6nmnAQckRoEIgtSItyVAi1CT(uHAnGYHXoTZU6MuT7NKyt2PyU(hkZxmF((TfRhp9520MBYVewYvBZQQUE1(DNDcYR48FdPswnKM9YdWccZ9gxUdvpNVD7I5a)K9eWCuY7lM)0(1fpuKxIVbMqnMomSqzCMX10WaQkhGixTF1HQHPHSLgp4gfqc1aK4s3G(7)4)snmDAjZAQEfRrkfFkkfpfkLCkkLmfkPpfL0tHsMtrjZuOK9uuYofkLEkkLofkrUIgJu410ZMw1y1WWll3MTEDXoQkCuLHAV9C5HYSXVbDHfPYZCD68L9c9mSzGIx5hhE9FEXFLtMvcV9F2xBR2Kb3ARW17(INYlVlF7T7l2vl5Yr1DBu9UwRuKzJFUyD9MRaXYE3gjLkn117QZllp8CnnRM7)eNu)YZG0(2nVuvSkBlxYsU8LljoJUPho8pSF7lbdfwQiE4xKejAUpgoLRkqlGbtjjkyf09g)LLRY2n8menkYHt4MmYiRBRdrQgUjC)nAVP3ozUtOZZYTa9wQ5h291DG50Ut9l8JPdq(W0VHe6EcGY9v1DwO2fbnBxC5UvBGJowrdRRjOnhCk3wIZJoPfSFP81Vn3neCPTrqWpZWG8nPg8lqAlqY64tSqakZ8Lqd(IbRUa8jwnXzOtqTBMYuW)moE(txbEMHE6vUXjusH1nFh5CLAbNMaYX394u6bjcLBy87PIzGlNF9WsvmZf4lTEXPc3cjJmeJejOVOIjcH1qyMlrbIsAJ1suqftdalzWmFqRU1YAO5Qtec3R8payp3N0EHs5gNHKztTIylvCKt8ztLoc4sO1rAtSBXS(v3L)cTtJ0eTzjASoMoussmexKKM6gBSGzzkOz4ljw3l0wMwAJ79MiwkcNNUVOabpTPLA3iCrI5wni7d3BK0Ik9cCSaTZCYvAPOmuNrIj3xsTKyZvYu3CT0UprsFsL5CMlkod)Gi3x0efKwsGIlcjwa2J(sAkTvW6)rmOI1r1KSxQvgEljPhKACtfo7ibkOutdutFXqtKQTgs6ilXlPKQQM1ffW2OrP2rsTqXNrcsriHvzaXfT42eAgGUeDIyOJe(GJEli0jwwODBjLoIPsmFjlY9beQVJXJKmvHJDbZqcsMdPMrQIkfRSityrzkljnP8fHy6luH4WNySgMpu0rQGURinssng(GPIrqYgJsZx3ewwroHfjs(AhM3RJhn(BYenCXlJBowKXJZBxr4TJqsAfTn0r86sNiABIJJvcwJhKZ0Lddpc(m3iy1hMnHTilInUBKbET)h7ZnWyl4d)29LGH1cgAkWo(wWoUZD6dzRY)TlxV(Z7Q(T3VfI14LF76NGqcQ(nAS)E1)3HSY81)(YTp3eWF18n7)2vLf57wdUpxsGo9LNXfRftR34d3NYgOlUH4G3CCOfmFDZE0DPp2)Jh35bdiNjJZ3cMpvsiCJoK8yi0Coz6Hwy34tEZHYQ8Je)IJIZsJRz7o8Z7lBCODrcf6YjsQcF1zG8AigE)sq(qVS4kWaMosI1lnsgBt1lE4Naf15)5IRsucRZIxsmyEW4Ft3nytqtFNyjxUhIy9PpbjovSdKRXO7AhKND2Ebpfol2MtE2D5B9DuOH1PzhJYnmgHZ5oGBcoPkfLlMd9QIq5K)uym6eiQx(9XET5(zhfsJpmnE7O8HX1WFtttM08VbtKygQe)HSTpCg7a(caE7Bsx2l3Fy36ox2dYUNu29uFa(4cz)JXaE5mSJ1t1CFr1(DdQQOxe0mbt5O9TVazMvSIg(m0uZHD1EBnE7o97oHnD7GaSGwdGHVVJi4BbHwIrTg02jOkSYzydi0wKyhzaCUZK7F)hxDy72)(p(5nf15mN3YmuEsHk4EgVBe10ipNlrDAkHag3t7FXz88JV7Q77OE0DrBQ1dUt9obo2PgLKPbTqcxmyB1GXQ2vJgbeDiVh8zvWc2aX317qPWYWelAfvDDn(lGftJgmn6QPT2QHOua7Inlt)t(qr4KUpDKZZLqMnp6UHD0v)HpgCYQlxvFaSk3unTGtKbYhUB(vOIgwHaFUuHkG3bCos3nJvAVgrB32N50xYcmA5UOGFjOIcYwLGaUL1KAYQFEn(NktVcdNfAe6qf4lYDxBoQY89uSRzYcPjf1fvIxd6Af9GhAsK9IuVTZevpIRGei7IMWKO(OmDpCGEviRv1Te6VgKvh3dDHxdYkIs(xHUjQEG4(AqwivYFifTriRSFxVmjYI2XFK)SK(mq)fYHRlejtI6JQ)(JX0JDYHLO41NSqQT9AbTxd6Af9WFAsK9cbF0L2eOudPJmDBpRjr6XeW9HS(1GS2erxuVMezVa8meM0tQouhojTleCtI4J734FfrbK43)cKvjt7bS4RbDf6Fqprxi0hPeJNL2JvK)34kTTFJq9AqwrYRSduyGyeJJ1E1TTbmOmgeeTlcExOBQMN3MiX1p90HD5DohGlj05acCbBnHc67y8Mwv0nNH1LHPZ0DXUAF5tJVjP6tSQWhv5sA)(JgYUVHOBI02fEQoj5K9nvnwBp5P6Vt3yKc1j75qKmMt1ND8k13zv3XyJorttqdX89gGsAorpUkyV9HOiEEf1QPEIVBx(tV4003TdssAv(tGYcLoaLV3D5zRDvBScZEEjYj4mw2mGVurN8u(h43wNJiv9CwznIYxE1HsUqoUwuynoTQ2zC)gyiBGK)C1pcMiL1vNIB9qz2t5TL1QDmTpZP7g20cDl0P7kLgdvY1bb0tDBTo5Q(X9iAyOu5O0TjceN0Cb2ny8kswTp)Cu3TFQSDVwbweYZ6uDt(MfwtQsYItDZcDCDL)WPkGBB7KCgAcRl)FG7D1NQ0GMJ0BAkgAly18kguJcFLe(u2FIMYQatqFSyhpCNOiWGH7V7CyVPyD(STf)1FLvcjfdgg2L1s1EwtxxEZHTBpJkv2SuNrjRyerN5XdvbjdYatXydgjj8dqZsZCi1Wa)jiqnereMrAfHpPinMqflv7HoYdPInHbxKrRtkzq5ucndQP2YOSeRAbVHWtknMXO0OzGwjYgjia9KIiltnBkXAXwcglnJcympYulH1AIIbDl2WRVIPa2ZY4FNeBOxerZqMyt9a2rCQiksZW5W7FgCWePhuqjXoYifHONwZevli0NKIenZXgcNlJhUYygXkHG2ckyeU1L6Tn3xaXirfqw5zsgKmcZvfizAew8XldWNHrKZ9tLG5a3kNAy8KCdxZN(rXmQyeKTGOMKGmv1wgrscvDPrtSgSA0aItPLtgLYamd8kXJSep1q6rAgtvypWkAwbH3Ps6X7mIHwxfZ0hwp3Yjie4afSy6avztzqEvscnEAdGlFJmJyac6rpWTjmM5UoUe)BnHbBIhy5ynJuAkbPOHWGLryfzrVeKyGejnogRwuerQZmC)rrKoySMiNIqYwMYai7rZlMH9lnMr(2W3pe2igQ0iARkvwBJEpX7ela6n8HCSKHSmvYBNOiUPfyPcmesGb6WewYwVgvsZbhZrwsMb0KWkw6bavZJqlOryjem1eOVc6Wd009xKszalBlB8DohIo3YHoLQbV5BQ6gCzVUB64iozl6Oh8Voy7Je6K1hmbocpApiPA9l7nC)Jgwyx47cCy49h3PCQn1dVBqVaPAI6nGd)1J(9ggcNdvtCPhZJGLUBSd(9nMEptHMLc1HAwSFzOivqmNoUYTDbRGErWE7yWbACqFupGs8rdmDj9Ji5tzpwSAGGfAa85cSdOMVfIgm)7GpUOjdO291Wqv2VHZACr3Q(SUCGtVGaiwx(gi4Shbs7Ao15vBZZFomK5Ly8EqsqEarkWpVrO0rPeU11LBRQpS7CMtc482DXB36ZEkwnTmBYOCPccLFy(cTOIRX(91N3ce7Yd7RvNZObZZuwBVSA7EkpYV3u0cJlzKQvz1WT2ZBzGKPDrywuHNm7oRDIgR7fmPdzNZOtsj2ADz2JquMllZZG8poJjgZ8gCiobzSt)F9QZz0qKDooR4PNHNCwtXRL8qEw5zPKG1GLBy1U3x(Hn0g4EWf89B8q1Y2bt0logUENnixxM2bTXbsnj0oMTXuq)CMQXSiN5t1Rxu)KPfifd8pwv0wlffACS4SrEnW(9LCkWok2aLkbyQ3K5ry)w8JkPxvWs0JQ)t4Aq7E23SHhvpCFzHxxfH3c(JDnqXncBx5)aNmoh(NrwJhD0poIV)6IR(jinHetme2leGBAQ2b5RjmUL7zuLxEKlP)5s0SgOxpBNubPm362DvrRoDqGaboBFo4)kgcd6yGe0Duf8UTTPUcmjF)H8QQCcK42(fliMRJ(pjIJ7yBVeK)VnG5y)V7mn)HVCZ9V7o8Bp5AyitKWzX)NV8U7U(ZbVisM4mQD7LF8Y3E9nnVG(r7dV4tx((31(uIk3E31VB(9npvbX9MYu)JF(n)3nVWfAl6Z)UVC9BBhUR9uHhF3NF)xAPTsNKGMZMp)dx(Pld5KybBMJUV3In)yT7UWFO1PJsCIg6)LeCHXJTm6smRGuvc9f8)ebwgKtyttR20SQyldsdgtkCj1SQlxWjUVK)zV7Mk2mY4BC)(fXN00zLCMIQySfpx6tvehRchc(eRIZd21RZ0yOme8n7mKsp3tLUs47gl1rOQ4yfT0WtO8gm(wG0AOKxCvMKztjowjNCxt(90V1yCike9mANWnjRHB2xjiwCVXNOVlvULlAB0uiLiUjYLTD(PV)J1ex601M5Yevj4dcljg89nAt5qAQlaiQIsPdRyUToJvCEZAl3YZ(KPeX(o(0Kkz2WNKySGe5uzewgKpBtzeGxqvNaOIomBnQTNX540ExY)K0qQ5Rnd9liBPtsdFu3RMKNHdkNDg2pxBJPD)(lrpZxZHa36(R1LAOTQoPo1AN7OcC(pW47r9U2Xz6DoEsAAxub(BT0p)U5OgwF7GSictgbL2DZP50RDOtZWutcAyss22gfa(t4lO0XNrjhp6)CAMKG944ec41ZO4LlhkrFMv6ekXSEHX1K(7X)Wb)NZ8BMyp3wvNvFOAP)kIxZgrGROjAJ6fl(pF81Sba" +end + +function Gladdy:GetMirProfile() + return "4XzT80SCBJZKpm75XfXpee4OvsCIRnXXRLtntQAkndLeTf3ir6LKAZ45qE2)AGUbjejLIyIZLiAsGgn6Ur)pYc2I7xmF5(hEOEM9FUEvzXTPRxNx84IBylMxLw8y2R2KT6l3w(1SQzPv3N9pnlMTy(Q06g4pNvwToR6vLBlRSqk1nRLlUjAX8hD)BL9FBwmFnmOYTRl)AXLBFAdoU1vVoVoD52SxLxTABwiyFmeKrxihhOnv5fFjR5qOSCX8nzPBB2aW5M0Dzxvw0mp)FZwCdhMAXt3x2KT72TPnz1ou5YTFn9567tREmRjBTD6vPRYt3EBz9I53D9BF39wm1bLvPa8rmh34ZBEgEZ8RlAYQEiDv2FE561FSO(pF7wGi(8FE9U0hZQ)tCS)1B3wwdGSEtkqgQZFCtZ957ay0c1o(GNw92QYV(68QSvn5LfTyZ)Fwvn83)1U0)3YQ)Qy)o3SF8WXo7J3F)h)GBdxLTR0Tbwm)1Lv513E7I5pL185pcRuwZIB(nfhOZ7RsFFEDZRZEiD)2glPxLKez)nRWsExB5ppvLdqO55f3iJS0)0vFba6BM9PRUYYq4jCUyAtHXfXXtBkczsK5OtHf3oL21isePN2AehlM4ExWuk20McxOmYPnfbJXsoN9EifwFcY14mLyPEIRcpMNm19IKDCcglAaBuejJpoBCe(U2OpU0Oyu2UupXnHugjpoPA0fHfjp(ImY(wZ48PHujSjk8cYHhFgm(WtuAP6SocgSRncTAAyvmxE8zm(IOmtLwXL84PUv0IPQLtdRYexePyYhB1QtCa5i6t48JlmYhkmYnGEUPi9YmXrtLAPmjhFRp6zkUYON6uIILtLaNKmrryM4e2rgxrA0uTjacxMZsVyOnbU54Ntgrvkpk6eS9JOEpEQQHatv8jUkSiEYj28JzfHFcRcJVgM4KJRJ)iwq5Nqb5rCEksF8DY4IW6KPkEjKsZeNcdusC8PmkIznvprhieGfLJlsoMMOKOtiFno9IhpvxAfIKPA2si4rtsfjxyobboE4eIJoHs7ro9QIMOl2jt2mQqimhFrgLBiJLIJlWpchxjNKaIsmvRHMOPsO0k5evMOzNqF1yI5k1PC1AeHJe904DnTXD3lirxaP)HpmXOJh9SnQ5UOxdNXQTP1U0kmitbxj1ArsuCCc4MNWAy9HFlwmEG(D5H4EmKF7cgGZU47VsMWzmJsbM24MyvcaqP2gSE)0AGOAhcDje7lIuJL(Il0wu4jkbiVlZg5oYPW8mCBw1QSIgiuFlw5hxxAhSSiiC735tkXzNZehO(q6)0rD7Mz9B64UvU8v875RB2Cv6QMshsBWq6DPMOA)tn4SGf8gw3Q288tzlMF7MNRZxLU1TYmhw4Xi7gT)WFx52NdgkSur0WVigEcMIS)uUkVk7GPehfScQbJ)YQvPfJpd3cO7pHBsB2tlr0fGf(WnH7VHjjgStM7sfdnl3cmyPMVV4lfLFTO)u)e9AKzrmo)gIPgqaQkRB6TqDlI9ay(LfR2aSUUKxzLCd4YDNVoGtZOZZzRFDMBi2LwhbgnMzDokXKyFWEGW4EJguSpZN6b4HeBuzWV2SWmZQ8q5Mj3a61SJN(1fy8mRgsHBCmbNPDZ3boxiQ2PXGyJCV2GViMjCdJ(ogeOD58RNneVzohgW1tAyUfIhLGisedFqirazJ9AMZblesQeTgHGqIdWgQ1mVXE3APtW5QIzm3N8Vaqp3V4EbdvXodoHMkbIwczKJ8PnChaCbc4aDI0TyA)Q787d3Prke2efvQKitbu5HyrSX4gRKrOm6Sb8qS29bLMGLkX99KiIkc8t3dcGWJBAUYncNfm3QbET5(chxuUNGBtS1mhDfxk0Z(zizY9GrJKnxQMCZvJ7(yo(lMEOzoRFj0lICpOqiW1ib1Uiizbqp8bJb3k28MGiOGKrviTNRej0wIJVWK4MkW7qckiuJduHpKGteZjHf0rAexmOOQIKfzW2OvO2bsftq8igkietIma5cxCDmodqwc5ijilHyC4xbIoIYmLBljureuK0HSi3pGlsoepItqfy7mcHyinhCPffffcsyHhtKsdrjtm0bbj(aMad7Bs0jeEiqwkdpRWt4Oym8dbLegsBsek64gttcYXejHth7SXl4WXe)jzego)mSBoIKrJZRxH51JGuAbUnur06ICeLo2HXcgjXd0z8WrcncINNWiXhcnHTirItCNidSqF22x7Nj(bkBNGllTQ0Ri7gKRs1Z3u(1RQYZkwdwnxIPP)tpHLzW7uZR8ojD4R91CXIqBo07bQWdyDg(2FFFz52M8N(2FxvUVynynHQFWbfd5mlQIFUwhyogrmyF2vyhxbtE)BUcg(2sRbPXiKVAFvD2bqKDGVwQdD37JLvTg6UigDPzyLmADTACCEmEtBnrcDw9zGdhZngUa0jAKGUvT1hsGd)plUsl1kHIdkYatF2i1XV0Fd26m13XFYLLnnL7(qA1J5foFtMtvZQ32l4TDvkQXvTQVJGoSoT7ylDZ67WuePdrAhqCu6oVFxL3s7(njOWRL5Cgsnl)(v5Q94CpX2eVxD0Uu496RffNM8oE(WwPqR866Q3LU9HZyhqrFyp1oPQa6oHMT(VwU9PXINcpd4H(i4Xf8HC3aCz6S2Ow(rOuCzEDzXOsvQfbf1DkS7x)Cr6U8v4WNzv0SVOXPLAwNwNHvjUv)Lx2tffQHOLD7RmnDGjqzUtsYQhgepw5ujcaARfyhOmD()3(0QSV93xTF72V93)(M8MmcZ7qgmuRdcWLq4(oLJJ8h98wVOEd2m(17pcu3EGyuFePncC7U3BK5qBLyCQs3Xh30HjcQ(Axl87X(nLpsfIshqpVUOgJnVlyLoAxFZT)HBZEGMGUbhQI(ZbK7LqOop6odDWH7XjGUD5LRA2dQJBRRVNwUC0aK77dGvSXMEaFWvlTs99jXGnqGY)iOYoZf(v92SSNSpeKcMhkRwL5j)52FVb8slYG2CBQ2w3SV4CMtSr5u1vvSU)uwESPOv4YSjTA35SgkBcmTRrzzZ5m(yW4iHt9NYXXjj3HtpVABzr25Skkge6G1VTvPnatR(CMdNf7OwRb9zwVWoRTJkkbJ9p9CgDSbrR1vPpwwuVSklfobDgtus42xoVDc34OXRxDoJwXKoKkF3tWBoRP4LsEilT6CgVnw)fUKx0E(3PAjWe8Pnney(1PE3(qqAZ4DQPc1)L)tPt1EKFq)cr2p7AiM4Kf96kkeNerdnvE9UD7lY6zKgcpeTwAtfL3kiQ)bHK2QzoVxo7ID9efGHohHUbiVdwTRkXtWNY1Yv590X9d0Ssh4MIV3GA1v6eyvXXNSeIn2W14NQvhCJHZeNS87wWKCQsotRKnfjNEm6Otu)aCijFVbi4jNODpCJP5WKaFEXJ0gR4BkY25cumTOa4bRY2bkTC0BYC7DzPRDdOM8MjZpdAaFQg584jlNfRmBYhFkTQXM42S69vKZ2K9myA1DZ4(nWq2agKDU53k32lUKhQapMPisqNcBhvVoAl08D)WyDNfmwfmR2tI5UTwpxfEpgp5YEU6q(Te1Ec2ny7rK0gVVrwz3HUx0)yfOsilTxGPEhELlccnLwOqVlhKA)VxW5D1T4mKnwx9)aUL2CQ48swmAKTDvFGwXapg9E29H0)XQDR(wGgNxqd3rCcuH4(7ES)n5RZMTn)F)30kylb(nxK2b1bkyxxDd4u9PtjtxGcNzqf0UYkx)LZGqEGJMosX9F0gFDOitdCwBtDx)DEEgzgSu9fFVlBleqvrdmKx9MBU)n3DiYpAs(dp1qhS772PpEBlJU9KOPJn8dO2N6r1(5ujKXpXCT0g(r)6tf3UVc70wpU)5oouyK2TwHx3hVwxfsXO50gOMugeQwy4BOwRrI6SxiI4zPa8Bam(bO2hyKLqzFuU2nziBim631v)Xy6u7N5iRw)zbNP60l7n4q(RfCwVnw57aKVZMafFTRgBZ3bU4Vja7ckaQvFOVqRDcUt5W0qp2S6wELpxbuNChRged7zP0nKBkAXVHS)rYVGDVHC6bQ3wowv58oQ(JlrGKEQaWRYBJcVlIE0vs(bACUK8BySSQ48JaBsB4RTvhuWmyv9WEy2(qKMgJV2pT18XM5DCWsSyAunFGPQPAKPPP6RPNR9PMfwGIiSQacjvPebttfksqdraci0S9Lm0wzp7d(AgYI0uPjumFnkIPY1jPQecVbRArIVsc6eScloVbj0KQDjwEgSLiTVW1QJoKYeDybcDEKAhlpMklzuevMpfwsN261is81IL3vafFz8ueJqGWxa7AK(Zui1UT8lCUVuFQwSIynIijvDePGQVPstvouXWQJYK(cNKy4eAiPsSiz(YgXWYkInW0mFh64gmv2oakk3SuerRT6Hq4aoKW1rmUrkn(60rLe1vrPtyFK3zFmu13anpq4)v5l33K11pdGZWB3UyoOAZMi35415ybmH15pKdovo3EkTPbcRAU1YjLQzmp6l8D5qpGCL1P0XHbVdgoxxTGqmciU0nOV93)xIXHthywJkvwVW3)ehdsYPaP4tbP4Paj1PGKAkqk5uqkzkqsFkiPNcKmNcsMPajSLepgOSUxF2WQn0RppSfSWSv6cl0(NGUY(nvwAy5e2x3uUZLH85wRcNYp8iCLDGLfd2i(faxnBq)0ojWEHXxfKyXaGlIsg0(Ltc6hfPh04SViGvl6N4IxcWQKdAhZxcWYII)La3yXGUE)LaSAo)Nsq7iGLp8AcnjWAZ03J0VuM)cKFfkv)EkDsq)OYV)Ci9X4Cdt82lby5XMb3zVxc4QzdAy3jb2lyeRZ0gJBlOTLn4Na0hJapSh)FjaRoM1pzNtcSxawgct9SrfkdhB6Nu3jb8JB34xcPGP)vW4eCZGoX(LaUy4o)eW9ciuOqHylVuFOG8VIJ06H3CSxcWYIFHnGcdSne7WCMEqkeoD6gcYV8KI)V21dc(mcL)5dBWM(Xn9zhEFqYkdZBBDtAZ(6LEu2dlBV70LFJ7CEy2VWD9sp)Q8rthxaXjSJKCPejTI6KaUoQDs0RKr2Sye0Nzh2ox3ww1uLMh2chhKiPjrrpiJkDBB6AUp36NUZn639jxGNWt7SnKL9Yf5kM2VF5D3D9hd(qmhl37Tx((lF9130(bmiE4dF4Y3(MU3Iq527U(nZVV9TcUiXqq)9F8v)3TFW1tLwYXDF66x3nCxBbdV(Up(2p1bBmKB41ZF3LF4YqmXMpaNC8bLl5NL61VOjFi9X8vhCwYBBK6rOlC7L022Ny65bK1ESSFPJoDXeCZa76O(jRlqa7NLGekc3LC1TzPWiPJcZgMm9U)ZOGKQ7sJhm02m7Y8B5UgyXVE9VplHLBS)13z2GYE4)FgcFnZ8zx5d5f57s3MBRviDLcCt2sKfqqvuNDtnxFehBaxBrGN5YMe158mSRGzrytxReuY6msSTYnkFVx77jznLIoFceBt1LG5ZLKstTPSu019ZydzBKut(NOOBQac2ig2r82M1KGMMY7MuJ9bUIAJEjnsJgZ2vSGsgPmHwFbbbkZGSyzIpZDypyhRn(oEhX02ecQm0(N6U(yUVR6P0aYJeyU1ukcO(m8XzuY2aebZQyIpjGsQLVBtzhmc362MYozmqgrOa0kpssDzoEPfAZYRfRj2l1H8julT7tYRfdCRSHY2lETsue3NYNlljYNQwKcsqLsMjtJPcLNOqudwnCasdUC8idLbtaxrCKO4MeuosrxkbypqcAAgEHbeC)fgiIUBkcjbFy9ClhdZaliGHzVui0g6wsiWSIsBa7Y3sZO84Ixbckl4X0LoXNP0yfMk9y)nZqsP21yWKRMGxIb6kkyrrpferaWSI7f0LDWsIqXzk53rrOmOuHGtGxfeUHUbg(2H3NuxJKU6ijsFg2JO7AqeUv5cTUvUhXDefa5gIjl9PSUlt1yIQtO7aadgcsWazy8YyO9suXTmocJ0indGjEzl4(BqaLl52KvRXRaGcV1emK5bs6(dsgQJ)d10EgTA06GAicXre20bNrPPpSQQNNrmwakewZ63UpRUoR2UDw67WObxqXdl4zxBkFF5L2sIDTZhVE3VYFCBzpf8FWthwMp7ho8ooUk33RYWEAX)5fSSRtb" end \ No newline at end of file diff --git a/Modules/XiconProfiles.lua b/Modules/XiconProfiles.lua index 9fb9c1b..ab871d9 100644 --- a/Modules/XiconProfiles.lua +++ b/Modules/XiconProfiles.lua @@ -64,6 +64,16 @@ function XiconProfiles:ApplyRukk() Gladdy:ToggleFrame(3) end +function XiconProfiles:ApplyMir() + local deserialized = Gladdy.modules["Export Import"]:Decode(Gladdy:GetMirProfile()) + if deserialized then + Gladdy.modules["Export Import"]:ApplyImport(deserialized, Gladdy.db) + end + Gladdy:Reset() + Gladdy:HideFrame() + Gladdy:ToggleFrame(3) +end + function XiconProfiles:GetOptions() return { headerProfileBlizzard = { @@ -106,7 +116,7 @@ function XiconProfiles:GetOptions() }, headerProfileClassicNoPet = { type = "header", - name = "Classic " .. L["Profile"] .. " No Pet", + name = "Classic " .. L["Profile"] .. L[" No Pet"], order = 6, }, classicProfileNoPet = { @@ -116,7 +126,7 @@ function XiconProfiles:GetOptions() XiconProfiles:ApplyClassicNoPet() end, name = " ", - desc = "Classic " .. L["Profile"] .. " No Pet", + desc = "Classic " .. L["Profile"] .. L[" No Pet"], image = "Interface\\AddOns\\Gladdy\\Images\\BasicProfiles\\Classic2.blp", imageWidth = 350, imageHeight = 175, @@ -180,5 +190,24 @@ function XiconProfiles:GetOptions() width = "full", order = 13, }, + headerProfileMir = { + type = "header", + name = "Mir's " .. L["Profile"], + order = 14, + }, + mirProfile = { + type = "execute", + func = function() + Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) + XiconProfiles:ApplyMir() + end, + name = " ", + desc = "Mir's " .. L["Profile"], + image = "Interface\\AddOns\\Gladdy\\Images\\BasicProfiles\\Mir1.blp", + imageWidth = 350, + imageHeight = 175, + width = "full", + order = 15, + }, } end \ No newline at end of file -- 2.39.5 From 60c823fa075a50f3c5a57a8086815299c6b120de Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 14 Sep 2021 23:55:17 +0200 Subject: [PATCH 034/268] LSM replace --- Gladdy.lua | 12 ++++++------ Modules/Auras.lua | 16 ++++++++-------- Modules/BuffsDebuffs.lua | 12 ++++++------ Modules/Castbar.lua | 20 ++++++++++---------- Modules/Cooldowns.lua | 12 ++++++------ Modules/Diminishings.lua | 8 ++++---- Modules/Healthbar.lua | 28 ++++++++++++++-------------- Modules/Highlight.lua | 12 ++++++------ Modules/Pets.lua | 28 ++++++++++++++-------------- Modules/Powerbar.lua | 20 ++++++++++---------- Modules/Racial.lua | 12 ++++++------ Modules/TotemPlates.lua | 6 +++--- Modules/Trinket.lua | 12 ++++++------ 13 files changed, 99 insertions(+), 99 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 9926240..5d4d709 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -486,12 +486,12 @@ end local defaults = {["statusbar"] = "Smooth", ["border"] = "Gladdy Tooltip round", ["font"] = "DorisPP"} local lastWarning = {} -function Gladdy:SMFetch(lsmType, key, dbEntry) - local smMediaType = self.LSM:Fetch(lsmType, key) - if (smMediaType == nil and key ~= "None") then - if not lastWarning[dbEntry] or GetTime() - lastWarning[dbEntry] > 120 then - lastWarning[dbEntry] = GetTime() - Gladdy:Warn("Could not find", "\"" .. lsmType .. "\"", key, "for", "\"" .. dbEntry .. "\"", "- setting it to", "\"" .. defaults[lsmType] .. "\"") +function Gladdy:SMFetch(lsmType, key) + local smMediaType = self.LSM:Fetch(lsmType, Gladdy.db[key]) + if (smMediaType == nil and Gladdy.db[key] ~= "None") then + if not lastWarning[key] or GetTime() - lastWarning[key] > 120 then + lastWarning[key] = GetTime() + Gladdy:Warn("Could not find", "\"" .. lsmType .. "\" \"", Gladdy.db[key], " \" for", "\"" .. key .. "\"", "- setting it to", "\"" .. defaults[lsmType] .. "\"") end return self.LSM:Fetch(lsmType, defaults[lsmType]) end diff --git a/Modules/Auras.lua b/Modules/Auras.lua index eed66a6..abf93c8 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -88,7 +88,7 @@ function Auras:CreateFrame(unit) auraFrame:SetAllPoints(classIcon) auraFrame.text = auraFrame.cooldownFrame:CreateFontString(nil, "OVERLAY") - auraFrame.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), 10, "OUTLINE") + auraFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), 10, "OUTLINE") auraFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) --auraFrame.text:SetShadowOffset(1, -1) --auraFrame.text:SetShadowColor(0, 0, 0, 1) @@ -152,7 +152,7 @@ function Auras:CreateInterrupt(unit) interruptFrame:SetAllPoints(classIcon) interruptFrame.text = interruptFrame.cooldownFrame:CreateFontString(nil, "OVERLAY") - interruptFrame.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), 10, "OUTLINE") + interruptFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), 10, "OUTLINE") interruptFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) --auraFrame.text:SetShadowOffset(1, -1) --auraFrame.text:SetShadowColor(0, 0, 0, 1) @@ -205,7 +205,7 @@ function Auras:UpdateFrame(unit) auraFrame.cooldown:SetPoint("CENTER", auraFrame, "CENTER") auraFrame.cooldown:SetAlpha(Gladdy.db.auraCooldownAlpha) - auraFrame.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") + auraFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") auraFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) auraFrame.icon.overlay:SetTexture(Gladdy.db.auraBorderStyle) @@ -243,7 +243,7 @@ function Auras:UpdateInterruptFrame(unit) interruptFrame.cooldown:SetPoint("CENTER", interruptFrame, "CENTER") interruptFrame.cooldown:SetAlpha(Gladdy.db.auraCooldownAlpha) - interruptFrame.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") + interruptFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") interruptFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) interruptFrame.icon.overlay:SetTexture(Gladdy.db.auraBorderStyle) @@ -496,7 +496,7 @@ function Auras:GetOptions() for i,v in ipairs(list) do borderArgs["auraSpellSchool" .. v.key] = { type = "color", - name = v.val.type, + name = L[v.val.type], order = i + 13, hasAlpha = true, width = "0.8", @@ -600,21 +600,21 @@ function Auras:GetOptions() debuffList = { type = "group", childGroups = "tree", - name = "Debuffs", + name = L["Debuffs"], order = 4, args = Auras:GetAuraOptions(AURA_TYPE_DEBUFF) }, buffList = { type = "group", childGroups = "tree", - name = "Buffs", + name = L["Buffs"], order = 5, args = Auras:GetAuraOptions(AURA_TYPE_BUFF) }, interruptList = { type = "group", childGroups = "tree", - name = "Interrupts", + name = L["Interrupts"], order = 6, args = Auras:GetInterruptOptions() } diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 4f0c6e8..7940fd6 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -264,9 +264,9 @@ local function styleIcon(aura, auraType) aura.border:SetTexture(Gladdy.db.buffsBorderStyle) aura.border:SetVertexColor(spellSchoolToOptionValue(aura.spellSchool)) - aura.cooldown:SetFont(Gladdy:SMFetch("font", Gladdy.db.buffsFont, "buffsFont"), (Gladdy.db.buffsIconSize/2 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") + aura.cooldown:SetFont(Gladdy:SMFetch("font", "buffsFont"), (Gladdy.db.buffsIconSize/2 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") aura.cooldown:SetTextColor(Gladdy.db.buffsFontColor.r, Gladdy.db.buffsFontColor.g, Gladdy.db.buffsFontColor.b, Gladdy.db.buffsFontColor.a) - aura.stacks:SetFont(Gladdy:SMFetch("font", Gladdy.db.buffsFont, "buffsFont"), (Gladdy.db.buffsIconSize/3 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") + aura.stacks:SetFont(Gladdy:SMFetch("font", "buffsFont"), (Gladdy.db.buffsIconSize/3 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") aura.stacks:SetTextColor(Gladdy.db.buffsFontColor.r, Gladdy.db.buffsFontColor.g, Gladdy.db.buffsFontColor.b, Gladdy.db.buffsFontColor.a) end @@ -903,7 +903,7 @@ function BuffsDebuffs:GetOptions() }, font = { type = "group", - name = "Font", + name = L["Font"], order = 4, args = { header = { @@ -946,7 +946,7 @@ function BuffsDebuffs:GetOptions() }, border = { type = "group", - name = "Border", + name = L["Border"], order = 5, args = { header = { @@ -1033,7 +1033,7 @@ function BuffsDebuffs:GetOptions() }, }, debuffList = { - name = "Debuff Lists", + name = L["Debuff Lists"], type = "group", order = 11, childGroups = "tree", @@ -1048,7 +1048,7 @@ function BuffsDebuffs:GetOptions() end, }, buffList = { - name = "Buff Lists", + name = L["Buff Lists"], type = "group", order = 12, childGroups = "tree", diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 96c4c98..17d62e7 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -61,13 +61,13 @@ function Castbar:CreateFrame(unit) castBar:EnableMouse(false) castBar.unit = unit - castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.castBarBorderStyle, "castBarBorderStyle"), + castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) castBar:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) castBar:SetFrameLevel(1) castBar.bar = CreateFrame("StatusBar", nil, castBar) - castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.castBarTexture, "castBarTexture")) + castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) castBar.bar:SetStatusBarColor(Gladdy.db.castBarColor.r, Gladdy.db.castBarColor.g, Gladdy.db.castBarColor.b, Gladdy.db.castBarColor.a) castBar.bar:SetMinMaxValues(0, 100) castBar.bar:SetFrameLevel(0) @@ -81,7 +81,7 @@ function Castbar:CreateFrame(unit) castBar.bg = castBar.bar:CreateTexture(nil, "BACKGROUND") castBar.bg:SetAlpha(1) - castBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.castBarTexture, "castBarTexture")) + castBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) castBar.bg:SetVertexColor(Gladdy.db.castBarBgColor.r, Gladdy.db.castBarBgColor.g, Gladdy.db.castBarBgColor.b, Gladdy.db.castBarBgColor.a) castBar.bg:SetAllPoints(castBar.bar) @@ -101,7 +101,7 @@ function Castbar:CreateFrame(unit) end castBar.spellText = castBar:CreateFontString(nil, "LOW") - castBar.spellText:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), Gladdy.db.castBarFontSize) + castBar.spellText:SetFont(Gladdy:SMFetch("font", "auraFont"), Gladdy.db.castBarFontSize) castBar.spellText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) castBar.spellText:SetShadowOffset(1, -1) castBar.spellText:SetShadowColor(0, 0, 0, 1) @@ -109,7 +109,7 @@ function Castbar:CreateFrame(unit) castBar.spellText:SetPoint("LEFT", 7, 0) -- Text of the spell castBar.timeText = castBar:CreateFontString(nil, "LOW") - castBar.timeText:SetFont(Gladdy:SMFetch("font", Gladdy.db.auraFont, "auraFont"), Gladdy.db.castBarFontSize) + castBar.timeText:SetFont(Gladdy:SMFetch("font", "auraFont"), Gladdy.db.castBarFontSize) castBar.timeText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) castBar.timeText:SetShadowOffset(1, -1) castBar.timeText:SetShadowColor(0, 0, 0, 1) @@ -129,17 +129,17 @@ function Castbar:UpdateFrame(unit) castBar:SetWidth(Gladdy.db.castBarWidth) castBar:SetHeight(Gladdy.db.castBarHeight) - castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.castBarBorderStyle, "castBarBorderStyle"), + castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) castBar:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) - castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.castBarTexture, "castBarTexture")) + castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) castBar.bar:ClearAllPoints() castBar.bar:SetStatusBarColor(Gladdy.db.castBarColor.r, Gladdy.db.castBarColor.g, Gladdy.db.castBarColor.b, Gladdy.db.castBarColor.a) castBar.bar:SetPoint("TOPLEFT", castBar, "TOPLEFT", (Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset)) castBar.bar:SetPoint("BOTTOMRIGHT", castBar, "BOTTOMRIGHT", -(Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset)) - castBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.castBarTexture, "castBarTexture")) + castBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) castBar.bg:SetVertexColor(Gladdy.db.castBarBgColor.r, Gladdy.db.castBarBgColor.g, Gladdy.db.castBarBgColor.b, Gladdy.db.castBarBgColor.a) if Gladdy.db.castBarSparkEnabled then @@ -183,10 +183,10 @@ function Castbar:UpdateFrame(unit) end end - castBar.spellText:SetFont(Gladdy:SMFetch("font", Gladdy.db.castBarFont, "castBarFont"), Gladdy.db.castBarFontSize) + castBar.spellText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize) castBar.spellText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) - castBar.timeText:SetFont(Gladdy:SMFetch("font", Gladdy.db.castBarFont, "castBarFont"), Gladdy.db.castBarFontSize) + castBar.timeText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize) castBar.timeText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) castBar.icon.texture.overlay:SetTexture(Gladdy.db.castBarIconStyle) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 622dd5b..97c0a15 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -120,7 +120,7 @@ function Cooldowns:CreateFrame(unit) icon.border:SetVertexColor(Gladdy.db.cooldownBorderColor.r, Gladdy.db.cooldownBorderColor.g, Gladdy.db.cooldownBorderColor.b, Gladdy.db.cooldownBorderColor.a) icon.cooldownFont = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") - icon.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") + icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) icon.cooldownFont:SetAllPoints(icon) @@ -172,7 +172,7 @@ function Cooldowns:UpdateFrame(unit) local icon = button.spellCooldownFrame["icon" .. j] icon:SetHeight(Gladdy.db.cooldownSize) icon:SetWidth(Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor) - icon.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") + icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) icon:ClearAllPoints() if (Gladdy.db.cooldownXPos == "RIGHT") then @@ -220,7 +220,7 @@ function Cooldowns:UpdateFrame(unit) icon.cooldown:SetPoint("CENTER", icon, "CENTER") icon.cooldown:SetAlpha(Gladdy.db.cooldownCooldownAlpha) - icon.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), (icon:GetWidth()/2 - 1) * Gladdy.db.cooldownFontScale, "OUTLINE") + icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), (icon:GetWidth()/2 - 1) * Gladdy.db.cooldownFontScale, "OUTLINE") icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) icon.border:SetTexture(Gladdy.db.cooldownBorderStyle) @@ -294,11 +294,11 @@ function Cooldowns:CooldownStart(button, spellId, duration) self.timeLeft = self.timeLeft - elapsed local timeLeft = ceil(self.timeLeft) if timeLeft >= 540 then - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 3.1 * Gladdy.db.cooldownFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 3.1 * Gladdy.db.cooldownFontScale, "OUTLINE") elseif timeLeft < 540 and timeLeft >= 60 then - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 2.15 * Gladdy.db.cooldownFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2.15 * Gladdy.db.cooldownFontScale, "OUTLINE") elseif timeLeft < 60 and timeLeft > 0 then - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.cooldownFont, "cooldownFont"), Gladdy.db.cooldownSize / 2.15 * Gladdy.db.cooldownFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2.15 * Gladdy.db.cooldownFontScale, "OUTLINE") end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 0) if (self.timeLeft <= 0) then diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 9cb5e9c..8da1386 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -116,7 +116,7 @@ function Diminishings:CreateFrame(unit) icon.text = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") icon.text:SetDrawLayer("OVERLAY") - icon.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.drFont, "drFont"), 10, "OUTLINE") + icon.text:SetFont(Gladdy:SMFetch("font", "drFont"), 10, "OUTLINE") icon.text:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) icon.text:SetShadowOffset(1, -1) icon.text:SetShadowColor(0, 0, 0, 1) @@ -125,7 +125,7 @@ function Diminishings:CreateFrame(unit) icon.timeText = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") icon.timeText:SetDrawLayer("OVERLAY") - icon.timeText:SetFont(Gladdy:SMFetch("font", Gladdy.db.drFont, "drFont"), 10, "OUTLINE") + icon.timeText:SetFont(Gladdy:SMFetch("font", "drFont"), 10, "OUTLINE") icon.timeText:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) icon.timeText:SetShadowOffset(1, -1) icon.timeText:SetShadowColor(0, 0, 0, 1) @@ -184,9 +184,9 @@ function Diminishings:UpdateFrame(unit) icon:SetWidth(Gladdy.db.drIconSize * Gladdy.db.drWidthFactor) icon:SetHeight(Gladdy.db.drIconSize) - icon.text:SetFont(Gladdy:SMFetch("font", Gladdy.db.drFont, "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") + icon.text:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") icon.text:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) - icon.timeText:SetFont(Gladdy:SMFetch("font", Gladdy.db.drFont, "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") + icon.timeText:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") icon.timeText:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) icon.cooldown:SetWidth(icon:GetWidth() - icon:GetWidth()/16) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index ea3f95c..31e850a 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -39,18 +39,18 @@ function Healthbar:CreateFrame(unit) local healthBar = CreateFrame("Frame", nil, Gladdy.buttons[unit], BackdropTemplateMixin and "BackdropTemplate") healthBar:EnableMouse(false) - healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.healthBarBorderStyle, "healthBarBorderStyle"), + healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "healthBarBorderStyle"), edgeSize = Gladdy.db.healthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.healthBarBorderColor.r, Gladdy.db.healthBarBorderColor.g, Gladdy.db.healthBarBorderColor.b, Gladdy.db.healthBarBorderColor.a) healthBar:SetFrameLevel(1) healthBar.hp = CreateFrame("StatusBar", nil, healthBar) - healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.healthBarTexture, "healthBarTexture")) + healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "healthBarTexture")) healthBar.hp:SetMinMaxValues(0, 100) healthBar.hp:SetFrameLevel(0) healthBar.bg = healthBar.hp:CreateTexture(nil, "BACKGROUND") - healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.healthBarTexture, "healthBarTexture")) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "healthBarTexture")) healthBar.bg:ClearAllPoints() healthBar.bg:SetAllPoints(healthBar.hp) healthBar.bg:SetAlpha(1) @@ -58,10 +58,10 @@ function Healthbar:CreateFrame(unit) healthBar.nameText = healthBar:CreateFontString(nil, "LOW", "GameFontNormalSmall") if (Gladdy.db.healthBarNameFontSize < 1) then - healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarNameFont, "healthBarNameFont"), 1) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarNameFont"), 1) healthBar.nameText:Hide() else - healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), Gladdy.db.healthBarNameFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarNameFontSize) healthBar.nameText:Show() end healthBar.nameText:SetTextColor(Gladdy.db.healthBarFontColor.r, Gladdy.db.healthBarFontColor.g, Gladdy.db.healthBarFontColor.b, Gladdy.db.healthBarFontColor.a) @@ -72,10 +72,10 @@ function Healthbar:CreateFrame(unit) healthBar.healthText = healthBar:CreateFontString(nil, "LOW") if (Gladdy.db.healthBarHealthFontSize < 1) then - healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), 1) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), 1) healthBar.healthText:Hide() else - healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), Gladdy.db.healthBarHealthFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarHealthFontSize) healthBar.healthText:Hide() end healthBar.healthText:SetTextColor(Gladdy.db.healthBarFontColor.r, Gladdy.db.healthBarFontColor.g, Gladdy.db.healthBarFontColor.b, Gladdy.db.healthBarFontColor.a) @@ -167,33 +167,33 @@ function Healthbar:UpdateFrame(unit) return end - healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.healthBarTexture, "healthBarTexture")) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "healthBarTexture")) healthBar.bg:SetVertexColor(Gladdy.db.healthBarBgColor.r, Gladdy.db.healthBarBgColor.g, Gladdy.db.healthBarBgColor.b, Gladdy.db.healthBarBgColor.a) - healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.healthBarBorderStyle, "healthBarBorderStyle"), + healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "healthBarBorderStyle"), edgeSize = Gladdy.db.healthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.healthBarBorderColor.r, Gladdy.db.healthBarBorderColor.g, Gladdy.db.healthBarBorderColor.b, Gladdy.db.healthBarBorderColor.a) healthBar:ClearAllPoints() healthBar:SetPoint("TOPLEFT", Gladdy.buttons[unit], "TOPLEFT", 0, 0) healthBar:SetPoint("BOTTOMRIGHT", Gladdy.buttons[unit], "BOTTOMRIGHT") - healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.healthBarTexture, "healthBarTexture")) + healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "healthBarTexture")) healthBar.hp:ClearAllPoints() healthBar.hp:SetPoint("TOPLEFT", healthBar, "TOPLEFT", (Gladdy.db.healthBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.healthBarBorderSize/Gladdy.db.statusbarBorderOffset)) healthBar.hp:SetPoint("BOTTOMRIGHT", healthBar, "BOTTOMRIGHT", -(Gladdy.db.healthBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.healthBarBorderSize/Gladdy.db.statusbarBorderOffset)) if (Gladdy.db.healthBarHealthFontSize < 1) then - healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), 1) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), 1) healthBar.healthText:Hide() else - healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), Gladdy.db.healthBarHealthFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarHealthFontSize) healthBar.healthText:Show() end if (Gladdy.db.healthBarNameFontSize < 1) then - healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarNameFont, "healthBarNameFont"), 1) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarNameFont"), 1) healthBar.nameText:Hide() else - healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.healthBarFont, "healthBarFont"), Gladdy.db.healthBarNameFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarNameFontSize) if Gladdy.db.healthName then healthBar.nameText:Show() else diff --git a/Modules/Highlight.lua b/Modules/Highlight.lua index 92f3356..5cebb1a 100644 --- a/Modules/Highlight.lua +++ b/Modules/Highlight.lua @@ -55,17 +55,17 @@ function Highlight:CreateFrame(unit) local healthBar = Gladdy.modules["Health Bar"].frames[unit] local targetBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") - targetBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) + targetBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) --targetBorder:SetFrameStrata("MEDIUM") targetBorder:Hide() local focusBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") - focusBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) + focusBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) --focusBorder:SetFrameStrata("MEDIUM") focusBorder:Hide() local leaderBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") - leaderBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) + leaderBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) --leaderBorder:SetFrameStrata("MEDIUM") leaderBorder:Hide() @@ -106,7 +106,7 @@ function Highlight:UpdateFrame(unit) button.targetBorder:SetPoint("TOP", button.healthBar, "TOP", 0, (Gladdy.db.highlightInset and 0 or borderSize)) end - button.targetBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = borderSize }) + button.targetBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = borderSize }) button.targetBorder:SetBackdropBorderColor(Gladdy.db.targetBorderColor.r, Gladdy.db.targetBorderColor.g, Gladdy.db.targetBorderColor.b, Gladdy.db.targetBorderColor.a) button.focusBorder:SetWidth(width) @@ -119,7 +119,7 @@ function Highlight:UpdateFrame(unit) button.focusBorder:SetPoint("TOP", button.healthBar, "TOP", 0, (Gladdy.db.highlightInset and 0 or borderSize)) end - button.focusBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = borderSize }) + button.focusBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = borderSize }) button.focusBorder:SetBackdropBorderColor(Gladdy.db.focusBorderColor.r, Gladdy.db.focusBorderColor.g, Gladdy.db.focusBorderColor.b, Gladdy.db.focusBorderColor.a) button.leaderBorder:SetWidth(width) @@ -132,7 +132,7 @@ function Highlight:UpdateFrame(unit) button.leaderBorder:SetPoint("TOP", button.healthBar, "TOP", 0, (Gladdy.db.highlightInset and 0 or borderSize)) end - button.leaderBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.highlightBorderStyle, "highlightBorderStyle"), edgeSize = borderSize }) + button.leaderBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = borderSize }) button.leaderBorder:SetBackdropBorderColor(Gladdy.db.leaderBorderColor.r, Gladdy.db.leaderBorderColor.g, Gladdy.db.leaderBorderColor.b, Gladdy.db.leaderBorderColor.a) if Gladdy.frame.testing then Highlight:Test(unit) diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 2eabfab..994a8b5 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -149,7 +149,7 @@ function Pets:CreateFrame(unitId) button.secure = secure local healthBar = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") - healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.petHealthBarBorderStyle, "petHealthBarBorderStyle"), + healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "petHealthBarBorderStyle"), edgeSize = Gladdy.db.petHealthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) healthBar:SetFrameLevel(1) @@ -167,14 +167,14 @@ function Pets:CreateFrame(unitId) healthBar.hp = CreateFrame("StatusBar", nil, healthBar) - healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.petHealthBarTexture, "petHealthBarTexture")) + healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "petHealthBarTexture")) healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) healthBar.hp:SetMinMaxValues(0, 100) healthBar.hp:SetFrameLevel(0) healthBar.hp:SetAllPoints(healthBar) healthBar.bg = healthBar.hp:CreateTexture(nil, "BACKGROUND") - healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.petHealthBarTexture, "petHealthBarTexture")) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "petHealthBarTexture")) healthBar.bg:ClearAllPoints() healthBar.bg:SetAllPoints(healthBar.hp) healthBar.bg:SetAlpha(1) @@ -182,10 +182,10 @@ function Pets:CreateFrame(unitId) healthBar.nameText = healthBar:CreateFontString(nil, "LOW", "GameFontNormalSmall") if (Gladdy.db.petHealthBarFontSize < 1) then - healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), 1) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), 1) healthBar.nameText:Hide() else - healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.nameText:Show() end healthBar.nameText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) @@ -196,10 +196,10 @@ function Pets:CreateFrame(unitId) healthBar.healthText = healthBar:CreateFontString(nil, "LOW") if (Gladdy.db.petHealthBarFontSize < 1) then - healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), 1) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), 1) healthBar.healthText:Hide() else - healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.healthText:Hide() end healthBar.healthText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) @@ -263,28 +263,28 @@ function Pets:UpdateFrame(unitId) healthBar.portrait.border:SetTexture(Gladdy.db.petPortraitBorderStyle) healthBar.portrait.border:SetVertexColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) - healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.petHealthBarTexture, "petHealthBarTexture")) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "petHealthBarTexture")) healthBar.bg:SetVertexColor(Gladdy.db.petHealthBarBgColor.r, Gladdy.db.petHealthBarBgColor.g, Gladdy.db.petHealthBarBgColor.b, Gladdy.db.petHealthBarBgColor.a) - healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.petHealthBarBorderStyle, "petHealthBarBorderStyle"), + healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "petHealthBarBorderStyle"), edgeSize = Gladdy.db.petHealthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) - healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.petHealthBarTexture, "petHealthBarTexture")) + healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "petHealthBarTexture")) healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) healthBar.hp:ClearAllPoints() healthBar.hp:SetPoint("TOPLEFT", healthBar, "TOPLEFT", (Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset)) healthBar.hp:SetPoint("BOTTOMRIGHT", healthBar, "BOTTOMRIGHT", -(Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset)) if (Gladdy.db.petHealthBarFontSize < 1) then - healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), 1) - healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), 1) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), 1) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), 1) healthBar.nameText:Hide() healthBar.healthText:Hide() else - healthBar.nameText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.nameText:Show() - healthBar.healthText:SetFont(Gladdy:SMFetch("font", Gladdy.db.petHealthBarFont, "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.healthText:Show() end healthBar.nameText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) diff --git a/Modules/Powerbar.lua b/Modules/Powerbar.lua index 686a1b6..eaa961a 100644 --- a/Modules/Powerbar.lua +++ b/Modules/Powerbar.lua @@ -38,24 +38,24 @@ function Powerbar:CreateFrame(unit) local powerBar = CreateFrame("Frame", nil, Gladdy.buttons[unit], BackdropTemplateMixin and "BackdropTemplate") powerBar:EnableMouse(false) - powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.powerBarBorderStyle, "powerBarBorderStyle"), + powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "powerBarBorderStyle"), edgeSize = Gladdy.db.powerBarBorderSize }) powerBar:SetBackdropBorderColor(Gladdy.db.powerBarBorderColor.r, Gladdy.db.powerBarBorderColor.g, Gladdy.db.powerBarBorderColor.b, Gladdy.db.powerBarBorderColor.a) powerBar:SetFrameLevel(1) powerBar.energy = CreateFrame("StatusBar", nil, powerBar) - powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.powerBarTexture, "powerBarTexture")) + powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) powerBar.energy:SetMinMaxValues(0, 100) powerBar.energy:SetFrameLevel(0) powerBar.bg = powerBar.energy:CreateTexture(nil, "BACKGROUND") - powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.powerBarTexture, "powerBarTexture")) + powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) powerBar.bg:ClearAllPoints() powerBar.bg:SetAllPoints(powerBar.energy) powerBar.bg:SetVertexColor(Gladdy.db.powerBarBgColor.r, Gladdy.db.powerBarBgColor.g, Gladdy.db.powerBarBgColor.b, Gladdy.db.powerBarBgColor.a) powerBar.raceText = powerBar:CreateFontString(nil, "LOW") - powerBar.raceText:SetFont(Gladdy:SMFetch("font", Gladdy.db.powerBarFont, "powerBarFont"), Gladdy.db.powerBarFontSize) + powerBar.raceText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.raceText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) powerBar.raceText:SetShadowOffset(1, -1) powerBar.raceText:SetShadowColor(0, 0, 0, 1) @@ -63,7 +63,7 @@ function Powerbar:CreateFrame(unit) powerBar.raceText:SetPoint("LEFT", 5, 1) powerBar.powerText = powerBar:CreateFontString(nil, "LOW") - powerBar.powerText:SetFont(Gladdy:SMFetch("font", Gladdy.db.powerBarFont, "powerBarFont"), Gladdy.db.powerBarFontSize) + powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.powerText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) powerBar.powerText:SetShadowOffset(1, -1) powerBar.powerText:SetShadowColor(0, 0, 0, 1) @@ -149,7 +149,7 @@ function Powerbar:UpdateFrame(unit) else powerBar:Show() end - powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", Gladdy.db.powerBarTexture, "powerBarTexture")) + powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) powerBar.bg:SetVertexColor(Gladdy.db.powerBarBgColor.r, Gladdy.db.powerBarBgColor.g, Gladdy.db.powerBarBgColor.b, Gladdy.db.powerBarBgColor.a) powerBar:SetWidth(healthBar:GetWidth()) @@ -158,18 +158,18 @@ function Powerbar:UpdateFrame(unit) powerBar:ClearAllPoints() powerBar:SetPoint("TOPLEFT", healthBar, "BOTTOMLEFT", 0, -1) - powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", Gladdy.db.powerBarBorderStyle, "powerBarBorderStyle"), + powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "powerBarBorderStyle"), edgeSize = Gladdy.db.powerBarBorderSize }) powerBar:SetBackdropBorderColor(Gladdy.db.powerBarBorderColor.r, Gladdy.db.powerBarBorderColor.g, Gladdy.db.powerBarBorderColor.b, Gladdy.db.powerBarBorderColor.a) - powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", Gladdy.db.powerBarTexture, "powerBarTexture")) + powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) powerBar.energy:ClearAllPoints() powerBar.energy:SetPoint("TOPLEFT", powerBar, "TOPLEFT", (Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset)) powerBar.energy:SetPoint("BOTTOMRIGHT", powerBar, "BOTTOMRIGHT", -(Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset)) - powerBar.raceText:SetFont(Gladdy:SMFetch("font", Gladdy.db.powerBarFont, "powerBarFont"), Gladdy.db.powerBarFontSize) + powerBar.raceText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.raceText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) - powerBar.powerText:SetFont(Gladdy:SMFetch("font", Gladdy.db.powerBarFont, "powerBarFont"), Gladdy.db.powerBarFontSize) + powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.powerText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) end diff --git a/Modules/Racial.lua b/Modules/Racial.lua index ad62474..94fb049 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -44,19 +44,19 @@ local function iconTimer(self,elapsed) if timeLeft >= 60 then self.cooldownFont:SetTextColor(1, 1, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 0.15* self:GetWidth()) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 0.15* self:GetWidth()) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 60 and timeLeft >= 30 then self.cooldownFont:SetTextColor(1, 1, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 30 and timeLeft >= 11 then self.cooldownFont:SetTextColor(1, 0.7, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 10 and timeLeft >= 5 then self.cooldownFont:SetTextColor(1, 0.7, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 5 and timeLeft > 0 then self.cooldownFont:SetTextColor(1, 0, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 10, true) end @@ -80,7 +80,7 @@ function Racial:CreateFrame(unit) racial.cooldownFrame:SetPoint("BOTTOMRIGHT", racial, "BOTTOMRIGHT") racial.cooldownFont = racial.cooldownFrame:CreateFontString(nil, "OVERLAY") - racial.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.racialFont, "racialFont"), 20, "OUTLINE") + racial.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), 20, "OUTLINE") --trinket.cooldownFont:SetAllPoints(trinket.cooldown) racial.cooldownFont:SetJustifyH("CENTER") racial.cooldownFont:SetPoint("CENTER") diff --git a/Modules/TotemPlates.lua b/Modules/TotemPlates.lua index ad72893..f87053d 100644 --- a/Modules/TotemPlates.lua +++ b/Modules/TotemPlates.lua @@ -269,7 +269,7 @@ function TotemPlates:UpdateFrameOnce() Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].color.b, Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].color.a) nameplate.gladdyTotemFrame.totemName:SetPoint("TOP", nameplate.gladdyTotemFrame, "BOTTOM", Gladdy.db.npTremorFontXOffset, Gladdy.db.npTremorFontYOffset) - nameplate.gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", Gladdy.db.npTremorFont, "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") + nameplate.gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") nameplate.gladdyTotemFrame.totemName:SetText(Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].customText or "") self:SetTotemAlpha(nameplate.gladdyTotemFrame, k) @@ -300,7 +300,7 @@ function TotemPlates:UpdateFrameOnce() gladdyTotemFrame:SetWidth(Gladdy.db.npTotemPlatesSize * Gladdy.db.npTotemPlatesWidthFactor) gladdyTotemFrame:SetHeight(Gladdy.db.npTotemPlatesSize) gladdyTotemFrame.totemBorder:SetTexture(Gladdy.db.npTotemPlatesBorderStyle) - gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", Gladdy.db.npTremorFont, "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") + gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") gladdyTotemFrame.totemName:SetPoint("TOP", gladdyTotemFrame, "BOTTOM", Gladdy.db.npTremorFontXOffset, Gladdy.db.npTremorFontYOffset) end end @@ -327,7 +327,7 @@ function TotemPlates:CreateTotemFrame(nameplate) nameplate.gladdyTotemFrame.totemBorder:SetPoint("BOTTOMRIGHT", nameplate.gladdyTotemFrame, "BOTTOMRIGHT") nameplate.gladdyTotemFrame.totemBorder:SetTexture(Gladdy.db.npTotemPlatesBorderStyle) nameplate.gladdyTotemFrame.totemName = nameplate.gladdyTotemFrame:CreateFontString(nil, "OVERLAY") - nameplate.gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", Gladdy.db.npTremorFont, "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") + nameplate.gladdyTotemFrame.totemName:SetFont(Gladdy:SMFetch("font", "npTremorFont"), Gladdy.db.npTremorFontSize, "OUTLINE") nameplate.gladdyTotemFrame.totemName:SetPoint("TOP", nameplate.gladdyTotemFrame, "BOTTOM", Gladdy.db.npTremorFontXOffset, Gladdy.db.npTremorFontYOffset) nameplate.gladdyTotemFrame.selectionHighlight = nameplate.gladdyTotemFrame:CreateTexture(nil, "OVERLAY") nameplate.gladdyTotemFrame.selectionHighlight:SetTexture("Interface/TargetingFrame/UI-TargetingFrame-BarFill") diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index db940bd..3a71c6a 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -40,19 +40,19 @@ local function iconTimer(self, elapsed) if timeLeft >= 60 then self.cooldownFont:SetTextColor(1, 1, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 0.15*self:GetWidth()) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 0.15*self:GetWidth()) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 60 and timeLeft >= 30 then self.cooldownFont:SetTextColor(1, 1, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 30 and timeLeft >= 11 then self.cooldownFont:SetTextColor(1, 0.7, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft <= 10 and timeLeft >= 5 then self.cooldownFont:SetTextColor(1, 0.7, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 5 and timeLeft > 0 then self.cooldownFont:SetTextColor(1, 0, 0) - self.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") + self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 10, true) end @@ -76,7 +76,7 @@ function Trinket:CreateFrame(unit) trinket.cooldownFrame:SetPoint("BOTTOMRIGHT", trinket, "BOTTOMRIGHT") trinket.cooldownFont = trinket.cooldownFrame:CreateFontString(nil, "OVERLAY") - trinket.cooldownFont:SetFont(Gladdy:SMFetch("font", Gladdy.db.trinketFont, "trinketFont"), 20, "OUTLINE") + trinket.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), 20, "OUTLINE") --trinket.cooldownFont:SetAllPoints(trinket.cooldown) trinket.cooldownFont:SetJustifyH("CENTER") trinket.cooldownFont:SetPoint("CENTER") -- 2.39.5 From ce5c8fc5a049bff1580a3df00c091628ef847247 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 14 Sep 2021 23:55:27 +0200 Subject: [PATCH 035/268] added zhTW locale --- .gitignore | 3 +- Lang.lua | 428 +++++++++++++++++++++++++++++++++++++++++ Modules/Clicks.lua | 4 +- Modules/RangeCheck.lua | 6 +- Options.lua | 12 +- 5 files changed, 441 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index f00ad52..23b1f2d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ BuffLib *.psd Ace-Libs Images_Raw -Gladdy_old \ No newline at end of file +Gladdy_old +Gladdy_TW \ No newline at end of file diff --git a/Lang.lua b/Lang.lua index 45e8808..ce0ec8d 100644 --- a/Lang.lua +++ b/Lang.lua @@ -557,6 +557,434 @@ elseif GetLocale() == "deDE" then L["Offset of border to statusbar (in case statusbar shows beyond the border)"] = "Offset des Rahmens zur Statusbar (falls der Balken hinter dem Rahmen erscheint)" L["Statusbar border color"] = "Balken Rahmenfarbe" L["This changes the border color of all statusbar frames"] = "Dies ändert die Rahmenfarbe aller Balken" +elseif GetLocale() == "zhTW" then + -- Announcements.lua + L["Announcements"] = "通報" + L["RESURRECTING: %s (%s)"] = "復活: %s (%s) " + L["SPEC DETECTED: %s - %s (%s)"] = "敵方天賦: %s - %s (%s)" + L["LOW HEALTH: %s (%s)"] = "低生命值: %s (%s)" + L["TRINKET USED: %s (%s)"] = "飾品已使用: %s (%s)" + L["TRINKET READY: %s (%s)"] = "飾品就緒: %s (%s)" + L["DRINKING: %s (%s)"] = "正在喝水: %s (%s)" + L["Self"] = "玩家" + L["Party"] = "隊伍" + L["Raid Warning"] = "團隊警告" + L["Blizzard's Floating Combat Text"] = "Blizzard 戰鬥浮動文字" + L["Trinket used"] = "飾品已使用" + L["Announce when an enemy's trinket is used"] = "當敵方使用飾品時發出通知" + L["Trinket ready"] = "飾品就緒" + L["Announce when an enemy's trinket is ready again"] = "當敵方飾品就緒時發出通報" + L["Drinking"] = "正在喝水" + L["Announces when enemies sit down to drink"] = "當敵方喝水時發出通報" + L["Resurrection"] = "復活" + L["Announces when an enemy tries to resurrect a teammate"] = "當敵方嘗試復活隊友時發出通報" + L["New enemies"] = "新的敵人" + L["Announces when new enemies are discovered"] = "當發現新的敵人時發出通報" + L["Spec Detection"] = "天賦偵測" + L["Announces when the spec of an enemy was detected"] = "當偵測到敵方天賦時發出通報" + L["Low health"] = "低生命值" + L["Announces when an enemy drops below a certain health threshold"] = "當敵方生命值低於一定條件時發出通報" + L["Low health threshold"] = "低生命值門檻" + L["Choose how low an enemy must be before low health is announced"] = "設定低生命值通報門檻" + L["Destination"] = "發送通報至" + L["Choose how your announcements are displayed"] = "選擇通報發送至哪個頻道" + + -- ArenaCountDown.lua + L["Arena Countdown"] = "競技場計時" + L["Turns countdown before the start of an arena match on/off."] = "在競技場開始前倒數剩餘秒數" + L["Size"] = "大小" + + -- Auras.lua + L["Auras"] = "光環" + L["Frame"] = "框架" + L["Cooldown"] = "冷卻時間" + L["No Cooldown Circle"] = "取消圖示冷卻倒數陰影" + L["Cooldown circle alpha"] = "冷卻倒數陰影alpha值" + L["Font"] = "字型" + L["Font of the cooldown"] = "設定冷卻時間字型" + L["Font scale"] = "字體大小" + L["Scale of the text"] = "設定字體大小" + L["Font color"] = "字體顏色" + L["Color of the text"] = "設定字體顏色" + L["Border"] = "邊框" + L["Border style"] = "邊框樣式" + L["Buff color"] = "增益顏色" + L["Debuff color"] = "減益顏色" + L["Check All"] = "全選" + L["Uncheck All"] = "取消全選" + L["Enabled"] = "啟用" + L["Priority"] = "優先" + L["Interrupt Spells School Colors"] = "打斷法術分類顏色" + L["Enable Interrupt Spell School Colors"] = "啟用" + L["Will use Debuff Color if disabled"] = "若未啟用則使用一般減益顏色" + L["Buffs"] = "增益" --Line 573 + L["Debuffs"] = "減益" --Line 566 + L["Interrupts"] = "斷法" --Line 580 + + -- BuffsDebuffs.lua + L["Buffs and Debuffs"] = "增益與減益" + L["Enabled Buffs and Debuffs module"] = "啟用增益與減益模組" + L["Show CC"] = "顯示控場" + L["Shows all debuffs, which are displayed on the ClassIcon as well"] = "顯示所有減益效果,這些減益效果也顯示在職業圖示上" + L["Buffs"] = "增益" + L["Size & Padding"] = "大小與內距" + L["Icon Size"] = "圖示大小" + L["Size of the DR Icons"] = "遞減圖示大小" + L["Icon Width Factor"] = "圖示寬度比例" + L["Stretches the icon"] = "圖示寬度" + L["Icon Padding"] = "圖示內距" + L["Space between Icons"] = "圖示間距" + L["Position"] = "位置" + L["Aura Position"] = "光環位置" + L["Position of the aura icons"] = "光環圖示位置" + L["Top"] = "頂部" + L["Bottom"] = "底部" + L["Left"] = "左" + L["Right"] = "右" + --L["Grow Direction"] = "" + L["Grow Direction of the aura icons"] = "光環圖示的延伸方向" + L["Horizontal offset"] = "水平位移" + L["Vertical offset"] = "垂直位移" + L["Alpha"] = "Alpha值" + L["Debuffs"] = "減益" + L["Dynamic Timer Color"] = "動態計時條顏色" + L["Show dynamic color on cooldown numbers"] = "冷卻時間數字以動態顏色顯示" + L["Color of the cooldown timer and stacks"] = "Farbe der Abklingzeit und Stapel" + L["Spell School Colors"] = "法術種類顏色" + L["Spell School Colors Enabled"] = "啟用" + L["Show border colors by spell school"] = "根據不同法術種類顯示不同邊框顏色" + L["Curse"] = "詛咒" + L["Color of the border"] = "邊框顏色" + L["Magic"] = "魔法" + L["Poison"] = "中毒" + L["Physical"] = "物理" + L["Immune"] = "免疫" + L["Disease"] = "疾病" + L["Aura"] = "光環" + L["Form"] = "形態" + L["Font"] = "字型" --Line 906 + L["Border"] = "邊框" --Line 949 + L["Debuff Lists"] = "減益列表" --Line 1036 + L["Buff Lists"] = "增益列表" --Line 1051 + + -- Castbar.lua + L["Cast Bar"] = "施法條" + L["Bar"] = "施法條" + L["Bar Size"] = "施法條大小" + L["Bar height"] = "高度" + L["Height of the bar"] = "計量條高度" + L["Bar width"] = "寬度" + L["Width of the bars"] = "計量條寬度" + L["Texture"] = "材質" + L["Bar texture"] = "施法條材質" + L["Texture of the bar"] = "計量條材質" + L["Bar color"] = "施法條顏色" + L["Color of the cast bar"] = "計量條顏色" + L["Background color"] = "背景顏色" + L["Color of the cast bar background"] = "施法條背景顏色" + L["Border size"] = "邊框大小" + L["Status Bar border"] = "狀態列邊框" + L["Status Bar border color"] = "狀態列邊框顏色" + L["Icon"] = "圖示" + L["Icon size"] = "圖示大小" + L["Icon border"] = "圖示邊框" + L["Icon border color"] = "圖示邊框顏色" + L["If test is running, type \"/gladdy test\" again"] = "如果測試已經開始,調整此選項後請輸入/gladdy test以重新開始測試" + L["Spark"] = "尾端發亮" + L["Spark enabled"] = "啟用" + L["Spark color"] = "顏色" + L["Color of the cast bar spark"] = "計時條進度的尾端顏色" + L["Font of the castbar"] = "施法條字型" + L["Font size"] = "字體大小" + L["Size of the text"] = "施法條字體大小" + L["Format"] = "格式" + L["Timer Format"] = "時間格式" + L["Remaining"] = "剩餘時間" + L["Total"] = "總時間" + L["Both"] = "兩者" + L["Castbar position"] = "施法條位置" + L["Icon position"] = "圖示位置" + L["Offsets"] = "位移" + + -- Classicon.lua + L["Class Icon"] = "職業圖示" + L["Balance"] = "平衡" + L["Feral"] = "野性" + L["Restoration"] = "恢復" + L["Beast Mastery"] = "獸王" + L["Marksmanship"] = "射擊" + L["Survival"] = "生存" + L["Arcane"] = "奧術" + L["Fire"] = "火焰" + L["Frost"] = "冰霜" + L["Holy"] = "神聖" + L["Protection"] = "防護" + L["Retribution"] = "懲戒" + L["Discipline"] = "戒律" + L["Shadow"] = "暗影" + L["Assassination"] = "刺殺" + L["Combat"] = "戰鬥" + L["Subtlety"] = "敏銳" + L["Elemental"] = "元素" + L["Enhancement"] = "增強" + L["Affliction"] = "痛苦" + L["Demonology"] = "惡魔" + L["Destruction"] = "毀滅" + L["Arms"] = "武器" + L["Fury"] = "狂怒" + L["Show Spec Icon"] = "顯示天賦圖示" + L["Shows Spec Icon once spec is detected"] = "若偵測到天賦則顯示天賦圖示" + L["Icon width factor"] = "圖示寬度比例" + L["This changes positions with trinket"] = "調整職業圖示位置" + L["Border color"] = "邊框顏色" + + --CombatIndicator.lua + L["Combat Indicator"] = "戰鬥指示器" + L["Enable Combat Indicator icon"] = "顯示是否進入戰鬥" + L["Anchor"] = "定位" + L["This changes the anchor of the ci icon"] = "調整戰鬥指示器圖示定位點" + L["This changes position relative to its anchor of the ci icon"] = "調整戰鬥指示器位置" + + -- Constants.lua + L["Physical"] = "物理" --Line 749 + L["Holy"] = "神聖" --Line 750 + L["Fire"] = "火焰" --Line 751 + L["Nature"] = "自然" --Line 752 + L["Frost"] = "冰霜" --Line 753 + L["Shadow"] = "暗影" --Line 754 + L["Arcane"] = "奧術" --Line 755 + L["Unknown"] = "未知" --Line 756 + + -- Cooldowns.lua + L["Cooldowns"] = "技能冷卻監控" + L["Enabled cooldown module"] = "啟用冷卻時間監控模組" + L["Cooldown size"] = "大小" + L["Size of each cd icon"] = "冷卻時間圖示大小" + L["Icon Width Factor"] = "寬度" + L["Max Icons per row"] = "每行圖示數量" + L["Scale of the font"] = "字體大小" + L["Anchor of the cooldown icons"] = "冷卻圖示定位" + L["Grow Direction of the cooldown icons"] = "冷卻圖示延伸方向" + L["Offset"] = "位移" + L["BloodElf"] = "血精靈" + L["NightElf"] = "夜精靈" + L["Scourge"] = "不死族" + + -- Diminishings.lua + L["Diminishings"] = "控場遞減" + L["Enabled DR module"] = "啟用遞減模組" + L["DR Cooldown position"] = "遞減冷卻時間位置" + L["Position of the cooldown icons"] = "遞減冷卻時間圖示位置" + L["DR Border Colors"] = "DR邊框顏色" + L["Dr Border Colors Enabled"] = "啟用" + L["Colors borders of DRs in respective DR-color below"] = "邊框顏色依遞減設定為以下顏色" + L["Half"] = "二分之一" + L["Quarter"] = "四分之一" + L["Categories"] = "法術列表" + L["Force Icon"] = "使用自訂圖示" + L["Icon of the DR"] = "選擇此區圖示取代原始技能圖示" + + -- ExportImport.lua + L["Export Import"] = "匯出/匯入" + L["Profile Export Import"] = "設定檔匯出/匯入" + L["Export"] = "匯出" --Line 138 + L["Export your current profile to share with others or your various accounts."] = "匯出您目前的設定檔" --Line 139 + L["Import"] = "匯入" --Line 162 + L["This will overwrite your current profile!"] = "這將會覆蓋您目前的設定檔" --Line 163 + + -- Healthbar.lua + L["Health Bar"] = "血量條" + L["DEAD"] = "死亡" + L["LEAVE"] = "暫離" + L["General"] = "一般" + L["Color of the status bar background"] = "狀態列背景顏色" + L["Font of the bar"] = "字型" + L["Name font size"] = "名稱字體大小" + L["Size of the name text"] = "設定名稱字體大小" + L["Health font size"] = "生命值字體大小" + L["Size of the health text"] = "設定生命值字體大小" + L["Size of the border"] = "邊框大小" + L["Health Bar Text"] = "血量條文字" + L["Show name text"] = "顯示名稱" + L["Show the units name"] = "顯示單位名稱" + L["Show ArenaX"] = "顯示編號" + L["Show 1-5 as name instead"] = "使用編號1-5代替角色名稱" + L["Show the actual health"] = "顯示目前生命值" + L["Show the actual health on the health bar"] = "在血量條上顯示目前生命值" + L["Show max health"] = "顯示最大生命值" + L["Show max health on the health bar"] = "在血量條上顯示最大生命值" + L["Show health percentage"] = "顯示百分比" + L["Show health percentage on the health bar"] = "在血量條上顯示生命值百分比" + + -- Highlight.lua + L["Highlight"] = "高亮提示" + L["Show Inside"] = "顯示在框架內" + L["Show Highlight border inside of frame"] = "將高亮邊框顯示於框架內側" + L["Colors"] = "邊框顏色" + L["Target border color"] = "目標" + L["Color of the selected targets border"] = "目標的邊框顏色" + L["Focus border color"] = "專注" + L["Color of the focus border"] = "專注目標邊框顏色" + L["Highlight target"] = "高亮目標" + L["Toggle if the selected target should be highlighted"] = "是否高亮當前目標" + L["Show border around target"] = "顯示目標邊框" + L["Toggle if a border should be shown around the selected target"] = "是否顯示當前目標的邊框" + L["Show border around focus"] = "顯示專注邊框" + L["Toggle of a border should be shown around the current focus"] = "是否顯示當前專注目標的邊框" + + -- Pets.lua + L["Pets"] = "寵物" + L["Enables Pets module"] = "啟用寵物模組" + L["Width of the bar"] = "寵物列寬度" + L["Health color"] = "生命值顏色" + L["Color of the status bar"] = "狀態列顏色" + L["Portrait"] = "頭像" + L["Health Values"] = "生命值" + + -- Powerbar.lua + L["Power Bar"] = "法力/能量條" + L["Power Bar Text"] = "法力/能量條文字" + L["Power Texts"] = "法力/能量條文字" + L["Show race"] = "顯示種族" + L["Show spec"] = "顯示天賦" + L["Show the actual power"] = "顯示目前法力/能量" + L["Show the actual power on the power bar"] = "在計量條中顯示目前法力/能量值" + L["Show max power"] = "顯示最大法力/能量值" + L["Show max power on the power bar"] = "在計量條中顯示最大法力/能量值" + L["Show power percentage"] = "顯示法力/能量百分比" + L["Show power percentage on the power bar"] = "在計量條中顯示目前法力/能量百分比" + + -- Racial.lua + L["Racial"] = "種族" + L["Enable racial icon"] = "啟用種族圖示" + L["This changes the anchor of the racial icon"] = "調整種族圖示定位點" + L["This changes position relative to its anchor of the racial icon"] = "調整種族圖示位置" + + -- TotemPlates.lua + L["Totem Plates"] = "圖騰名條" + L["Customize Totems"] = "自訂圖騰" + L["Custom totem name"] = "自訂圖騰名稱" + L["Totem General"] = "圖騰通用設定" + L["Turns totem icons instead of nameplates on or off. (Requires reload)"] = "是否顯示圖騰名條(需重新載入)" + L["Show friendly"] = "顯示友方圖騰" + L["Show enemy"] = "顯示敵方圖騰" + L["Totem size"] = "圖騰大小" + L["Size of totem icons"] = "圖騰圖示大小" + L["Font of the custom totem name"] = "自訂圖騰字型" + L["Apply alpha when no target"] = "圖騰非目標時套用alpha值" + L["Always applies alpha, even when you don't have a target. Else it is 1."] = "若圖騰未被選為目標,其圖示套用alpha值設定" + L["Apply alpha when targeted"] = "圖騰為目標時套用alpha值" + L["Always applies alpha, even when you target the totem. Else it is 1."] = "圖騰被選為目標時,其圖示套用alpha值設定" + L["All totem border alphas (configurable per totem)"] = "圖騰 Alpha值 " + L["Totem icon border style"] = "圖騰邊框樣式" + L["All totem border color"] = "圖騰邊框顏色" + + -- Trinket.lua + L["Trinket"] = "飾品" + L["Enable trinket icon"] = "啟用飾品圖示" + L["This changes positions of the trinket"] = "調整飾品圖示位置" + + -- XiconProfiles.lua + L["Profile"] = "樣式" + L["XiconProfiles"] = "框架外觀" --Line 4 + L[" No Pet"] = "(無寵物)" --Line 109, 119 + + -- Frame.lua + L["Gladdy - drag to move"] = "Gladdy - 拖曳移動" + + -- Gladdy.lua + L["Welcome to Gladdy!"] = "歡迎使用 Gladdy!" + L["First run has been detected, displaying test frame."] = "第一次使用時,顯示此測試框架。" + L["Valid slash commands are:"] = "可用的指令為:" + L["If this is not your first run please lock or move the frame to prevent this from happening."] = "若非第一次使用,請移動或鎖定框架以避免此提示再次出現。" + + -- Clicks.lua + L["Action #%d"] = "動作 #%d" + L["Target"] = "目標" --Line 15 + L["Focus"] = "專注" --Line 16 + L["Clicks"] = "點擊動作" + L["Left button"] = "左鍵" + L["Right button"] = "右鍵" + L["Middle button"] = "中鍵" + L["Button 4"] = "滑鼠按鍵4" + L["Button 5"] = "滑鼠按鍵5" + L["Select what action this mouse button does"] = "設定輸入按鍵後的欲執行的動作" + L["Modifier"] = "修飾鍵" + L["Select which modifier to use"] = "設定欲使用的修飾鍵" + L["Button"] = "按鍵" + L["Select which mouse button to use"] = "設定欲使用的滑鼠按鍵" + L["Name"] = "名稱" + L["Select the name of the click option"] = "設定動作名稱" + L["Action"] = "動作" + L["Cast Spell / Macro"] = "施放法術/巨集" + + --RangeCheck.lua + L["Range Check"] = "距離檢查" + L["Spells"] = "法術" + L["Fade"] = "變暗" + L["Out of Range Darkening Level"] = "超出距離時變暗程度" + L["Higher is darker"] = "數值越高越暗" + L["yds"] = " 碼" --Line 366, 388 + L["Changing the spellID only applies to your player class!\n\nExample: If you are a Paladin and wish to change your range check spell to Repentance, edit the Paladin spellID to 20066."] = "對應您的職業修改欲用於監控距離的技能。\n\n範例:若您為聖騎士且想以懺悔技能用於距離監控,請將聖騎士的法術ID改為20066。" --Line 352 + + --ShadowsightTimer.lua + L["Shadowsight Timer"] = "暗影視界計時" + L["Locked"] = "鎖定" + L["Announce"] = "通報" + L["Scale"] = "大小" + L["Shadowsight up in %ds"] = "暗影視界於%d秒後就緒" + L["Shadowsight up!"] = "暗影視界已就緒" + + -- Options.lua + L["settings"] = "設定" + L["Reset module"] = "重設模組" + L["Reset module to defaults"] = "將模組重設為預設值" + L["No settings"] = "無設定" + L["Module has no settings"] = "模組沒有設定" + L["General settings"] = "通用設定" + L["Lock frame"] = "鎖定框架" + L["Toggle if frame can be moved"] = "調整框架是否可移動" + L["Grow frame upwards"] = "框架向上延伸" + L["If enabled the frame will grow upwards instead of downwards"] = "開啟此選項時框架向上延伸" + L["Down"] = "下" + L["Up"] = "上" + L["Frame General"] = "框架" + L["Frame scale"] = "框架大小" + L["Scale of the frame"] = "框架的尺寸" + L["Frame padding"] = "框架內距" + L["Padding of the frame"] = "框架的內距" + L["Frame width"] = "框架寬度" + L["Margin"] = "框架間距" + L["Margin between each button"] = "框架的間距" + L["Cooldown General"] = "冷卻" + L["Font General"] = "字型" + L["General Font"] = "Allgemeine Schriftart" + L["Font color text"] = "文字顏色" + L["Font color timer"] = "計時器文字顏色" + L["Color of the timers"] = "計時器顏色" + L["Icons General"] = "圖示" + L["Icon border style"] = "圖示邊框樣式" + L["This changes the border style of all icons"] = "調整所有圖示的邊框樣式" + L["This changes the border color of all icons"] = "調整所有圖示的邊框顏色" + L["Statusbar General"] = "狀態列" + L["Statusbar texture"] = "狀態列材質" + L["This changes the texture of all statusbar frames"] = "調整所有狀態列的材質" + L["Statusbar border style"] = "狀態列邊框樣式" + L["This changes the border style of all statusbar frames"] = "調整所有狀態列的邊框樣式" + L["Statusbar border offset divider (smaller is higher offset)"] = "狀態列邊框距離" + L["Offset of border to statusbar (in case statusbar shows beyond the border)"] = "調整狀態列邊框距離" + L["Statusbar border color"] = "狀態列邊框顏色" + L["This changes the border color of all statusbar frames"] = "調整所有狀態列的邊框顏色" + L["Hide Blizzard"] = "隱藏暴雪框架" + L["Grow Direction"] = "框架延伸方向" + L["Arena only"] = "只在競技場中" + L["Never"] = "從不" + L["Always"] = "永遠" + L["Load configuration"] = "設定選項" --Line 713 + L["Load configuration options"] = "載入設定選項" --Line 714 + L["Background Color of the frame"] = "框架的背景顏色" + + L["Gladdy"] = "Gladdy目標框架" --Line 210, 709, 727 end diff --git a/Modules/Clicks.lua b/Modules/Clicks.lua index 2e20924..1b5f971 100644 --- a/Modules/Clicks.lua +++ b/Modules/Clicks.lua @@ -12,8 +12,8 @@ local Gladdy = LibStub("Gladdy") local L = Gladdy.L local attributes = { - { name = "Target", button = "1", modifier = "", action = "target", spell = "" }, - { name = "Focus", button = "2", modifier = "", action = "focus", spell = "" }, + { name = L["Target"], button = "1", modifier = "", action = "target", spell = "" }, + { name = L["Focus"], button = "2", modifier = "", action = "focus", spell = "" }, } for i = 3, 10 do tinsert(attributes, { name = L["Action #%d"]:format(i), button = "", modifier = "", action = "disabled", spell = "" }) diff --git a/Modules/RangeCheck.lua b/Modules/RangeCheck.lua index 5fac117..3e95600 100644 --- a/Modules/RangeCheck.lua +++ b/Modules/RangeCheck.lua @@ -349,7 +349,7 @@ function RangeCheck:GetSpells() local group = { description = { type = "description", - name = "Changing the spellID only applies to your player class!\n\nExample: If you are a Paladin and wish to change your range check spell to Repentance, edit the Paladin spellID to 20066.", + name = L["Changing the spellID only applies to your player class!\n\nExample: If you are a Paladin and wish to change your range check spell to Repentance, edit the Paladin spellID to 20066."], order = 1, }, } @@ -363,7 +363,7 @@ function RangeCheck:GetSpells() args = { headerMin = { type = "header", - name = GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min) and format("|T%s:20|t %s - %dyds", select(3, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(1, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(6, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min))) + name = GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min) and format("|T%s:20|t %s - %d" .. L["yds"], select(3, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(1, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(6, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min))) or "nil", order = 1, }, @@ -385,7 +385,7 @@ function RangeCheck:GetSpells() Gladdy.db.rangeCheckDefaultSpells[class].min = tonumber(value) --Gladdy.options.args["Range Check"].args.oorSpells.args[class].args.min.name = GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min) and format("|T%s:20|t %s", select(3, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(1, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min))) -- or "nil" - Gladdy.options.args["Range Check"].args.oorSpells.args[class].args.headerMin.name = GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min) and format("|T%s:20|t %s - %dyds", select(3, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(1, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(6, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min))) + Gladdy.options.args["Range Check"].args.oorSpells.args[class].args.headerMin.name = GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min) and format("|T%s:20|t %s - %d" .. L["yds"], select(3, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(1, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min)), select(6, GetSpellInfo(Gladdy.db.rangeCheckDefaultSpells[class].min))) or "nil" end }, diff --git a/Options.lua b/Options.lua index 68c3abe..0c8faa6 100644 --- a/Options.lua +++ b/Options.lua @@ -208,7 +208,7 @@ end function Gladdy:SetupOptions() self.options = { type = "group", - name = "Gladdy", + name = L["Gladdy"], plugins = {}, childGroups = "tree", get = getOpt, @@ -735,12 +735,12 @@ function Gladdy:SetupOptions() end local options = { - name = "Gladdy", + name = L["Gladdy"], type = "group", args = { load = { - name = "Load configuration", - desc = "Load configuration options", + name = L["Load configuration"], + desc = L["Load configuration options"], type = "execute", func = function() HideUIPanel(InterfaceOptionsFrame) @@ -767,7 +767,7 @@ function Gladdy:GetAuras(auraType) ckeckAll = { order = 1, width = "0.7", - name = "Check All", + name = L["Check All"], type = "execute", func = function(info) if auraType == AURA_TYPE_DEBUFF then @@ -784,7 +784,7 @@ function Gladdy:GetAuras(auraType) uncheckAll = { order = 2, width = "0.7", - name = "Uncheck All", + name = L["Uncheck All"], type = "execute", func = function(info) if auraType == AURA_TYPE_DEBUFF then -- 2.39.5 From b6d243b8c06d20147b7abb250dd774bb2be69df0 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 15 Sep 2021 00:24:36 +0200 Subject: [PATCH 036/268] fix GetItemInfo item not loaded from server yet... fallback to constant --- Constants.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Constants.lua b/Constants.lua index e6458a5..67c8f8d 100644 --- a/Constants.lua +++ b/Constants.lua @@ -740,7 +740,7 @@ local importantAuras = { duration = 8, priority = 15, spellID = 5024, - altName = select(1, GetSpellInfo(5024)) .. " - " .. select(1, GetItemInfo(4984)), + altName = select(1, GetSpellInfo(5024)) .. " - " .. (select(1, GetItemInfo(4984)) or "Skull of Impending Doom"), }, } function Gladdy:GetImportantAuras() -- 2.39.5 From f9b1ac9c51fd533b20b00cd6c82833ce36f64390 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 15 Sep 2021 00:29:12 +0200 Subject: [PATCH 037/268] possible localization on DR-Categories --- Modules/Diminishings.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 8da1386..780c188 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -642,7 +642,7 @@ function Diminishings:CategoryOptions() for i,k in ipairs(indexList) do categories[k] = { type = "group", - name = DRData:GetCategoryName(k), + name = L[DRData:GetCategoryName(k)], order = i, icon = Gladdy.db.drCategories[k].icon, args = { -- 2.39.5 From f36883df31e88bfef311031ed49b50e1743b3ced Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 15 Sep 2021 00:42:36 +0200 Subject: [PATCH 038/268] add version in options --- Options.lua | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Options.lua b/Options.lua index 0c8faa6..e0c7f37 100644 --- a/Options.lua +++ b/Options.lua @@ -216,7 +216,7 @@ function Gladdy:SetupOptions() args = { test = { order = 1, - width = "0.7", + width = 0.7, name = L["Test"], type = "execute", func = function() @@ -225,7 +225,7 @@ function Gladdy:SetupOptions() }, hide = { order = 2, - width = "0.7", + width = 0.7, name = L["Hide"], type = "execute", func = function() @@ -235,19 +235,25 @@ function Gladdy:SetupOptions() }, reload = { order = 3, - width = "0.7", + width = 0.7, name = L["ReloadUI"], type = "execute", func = function() ReloadUI() end, }, + version = { + order = 4, + width = 1, + type = "description", + name = " Gladdy v" .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType + }, general = { type = "group", name = L["General"], desc = L["General settings"], childGroups = "tab", - order = 4, + order = 5, args = { locked = { type = "toggle", @@ -728,7 +734,7 @@ function Gladdy:SetupOptions() }, } - local order = 5 + local order = 6 for k, v in pairsByKeys(self.modules) do self:SetupModule(k, v, order) order = order + 1 -- 2.39.5 From c3a1555932e0115ed879d52ec90ca63db4129929 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 15 Sep 2021 00:42:49 +0200 Subject: [PATCH 039/268] bump version --- Gladdy.lua | 4 ++-- Gladdy.toc | 4 ++-- README.md | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 5d4d709..a3f6578 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -26,9 +26,9 @@ local MAJOR, MINOR = "Gladdy", 4 local Gladdy = LibStub:NewLibrary(MAJOR, MINOR) local L Gladdy.version_major_num = 1 -Gladdy.version_minor_num = 0.19 +Gladdy.version_minor_num = 0.20 Gladdy.version_num = Gladdy.version_major_num + Gladdy.version_minor_num -Gladdy.version_releaseType = RELEASE_TYPES.beta +Gladdy.version_releaseType = RELEASE_TYPES.release Gladdy.version = PREFIX .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType Gladdy.VERSION_REGEX = VERSION_REGEX diff --git a/Gladdy.toc b/Gladdy.toc index ba5a687..b3623bc 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -1,6 +1,6 @@ -## Interface: 20501 +## Interface: 20502 ## Title: Gladdy - TBC -## Version: 1.19-Beta +## Version: 1.20-Release ## Notes: The most powerful arena AddOn for WoW 2.5.1 ## Author: XiconQoo, DnB_Junkee, Knall ## X-Email: contact me on discord Knall#1751 diff --git a/README.md b/README.md index f4bdfb5..ad22649 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Gladdy - TBC ### The most powerful arena addon for WoW TBC 2.5.1 -## [v1.19-Beta Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.19-Beta/Gladdy_TBC-Classic_v1.19-Beta.zip) +## [v1.20-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.19-Release/Gladdy_TBC-Classic_v1.20-Release.zip) ###### Please consider donating if you like my work @@ -62,6 +62,9 @@ The goal is to make Gladdy highly configurable in it's appearance. Everything ca ### Changes +### v1.20-Release +TODO + ### v1.19-Beta - fix gladdy frames not showing v2 - minor bug fixes -- 2.39.5 From b861091d4494fc411024fa32b3347a6094b72109 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 15 Sep 2021 00:55:06 +0200 Subject: [PATCH 040/268] added 1.20 changelist --- README.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ad22649..06f3d23 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Gladdy - TBC ### The most powerful arena addon for WoW TBC 2.5.1 -## [v1.20-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.19-Release/Gladdy_TBC-Classic_v1.20-Release.zip) +## [v1.20-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.20-Release/Gladdy_TBC-Classic_v1.20-Release.zip) ###### Please consider donating if you like my work @@ -63,7 +63,23 @@ The goal is to make Gladdy highly configurable in it's appearance. Everything ca ### Changes ### v1.20-Release -TODO +- configurable DR duration +- scale in 0.01 percent steps +- added Net-o-Matic, Nigh Invulnerablility Shield, Nigh Invulnerablility Backfire & Flee (Skull of Impending Doom) to Auras +- added Mangle, Chastise, Avenging Wrath, Rapid Fire to BuffsDebuffs +- improved testmode to only activate Auras/Buffs/Debuffs/Dr's that are actually enabled +- added Mir's profile to XiconProfiles +- added zhTW localization +- added buttons for Test, Hide & Reload in the config +- added version in config +- ArenaCountdown upgrade +- Repentance, Freezing Trap & Wyvern Sting are now disorients +- import string now ignores errors on deleted options +- added (un)checkAll button in DR-Categories in Diminishing Module +- totemplates fix option to alter all colors/alphas +- hide blizzard arena pets as well +- fix shadowsight timer showing when not in arena or testmode +- some minor refactoring / optimization ### v1.19-Beta - fix gladdy frames not showing v2 -- 2.39.5 From a0ed3be791b4fcbeb22e41b554daa2e69a68c451 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 15 Sep 2021 19:33:33 +0200 Subject: [PATCH 041/268] fix ArenaEnemyFrame hide only if exists --- Gladdy.lua | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index a3f6578..60acae4 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -463,17 +463,39 @@ end function Gladdy:BlizzArenaSetAlpha(alpha) if IsAddOnLoaded("Blizzard_ArenaUI") then - ArenaEnemyFrames:SetAlpha(alpha) - ArenaEnemyFrame1:SetAlpha(alpha) - ArenaEnemyFrame1PetFrame:SetAlpha(alpha) - ArenaEnemyFrame2:SetAlpha(alpha) - ArenaEnemyFrame2PetFrame:SetAlpha(alpha) - ArenaEnemyFrame3:SetAlpha(alpha) - ArenaEnemyFrame3PetFrame:SetAlpha(alpha) - ArenaEnemyFrame4:SetAlpha(alpha) - ArenaEnemyFrame4PetFrame:SetAlpha(alpha) - ArenaEnemyFrame5:SetAlpha(alpha) - ArenaEnemyFrame5PetFrame:SetAlpha(alpha) + if (ArenaEnemyFrames) then + ArenaEnemyFrames:SetAlpha(alpha) + end + if ArenaEnemyFrame1 then + ArenaEnemyFrame1:SetAlpha(alpha) + end + if ArenaEnemyFrame1PetFrame then + ArenaEnemyFrame1PetFrame:SetAlpha(alpha) + end + if ArenaEnemyFrame2 then + ArenaEnemyFrame2:SetAlpha(alpha) + end + if ArenaEnemyFrame2PetFrame then + ArenaEnemyFrame2PetFrame:SetAlpha(alpha) + end + if ArenaEnemyFrame3 then + ArenaEnemyFrame3:SetAlpha(alpha) + end + if ArenaEnemyFrame3PetFrame then + ArenaEnemyFrame3PetFrame:SetAlpha(alpha) + end + if ArenaEnemyFrame4 then + ArenaEnemyFrame4:SetAlpha(alpha) + end + if ArenaEnemyFrame4PetFrame then + ArenaEnemyFrame4PetFrame:SetAlpha(alpha) + end + if ArenaEnemyFrame5 then + ArenaEnemyFrame5:SetAlpha(alpha) + end + if ArenaEnemyFrame5PetFrame then + ArenaEnemyFrame5PetFrame:SetAlpha(alpha) + end end end -- 2.39.5 From f29e8eff3b36cef326d143649b341cf1e3c36b3d Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 15 Sep 2021 19:40:07 +0200 Subject: [PATCH 042/268] added Pummel to CoolDowns --- Constants.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Constants.lua b/Constants.lua index 67c8f8d..cbffad3 100644 --- a/Constants.lua +++ b/Constants.lua @@ -890,12 +890,12 @@ local cooldownList = { -- Warrior ["WARRIOR"] = { - --[[6552] = { cd = 10, -- Pummel + [6552] = { cd = 10, -- Pummel sharedCD = { [72] = true, }, }, - [72] = { cd = 12, -- Shield Bash + --[[72] = { cd = 12, -- Shield Bash sharedCD = { [6552] = true, }, -- 2.39.5 From 7a7c50e283a7d6bc18730a3e6724e9a119028a43 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 15 Sep 2021 19:40:24 +0200 Subject: [PATCH 043/268] bump version --- Gladdy.lua | 2 +- Gladdy.toc | 2 +- README.md | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 60acae4..35a68b1 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -26,7 +26,7 @@ local MAJOR, MINOR = "Gladdy", 4 local Gladdy = LibStub:NewLibrary(MAJOR, MINOR) local L Gladdy.version_major_num = 1 -Gladdy.version_minor_num = 0.20 +Gladdy.version_minor_num = 0.21 Gladdy.version_num = Gladdy.version_major_num + Gladdy.version_minor_num Gladdy.version_releaseType = RELEASE_TYPES.release Gladdy.version = PREFIX .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType diff --git a/Gladdy.toc b/Gladdy.toc index b3623bc..e011806 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -1,6 +1,6 @@ ## Interface: 20502 ## Title: Gladdy - TBC -## Version: 1.20-Release +## Version: 1.21-Release ## Notes: The most powerful arena AddOn for WoW 2.5.1 ## Author: XiconQoo, DnB_Junkee, Knall ## X-Email: contact me on discord Knall#1751 diff --git a/README.md b/README.md index 06f3d23..eaa9f30 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Gladdy - TBC ### The most powerful arena addon for WoW TBC 2.5.1 -## [v1.20-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.20-Release/Gladdy_TBC-Classic_v1.20-Release.zip) +## [v1.21-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.21-Release/Gladdy_TBC-Classic_v1.21-Release.zip) ###### Please consider donating if you like my work @@ -62,6 +62,10 @@ The goal is to make Gladdy highly configurable in it's appearance. Everything ca ### Changes +### v1.21-Release +- fixed error when hiding blizzard frames ArenaEnemyFrames related to ElvUI +- added Pummel cooldown + ### v1.20-Release - configurable DR duration - scale in 0.01 percent steps -- 2.39.5 From 01f907f71c031d62ef35812d60b2782be593f208 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 18 Sep 2021 13:15:27 +0200 Subject: [PATCH 044/268] fix import for TW and general issue with BuffsDebuffs --- Libs/LibClassAuras-1.0/LibClassAuras-1.0.lua | 39 +++++++++++++++----- Modules/BuffsDebuffs.lua | 18 +++++++-- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/Libs/LibClassAuras-1.0/LibClassAuras-1.0.lua b/Libs/LibClassAuras-1.0/LibClassAuras-1.0.lua index 396f988..1a67d4c 100644 --- a/Libs/LibClassAuras-1.0/LibClassAuras-1.0.lua +++ b/Libs/LibClassAuras-1.0/LibClassAuras-1.0.lua @@ -7,6 +7,7 @@ LibClassAuras.debuffs = {} LibClassAuras.debuffToId = {} LibClassAuras.buffs = {} LibClassAuras.buffToId = {} +LibClassAuras.altNames = {} local function Spell(id, opts, class, spellTable, idTable) if not opts or not class then @@ -26,9 +27,20 @@ local function Spell(id, opts, class, spellTable, idTable) return end if opts.altName then - idTable[opts.altName] = {id = id , class = class} + for _,v in ipairs(id) do + LibClassAuras.altNames[v] = opts.altName + end + if idTable[opts.altName] then + tinsert(idTable[opts.altName], {id = id , class = class}) + else + idTable[opts.altName] = {[1] = {id = id , class = class}} + end else - idTable[spellName] = {id = id , class = class} + if idTable[spellName] then + tinsert(idTable[spellName], {id = id , class = class}) + else + idTable[spellName] = {[1] = {id = id , class = class}} + end end if type(id) == "table" then @@ -54,9 +66,11 @@ LibClassAuras.Buff = Buff local function getClassDebuffs(class) local classSpells = {} - for k,v in pairs(LibClassAuras.debuffToId) do - if v.class == class then - tinsert(classSpells, {name = k, id = v.id}) + for name, spells in pairs(LibClassAuras.debuffToId) do + for _, spellInfo in ipairs(spells) do + if spellInfo.class == class then + tinsert(classSpells, {name = name, id = spellInfo.id}) + end end end return classSpells @@ -65,9 +79,11 @@ LibClassAuras.GetClassDebuffs = getClassDebuffs local function getClassBuffs(class) local classSpells = {} - for k,v in pairs(LibClassAuras.buffToId) do - if v.class == class then - tinsert(classSpells, {name = k, id = v.id}) + for name, spells in pairs(LibClassAuras.buffToId) do + for _, spellInfo in ipairs(spells) do + if spellInfo.class == class then + tinsert(classSpells, {name = name, id = spellInfo.id}) + end end end return classSpells @@ -82,4 +98,9 @@ local function getSpellNameToId(auraType) end end -LibClassAuras.GetSpellNameToId = getSpellNameToId \ No newline at end of file +LibClassAuras.GetSpellNameToId = getSpellNameToId + +local function getAltName(spellID) + return LibClassAuras.altNames[spellID] +end +LibClassAuras.GetAltName = getAltName \ No newline at end of file diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 7940fd6..61eed84 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -138,7 +138,8 @@ function BuffsDebuffs:Test(unit) BuffsDebuffs:AURA_FADE(unit, AURA_TYPE_DEBUFF) BuffsDebuffs:AURA_FADE(unit, AURA_TYPE_BUFF) - + --BuffsDebuffs:AURA_GAIN(unit, AURA_TYPE_BUFF, 1243, select(1, GetSpellInfo(1243)), select(3, GetSpellInfo(1243)), 10, GetTime() + 10, 1, "physical") + --self:AURA_GAIN(unit, AURA_TYPE_DEBUFF, 31117, select(1, GetSpellInfo(31117)), select(3, GetSpellInfo(31117)), 10, GetTime() + 10, 1, "physical") local i = 1 for spellID, enabled in pairs(Gladdy.db.trackedDebuffs) do if i > 4 then @@ -197,13 +198,24 @@ function BuffsDebuffs:AURA_GAIN(unit, auraType, spellID, spellName, texture, dur return end local auraFrame = self.frames[unit] + spellName = LibClassAuras.GetAltName(spellID) or spellName local aura = Gladdy:GetImportantAuras()[spellName] and Gladdy.db.auraListDefault[tostring(Gladdy:GetImportantAuras()[spellName].spellID)].enabled if aura and Gladdy.db.buffsShowAuraDebuffs then aura = false end local auraNames = LibClassAuras.GetSpellNameToId(auraType) - local spellId = auraNames[spellName] and auraNames[spellName].id[1] - if not aura and spellID and spellId and expirationTime and (Gladdy.db.trackedBuffs[tostring(spellId)] or Gladdy.db.trackedDebuffs[tostring(spellId)]) then + local spellId + local isTracked = false + if auraNames[spellName] then + for _, spellInfo in ipairs(auraNames[spellName]) do + spellId = spellInfo.id[1] + if (Gladdy.db.trackedBuffs[tostring(spellId)] or Gladdy.db.trackedDebuffs[tostring(spellId)]) then + isTracked = true + break + end + end + end + if not aura and spellID and expirationTime and isTracked then local index if auraType == AURA_TYPE_DEBUFF then auraFrame.numDebuffs = auraFrame.numDebuffs + 1 -- 2.39.5 From df2721f1cf1e822fb75052da573d1234197e58cd Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 18 Sep 2021 15:00:00 +0200 Subject: [PATCH 045/268] cleanup --- Modules/ExportImport.lua | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Modules/ExportImport.lua b/Modules/ExportImport.lua index 1bafaaa..a1c709e 100644 --- a/Modules/ExportImport.lua +++ b/Modules/ExportImport.lua @@ -14,12 +14,6 @@ local function table_copy(t, str) end for k,v in pairs(t) do if type(v) == "table" then - if k == "drCategories" then - for key,val in pairs(v) do - --Gladdy:Print("TableCopy", str .. "." .. key) - end - end - t2[k] = table_copy(v, str .. "." .. k); else @@ -94,7 +88,7 @@ end) import:AddChild(importClearButton) import.clearButton = importClearButton -local deletedOptions = { --TODO backward compatibility Imports on deleted options +local deletedOptions = { -- backwards compatibility growUp = true, freezetrap = true, repentance = true -- 2.39.5 From 548234aaaa078ac16eda86e0357e4b9892c7c689 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 18 Sep 2021 15:00:16 +0200 Subject: [PATCH 046/268] grounding totem effect fix --- Constants.lua | 2 +- Modules/Auras.lua | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Constants.lua b/Constants.lua index cbffad3..5595fe2 100644 --- a/Constants.lua +++ b/Constants.lua @@ -649,7 +649,7 @@ local importantAuras = { -- Grounding Totem Effect [GetSpellInfo(8178)] = { track = AURA_TYPE_BUFF, - duration = 4, + duration = 0, priority = 20, spellID = 8178 }, diff --git a/Modules/Auras.lua b/Modules/Auras.lua index abf93c8..b1f0900 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -106,8 +106,12 @@ function Auras:CreateFrame(unit) if (self.timeLeft <= 0) then Auras:AURA_FADE(self.unit, self.track) else + if self.spellID == 8178 then + self.text:SetText("") + else + Gladdy:FormatTimer(self.text, self.timeLeft, self.timeLeft < 10) + end self.timeLeft = self.timeLeft - elapsed - Gladdy:FormatTimer(self.text, self.timeLeft, self.timeLeft < 10) end else self:SetAlpha(0.01) @@ -359,7 +363,8 @@ function Auras:AURA_GAIN(unit, auraType, spellID, spellName, icon, duration, exp auraFrame.startTime = expirationTime - duration auraFrame.endTime = expirationTime auraFrame.name = spellName - auraFrame.timeLeft = expirationTime - GetTime() + auraFrame.spellID = spellID + auraFrame.timeLeft = spellID == 8178 and 45 or expirationTime - GetTime() auraFrame.priority = Gladdy.db.auraListDefault[tostring(self.auras[spellName].spellID)].priority auraFrame.icon:SetTexture(Gladdy:GetImportantAuras()[GetSpellInfo(self.auras[spellName].spellID)] and Gladdy:GetImportantAuras()[GetSpellInfo(self.auras[spellName].spellID)].texture or icon) auraFrame.track = auraType @@ -373,9 +378,11 @@ function Auras:AURA_GAIN(unit, auraType, spellID, spellName, icon, duration, exp else auraFrame.icon.overlay:SetVertexColor(Gladdy.db.frameBorderColor.r, Gladdy.db.frameBorderColor.g, Gladdy.db.frameBorderColor.b, Gladdy.db.frameBorderColor.a) end - if not Gladdy.db.auraDisableCircle then + if not Gladdy.db.auraDisableCircle and spellID ~= 8178 then auraFrame.cooldown:Show() auraFrame.cooldown:SetCooldown(auraFrame.startTime, duration) + else + auraFrame.cooldown:Hide() end end -- 2.39.5 From ff4799ceef3e8c6bc0246b1865ffa6ab1ec98c09 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 18 Sep 2021 15:00:34 +0200 Subject: [PATCH 047/268] add option cooldown number alpha --- Modules/Auras.lua | 16 ++++++++++++++++ Modules/BuffsDebuffs.lua | 28 ++++++++++++++++++++++------ Modules/Cooldowns.lua | 16 ++++++++++++++++ Modules/Diminishings.lua | 16 ++++++++++++++++ Modules/Racial.lua | 20 +++++++++++++++----- Modules/Trinket.lua | 20 +++++++++++++++----- 6 files changed, 100 insertions(+), 16 deletions(-) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index b1f0900..63c2b4f 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -557,6 +557,22 @@ function Auras:GetOptions() order = 4, width = "full", }), + auraCooldownNumberAlpha = { + type = "range", + name = L["Cooldown number alpha"], + min = 0, + max = 1, + step = 0.1, + order = 5, + width = "full", + set = function(info, value) + Gladdy.db.auraFontColor.a = value + Gladdy:UpdateFrame() + end, + get = function(info) + return Gladdy.db.auraFontColor.a + end, + }, } }, font = { diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 61eed84..0a4faeb 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -279,7 +279,7 @@ local function styleIcon(aura, auraType) aura.cooldown:SetFont(Gladdy:SMFetch("font", "buffsFont"), (Gladdy.db.buffsIconSize/2 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") aura.cooldown:SetTextColor(Gladdy.db.buffsFontColor.r, Gladdy.db.buffsFontColor.g, Gladdy.db.buffsFontColor.b, Gladdy.db.buffsFontColor.a) aura.stacks:SetFont(Gladdy:SMFetch("font", "buffsFont"), (Gladdy.db.buffsIconSize/3 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") - aura.stacks:SetTextColor(Gladdy.db.buffsFontColor.r, Gladdy.db.buffsFontColor.g, Gladdy.db.buffsFontColor.b, Gladdy.db.buffsFontColor.a) + aura.stacks:SetTextColor(Gladdy.db.buffsFontColor.r, Gladdy.db.buffsFontColor.g, Gladdy.db.buffsFontColor.b, 1) end function BuffsDebuffs:UpdateFrame(unit) @@ -486,15 +486,15 @@ local function iconTimer(auraFrame, elapsed) auraFrame.timeLeft = timeLeftMilliSec if Gladdy.db.buffsDynamicColor then if timeLeftSec >= 60 then - auraFrame.cooldown:SetTextColor(0.7, 1, 0) + auraFrame.cooldown:SetTextColor(0.7, 1, 0, Gladdy.db.buffsFontColor.a) elseif timeLeftSec < 60 and timeLeftSec >= 11 then - auraFrame.cooldown:SetTextColor(0.7, 1, 0) + auraFrame.cooldown:SetTextColor(0.7, 1, 0, Gladdy.db.buffsFontColor.a) elseif timeLeftSec <= 10 and timeLeftSec >= 5 then - auraFrame.cooldown:SetTextColor(1, 0.7, 0) + auraFrame.cooldown:SetTextColor(1, 0.7, 0, Gladdy.db.buffsFontColor.a) elseif timeLeftSec <= 4 and timeLeftSec >= 3 then - auraFrame.cooldown:SetTextColor(1, 0, 0) + auraFrame.cooldown:SetTextColor(1, 0, 0, Gladdy.db.buffsFontColor.a) elseif timeLeftMilliSec <= 3 and timeLeftMilliSec > 0 then - auraFrame.cooldown:SetTextColor(1, 0, 0) + auraFrame.cooldown:SetTextColor(1, 0, 0, Gladdy.db.buffsFontColor.a) end end if timeLeftMilliSec < 0 then @@ -911,6 +911,22 @@ function BuffsDebuffs:GetOptions() order = 10, width = "full", }), + buffsCooldownNumberAlpha = { + type = "range", + name = L["Cooldown number alpha"], + min = 0, + max = 1, + step = 0.1, + order = 11, + width = "full", + set = function(info, value) + Gladdy.db.buffsFontColor.a = value + Gladdy:UpdateFrame() + end, + get = function(info) + return Gladdy.db.buffsFontColor.a + end, + }, }, }, font = { diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 97c0a15..c2ed7b9 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -663,6 +663,22 @@ function Cooldowns:GetOptions() order = 9, width = "full", }), + cooldownCooldownNumberAlpha = { + type = "range", + name = L["Cooldown number alpha"], + min = 0, + max = 1, + step = 0.1, + order = 10, + width = "full", + set = function(info, value) + Gladdy.db.cooldownFontColor.a = value + Gladdy:UpdateFrame() + end, + get = function(info) + return Gladdy.db.cooldownFontColor.a + end, + }, }, }, font = { diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 780c188..e999943 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -456,6 +456,22 @@ function Diminishings:GetOptions() order = 9, width = "full", }), + drCooldownNumberAlpha = { + type = "range", + name = L["Cooldown number alpha"], + min = 0, + max = 1, + step = 0.1, + order = 10, + width = "full", + set = function(info, value) + Gladdy.db.drFontColor.a = value + Gladdy:UpdateFrame() + end, + get = function(info) + return Gladdy.db.drFontColor.a + end, + }, }, }, font = { diff --git a/Modules/Racial.lua b/Modules/Racial.lua index 94fb049..aaf3731 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -19,6 +19,7 @@ local Racial = Gladdy:NewModule("Racial", nil, { racialBorderColor = { r = 0, g = 0, b = 0, a = 1 }, racialDisableCircle = false, racialCooldownAlpha = 1, + racialCooldownNumberAlpha = 1, }) local ANCHORS = { ["LEFT"] = "RIGHT", ["RIGHT"] = "LEFT", ["BOTTOM"] = "TOP", ["TOP"] = "BOTTOM"} @@ -43,19 +44,19 @@ local function iconTimer(self,elapsed) local timeLeft = ceil(self.timeLeft) if timeLeft >= 60 then - self.cooldownFont:SetTextColor(1, 1, 0) + self.cooldownFont:SetTextColor(1, 1, 0, Gladdy.db.racialCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 0.15* self:GetWidth()) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 60 and timeLeft >= 30 then - self.cooldownFont:SetTextColor(1, 1, 0) + self.cooldownFont:SetTextColor(1, 1, 0, Gladdy.db.racialCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 30 and timeLeft >= 11 then - self.cooldownFont:SetTextColor(1, 0.7, 0) + self.cooldownFont:SetTextColor(1, 0.7, 0, Gladdy.db.racialCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 10 and timeLeft >= 5 then - self.cooldownFont:SetTextColor(1, 0.7, 0) + self.cooldownFont:SetTextColor(1, 0.7, 0, Gladdy.db.racialCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") elseif timeLeft < 5 and timeLeft > 0 then - self.cooldownFont:SetTextColor(1, 0, 0) + self.cooldownFont:SetTextColor(1, 0, 0, Gladdy.db.racialCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), (self:GetWidth()/2 - 1) * Gladdy.db.racialFontScale, "OUTLINE") end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 10, true) @@ -270,6 +271,15 @@ function Racial:GetOptions() order = 8, width = "full", }), + racialCooldownNumberAlpha = Gladdy:option({ + type = "range", + name = L["Cooldown number alpha"], + min = 0, + max = 1, + step = 0.1, + order = 9, + width = "full", + }), }, }, font = { diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 3a71c6a..53126e4 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -17,6 +17,7 @@ local Trinket = Gladdy:NewModule("Trinket", nil, { trinketBorderColor = { r = 0, g = 0, b = 0, a = 1 }, trinketDisableCircle = false, trinketCooldownAlpha = 1, + trinketCooldownNumberAlpha = 1, }) LibStub("AceComm-3.0"):Embed(Trinket) @@ -39,19 +40,19 @@ local function iconTimer(self, elapsed) local timeLeft = ceil(self.timeLeft) if timeLeft >= 60 then - self.cooldownFont:SetTextColor(1, 1, 0) + self.cooldownFont:SetTextColor(1, 1, 0, Gladdy.db.trinketCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 0.15*self:GetWidth()) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 60 and timeLeft >= 30 then - self.cooldownFont:SetTextColor(1, 1, 0) + self.cooldownFont:SetTextColor(1, 1, 0, Gladdy.db.trinketCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 30 and timeLeft >= 11 then - self.cooldownFont:SetTextColor(1, 0.7, 0) + self.cooldownFont:SetTextColor(1, 0.7, 0, Gladdy.db.trinketCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft <= 10 and timeLeft >= 5 then - self.cooldownFont:SetTextColor(1, 0.7, 0) + self.cooldownFont:SetTextColor(1, 0.7, 0, Gladdy.db.trinketCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") elseif timeLeft < 5 and timeLeft > 0 then - self.cooldownFont:SetTextColor(1, 0, 0) + self.cooldownFont:SetTextColor(1, 0, 0, Gladdy.db.trinketCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 10, true) @@ -276,6 +277,15 @@ function Trinket:GetOptions() order = 8, width = "full", }), + trinketCooldownNumberAlpha = Gladdy:option({ + type = "range", + name = L["Cooldown number alpha"], + min = 0, + max = 1, + step = 0.1, + order = 9, + width = "full", + }), }, }, font = { -- 2.39.5 From 4925195de63342d374c3a149f3cc6b5fdf2a407a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 19 Sep 2021 12:42:35 +0200 Subject: [PATCH 048/268] update klimp profile --- ImportStrings.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ImportStrings.lua b/ImportStrings.lua index 80e7914..b2c8dba 100644 --- a/ImportStrings.lua +++ b/ImportStrings.lua @@ -1,7 +1,7 @@ local Gladdy = LibStub("Gladdy") function Gladdy:GetKlimpProfile() - return "4XzTCTTCBJZK(HzVoUiaibbV0kjoX1M44FlNAMPQP0ekjAlUrh8ssTZ45I8SV9jEMurmX5IzmdjqJgnA0N(A7fQf3Vy(6SzhYwNK96dBpKHViEXnQfZxs))hP)Fg()lGFgV)XKxVjz1xV9WFNKnlo7(K)PyXSfZxfNxa)ZXOKhrjpIsEiLwdd6W21h(79xU9Pn84wN9M084LBtEDA2QTjlwwt2hBssVl8hMOfzP7)AsrpQ8usX7tI3wSbi17tsFCtXIBSW82)09hks2D724IKCIpUC7Fh)C(9XzpMuKSgNBw8Q04T3EiFX87U(DV)(gu72KSvj7lIFmbLaYI3tcCvqGZ33AcCEoxe8FlE4vbMH3a1Y3k(fj9YJp8q(m8)vk0Ex2H)(nPzjRkspSFX8p82RG16)ljlh(N)1U4)Ndz)1(J74tW2dD2NU)(p9rAVNLS7q2vh2dl8BoKLMF7T0M7p(eSqjfaJ775BurbbAyd488egp(yw8hsZlEtYdXh3wG7sByOh(ZK9OGFnYZpLLc0S45f347HcN4vFfwM3o7ZxDfUt1HATzAtrPnbbtBkg)qVOrNIkOAkvRHNXZnT1iiWmX9UrzTQPnfTXg5pTPyukv45S3BkHDNqCn8HsGVBIRIoqho19IVACbMYR3XOXZpy8JXbo3DrUX1gndES77M4MWhUonUOAWfr55p(ImW(2P06PXuHQjQ8c6HTMXYwSKU)nkNV9SUc2yxhzC2PXvbA)XNXWlInAQYkTVoyQBfNzQw5CWQmXfX3m5RTo7jUGmI9eTECLrDFLrDeyNBkAVGRgVPkTSrHJV1h8oL2g5M6u8c8NQaomCIQWkZj8JmSHuVP6tauUIol7In9jOJg)EYaMs1EEN4yFeZ7bt1me4QspXvr5PdpXMFiVi6t4vy41ikiCCB8J4bvFcdKJe8egg50uHDHtv9Y47hnXPOaJeJpLbzm0v9edGWaEugxLCilrHENq)Ay5LoyQH0AmHt1TLXO9MKjsTj6ec4G(tiW7egTh42R1BIHyhoz3OgJjA8fzWtd)aFZ4k8dCIB9NKccMD202erEtvq5S(t0yItDc7vdPMBTNkuRbuocDt7SROkJCoTXRYs)3V9L)ZX41zXfXF7l3deRzY2y1boMLSy(8DhouSz8mURZ0Um7tmT4vBJZZVE1H9)ujvVsYzUkVwxaC457RJa5LYbQVp8kW9(84cif(LhbgdwJBO8nYFkz72fZb(oEhSl46cSa2mRtFinjd)cmHcmVAit7yjf7cEyWEqparU6WQJ5dtdDnnEGgfqcZaK4sAqF7l)xMHPtnzwZLcznsj)trj)PqPGtrPGPqj7POKDkuk8uukCkuYDkk5McLIofLIMcLy3xJrk8Q9ztRcSqB4LQBJxVoDpxGpUct13YU8ywmFtBOc4DHdPYtsjalROgiA2mqDXkhgAXyE6)MqdSPrIZUMH5BIH7X54QDF6UKS7s2E7H09fW1M7)0T93e5VT2UgBC53sxxS5kqOCG2grCXSUEFrsw2XNk4zvD7N5KINFcK13U5580vXBLAHk1fDjZz898Md)9h2(CJHclLNm8lc8uv3gBoLRsrdLnMsGxJvW2B8xMTkE)WZqvPg3Cc3eZ2IPToeBBZnb9VrRn92jZjHUmlAb6TuZpU)R7bdSDN6NLxZhGYHz5gsz7jaYoKx0zHQxe0qE6L7xTbo6e9mS6OGUCJt56cL26KwjEYsw)MeAi4s78GWLwIPfegfIpaj6aP3JVb9jSSSOBWdHy9iGFI1FCj620sZuhbE0XXl)Kkj0sm2adnoLrRC08jYrfNbNMs5OXtHoHZtzOHjFNl)bUCLRhwCJLuOY865hPOfs7fYmINIFW4ZecR6Wsk1cMs2qNJPGXNhawKHLLH5sRLlKNRnqPOpv(cG9OFY7fojDCgAHnTgMTm(EK4ZfPjcqPatKo0Nwmx5Qtz8W7upltBrI6B95dLGGqMlcIIOX6RewMdZgEiWrFW6eAzdPVh6jsr48KEWacEEtRT0iOy3OvdYxH(IMxuDPahlP7ssUYlfNt7swmrpe5yXgvKvAUoE3hO5FYfgDjf3xO8cp6bltbTJfO4IWIfG94hII4TcwXqMbnIoQLL9ARju2sA(frH0uHZowGck18aT8dH8e5QXHK2ZX8seRQAfDrfSnQuQjsAvg5msXkcbIkdiU4f3fWZa0L4tKq(iro44VccDMLvwAlzSEcv8LlzE0pGKdig3tlufo2vcdPyzoKmhRkAmIYIoqeLrIKmmsUi4ZpWLUdFtOlu4ddFKQ47k6qnRgd)qOsOILnHgRCDt5ef5arKOLRDyMYepgwEtMPbfHnU5erMmUs7kQs7iSK2WBdRNSU8jI1fqCSrjA8GCMVCekJqoZdbRcZqMqytylkI4q6gzdF2)W(CBySf8HF7HmWWAQa6fyhFlyhNCN(q8QK)8Y1R)0(8)8DBHinE(pVEherq(FYJ9VYoCC)6K1)1YTpvLwq(8nh(BiNIK9Rb3NlzSR(8t4t1iJ96YKcA)6sajroBt7qle(IzdijfiFGI0N(2xiwOo)aKE1ZSjIJxbx78DG7GaLNNhKZ(PY2GZpI8)asv48UbwNemImyDKFOEiv2neMxFmlpP1jKQvGywCjRfcF6qwLpVlc4OBoVm1WrDgaa3e1WFVrMApdzv5c04vfm3kWisaMvfKvX)aFHUoyTEUqVqNpk98n93RvHy9DI7C5bi62DFesYkDpe6fb5ab96470gdaoGarniEmLjQ9DUlalA12hLNy4fNZ1hAcKiMdpgcTcIGPPqR80zm60qUV87c(B1n7h7rURCwSE)G)zWwm4nIswoaxIX(s2yFPOtO7NhU88TQBWKwMHxhEF82hoJnTCvcVR)tBAPrfh47nLuFa(4cD)t(g8Ypyzi6PUFin)W(b14SlA0Netrd5npdzgMUIh(m002X9fKTTz125A34fTr5piYkBHnDBycSEqd0FcLnaICfRP)buJeTOdQmRiZYaH2IeRLz55)VhJZs(2xU642TF7l)2M0Iez3uDA5kZFR5TNYTt3i95rEo3q70YfLS(YAA)7nmy3srQ7IwvPkCVw6CQTZwo3xp0SmCfQ0)G2vVA0iUcckWznrEqmEyGYg0AzLaOmbirA3qME9EuWSSzoq1DwtxV4)o6sZd8MbMJTEqcjq8bWXEL0RFV50uQ(JFzCjKe2J0BAz3y4tgs8D5QIJGlHLLCqJdPbsDVBQGO2hwkJY0(w2qR8oGZBfSqvXk)y6(0DXBtZBkFP52W03PVs2WShDfcFOUaiim5Lkhn2qIgwvviMxG)ttyVsFh30m2XCWBiDlCoQk99u4leYQWt)Fb01P6ba2Ki7frLwFrRqDiUbs4TlEjtI6JY09q66fHSotxqcEjiR1Vh(jVeKv5f8lHUbMEWu)sqwi13FkfTriRUFF9mjYErqP6ReZAqt9xiNZUGanjQpQ(7phtp2jhwsLxEYcPI3Rj7EjORt1dHTjr2luYrxuvyvvK2lSBdOnjspMaUpO8VeK1fO6IR3Ki7fGNHMPDfzBQdhe1fKXjr8X9B8lruOC)ko4m6OEqN(sqxL9N0t0fkBlLy8S01wr(xXvAx)w96LGSQGxyhOWaXWghRpZRaF(vyBiuhjnfzpf6w97RtW46D7oUpPZ5aCjHphqGweRjCqFTHhBvA3CjwNvLMZRu9xTRoKTB8DjxIKvPDIt(hiW9CkVmjW9YE(UkEBk(ulK0yNJNwnxsbwms9PAHvAmAL5KTvjsMWt1kHYk13Bv3X48orFHWdj87naJo8eTXRsC33e1Z(56OAKQqzD1Qka6B3NS7zsvF)EivPvj7aTfoFaoRV7sIxtLhnxsSoHMXYQb85CMT4eqWpSobtM5P4ScewYK8Jzs5JYXXTgNwE9mUFdmKnqkGuBMatKZ9QZVQapKfVlPSCAnht97iD3MD0r3kZs3PcK2DGFhYgDZx9dhqW7AKJeNfopDSWeY9xAW4fK4IY02rn3(PZ29sfyqijUtLwL7vyrTYydofvlu7YG)(PvV56oO5mQ466S)dCpSy0AzCLVZZ4mrqA8bAxGosQFtdnRQk2kzFwlVAuEJYIq8X4)bT2LdwP(q6Eu8ksRU5w3rByt66KzBt)3)nod2JGLJ9X1eTN921z3CC72ZOaQvl1zucmbJ3zLi8AG0ffO2e0o90mIiODlcyeb5sTIHPr5XOGznmIRQiFgNViBjyyLGe5ce4sf8h1AbMrJYkW0ADcUr(MA4OyeYI8fuxdTc0Xmz9umeLALNtOMlIznFhdmNvW10xgzKJrpoWiWi6hkRVrOa2324)oWpK)GhpdDGlQecsMtvEEwbGkz)lWDIL2NEb1nW0ummgLwRquRIXttRcSchhYi3fwcaRVGbNsXBbdmcAD5(7JEaeJmvazvjtkW(XOiBajtLWsoEfildfmgPFDreoGw5OqbHmA4w503ZxW5JbHge1SeuOQ1jySY9jGo0YSgSA8a8J4Lt7fjqMd8kZJIepkK1JSckXWEqu0CkgbxJUebxpPzbm(c9H1JwofJPiOG5ZhOgxKaBTrZ9xaVbWLVsMXmadMAju0bsxaqDDk(VTmQYbLqL7BfSFJyqsdzuLfmJrwSucYmqGMhNG(mkIy1zPbgqWYycWKZWyZRJeiXlXN0xaYmYxWYpuUFOCEc4VE8wvBCUk9EM3zwa0BKdzFTacBKw2oEEsByisfyiSad0Hz0XDLAubvhCch5yzgqtg9BDjKUwzewfpchJjRLHXwXhEGME5fPibc26coFh5Xe)Crt)wfG7(n5Dd)Sx3AvhtQUgnd0f)xhSHyA6fUmAdkidbekKu1oUlnC)Zg3yxigB4WO0L9qvDTQC6DJngOxzWXxzbTSaLVFqGNgUYqWkgwZ6)rZFNnBcLelZ8kXwzyed7gbsdrdtQQy01MgYRQ3g0iwhe4R2f)Tlsi8hASVBJ7qLd8wnhlZhLWZOhiXKpg)y6QbcVOcHPlWM(A(wiEYKVtlbOQsIQEF9DXBT7PxLZCrAsi7SoR9WqGzFQfqsRZEneT3JGId1AUZZ3MK8uZiWxIbqcjvvc8sk(ZBuGoreJjFr228IJ7pN5eaU6PRP7xF2tXz5LztmNA23Bcw0(lUghou0jtIHhpybdh)xZphQdgZ5KaFE12dCEPdUaZAkO0KMq(Q4c4o(5TmqY5uaQP54jZ(ZBNG1rdM0X4ZzjcW(GIIbo(riK0LzjXq6mNXe9fEdoe7kJh)q0NebRxDoJgIdK4S0DpbV5SMsPwYdjXzN1zc2LGs762oRQ1z)aMLF32d55ykGIBepji9xxcrSyxmWUOD3g0WuuhanpR0C6KONyzOFgzfygQZktJSxcdSrhi5e8FSkTrHAqZMPNnCVnSRFPKEnvfMk8BRsPKecv2ZXBGvRZKe8TaaDvAT7NAFZnH1M3)sJsxAZSLfsDT7Mw2sT0Fbfa35uBHCJY19m4SoVOiioJ8sBPJ0eP(UEo)Jfx9ki(tNZdsmjc7XsNPcS5YqHUxWZEzlNytso3REvmOVNTBTgPLx7OEvkP(tTxEJyig4oXGXXmqTbkViSLlPXSk6(UJj55j5sjfk7SUwUbBSxA3B7LIr5pjdZXFpbiJ4V)Z3C)BVdFAh1SuHEkY3WVD5D3D9NA8bS6b4hU9YpC5BU(MQpW)bra(WhV8DVT(TmvU9URF787RERbINosO(h(0R)VR(afYmg73DF(63upCQrEHxF3NE3NRPTXgabHdVE(7V8Jx2Kt8v(Sbr2yqDRbm2VyaQYtUoD(cjA4)cumBH0a4ZWSnImb8d4FGgMvMRjogQ9EXhOCPWhGKx4bJjBoJBRx89ubbMj)jfGMk2224d0VBO4dupOsRSVptcSzyNvMck(fJmeJZekZgB3AEmGNQzsBHtubZqMwAL8quGHPRVHNm8ghV0yZIIp4c9O3qLevyt6bQASZkRBa(c63JBIPI45W9aoro(lgniwyEblGWmjfXzl4wYLMByaZB0VfU0cILsGOgMNg9jdtFidxdl)vwwAZDy7Sfszw4nBjxjhngsbbFJVHpsGu45Zcojn6tyVXsCEKwydm5t(tYPcvEIzL5jpRS8e0GXisWhCyroMXzbsBtprsqAVZKFD)OrI18Hyg83opIi4oPOxXqpdVxKXgXjyDt1D)Hlrp5xtXESoRzscI72b)ZxtpJDTQT6pGf42E6ALbz)EseePrwFkVElQ2JUe8PcAoYxYg7lOZO2nCB5A3nV5MfLF4exAMkuhNrNHpXMULhjXOgDCkQlSUrkPgBR6GFgfhT1FYH(5pQoZYSUSxjjQv06e(0SrcKSZVyN)4S(Mj2)Y5fXfhZxwELR8McwaL0QyrlwS4)FtekbA" + return "4XzT8K1CBB0K)y2NJkmZGzWGhfTTSvTXY6tuUssvPymijSiwZdTaGBIYd(3(2xaeN0eooVydbmt390Dp9T0c1IhxmF5Xp)5Iz4)C7Qd7Vpz96S9pT4oL8f8LZZ(70f3PDlMVkPOCws(Sd5RtZF1HThYrqKWlFXDblM)e9V54)wwV(F9daKslbyyGfUo)1zfjl3M(QS8vBtxS8eCFQjmdUkCyOwMNT)lPL9GYZPLVlnzB5gauVln7PnagDW(2)8Jhkt3D)2KY0IR3(8MKR3(NjVu8ys(tPLPRX9MNSklz79hkwm)HBF77ESb0UpnFv6(YKNsxmdPE(0pV8faRZVDFzA(NtwL(7xVE9h2x87VDlWcF53VDhS(IFNx7F82Thkkeo6RoCy76d)5Ecx)8BUPLmO6JVn)WF(6S80vLzh2xTS)V08c4h)JDj)phY)J9h3r89NAV0zF4Xh)W7PdDE6Ud53CypWYE9H8SI7VNov)MinUXggeAuXwR2hg6dcw85FYAaw)X8KFoRO81PFo542suA4IIcW)pDpYXxJ8HNZZayw(YI7cdqrsYQVaO5nZ(4n3GYiDKwBM2wuAJ1oTTycJcIhDlkB9wQXrGjWpnCyTMjE2nkNtnTTOnU4WPTfJsPIUKZEtoS)mSRHfk2q)eXI2QJM6zjunodtf0tmAccTJlghqU7J9JRnAguSh6N4HieUonoRAqKOcchhjdCU9kTEAevKAIkVGEyRDSSfjP7FJYh6UORGno1XgVBAuLvho(oggjU4PYR0HA7upkEZuTY5bSmrKeAM81wV7mxqgXEIwpUYOUVYOogSZnfTxWvtWu5wU4OXp6dENs7I9tDlb2WPYGJIMOkSYCg)idBinyQ(eaLR4lYUytFc64XVNmGPuDqWze7JyE3ovZqGRk9eXIkqhDMd)qEr0NXRWW4i2gnUn(r8GQpJbYrcEkWp(jzyvyF0uvVmHHXtClkWiX4BzqcdDvpXaimGhLXvjhYsuuWz0VgMFPTtnKwJjAQUTmgDWKmrQnXNHbB7VbBWzmApWTxxWedXoAYUrngt84izqPrOn0mUc)asCx4KuqCMP6nmoyQmkVlCIgt8QZyVAi1CN7CHAnGYrKFAYoypRY(oYVn)WX9Rtx)hl3(SKnBDk)kiVsaOsneWNLuCXetHe)bKaz6J1wyBsbvUHEvx4gRfsqfLHGzXy00iNO6q1gipz)tPVAt6QV8ixLama2KYY8SLhHS)baEhLPrXZPB3UyoKNCYo4yYLcyX8DhwN95S0C8lWgkXmQHCStKKRl5LHvYyaGCZHvhlggg6tW4Z0Qaqygaextl6RF6)YmmCobM1C1pwJqk8CqkCkqYEoizNcKCNdsUPaPOZbPOPaj)5GKFkqk(CqkEkqIDCngOWl1xmSkXQtnyv8ACL66J5j81QHkA3vEekpF4ptZBuenG1SzGsHvTm6MmD)gwyZIWDX1jSytcysOaX2Jz7sZFiD79hY2xcxBE8d33)qu8Mtw0YPk39lzRl3CdWuoqhJyUmwK1R8JpxY7Q(2ptjLV8mWRVFZlfzGDiIAueLvrLv3ZBU83Dy7lnwkGQaz5xzHNQUn2Cl3KLN2Al2GgyW1B9xNVkz)W7qvRg3Cd3LuEuqrWvquTnpe0pJwB6DsMtmDzxec6HQ5h3)L9GT6UB9JYRzbOimRoqkxpgq(HIYoi6esiNoxVF1gq0j6zGUdQl3qkFQePTK0kXhw66xNslbrTpacuAjMqquCe(aKIdKyp(gpemZYQYTbpeHvIa(FSYJlrhMoAN6yWxoUE5)PIbTeJkWqRtz0kpTFcCuzzOTffqRNcAc3NYqlt(ox4deDv4dlRXskizgFHXkcr6GiMqcu8dMqgqy9gwsjvWqYf59memH8cWYlSSkaxcx(iEVoRsrFQ6fa5r)pFw40ZXDOfY0zyYYegqSpFSMaaL8lb6Oqcz(kSt56WN0ahdBHJg6czHI1gXuHnoMwBOsizoaB4bRN(GZlWYfrFpkq4IG8KEWamE(qRD0kOO2iSbzQqFrZivxXWXI5UK4RmQ4SzxYSj6HypZ2OYRs71ZNERM)FUKOlPi(IKxeqp4yiO9mdfrcZwaYJFioMpkyTczc0i6OoM3RDMi5iP5xehrBfKDmdfuQ5f64hevoUoCiOd8mTeZQQorxubhJALAcKoLrKrkwrWkQma7IrU3Y7a0Lyjselsebh)vGPZKSYjAhkwC6ccycuycH8DoQqi4jiqlGhK)kHYumZhYNJVFXxWa9kRWsfyOJILleH8dCX7i07JIe8WKLHLWAqpNzPHggkuAb0wmo5ANYlk0wH1OLRFyUYejgvDJMHbfJnrP03f7kkz5rQk7jm8J08nkhRNQKJNZBzdv2i(YHrj3bePoKsfVEW8WmKke6eoCIelIUA2W593TZ3EwDhbq12XZfNfsF2kMV5WFEtEw6(1GRYLChQ(4Z4tNIo)vvr73(13lepIC2vaek0rW58YtjoGpx7MOvldVbUef6bJ7wiRJai37ZKOqZ0qgJj14SToFG(2T9a65zig1RoMxKoa3Qkmlx7Cv(WH8ApAxz5yx4g3b8X)(RF6)CmzDEszYx)0Jp2oeRHj)Hen1DdSo1mGyEzXnEVvJxaatNHGjclWZaL15)f8fsj35c8rbr(qKBgA6FwRdG6Bev5YdqSR7EpKcv2EiWkQvcukAJFsBSajvr1vMQ0W(gk4asRp(i)edE4sUtqBGyXCWVqGtq8jnzAvsNlqTz53SPU1xxFQh4UX7W64dEFblTGVgkVxlIIX(s(yFPStG5xwJ25Bz3HPKmdVc8UKTF(co0s38Prh47Ukc9BA)cPobm0hGoUs3xY3Gw(oROqp19dzfh2pOgN70U2MMaBG3gAWIGYRFbsVlBftiZqBqh3xsM0MDYGuL2cFMB3KEBStO0nDh0bSCoNmOulPFm9VkPC16LwgNXMv0arB2WIwrgEbiUfHARkbn))9ysE6x)0nh3U9RF6x2KvMkhRAPJVkBSM3wQoxDJBNx5LCJStHDQ8p1WLWV2WOClfNUiTUit4zTY9tBpMmFjanddmncaWw1(tyJwXnGRDVZeharSHH9AqRJ1mGQ0zedy9TzV40izCk1gHrQ67t(xrFBbGBnWoSlaIKb82dkcnprnybnzTF)3axc5v9e9Mwglgw8q8Wt(QzkOHKAGSX7gNbQcIvNOktULnunFaO8tXei61uoVVpBF2UKTzycM1kU0EBWXpVrRg26Olu4dNQPb2Z7knKghirnRUWcZlXF0e1Ro2jnTDDSaCbs3jNJ6tFlT(sbSkuY)VaC9QEDZAsG9Q4ktUOnPoa3a5W2T5htc6Js09AB1peW6nDR4)pcW6c71mKFeGvfy)xbUwtVEo)JaSq2S)Ju0gbS6(dPZKa7v2k1xjqvBt9xiVXUD0zsqFu93)ze9ysoSkj)4blKvDVjM7hbC9QETlBsG9kLi6IRd2Rg0brDNMSjb6XyW97W(pcW6TQUnPBsG9kWZqZCTIDn1HTXD7y4Ka(4(n(xHvO8)Bi4m64E9b9hbCvU)HEIUs5APeJYsFBf5)nUs77p3w)iaRY(d2bkSqmSXXMw8Q5y(UFcNPG2ZX(PrwVB6B3UB3X9PDKdWLewoG9orSMiXWkn2sjqQvcfAmP46CD(jvFSDZH8DJFk56ISkRtCYFhbUxqjNjbUxna31XBtXN6Gui7iEAnPiLyzf1NBEuP1OvMZoJKiyIo3CbkyQV3QURXhCMH8Gxs03AbgD0zMjxL4UVzJm7NRJQrQc9QZ5B2NU7fsvF)EivPvP7s3Z8Bj1VhstwtvbTqYUoL2XY6f8XcMS4eqWpSoftM55K8sStJPfhZLAgvGRBnUTIt74XnWs2azMsJxrTEBNKm5xwvBH7oUBjKUwD6MFopzxAvf2AcHtVJ0S)Tg51VzKYjqZ3Gu4Jz9ZK9N5AMUStI682XIyi3UPfJxFskRsRf1RBxDK7g4khyUinPtXxLBDyDUYzZrL1iQrAOduKe(siFN7RF6ra7Lzp)1prPfdGojVQabGNaq08FGRHLJwpJBc9bgVjgYG3Q9wDSumNgkw1vPvs(8edPr(9vfI49j)fASR4EGTMTh5Fc7OBQ1Dug2KToD22S)(VtYHdby4yFYjG2ZC7687oUD7fu00AuDb1iu6A7SQE2AGSfLMNj9VmqZT2anBrD4q6fPwXnCrfW91YzcD4b1y8XuVtIDvT3kuA3JxAZJt6OOwlno0OCsJxDEPdqHMtnwI75vCO0h1iN0mygSbkUPJAvGxGMpMB7R0GsT1ZTdkuwzSN7hS1ingmc7VZmSFrrcHyeqHdJn(Z2Wi(db8wryw1DrHK1(qMteZ9Skw6KjwxF6f0i(sBXWTF05eG6uv9gZ6yUAye3lUOQERgkTvtP4dLbwbFOOH2JEa4NmuaMwfrknYJBqSbyr1CnrolDJmsAFi97aIqbeMJ5tbFg0orniiu4CC)LbEoZkfO68s7t5raqh5ysdWgVGWygD6GyPB4aTY0OWXJJ4MY7KgadNbw(IRKzb6QMZgiZbGoMBfmGocBkUlHEPv3WpZNfTrZAxbbCFXTC77LtJku4kvTywX99JNJu89Uy58PK(eh6KM6gZD9mI7XP0myKaR4Fm31Q51jTvgzqmg5(HhXV2GTpJHdJM4qUT419BmuADzSiXnEUJKGajqAMBGCwbujDbvqLqcrM6g67QAeCKmwfsBuH3iD9M7hSguGz1rNYxDnWwl3eW5Lpb6WC3wL7JUqrok9S1ekAfoPf1S0d00RUiflnvD9inABa7AKt9EdPc6sN9WC)HCW4xwzdB0RhTzT9I9qCgGrh8LbhpMFBGsVpc0VbUah7cjbLdViHUJcjhvJ8L8X(IeQELJRtHn0Me((JPLcrR94NvfOWqvcUUQ49Nwis(08x0Zks83A9Yg9WQE0vxN)nBvzRbtRx3yWx3SZqxqDPp145tH80TbnCOclA1xuMcAg03P9x32KkDfB7ypAPdXmIQ2mPBg533KBCkQU6ydQh5xEwbRiHBCGbiRkm0Ad0WTsQzZr0sAWsRXm2tY2LOFSriujJqyzZ4jlbTOnfym2YGssc326kyJMbMpeC6tqCt0OdpVyBA6ZntNyjgVlOuw1kPm8)Vtb0FmpLbL5BlkpU)s2JfcCHIFF)6lElEhJMnjCEMFRn4q)iiooCOStArdVEC8TH1)LIlb6GzwoJ2xwT9aNK9GiywtgLghpX5fRskbJcxgAuwIrToRaLm7VStcwuqythtUeuyX50IU9L8eeG9Y80eik)lyJHcTbcXU84XfIHely9Qlz1quTeLLT7z4nx0wQ0s(CAs(fjtW5KQvIXxuYqT(JdqD6GILG(gHyJPDt6Sx2hY(7zVCkTWxOSMPQTzIdqdVEiHlKMo1f52236r8nmkDTuFG2EgQM3P620J)SGLtR6bI1GVR)FPaAMwiFmh3QCJfCbh52YZZl7BM5CTd557GBaBg)V)cD4qKz7FBXn)ee7R3hazefJZTP3iD6Mvqgk(M6)Igar9hydd1XoNJM1xWjsmQQ1Axz9MkGmIls(jA44VjRnRr1gjL3xdH7qZXZDqga1LeQwgowGjfLjLhlwwXwRaQRJI(KcuQvx7pP1i)9Byo(Rwazx9DF8UhFZd4t7OjWkkqrMR)LRF4HB)qJpGLNa)W9x)Zx)6BVR(d8F9eGp8(RF7Bo9wgk3)WTVz(J1V1aHQhlq)N)WR(VR)af8n8(x)WhV91Nwon7VWRF4dV9JNGTXz5OlN)URF)1nPKqviBJQHs9POboDpPoadBmMzIY4TOrAilsq3W2Q8rtIP3k60nt(34HMXXFb3fRJ4729f8VttDhxiscZ)v3aRNan67yvruXgl)a(hLIzvPIJRHgSz8bkBt6nOBVzsU4Z4bAgFpv4KzYFgfOfIdSo(a97dl(an1TeMddzqGJ)l(cQqk4dgzjgVjs2noO5eXH(aNjdepbfSaceQvYdXwdd3qdVz4nEg1vfrXhfqVHQCSqM0durRNvvwf8f0V76erfZ7HN(DcC8xmAGTW0cMR(mjh6zl4HqM2BKLPn638ycHyLwO3yeWsjkZNEMBBGJpliuoMTZLJIObmry(ulebn3XZOIqiJ(lKbULPgplu4uHjkpw7zcmG3ovZF8lHkr6qvXzwvff4p5zzoDvdFJhRf0moD5zv15HwQHvlOFvhNvv8fIwWFZePJlsTLsJBOb55IZ0P7isD62ClhiFh3vBzGSrk4)tb1P5J8XdxJvr92wtLw3FvSA2MHHDq3QqanRIB1VvMxGLLU1L)Be0wJXGEmA6uKogxR67Fb1eUR)9gvgGTa(2JPffPKJZLvDV7(gPL1AcABoPHDR7)7tEkB1awrRhlZRi3oD(1m97x43jW2UTuHQQ(RQgWtPgcwSpOz1lQCXI))Jf(1Ge" end function Gladdy:GetClassicProfile() -- 2.39.5 From 033aa260f44e0185945df27cf4f1fedca2b8ee81 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 19 Sep 2021 12:43:20 +0200 Subject: [PATCH 049/268] bump version --- Gladdy.lua | 2 +- Gladdy.toc | 2 +- README.md | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 35a68b1..6923c67 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -26,7 +26,7 @@ local MAJOR, MINOR = "Gladdy", 4 local Gladdy = LibStub:NewLibrary(MAJOR, MINOR) local L Gladdy.version_major_num = 1 -Gladdy.version_minor_num = 0.21 +Gladdy.version_minor_num = 0.22 Gladdy.version_num = Gladdy.version_major_num + Gladdy.version_minor_num Gladdy.version_releaseType = RELEASE_TYPES.release Gladdy.version = PREFIX .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType diff --git a/Gladdy.toc b/Gladdy.toc index e011806..cfb91f4 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -1,6 +1,6 @@ ## Interface: 20502 ## Title: Gladdy - TBC -## Version: 1.21-Release +## Version: 1.22-Release ## Notes: The most powerful arena AddOn for WoW 2.5.1 ## Author: XiconQoo, DnB_Junkee, Knall ## X-Email: contact me on discord Knall#1751 diff --git a/README.md b/README.md index eaa9f30..7408ec7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Gladdy - TBC ### The most powerful arena addon for WoW TBC 2.5.1 -## [v1.21-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.21-Release/Gladdy_TBC-Classic_v1.21-Release.zip) +## [v1.22-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.22-Release/Gladdy_TBC-Classic_v1.22-Release.zip) ###### Please consider donating if you like my work @@ -62,6 +62,12 @@ The goal is to make Gladdy highly configurable in it's appearance. Everything ca ### Changes +### v1.22-Release +- fixed import for some localizations not working +- added cooldown number alpha configurations for Auras, BuffsDebuffs, Cooldowns, Diminishings, Racial & Trinket +- grounding totem effect fix +- fixed some buffs/debuffs not being present in BuffsDebuffs + ### v1.21-Release - fixed error when hiding blizzard frames ArenaEnemyFrames related to ElvUI - added Pummel cooldown -- 2.39.5 From 1010d59bd3c2ba600ae63936033cff419a3c0976 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 22 Sep 2021 17:12:10 +0200 Subject: [PATCH 050/268] pixel perfect option added --- Frame.lua | 1 + Gladdy.lua | 26 ++++++++++++++++++++++++++ Options.lua | 18 +++++++++++++----- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Frame.lua b/Frame.lua index 5ed139a..f1f5bc4 100644 --- a/Frame.lua +++ b/Frame.lua @@ -190,6 +190,7 @@ function Gladdy:UpdateFrame() end self.frame:SetScale(self.db.frameScale) + self:PixelPerfectScale(false) self.frame:SetWidth(width) self.frame:SetHeight(height) self.frame:ClearAllPoints() diff --git a/Gladdy.lua b/Gladdy.lua index 6923c67..428005a 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -5,6 +5,7 @@ local select = select local pairs = pairs local tinsert = table.insert local tsort = table.sort +local str_lower = string.lower local GetTime = GetTime local CreateFrame = CreateFrame local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME @@ -66,10 +67,20 @@ end Gladdy.events = CreateFrame("Frame") Gladdy.events.registered = {} Gladdy.events:RegisterEvent("PLAYER_LOGIN") +Gladdy.events:RegisterEvent("CVAR_UPDATE") +hooksecurefunc("VideoOptionsFrameOkay_OnClick", function(self, button, down, apply) + if (self:GetName() == "VideoOptionsFrameApply") then + Gladdy:PixelPerfectScale(true) + end +end) Gladdy.events:SetScript("OnEvent", function(self, event, ...) if (event == "PLAYER_LOGIN") then Gladdy:OnInitialize() Gladdy:OnEnable() + elseif (event == "CVAR_UPDATE") then + if (str_lower(select(1, ...)) == "uiscale") then + Gladdy:PixelPerfectScale(true) + end else local func = self.registered[event] @@ -186,6 +197,21 @@ function Gladdy:DeleteUnknownOptions(tbl, refTbl, str) end end +function Gladdy:PixelPerfectScale(update) + local physicalWidth, physicalHeight = GetPhysicalScreenSize() + local perfectUIScale = 768/physicalHeight--768/select(2, strsplit("x",({ GetScreenResolutions()})[GetCurrentResolution()])) + if self.db and self.db.pixelPerfect and self.frame then + self.frame:SetIgnoreParentScale(true) + self.frame:SetScale(perfectUIScale) + --self.db.frameScale = perfectUIScale --(GetCVar("useUiScale") == "1" and 1 + perfectUIScale - GetCVar("UIScale") or perfectUIScale) + if update then + self:UpdateFrame() + end + elseif self.frame then + self.frame:SetIgnoreParentScale(false) + end +end + function Gladdy:OnInitialize() self.dbi = LibStub("AceDB-3.0"):New("GladdyXZ", self.defaults) self.dbi.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged") diff --git a/Options.lua b/Options.lua index e0c7f37..4eec88a 100644 --- a/Options.lua +++ b/Options.lua @@ -50,6 +50,7 @@ Gladdy.defaults = { growUp = false, growDirection = "BOTTOM", frameScale = 1, + pixelPerfect = false, padding = 1, barWidth = 180, bottomMargin = 2, @@ -298,11 +299,18 @@ function Gladdy:SetupOptions() name = L["Frame General"], order = 3, }, + pixelPerfect = { + type = "toggle", + name = L["Pixel Perfect Scale"], + desc = L["Enables Pixel Perfect Scale - disables manual "].. L["Frame scale"], + order = 4, + }, frameScale = { type = "range", name = L["Frame scale"], desc = L["Scale of the frame"], - order = 4, + disabled = function() return Gladdy.db.pixelPerfect end, + order = 5, min = .1, max = 2, step = .01, @@ -311,7 +319,7 @@ function Gladdy:SetupOptions() type = "range", name = L["Frame padding"], desc = L["Padding of the frame"], - order = 5, + order = 6, min = 0, max = 20, step = 1, @@ -320,7 +328,7 @@ function Gladdy:SetupOptions() type = "range", name = L["Frame width"], desc = L["Width of the bars"], - order = 6, + order = 7, min = 10, max = 500, step = 5, @@ -329,7 +337,7 @@ function Gladdy:SetupOptions() type = "range", name = L["Margin"], desc = L["Margin between each button"], - order = 7, + order = 8, min = -200, max = 200, step = 1, @@ -338,7 +346,7 @@ function Gladdy:SetupOptions() type = "color", name = L["Background color"], desc = L["Background Color of the frame"], - order = 8, + order = 9, hasAlpha = true, get = getColorOpt, set = setColorOpt, -- 2.39.5 From 3f28947b05555066835ec49e5b8432c98deef259 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 24 Sep 2021 15:51:24 +0200 Subject: [PATCH 051/268] move modules with mouse --- Gladdy.lua | 51 +++++++++++++++++++++++++++++++++++++ Modules/BuffsDebuffs.lua | 9 +++++++ Modules/Castbar.lua | 5 ++++ Modules/CombatIndicator.lua | 4 +++ Modules/Cooldowns.lua | 4 +++ Modules/Diminishings.lua | 5 ++++ Modules/Pets.lua | 4 +++ 7 files changed, 82 insertions(+) diff --git a/Gladdy.lua b/Gladdy.lua index 428005a..7cdf5a0 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -6,6 +6,7 @@ local pairs = pairs local tinsert = table.insert local tsort = table.sort local str_lower = string.lower +local math_abs = math.abs local GetTime = GetTime local CreateFrame = CreateFrame local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME @@ -172,6 +173,56 @@ function Gladdy:NewModule(name, priority, defaults) return module end +function Gladdy:CreateMover(frame, x, y, name, points) + if not frame.mover then + frame.mover = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate") + frame.mover:SetFrameStrata("TOOLTIP") + frame.mover:SetPoint(points[1], frame, points[2], 0, 0) + local backdrop = { + bgFile = "Interface/Tooltips/UI-Tooltip-Background", + edgeFile = "", + tile = true, tileSize = 16, edgeSize = 10, + insets = {left = 0, right = 0, top = 0, bottom = 0} + } + + frame.mover:SetBackdrop(backdrop) + frame.mover:SetBackdropColor(0,0,0,0.8) + frame.mover:SetHeight(15) + frame.mover:SetWidth(60) + frame.mover.text = frame.mover:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") + frame.mover.text:SetText(name) + frame.mover.text:SetPoint("CENTER") + + frame.mover:SetMovable(true) + frame.mover:EnableMouse(true) + + frame.mover:SetScript("OnMouseDown", function(self) + self.point = { frame:GetPoint() } + self.start = { frame:GetCenter() } + frame:StartMoving() + self:StartMoving() + end) + frame.mover:SetScript("OnMouseUp", function(self) + frame:StopMovingOrSizing() + self:StopMovingOrSizing() + self.stop = { frame:GetCenter() } + local diffX = math_abs(self.start[1] - self.stop[1]) + diffX = self.start[1] > self.stop[1] and -diffX or diffX + local diffY = math_abs(self.start[2] - self.stop[2]) + diffY = self.start[2] > self.stop[2] and -diffY or diffY + frame:ClearAllPoints() + frame:SetPoint(self.point[1], self.point[2], self.point[3], self.point[4] + diffX, self.point[5] + diffY) + Gladdy.db[x] = self.point[4] + diffX + Gladdy.db[y] = self.point[5] + diffY + Gladdy:UpdateFrame() + end) + else + frame.mover:ClearAllPoints() + frame.mover:SetPoint(points[1], frame, points[2], 0, 0) + end + +end + --------------------------- -- INIT diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 0a4faeb..966e459 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -235,11 +235,13 @@ end function BuffsDebuffs:CreateFrame(unit) local verticalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding local debuffFrame = CreateFrame("Frame", "GladdyDebuffs" .. unit, Gladdy.buttons[unit]) + debuffFrame:SetMovable(true) debuffFrame:SetHeight(Gladdy.db.buffsIconSize) debuffFrame:SetWidth(1) debuffFrame:SetPoint("BOTTOMLEFT", Gladdy.buttons[unit].healthBar, "TOPLEFT", 0, verticalMargin) debuffFrame.unit = unit local buffFrame = CreateFrame("Frame", "GladdyBuffs" .. unit, Gladdy.buttons[unit]) + buffFrame:SetMovable(true) buffFrame:SetHeight(Gladdy.db.buffsIconSize) buffFrame:SetWidth(1) buffFrame:SetPoint("BOTTOMLEFT", Gladdy.buttons[unit].healthBar, "TOPLEFT", 0, verticalMargin) @@ -328,6 +330,9 @@ function BuffsDebuffs:UpdateFrame(unit) self.frames[unit].debuffFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset) end end + if (unit == "arena1") then + Gladdy:CreateMover(self.frames[unit].debuffFrame, "buffsXOffset", "buffsYOffset", L["Debuffs"], {"BOTTOMLEFT", "TOPLEFT"}) + end --BUFFS self.frames[unit].buffFrame:SetHeight(Gladdy.db.buffsBuffsIconSize) @@ -422,6 +427,10 @@ function BuffsDebuffs:UpdateFrame(unit) self.frames[unit].buffFrame:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset) end end + if (unit == "arena1") then + Gladdy:CreateMover(self.frames[unit].buffFrame, "buffsBuffsXOffset", "buffsBuffsYOffset", L["Buffs"], {"BOTTOMLEFT", "TOPLEFT"}) + end + for i=1, #self.frames[unit].auras[AURA_TYPE_BUFF] do styleIcon(self.frames[unit].auras[AURA_TYPE_BUFF][i], AURA_TYPE_BUFF) end diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 17d62e7..b0a07b3 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -59,6 +59,7 @@ end function Castbar:CreateFrame(unit) local castBar = CreateFrame("Frame", nil, Gladdy.buttons[unit], BackdropTemplateMixin and "BackdropTemplate") castBar:EnableMouse(false) + castBar:SetMovable(true) castBar.unit = unit castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), @@ -191,6 +192,10 @@ function Castbar:UpdateFrame(unit) castBar.icon.texture.overlay:SetTexture(Gladdy.db.castBarIconStyle) castBar.icon.texture.overlay:SetVertexColor(Gladdy.db.castBarIconColor.r, Gladdy.db.castBarIconColor.g, Gladdy.db.castBarIconColor.b, Gladdy.db.castBarIconColor.a) + + if (unit == "arena1") then + Gladdy:CreateMover(castBar, "castBarXOffset", "castBarYOffset", L["Cast Bar"], {"BOTTOMLEFT", "TOPLEFT"}) + end end --------------------------- diff --git a/Modules/CombatIndicator.lua b/Modules/CombatIndicator.lua index 54a8b76..572e0b1 100644 --- a/Modules/CombatIndicator.lua +++ b/Modules/CombatIndicator.lua @@ -38,6 +38,7 @@ function CombatIndicator:CreateFrame(unit) end local ciFrame = CreateFrame("Frame", "GladdyCombatindicator" .. unit, button) ciFrame:EnableMouse(false) + ciFrame:SetMovable(true) ciFrame:SetFrameStrata("HIGH") ciFrame:SetHeight(Gladdy.db.ciSize) ciFrame:SetWidth(Gladdy.db.ciSize * Gladdy.db.ciWidthFactor) @@ -77,6 +78,9 @@ function CombatIndicator:UpdateFrame(unit) else ciFrame:Show() end + if (unit == "arena1") then + Gladdy:CreateMover(ciFrame, "ciXOffset", "ciYOffset", L["Combat Indicator"], {"BOTTOMLEFT", "TOPLEFT"}) + end end function CombatIndicator:Test() diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index c2ed7b9..90bb6a4 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -94,6 +94,7 @@ function Cooldowns:CreateFrame(unit) -- Cooldown frame local spellCooldownFrame = CreateFrame("Frame", nil, button) spellCooldownFrame:EnableMouse(false) + spellCooldownFrame:SetMovable(true) for x = 1, 14 do local icon = CreateFrame("Frame", nil, spellCooldownFrame) icon:EnableMouse(false) @@ -166,6 +167,9 @@ function Cooldowns:UpdateFrame(unit) button.spellCooldownFrame:SetHeight(Gladdy.db.cooldownSize) button.spellCooldownFrame:SetWidth(1) button.spellCooldownFrame:Show() + if (unit == "arena1") then + Gladdy:CreateMover(button.spellCooldownFrame, "cooldownXOffset", "cooldownYOffset", L["Cooldown"], {"BOTTOMLEFT", "TOPLEFT"}) + end -- Update each cooldown icon local o = 1 for j = 1, 14 do diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index e999943..f11f872 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -67,6 +67,7 @@ end function Diminishings:CreateFrame(unit) local drFrame = CreateFrame("Frame", nil, Gladdy.buttons[unit]) drFrame:EnableMouse(false) + drFrame:SetMovable(true) for i = 1, 16 do local icon = CreateFrame("Frame", "GladdyDr" .. unit .. "Icon" .. i, drFrame) @@ -177,6 +178,10 @@ function Diminishings:UpdateFrame(unit) drFrame:SetWidth(Gladdy.db.drIconSize * 16) drFrame:SetHeight(Gladdy.db.drIconSize) + if (unit == "arena1") then + Gladdy:CreateMover(drFrame, "drXOffset", "drYOffset", L["Diminishings"], + Gladdy.db.drCooldownPos == "RIGHT" and {"BOTTOMLEFT", "TOPLEFT"} or {"BOTTOMRIGHT", "TOPRIGHT"}) + end for i = 1, 16 do local icon = drFrame["icon" .. i] diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 994a8b5..780febf 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -134,6 +134,7 @@ function Pets:CreateFrame(unitId) return end local button = CreateFrame("Frame", "GladdyButtonFramePet" .. unit, Gladdy.frame) + button:SetMovable(true) --button:SetAlpha(0) button:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) @@ -289,6 +290,9 @@ function Pets:UpdateFrame(unitId) end healthBar.nameText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) healthBar.healthText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) + if (unit == "arenapet1") then + Gladdy:CreateMover(self.frames[unit], "petXOffset", "petYOffset", L["Pets"], {"BOTTOMLEFT", "TOPLEFT"}) + end end function Pets:SetHealthText(healthBar, health, healthMax) -- 2.39.5 From fabd9ae0483f99a73d20da2e3b4345850867c439 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 24 Sep 2021 16:40:36 +0200 Subject: [PATCH 052/268] grouping of pets first step --- Modules/Pets.lua | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 780febf..4cb8196 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -23,6 +23,8 @@ local Pets = Gladdy:NewModule("Pets", nil, { petHealthPercentage = true, petXOffset = 1, petYOffset = -62, + petGroup = false, + petMargin = 1, }) function Pets:Initialize() @@ -251,6 +253,18 @@ function Pets:UpdateFrame(unitId) self.frames[unit]:SetWidth(Gladdy.db.petWidth) self.frames[unit]:SetHeight(Gladdy.db.petHeight) self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + if (Gladdy.db.petGroup) then + if (unit == "arenapet1") then + self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + else + local previousPet = "arenapet" .. string_gsub(unit, "arenapet", "") - 1 + self.frames[unit]:ClearAllPoints() + self.frames[unit]:SetPoint("TOPLEFT", self.frames[previousPet], "BOTTOMLEFT", 0, - Gladdy.db.petMargin) + end + else + self.frames[unit]:ClearAllPoints() + self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + end healthBar.portrait:SetHeight(Gladdy.db.petHeight) healthBar.portrait:SetWidth(Gladdy.db.petHeight) @@ -384,11 +398,28 @@ function Pets:GetOptions() step = 1, width = "full", }), + petGroup = option({ + type = "toggle", + name = L["Group Pets"], + order = 5, + }), + petMargin = option({ + type = "range", + name = L["Margin"], + desc = L["Height of the bar"], + order = 6, + disabled = function() + return not Gladdy.db.petGroup + end, + min = 0, + max = 50, + step = .1, + }), petHealthBarTexture = option({ type = "select", name = L["Bar texture"], desc = L["Texture of the bar"], - order = 5, + order = 7, dialogControl = "LSM30_Statusbar", values = AceGUIWidgetLSMlists.statusbar, }), @@ -396,14 +427,14 @@ function Pets:GetOptions() type = "color", name = L["Health color"], desc = L["Color of the status bar"], - order = 6, + order = 8, hasAlpha = true, }), petHealthBarBgColor = Gladdy:colorOption({ type = "color", name = L["Background color"], desc = L["Color of the status bar background"], - order = 7, + order = 9, hasAlpha = true, }), }, -- 2.39.5 From ebb56c41278f2eb1ee14fd4b8236ff658182458f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 25 Sep 2021 14:03:57 +0200 Subject: [PATCH 053/268] testmode only movable frames --- Frame.lua | 2 ++ Gladdy.lua | 46 ++++++++++++++++++++++------------------ Modules/BuffsDebuffs.lua | 10 +++++++-- Modules/Castbar.lua | 2 +- Modules/Cooldowns.lua | 4 +++- Modules/Diminishings.lua | 6 +++++- Modules/Pets.lua | 2 +- 7 files changed, 45 insertions(+), 27 deletions(-) diff --git a/Frame.lua b/Frame.lua index f1f5bc4..128452d 100644 --- a/Frame.lua +++ b/Frame.lua @@ -305,6 +305,7 @@ end function Gladdy:ToggleFrame(i) self:Reset() if (self.frame and self.frame:IsShown() and i == self.curBracket) then + self.frame.testing = nil self:HideFrame() else self.curBracket = i @@ -312,6 +313,7 @@ function Gladdy:ToggleFrame(i) if (not self.frame) then self:CreateFrame() end + self.frame.testing = true for o = 1, self.curBracket do local unit = "arena" .. o diff --git a/Gladdy.lua b/Gladdy.lua index 7cdf5a0..4538015 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -8,10 +8,10 @@ local tsort = table.sort local str_lower = string.lower local math_abs = math.abs local GetTime = GetTime +local InCombatLockdown = InCombatLockdown local CreateFrame = CreateFrame local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME local IsAddOnLoaded = IsAddOnLoaded -local IsInInstance = IsInInstance local GetBattlefieldStatus = GetBattlefieldStatus local IsActiveBattlefieldArena = IsActiveBattlefieldArena local RELEASE_TYPES = { alpha = "Alpha", beta = "Beta", release = "Release"} @@ -173,23 +173,28 @@ function Gladdy:NewModule(name, priority, defaults) return module end -function Gladdy:CreateMover(frame, x, y, name, points) +function Gladdy:CreateMover(frame, xConfig, yConfig, name, points, width, height, xOffset, yOffset) if not frame.mover then frame.mover = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate") - frame.mover:SetFrameStrata("TOOLTIP") - frame.mover:SetPoint(points[1], frame, points[2], 0, 0) + frame.mover:SetFrameStrata("DIALOG") + frame.mover:SetPoint(points[1], frame, points[2], xOffset or 0, yOffset or 0) + frame.mover:SetHeight(height or frame:GetHeight()) + frame.mover:SetWidth(width or frame:GetWidth()) + local backdrop = { bgFile = "Interface/Tooltips/UI-Tooltip-Background", edgeFile = "", tile = true, tileSize = 16, edgeSize = 10, insets = {left = 0, right = 0, top = 0, bottom = 0} } - frame.mover:SetBackdrop(backdrop) - frame.mover:SetBackdropColor(0,0,0,0.8) - frame.mover:SetHeight(15) - frame.mover:SetWidth(60) - frame.mover.text = frame.mover:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") + frame.mover:SetBackdropColor(0,1,0,0.5) + frame.mover.border = CreateFrame("Frame", nil, frame.mover, BackdropTemplateMixin and "BackdropTemplate") + frame.mover.border:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = 2 }) + frame.mover.border:SetAllPoints(frame.mover) + frame.mover.border:SetBackdropBorderColor(0,1,0,1) + + frame.mover.text = frame.mover.border:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") frame.mover.text:SetText(name) frame.mover.text:SetPoint("CENTER") @@ -212,15 +217,21 @@ function Gladdy:CreateMover(frame, x, y, name, points) diffY = self.start[2] > self.stop[2] and -diffY or diffY frame:ClearAllPoints() frame:SetPoint(self.point[1], self.point[2], self.point[3], self.point[4] + diffX, self.point[5] + diffY) - Gladdy.db[x] = self.point[4] + diffX - Gladdy.db[y] = self.point[5] + diffY + Gladdy.db[xConfig] = self.point[4] + diffX + Gladdy.db[yConfig] = self.point[5] + diffY Gladdy:UpdateFrame() end) else frame.mover:ClearAllPoints() - frame.mover:SetPoint(points[1], frame, points[2], 0, 0) + frame.mover:SetPoint(points[1], frame, points[2], xOffset or 0, yOffset or 0) + frame.mover:SetHeight(height or frame:GetHeight()) + frame.mover:SetWidth(width or frame:GetWidth()) + end + if self.frame and self.frame.testing then + frame.mover:Show() + else + frame.mover:Hide() end - end --------------------------- @@ -298,7 +309,6 @@ function Gladdy:OnInitialize() self.guids = {} self.curBracket = nil self.curUnit = 1 - self.lastInstance = nil self:SetupOptions() @@ -402,16 +412,10 @@ function Gladdy:PLAYER_ENTERING_WORLD() LibStub("AceConfigDialog-3.0"):Open("Gladdy", nil, LibStub("AceConfigDialog-3.0"):SelectGroup("Gladdy", "XiconProfiles")) self.showConfig = nil end - local instance = select(2, IsInInstance()) - if (instance ~= "arena" and self.frame and self.frame:IsVisible() and not self.frame.testing) then + if (self.frame and self.frame:IsVisible()) then self:Reset() self:HideFrame() end - if (instance == "arena") then - self:Reset() - self:HideFrame() - end - self.lastInstance = instance end function Gladdy:UPDATE_BATTLEFIELD_STATUS(_, index) diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 966e459..0590c9c 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -331,7 +331,10 @@ function BuffsDebuffs:UpdateFrame(unit) end end if (unit == "arena1") then - Gladdy:CreateMover(self.frames[unit].debuffFrame, "buffsXOffset", "buffsYOffset", L["Debuffs"], {"BOTTOMLEFT", "TOPLEFT"}) + Gladdy:CreateMover(self.frames[unit].debuffFrame, "buffsXOffset", "buffsYOffset", L["Debuffs"], + Gladdy.db.buffsCooldownGrowDirection == "LEFT" and {"TOPRIGHT", "TOPRIGHT"} or {"TOPLEFT", "TOPLEFT"}, + Gladdy.db.buffsIconSize * Gladdy.db.buffsWidthFactor, + Gladdy.db.buffsIconSize, Gladdy.db.buffsCooldownGrowDirection == "LEFT"and -1 or 1, 0) end --BUFFS @@ -428,7 +431,10 @@ function BuffsDebuffs:UpdateFrame(unit) end end if (unit == "arena1") then - Gladdy:CreateMover(self.frames[unit].buffFrame, "buffsBuffsXOffset", "buffsBuffsYOffset", L["Buffs"], {"BOTTOMLEFT", "TOPLEFT"}) + Gladdy:CreateMover(self.frames[unit].buffFrame, "buffsBuffsXOffset", "buffsBuffsYOffset", L["Buffs"], + Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT" and {"TOPRIGHT", "TOPRIGHT"} or {"TOPLEFT", "TOPLEFT"}, + Gladdy.db.buffsBuffsIconSize * Gladdy.db.buffsBuffsWidthFactor, + Gladdy.db.buffsBuffsIconSize, Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT"and -1 or 1, 0) end for i=1, #self.frames[unit].auras[AURA_TYPE_BUFF] do diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index b0a07b3..4717563 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -194,7 +194,7 @@ function Castbar:UpdateFrame(unit) castBar.icon.texture.overlay:SetVertexColor(Gladdy.db.castBarIconColor.r, Gladdy.db.castBarIconColor.g, Gladdy.db.castBarIconColor.b, Gladdy.db.castBarIconColor.a) if (unit == "arena1") then - Gladdy:CreateMover(castBar, "castBarXOffset", "castBarYOffset", L["Cast Bar"], {"BOTTOMLEFT", "TOPLEFT"}) + Gladdy:CreateMover(castBar, "castBarXOffset", "castBarYOffset", L["Cast Bar"], {"TOPLEFT", "TOPLEFT"}, Gladdy.db.castBarWidth, Gladdy.db.castBarHeight, 0, 0) end end diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 90bb6a4..1ab006d 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -168,7 +168,9 @@ function Cooldowns:UpdateFrame(unit) button.spellCooldownFrame:SetWidth(1) button.spellCooldownFrame:Show() if (unit == "arena1") then - Gladdy:CreateMover(button.spellCooldownFrame, "cooldownXOffset", "cooldownYOffset", L["Cooldown"], {"BOTTOMLEFT", "TOPLEFT"}) + Gladdy:CreateMover(button.spellCooldownFrame, "cooldownXOffset", "cooldownYOffset", L["Cooldown"], + Gladdy.db.cooldownXPos == "RIGHT" and {"TOPRIGHT", "TOPRIGHT"} or {"TOPLEFT", "TOPLEFT"}, + Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor, Gladdy.db.cooldownSize) end -- Update each cooldown icon local o = 1 diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index f11f872..3d46253 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -180,7 +180,11 @@ function Diminishings:UpdateFrame(unit) drFrame:SetHeight(Gladdy.db.drIconSize) if (unit == "arena1") then Gladdy:CreateMover(drFrame, "drXOffset", "drYOffset", L["Diminishings"], - Gladdy.db.drCooldownPos == "RIGHT" and {"BOTTOMLEFT", "TOPLEFT"} or {"BOTTOMRIGHT", "TOPRIGHT"}) + Gladdy.db.drCooldownPos == "RIGHT" and {"TOPLEFT", "TOPLEFT"} or {"TOPRIGHT", "TOPRIGHT"}, --point + Gladdy.db.drIconSize * Gladdy.db.drWidthFactor, -- width + Gladdy.db.drIconSize, + 0, --xoffset + 0) --yoffset end for i = 1, 16 do diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 4cb8196..9039ce8 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -305,7 +305,7 @@ function Pets:UpdateFrame(unitId) healthBar.nameText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) healthBar.healthText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) if (unit == "arenapet1") then - Gladdy:CreateMover(self.frames[unit], "petXOffset", "petYOffset", L["Pets"], {"BOTTOMLEFT", "TOPLEFT"}) + Gladdy:CreateMover(self.frames[unit], "petXOffset", "petYOffset", L["Pets"], {"TOPLEFT", "TOPLEFT"}) end end -- 2.39.5 From 09a47e81f1e65b3dda16e8f4051433ffc96f442c Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 26 Sep 2021 14:06:50 +0200 Subject: [PATCH 054/268] CI movable frames --- Gladdy.lua | 2 ++ Modules/CombatIndicator.lua | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Gladdy.lua b/Gladdy.lua index 4538015..2b0b28c 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -17,6 +17,7 @@ local IsActiveBattlefieldArena = IsActiveBattlefieldArena local RELEASE_TYPES = { alpha = "Alpha", beta = "Beta", release = "Release"} local PREFIX = "TBC-Classic_v" local VERSION_REGEX = PREFIX .. "(%d+%.%d+)%-(%a)" +local LibStub = LibStub --------------------------- @@ -219,6 +220,7 @@ function Gladdy:CreateMover(frame, xConfig, yConfig, name, points, width, height frame:SetPoint(self.point[1], self.point[2], self.point[3], self.point[4] + diffX, self.point[5] + diffY) Gladdy.db[xConfig] = self.point[4] + diffX Gladdy.db[yConfig] = self.point[5] + diffY + LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") Gladdy:UpdateFrame() end) else diff --git a/Modules/CombatIndicator.lua b/Modules/CombatIndicator.lua index 572e0b1..91447ad 100644 --- a/Modules/CombatIndicator.lua +++ b/Modules/CombatIndicator.lua @@ -79,7 +79,7 @@ function CombatIndicator:UpdateFrame(unit) ciFrame:Show() end if (unit == "arena1") then - Gladdy:CreateMover(ciFrame, "ciXOffset", "ciYOffset", L["Combat Indicator"], {"BOTTOMLEFT", "TOPLEFT"}) + Gladdy:CreateMover(ciFrame, "ciXOffset", "ciYOffset", L["Combat Indicator"], {"TOPLEFT", "TOPLEFT"}) end end -- 2.39.5 From 69c1eca49b9e3a5efb89c0a5682a5d5e412baf29 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Mon, 27 Sep 2021 13:38:40 +0200 Subject: [PATCH 055/268] add contributors --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 7408ec7..b427e3d 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,15 @@ The goal is to make Gladdy highly configurable in it's appearance. Everything ca +## Contributors + +- [ManneN1](https://github.com/ManneN1) +- [AlexFolland](https://github.com/AlexFolland) +- [dfherr](https://github.com/dfherr) +- [miraage](https://github.com/miraage) + +Thank you! + ## Special Thanks - **miraage** - the origininal author of Gladdy! Your work set the foundation for this edit. Thanks! -- 2.39.5 From 41f74f589603c84c93bcf4038eae203905907b2c Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Mon, 27 Sep 2021 13:40:02 +0200 Subject: [PATCH 056/268] DR Level Icon Text by ManneN1 --- Modules/Diminishings.lua | 71 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 3d46253..2a2c1d2 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -44,6 +44,9 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { drHalfColor = {r = 1, g = 1, b = 0, a = 1 }, drQuarterColor = {r = 1, g = 0.7, b = 0, a = 1 }, drNullColor = {r = 1, g = 0, b = 0, a = 1 }, + drLevelTextEnabled = false, + drLevelTextFont = "DorisPP", + drLevelTextFontScale = 1, drWidthFactor = 1, drCategories = defaultCategories(), drDuration = 18 @@ -59,6 +62,16 @@ local function getDiminishColor(dr) end end +local function getDiminishText(dr) + if dr == 0.5 then + return "½" + elseif dr == 0.25 then + return "¼" + else + return "ø" + end +end + function Diminishings:Initialize() self.frames = {} self:RegisterMessage("UNIT_DEATH", "ResetUnit", "AURA_FADE", "UNIT_DESTROYED") @@ -133,6 +146,15 @@ function Diminishings:CreateFrame(unit) icon.timeText:SetJustifyH("CENTER") icon.timeText:SetPoint("CENTER", icon, "CENTER", 0, 1) + icon.drLevelText = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") + icon.drLevelText:SetDrawLayer("OVERLAY") + icon.drLevelText:SetFont(Gladdy:SMFetch("font", "drLevelTextFont"), 10, "OUTLINE") + icon.drLevelText:SetTextColor(getDiminishColor(1)) + icon.drLevelText:SetShadowOffset(1, -1) + icon.drLevelText:SetShadowColor(0, 0, 0, 1) + icon.drLevelText:SetJustifyH("CENTER") + icon.drLevelText:SetPoint("BOTTOM", icon, "BOTTOM", 0, 0) + icon.diminishing = 1 drFrame["icon" .. i] = icon @@ -198,6 +220,9 @@ function Diminishings:UpdateFrame(unit) icon.timeText:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") icon.timeText:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) + icon.drLevelText:SetFont(Gladdy:SMFetch("font", "drLevelTextFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drLevelTextFontScale, "OUTLINE") + icon.drLevelText:SetTextColor(getDiminishColor(icon.diminishing)) + icon.cooldown:SetWidth(icon:GetWidth() - icon:GetWidth()/16) icon.cooldown:SetHeight(icon:GetHeight() - icon:GetHeight()/16) icon.cooldown:ClearAllPoints() @@ -214,6 +239,13 @@ function Diminishings:UpdateFrame(unit) icon.border:SetVertexColor(Gladdy.db.drBorderColor.r, Gladdy.db.drBorderColor.g, Gladdy.db.drBorderColor.b, Gladdy.db.drBorderColor.a) end + if Gladdy.db.drLevelTextEnabled then + icon.drLevelText:Show() + icon.drLevelText:SetText(getDiminishText(icon.diminishing)) + else + icon.drLevelText:Hide() + end + icon:ClearAllPoints() if (Gladdy.db.drCooldownPos == "LEFT") then if (i == 1) then @@ -565,10 +597,47 @@ function Diminishings:GetOptions() }), }, }, + level = { + type = "group", + name = L["Level Text"], + order = 5, + args = { + headerBorder = { + type = "header", + name = L["DR Level"], + order = 1, + }, + drLevelTextEnabled = Gladdy:option({ + type = "toggle", + name = L["DR Level Text Enabled"], + desc = L["Shows the current DR Level on the DR icon."], + order = 2, + width = "full", + }), + drLevelTextFont = Gladdy:option({ + type = "select", + name = L["Font"], + desc = L["Font of the cooldown"], + order = 3, + dialogControl = "LSM30_Font", + values = AceGUIWidgetLSMlists.font, + }), + drLevelTextFontScale = Gladdy:option({ + type = "range", + name = L["Font scale"], + desc = L["Scale of the text"], + order = 4, + min = 0.1, + max = 2, + step = 0.1, + width = "full", + }), + }, + }, border = { type = "group", name = L["Border"], - order = 5, + order = 6, args = { headerBorder = { type = "header", -- 2.39.5 From 91c25edcfee12bf5595a9f7b12d2a83b262fae2c Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Mon, 10 Jan 2022 23:59:08 +0100 Subject: [PATCH 057/268] zhCN Locale --- Lang.lua | 428 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) diff --git a/Lang.lua b/Lang.lua index ce0ec8d..740b673 100644 --- a/Lang.lua +++ b/Lang.lua @@ -985,6 +985,434 @@ elseif GetLocale() == "zhTW" then L["Background Color of the frame"] = "框架的背景顏色" L["Gladdy"] = "Gladdy目標框架" --Line 210, 709, 727 +elseif GetLocale() == "zhCN" then + -- Announcements.lua + L["Announcements"] = "通知" + L["RESURRECTING: %s (%s)"] = "复活: %s (%s) " + L["SPEC DETECTED: %s - %s (%s)"] = "敌方天赋: %s - %s (%s)" + L["LOW HEALTH: %s (%s)"] = "低生命值: %s (%s)" + L["TRINKET USED: %s (%s)"] = "饰品已使用: %s (%s)" + L["TRINKET READY: %s (%s)"] = "饰品就绪: %s (%s)" + L["DRINKING: %s (%s)"] = "正在喝水: %s (%s)" + L["Self"] = "玩家" + L["Party"] = "队伍" + L["Raid Warning"] = "团队警告" + L["Blizzard's Floating Combat Text"] = "Blizzard 战斗浮动文字" + L["Trinket used"] = "饰品已使用" + L["Announce when an enemy's trinket is used"] = "当敌方使用饰品时发出通知" + L["Trinket ready"] = "饰品就緒" + L["Announce when an enemy's trinket is ready again"] = "当敌方饰品就绪时发出通报" + L["Drinking"] = "正在喝水" + L["Announces when enemies sit down to drink"] = "当敌方喝水时发出通报" + L["Resurrection"] = "复活" + L["Announces when an enemy tries to resurrect a teammate"] = "当敌方尝试复活队友时发出通报" + L["New enemies"] = "新的敌人" + L["Announces when new enemies are discovered"] = "当发现新的敌人时发出通报" + L["Spec Detection"] = "天赋侦测" + L["Announces when the spec of an enemy was detected"] = "当侦测到敌方天赋时发出通报" + L["Low health"] = "低生命值" + L["Announces when an enemy drops below a certain health threshold"] = "当敌方生命值低于一定条件时发出通报" + L["Low health threshold"] = "低生命值门槛" + L["Choose how low an enemy must be before low health is announced"] = "设定低生命值通报门槛" + L["Destination"] = "发送通报至" + L["Choose how your announcements are displayed"] = "选择通报发送至哪个频道" + + -- ArenaCountDown.lua + L["Arena Countdown"] = "竞技场计时" + L["Turns countdown before the start of an arena match on/off."] = "在竞技场开始前倒数剩余秒数" + L["Size"] = "大小" + + -- Auras.lua + L["Auras"] = "光环" + L["Frame"] = "框架" + L["Cooldown"] = "冷却时间" + L["No Cooldown Circle"] = "取消图示冷却倒数阴影" + L["Cooldown circle alpha"] = "冷却倒数阴影alpha值" + L["Font"] = "字体" + L["Font of the cooldown"] = "設定冷卻時間字型" + L["Font scale"] = "字体大小" + L["Scale of the text"] = "设定字体大小" + L["Font color"] = "字体颜色" + L["Color of the text"] = "设定字体颜色" + L["Border"] = "边框" + L["Border style"] = "边框样式" + L["Buff color"] = "增益顏色" + L["Debuff color"] = "减益顏色" + L["Check All"] = "全选" + L["Uncheck All"] = "取消全选" + L["Enabled"] = "启用" + L["Priority"] = "优先" + L["Interrupt Spells School Colors"] = "打断法术分类颜色" + L["Enable Interrupt Spell School Colors"] = "启用" + L["Will use Debuff Color if disabled"] = "若未启用则使用一般减益颜色" + L["Buffs"] = "增益" --Line 573 + L["Debuffs"] = "減益" --Line 566 + L["Interrupts"] = "打断" --Line 580 + + -- BuffsDebuffs.lua + L["Buffs and Debuffs"] = "增益与减益" + L["Enabled Buffs and Debuffs module"] = "启用增益与减益模块" + L["Show CC"] = "显示控场" + L["Shows all debuffs, which are displayed on the ClassIcon as well"] = "显示所有减益效果,这些减益效果也显示在职业图标上" + L["Buffs"] = "增益" + L["Size & Padding"] = "大小与內距" + L["Icon Size"] = "图标大小" + L["Size of the DR Icons"] = "递减图标大小" + L["Icon Width Factor"] = "图标宽度比例" + L["Stretches the icon"] = "图标宽度" + L["Icon Padding"] = "图标內距" + L["Space between Icons"] = "图标间距" + L["Position"] = "位置" + L["Aura Position"] = "光环位置" + L["Position of the aura icons"] = "光环图标位置" + L["Top"] = "顶部" + L["Bottom"] = "底部" + L["Left"] = "左" + L["Right"] = "右" + --L["Grow Direction"] = "" + L["Grow Direction of the aura icons"] = "光环图标的延伸方向" + L["Horizontal offset"] = "水平偏移" + L["Vertical offset"] = "垂直偏移" + L["Alpha"] = "Alpha值" + L["Debuffs"] = "减益" + L["Dynamic Timer Color"] = "动态计时条颜色" + L["Show dynamic color on cooldown numbers"] = "冷却时间数字以动态颜色显示" + L["Color of the cooldown timer and stacks"] = "Farbe der Abklingzeit und Stapel" + L["Spell School Colors"] = "法术种类颜色" + L["Spell School Colors Enabled"] = "启用" + L["Show border colors by spell school"] = "根据不同法术显示不同边框颜色" + L["Curse"] = "诅咒" + L["Color of the border"] = "边框颜色" + L["Magic"] = "魔法" + L["Poison"] = "中毒" + L["Physical"] = "物理" + L["Immune"] = "免疫" + L["Disease"] = "疾病" + L["Aura"] = "光环" + L["Form"] = "形态" + L["Font"] = "字体" --Line 906 + L["Border"] = "边框" --Line 949 + L["Debuff Lists"] = "减益列表" --Line 1036 + L["Buff Lists"] = "增益列表" --Line 1051 + + -- Castbar.lua + L["Cast Bar"] = "施法条" + L["Bar"] = "施法条" + L["Bar Size"] = "施法条大小" + L["Bar height"] = "高度" + L["Height of the bar"] = "计量条高度" + L["Bar width"] = "宽度" + L["Width of the bars"] = "计量条宽度" + L["Texture"] = "材质" + L["Bar texture"] = "施法条材质" + L["Texture of the bar"] = "计量条材质" + L["Bar color"] = "施法条颜色" + L["Color of the cast bar"] = "计量条颜色" + L["Background color"] = "背景颜色" + L["Color of the cast bar background"] = "施法条背景顏色" + L["Border size"] = "边框大小" + L["Status Bar border"] = "状态条边框" + L["Status Bar border color"] = "状态条边框颜色" + L["Icon"] = "图标" + L["Icon size"] = "图标大小" + L["Icon border"] = "图标边框" + L["Icon border color"] = "图标边框颜色" + L["If test is running, type \"/gladdy test\" again"] = "如果测试已经开始,调整此选项后请输入/gladdy test以重新开始测试" + L["Spark"] = "尾部发亮" + L["Spark enabled"] = "启用" + L["Spark color"] = "颜色" + L["Color of the cast bar spark"] = "计时条进度的尾部颜色" + L["Font of the castbar"] = "施法条字体" + L["Font size"] = "字体大小" + L["Size of the text"] = "施法条字体大小" + L["Format"] = "格式" + L["Timer Format"] = "时间格式" + L["Remaining"] = "剩余时间" + L["Total"] = "总时间" + L["Both"] = "两者" + L["Castbar position"] = "施法条位置" + L["Icon position"] = "图标位置" + L["Offsets"] = "偏移" + + -- Classicon.lua + L["Class Icon"] = "职业图标" + L["Balance"] = "平衡" + L["Feral"] = "野性" + L["Restoration"] = "恢复" + L["Beast Mastery"] = "兽王" + L["Marksmanship"] = "射击" + L["Survival"] = "生存" + L["Arcane"] = "奥术" + L["Fire"] = "火焰" + L["Frost"] = "冰霜" + L["Holy"] = "神圣" + L["Protection"] = "防护" + L["Retribution"] = "惩戒" + L["Discipline"] = "戒律" + L["Shadow"] = "暗影" + L["Assassination"] = "刺杀" + L["Combat"] = "战斗" + L["Subtlety"] = "敏锐" + L["Elemental"] = "元素" + L["Enhancement"] = "增强" + L["Affliction"] = "痛苦" + L["Demonology"] = "恶魔" + L["Destruction"] = "毁灭" + L["Arms"] = "武器" + L["Fury"] = "狂怒" + L["Show Spec Icon"] = "显示天赋图标" + L["Shows Spec Icon once spec is detected"] = "若侦测到天赋则显示天赋图标" + L["Icon width factor"] = "图标宽度比例" + L["This changes positions with trinket"] = "调整职业图标位置" + L["Border color"] = "边框颜色" + + --CombatIndicator.lua + L["Combat Indicator"] = "战斗指示器" + L["Enable Combat Indicator icon"] = "显示是否进入战斗" + L["Anchor"] = "锚点" + L["This changes the anchor of the ci icon"] = "调整战斗指示器显示锚点" + L["This changes position relative to its anchor of the ci icon"] = "调整战斗指示器位置" + + -- Constants.lua + L["Physical"] = "物理" --Line 749 + L["Holy"] = "神圣" --Line 750 + L["Fire"] = "火焰" --Line 751 + L["Nature"] = "自然" --Line 752 + L["Frost"] = "冰霜" --Line 753 + L["Shadow"] = "暗影" --Line 754 + L["Arcane"] = "奥术" --Line 755 + L["Unknown"] = "未知" --Line 756 + + -- Cooldowns.lua + L["Cooldowns"] = "技能冷却监控" + L["Enabled cooldown module"] = "启用冷却时间监控模块" + L["Cooldown size"] = "大小" + L["Size of each cd icon"] = "冷却时间图标" + L["Icon Width Factor"] = "宽度" + L["Max Icons per row"] = "每行图标数量" + L["Scale of the font"] = "字体大小" + L["Anchor of the cooldown icons"] = "冷却图标锚点" + L["Grow Direction of the cooldown icons"] = "冷却图标延伸方向" + L["Offset"] = "偏移" + L["BloodElf"] = "血精灵" + L["NightElf"] = "暗夜精灵" + L["Scourge"] = "亡灵" + + -- Diminishings.lua + L["Diminishings"] = "控场递减" + L["Enabled DR module"] = "启用递减模块" + L["DR Cooldown position"] = "递减冷却时间位置" + L["Position of the cooldown icons"] = "递减冷却时间图标位置" + L["DR Border Colors"] = "DR边框颜色" + L["Dr Border Colors Enabled"] = "启用" + L["Colors borders of DRs in respective DR-color below"] = "边框颜色依递减设定为以下颜色" + L["Half"] = "二分之一" + L["Quarter"] = "四分之一" + L["Categories"] = "法术列表" + L["Force Icon"] = "使用自定义图标" + L["Icon of the DR"] = "选择此图标取代原始技能图标" + + -- ExportImport.lua + L["Export Import"] = "导出/导入" + L["Profile Export Import"] = "设置导出/导入" + L["Export"] = "导出" --Line 138 + L["Export your current profile to share with others or your various accounts."] = "导出您目前的设置" --Line 139 + L["Import"] = "导入" --Line 162 + L["This will overwrite your current profile!"] = "这将会覆盖您目前的设置" --Line 163 + + -- Healthbar.lua + L["Health Bar"] = "血量条" + L["DEAD"] = "死亡" + L["LEAVE"] = "暂离" + L["General"] = "一般" + L["Color of the status bar background"] = "状态条背景颜色" + L["Font of the bar"] = "字体" + L["Name font size"] = "名称字体大小" + L["Size of the name text"] = "设定名称字体大小" + L["Health font size"] = "生命值字体大小" + L["Size of the health text"] = "设定生命值字体大小" + L["Size of the border"] = "边框大小" + L["Health Bar Text"] = "血量条文字" + L["Show name text"] = "显示名字" + L["Show the units name"] = "显示单位名称" + L["Show ArenaX"] = "显示编号" + L["Show 1-5 as name instead"] = "使用编号1-5代替角色名字" + L["Show the actual health"] = "显示目前生命值" + L["Show the actual health on the health bar"] = "在血量条上显示目前生命值" + L["Show max health"] = "显示最大生命值" + L["Show max health on the health bar"] = "在血量条上显示最大生命值" + L["Show health percentage"] = "显示百分比" + L["Show health percentage on the health bar"] = "在血量条上显示生命值百分比" + + -- Highlight.lua + L["Highlight"] = "高亮提示" + L["Show Inside"] = "显示在框架內" + L["Show Highlight border inside of frame"] = "將高亮边框显示于框架內侧" + L["Colors"] = "边框颜色" + L["Target border color"] = "目标" + L["Color of the selected targets border"] = "目标的边框顏色" + L["Focus border color"] = "焦点" + L["Color of the focus border"] = "焦点目标边框顏色" + L["Highlight target"] = "高亮目标" + L["Toggle if the selected target should be highlighted"] = "是否高亮当前目标" + L["Show border around target"] = "显示目标边框" + L["Toggle if a border should be shown around the selected target"] = "是否显示当前目标的边框" + L["Show border around focus"] = "显示焦点边框" + L["Toggle of a border should be shown around the current focus"] = "是否显示当前焦点目标的边框" + + -- Pets.lua + L["Pets"] = "宠物" + L["Enables Pets module"] = "启用宠物模块" + L["Width of the bar"] = "宠物条宽度" + L["Health color"] = "生命值顏色" + L["Color of the status bar"] = "状态条顏色" + L["Portrait"] = "头像" + L["Health Values"] = "生命值" + + -- Powerbar.lua + L["Power Bar"] = "法力/能量条" + L["Power Bar Text"] = "法力/能量条文字" + L["Power Texts"] = "法力/能量条文字" + L["Show race"] = "显示种族" + L["Show spec"] = "显示天赋" + L["Show the actual power"] = "显示目前法力/能量" + L["Show the actual power on the power bar"] = "在计量条中显示目前法力/能量值" + L["Show max power"] = "显示最大法力/能量值" + L["Show max power on the power bar"] = "在计量条中显示最大法力/能量值" + L["Show power percentage"] = "显示法力/能量百分比" + L["Show power percentage on the power bar"] = "在计量条中显示目前法力/能量百分比" + + -- Racial.lua + L["Racial"] = "种族" + L["Enable racial icon"] = "启用种族图标" + L["This changes the anchor of the racial icon"] = "调整种族图标锚点" + L["This changes position relative to its anchor of the racial icon"] = "调整种族图标位置" + + -- TotemPlates.lua + L["Totem Plates"] = "图腾栏" + L["Customize Totems"] = "自定义图腾" + L["Custom totem name"] = "自定义图腾名字" + L["Totem General"] = "图腾通用设置" + L["Turns totem icons instead of nameplates on or off. (Requires reload)"] = "是否显示图腾名字(需重新加载)" + L["Show friendly"] = "显示右方图腾" + L["Show enemy"] = "显示敌方图腾" + L["Totem size"] = "图腾大小" + L["Size of totem icons"] = "图腾图标大小" + L["Font of the custom totem name"] = "自定义图腾字体" + L["Apply alpha when no target"] = "图腾非目标时使用alpha值" + L["Always applies alpha, even when you don't have a target. Else it is 1."] = "若图腾未被选为目标,其图标使用alpha值設定" + L["Apply alpha when targeted"] = "图腾为目标时使用alpha值" + L["Always applies alpha, even when you target the totem. Else it is 1."] = "图腾被选为目标时,其图标使用alpha值設定" + L["All totem border alphas (configurable per totem)"] = "图腾 Alpha值 " + L["Totem icon border style"] = "图腾边框样式" + L["All totem border color"] = "图腾边框顏色" + + -- Trinket.lua + L["Trinket"] = "饰品" + L["Enable trinket icon"] = "启用饰品图标" + L["This changes positions of the trinket"] = "调整饰品图标位置" + + -- XiconProfiles.lua + L["Profile"] = "样式" + L["XiconProfiles"] = "框架外观" --Line 4 + L[" No Pet"] = "(无宠物)" --Line 109, 119 + + -- Frame.lua + L["Gladdy - drag to move"] = "Gladdy - 拖拽移动" + + -- Gladdy.lua + L["Welcome to Gladdy!"] = "欢迎使用 Gladdy!" + L["First run has been detected, displaying test frame."] = "第一次使用时,显示此测试框架。" + L["Valid slash commands are:"] = "可用的指令为:" + L["If this is not your first run please lock or move the frame to prevent this from happening."] = "若非第一次使用,请移动或锁定框架以免此提示再次出现。" + + -- Clicks.lua + L["Action #%d"] = "动作 #%d" + L["Target"] = "目标" --Line 15 + L["Focus"] = "焦点" --Line 16 + L["Clicks"] = "点击动作" + L["Left button"] = "左键" + L["Right button"] = "右键" + L["Middle button"] = "中键" + L["Button 4"] = "鼠标按键4" + L["Button 5"] = "鼠标按键5" + L["Select what action this mouse button does"] = "设置输入按键后欲执行的动作" + L["Modifier"] = "修饰键" + L["Select which modifier to use"] = "设置欲使用的修饰键" + L["Button"] = "按键" + L["Select which mouse button to use"] = "设置欲使用的鼠标按键" + L["Name"] = "名称" + L["Select the name of the click option"] = "设置动作名称" + L["Action"] = "动作" + L["Cast Spell / Macro"] = "施放法术/宏" + + --RangeCheck.lua + L["Range Check"] = "距离检测" + L["Spells"] = "法术" + L["Fade"] = "变暗" + L["Out of Range Darkening Level"] = "超出距离时变暗程度" + L["Higher is darker"] = "数值越高越暗" + L["yds"] = " 码" --Line 366, 388 + L["Changing the spellID only applies to your player class!\n\nExample: If you are a Paladin and wish to change your range check spell to Repentance, edit the Paladin spellID to 20066."] = "对应您的职业修改欲使用监控距离的技能。\n\n例:若您为圣骑士且想以忏悔技能用于距离监控,请将圣骑士的法术ID改为20066。" --Line 352 + + --ShadowsightTimer.lua + L["Shadowsight Timer"] = "暗影视界计时" + L["Locked"] = "锁定" + L["Announce"] = "通报" + L["Scale"] = "大小" + L["Shadowsight up in %ds"] = "暗影视界於%d秒后就绪" + L["Shadowsight up!"] = "暗影视界已就绪" + + -- Options.lua + L["settings"] = "设置" + L["Reset module"] = "重置模块" + L["Reset module to defaults"] = "将模块重置为初始值" + L["No settings"] = "无设置" + L["Module has no settings"] = "模块没有设置" + L["General settings"] = "通用设置" + L["Lock frame"] = "锁定框架" + L["Toggle if frame can be moved"] = "调整框架是否可移动" + L["Grow frame upwards"] = "框架向上延伸" + L["If enabled the frame will grow upwards instead of downwards"] = "开启次选项时框架向上延伸" + L["Down"] = "下" + L["Up"] = "上" + L["Frame General"] = "框架" + L["Frame scale"] = "框架大小" + L["Scale of the frame"] = "框架的尺寸" + L["Frame padding"] = "框架內距" + L["Padding of the frame"] = "框架的內距" + L["Frame width"] = "框架宽度" + L["Margin"] = "框架间距" + L["Margin between each button"] = "框架的间距" + L["Cooldown General"] = "冷却" + L["Font General"] = "字体" + L["General Font"] = "通用字体" + L["Font color text"] = "文字顏色" + L["Font color timer"] = "计时器文字顏色" + L["Color of the timers"] = "计时器顏色" + L["Icons General"] = "图标" + L["Icon border style"] = "图标边框样式" + L["This changes the border style of all icons"] = "调整所有图标的边框样式" + L["This changes the border color of all icons"] = "调整所有图标的边框顏色" + L["Statusbar General"] = "状态条" + L["Statusbar texture"] = "状态条材质" + L["This changes the texture of all statusbar frames"] = "调整所有状态条的材质" + L["Statusbar border style"] = "状态条边框样式" + L["This changes the border style of all statusbar frames"] = "调整所有状态条的边框样式" + L["Statusbar border offset divider (smaller is higher offset)"] = "状态条边框距离" + L["Offset of border to statusbar (in case statusbar shows beyond the border)"] = "调整状态条边框距离" + L["Statusbar border color"] = "状态条边框顏色" + L["This changes the border color of all statusbar frames"] = "调整所有状态条的边框颜色" + L["Hide Blizzard"] = "隐藏暴雪框架" + L["Grow Direction"] = "框架延伸方向" + L["Arena only"] = "只在竞技场中" + L["Never"] = "从不" + L["Always"] = "一直" + L["Load configuration"] = "设置选项" --Line 713 + L["Load configuration options"] = "加载设置选项" --Line 714 + L["Background Color of the frame"] = "框架的背景顏色" + + L["Gladdy"] = "Gladdy框架" --Line 210, 709, 727 end -- 2.39.5 From 92322a4d9bf921cd5e78ba2b22bf2d45966a5168 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Mon, 10 Jan 2022 23:59:20 +0100 Subject: [PATCH 058/268] spell interrupt announce --- Modules/Announcements.lua | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/Modules/Announcements.lua b/Modules/Announcements.lua index aeb5fd5..4b63595 100644 --- a/Modules/Announcements.lua +++ b/Modules/Announcements.lua @@ -26,6 +26,7 @@ local Announcements = Gladdy:NewModule("Announcements", nil, { healthThreshold = 20, trinketUsed = true, trinketReady = false, + spellInterrupt = true, dest = "party", }, }) @@ -48,6 +49,7 @@ function Announcements:Initialize() self:RegisterMessage("TRINKET_USED") self:RegisterMessage("TRINKET_READY") self:RegisterMessage("SHADOWSIGHT") + self:RegisterMessage("SPELL_INTERRUPT") end function Announcements:Reset() @@ -138,6 +140,14 @@ function Announcements:TRINKET_READY(unit) self:Send(L["TRINKET READY: %s (%s)"]:format(button.name, button.classLoc), 3, RAID_CLASS_COLORS[button.class]) end +function Announcements:SPELL_INTERRUPT(destUnit,spellID,spellName,spellSchool,extraSpellId,extraSpellName,extraSpellSchool) + local button = Gladdy.buttons[destUnit] + if (not button or not Gladdy.db.announcements.spellInterrupt) then + return + end + self:Send(L["INTERRUPTED: %s (%s)"]:format(extraSpellName, button.name or ""), 3, RAID_CLASS_COLORS[button.class]) +end + function Announcements:CheckDrink(unit, aura) local button = Gladdy.buttons[unit] if (not button or not Gladdy.db.announcements.drinks) then @@ -237,41 +247,47 @@ function Announcements:GetOptions() desc = L["Announce when an enemy's trinket is ready again"], order = 4, }), + spellInterrupt = option({ + type = "toggle", + name = L["Interrupts"], + desc = L["Announces when enemies' spells are interrupted"], + order = 5, + }), drinks = option({ type = "toggle", name = L["Drinking"], desc = L["Announces when enemies sit down to drink"], - order = 5, + order = 6, }), resurrections = option({ type = "toggle", name = L["Resurrection"], desc = L["Announces when an enemy tries to resurrect a teammate"], - order = 6, + order = 7, }), enemy = option({ type = "toggle", name = L["New enemies"], desc = L["Announces when new enemies are discovered"], - order = 7, + order = 8, }), spec = option({ type = "toggle", name = L["Spec Detection"], desc = L["Announces when the spec of an enemy was detected"], - order = 8, + order = 9, }), health = option({ type = "toggle", name = L["Low health"], desc = L["Announces when an enemy drops below a certain health threshold"], - order = 9, + order = 10, }), healthThreshold = option({ type = "range", name = L["Low health threshold"], desc = L["Choose how low an enemy must be before low health is announced"], - order = 10, + order = 11, min = 1, max = 100, step = 1, @@ -283,7 +299,7 @@ function Announcements:GetOptions() type = "select", name = L["Destination"], desc = L["Choose how your announcements are displayed"], - order = 11, + order = 12, values = destValues, }), } -- 2.39.5 From fed5d1c3416835836b159622115934cdf268d7b4 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Mon, 10 Jan 2022 23:59:33 +0100 Subject: [PATCH 059/268] reload during arena --- EventListener.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/EventListener.lua b/EventListener.lua index 4d87a28..7d96b78 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -33,6 +33,16 @@ function EventListener:JOINED_ARENA() self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START") self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") self:SetScript("OnEvent", EventListener.OnEvent) + + -- in case arena has started already we check for units + for i=1,Gladdy.curBracket do + if UnitExists("arena" .. i) then + Gladdy:SpotEnemy("arena" .. i, true) + end + if UnitExists("arenapet" .. i) then + Gladdy:SendMessage("PET_SPOTTED", "arenapet" .. i) + end + end end function EventListener:Reset() -- 2.39.5 From b2c8ed9c44ab8beb6f1793cff70a47ec81cc2eda Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:00:17 +0100 Subject: [PATCH 060/268] fixed spec detection --- Modules/Cooldowns.lua | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 1ab006d..bf30c5d 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -338,13 +338,24 @@ function Cooldowns:CooldownReady(button, spellId, frame) end end +local function notIn(spec, list) + for _,v in ipairs(list) do + if spec == v then + return false + end + end + return true +end + function Cooldowns:DetectSpec(unit, spec) local button = Gladdy.buttons[unit] if (not button or not spec or button.spec) then return end - if button.class == "PALADIN" and (spec ~= L["Holy"] or spec ~= L["Retribution"]) then + if button.class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) + or button.class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) + or button.class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then return end -- 2.39.5 From e2a78c717b75dabd444d1217db40540557f95311 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:01:57 +0100 Subject: [PATCH 061/268] fixed DRs Hibernate/Chastice/Dragonsbreath/ImpConcussiveShot/Counterattack --- Libs/DRData-1.0/DRData-1.0.lua | 38 +++++++++++++++++++--------------- Modules/ExportImport.lua | 6 +++++- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Libs/DRData-1.0/DRData-1.0.lua b/Libs/DRData-1.0/DRData-1.0.lua index e6bd775..6b7d0e7 100644 --- a/Libs/DRData-1.0/DRData-1.0.lua +++ b/Libs/DRData-1.0/DRData-1.0.lua @@ -188,9 +188,9 @@ Data.spells = { --[[ SLEEPS ]]-- -- Hibernate - [2637] = "sleep", - [18657] = "sleep", - [18658] = "sleep", + [2637] = "disorient", + [18657] = "disorient", + [18658] = "disorient", -- Wyvern Sting [19386] = "disorient", @@ -199,19 +199,19 @@ Data.spells = { [27068] = "disorient", --[[ MISC ]]-- - -- Chastise (Maybe this shares DR with Imp HS?) - [44041] = "root", - [44043] = "root", - [44044] = "root", - [44045] = "root", - [44046] = "root", - [44047] = "root", + -- Chastise + [44041] = "chastise", + [44043] = "chastise", + [44044] = "chastise", + [44045] = "chastise", + [44046] = "chastise", + [44047] = "chastise", -- Dragon's Breath - [31661] = "dragonsbreath", -- Dragon's Breath - [33041] = "dragonsbreath", -- Dragon's Breath - [33042] = "dragonsbreath", -- Dragon's Breath - [33043] = "dragonsbreath", -- Dragon's Breath + [31661] = "scatters", -- Dragon's Breath + [33041] = "scatters", -- Dragon's Breath + [33042] = "scatters", -- Dragon's Breath + [33043] = "scatters", -- Dragon's Breath -- Repentance [20066] = "disorient", @@ -224,9 +224,9 @@ Data.spells = { [14309] = "disorient", -- Improved Conc Shot - [19410] = "impconc", - [22915] = "impconc", - [28445] = "impconc", + [19410] = "rndstun", + [22915] = "rndstun", + [28445] = "rndstun", -- Death Coil [6789] = "dc", @@ -242,6 +242,9 @@ Data.spells = { [605] = "charm", [10911] = "charm", [10912] = "charm", + + -- Counterattack + [19306] = "counterattack" } -- DR Category names @@ -264,6 +267,7 @@ Data.typeNames = { ["repentance"] = "Repentance", ["dragonsbreath"] = "Dragon's Breath", ["ua"] = "Unstable Affliction Silence", + ["counterattack"] = "Counterattack Immobilize" } -- Categories that have DR in PvE as well as PvP diff --git a/Modules/ExportImport.lua b/Modules/ExportImport.lua index a1c709e..330499a 100644 --- a/Modules/ExportImport.lua +++ b/Modules/ExportImport.lua @@ -89,7 +89,11 @@ import:AddChild(importClearButton) import.clearButton = importClearButton local deletedOptions = { -- backwards compatibility - growUp = true, + --deleted DR-categories + repentance = true, + sleep = true, + impconc = true, + dragonsbreath = true, freezetrap = true, repentance = true } -- 2.39.5 From 7db32cceef1efb53d1885ed1b777154e1863ac21 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:02:10 +0100 Subject: [PATCH 062/268] fix grow up positioning --- Frame.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Frame.lua b/Frame.lua index 128452d..b3d1e78 100644 --- a/Frame.lua +++ b/Frame.lua @@ -58,7 +58,7 @@ function Gladdy:CreateFrame() local scale = f:GetEffectiveScale() self.db.x = f:GetLeft() * scale - self.db.y = (self.db.growUp and f:GetBottom() or f:GetTop()) * scale + self.db.y = (self.db.growDirection == "TOP" and f:GetBottom() or f:GetTop()) * scale end end) @@ -82,7 +82,7 @@ function Gladdy:CreateFrame() local scale = self.frame:GetEffectiveScale() self.db.x = self.frame:GetLeft() * scale - self.db.y = (self.db.growUp and self.frame:GetBottom() or self.frame:GetTop()) * scale + self.db.y = (self.db.growDirection == "TOP" and self.frame:GetBottom() or self.frame:GetTop()) * scale end end) self.anchor:SetScript("OnClick", function() -- 2.39.5 From 2dcdc9c9786fb3775cac6cd6ffee1c8144ef6b47 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:02:21 +0100 Subject: [PATCH 063/268] fix dr level text --- Modules/Diminishings.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 2a2c1d2..069efb0 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -221,7 +221,6 @@ function Diminishings:UpdateFrame(unit) icon.timeText:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) icon.drLevelText:SetFont(Gladdy:SMFetch("font", "drLevelTextFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drLevelTextFontScale, "OUTLINE") - icon.drLevelText:SetTextColor(getDiminishColor(icon.diminishing)) icon.cooldown:SetWidth(icon:GetWidth() - icon:GetWidth()/16) icon.cooldown:SetHeight(icon:GetHeight() - icon:GetHeight()/16) @@ -241,7 +240,6 @@ function Diminishings:UpdateFrame(unit) if Gladdy.db.drLevelTextEnabled then icon.drLevelText:Show() - icon.drLevelText:SetText(getDiminishText(icon.diminishing)) else icon.drLevelText:Hide() end @@ -368,6 +366,8 @@ function Diminishings:AuraFade(unit, spellID) lastIcon.active = true self:Positionate(unit) lastIcon:Show() + lastIcon.drLevelText:SetText(getDiminishText(lastIcon.diminishing)) + lastIcon.drLevelText:SetTextColor(getDiminishColor(lastIcon.diminishing)) end function Diminishings:Positionate(unit) -- 2.39.5 From f923f471d89a627277d64ff17f5934fef0a79573 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:03:36 +0100 Subject: [PATCH 064/268] detect spelllock and devour magic --- EventListener.lua | 4 ++++ Modules/Pets.lua | 1 + 2 files changed, 5 insertions(+) diff --git a/EventListener.lua b/EventListener.lua index 7d96b78..530f482 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -112,6 +112,10 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() end end if srcUnit then + srcUnit = string_gsub(srcUnit, "pet", "") + if (not UnitExists(srcUnit)) then + return + end if (eventType == "SPELL_CAST_SUCCESS" or eventType == "SPELL_AURA_APPLIED") then local unitRace = Gladdy.buttons[srcUnit].race -- cooldown tracker diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 9039ce8..36a32d2 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -65,6 +65,7 @@ function Pets:ResetUnit(unitId) end function Pets:PET_SPOTTED(unit) + Gladdy.guids[UnitGUID(unit)] = unit if Gladdy.db.petEnabled then self.frames[unit].healthBar:SetAlpha(1) self.frames[unit].healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) -- 2.39.5 From 0a5176aaed0bff1728778cdbbfc7b0d064efa6b1 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:04:08 +0100 Subject: [PATCH 065/268] detect arena and pets faster on reload --- Gladdy.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Gladdy.lua b/Gladdy.lua index 2b0b28c..a605d9b 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -14,6 +14,8 @@ local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME local IsAddOnLoaded = IsAddOnLoaded local GetBattlefieldStatus = GetBattlefieldStatus local IsActiveBattlefieldArena = IsActiveBattlefieldArena +local IsInInstance = IsInInstance +local GetNumArenaOpponents = GetNumArenaOpponents local RELEASE_TYPES = { alpha = "Alpha", beta = "Beta", release = "Release"} local PREFIX = "TBC-Classic_v" local VERSION_REGEX = PREFIX .. "(%d+%.%d+)%-(%a)" @@ -422,7 +424,9 @@ end function Gladdy:UPDATE_BATTLEFIELD_STATUS(_, index) local status, mapName, instanceID, levelRangeMin, levelRangeMax, teamSize, isRankedArena, suspendedQueue, bool, queueType = GetBattlefieldStatus(index) - if (status == "active" and teamSize > 0 and IsActiveBattlefieldArena()) then + local instanceType = select(2, IsInInstance()) + Gladdy:Debug("INFO", "UPDATE_BATTLEFIELD_STATUS", instanceType, status, teamSize) + if ((instanceType == "arena" or GetNumArenaOpponents() > 0) and status == "active" and teamSize > 0) then self.curBracket = teamSize self:JoinedArena() end -- 2.39.5 From 1b2311fea2640acd2390e92997ca65ad0b3d4e89 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:04:54 +0100 Subject: [PATCH 066/268] debug messages --- Gladdy.lua | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Gladdy.lua b/Gladdy.lua index a605d9b..1b3f4ba 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -37,6 +37,8 @@ Gladdy.version_releaseType = RELEASE_TYPES.release Gladdy.version = PREFIX .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType Gladdy.VERSION_REGEX = VERSION_REGEX +Gladdy.debug = false + LibStub("AceTimer-3.0"):Embed(Gladdy) LibStub("AceComm-3.0"):Embed(Gladdy) Gladdy.modules = {} @@ -58,6 +60,17 @@ function Gladdy:Print(...) end function Gladdy:Warn(...) + local text = "|cfff29f05Gladdy|r:" + local val + for i = 1, select("#", ...) do + val = select(i, ...) + if (type(val) == 'boolean') then val = val and "true" or false end + text = text .. " " .. tostring(val) + end + DEFAULT_CHAT_FRAME:AddMessage(text) +end + +function Gladdy:Error(...) local text = "|cfffc0303Gladdy|r:" local val for i = 1, select("#", ...) do @@ -68,6 +81,18 @@ function Gladdy:Warn(...) DEFAULT_CHAT_FRAME:AddMessage(text) end +function Gladdy:Debug(lvl, ...) + if Gladdy.debug then + if lvl == "INFO" then + Gladdy:Print(...) + elseif lvl == "WARN" then + Gladdy:Warn(...) + elseif lvl == "ERROR" then + Gladdy:Error(...) + end + end +end + Gladdy.events = CreateFrame("Frame") Gladdy.events.registered = {} Gladdy.events:RegisterEvent("PLAYER_LOGIN") -- 2.39.5 From 8df7aae3b6466de42834132994f260b08fb1d07a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:05:31 +0100 Subject: [PATCH 067/268] detect fear ward cd when buffed pre arena start --- EventListener.lua | 33 ++++++++++++++++++++++++++------- Modules/Cooldowns.lua | 4 ++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 530f482..e867791 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -1,13 +1,14 @@ -local select, string_gsub, tostring = select, string.gsub, tostring +local select, string_gsub, tostring, pairs = select, string.gsub, tostring, pairs local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo local AURA_TYPE_DEBUFF = AURA_TYPE_DEBUFF local AURA_TYPE_BUFF = AURA_TYPE_BUFF -local UnitName, UnitAura, UnitRace, UnitClass, UnitGUID, UnitIsUnit = UnitName, UnitAura, UnitRace, UnitClass, UnitGUID, UnitIsUnit +local UnitName, UnitAura, UnitRace, UnitClass, UnitGUID, UnitIsUnit, UnitExists = UnitName, UnitAura, UnitRace, UnitClass, UnitGUID, UnitIsUnit, UnitExists local UnitCastingInfo, UnitChannelInfo = UnitCastingInfo, UnitChannelInfo local GetSpellInfo = GetSpellInfo local FindAuraByName = AuraUtil.FindAuraByName +local GetTime = GetTime local Gladdy = LibStub("Gladdy") local Cooldowns = Gladdy.modules["Cooldowns"] @@ -50,9 +51,9 @@ function EventListener:Reset() self:SetScript("OnEvent", nil) end -function Gladdy:DetectSpec(unit, specSpell) - if specSpell then - self.modules["Cooldowns"]:DetectSpec(unit, specSpell) +function Gladdy:DetectSpec(unit, spec) + if spec then + self.modules["Cooldowns"]:DetectSpec(unit, spec) end end @@ -73,11 +74,18 @@ function Gladdy:SpotEnemy(unit, auraScan) end if auraScan and not button.spec then for n = 1, 30 do - local spellName,_,_,_,_,_,unitCaster = UnitAura(unit, n, "HELPFUL") + local spellName,_,_,_,_,expirationTime,unitCaster = UnitAura(unit, n, "HELPFUL") if ( not spellName ) then break end - if Gladdy.specBuffs[spellName] then + if Gladdy.cooldownBuffs[spellName] then -- Check for auras that detect used CDs (like Fear Ward) + for arenaUnit,v in pairs(self.buttons) do + if (UnitIsUnit(arenaUnit, unitCaster)) then + Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, expirationTime - GetTime()) + end + end + end + if Gladdy.specBuffs[spellName] then -- Check for auras that detect a spec local unitPet = string_gsub(unit, "%d$", "pet%1") if UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster) then Gladdy:DetectSpec(unit, Gladdy.specBuffs[spellName]) @@ -202,6 +210,10 @@ Gladdy.exceptionNames = { -- TODO MOVE ME TO CLASSBUFFS LIB [27010] = select(1, GetSpellInfo(27010)) .. " " .. select(1, GetSpellInfo(16689)), } +Gladdy.cooldownBuffs = { + [GetSpellInfo(6346)] = { cd = 180, spellId = 6346 }, -- Fear Ward +} + function EventListener:UNIT_AURA(unit) local button = Gladdy.buttons[unit] if not button then @@ -220,6 +232,13 @@ function EventListener:UNIT_AURA(unit) Gladdy:SendMessage("AURA_GAIN_LIMIT", unit, auraType, n - 1) break end + if Gladdy.cooldownBuffs[spellName] then -- Check for auras that hint used CDs (like Fear Ward) + for arenaUnit,v in pairs(Gladdy.buttons) do + if (UnitIsUnit(arenaUnit, unitCaster)) then + Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, expirationTime - GetTime()) + end + end + end if not button.spec and Gladdy.specBuffs[spellName] then local unitPet = string_gsub(unit, "%d$", "pet%1") if unitCaster and (UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster)) then diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index bf30c5d..0ce1594 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -502,7 +502,7 @@ function Cooldowns:UpdateCooldowns(button) end end -function Cooldowns:CooldownUsed(unit, unitClass, spellId) +function Cooldowns:CooldownUsed(unit, unitClass, spellId, expirationTimeInSeconds) local button = Gladdy.buttons[unit] if not button then return @@ -547,7 +547,7 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId) if (Gladdy.db.cooldown) then -- start cooldown - self:CooldownStart(button, spellId, cd) + self:CooldownStart(button, spellId, expirationTimeInSeconds or cd) end --[[ announcement -- 2.39.5 From be292401cc1aef152a7b69ce9393c910ed200998 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:05:57 +0100 Subject: [PATCH 068/268] pixel perfect scale minor adjustments --- Gladdy.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 1b3f4ba..f84824f 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -8,6 +8,7 @@ local tsort = table.sort local str_lower = string.lower local math_abs = math.abs local GetTime = GetTime +local GetPhysicalScreenSize = GetPhysicalScreenSize local InCombatLockdown = InCombatLockdown local CreateFrame = CreateFrame local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME @@ -290,15 +291,17 @@ end function Gladdy:PixelPerfectScale(update) local physicalWidth, physicalHeight = GetPhysicalScreenSize() - local perfectUIScale = 768/physicalHeight--768/select(2, strsplit("x",({ GetScreenResolutions()})[GetCurrentResolution()])) + local perfectUIScale = 768.0/physicalHeight--768/select(2, strsplit("x",({ GetScreenResolutions()})[GetCurrentResolution()])) if self.db and self.db.pixelPerfect and self.frame then self.frame:SetIgnoreParentScale(true) self.frame:SetScale(perfectUIScale) - --self.db.frameScale = perfectUIScale --(GetCVar("useUiScale") == "1" and 1 + perfectUIScale - GetCVar("UIScale") or perfectUIScale) + --local adaptiveScale = (GetCVar("useUiScale") == "1" and 1.0 + perfectUIScale - GetCVar("UIScale") or perfectUIScale) + --self.frame:SetScale(adaptiveScale) if update then self:UpdateFrame() end elseif self.frame then + self.frame:SetScale(self.db.frameScale) self.frame:SetIgnoreParentScale(false) end end -- 2.39.5 From adb06d0c7fc23b23ee7f14123a63e313b15ff64a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:13:31 +0100 Subject: [PATCH 069/268] add spec detection spells: - Expose Weakness (Survival Hunter) - Slow (Arcane Mage) - Improved Blink (Fire Mage) - Vindication (Retribution Paladin) - Holy Shield (Protection Paladin) - Vampiric Embrace (Shadow Priest) - Blade Flurry (Combat Rogue) - Unleashed Rage (Enhancement Shaman) - Flurry (Enhancement Shaman) - Shamanistic Rage (Enhancement Shaman) - Healing Way (Restoration Shaman) - Totem of Wrath (Elemental Shaman) - Dark Pact (Affliction Warlock) - Conflagate (Destruction Warlock) - Shield Slam (Protection Warrior) Added Cooldowns: - Scare Beast (Hunter) - Feign Death (Hunter) - Viper Sting (Hunter) - Flare (Hunter) - Fear Ward (Priest) - Shadow Word: Death (Priest) - Evocation (Mage) - Grounding Totem (Shaman) - Spell Lock (Warlock) - Devour Magic (Warlock) - Intercept (Warrior) Added Auras: - Scare Beast (Hunter) - Fear Ward (Priest) --- Constants.lua | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/Constants.lua b/Constants.lua index 5595fe2..1e431b8 100644 --- a/Constants.lua +++ b/Constants.lua @@ -26,13 +26,16 @@ local specBuffs = { [GetSpellInfo(20895)] = L["Beast Mastery"], -- Spirit Bond [GetSpellInfo(34455)] = L["Beast Mastery"], -- Ferocious Inspiration [GetSpellInfo(27066)] = L["Marksmanship"], -- Trueshot Aura + [GetSpellInfo(34501)] = L["Survival"], -- Expose Weakness -- MAGE [GetSpellInfo(33405)] = L["Frost"], -- Ice Barrier [GetSpellInfo(11129)] = L["Fire"], -- Combustion [GetSpellInfo(12042)] = L["Arcane"], -- Arcane Power [GetSpellInfo(12043)] = L["Arcane"], -- Presence of Mind + [GetSpellInfo(31589)] = L["Arcane"], -- Slow [GetSpellInfo(12472)] = L["Frost"], -- Icy Veins + [GetSpellInfo(46989)] = L["Fire"], -- Improved Blink -- PALADIN [GetSpellInfo(31836)] = L["Holy"], -- Light's Grace @@ -41,9 +44,12 @@ local specBuffs = { [GetSpellInfo(20375)] = L["Retribution"], -- Seal of Command [GetSpellInfo(20049)] = L["Retribution"], -- Vengeance [GetSpellInfo(20218)] = L["Retribution"], -- Sanctity Aura + [GetSpellInfo(26018)] = L["Retribution"], -- Vindication + [GetSpellInfo(27179)] = L["Protection"], -- Holy Shield -- PRIEST [GetSpellInfo(15473)] = L["Shadow"], -- Shadowform + [GetSpellInfo(15286)] = L["Shadow"], -- Vampiric Embrace [GetSpellInfo(45234)] = L["Discipline"], -- Focused Will [GetSpellInfo(27811)] = L["Discipline"], -- Blessed Recovery [GetSpellInfo(33142)] = L["Holy"], -- Blessed Resilience @@ -59,11 +65,15 @@ local specBuffs = { [GetSpellInfo(36563)] = L["Subtlety"], -- Shadowstep DMG [GetSpellInfo(14278)] = L["Subtlety"], -- Ghostly Strike [GetSpellInfo(31233)] = L["Assassination"], -- Find Weakness + [GetSpellInfo(13877)] = L["Combat"], -- Blade Flurry --Shaman + [GetSpellInfo(30807)] = L["Enhancement"], -- Unleashed Rage + [GetSpellInfo(16280)] = L["Enhancement"], -- Flurry + [GetSpellInfo(30823)] = L["Enhancement"], -- Shamanistic Rage [GetSpellInfo(16190)] = L["Restoration"], -- Mana Tide Totem [GetSpellInfo(32594)] = L["Restoration"], -- Earth Shield - [GetSpellInfo(30823)] = L["Enhancement"], -- Shamanistic Rage + [GetSpellInfo(29202)] = L["Restoration"], -- Healing Way -- WARLOCK [GetSpellInfo(19028)] = L["Demonology"], -- Soul Link @@ -122,11 +132,13 @@ local specSpells = { [GetSpellInfo(34861)] = L["Holy"], -- Circle of Healing [GetSpellInfo(15473)] = L["Shadow"], -- Shadowform [GetSpellInfo(34917)] = L["Shadow"], -- Vampiric Touch + [GetSpellInfo(15286)] = L["Shadow"], -- Vampiric Embrace -- ROGUE [GetSpellInfo(34413)] = L["Assassination"], -- Mutilate [GetSpellInfo(14177)] = L["Assassination"], -- Cold Blood [GetSpellInfo(13750)] = L["Combat"], -- Adrenaline Rush + [GetSpellInfo(13877)] = L["Combat"], -- Blade Flurry [GetSpellInfo(14185)] = L["Subtlety"], -- Preparation [GetSpellInfo(16511)] = L["Subtlety"], -- Hemorrhage [GetSpellInfo(36554)] = L["Subtlety"], -- Shadowstep @@ -135,6 +147,7 @@ local specSpells = { -- SHAMAN [GetSpellInfo(16166)] = L["Elemental"], -- Elemental Mastery + [GetSpellInfo(30706)] = L["Elemental"], -- Totem of Wrath [GetSpellInfo(30823)] = L["Enhancement"], -- Shamanistic Rage [GetSpellInfo(17364)] = L["Enhancement"], -- Stormstrike [GetSpellInfo(16190)] = L["Restoration"], -- Mana Tide Totem @@ -143,8 +156,10 @@ local specSpells = { -- WARLOCK [GetSpellInfo(30405)] = L["Affliction"], -- Unstable Affliction + [GetSpellInfo(18220)] = L["Affliction"], -- Dark Pact --[GetSpellInfo(30911)] = L["Affliction"], -- Siphon Life [GetSpellInfo(30414)] = L["Destruction"], -- Shadowfury + [GetSpellInfo(30912)] = L["Destruction"], -- Conflagrate -- WARRIOR [GetSpellInfo(30330)] = L["Arms"], -- Mortal Strike @@ -152,6 +167,7 @@ local specSpells = { [GetSpellInfo(30335)] = L["Fury"], -- Bloodthirst [GetSpellInfo(12809)] = L["Protection"], -- Concussion Blow [GetSpellInfo(30022)] = L["Protection"], -- Devastation + [GetSpellInfo(30356)] = L["Protection"], -- Shield Slam } function Gladdy:GetSpecSpells() return specSpells @@ -264,6 +280,16 @@ local importantAuras = { onDamage = true, spellID = 19503, }, + -- Scare Beast + [GetSpellInfo(14327)] = { + track = AURA_TYPE_DEBUFF, + duration = 8, + priority = 40, + onDamage = true, + fear = true, + magic = true, + spellID = 14327, + }, -- Silencing Shot [GetSpellInfo(34490)] = { track = AURA_TYPE_DEBUFF, @@ -446,6 +472,13 @@ local importantAuras = { priority = 10, spellID = 33206, }, + -- Fear Ward + [GetSpellInfo(6346)] = { + track = AURA_TYPE_BUFF, + duration = 180, + priority = 9, + spellID = 6346, + }, -- Sap @@ -796,7 +829,7 @@ local cooldownList = { ["MAGE"] = { [1953] = 15, -- Blink --[122] = 22, -- Frost Nova - --[12051] = 480, --Evocation + [12051] = 480, --Evocation [2139] = 24, -- Counterspell [45438] = { cd = 300, [L["Frost"]] = 240, }, -- Ice Block [12472] = { cd = 180, spec = L["Frost"], }, -- Icy Veins @@ -828,6 +861,8 @@ local cooldownList = { [10060] = { cd = 180, spec = L["Discipline"], }, -- Power Infusion [33206] = { cd = 120, spec = L["Discipline"], }, -- Pain Suppression [34433] = 300, -- Shadowfiend + [32379] = 12, -- Shadow Word: Death + [6346] = 180, -- Fear Ward }, -- Druid @@ -853,6 +888,7 @@ local cooldownList = { [16166] = { cd = 180, spec = L["Elemental"], }, -- Elemental Mastery [16188] = { cd = 180, spec = L["Restoration"], }, -- Natures Swiftness [16190] = { cd = 300, spec = L["Restoration"], }, -- Mana Tide Totem + [8177] = 15, -- Grounding Totem }, -- Paladin @@ -882,7 +918,8 @@ local cooldownList = { ["WARLOCK"] = { [17928] = 40, -- Howl of Terror [27223] = 120, -- Death Coil - --[19647] = { cd = 24 }, -- Spell Lock; how will I handle pet spells? + [19647] = 24, -- Spell Lock + [27277] = 8, -- Devour Magic [30414] = { cd = 20, spec = L["Destruction"], }, -- Shadowfury [17877] = { cd = 15, spec = L["Destruction"], }, -- Shadowburn [18708] = { cd = 900, spec = L["Demonology"], }, -- Feldom @@ -907,6 +944,7 @@ local cooldownList = { [18499] = 30, -- Berserker Rage --[2565] = 60, -- Shield Block [12292] = { cd = 180, spec = L["Arms"], }, -- Death Wish + [20252] = { cd = 30, [L["Arms"]] = 20 }, -- Intercept [12975] = { cd = 180, spec = L["Protection"], }, -- Last Stand [12809] = { cd = 30, spec = L["Protection"], }, -- Concussion Blow @@ -915,6 +953,7 @@ local cooldownList = { -- Hunter ["HUNTER"] = { [19503] = 30, -- Scatter Shot + [14327] = 30, -- Scare Beast [19263] = 300, -- Deterrence; not on BM but can't do 2 specs [14311] = { cd = 30, -- Freezing Trap sharedCD = { @@ -938,6 +977,9 @@ local cooldownList = { [19386] = { cd = 60, spec = L["Survival"], }, -- Wyvern Sting [19577] = { cd = 60, spec = L["Beast Mastery"], }, -- Intimidation [38373] = { cd = 120, spec = L["Beast Mastery"], }, -- The Beast Within + [5384] = 30, -- Feign Death + [3034] = 15, -- Viper Sting + [1543] = 20, -- Flare }, -- Rogue -- 2.39.5 From 59da6f34c6f00bc769f30b663c00fb3dea608b8b Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:29:17 +0100 Subject: [PATCH 070/268] movable frames --- Constants.lua | 55 +++++ Frame.lua | 271 ++++++++++++++++++------ Gladdy.lua | 88 ++------ Modules/BuffsDebuffs.lua | 396 +++++++++++++++++------------------- Modules/Castbar.lua | 82 ++++---- Modules/Classicon.lua | 46 +++-- Modules/CombatIndicator.lua | 50 ++--- Modules/Cooldowns.lua | 193 +++++++++--------- Modules/Diminishings.lua | 94 +++++---- Modules/ExportImport.lua | 19 +- Modules/Pets.lua | 36 +++- Modules/Racial.lua | 50 +++-- Modules/Trinket.lua | 55 +++-- Options.lua | 54 +++-- 14 files changed, 881 insertions(+), 608 deletions(-) diff --git a/Constants.lua b/Constants.lua index 1e431b8..7efeeee 100644 --- a/Constants.lua +++ b/Constants.lua @@ -1180,3 +1180,58 @@ function Gladdy:GetArenaTimer() end end +Gladdy.legacy = { + castBarPos = "LEFT", + buffsCooldownPos = "TOP", + buffsBuffsCooldownPos = "BOTTOM", + classIconPos = "LEFT", + ciAnchor = "healthBar", + ciPos = "TOP", + cooldownYPos = "TOP", + cooldownXPos = "LEFT", + drCooldownPos = "RIGHT", + racialAnchor = "trinket", + racialPos = "RIGHT", + trinketPos = "RIGHT", + padding = 1, + growUp = false, +} + +Gladdy.newDefaults = { + ["bottomMargin"] = 94.99996948242188, + ["newLayout"] = true, + Pets = { + ["petYOffset"] = -81.99993896484375, + ["petXOffset"] = 181, + }, + ClassIcon = { + ["classIconXOffset"] = -74.90008544921875, + }, + Racial = { + ["racialXOffset"] = 255.9000244140625, + }, + Trinket = { + ["trinketXOffset"] = 182, + }, + ["Combat Indicator"] = { + ["ciXOffset"] = 79.99993896484375, + ["ciYOffset"] = -10.99993896484375, + }, + Cooldowns = { + ["cooldownYOffset"] = 31, + }, + ["Buffs and Debuffs"] = { + ["buffsBuffsXOffset"] = 29, + ["buffsBuffsYOffset"] = -82.99993896484375, + ["buffsXOffset"] = 29, + ["buffsYOffset"] = 62.00006103515625, + }, + Diminishings = { + ["drXOffset"] = 329.7999877929688, + ["drYOffset"] = -22.5, + }, + ["Cast Bar"] = { + ["castBarXOffset"] = -235.900146484375, + ["castBarYOffset"] = -30.5, + }, +} \ No newline at end of file diff --git a/Frame.lua b/Frame.lua index b3d1e78..e6d58e0 100644 --- a/Frame.lua +++ b/Frame.lua @@ -1,6 +1,9 @@ local CreateFrame = CreateFrame local UIParent = UIParent local InCombatLockdown = InCombatLockdown +local math_abs = math.abs +local pairs = pairs +local LibStub = LibStub local Gladdy = LibStub("Gladdy") local L = Gladdy.L @@ -45,7 +48,7 @@ function Gladdy:CreateFrame() self.frame:SetClampedToScreen(true) self.frame:EnableMouse(false) self.frame:SetMovable(true) - self.frame:RegisterForDrag("LeftButton") + --self.frame:RegisterForDrag("LeftButton") self.frame:SetScript("OnDragStart", function(f) if (not InCombatLockdown() and not self.db.locked) then @@ -126,72 +129,24 @@ function Gladdy:UpdateFrame() local highlightBorderSize = (self.db.highlightInset and 0 or self.db.highlightBorderSize * 2) local powerBarHeight = self.db.powerBarEnabled and (self.db.powerBarHeight + 1) or 0 - local leftSize = 0 - local rightSize = 0 - --Trinket + Racial - if self.db.trinketEnabled and self.db.trinketPos == "LEFT" then - leftSize = leftSize + self.db.trinketSize * self.db.trinketWidthFactor + self.db.padding - if self.db.racialEnabled and self.db.racialAnchor == "trinket" and self.db.racialPos == "LEFT" then - leftSize = leftSize + self.db.racialSize * self.db.racialWidthFactor + self.db.padding - end - end - if self.db.trinketEnabled and self.db.trinketPos == "RIGHT" then - rightSize = rightSize + self.db.trinketSize * self.db.trinketWidthFactor + self.db.padding - if self.db.racialEnabled and self.db.racialAnchor == "trinket" and self.db.racialPos == "RIGHT" then - rightSize = rightSize + self.db.racialSize * self.db.racialWidthFactor + self.db.padding - end - end - --ClassIcon - if self.db.classIconPos == "LEFT" then - leftSize = leftSize + self.db.classIconSize * self.db.classIconWidthFactor + self.db.padding - else - rightSize = rightSize + self.db.classIconSize * self.db.classIconWidthFactor + self.db.padding - end - --Highlight - if not self.db.highlightInset then - leftSize = leftSize + self.db.highlightBorderSize - rightSize = rightSize + self.db.highlightBorderSize - end local margin = powerBarHeight - local width = self.db.barWidth + leftSize + rightSize local height = (self.db.healthBarHeight + powerBarHeight) * teamSize + (self.db.highlightInset and 0 or self.db.highlightBorderSize * 2 * teamSize) + self.db.bottomMargin * (teamSize - 1) -- Highlight margin = margin + highlightBorderSize - - if (self.db.cooldownYPos == "TOP" or self.db.cooldownYPos == "BOTTOM") and self.db.cooldown then - margin = margin + self.db.cooldownSize - height = height + self.db.cooldownSize * (teamSize - 1) - end - if (self.db.buffsCooldownPos == "TOP" or self.db.buffsCooldownPos == "BOTTOM") and self.db.buffsEnabled then - margin = margin + self.db.buffsIconSize - height = height + self.db.buffsIconSize * (teamSize - 1) - end - if (self.db.buffsBuffsCooldownPos == "TOP" or self.db.buffsBuffsCooldownPos == "BOTTOM") and self.db.buffsEnabled then - margin = margin + self.db.buffsBuffsIconSize - height = height + self.db.buffsBuffsIconSize * (teamSize - 1) - end - if self.db.buffsCooldownPos == "TOP" and self.db.cooldownYPos == "TOP" and self.db.cooldown and self.db.buffsEnabled then - margin = margin + 1 - height = height + (teamSize - 1) - end - if self.db.buffsCooldownPos == "BOTTOM" and self.db.cooldownYPos == "BOTTOM" and self.db.cooldown and self.db.buffsEnabled then - margin = margin + 1 - height = height + (teamSize - 1) - end + margin, height = Gladdy:LegacyPositioning(margin, height, teamSize) -- GrowDirection if (self.db.growDirection == "LEFT" or self.db.growDirection == "RIGHT") then - width = self.db.barWidth * teamSize + (leftSize + rightSize) * teamSize + self.db.bottomMargin * (teamSize - 1) height = self.db.healthBarHeight + powerBarHeight end self.frame:SetScale(self.db.frameScale) self:PixelPerfectScale(false) - self.frame:SetWidth(width) + self.frame:SetWidth(self.db.barWidth + highlightBorderSize) self.frame:SetHeight(height) self.frame:ClearAllPoints() self.frame.background:SetBackdropColor(self.db.backgroundColor.r, self.db.backgroundColor.g, self.db.backgroundColor.b, self.db.backgroundColor.a) @@ -209,14 +164,14 @@ function Gladdy:UpdateFrame() end --Anchor - self.anchor:SetWidth(width) + self.anchor:SetWidth(self.db.barWidth * 2 + highlightBorderSize) self.anchor:ClearAllPoints() if (self.db.growDirection == "TOP") then - self.anchor:SetPoint("TOPLEFT", self.frame, "BOTTOMLEFT") + self.anchor:SetPoint("TOP", self.frame, "BOTTOM") elseif self.growDirection == "BOTTOM" or self.growDirection == "RIGHT" then - self.anchor:SetPoint("BOTTOMLEFT", self.frame, "TOPLEFT") + self.anchor:SetPoint("BOTTOM", self.frame, "TOP") else - self.anchor:SetPoint("BOTTOMRIGHT", self.frame, "TOPRIGHT") + self.anchor:SetPoint("BOTTOM", self.frame, "TOP") end if (self.db.locked) then @@ -236,7 +191,7 @@ function Gladdy:UpdateFrame() button.secure:ClearAllPoints() if (self.db.growDirection == "TOP") then if (i == 1) then - button:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMLEFT", leftSize, powerBarHeight) + button:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMLEFT", 0, powerBarHeight) button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") else button:SetPoint("BOTTOMLEFT", self.buttons["arena" .. (i - 1)], "TOPLEFT", 0, margin + self.db.bottomMargin) @@ -244,7 +199,7 @@ function Gladdy:UpdateFrame() end elseif (self.db.growDirection == "BOTTOM") then if (i == 1) then - button:SetPoint("TOPLEFT", self.frame, "TOPLEFT", leftSize, 0) + button:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, 0) button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") else button:SetPoint("TOPLEFT", self.buttons["arena" .. (i - 1)], "BOTTOMLEFT", 0, -margin - self.db.bottomMargin) @@ -252,18 +207,18 @@ function Gladdy:UpdateFrame() end elseif (self.db.growDirection == "LEFT") then if (i == 1) then - button:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -rightSize, 0) + button:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -0, 0) button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") else - button:SetPoint("TOPRIGHT", self.buttons["arena" .. (i - 1)], "TOPLEFT", -rightSize - leftSize - self.db.bottomMargin, 0) + button:SetPoint("TOPRIGHT", self.buttons["arena" .. (i - 1)], "TOPLEFT", - self.db.bottomMargin, 0) button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") end elseif (self.db.growDirection == "RIGHT") then if (i == 1) then - button:SetPoint("TOPLEFT", self.frame, "TOPLEFT", leftSize, 0) + button:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, 0) button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") else - button:SetPoint("TOPLEFT", self.buttons["arena" .. (i - 1)], "TOPRIGHT", leftSize + rightSize + self.db.bottomMargin, 0) + button:SetPoint("TOPLEFT", self.buttons["arena" .. (i - 1)], "TOPRIGHT", self.db.bottomMargin, 0) button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") end end @@ -287,6 +242,27 @@ function Gladdy:UpdateFrame() elseif Gladdy.db.hideBlizzard == "never" then Gladdy:BlizzArenaSetAlpha(1) end + if (not Gladdy.db.newLayout) then + Gladdy.db.newLayout = true + --get margin + local arena1Bottom + local arena2Top + if (self.db.growDirection == "BOTTOM") then + arena1Bottom = self.buttons["arena1"].secure:GetBottom() + arena2Top = self.buttons["arena2"].secure:GetTop() + elseif (self.db.growDirection == "TOP") then + arena1Bottom = self.buttons["arena1"].secure:GetTop() + arena2Top = self.buttons["arena2"].secure:GetBottom() + elseif (self.db.growDirection == "LEFT") then + arena1Bottom = self.buttons["arena1"].secure:GetLeft() + arena2Top = self.buttons["arena2"].secure:GetRight() + elseif (self.db.growDirection == "RIGHT") then + arena1Bottom = self.buttons["arena1"].secure:GetRight() + arena2Top = self.buttons["arena2"].secure:GetLeft() + end + Gladdy.db.bottomMargin = math_abs(arena1Bottom - arena2Top) + Gladdy:UpdateFrame() + end end function Gladdy:HideFrame() @@ -381,6 +357,179 @@ function Gladdy:CreateButton(i) self:ResetButton("arena" .. i) end + + +function Gladdy:SetPosition(frame, unit, xOffsetDB, yOffsetDB, newLayout, module) + local button = self.buttons[unit] + if not button or not frame or not xOffsetDB or not yOffsetDB then + return + end + + if (not newLayout) then + --Gladdy:Debug("INFO", name, "old X/Y:", frame:GetCenter()) + local xOffset, yOffset = frame:GetLeft(), frame:GetTop() + local x,y = button.healthBar:GetLeft(), button.healthBar:GetTop() + local newXOffset = math_abs(x - xOffset) * (x > xOffset and -1 or 1) + local newYOffset = math_abs(y - yOffset) * (y > yOffset and -1 or 1) + frame:ClearAllPoints() + frame:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT", newXOffset, newYOffset) + --Gladdy:Debug("INFO", name, "new X/Y:", frame:GetCenter()) + if unit == "arena1" then + Gladdy.db[xOffsetDB] = newXOffset + Gladdy.db[yOffsetDB] = newYOffset + LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") + end + else + frame:ClearAllPoints() + frame:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT", Gladdy.db[xOffsetDB], Gladdy.db[yOffsetDB]) + end + if (self.newDefaults[module.name]) then + for k,v in pairs(self.newDefaults[module.name]) do + module.defaults[k] = v + end + end +end + +function Gladdy:CreateMover(frame, xConfig, yConfig, name, points, width, height, xOffset, yOffset, activated) + if not frame.mover then + frame:EnableMouse(false) + frame:SetMovable(true) + frame.mover = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate") + frame.mover:SetFrameStrata("DIALOG") + frame.mover:SetPoint(points[1], frame, points[2], xOffset or 0, yOffset or 0) + frame.mover:SetHeight(height or frame:GetHeight()) + frame.mover:SetWidth(width or frame:GetWidth()) + + local backdrop = { + bgFile = "Interface/Tooltips/UI-Tooltip-Background", + edgeFile = "", + tile = true, tileSize = 16, edgeSize = 10, + insets = {left = 0, right = 0, top = 0, bottom = 0} + } + frame.mover:SetBackdrop(backdrop) + frame.mover:SetBackdropColor(0,1,0,0.5) + frame.mover.border = CreateFrame("Frame", nil, frame.mover, BackdropTemplateMixin and "BackdropTemplate") + frame.mover.border:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = 2 }) + frame.mover.border:SetAllPoints(frame.mover) + frame.mover.border:SetBackdropBorderColor(0,1,0,1) + + frame.mover.text = frame.mover.border:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") + frame.mover.text:SetText(name) + frame.mover.text:SetPoint("CENTER") + + frame.mover:SetMovable(true) + frame.mover:EnableMouse(true) + + frame.mover:SetScript("OnMouseDown", function(self) + self.point = { frame:GetPoint() } + self.start = { frame:GetCenter() } + frame:StartMoving() + self:StartMoving() + end) + frame.mover:SetScript("OnMouseUp", function(self) + frame:StopMovingOrSizing() + self:StopMovingOrSizing() + self.stop = { frame:GetCenter() } + local diffX = math_abs(self.start[1] - self.stop[1]) + diffX = self.start[1] > self.stop[1] and -diffX or diffX + local diffY = math_abs(self.start[2] - self.stop[2]) + diffY = self.start[2] > self.stop[2] and -diffY or diffY + frame:ClearAllPoints() + frame:SetPoint(self.point[1], self.point[2], self.point[3], self.point[4] + diffX, self.point[5] + diffY) + Gladdy.db[xConfig] = self.point[4] + diffX + Gladdy.db[yConfig] = self.point[5] + diffY + LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") + Gladdy:UpdateFrame() + end) + else + frame.mover:ClearAllPoints() + frame.mover:SetPoint(points[1], frame, points[2], xOffset or 0, yOffset or 0) + frame.mover:SetHeight(height or frame:GetHeight()) + frame.mover:SetWidth(width or frame:GetWidth()) + end + if self.frame and self.frame.testing and self.db.showMover then + frame.mover:Show() + else + frame.mover:Hide() + end +end + +--------------------------- + +-- LAGACY SUPPORT + +--------------------------- + +function Gladdy:LegacyPositioning(margin, height, teamSize) + if not Gladdy.db.newLayout then + for k,v in pairs(Gladdy.legacy) do + if Gladdy.db[k] == nil then + Gladdy:Debug("INFO", "Gladdy:LegacyPositioning write", k,v) + Gladdy.db[k] = v + else + Gladdy:Debug("INFO", "Gladdy:LegacyPositioning found", k,v) + end + end + if (self.db.cooldownYPos == "TOP" or self.db.cooldownYPos == "BOTTOM") and self.db.cooldown then + margin = margin + self.db.cooldownSize + height = height + self.db.cooldownSize * (teamSize - 1) + end + if (self.db.buffsCooldownPos == "TOP" or self.db.buffsCooldownPos == "BOTTOM") and self.db.buffsEnabled then + margin = margin + self.db.buffsIconSize + height = height + self.db.buffsIconSize * (teamSize - 1) + end + if (self.db.buffsBuffsCooldownPos == "TOP" or self.db.buffsBuffsCooldownPos == "BOTTOM") and self.db.buffsEnabled then + margin = margin + self.db.buffsBuffsIconSize + height = height + self.db.buffsBuffsIconSize * (teamSize - 1) + end + if self.db.buffsCooldownPos == "TOP" and self.db.cooldownYPos == "TOP" and self.db.cooldown and self.db.buffsEnabled then + margin = margin + 1 + height = height + (teamSize - 1) + end + if self.db.buffsCooldownPos == "BOTTOM" and self.db.cooldownYPos == "BOTTOM" and self.db.cooldown and self.db.buffsEnabled then + margin = margin + 1 + height = height + (teamSize - 1) + end + end + return margin, height +end + +function Gladdy:PositionButton(button, i, leftSize, rightSize, powerBarHeight, margin) + if (self.db.growDirection == "TOP") then + if (i == 1) then + button:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMLEFT", leftSize, powerBarHeight) + button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") + else + button:SetPoint("BOTTOMLEFT", self.buttons["arena" .. (i - 1)], "TOPLEFT", 0, margin + self.db.bottomMargin) + button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") + end + elseif (self.db.growDirection == "BOTTOM") then + if (i == 1) then + button:SetPoint("TOPLEFT", self.frame, "TOPLEFT", leftSize, 0) + button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") + else + button:SetPoint("TOPLEFT", self.buttons["arena" .. (i - 1)], "BOTTOMLEFT", 0, -margin - self.db.bottomMargin) + button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") + end + elseif (self.db.growDirection == "LEFT") then + if (i == 1) then + button:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -rightSize, 0) + button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") + else + button:SetPoint("TOPRIGHT", self.buttons["arena" .. (i - 1)], "TOPLEFT", -rightSize - leftSize - self.db.bottomMargin, 0) + button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") + end + elseif (self.db.growDirection == "RIGHT") then + if (i == 1) then + button:SetPoint("TOPLEFT", self.frame, "TOPLEFT", leftSize, 0) + button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") + else + button:SetPoint("TOPLEFT", self.buttons["arena" .. (i - 1)], "TOPRIGHT", leftSize + rightSize + self.db.bottomMargin, 0) + button.secure:SetPoint("TOPLEFT", button.healthBar, "TOPLEFT") + end + end +end + function Gladdy:GetAnchor(unit, position) local anchor = "healthBar" if Gladdy.db.classIconPos == position then diff --git a/Gladdy.lua b/Gladdy.lua index f84824f..d117a96 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -6,7 +6,6 @@ local pairs = pairs local tinsert = table.insert local tsort = table.sort local str_lower = string.lower -local math_abs = math.abs local GetTime = GetTime local GetPhysicalScreenSize = GetPhysicalScreenSize local InCombatLockdown = InCombatLockdown @@ -97,6 +96,7 @@ end Gladdy.events = CreateFrame("Frame") Gladdy.events.registered = {} Gladdy.events:RegisterEvent("PLAYER_LOGIN") +Gladdy.events:RegisterEvent("PLAYER_LOGOUT") Gladdy.events:RegisterEvent("CVAR_UPDATE") hooksecurefunc("VideoOptionsFrameOkay_OnClick", function(self, button, down, apply) if (self:GetName() == "VideoOptionsFrameApply") then @@ -111,6 +111,8 @@ Gladdy.events:SetScript("OnEvent", function(self, event, ...) if (str_lower(select(1, ...)) == "uiscale") then Gladdy:PixelPerfectScale(true) end + elseif (event == "PLAYER_LOGOUT") then + Gladdy:DeleteUnknownOptions(Gladdy.db, Gladdy.defaults.profile) else local func = self.registered[event] @@ -202,68 +204,6 @@ function Gladdy:NewModule(name, priority, defaults) return module end -function Gladdy:CreateMover(frame, xConfig, yConfig, name, points, width, height, xOffset, yOffset) - if not frame.mover then - frame.mover = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate") - frame.mover:SetFrameStrata("DIALOG") - frame.mover:SetPoint(points[1], frame, points[2], xOffset or 0, yOffset or 0) - frame.mover:SetHeight(height or frame:GetHeight()) - frame.mover:SetWidth(width or frame:GetWidth()) - - local backdrop = { - bgFile = "Interface/Tooltips/UI-Tooltip-Background", - edgeFile = "", - tile = true, tileSize = 16, edgeSize = 10, - insets = {left = 0, right = 0, top = 0, bottom = 0} - } - frame.mover:SetBackdrop(backdrop) - frame.mover:SetBackdropColor(0,1,0,0.5) - frame.mover.border = CreateFrame("Frame", nil, frame.mover, BackdropTemplateMixin and "BackdropTemplate") - frame.mover.border:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = 2 }) - frame.mover.border:SetAllPoints(frame.mover) - frame.mover.border:SetBackdropBorderColor(0,1,0,1) - - frame.mover.text = frame.mover.border:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") - frame.mover.text:SetText(name) - frame.mover.text:SetPoint("CENTER") - - frame.mover:SetMovable(true) - frame.mover:EnableMouse(true) - - frame.mover:SetScript("OnMouseDown", function(self) - self.point = { frame:GetPoint() } - self.start = { frame:GetCenter() } - frame:StartMoving() - self:StartMoving() - end) - frame.mover:SetScript("OnMouseUp", function(self) - frame:StopMovingOrSizing() - self:StopMovingOrSizing() - self.stop = { frame:GetCenter() } - local diffX = math_abs(self.start[1] - self.stop[1]) - diffX = self.start[1] > self.stop[1] and -diffX or diffX - local diffY = math_abs(self.start[2] - self.stop[2]) - diffY = self.start[2] > self.stop[2] and -diffY or diffY - frame:ClearAllPoints() - frame:SetPoint(self.point[1], self.point[2], self.point[3], self.point[4] + diffX, self.point[5] + diffY) - Gladdy.db[xConfig] = self.point[4] + diffX - Gladdy.db[yConfig] = self.point[5] + diffY - LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") - Gladdy:UpdateFrame() - end) - else - frame.mover:ClearAllPoints() - frame.mover:SetPoint(points[1], frame, points[2], xOffset or 0, yOffset or 0) - frame.mover:SetHeight(height or frame:GetHeight()) - frame.mover:SetWidth(width or frame:GetWidth()) - end - if self.frame and self.frame.testing then - frame.mover:Show() - else - frame.mover:Hide() - end -end - --------------------------- -- INIT @@ -310,7 +250,7 @@ function Gladdy:OnInitialize() self.dbi = LibStub("AceDB-3.0"):New("GladdyXZ", self.defaults) self.dbi.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged") self.dbi.RegisterCallback(self, "OnProfileCopied", "OnProfileChanged") - self.dbi.RegisterCallback(self, "OnProfileReset", "OnProfileChanged") + self.dbi.RegisterCallback(self, "OnProfileReset", "OnProfileReset") self.db = self.dbi.profile self.LSM = LibStub("LibSharedMedia-3.0") @@ -347,18 +287,32 @@ function Gladdy:OnInitialize() for _, module in self:IterModules() do self:Call(module, "Initialize") -- B.E > A.E :D end - self:DeleteUnknownOptions(self.db, self.defaults.profile) if Gladdy.db.hideBlizzard == "always" then Gladdy:BlizzArenaSetAlpha(0) end + if not self.db.newLayout then + self:ToggleFrame(3) + self:HideFrame() + end +end + +function Gladdy:OnProfileReset() + self.db = self.dbi.profile + Gladdy:Debug("INFO", "OnProfileReset") + self:HideFrame() + self:ToggleFrame(3) + Gladdy.options.args.lock.name = Gladdy.db.locked and L["Unlock frame"] or L["Lock frame"] + Gladdy.options.args.showMover.name = Gladdy.db.showMover and L["Hide Mover"] or L["Show Mover"] + LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") end function Gladdy:OnProfileChanged() self.db = self.dbi.profile - self:DeleteUnknownOptions(self.db, self.defaults.profile) - self:HideFrame() self:ToggleFrame(3) + Gladdy.options.args.lock.name = Gladdy.db.locked and L["Unlock frame"] or L["Lock frame"] + Gladdy.options.args.showMover.name = Gladdy.db.showMover and L["Hide Mover"] or L["Show Mover"] + LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") end function Gladdy:OnEnable() diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 0590c9c..81ff806 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -31,11 +31,9 @@ local BuffsDebuffs = Gladdy:NewModule("Buffs and Debuffs", nil, { buffsFontScale = 1, buffsFontColor = {r = 1, g = 1, b = 0, a = 1}, buffsDynamicColor = true, - buffsCooldownPos = "TOP", buffsCooldownGrowDirection = "RIGHT", buffsXOffset = 0, buffsYOffset = 0, - buffsBuffsCooldownPos = "BOTTOM", buffsBuffsCooldownGrowDirection = "RIGHT", buffsBuffsXOffset = 0, buffsBuffsYOffset = 0, @@ -51,7 +49,7 @@ local BuffsDebuffs = Gladdy:NewModule("Buffs and Debuffs", nil, { buffsBorderColorImmune = Gladdy:GetAuraTypeColor()["immune"], buffsBorderColorDisease = Gladdy:GetAuraTypeColor()["disease"], buffsBorderColorForm = Gladdy:GetAuraTypeColor()["form"], - buffsBorderColorAura = Gladdy:GetAuraTypeColor()["aura"] + buffsBorderColorAura = Gladdy:GetAuraTypeColor()["aura"], }) local spellSchoolToOptionValueTable @@ -233,18 +231,15 @@ end --------------------------- function BuffsDebuffs:CreateFrame(unit) - local verticalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding local debuffFrame = CreateFrame("Frame", "GladdyDebuffs" .. unit, Gladdy.buttons[unit]) debuffFrame:SetMovable(true) debuffFrame:SetHeight(Gladdy.db.buffsIconSize) debuffFrame:SetWidth(1) - debuffFrame:SetPoint("BOTTOMLEFT", Gladdy.buttons[unit].healthBar, "TOPLEFT", 0, verticalMargin) debuffFrame.unit = unit local buffFrame = CreateFrame("Frame", "GladdyBuffs" .. unit, Gladdy.buttons[unit]) buffFrame:SetMovable(true) buffFrame:SetHeight(Gladdy.db.buffsIconSize) buffFrame:SetWidth(1) - buffFrame:SetPoint("BOTTOMLEFT", Gladdy.buttons[unit].healthBar, "TOPLEFT", 0, verticalMargin) buffFrame.unit = unit self.frames[unit] = {} self.frames[unit].buffFrame = buffFrame @@ -285,156 +280,30 @@ local function styleIcon(aura, auraType) end function BuffsDebuffs:UpdateFrame(unit) - self.frames[unit].debuffFrame:SetHeight(Gladdy.db.buffsIconSize) - self.frames[unit].debuffFrame:ClearAllPoints() - --DEBUFFS - local powerBarHeight = Gladdy.db.powerBarEnabled and (Gladdy.db.powerBarHeight + 1) or 0 - local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) - local verticalMargin = -(Gladdy.db.powerBarHeight)/2 - if Gladdy.db.buffsCooldownPos == "TOP" then - verticalMargin = horizontalMargin + 1 - if Gladdy.db.cooldownYPos == "TOP" and Gladdy.db.cooldown then - verticalMargin = verticalMargin + Gladdy.db.cooldownSize - end - if Gladdy.db.buffsCooldownGrowDirection == "LEFT" then - self.frames[unit].debuffFrame:SetPoint("BOTTOMLEFT", Gladdy.buttons[unit].healthBar, "TOPRIGHT", Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset + verticalMargin) - else - self.frames[unit].debuffFrame:SetPoint("BOTTOMRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset + verticalMargin) - end - elseif Gladdy.db.buffsCooldownPos == "BOTTOM" then - verticalMargin = horizontalMargin + 1 - if Gladdy.db.cooldownYPos == "BOTTOM" and Gladdy.db.cooldown then - verticalMargin = verticalMargin + Gladdy.db.cooldownSize - end - if Gladdy.db.buffsCooldownGrowDirection == "LEFT" then - self.frames[unit].debuffFrame:SetPoint("TOPLEFT", Gladdy.buttons[unit].healthBar, "BOTTOMRIGHT", Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset -verticalMargin - powerBarHeight) - else - self.frames[unit].debuffFrame:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "BOTTOMLEFT", Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset -verticalMargin - powerBarHeight) - end - elseif Gladdy.db.buffsCooldownPos == "LEFT" then - horizontalMargin = horizontalMargin - 1 + Gladdy.db.padding - local anchor = Gladdy:GetAnchor(unit, "LEFT") - if anchor == Gladdy.buttons[unit].healthBar then - self.frames[unit].debuffFrame:SetPoint("RIGHT", anchor, "LEFT", -horizontalMargin + Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset) - else - self.frames[unit].debuffFrame:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding + Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset) - end - - elseif Gladdy.db.buffsCooldownPos == "RIGHT" then - horizontalMargin = horizontalMargin - 1 + Gladdy.db.padding - local anchor = Gladdy:GetAnchor(unit, "RIGHT") - if anchor == Gladdy.buttons[unit].healthBar then - self.frames[unit].debuffFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset) - else - self.frames[unit].debuffFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.buffsXOffset, Gladdy.db.buffsYOffset) - end - end + self.frames[unit].debuffFrame:SetHeight(Gladdy.db.buffsIconSize) + Gladdy:SetPosition(self.frames[unit].debuffFrame, unit, "buffsXOffset", "buffsYOffset", BuffsDebuffs:LegacySetPositionDebuffs(unit), BuffsDebuffs) if (unit == "arena1") then Gladdy:CreateMover(self.frames[unit].debuffFrame, "buffsXOffset", "buffsYOffset", L["Debuffs"], - Gladdy.db.buffsCooldownGrowDirection == "LEFT" and {"TOPRIGHT", "TOPRIGHT"} or {"TOPLEFT", "TOPLEFT"}, + {"TOPRIGHT", "TOPRIGHT"}, Gladdy.db.buffsIconSize * Gladdy.db.buffsWidthFactor, - Gladdy.db.buffsIconSize, Gladdy.db.buffsCooldownGrowDirection == "LEFT"and -1 or 1, 0) + Gladdy.db.buffsIconSize, 0, 0) + if not Gladdy.db.buffsEnabled then + self.frames[unit].debuffFrame.mover:Hide() + end end --BUFFS self.frames[unit].buffFrame:SetHeight(Gladdy.db.buffsBuffsIconSize) - self.frames[unit].buffFrame:ClearAllPoints() - horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) - verticalMargin = -(Gladdy.db.powerBarHeight)/2 - if Gladdy.db.buffsBuffsCooldownPos == "TOP" then - verticalMargin = horizontalMargin + 1 - if Gladdy.db.cooldownYPos == "TOP" and Gladdy.db.cooldown then - verticalMargin = verticalMargin + Gladdy.db.cooldownSize - end - if Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT" then - self.frames[unit].buffFrame:SetPoint("BOTTOMLEFT", Gladdy.buttons[unit].healthBar, "TOPRIGHT", Gladdy.db.buffsXOffset, Gladdy.db.buffsBuffsYOffset + verticalMargin) - else - self.frames[unit].buffFrame:SetPoint("BOTTOMRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", Gladdy.db.buffsXOffset, Gladdy.db.buffsBuffsYOffset + verticalMargin) - end - elseif Gladdy.db.buffsBuffsCooldownPos == "BOTTOM" then - verticalMargin = horizontalMargin + 1 - if Gladdy.db.cooldownYPos == "BOTTOM" and Gladdy.db.cooldown then - verticalMargin = verticalMargin + Gladdy.db.cooldownSize - end - if Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT" then - self.frames[unit].buffFrame:SetPoint("TOPLEFT", Gladdy.buttons[unit].healthBar, "BOTTOMRIGHT", Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset -verticalMargin - powerBarHeight) - else - self.frames[unit].buffFrame:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "BOTTOMLEFT", Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset -verticalMargin - powerBarHeight) - end - elseif Gladdy.db.buffsBuffsCooldownPos == "LEFT" then - horizontalMargin = horizontalMargin - 1 + Gladdy.db.padding - if (Gladdy.db.trinketPos == "LEFT" and Gladdy.db.trinketEnabled) then - horizontalMargin = horizontalMargin + (Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor) + Gladdy.db.padding - if (Gladdy.db.classIconPos == "LEFT") then - horizontalMargin = horizontalMargin + (Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) + Gladdy.db.padding - end - elseif (Gladdy.db.classIconPos == "LEFT") then - horizontalMargin = horizontalMargin + (Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) + Gladdy.db.padding - if (Gladdy.db.trinketPos == "LEFT" and Gladdy.db.trinketEnabled) then - horizontalMargin = horizontalMargin + (Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor) + Gladdy.db.padding - end - end - if (Gladdy.db.drCooldownPos == "LEFT" and Gladdy.db.drEnabled) then - verticalMargin = verticalMargin + Gladdy.db.drIconSize/2 + Gladdy.db.padding/2 - end - if (Gladdy.db.castBarPos == "LEFT") then - verticalMargin = verticalMargin - - (((Gladdy.db.castBarHeight < Gladdy.db.castBarIconSize) and Gladdy.db.castBarIconSize - or Gladdy.db.castBarHeight)/2 + Gladdy.db.padding/2) - end - if (Gladdy.db.cooldownYPos == "LEFT" and Gladdy.db.cooldown) then - verticalMargin = verticalMargin + (Gladdy.db.buffsBuffsIconSize/2 + Gladdy.db.padding/2) - end - --self.frames[unit].buffFrame:SetPoint("RIGHT", Gladdy.buttons[unit].healthBar, "LEFT", -horizontalMargin + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset + verticalMargin) - - local anchor = Gladdy:GetAnchor(unit, "LEFT") - horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) - 1 + Gladdy.db.padding - if anchor == Gladdy.buttons[unit].healthBar then - self.frames[unit].buffFrame:SetPoint("RIGHT", anchor, "LEFT", -horizontalMargin + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset) - else - self.frames[unit].buffFrame:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset) - end - - elseif Gladdy.db.buffsBuffsCooldownPos == "RIGHT" then - horizontalMargin = horizontalMargin - 1 + Gladdy.db.padding - if (Gladdy.db.trinketPos == "RIGHT" and Gladdy.db.trinketEnabled) then - horizontalMargin = horizontalMargin + (Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor) + Gladdy.db.padding - if (Gladdy.db.classIconPos == "RIGHT") then - horizontalMargin = horizontalMargin + (Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) + Gladdy.db.padding - end - elseif (Gladdy.db.classIconPos == "RIGHT") then - horizontalMargin = horizontalMargin + (Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) + Gladdy.db.padding - if (Gladdy.db.trinketPos == "RIGHT" and Gladdy.db.trinketEnabled) then - horizontalMargin = horizontalMargin + (Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor) + Gladdy.db.padding - end - end - if (Gladdy.db.drCooldownPos == "RIGHT" and Gladdy.db.drEnabled) then - verticalMargin = verticalMargin + Gladdy.db.drIconSize/2 + Gladdy.db.padding/2 - end - if (Gladdy.db.castBarPos == "RIGHT") then - verticalMargin = verticalMargin - - (((Gladdy.db.castBarHeight < Gladdy.db.castBarIconSize) and Gladdy.db.castBarIconSize - or Gladdy.db.castBarHeight)/2 + Gladdy.db.padding/2) - end - if (Gladdy.db.cooldownYPos == "RIGHT" and Gladdy.db.cooldown) then - verticalMargin = verticalMargin + (Gladdy.db.buffsBuffsIconSize/2 + Gladdy.db.padding/2) - end - --self.frames[unit].buffFrame:SetPoint("LEFT", Gladdy.buttons[unit].healthBar, "RIGHT", horizontalMargin + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset + verticalMargin) - - local anchor = Gladdy:GetAnchor(unit, "RIGHT") - horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) - 1 + Gladdy.db.padding - if anchor == Gladdy.buttons[unit].healthBar then - self.frames[unit].buffFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset) - else - self.frames[unit].buffFrame:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset) - end - end + Gladdy:SetPosition(self.frames[unit].buffFrame, unit, "buffsBuffsXOffset", "buffsBuffsYOffset", BuffsDebuffs:LegacySetPositionBuffs(unit), BuffsDebuffs) if (unit == "arena1") then Gladdy:CreateMover(self.frames[unit].buffFrame, "buffsBuffsXOffset", "buffsBuffsYOffset", L["Buffs"], - Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT" and {"TOPRIGHT", "TOPRIGHT"} or {"TOPLEFT", "TOPLEFT"}, + {"TOPRIGHT", "TOPRIGHT"}, Gladdy.db.buffsBuffsIconSize * Gladdy.db.buffsBuffsWidthFactor, - Gladdy.db.buffsBuffsIconSize, Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT"and -1 or 1, 0) + Gladdy.db.buffsBuffsIconSize, 0, 0) + if not Gladdy.db.buffsEnabled then + self.frames[unit].buffFrame.mover:Hide() + end end for i=1, #self.frames[unit].auras[AURA_TYPE_BUFF] do @@ -456,13 +325,8 @@ end function BuffsDebuffs:UpdateAurasOnUnit(unit) for i=1, #self.frames[unit].auras[AURA_TYPE_BUFF] do if i == 1 then - if Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT" then - self.frames[unit].auras[AURA_TYPE_BUFF][i]:ClearAllPoints() - self.frames[unit].auras[AURA_TYPE_BUFF][i]:SetPoint("RIGHT", self.frames[unit].buffFrame, "LEFT") - else - self.frames[unit].auras[AURA_TYPE_BUFF][i]:ClearAllPoints() - self.frames[unit].auras[AURA_TYPE_BUFF][i]:SetPoint("LEFT", self.frames[unit].buffFrame, "RIGHT") - end + self.frames[unit].auras[AURA_TYPE_BUFF][i]:ClearAllPoints() + self.frames[unit].auras[AURA_TYPE_BUFF][i]:SetPoint("RIGHT", self.frames[unit].buffFrame, "LEFT") else if Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT" then self.frames[unit].auras[AURA_TYPE_BUFF][i]:ClearAllPoints() @@ -475,13 +339,8 @@ function BuffsDebuffs:UpdateAurasOnUnit(unit) end for i=1, #self.frames[unit].auras[AURA_TYPE_DEBUFF] do if i == 1 then - if Gladdy.db.buffsCooldownGrowDirection == "LEFT" then - self.frames[unit].auras[AURA_TYPE_DEBUFF][i]:ClearAllPoints() - self.frames[unit].auras[AURA_TYPE_DEBUFF][i]:SetPoint("RIGHT", self.frames[unit].debuffFrame, "LEFT") - else - self.frames[unit].auras[AURA_TYPE_DEBUFF][i]:ClearAllPoints() - self.frames[unit].auras[AURA_TYPE_DEBUFF][i]:SetPoint("LEFT", self.frames[unit].debuffFrame, "RIGHT") - end + self.frames[unit].auras[AURA_TYPE_DEBUFF][i]:ClearAllPoints() + self.frames[unit].auras[AURA_TYPE_DEBUFF][i]:SetPoint("RIGHT", self.frames[unit].debuffFrame, "LEFT") else if Gladdy.db.buffsCooldownGrowDirection == "LEFT" then self.frames[unit].auras[AURA_TYPE_DEBUFF][i]:ClearAllPoints() @@ -602,36 +461,6 @@ end -- OPTIONS ------------ -local function option(params) - local defaults = { - get = function(info) - local key = info.arg or info[#info] - return Gladdy.dbi.profile[key] - end, - set = function(info, value) - local key = info.arg or info[#info] - Gladdy.dbi.profile[key] = value - if Gladdy.db.buffsCooldownPos == "LEFT" then - Gladdy.db.buffsCooldownGrowDirection = "LEFT" - elseif Gladdy.db.buffsCooldownPos == "RIGHT" then - Gladdy.db.buffsCooldownGrowDirection = "RIGHT" - end - if Gladdy.db.buffsBuffsCooldownPos == "LEFT" then - Gladdy.db.buffsBuffsCooldownGrowDirection = "LEFT" - elseif Gladdy.db.buffsBuffsCooldownPos == "RIGHT" then - Gladdy.db.buffsBuffsCooldownGrowDirection = "RIGHT" - end - Gladdy:UpdateFrame() - end, - } - - for k, v in pairs(params) do - defaults[k] = v - end - - return defaults -end - function BuffsDebuffs:GetOptions() return { headerBuffs = { @@ -714,18 +543,6 @@ function BuffsDebuffs:GetOptions() name = L["Position"], order = 5, }, - buffsBuffsCooldownPos = option({ - type = "select", - name = L["Aura Position"], - desc = L["Position of the aura icons"], - order = 21, - values = { - ["TOP"] = L["Top"], - ["BOTTOM"] = L["Bottom"], - ["LEFT"] = L["Left"], - ["RIGHT"] = L["Right"], - }, - }), buffsBuffsCooldownGrowDirection = Gladdy:option({ type = "select", name = L["Grow Direction"], @@ -836,18 +653,6 @@ function BuffsDebuffs:GetOptions() name = L["Position"], order = 5, }, - buffsCooldownPos = option({ - type = "select", - name = L["Aura Position"], - desc = L["Position of the aura icons"], - order = 21, - values = { - ["TOP"] = L["Top"], - ["BOTTOM"] = L["Bottom"], - ["LEFT"] = L["Left"], - ["RIGHT"] = L["Right"], - }, - }), buffsCooldownGrowDirection = Gladdy:option({ type = "select", name = L["Grow Direction"], @@ -1108,3 +913,168 @@ function BuffsDebuffs:GetOptions() } end +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function BuffsDebuffs:LegacySetPositionDebuffs(unit) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + self.frames[unit].debuffFrame:ClearAllPoints() + local powerBarHeight = Gladdy.db.powerBarEnabled and (Gladdy.db.powerBarHeight + 1) or 0 + local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + local verticalMargin = -(Gladdy.db.powerBarHeight)/2 + local offset = 0 + if (Gladdy.db.buffsCooldownGrowDirection == "RIGHT") then + offset = Gladdy.db.buffsIconSize * Gladdy.db.buffsWidthFactor + end + local pos = Gladdy.db.buffsCooldownPos + + if pos == "TOP" then + verticalMargin = horizontalMargin + 1 + if Gladdy.db.cooldownYPos == "TOP" and Gladdy.db.cooldown then + verticalMargin = verticalMargin + Gladdy.db.cooldownSize + end + if Gladdy.db.buffsCooldownGrowDirection == "LEFT" then + self.frames[unit].debuffFrame:SetPoint("BOTTOMLEFT", Gladdy.buttons[unit].healthBar, "TOPRIGHT", Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsYOffset + verticalMargin) + else + self.frames[unit].debuffFrame:SetPoint("BOTTOMRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsYOffset + verticalMargin) + end + elseif pos == "BOTTOM" then + verticalMargin = horizontalMargin + 1 + if Gladdy.db.cooldownYPos == "BOTTOM" and Gladdy.db.cooldown then + verticalMargin = verticalMargin + Gladdy.db.cooldownSize + end + if Gladdy.db.buffsCooldownGrowDirection == "LEFT" then + self.frames[unit].debuffFrame:SetPoint("TOPLEFT", Gladdy.buttons[unit].healthBar, "BOTTOMRIGHT", Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsYOffset -verticalMargin - powerBarHeight) + else + self.frames[unit].debuffFrame:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "BOTTOMLEFT", Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsYOffset -verticalMargin - powerBarHeight) + end + elseif pos == "LEFT" then + horizontalMargin = horizontalMargin - 1 + Gladdy.db.padding + local anchor = Gladdy:GetAnchor(unit, "LEFT") + if anchor == Gladdy.buttons[unit].healthBar then + self.frames[unit].debuffFrame:SetPoint("RIGHT", anchor, "LEFT", -horizontalMargin + Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsYOffset) + else + self.frames[unit].debuffFrame:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding + Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsYOffset) + end + elseif pos == "RIGHT" then + horizontalMargin = horizontalMargin - 1 + Gladdy.db.padding + local anchor = Gladdy:GetAnchor(unit, "RIGHT") + if anchor == Gladdy.buttons[unit].healthBar then + self.frames[unit].debuffFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsYOffset) + else + self.frames[unit].debuffFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsYOffset) + end + end + return Gladdy.db.newLayout +end + +function BuffsDebuffs:LegacySetPositionBuffs(unit) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + self.frames[unit].buffFrame:ClearAllPoints() + local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + local verticalMargin = -(Gladdy.db.powerBarHeight)/2 + local powerBarHeight = Gladdy.db.powerBarEnabled and (Gladdy.db.powerBarHeight + 1) or 0 + local offset = 0 + if (Gladdy.db.buffsBuffsCooldownGrowDirection == "RIGHT") then + offset = Gladdy.db.buffsBuffsIconSize * Gladdy.db.buffsBuffsWidthFactor + end + + local pos = Gladdy.db.buffsBuffsCooldownPos + + if pos == "TOP" then + verticalMargin = horizontalMargin + 1 + if Gladdy.db.cooldownYPos == "TOP" and Gladdy.db.cooldown then + verticalMargin = verticalMargin + Gladdy.db.cooldownSize + end + if Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT" then + self.frames[unit].buffFrame:SetPoint("BOTTOMLEFT", Gladdy.buttons[unit].healthBar, "TOPRIGHT", Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsBuffsYOffset + verticalMargin) + else + self.frames[unit].buffFrame:SetPoint("BOTTOMRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", Gladdy.db.buffsXOffset + offset, Gladdy.db.buffsBuffsYOffset + verticalMargin) + end + elseif pos == "BOTTOM" then + verticalMargin = horizontalMargin + 1 + if Gladdy.db.cooldownYPos == "BOTTOM" and Gladdy.db.cooldown then + verticalMargin = verticalMargin + Gladdy.db.cooldownSize + end + if Gladdy.db.buffsBuffsCooldownGrowDirection == "LEFT" then + self.frames[unit].buffFrame:SetPoint("TOPLEFT", Gladdy.buttons[unit].healthBar, "BOTTOMRIGHT", Gladdy.db.buffsBuffsXOffset + offset, Gladdy.db.buffsBuffsYOffset -verticalMargin - powerBarHeight) + else + self.frames[unit].buffFrame:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "BOTTOMLEFT", Gladdy.db.buffsBuffsXOffset + offset, Gladdy.db.buffsBuffsYOffset -verticalMargin - powerBarHeight) + end + elseif pos == "LEFT" then + horizontalMargin = horizontalMargin - 1 + Gladdy.db.padding + if (Gladdy.db.trinketPos == "LEFT" and Gladdy.db.trinketEnabled) then + horizontalMargin = horizontalMargin + (Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor) + Gladdy.db.padding + if (Gladdy.db.classIconPos == "LEFT") then + horizontalMargin = horizontalMargin + (Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) + Gladdy.db.padding + end + elseif (Gladdy.db.classIconPos == "LEFT") then + horizontalMargin = horizontalMargin + (Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) + Gladdy.db.padding + if (Gladdy.db.trinketPos == "LEFT" and Gladdy.db.trinketEnabled) then + horizontalMargin = horizontalMargin + (Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor) + Gladdy.db.padding + end + end + if (Gladdy.db.drCooldownPos == "LEFT" and Gladdy.db.drEnabled) then + verticalMargin = verticalMargin + Gladdy.db.drIconSize/2 + Gladdy.db.padding/2 + end + if (Gladdy.db.castBarPos == "LEFT") then + verticalMargin = verticalMargin - + (((Gladdy.db.castBarHeight < Gladdy.db.castBarIconSize) and Gladdy.db.castBarIconSize + or Gladdy.db.castBarHeight)/2 + Gladdy.db.padding/2) + end + if (Gladdy.db.cooldownYPos == "LEFT" and Gladdy.db.cooldown) then + verticalMargin = verticalMargin + (Gladdy.db.buffsBuffsIconSize/2 + Gladdy.db.padding/2) + end + --self.frames[unit].buffFrame:SetPoint("RIGHT", Gladdy.buttons[unit].healthBar, "LEFT", -horizontalMargin + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset + verticalMargin) + + local anchor = Gladdy:GetAnchor(unit, "LEFT") + horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) - 1 + Gladdy.db.padding + if anchor == Gladdy.buttons[unit].healthBar then + self.frames[unit].buffFrame:SetPoint("RIGHT", anchor, "LEFT", -horizontalMargin + Gladdy.db.buffsBuffsXOffset + offset, Gladdy.db.buffsBuffsYOffset) + else + self.frames[unit].buffFrame:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding + Gladdy.db.buffsBuffsXOffset + offset, Gladdy.db.buffsBuffsYOffset) + end + + elseif pos == "RIGHT" then + horizontalMargin = horizontalMargin - 1 + Gladdy.db.padding + if (Gladdy.db.trinketPos == "RIGHT" and Gladdy.db.trinketEnabled) then + horizontalMargin = horizontalMargin + (Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor) + Gladdy.db.padding + if (Gladdy.db.classIconPos == "RIGHT") then + horizontalMargin = horizontalMargin + (Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) + Gladdy.db.padding + end + elseif (Gladdy.db.classIconPos == "RIGHT") then + horizontalMargin = horizontalMargin + (Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) + Gladdy.db.padding + if (Gladdy.db.trinketPos == "RIGHT" and Gladdy.db.trinketEnabled) then + horizontalMargin = horizontalMargin + (Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor) + Gladdy.db.padding + end + end + if (Gladdy.db.drCooldownPos == "RIGHT" and Gladdy.db.drEnabled) then + verticalMargin = verticalMargin + Gladdy.db.drIconSize/2 + Gladdy.db.padding/2 + end + if (Gladdy.db.castBarPos == "RIGHT") then + verticalMargin = verticalMargin - + (((Gladdy.db.castBarHeight < Gladdy.db.castBarIconSize) and Gladdy.db.castBarIconSize + or Gladdy.db.castBarHeight)/2 + Gladdy.db.padding/2) + end + if (Gladdy.db.cooldownYPos == "RIGHT" and Gladdy.db.cooldown) then + verticalMargin = verticalMargin + (Gladdy.db.buffsBuffsIconSize/2 + Gladdy.db.padding/2) + end + --self.frames[unit].buffFrame:SetPoint("LEFT", Gladdy.buttons[unit].healthBar, "RIGHT", horizontalMargin + Gladdy.db.buffsBuffsXOffset, Gladdy.db.buffsBuffsYOffset + verticalMargin) + + local anchor = Gladdy:GetAnchor(unit, "RIGHT") + horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) - 1 + Gladdy.db.padding + if anchor == Gladdy.buttons[unit].healthBar then + self.frames[unit].buffFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.buffsBuffsXOffset + offset, Gladdy.db.buffsBuffsYOffset) + else + self.frames[unit].buffFrame:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + Gladdy.db.buffsBuffsXOffset + offset, Gladdy.db.buffsBuffsYOffset) + end + end + return Gladdy.db.newLayout +end \ No newline at end of file diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 4717563..1eb5b70 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -34,7 +34,6 @@ local Castbar = Gladdy:NewModule("Cast Bar", 70, { castBarBorderColor = { r = 0, g = 0, b = 0, a = 1 }, castBarFontColor = { r = 1, g = 1, b = 1, a = 1 }, castBarGuesses = true, - castBarPos = "LEFT", castBarXOffset = 0, castBarYOffset = 0, castBarIconPos = "LEFT", @@ -57,15 +56,17 @@ end --------------------------- function Castbar:CreateFrame(unit) - local castBar = CreateFrame("Frame", nil, Gladdy.buttons[unit], BackdropTemplateMixin and "BackdropTemplate") + local castBar = CreateFrame("Frame", nil, Gladdy.buttons[unit]) castBar:EnableMouse(false) castBar:SetMovable(true) castBar.unit = unit - castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), + castBar.backdrop = CreateFrame("Frame", nil, castBar, BackdropTemplateMixin and "BackdropTemplate") + castBar.backdrop:SetAllPoints(castBar) + castBar.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) - castBar:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) - castBar:SetFrameLevel(1) + castBar.backdrop:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) + castBar.backdrop:SetFrameLevel(1) castBar.bar = CreateFrame("StatusBar", nil, castBar) castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) @@ -130,9 +131,9 @@ function Castbar:UpdateFrame(unit) castBar:SetWidth(Gladdy.db.castBarWidth) castBar:SetHeight(Gladdy.db.castBarHeight) - castBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), + castBar.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) - castBar:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) + castBar.backdrop:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) castBar.bar:ClearAllPoints() @@ -165,24 +166,7 @@ function Castbar:UpdateFrame(unit) leftMargin = Gladdy.db.castBarIconSize + 1 end - castBar:ClearAllPoints() - local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding - if (Gladdy.db.castBarPos == "LEFT") then - local anchor = Gladdy:GetAnchor(unit, "LEFT") - if anchor == Gladdy.buttons[unit].healthBar then - castBar:SetPoint("RIGHT", anchor, "LEFT", -horizontalMargin - leftMargin + Gladdy.db.castBarXOffset, Gladdy.db.castBarYOffset) - else - castBar:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding - leftMargin + Gladdy.db.castBarXOffset, Gladdy.db.castBarYOffset) - end - end - if (Gladdy.db.castBarPos == "RIGHT") then - local anchor = Gladdy:GetAnchor(unit, "RIGHT") - if anchor == Gladdy.buttons[unit].healthBar then - castBar:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + rightMargin + Gladdy.db.castBarXOffset, Gladdy.db.castBarYOffset) - else - castBar:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + rightMargin + Gladdy.db.castBarXOffset, Gladdy.db.castBarYOffset) - end - end + Gladdy:SetPosition(castBar, unit, "castBarXOffset", "castBarYOffset", Castbar:LegacySetPosition(castBar, unit, leftMargin, rightMargin), Castbar) castBar.spellText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize) castBar.spellText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) @@ -410,7 +394,10 @@ function Castbar:CAST_START(unit, spell, icon, value, maxValue, test) castBar.spellText:SetText(spell) castBar.timeText:SetText(maxValue) castBar.bg:Show() - castBar:Show() + castBar.backdrop:Show() + if Gladdy.db.castBarSparkEnabled then + castBar.spark:Show() + end castBar:SetAlpha(1) castBar.icon:Show() end @@ -430,7 +417,8 @@ function Castbar:CAST_STOP(unit, ...) castBar.timeText:SetText("") castBar.bar:SetValue(0) castBar.bg:Hide() - castBar:Hide() + castBar.backdrop:Hide() + castBar.spark:Hide() castBar.icon:Hide() else castBar.bar:SetStatusBarColor(...) @@ -771,15 +759,6 @@ function Castbar:GetOptions() name = L["Position"], order = 1, }, - castBarPos = option({ - type = "select", - name = L["Castbar position"], - order = 2, - values = { - ["LEFT"] = L["Left"], - ["RIGHT"] = L["Right"], - }, - }), castBarIconPos = option( { type = "select", name = L["Icon position"], @@ -817,4 +796,35 @@ function Castbar:GetOptions() }, }, } +end + +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function Castbar:LegacySetPosition(castBar, unit, leftMargin, rightMargin) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + castBar:ClearAllPoints() + local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding + if (Gladdy.db.castBarPos == "LEFT") then + local anchor = Gladdy:GetAnchor(unit, "LEFT") + if anchor == Gladdy.buttons[unit].healthBar then + castBar:SetPoint("RIGHT", anchor, "LEFT", -horizontalMargin - leftMargin + Gladdy.db.castBarXOffset, Gladdy.db.castBarYOffset) + else + castBar:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding - leftMargin + Gladdy.db.castBarXOffset, Gladdy.db.castBarYOffset) + end + end + if (Gladdy.db.castBarPos == "RIGHT") then + local anchor = Gladdy:GetAnchor(unit, "RIGHT") + if anchor == Gladdy.buttons[unit].healthBar then + castBar:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + rightMargin + Gladdy.db.castBarXOffset, Gladdy.db.castBarYOffset) + else + castBar:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + rightMargin + Gladdy.db.castBarXOffset, Gladdy.db.castBarYOffset) + end + end + return Gladdy.db.newLayout end \ No newline at end of file diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index 839b52f..8890d5b 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -4,13 +4,14 @@ local Gladdy = LibStub("Gladdy") local CreateFrame = CreateFrame local GetSpellInfo = GetSpellInfo local L = Gladdy.L -local Classicon = Gladdy:NewModule("Class Icon", 80, { - classIconPos = "LEFT", +local Classicon = Gladdy:NewModule("Class Icon", 81, { classIconSize = 60 + 20 + 1, classIconWidthFactor = 0.9, classIconBorderStyle = "Interface\\AddOns\\Gladdy\\Images\\Border_rounded_blp", classIconBorderColor = { r = 0, g = 0, b = 0, a = 1 }, classIconSpecIcon = false, + classIconXOffset = 0, + classIconYOffset = 0, }) local classIconPath = "Interface\\Addons\\Gladdy\\Images\\Classes\\" @@ -99,13 +100,6 @@ function Classicon:CreateFrame(unit) classIcon:SetFrameStrata("MEDIUM") classIcon:SetFrameLevel(2) - classIcon:ClearAllPoints() - if (Gladdy.db.classIconPos == "RIGHT") then - classIcon:SetPoint("TOPLEFT", Gladdy.buttons[unit].healthBar, "TOPRIGHT", 2, 2) - else - classIcon:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", -2, 2) - end - Gladdy.buttons[unit].classIcon = classIcon self.frames[unit] = classIcon end @@ -119,12 +113,15 @@ function Classicon:UpdateFrame(unit) classIcon:SetWidth(Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) classIcon:SetHeight(Gladdy.db.classIconSize) - classIcon:ClearAllPoints() - local margin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding - if (Gladdy.db.classIconPos == "LEFT") then - classIcon:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", -margin, 0) - else - classIcon:SetPoint("TOPLEFT", Gladdy.buttons[unit], "TOPRIGHT", margin, 0) + Gladdy:SetPosition(classIcon, unit, "classIconXOffset", "classIconYOffset", Classicon:LegacySetPosition(classIcon, unit), Classicon) + + if (unit == "arena1") then + Gladdy:CreateMover(classIcon, "classIconXOffset", "classIconYOffset", L["Class Icon"], + {"TOPLEFT", "TOPLEFT"}, + Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor, + Gladdy.db.classIconSize, + 0, + 0) end classIcon.texture:ClearAllPoints() @@ -278,4 +275,23 @@ function Classicon:GetOptions() }, }, } +end + +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function Classicon:LegacySetPosition(classIcon, unit) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + classIcon:ClearAllPoints() + local margin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding + if (Gladdy.db.classIconPos == "LEFT") then + classIcon:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", -margin, 0) + else + classIcon:SetPoint("TOPLEFT", Gladdy.buttons[unit], "TOPRIGHT", margin, 0) + end end \ No newline at end of file diff --git a/Modules/CombatIndicator.lua b/Modules/CombatIndicator.lua index 91447ad..73a016d 100644 --- a/Modules/CombatIndicator.lua +++ b/Modules/CombatIndicator.lua @@ -1,7 +1,6 @@ local select = select local UnitExists, UnitAffectingCombat, GetSpellInfo = UnitExists, UnitAffectingCombat, GetSpellInfo local CreateFrame = CreateFrame -local ANCHORS = { ["LEFT"] = "RIGHT", ["RIGHT"] = "LEFT", ["BOTTOM"] = "TOP", ["TOP"] = "BOTTOM"} local Gladdy = LibStub("Gladdy") local L = Gladdy.L @@ -11,8 +10,6 @@ local CombatIndicator = Gladdy:NewModule("Combat Indicator", nil, { ciSize = 20, ciAlpha = 1, ciWidthFactor = 1, - ciAnchor = "healthBar", - ciPos = "TOP", ciXOffset = 0, ciYOffset = -31, ciBorderStyle = "Interface\\AddOns\\Gladdy\\Images\\Border_rounded_blp", @@ -68,8 +65,7 @@ function CombatIndicator:UpdateFrame(unit) ciFrame.border:SetTexture(Gladdy.db.ciBorderStyle) ciFrame.border:SetVertexColor(Gladdy.db.ciBorderColor.r, Gladdy.db.ciBorderColor.g, Gladdy.db.ciBorderColor.b, Gladdy.db.ciBorderColor.a) - ciFrame:ClearAllPoints() - ciFrame:SetPoint(ANCHORS[Gladdy.db.ciPos], Gladdy.buttons[unit][Gladdy.db.ciAnchor], Gladdy.db.ciPos, Gladdy.db.ciXOffset, Gladdy.db.ciYOffset) + Gladdy:SetPosition(ciFrame, unit, "ciXOffset", "ciYOffset", CombatIndicator:LegacySetPosition(ciFrame, unit), CombatIndicator) ciFrame:SetAlpha(Gladdy.db.ciAlpha) @@ -177,30 +173,6 @@ function CombatIndicator:GetOptions() name = L["Position"], order = 4, }, - ciAnchor = Gladdy:option({ - type = "select", - name = L["Anchor"], - desc = L["This changes the anchor of the ci icon"], - order = 20, - values = { - ["trinket"] = L["Trinket"], - ["classIcon"] = L["Class Icon"], - ["healthBar"] = L["Health Bar"], - ["powerBar"] = L["Power Bar"], - }, - }), - ciPos = Gladdy:option({ - type = "select", - name = L["Position"], - desc = L["This changes position relative to its anchor of the ci icon"], - order = 21, - values = { - ["LEFT"] = L["Left"], - ["RIGHT"] = L["Right"], - ["TOP"] = L["Top"], - ["BOTTOM"] = L["Bottom"], - }, - }), ciXOffset = Gladdy:option({ type = "range", name = L["Horizontal offset"], @@ -249,4 +221,24 @@ function CombatIndicator:GetOptions() }, }, } +end + +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function CombatIndicator:LegacySetPosition(ciFrame, unit) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + -- LEGACY options + local ANCHORS = { ["LEFT"] = "RIGHT", ["RIGHT"] = "LEFT", ["BOTTOM"] = "TOP", ["TOP"] = "BOTTOM"} + local ciAnchor = Gladdy.db.ciAnchor or Gladdy.legacy.ciAnchor + local ciPos = Gladdy.db.ciPos + + ciFrame:ClearAllPoints() + ciFrame:SetPoint(ANCHORS[ciPos], Gladdy.buttons[unit][ciAnchor], ciPos, Gladdy.db.ciXOffset, Gladdy.db.ciYOffset) + return Gladdy.db.newLayout end \ No newline at end of file diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 0ce1594..f5803da 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -1,4 +1,4 @@ -local type, pairs, ceil, tonumber, mod, tostring, upper, select = type, pairs, ceil, tonumber, mod, tostring, string.upper, select +local type, pairs, ipairs, ceil, tonumber, mod, tostring, upper, select = type, pairs, ipairs, ceil, tonumber, mod, tostring, string.upper, select local GetTime = GetTime local CreateFrame = CreateFrame local RACE_ICON_TCOORDS = { @@ -54,8 +54,8 @@ local Cooldowns = Gladdy:NewModule("Cooldowns", nil, { cooldownFontScale = 1, cooldownFontColor = { r = 1, g = 1, b = 0, a = 1 }, cooldown = true, - cooldownYPos = "TOP", - cooldownXPos = "LEFT", + cooldownYGrowDirection = "UP", + cooldownXGrowDirection = "RIGHT", cooldownYOffset = 0, cooldownXOffset = 0, cooldownSize = 30, @@ -66,7 +66,7 @@ local Cooldowns = Gladdy:NewModule("Cooldowns", nil, { cooldownBorderColor = { r = 1, g = 1, b = 1, a = 1 }, cooldownDisableCircle = false, cooldownCooldownAlpha = 1, - cooldownCooldowns = getDefaultCooldown() + cooldownCooldowns = getDefaultCooldown(), }) function Cooldowns:Initialize() @@ -134,42 +134,15 @@ function Cooldowns:UpdateFrame(unit) local button = Gladdy.buttons[unit] -- Cooldown frame if (Gladdy.db.cooldown) then - button.spellCooldownFrame:ClearAllPoints() - local powerBarHeight = Gladdy.db.powerBarEnabled and (Gladdy.db.powerBarHeight + 1) or 0 - local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) - if Gladdy.db.cooldownYPos == "TOP" then - if Gladdy.db.cooldownXPos == "RIGHT" then - button.spellCooldownFrame:SetPoint("BOTTOMRIGHT", button.healthBar, "TOPRIGHT", Gladdy.db.cooldownXOffset, horizontalMargin + Gladdy.db.cooldownYOffset) - else - button.spellCooldownFrame:SetPoint("BOTTOMLEFT", button.healthBar, "TOPLEFT", Gladdy.db.cooldownXOffset, horizontalMargin + Gladdy.db.cooldownYOffset) - end - elseif Gladdy.db.cooldownYPos == "BOTTOM" then - if Gladdy.db.cooldownXPos == "RIGHT" then - button.spellCooldownFrame:SetPoint("TOPRIGHT", button.healthBar, "BOTTOMRIGHT", Gladdy.db.cooldownXOffset, -horizontalMargin + Gladdy.db.cooldownYOffset - powerBarHeight) - else - button.spellCooldownFrame:SetPoint("TOPLEFT", button.healthBar, "BOTTOMLEFT", Gladdy.db.cooldownXOffset, -horizontalMargin + Gladdy.db.cooldownYOffset - powerBarHeight) - end - elseif Gladdy.db.cooldownYPos == "LEFT" then - local anchor = Gladdy:GetAnchor(unit, "LEFT") - if anchor == Gladdy.buttons[unit].healthBar then - button.spellCooldownFrame:SetPoint("RIGHT", anchor, "LEFT", -(horizontalMargin + Gladdy.db.padding) + Gladdy.db.cooldownXOffset, Gladdy.db.cooldownYOffset) - else - button.spellCooldownFrame:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding + Gladdy.db.cooldownXOffset, Gladdy.db.cooldownYOffset) - end - elseif Gladdy.db.cooldownYPos == "RIGHT" then - local anchor = Gladdy:GetAnchor(unit, "RIGHT") - if anchor == Gladdy.buttons[unit].healthBar then - button.spellCooldownFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.padding + Gladdy.db.cooldownXOffset, Gladdy.db.cooldownYOffset) - else - button.spellCooldownFrame:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + Gladdy.db.cooldownXOffset, Gladdy.db.cooldownYOffset) - end - end button.spellCooldownFrame:SetHeight(Gladdy.db.cooldownSize) button.spellCooldownFrame:SetWidth(1) button.spellCooldownFrame:Show() + + Gladdy:SetPosition(button.spellCooldownFrame, unit, "cooldownXOffset", "cooldownYOffset", Cooldowns:LegacySetPosition(button, unit), Cooldowns) + if (unit == "arena1") then - Gladdy:CreateMover(button.spellCooldownFrame, "cooldownXOffset", "cooldownYOffset", L["Cooldown"], - Gladdy.db.cooldownXPos == "RIGHT" and {"TOPRIGHT", "TOPRIGHT"} or {"TOPLEFT", "TOPLEFT"}, + Gladdy:CreateMover(button.spellCooldownFrame,"cooldownXOffset", "cooldownYOffset", L["Cooldown"], + {"TOPLEFT", "TOPLEFT"}, Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor, Gladdy.db.cooldownSize) end -- Update each cooldown icon @@ -181,11 +154,11 @@ function Cooldowns:UpdateFrame(unit) icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) icon:ClearAllPoints() - if (Gladdy.db.cooldownXPos == "RIGHT") then + if (Gladdy.db.cooldownXGrowDirection == "LEFT") then if (j == 1) then - icon:SetPoint("RIGHT", button.spellCooldownFrame, "RIGHT", 0, 0) + icon:SetPoint("LEFT", button.spellCooldownFrame, "LEFT", 0, 0) elseif (mod(j-1,Gladdy.db.cooldownMaxIconsPerLine) == 0) then - if (Gladdy.db.cooldownYPos == "BOTTOM" or Gladdy.db.cooldownYPos == "LEFT" or Gladdy.db.cooldownYPos == "RIGHT") then + if (Gladdy.db.cooldownYGrowDirection == "DOWN") then icon:SetPoint("TOP", button.spellCooldownFrame["icon" .. o], "BOTTOM", 0, -Gladdy.db.cooldownIconPadding) else icon:SetPoint("BOTTOM", button.spellCooldownFrame["icon" .. o], "TOP", 0, Gladdy.db.cooldownIconPadding) @@ -195,11 +168,11 @@ function Cooldowns:UpdateFrame(unit) icon:SetPoint("RIGHT", button.spellCooldownFrame["icon" .. j - 1], "LEFT", -Gladdy.db.cooldownIconPadding, 0) end end - if (Gladdy.db.cooldownXPos == "LEFT") then + if (Gladdy.db.cooldownXGrowDirection == "RIGHT") then if (j == 1) then icon:SetPoint("LEFT", button.spellCooldownFrame, "LEFT", 0, 0) elseif (mod(j-1,Gladdy.db.cooldownMaxIconsPerLine) == 0) then - if (Gladdy.db.cooldownYPos == "BOTTOM" or Gladdy.db.cooldownYPos == "LEFT" or Gladdy.db.cooldownYPos == "RIGHT") then + if (Gladdy.db.cooldownYGrowDirection == "DOWN") then icon:SetPoint("TOP", button.spellCooldownFrame["icon" .. o], "BOTTOM", 0, -Gladdy.db.cooldownIconPadding) else icon:SetPoint("BOTTOM", button.spellCooldownFrame["icon" .. o], "TOP", 0, Gladdy.db.cooldownIconPadding) @@ -561,31 +534,6 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId, expirationTimeInSecond end ]] end -local function option(params) - local defaults = { - get = function(info) - local key = info.arg or info[#info] - return Gladdy.dbi.profile[key] - end, - set = function(info, value) - local key = info.arg or info[#info] - Gladdy.dbi.profile[key] = value - if Gladdy.db.cooldownYPos == "LEFT" then - Gladdy.db.cooldownXPos = "RIGHT" - elseif Gladdy.db.cooldownYPos == "RIGHT" then - Gladdy.db.cooldownXPos = "LEFT" - end - Gladdy:UpdateFrame() - end, - } - - for k, v in pairs(params) do - defaults[k] = v - end - - return defaults -end - function Cooldowns:GetOptions() return { headerCooldown = { @@ -644,15 +592,6 @@ function Cooldowns:GetOptions() step = 0.1, width = "full", }), - cooldownMaxIconsPerLine = Gladdy:option({ - type = "range", - name = L["Max Icons per row"], - order = 7, - min = 3, - max = 14, - step = 1, - width = "full", - }), }, }, cooldown = { @@ -745,37 +684,44 @@ function Cooldowns:GetOptions() name = L["Position"], order = 2, }, - cooldownYPos = option({ + cooldownYGrowDirection = Gladdy:option({ type = "select", - name = L["Anchor"], - desc = L["Anchor of the cooldown icons"], + name = L["Vertical Grow Direction"], + desc = L["Vertical Grow Direction of the cooldown icons"], order = 3, values = { - ["TOP"] = L["Top"], - ["BOTTOM"] = L["Bottom"], + ["UP"] = L["Up"], + ["DOWN"] = L["Down"], + }, + }), + cooldownXGrowDirection = Gladdy:option({ + type = "select", + name = L["Horizontal Grow Direction"], + desc = L["Horizontal Grow Direction of the cooldown icons"], + order = 4, + values = { ["LEFT"] = L["Left"], ["RIGHT"] = L["Right"], }, }), - cooldownXPos = Gladdy:option({ - type = "select", - name = L["Grow Direction"], - desc = L["Grow Direction of the cooldown icons"], - order = 4, - values = { - ["LEFT"] = L["Right"], - ["RIGHT"] = L["Left"], - }, + cooldownMaxIconsPerLine = Gladdy:option({ + type = "range", + name = L["Max Icons per row"], + order = 5, + min = 3, + max = 14, + step = 1, + width = "full", }), headerOffset = { type = "header", name = L["Offset"], - order = 5, + order = 10, }, cooldownXOffset = Gladdy:option({ type = "range", name = L["Horizontal offset"], - order = 6, + order = 11, min = -400, max = 400, step = 0.1, @@ -784,7 +730,7 @@ function Cooldowns:GetOptions() cooldownYOffset = Gladdy:option({ type = "range", name = L["Vertical offset"], - order = 7, + order = 12, min = -400, max = 400, step = 0.1, @@ -913,4 +859,67 @@ function Gladdy:UpdateTestCooldowns(i) Cooldowns:CooldownUsed(unit, button.race, spellID) end end +end + +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function Cooldowns:LegacySetPosition(button, unit) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + button.spellCooldownFrame:ClearAllPoints() + local powerBarHeight = Gladdy.db.powerBarEnabled and (Gladdy.db.powerBarHeight + 1) or 0 + local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + + local offset = 0 + if (Gladdy.db.cooldownXPos == "RIGHT") then + offset = -(Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor) + end + + if Gladdy.db.cooldownYPos == "TOP" then + Gladdy.db.cooldownYGrowDirection = "UP" + if Gladdy.db.cooldownXPos == "RIGHT" then + Gladdy.db.cooldownXGrowDirection = "LEFT" + button.spellCooldownFrame:SetPoint("BOTTOMRIGHT", button.healthBar, "TOPRIGHT", Gladdy.db.cooldownXOffset + offset, horizontalMargin + Gladdy.db.cooldownYOffset) + else + Gladdy.db.cooldownXGrowDirection = "RIGHT" + button.spellCooldownFrame:SetPoint("BOTTOMLEFT", button.healthBar, "TOPLEFT", Gladdy.db.cooldownXOffset + offset, horizontalMargin + Gladdy.db.cooldownYOffset) + end + elseif Gladdy.db.cooldownYPos == "BOTTOM" then + Gladdy.db.cooldownYGrowDirection = "DOWN" + if Gladdy.db.cooldownXPos == "RIGHT" then + Gladdy.db.cooldownXGrowDirection = "LEFT" + button.spellCooldownFrame:SetPoint("TOPRIGHT", button.healthBar, "BOTTOMRIGHT", Gladdy.db.cooldownXOffset + offset, -horizontalMargin + Gladdy.db.cooldownYOffset - powerBarHeight) + else + Gladdy.db.cooldownXGrowDirection = "RIGHT" + button.spellCooldownFrame:SetPoint("TOPLEFT", button.healthBar, "BOTTOMLEFT", Gladdy.db.cooldownXOffset + offset, -horizontalMargin + Gladdy.db.cooldownYOffset - powerBarHeight) + end + elseif Gladdy.db.cooldownYPos == "LEFT" then + Gladdy.db.cooldownYGrowDirection = "DOWN" + local anchor = Gladdy:GetAnchor(unit, "LEFT") + if anchor == Gladdy.buttons[unit].healthBar then + Gladdy.db.cooldownXGrowDirection = "LEFT" + button.spellCooldownFrame:SetPoint("RIGHT", anchor, "LEFT", -(horizontalMargin + Gladdy.db.padding) + Gladdy.db.cooldownXOffset + offset, Gladdy.db.cooldownYOffset) + else + Gladdy.db.cooldownXGrowDirection = "LEFT" + button.spellCooldownFrame:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding + Gladdy.db.cooldownXOffset + offset, Gladdy.db.cooldownYOffset) + end + elseif Gladdy.db.cooldownYPos == "RIGHT" then + Gladdy.db.cooldownYGrowDirection = "DOWN" + local anchor = Gladdy:GetAnchor(unit, "RIGHT") + if anchor == Gladdy.buttons[unit].healthBar then + Gladdy.db.cooldownXGrowDirection = "RIGHT" + button.spellCooldownFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.padding + Gladdy.db.cooldownXOffset + offset, Gladdy.db.cooldownYOffset) + else + Gladdy.db.cooldownXGrowDirection = "RIGHT" + button.spellCooldownFrame:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + Gladdy.db.cooldownXOffset + offset, Gladdy.db.cooldownYOffset) + end + end + LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") + + return Gladdy.db.newLayout end \ No newline at end of file diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 069efb0..5c3acd9 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -30,7 +30,7 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { drFont = "DorisPP", drFontColor = { r = 1, g = 1, b = 0, a = 1 }, drFontScale = 1, - drCooldownPos = "RIGHT", + drGrowDirection = "RIGHT", drXOffset = 0, drYOffset = 0, drIconSize = 36, @@ -49,7 +49,7 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { drLevelTextFontScale = 1, drWidthFactor = 1, drCategories = defaultCategories(), - drDuration = 18 + drDuration = 18, }) local function getDiminishColor(dr) @@ -179,34 +179,18 @@ function Diminishings:UpdateFrame(unit) drFrame:Show() end - drFrame:ClearAllPoints() - local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding - if (Gladdy.db.drCooldownPos == "LEFT") then - local anchor = Gladdy:GetAnchor(unit, "LEFT") - if anchor == Gladdy.buttons[unit].healthBar then - drFrame:SetPoint("RIGHT", anchor, "LEFT", -horizontalMargin + Gladdy.db.drXOffset, Gladdy.db.drYOffset) - else - drFrame:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding + Gladdy.db.drXOffset, Gladdy.db.drYOffset) - end - end - if (Gladdy.db.drCooldownPos == "RIGHT") then - local anchor = Gladdy:GetAnchor(unit, "RIGHT") - if anchor == Gladdy.buttons[unit].healthBar then - drFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.drXOffset, Gladdy.db.drYOffset) - else - drFrame:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + Gladdy.db.drXOffset, Gladdy.db.drYOffset) - end - end - - drFrame:SetWidth(Gladdy.db.drIconSize * 16) + drFrame:SetWidth(Gladdy.db.drIconSize) drFrame:SetHeight(Gladdy.db.drIconSize) + + Gladdy:SetPosition(drFrame, unit, "drXOffset", "drYOffset", Diminishings:LegacySetPosition(drFrame, unit), Diminishings) + if (unit == "arena1") then - Gladdy:CreateMover(drFrame, "drXOffset", "drYOffset", L["Diminishings"], - Gladdy.db.drCooldownPos == "RIGHT" and {"TOPLEFT", "TOPLEFT"} or {"TOPRIGHT", "TOPRIGHT"}, --point - Gladdy.db.drIconSize * Gladdy.db.drWidthFactor, -- width + Gladdy:CreateMover(drFrame,"drXOffset", "drYOffset", L["Diminishings"], + Gladdy.db.drGrowDirection == "RIGHT" and {"TOPLEFT", "TOPLEFT"} or {"TOPRIGHT", "TOPRIGHT"}, + Gladdy.db.drIconSize * Gladdy.db.drWidthFactor, Gladdy.db.drIconSize, - 0, --xoffset - 0) --yoffset + 0, + 0) end for i = 1, 16 do @@ -245,15 +229,15 @@ function Diminishings:UpdateFrame(unit) end icon:ClearAllPoints() - if (Gladdy.db.drCooldownPos == "LEFT") then + if (Gladdy.db.drGrowDirection == "LEFT") then if (i == 1) then - icon:SetPoint("TOPRIGHT") + icon:SetPoint("TOPRIGHT", drFrame, "TOPRIGHT") else icon:SetPoint("RIGHT", drFrame["icon" .. (i - 1)], "LEFT", -Gladdy.db.drIconPadding, 0) end else if (i == 1) then - icon:SetPoint("TOPLEFT") + icon:SetPoint("TOPLEFT", drFrame, "TOPLEFT") else icon:SetPoint("LEFT", drFrame["icon" .. (i - 1)], "RIGHT", Gladdy.db.drIconPadding, 0) end @@ -383,13 +367,15 @@ function Diminishings:Positionate(unit) if (icon.active) then icon:ClearAllPoints() - if (Gladdy.db.drCooldownPos == "LEFT") then + if (Gladdy.db.newLayout and Gladdy.db.drGrowDirection == "LEFT" + or not Gladdy.db.newLayout and Gladdy.db.drCooldownPos == "LEFT") then if (not lastIcon) then icon:SetPoint("TOPRIGHT") else icon:SetPoint("RIGHT", lastIcon, "LEFT", -Gladdy.db.drIconPadding, 0) end - else + elseif (Gladdy.db.newLayout and Gladdy.db.drGrowDirection == "RIGHT" + or not Gladdy.db.newLayout and Gladdy.db.drCooldownPos == "RIGHT") then if (not lastIcon) then icon:SetPoint("TOPLEFT") else @@ -562,21 +548,16 @@ function Diminishings:GetOptions() name = L["Position"], order = 20, }, - drCooldownPos = Gladdy:option({ + drGrowDirection = Gladdy:option({ type = "select", - name = L["DR Cooldown position"], - desc = L["Position of the cooldown icons"], + name = L["DR Grow Direction"], + desc = L["Grow Direction of the dr icons"], order = 21, values = { ["LEFT"] = L["Left"], ["RIGHT"] = L["Right"], }, }), - headerOffset = { - type = "header", - name = L["Offset"], - order = 22, - }, drXOffset = Gladdy:option({ type = "range", name = L["Horizontal offset"], @@ -791,3 +772,36 @@ function Diminishings:GetDRIcons(category) end return icons end + +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function Diminishings:LegacySetPosition(drFrame, unit) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + drFrame:ClearAllPoints() + local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding + if (Gladdy.db.drCooldownPos == "LEFT") then + Gladdy.db.drGrowDirection = "LEFT" + local anchor = Gladdy:GetAnchor(unit, "LEFT") + if anchor == Gladdy.buttons[unit].healthBar then + drFrame:SetPoint("RIGHT", anchor, "LEFT", -horizontalMargin + Gladdy.db.drXOffset, Gladdy.db.drYOffset) + else + drFrame:SetPoint("RIGHT", anchor, "LEFT", -Gladdy.db.padding + Gladdy.db.drXOffset, Gladdy.db.drYOffset) + end + end + if (Gladdy.db.drCooldownPos == "RIGHT") then + Gladdy.db.drGrowDirection = "RIGHT" + local anchor = Gladdy:GetAnchor(unit, "RIGHT") + if anchor == Gladdy.buttons[unit].healthBar then + drFrame:SetPoint("LEFT", anchor, "RIGHT", horizontalMargin + Gladdy.db.drXOffset, Gladdy.db.drYOffset) + else + drFrame:SetPoint("LEFT", anchor, "RIGHT", Gladdy.db.padding + Gladdy.db.drXOffset, Gladdy.db.drYOffset) + end + end + return Gladdy.db.newLayout +end \ No newline at end of file diff --git a/Modules/ExportImport.lua b/Modules/ExportImport.lua index 330499a..889189a 100644 --- a/Modules/ExportImport.lua +++ b/Modules/ExportImport.lua @@ -95,7 +95,21 @@ local deletedOptions = { -- backwards compatibility impconc = true, dragonsbreath = true, freezetrap = true, - repentance = true + --deleted db options + castBarPos = true, + buffsCooldownPos = true, + buffsBuffsCooldownPos = true, + classIconPos = true, + ciAnchor = true, + ciPos = true, + cooldownYPos = true, + cooldownXPos = true, + drCooldownPos = true, + racialAnchor = true, + racialPos = true, + trinketPos = true, + padding = true, + growUp = true, } local function checkIsDeletedOption(k, str, msg, errorFound, errorMsg) @@ -208,6 +222,9 @@ end function ExportImport:ApplyImport(t, table, str) if str == nil then str = "Gladdy.db" + if (not t.newLayout) then + table.newLayout = false + end end for k,v in pairs(t) do if type(v) == "table" then diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 36a32d2..b9406e9 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -253,10 +253,13 @@ function Pets:UpdateFrame(unitId) self.frames[unit]:SetWidth(Gladdy.db.petWidth) self.frames[unit]:SetHeight(Gladdy.db.petHeight) - self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + + Gladdy:SetPosition(self.frames[unit], unitId, "petXOffset", "petYOffset", Pets:LegacySetPosition(unit, unitId), Pets) + if (Gladdy.db.petGroup) then if (unit == "arenapet1") then - self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + self.frames[unit]:ClearAllPoints() + self.frames[unit]:SetPoint("TOPLEFT", Gladdy.buttons[unitId].healthBar, "TOPLEFT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) else local previousPet = "arenapet" .. string_gsub(unit, "arenapet", "") - 1 self.frames[unit]:ClearAllPoints() @@ -264,7 +267,7 @@ function Pets:UpdateFrame(unitId) end else self.frames[unit]:ClearAllPoints() - self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + self.frames[unit]:SetPoint("TOPLEFT", Gladdy.buttons[unitId].healthBar, "TOPLEFT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) end healthBar.portrait:SetHeight(Gladdy.db.petHeight) @@ -587,4 +590,31 @@ function Pets:GetOptions() }, }, } +end + +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function Pets:LegacySetPosition(unit, unitId) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + self.frames[unit]:ClearAllPoints() + self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + if (Gladdy.db.petGroup) then + if (unit == "arenapet1") then + self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + else + local previousPet = "arenapet" .. string_gsub(unit, "arenapet", "") - 1 + self.frames[unit]:ClearAllPoints() + self.frames[unit]:SetPoint("TOPLEFT", self.frames[previousPet], "BOTTOMLEFT", 0, - Gladdy.db.petMargin) + end + else + self.frames[unit]:ClearAllPoints() + self.frames[unit]:SetPoint("LEFT", Gladdy.buttons[unitId].healthBar, "RIGHT", Gladdy.db.petXOffset, Gladdy.db.petYOffset) + end + return Gladdy.db.newLayout end \ No newline at end of file diff --git a/Modules/Racial.lua b/Modules/Racial.lua index aaf3731..b03c6d2 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -5,14 +5,12 @@ local GetTime = GetTime local Gladdy = LibStub("Gladdy") local L = Gladdy.L -local Racial = Gladdy:NewModule("Racial", nil, { +local Racial = Gladdy:NewModule("Racial", 79, { racialFont = "DorisPP", racialFontScale = 1, racialEnabled = true, racialSize = 60 + 20 + 1, racialWidthFactor = 0.9, - racialAnchor = "trinket", - racialPos = "RIGHT", racialXOffset = 0, racialYOffset = 0, racialBorderStyle = "Interface\\AddOns\\Gladdy\\Images\\Border_rounded_blp", @@ -22,7 +20,6 @@ local Racial = Gladdy:NewModule("Racial", nil, { racialCooldownNumberAlpha = 1, }) -local ANCHORS = { ["LEFT"] = "RIGHT", ["RIGHT"] = "LEFT", ["BOTTOM"] = "TOP", ["TOP"] = "BOTTOM"} function Racial:Initialize() self.frames = {} @@ -121,16 +118,15 @@ function Racial:UpdateFrame(unit) racial.texture.overlay:SetTexture(Gladdy.db.racialBorderStyle) racial.texture.overlay:SetVertexColor(Gladdy.db.racialBorderColor.r, Gladdy.db.racialBorderColor.g, Gladdy.db.racialBorderColor.b, Gladdy.db.racialBorderColor.a) - racial:ClearAllPoints() - local parent = Gladdy.buttons[unit][Gladdy.db.racialAnchor] - if (Gladdy.db.racialPos == "RIGHT") then - racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, Gladdy.db.padding + Gladdy.db.racialXOffset, Gladdy.db.racialYOffset) - elseif (Gladdy.db.racialPos == "LEFT") then - racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, -Gladdy.db.padding + Gladdy.db.racialXOffset, Gladdy.db.racialYOffset) - elseif (Gladdy.db.racialPos == "TOP") then - racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, Gladdy.db.racialXOffset, Gladdy.db.padding + Gladdy.db.racialYOffset) - elseif (Gladdy.db.racialPos == "BOTTOM") then - racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, Gladdy.db.racialXOffset, -Gladdy.db.padding + Gladdy.db.racialYOffset) + Gladdy:SetPosition(racial, unit, "racialXOffset", "racialYOffset", Racial:LegacySetPosition(racial, unit), Racial) + + if (unit == "arena1") then + Gladdy:CreateMover(racial,"racialXOffset", "racialYOffset", L["Racial"], + {"TOPLEFT", "TOPLEFT"}, + Gladdy.db.racialSize * Gladdy.db.racialWidthFactor, + Gladdy.db.racialSize, + 0, + 0) end if (Gladdy.db.racialEnabled == false) then @@ -394,4 +390,30 @@ function Racial:GetOptions() }, }, } +end + +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function Racial:LegacySetPosition(racial, unit) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + + local ANCHORS = { ["LEFT"] = "RIGHT", ["RIGHT"] = "LEFT", ["BOTTOM"] = "TOP", ["TOP"] = "BOTTOM"} + racial:ClearAllPoints() + local parent = Gladdy.buttons[unit][Gladdy.db.racialAnchor] + if (Gladdy.db.racialPos == "RIGHT") then + racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, Gladdy.db.padding + Gladdy.db.racialXOffset, Gladdy.db.racialYOffset) + elseif (Gladdy.db.racialPos == "LEFT") then + racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, -Gladdy.db.padding + Gladdy.db.racialXOffset, Gladdy.db.racialYOffset) + elseif (Gladdy.db.racialPos == "TOP") then + racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, Gladdy.db.racialXOffset, Gladdy.db.padding + Gladdy.db.racialYOffset) + elseif (Gladdy.db.racialPos == "BOTTOM") then + racial:SetPoint(ANCHORS[Gladdy.db.racialPos], parent, Gladdy.db.racialPos, Gladdy.db.racialXOffset, -Gladdy.db.padding + Gladdy.db.racialYOffset) + end + return Gladdy.db.newLayout end \ No newline at end of file diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 53126e4..d3a9911 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -6,18 +6,19 @@ local GetTime = GetTime local Gladdy = LibStub("Gladdy") local L = Gladdy.L -local Trinket = Gladdy:NewModule("Trinket", nil, { +local Trinket = Gladdy:NewModule("Trinket", 80, { trinketFont = "DorisPP", trinketFontScale = 1, trinketEnabled = true, trinketSize = 60 + 20 + 1, trinketWidthFactor = 0.9, - trinketPos = "RIGHT", trinketBorderStyle = "Interface\\AddOns\\Gladdy\\Images\\Border_rounded_blp", trinketBorderColor = { r = 0, g = 0, b = 0, a = 1 }, trinketDisableCircle = false, trinketCooldownAlpha = 1, trinketCooldownNumberAlpha = 1, + trinketXOffset = 0, + trinketYOffset = 0, }) LibStub("AceComm-3.0"):Embed(Trinket) @@ -119,20 +120,15 @@ function Trinket:UpdateFrame(unit) trinket.texture.overlay:SetTexture(Gladdy.db.trinketBorderStyle) trinket.texture.overlay:SetVertexColor(Gladdy.db.trinketBorderColor.r, Gladdy.db.trinketBorderColor.g, Gladdy.db.trinketBorderColor.b, Gladdy.db.trinketBorderColor.a) - trinket:ClearAllPoints() - local margin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding - if (Gladdy.db.classIconPos == "LEFT") then - if (Gladdy.db.trinketPos == "RIGHT") then - trinket:SetPoint("TOPLEFT", Gladdy.buttons[unit].healthBar, "TOPRIGHT", margin, 0) - else - trinket:SetPoint("TOPRIGHT", Gladdy.buttons[unit].classIcon, "TOPLEFT", -Gladdy.db.padding, 0) - end - else - if (Gladdy.db.trinketPos == "RIGHT") then - trinket:SetPoint("TOPLEFT", Gladdy.buttons[unit].classIcon, "TOPRIGHT", Gladdy.db.padding, 0) - else - trinket:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", -margin, 0) - end + Gladdy:SetPosition(trinket, unit, "trinketXOffset", "trinketYOffset", Trinket:LegacySetPosition(trinket, unit), Trinket) + + if (unit == "arena1") then + Gladdy:CreateMover(trinket,"trinketXOffset", "trinketYOffset", L["Trinket"], + {"TOPLEFT", "TOPLEFT"}, + Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor, + Gladdy.db.trinketSize, + 0, + 0) end if (Gladdy.db.trinketEnabled == false) then @@ -368,4 +364,31 @@ function Trinket:GetOptions() }, }, } +end + +--------------------------- + +-- LAGACY HANDLER + +--------------------------- + +function Trinket:LegacySetPosition(trinket, unit) + if Gladdy.db.newLayout then + return Gladdy.db.newLayout + end + trinket:ClearAllPoints() + local margin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding + if (Gladdy.db.classIconPos == "LEFT") then + if (Gladdy.db.trinketPos == "RIGHT") then + trinket:SetPoint("TOPLEFT", Gladdy.buttons[unit].healthBar, "TOPRIGHT", margin, 0) + else + trinket:SetPoint("TOPRIGHT", Gladdy.buttons[unit].classIcon, "TOPLEFT", -Gladdy.db.padding, 0) + end + else + if (Gladdy.db.trinketPos == "RIGHT") then + trinket:SetPoint("TOPLEFT", Gladdy.buttons[unit].classIcon, "TOPRIGHT", Gladdy.db.padding, 0) + else + trinket:SetPoint("TOPRIGHT", Gladdy.buttons[unit].healthBar, "TOPLEFT", -margin, 0) + end + end end \ No newline at end of file diff --git a/Options.lua b/Options.lua index 4eec88a..0dd3bfe 100644 --- a/Options.lua +++ b/Options.lua @@ -47,16 +47,16 @@ Gladdy.defaults = { hideBlizzard = "arena", x = 0, y = 0, - growUp = false, growDirection = "BOTTOM", frameScale = 1, pixelPerfect = false, - padding = 1, barWidth = 180, bottomMargin = 2, statusbarBorderOffset = 6, timerFormat = Gladdy.TIMER_FORMAT.tenths, backgroundColor = {r = 0, g = 0, b = 0, a = 0}, + newLayout = false, + showMover = true, }, } @@ -215,19 +215,45 @@ function Gladdy:SetupOptions() get = getOpt, set = setOpt, args = { - test = { + lock = { order = 1, width = 0.7, + name = Gladdy.db.locked and L["Unlock frame"] or L["Lock frame"], + desc = L["Toggle if frame can be moved"], + type = "execute", + func = function() + Gladdy.db.locked = not Gladdy.db.locked + Gladdy:UpdateFrame() + self.options.args.lock.name = Gladdy.db.locked and L["Unlock frame"] or L["Lock frame"] + end, + }, + showMover = { + order = 2, + width = 0.7, + name = Gladdy.db.showMover and L["Hide Mover"] or L["Show Mover"], + desc = L["Toggle to show Mover Frames"], + type = "execute", + func = function() + Gladdy.db.showMover = not Gladdy.db.showMover + Gladdy:UpdateFrame() + self.options.args.showMover.name = Gladdy.db.showMover and L["Hide Mover"] or L["Show Mover"] + end, + }, + test = { + order = 2, + width = 0.7, name = L["Test"], + desc = L["Show Test frames"], type = "execute", func = function() Gladdy:ToggleFrame(3) end, }, hide = { - order = 2, + order = 3, width = 0.7, name = L["Hide"], + desc = L["Hide frames"], type = "execute", func = function() Gladdy:Reset() @@ -235,16 +261,17 @@ function Gladdy:SetupOptions() end, }, reload = { - order = 3, + order = 4, width = 0.7, name = L["ReloadUI"], + desc = L["Reloads the UI"], type = "execute", func = function() ReloadUI() end, }, version = { - order = 4, + order = 5, width = 1, type = "description", name = " Gladdy v" .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType @@ -256,12 +283,6 @@ function Gladdy:SetupOptions() childGroups = "tab", order = 5, args = { - locked = { - type = "toggle", - name = L["Lock frame"], - desc = L["Toggle if frame can be moved"], - order = 1, - }, growDirection = { type = "select", name = L["Grow Direction"], @@ -315,15 +336,6 @@ function Gladdy:SetupOptions() max = 2, step = .01, }, - padding = { - type = "range", - name = L["Frame padding"], - desc = L["Padding of the frame"], - order = 6, - min = 0, - max = 20, - step = 1, - }, barWidth = { type = "range", name = L["Frame width"], -- 2.39.5 From 114c0ac96d39eca8ef2e618c7c17e0e8fa0b2883 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:29:30 +0100 Subject: [PATCH 071/268] clean up --- EventListener.lua | 2 +- Modules/Cooldowns.lua | 5 +-- Modules/ExportImport.lua | 5 ++- Modules/Healthbar.lua | 16 +------- Modules/XiconProfiles.lua | 81 ++++++--------------------------------- 5 files changed, 19 insertions(+), 90 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index e867791..aef0ae1 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -136,7 +136,7 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() else unitClass = Gladdy.buttons[srcUnit].race end - Cooldowns:CooldownUsed(srcUnit, unitClass, spellId, spellName) + Cooldowns:CooldownUsed(srcUnit, unitClass, spellId) Gladdy:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) end end diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index f5803da..3ca104e 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -42,7 +42,7 @@ local function getDefaultCooldown() if spellName then cooldowns[tostring(spellId)] = true else - Gladdy:Print("spellid does not exist " .. spellId) + Gladdy:Debug("ERROR", "spellid does not exist " .. spellId) end end end @@ -79,7 +79,7 @@ function Cooldowns:Initialize() self.cooldownSpellIds[spellName] = spellId self.spellTextures[spellId] = texture else - Gladdy:Print("spellid does not exist " .. spellId) + Gladdy:Debug("ERROR", "spellid does not exist " .. spellId) end end end @@ -373,7 +373,6 @@ function Cooldowns:DetectSpec(unit, spec) end end end - --end end ---------------------- --- RACE FUNCTIONALITY diff --git a/Modules/ExportImport.lua b/Modules/ExportImport.lua index 889189a..2ac8895 100644 --- a/Modules/ExportImport.lua +++ b/Modules/ExportImport.lua @@ -72,6 +72,7 @@ importButton:SetCallback("OnClick", function(widget) Gladdy:Reset() Gladdy:HideFrame() Gladdy:ToggleFrame(3) + LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") end) import:AddChild(importButton) import.button = importButton @@ -117,7 +118,7 @@ local function checkIsDeletedOption(k, str, msg, errorFound, errorMsg) for key, _ in pairs(deletedOptions) do if str_match(k, key) then isDeleted = true - Gladdy:Warn("found deleted option =", str .. "." .. k) + Gladdy:Debug("WARN", "found deleted option =", str .. "." .. k) end end if errorFound then @@ -231,7 +232,7 @@ function ExportImport:ApplyImport(t, table, str) if (table[k] ~= nil) then ExportImport:ApplyImport(v, table[k], str .. "." .. k) else - Gladdy:Warn("ApplyImport failed for", str .. "." .. k) + Gladdy:Debug("ERROR", "ApplyImport failed for", str .. "." .. k) end else diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 31e850a..bda54ef 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -251,7 +251,7 @@ function Healthbar:ENEMY_SPOTTED(unit) healthBar.hp:SetValue(health) Healthbar:SetHealthText(healthBar, health, healthMax) end - if Gladdy.db.healthName and not Gladdy.db.healthNameToArenaId then + if button.name and Gladdy.db.healthName and not Gladdy.db.healthNameToArenaId then healthBar.nameText:SetText(button.name) end @@ -504,20 +504,6 @@ function Healthbar:GetOptions() width = "full", disabled = function() return not Gladdy.db.healthName end }), - healthActual = option({ - type = "toggle", - name = L["Show the actual health"], - desc = L["Show the actual health on the health bar"], - order = 4, - width = "full", - }), - healthMax = option({ - type = "toggle", - name = L["Show max health"], - desc = L["Show max health on the health bar"], - order = 5, - width = "full", - }), healthPercentage = option({ type = "toggle", name = L["Show health percentage"], diff --git a/Modules/XiconProfiles.lua b/Modules/XiconProfiles.lua index ab871d9..bd12442 100644 --- a/Modules/XiconProfiles.lua +++ b/Modules/XiconProfiles.lua @@ -4,74 +4,17 @@ local L = Gladdy.L local XiconProfiles = Gladdy:NewModule("XiconProfiles", nil, { }) -function XiconProfiles:ApplyKlimp() - local deserialized = Gladdy.modules["Export Import"]:Decode(Gladdy:GetKlimpProfile()) - if deserialized then - Gladdy.modules["Export Import"]:ApplyImport(deserialized, Gladdy.db) - end - Gladdy:Reset() - Gladdy:HideFrame() - Gladdy:ToggleFrame(3) -end - -function XiconProfiles:ApplyKnall() - local deserialized = Gladdy.modules["Export Import"]:Decode(Gladdy:GetKnallProfile()) - if deserialized then - Gladdy.modules["Export Import"]:ApplyImport(deserialized, Gladdy.db) - end - Gladdy:Reset() - Gladdy:HideFrame() - Gladdy:ToggleFrame(3) -end - -function XiconProfiles:ApplyClassic() - local deserialized = Gladdy.modules["Export Import"]:Decode(Gladdy:GetClassicProfile()) - if deserialized then - Gladdy.modules["Export Import"]:ApplyImport(deserialized, Gladdy.db) - end - Gladdy:Reset() - Gladdy:HideFrame() - Gladdy:ToggleFrame(3) -end - -function XiconProfiles:ApplyClassicNoPet() - local deserialized = Gladdy.modules["Export Import"]:Decode(Gladdy:GetClassicProfileNoPet()) - if deserialized then - Gladdy.modules["Export Import"]:ApplyImport(deserialized, Gladdy.db) - end - Gladdy:Reset() - Gladdy:HideFrame() - Gladdy:ToggleFrame(3) -end - -function XiconProfiles:ApplyBlizz() - local deserialized = Gladdy.modules["Export Import"]:Decode(Gladdy:GetBlizzardProfile()) - if deserialized then - Gladdy.modules["Export Import"]:ApplyImport(deserialized, Gladdy.db) - end - Gladdy:Reset() - Gladdy:HideFrame() - Gladdy:ToggleFrame(3) -end - -function XiconProfiles:ApplyRukk() - local deserialized = Gladdy.modules["Export Import"]:Decode(Gladdy:GetRukkProfile()) - if deserialized then - Gladdy.modules["Export Import"]:ApplyImport(deserialized, Gladdy.db) - end - Gladdy:Reset() - Gladdy:HideFrame() - Gladdy:ToggleFrame(3) -end - -function XiconProfiles:ApplyMir() - local deserialized = Gladdy.modules["Export Import"]:Decode(Gladdy:GetMirProfile()) +local function applyProfile(profileString) + local deserialized = Gladdy.modules["Export Import"]:Decode(profileString) if deserialized then Gladdy.modules["Export Import"]:ApplyImport(deserialized, Gladdy.db) end Gladdy:Reset() Gladdy:HideFrame() Gladdy:ToggleFrame(3) + Gladdy.options.args.lock.name = Gladdy.db.locked and L["Unlock frame"] or L["Lock frame"] + Gladdy.options.args.showMover.name = Gladdy.db.showMover and L["Hide Mover"] or L["Show Mover"] + LibStub("AceConfigRegistry-3.0"):NotifyChange("Gladdy") end function XiconProfiles:GetOptions() @@ -85,7 +28,7 @@ function XiconProfiles:GetOptions() type = "execute", func = function() Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) - XiconProfiles:ApplyBlizz() + applyProfile(Gladdy:GetBlizzardProfile()) end, name = " ", desc = "Blizzard " .. L["Profile"], @@ -104,7 +47,7 @@ function XiconProfiles:GetOptions() type = "execute", func = function() Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) - XiconProfiles:ApplyClassic() + applyProfile(Gladdy:GetClassicProfile()) end, name = " ", desc = "Classic " .. L["Profile"], @@ -123,7 +66,7 @@ function XiconProfiles:GetOptions() type = "execute", func = function() Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) - XiconProfiles:ApplyClassicNoPet() + applyProfile(Gladdy:GetClassicProfileNoPet()) end, name = " ", desc = "Classic " .. L["Profile"] .. L[" No Pet"], @@ -142,7 +85,7 @@ function XiconProfiles:GetOptions() type = "execute", func = function() Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) - XiconProfiles:ApplyKnall() + applyProfile(Gladdy:GetKnallProfile()) end, name = " ", desc = "Knall's " .. L["Profile"], @@ -161,7 +104,7 @@ function XiconProfiles:GetOptions() type = "execute", func = function() Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) - XiconProfiles:ApplyKlimp() + applyProfile(Gladdy:GetKlimpProfile()) end, image = "Interface\\AddOns\\Gladdy\\Images\\BasicProfiles\\Klimp1.blp", imageWidth = 350, @@ -180,7 +123,7 @@ function XiconProfiles:GetOptions() type = "execute", func = function() Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) - XiconProfiles:ApplyRukk() + applyProfile(Gladdy:GetRukkProfile()) end, name = " ", desc = "Rukk1's " .. L["Profile"], @@ -199,7 +142,7 @@ function XiconProfiles:GetOptions() type = "execute", func = function() Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) - XiconProfiles:ApplyMir() + applyProfile(Gladdy:GetMirProfile()) end, name = " ", desc = "Mir's " .. L["Profile"], -- 2.39.5 From 1c42523a2ff8de061e790a0160872e7262092774 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 00:30:32 +0100 Subject: [PATCH 072/268] bump version + backwards compatible imports --- Gladdy.lua | 4 ++-- Modules/ExportImport.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index d117a96..53160f2 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -30,8 +30,8 @@ local LibStub = LibStub local MAJOR, MINOR = "Gladdy", 4 local Gladdy = LibStub:NewLibrary(MAJOR, MINOR) local L -Gladdy.version_major_num = 1 -Gladdy.version_minor_num = 0.22 +Gladdy.version_major_num = 2 +Gladdy.version_minor_num = 0.00 Gladdy.version_num = Gladdy.version_major_num + Gladdy.version_minor_num Gladdy.version_releaseType = RELEASE_TYPES.release Gladdy.version = PREFIX .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType diff --git a/Modules/ExportImport.lua b/Modules/ExportImport.lua index 2ac8895..3cc5676 100644 --- a/Modules/ExportImport.lua +++ b/Modules/ExportImport.lua @@ -133,8 +133,8 @@ function ExportImport:CheckDeserializedOptions(tbl, refTbl, str) if str == nil and not tbl.version_major_num then return false, "Version conflict: version_major_num not seen" end - if str == nil and tbl.version_major_num ~= Gladdy.version_major_num then - return false, "Version conflict: " .. tbl.version_major_num .. " ~= " .. Gladdy.version_major_num + if str == nil and tbl.version_major_num > Gladdy.version_major_num then + return false, "Version conflict: Major v" .. tbl.version_major_num .. " ~= v" .. Gladdy.version_major_num end if str == nil then str = "Gladdy.db" -- 2.39.5 From 2571df30527e428cc970fef3b2c7ce60e52b2712 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 03:00:57 +0100 Subject: [PATCH 073/268] cleanup --- Modules/Healthbar.lua | 42 ++++-------------------------------------- Modules/Trinket.lua | 1 - 2 files changed, 4 insertions(+), 39 deletions(-) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index bda54ef..8338a1a 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -129,7 +129,7 @@ function Healthbar.OnEvent(self, event, unit) end function Healthbar:SetHealthText(healthBar, health, healthMax) - local healthText + local healthText = "" local healthPercentage = floor(health * 100 / healthMax) if health == 0 and UnitExists(healthBar.unit) and UnitIsDeadOrGhost(healthBar.unit) then @@ -137,25 +137,8 @@ function Healthbar:SetHealthText(healthBar, health, healthMax) return end - if (Gladdy.db.healthActual) then - healthText = healthMax > 999 and ("%.1fk"):format(health / 1000) or health - end - - if (Gladdy.db.healthMax) then - local text = healthMax > 999 and ("%.1fk"):format(healthMax / 1000) or healthMax - if (healthText) then - healthText = ("%s/%s"):format(healthText, text) - else - healthText = text - end - end - if (Gladdy.db.healthPercentage) then - if (healthText) then - healthText = ("%s (%d%%)"):format(healthText, healthPercentage) - else - healthText = ("%d%%"):format(healthPercentage) - end + healthText = ("%d%%"):format(healthPercentage) end healthBar.healthText:SetText(healthText) @@ -271,27 +254,10 @@ function Healthbar:UNIT_HEALTH(unit, health, healthMax) Gladdy:SendMessage("UNIT_HEALTH", unit, health, healthMax) local healthPercentage = floor(health * 100 / healthMax) - local healthText - - if (Gladdy.db.healthActual) then - healthText = healthMax > 999 and ("%.1fk"):format(health / 1000) or health - end - - if (Gladdy.db.healthMax) then - local text = healthMax > 999 and ("%.1fk"):format(healthMax / 1000) or healthMax - if (healthText) then - healthText = ("%s/%s"):format(healthText, text) - else - healthText = text - end - end + local healthText = "" if (Gladdy.db.healthPercentage) then - if (healthText) then - healthText = ("%s (%d%%)"):format(healthText, healthPercentage) - else - healthText = ("%d%%"):format(healthPercentage) - end + healthText = ("%d%%"):format(healthPercentage) end healthBar.healthText:SetText(healthText) diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index d3a9911..928d30c 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -20,7 +20,6 @@ local Trinket = Gladdy:NewModule("Trinket", 80, { trinketXOffset = 0, trinketYOffset = 0, }) -LibStub("AceComm-3.0"):Embed(Trinket) function Trinket:Initialize() self.frames = {} -- 2.39.5 From 6b94fdc32f245c8b798c88401211a73684f762bd Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 03:01:16 +0100 Subject: [PATCH 074/268] fix minor castbar issue --- Modules/Castbar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 1eb5b70..7cb266d 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -220,7 +220,7 @@ function Castbar.OnUpdate(castBar, elapsed) castBar.spark:SetPoint("CENTER", castBar.bar, "LEFT", castBar.spark.position, 0) castBar.spark:Show() end - elseif ( GetTime() < castBar.holdTime ) then + elseif ( castBar.holdTime and GetTime() < castBar.holdTime ) then castBar.timeText:Hide() castBar.spark:Hide() return -- 2.39.5 From 65daef4cd447491c0409324669d573318a831e68 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 03:01:32 +0100 Subject: [PATCH 075/268] fix announcement throttle --- Modules/Announcements.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Modules/Announcements.lua b/Modules/Announcements.lua index 4b63595..3c8b376 100644 --- a/Modules/Announcements.lua +++ b/Modules/Announcements.lua @@ -145,7 +145,7 @@ function Announcements:SPELL_INTERRUPT(destUnit,spellID,spellName,spellSchool,ex if (not button or not Gladdy.db.announcements.spellInterrupt) then return end - self:Send(L["INTERRUPTED: %s (%s)"]:format(extraSpellName, button.name or ""), 3, RAID_CLASS_COLORS[button.class]) + self:Send(L["INTERRUPTED: %s (%s)"]:format(extraSpellName, button.name or ""), nil, RAID_CLASS_COLORS[button.class]) end function Announcements:CheckDrink(unit, aura) @@ -167,9 +167,12 @@ function Announcements:Send(msg, throttle, color) if (throttle and throttle > 0) then if (not self.throttled[msg]) then self.throttled[msg] = GetTime() + throttle + Gladdy:Debug("INFO", msg, "- NOT THROTTLED -", self.throttled[msg]) elseif (self.throttled[msg] < GetTime()) then - self.throttled[msg] = nil + Gladdy:Debug("INFO", msg, "- THROTTLED OVER -", self.throttled[msg]) + self.throttled[msg] = GetTime() + throttle else + Gladdy:Debug("INFO", msg, "- THROTTLED -", self.throttled[msg]) return end end -- 2.39.5 From c3a7c6cbc87884670ead83420f398c586b3a17ea Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 04:26:59 +0100 Subject: [PATCH 076/268] shadowsight: - reset timer when shadowsight buff is active - add a second timer - show one or two timers option added --- Modules/ShadowsightTimer.lua | 304 ++++++++++++++++++++++++++--------- 1 file changed, 228 insertions(+), 76 deletions(-) diff --git a/Modules/ShadowsightTimer.lua b/Modules/ShadowsightTimer.lua index edd280e..d16c21d 100644 --- a/Modules/ShadowsightTimer.lua +++ b/Modules/ShadowsightTimer.lua @@ -1,6 +1,12 @@ local floor, str_find, pairs = math.floor, string.find, pairs local CreateFrame = CreateFrame +--------------------------- + +-- CORE + +--------------------------- + local Gladdy = LibStub("Gladdy") local L = Gladdy.L local ShadowsightTimer = Gladdy:NewModule("Shadowsight Timer", nil, { @@ -12,8 +18,14 @@ local ShadowsightTimer = Gladdy:NewModule("Shadowsight Timer", nil, { shadowsightTimerX = 0, shadowsightTimerY = 0, shadowsightAnnounce = true, + shadowsightTimerStartTime = 91, + shadowsightTimerResetTime = 120, + shadowsightTimerShowTwoTimer = false, }) +-- /run LibStub("Gladdy").modules["Shadowsight Timer"]:AURA_GAIN(nil, nil, 34709) +-- /run LibStub("Gladdy").modules["Shadowsight Timer"].timerFrame1:SetAlpha(0) + function ShadowsightTimer:OnEvent(event, ...) self[event](self, ...) end @@ -22,20 +34,120 @@ function ShadowsightTimer:Initialize() self.locale = Gladdy:GetArenaTimer() self:RegisterMessage("JOINED_ARENA") self:RegisterMessage("AURA_GAIN") - self:CreateTimerFrame() + self:CreateAnchor() end +function ShadowsightTimer:Reset() + self.anchor:Hide() + for i=1,2 do + self["timerFrame" .. i].active = false + self["timerFrame" .. i]:SetScript("OnUpdate", nil) + self["timerFrame" .. i].font:SetTextColor(1, 0.8, 0) + end + self:UnregisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") + self:SetScript("OnEvent", nil) +end + +--------------------------- + +-- FRAME SETUP + +--------------------------- + +function ShadowsightTimer:CreateTimerFrame(anchor, name, points) + local backdrop = { + bgFile = "Interface/Tooltips/UI-Tooltip-Background", + edgeFile = "", + tile = true, tileSize = 16, edgeSize = 10, + insets = {left = 0, right = 0, top = 0, bottom = 0} + } + self[name] = CreateFrame("Frame", nil, anchor, BackdropTemplateMixin and "BackdropTemplate") + self[name]:SetPoint(points[1], anchor, points[2]) + self[name]:SetBackdrop(backdrop) + self[name]:SetBackdropColor(0,0,0,0.8) + self[name]:SetHeight(17) + self[name]:SetWidth(35) + + self[name].texture = self[name]:CreateTexture(nil,"OVERLAY") + self[name].texture:SetWidth(16) + self[name].texture:SetHeight(16) + self[name].texture:SetTexture("Interface\\Icons\\Spell_Shadow_EvilEye") + self[name].texture:SetTexCoord(0.125,0.875,0.125,0.875) + self[name].texture:SetPoint("RIGHT", self[name], "LEFT") + + self[name].font = self[name]:CreateFontString(nil,"OVERLAY","GameFontNormal") + self[name].font:SetPoint("LEFT", 5, 0) + self[name].font:SetJustifyH("LEFT") + self[name].font:SetTextColor(1, 0.8, 0) +end + +function ShadowsightTimer:CreateAnchor() + self.anchor = CreateFrame("Frame") + self.anchor:SetMovable(true) + self.anchor:EnableMouse(true) + self.anchor:SetWidth(35) + self.anchor:SetHeight(17) + self.anchor:SetPoint(Gladdy.db.shadowsightTimerRelPoint1, nil, Gladdy.db.shadowsightTimerRelPoint, Gladdy.db.shadowsightTimerX, Gladdy.db.shadowsightTimerY) + self.anchor:SetScript("OnMouseDown",function(self) self:StartMoving() end) + self.anchor:SetScript("OnMouseUp",function(self) + self:StopMovingOrSizing() + Gladdy.db.shadowsightTimerRelPoint1,_,Gladdy.db.shadowsightTimerRelPoint2,Gladdy.db.shadowsightTimerX,Gladdy.db.shadowsightTimerY = self:GetPoint() + end) + self.anchor:SetScale(Gladdy.db.shadowsightTimerScale) + self.anchor:Hide() + + self:CreateTimerFrame(self.anchor, "timerFrame1", {"TOP", "TOP"}) + local show = Gladdy.db.shadowsightTimerShowTwoTimer + self:CreateTimerFrame(show and self.timerFrame1 or self.anchor, "timerFrame2", show and {"TOP", "BOTTOM"} or {"TOP", "TOP"}) +end + +function ShadowsightTimer:UpdateFrameOnce() + self.anchor:EnableMouse(not Gladdy.db.shadowsightTimerLocked) + if Gladdy.db.shadowsightTimerEnabled then + self.anchor:SetScale(Gladdy.db.shadowsightTimerScale) + self.anchor:ClearAllPoints() + self.anchor:SetPoint(Gladdy.db.shadowsightTimerRelPoint1, nil, Gladdy.db.shadowsightTimerRelPoint2, Gladdy.db.shadowsightTimerX, Gladdy.db.shadowsightTimerY) + if Gladdy.frame.testing or Gladdy.curBracket then + self.anchor:Show() + end + if Gladdy.db.shadowsightTimerShowTwoTimer then + self.anchor:SetHeight(34) + self.timerFrame2:ClearAllPoints() + self.timerFrame2:SetPoint("TOP", self.timerFrame1, "BOTTOM") + ShadowsightTimer:NotifyStart() + else + self.anchor:SetHeight(17) + self.timerFrame2:ClearAllPoints() + self.timerFrame2:SetPoint("TOP", self.anchor, "TOP") + ShadowsightTimer:NotifyStart() + end + else + self.anchor:SetScale(Gladdy.db.shadowsightTimerScale) + self.anchor:ClearAllPoints() + self.anchor:SetPoint(Gladdy.db.shadowsightTimerRelPoint1, nil, Gladdy.db.shadowsightTimerRelPoint2, Gladdy.db.shadowsightTimerX, Gladdy.db.shadowsightTimerY) + self.anchor:Hide() + end +end + +--------------------------- + +-- EVENT HANDLING + +--------------------------- + function ShadowsightTimer:JOINED_ARENA() self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") self:SetScript("OnEvent", ShadowsightTimer.OnEvent) - self.timerFrame.font:SetText("1:30") - self.timerFrame.font:SetTextColor(1, 0.8, 0) - self.timerFrame:Show() + for i=1,2 do + self["timerFrame" .. i].font:SetText("1:30") + self["timerFrame" .. i].font:SetTextColor(1, 0.8, 0) + end + self.anchor:Show() end function ShadowsightTimer:AURA_GAIN(unit, auraType, spellID) if (spellID == 34709) then - --TODO reset timer after 15s + self:Start(Gladdy.db.shadowsightTimerResetTime, self:GetHiddenTimer()) end end @@ -43,96 +155,53 @@ function ShadowsightTimer:CHAT_MSG_BG_SYSTEM_NEUTRAL(msg) for k,v in pairs(self.locale) do if str_find(msg, v) then if k == 0 then - self:Start() + self:Start(nil, self.timerFrame1) + self:Start(nil, self.timerFrame2) end end end end +--------------------------- + +-- TEST + +--------------------------- + function ShadowsightTimer:Test() if Gladdy.db.shadowsightTimerEnabled then - self.timerFrame:Show() - self:Start() + self.anchor:Show() + ShadowsightTimer:JOINED_ARENA() + self:Start(20, self.timerFrame1) + self:Start(25, self.timerFrame2) end end -function ShadowsightTimer:Reset() - self.timerFrame:Hide() - self.timerFrame:SetScript("OnUpdate", nil) - self.timerFrame.font:SetTextColor(1, 0.8, 0) -end +--------------------------- -function ShadowsightTimer:CreateTimerFrame() - self.timerFrame = CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate") - self.timerFrame:SetPoint(Gladdy.db.shadowsightTimerRelPoint1, nil, Gladdy.db.shadowsightTimerRelPoint, Gladdy.db.shadowsightTimerX, Gladdy.db.shadowsightTimerY) +-- TIMER - local backdrop = { - bgFile = "Interface/Tooltips/UI-Tooltip-Background", - edgeFile = "", - tile = true, tileSize = 16, edgeSize = 10, - insets = {left = 0, right = 0, top = 0, bottom = 0} - } +--------------------------- - self.timerFrame:SetBackdrop(backdrop) - self.timerFrame:SetBackdropColor(0,0,0,0.8) - self.timerFrame:SetHeight(17) - self.timerFrame:SetWidth(35) - - self.timerFrame:SetMovable(true) - self.timerFrame:EnableMouse(true) - - self.timerFrame.texture = self.timerFrame:CreateTexture(nil,"OVERLAY") - self.timerFrame.texture:SetWidth(16) - self.timerFrame.texture:SetHeight(16) - self.timerFrame.texture:SetTexture("Interface\\Icons\\Spell_Shadow_EvilEye") - self.timerFrame.texture:SetTexCoord(0.125,0.875,0.125,0.875) - self.timerFrame.texture:SetPoint("RIGHT", self.timerFrame, "LEFT") - - self.timerFrame.font = self.timerFrame:CreateFontString(nil,"OVERLAY","GameFontNormal") - self.timerFrame.font:SetPoint("LEFT", 5, 0) - self.timerFrame.font:SetJustifyH("LEFT") - self.timerFrame.font:SetTextColor(1, 0.8, 0) - - self.timerFrame:SetScript("OnMouseDown",function(self) self:StartMoving() end) - self.timerFrame:SetScript("OnMouseUp",function(self) - self:StopMovingOrSizing() - Gladdy.db.shadowsightTimerRelPoint1,_,Gladdy.db.shadowsightTimerRelPoint2,Gladdy.db.shadowsightTimerX,Gladdy.db.shadowsightTimerY = self:GetPoint() - end) - self.timerFrame:SetScale(Gladdy.db.shadowsightTimerScale) - self.timerFrame:Hide() -end - -function ShadowsightTimer:UpdateFrameOnce() - self.timerFrame:EnableMouse(not Gladdy.db.shadowsightTimerLocked) - if Gladdy.db.shadowsightTimerEnabled then - self.timerFrame:SetScale(Gladdy.db.shadowsightTimerScale) - self.timerFrame:ClearAllPoints() - self.timerFrame:SetPoint(Gladdy.db.shadowsightTimerRelPoint1, nil, Gladdy.db.shadowsightTimerRelPoint2, Gladdy.db.shadowsightTimerX, Gladdy.db.shadowsightTimerY) - if Gladdy.frame.testing or Gladdy.curBracket then - self.timerFrame:Show() - end - else - self.timerFrame:SetScale(Gladdy.db.shadowsightTimerScale) - self.timerFrame:ClearAllPoints() - self.timerFrame:SetPoint(Gladdy.db.shadowsightTimerRelPoint1, nil, Gladdy.db.shadowsightTimerRelPoint2, Gladdy.db.shadowsightTimerX, Gladdy.db.shadowsightTimerY) - self.timerFrame:Hide() - end -end - -function ShadowsightTimer:Start() - self.timerFrame.endTime = 91 - self.timerFrame.timeSinceLastUpdate = 0 - self.timerFrame:SetScript("OnUpdate", ShadowsightTimer.OnUpdate) +function ShadowsightTimer:Start(time, frame) + frame.endTime = time or Gladdy.db.shadowsightTimerStartTime + frame.active = true + ShadowsightTimer:NotifyStart() + frame.announced = nil + frame.timeSinceLastUpdate = 0 + frame.font:SetTextColor(1, 0.8, 0) + frame:SetScript("OnUpdate", ShadowsightTimer.OnUpdate) end function ShadowsightTimer.OnUpdate(self, elapsed) self.timeSinceLastUpdate = self.timeSinceLastUpdate + elapsed; self.endTime = self.endTime - elapsed - if (self.timeSinceLastUpdate > 0.1) then + if (self.timeSinceLastUpdate > 0.01) then self.font:SetFormattedText(floor(self.endTime / 60) .. ":" .. "%02d", self.endTime - floor(self.endTime / 60) * 60) self.timeSinceLastUpdate = 0; - if floor(self.endTime) == 15 and Gladdy.db.shadowsightAnnounce then + if floor(self.endTime) == 15 and Gladdy.db.shadowsightAnnounce and not self.announced then + self.announced = true Gladdy:SendMessage("SHADOWSIGHT", L["Shadowsight up in %ds"]:format(15)) end end @@ -143,9 +212,61 @@ function ShadowsightTimer.OnUpdate(self, elapsed) self:SetScript("OnUpdate", nil) self.font:SetText("0:00") self.font:SetTextColor(0, 1, 0) + self.active = false + ShadowsightTimer:NotifyEnd() end end +function ShadowsightTimer:NotifyStart() + local show = Gladdy.db.shadowsightTimerShowTwoTimer + if self.timerFrame1.active and self.timerFrame2.active then + if self.timerFrame1.endTime < self.timerFrame2.endTime then + self.timerFrame1:SetAlpha(1) + self.timerFrame2:SetAlpha(show and 1 or 0) + else + self.timerFrame1:SetAlpha(show and 1 or 0) + self.timerFrame2:SetAlpha(1) + end + else + if self.timerFrame1.active then + self.timerFrame1:SetAlpha(1) + self.timerFrame2:SetAlpha(show and 1 or 0) + elseif self.timerFrame2.active then + self.timerFrame1:SetAlpha(show and 1 or 0) + self.timerFrame2:SetAlpha(1) + else + self.timerFrame1:SetAlpha(1) + self.timerFrame2:SetAlpha(show and 1 or 0) + end + end +end +function ShadowsightTimer:NotifyEnd() + local show = Gladdy.db.shadowsightTimerShowTwoTimer + if self.timerFrame1.active then + self.timerFrame1:SetAlpha(1) + self.timerFrame2:SetAlpha(show and 1 or 0) + elseif self.timerFrame2.active then + self.timerFrame1:SetAlpha(show and 1 or 0) + self.timerFrame2:SetAlpha(1) + else + self.timerFrame1:SetAlpha(1) + self.timerFrame2:SetAlpha(show and 1 or 0) + end +end +function ShadowsightTimer:GetHiddenTimer() + if self.timerFrame1.active and self.timerFrame2.active then + return self.timerFrame1.endTime < self.timerFrame2.endTime and self.timerFrame1 or self.timerFrame2 + else + return self.timerFrame1.active and self.timerFrame2 or self.timerFrame1 + end +end + +--------------------------- + +-- OPTIONS + +--------------------------- + function ShadowsightTimer:GetOptions() return { headerArenaCountdown = { @@ -167,21 +288,52 @@ function ShadowsightTimer:GetOptions() order = 4, width = "full", }), + shadowsightTimerShowTwoTimer = Gladdy:option({ + type = "toggle", + name = L["Show two timers"], + order = 5, + width = "full", + }), shadowsightAnnounce = Gladdy:option({ type = "toggle", name = L["Announce"], --desc = L["Turns countdown before the start of an arena match on/off."], - order = 5, + order = 6, width = "full", }), shadowsightTimerScale = Gladdy:option({ type = "range", name = L["Scale"], - order = 6, + order = 7, min = 0.1, max = 5, step = 0.1, width = "full", }), + headerTimer = { + type = "header", + name = L["Shadowsight CDs"], + order = 10, + }, + shadowsightTimerStartTime = Gladdy:option({ + type = "range", + name = L["Start Time"], + desc = L["Start time in seconds"], + min = 80, + max = 100, + order = 11, + step = 0.1, + width = "full", + }), + shadowsightTimerResetTime = Gladdy:option({ + type = "range", + name = L["Reset Time"], + desc = L["Reset time in seconds"], + min = 110, + max = 130, + order = 12, + step = 0.1, + width = "full", + }), } end \ No newline at end of file -- 2.39.5 From b5f67d066fe42acf7cefc53ab68b6c42b2a2083b Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 04:27:16 +0100 Subject: [PATCH 077/268] fix castbar hiding --- Modules/Castbar.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 7cb266d..f4c6086 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -232,7 +232,7 @@ function Castbar.OnUpdate(castBar, elapsed) castBar.fadeOut = nil; castBar.timeText:Show() castBar.spark:Show() - castBar:Hide(); + castBar:SetAlpha(0) end end end @@ -241,7 +241,7 @@ Castbar.CastEventsFunc = {} Castbar.CastEventsFunc["UNIT_SPELLCAST_START"] = function(castBar, event, ...) local name, text, texture, startTime, endTime, isTradeSkill, castID = UnitCastingInfo(castBar.unit) if ( not name or (not castBar.showTradeSkills and isTradeSkill)) then - castBar:Hide() + castBar:SetAlpha(0) return end @@ -272,7 +272,7 @@ Castbar.CastEventsFunc["UNIT_SPELLCAST_SUCCEEDED"] = function(castBar, event, .. end Castbar.CastEventsFunc["UNIT_SPELLCAST_STOP"] = function(castBar, event, ...) if ( not castBar:IsVisible() ) then - castBar:Hide() + castBar:SetAlpha(0) end if ( (castBar.casting and event == "UNIT_SPELLCAST_STOP" and select(2, ...) == castBar.castID) or (castBar.channeling and event == "UNIT_SPELLCAST_CHANNEL_STOP") ) then @@ -320,7 +320,7 @@ Castbar.CastEventsFunc["UNIT_SPELLCAST_DELAYED"] = function(castBar, event, ...) if ( not name or (not castBar.showTradeSkills and isTradeSkill)) then -- if there is no name, there is no bar - castBar:Hide() + castBar:SetAlpha(0) return end castBar.value = (GetTime() - (startTime / 1000)) @@ -338,7 +338,7 @@ Castbar.CastEventsFunc["UNIT_SPELLCAST_CHANNEL_START"] = function(castBar, event local name, text, texture, startTime, endTime, isTradeSkill, spellID = UnitChannelInfo(castBar.unit) if ( not name or (not castBar.showTradeSkills and isTradeSkill)) then - castBar:Hide() + castBar:SetAlpha(0) return end if ( castBar.spark ) then @@ -356,7 +356,7 @@ Castbar.CastEventsFunc["UNIT_SPELLCAST_CHANNEL_UPDATE"] = function(castBar, even if ( castBar:IsShown() ) then local name, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(castBar.unit) if ( not name or (not castBar.showTradeSkills and isTradeSkill)) then - castBar:Hide() + castBar:SetAlpha(0) return end castBar.value = ((endTime / 1000) - GetTime()) -- 2.39.5 From 2e3fb06269fc11b5275656e67304196f2c878133 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 04:27:45 +0100 Subject: [PATCH 078/268] DR Level text default on --- Modules/Diminishings.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 5c3acd9..a2b89f1 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -44,9 +44,9 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { drHalfColor = {r = 1, g = 1, b = 0, a = 1 }, drQuarterColor = {r = 1, g = 0.7, b = 0, a = 1 }, drNullColor = {r = 1, g = 0, b = 0, a = 1 }, - drLevelTextEnabled = false, + drLevelTextEnabled = true, drLevelTextFont = "DorisPP", - drLevelTextFontScale = 1, + drLevelTextFontScale = 0.8, drWidthFactor = 1, drCategories = defaultCategories(), drDuration = 18, -- 2.39.5 From 035942abbe570568241458e03b34c1433b1188b5 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 11 Jan 2022 04:33:41 +0100 Subject: [PATCH 079/268] bump version --- Gladdy.toc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gladdy.toc b/Gladdy.toc index cfb91f4..5113781 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -1,7 +1,7 @@ -## Interface: 20502 +## Interface: 20503 ## Title: Gladdy - TBC -## Version: 1.22-Release -## Notes: The most powerful arena AddOn for WoW 2.5.1 +## Version: 2.00-Release +## Notes: The most powerful arena AddOn for WoW 2.5.3 ## Author: XiconQoo, DnB_Junkee, Knall ## X-Email: contact me on discord Knall#1751 ## SavedVariables: GladdyXZ -- 2.39.5 From 5766484f92810d75aeefe839d7980d4a16f3e170 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 02:24:46 +0100 Subject: [PATCH 080/268] detach auras and interrupts --- Modules/Auras.lua | 320 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 284 insertions(+), 36 deletions(-) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 63c2b4f..2e694cd 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -41,7 +41,17 @@ local Auras = Gladdy:NewModule("Auras", nil, { auraListDefault = defaultSpells(), auraListInterrupts = defaultInterrupts(), auraInterruptColorsEnabled = true, - auraInterruptColors = Gladdy:GetSpellSchoolColors() + auraInterruptColors = Gladdy:GetSpellSchoolColors(), + auraDetached = false, + auraXOffset = 0, + auraYOffset = 0, + auraSize = 60 + 20 + 1, + auraWidthFactor = 0.9, + auraInterruptDetached = false, + auraInterruptXOffset = 0, + auraInterruptYOffset = 0, + auraInterruptSize = 60 + 20 + 1, + auraInterruptWidthFactor = 0.9, }) function Auras:Initialize() @@ -57,25 +67,30 @@ function Auras:Initialize() end function Auras:CreateFrame(unit) - local auraFrame = CreateFrame("Frame", nil, Gladdy.modules["Class Icon"].frames[unit]) + local auraFrame = CreateFrame("Frame", nil, Gladdy.buttons[unit]) auraFrame:EnableMouse(false) auraFrame:SetFrameStrata("MEDIUM") auraFrame:SetFrameLevel(3) + auraFrame.frame = CreateFrame("Frame", nil, auraFrame) + auraFrame.frame:SetPoint("TOPLEFT", auraFrame, "TOPLEFT") + auraFrame.frame:EnableMouse(false) + auraFrame.frame:SetFrameStrata("MEDIUM") + auraFrame.frame:SetFrameLevel(3) - auraFrame.cooldown = CreateFrame("Cooldown", nil, auraFrame, "CooldownFrameTemplate") + auraFrame.cooldown = CreateFrame("Cooldown", nil, auraFrame.frame, "CooldownFrameTemplate") auraFrame.cooldown.noCooldownCount = true auraFrame.cooldown:SetFrameStrata("MEDIUM") auraFrame.cooldown:SetFrameLevel(4) auraFrame.cooldown:SetReverse(true) auraFrame.cooldown:SetHideCountdownNumbers(true) - auraFrame.cooldownFrame = CreateFrame("Frame", nil, auraFrame) + auraFrame.cooldownFrame = CreateFrame("Frame", nil, auraFrame.frame) auraFrame.cooldownFrame:ClearAllPoints() - auraFrame.cooldownFrame:SetAllPoints(auraFrame) + auraFrame.cooldownFrame:SetAllPoints(auraFrame.frame) auraFrame.cooldownFrame:SetFrameStrata("MEDIUM") auraFrame.cooldownFrame:SetFrameLevel(5) - auraFrame.icon = auraFrame:CreateTexture(nil, "BACKGROUND") + auraFrame.icon = auraFrame.frame:CreateTexture(nil, "BACKGROUND") auraFrame.icon:SetMask("Interface\\AddOns\\Gladdy\\Images\\mask") auraFrame.icon:SetAllPoints(auraFrame) @@ -98,10 +113,10 @@ function Auras:CreateFrame(unit) auraFrame:SetScript("OnUpdate", function(self, elapsed) if (self.active) then - if (self.interruptFrame.priority and self.priority < self.interruptFrame.priority) then - self:SetAlpha(0.01) + if (not Gladdy.db.auraInterruptDetached and not Gladdy.db.auraDetached and self.interruptFrame.priority and self.priority < self.interruptFrame.priority) then + self.frame:SetAlpha(0.001) else - self:SetAlpha(1) + self.frame:SetAlpha(1) end if (self.timeLeft <= 0) then Auras:AURA_FADE(self.unit, self.track) @@ -114,7 +129,7 @@ function Auras:CreateFrame(unit) self.timeLeft = self.timeLeft - elapsed end else - self:SetAlpha(0.01) + self.frame:SetAlpha(0.001) end end) @@ -125,30 +140,35 @@ function Auras:CreateFrame(unit) end function Auras:CreateInterrupt(unit) - local interruptFrame = CreateFrame("Frame", nil, Gladdy.modules["Class Icon"].frames[unit]) + local interruptFrame = CreateFrame("Frame", nil, Gladdy.buttons[unit]) interruptFrame:EnableMouse(false) interruptFrame:SetFrameStrata("MEDIUM") interruptFrame:SetFrameLevel(3) + interruptFrame.frame = CreateFrame("Frame", nil, interruptFrame) + interruptFrame.frame:SetPoint("TOPLEFT", interruptFrame, "TOPLEFT") + interruptFrame.frame:EnableMouse(false) + interruptFrame.frame:SetFrameStrata("MEDIUM") + interruptFrame.frame:SetFrameLevel(3) - interruptFrame.cooldown = CreateFrame("Cooldown", nil, interruptFrame, "CooldownFrameTemplate") + interruptFrame.cooldown = CreateFrame("Cooldown", nil, interruptFrame.frame, "CooldownFrameTemplate") interruptFrame.cooldown.noCooldownCount = true interruptFrame.cooldown:SetFrameStrata("MEDIUM") interruptFrame.cooldown:SetFrameLevel(4) interruptFrame.cooldown:SetReverse(true) interruptFrame.cooldown:SetHideCountdownNumbers(true) - interruptFrame.cooldownFrame = CreateFrame("Frame", nil, interruptFrame) + interruptFrame.cooldownFrame = CreateFrame("Frame", nil, interruptFrame.frame) interruptFrame.cooldownFrame:ClearAllPoints() - interruptFrame.cooldownFrame:SetAllPoints(interruptFrame) + interruptFrame.cooldownFrame:SetAllPoints(interruptFrame.frame) interruptFrame.cooldownFrame:SetFrameStrata("MEDIUM") interruptFrame.cooldownFrame:SetFrameLevel(5) - interruptFrame.icon = interruptFrame:CreateTexture(nil, "BACKGROUND") + interruptFrame.icon = interruptFrame.frame:CreateTexture(nil, "BACKGROUND") interruptFrame.icon:SetMask("Interface\\AddOns\\Gladdy\\Images\\mask") - interruptFrame.icon:SetAllPoints(interruptFrame) + interruptFrame.icon:SetAllPoints(interruptFrame.frame) interruptFrame.icon.overlay = interruptFrame.cooldownFrame:CreateTexture(nil, "OVERLAY") - interruptFrame.icon.overlay:SetAllPoints(interruptFrame) + interruptFrame.icon.overlay:SetAllPoints(interruptFrame.frame) interruptFrame.icon.overlay:SetTexture(Gladdy.db.buttonBorderStyle) local classIcon = Gladdy.modules["Class Icon"].frames[unit] @@ -166,23 +186,25 @@ function Auras:CreateInterrupt(unit) interruptFrame:SetScript("OnUpdate", function(self, elapsed) if (self.active) then - if (Auras.frames[self.unit].priority and self.priority <= Auras.frames[self.unit].priority) then - self:SetAlpha(0.01) + if (not Gladdy.db.auraInterruptDetached and Auras.frames[self.unit].priority and self.priority <= Auras.frames[self.unit].priority) then + self.frame:SetAlpha(0.001) else - self:SetAlpha(1) + self.frame:SetAlpha(1) end if (self.timeLeft <= 0) then self.active = false self.priority = nil self.spellSchool = nil self.cooldown:Clear() - self:SetAlpha(0.01) + self.frame:SetAlpha(0.001) else self.timeLeft = self.timeLeft - elapsed Gladdy:FormatTimer(self.text, self.timeLeft, self.timeLeft < 10) end else - self:SetAlpha(0.01) + self.priority = nil + self.spellSchool = nil + self.frame:SetAlpha(0.001) end end) @@ -197,16 +219,40 @@ function Auras:UpdateFrame(unit) return end - local width, height = Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor, Gladdy.db.classIconSize + local width, height + + if Gladdy.db.auraDetached then + width, height = Gladdy.db.auraSize * Gladdy.db.auraWidthFactor, Gladdy.db.auraSize + auraFrame:ClearAllPoints() + Gladdy:SetPosition(auraFrame, unit, "auraXOffset", "auraYOffset", true, Auras) + if (unit == "arena1") then + Gladdy:CreateMover(auraFrame, "auraXOffset", "auraYOffset", L["Auras"], + {"TOPLEFT", "TOPLEFT"}, + width, + height, + 0, + 0) + end + else + width, height = Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor, Gladdy.db.classIconSize + auraFrame:ClearAllPoints() + auraFrame:SetPoint("TOPLEFT", Gladdy.modules["Class Icon"].frames[unit], "TOPLEFT") + if auraFrame.mover then + auraFrame.mover:Hide() + end + end auraFrame:SetWidth(width) auraFrame:SetHeight(height) - auraFrame:SetAllPoints(Gladdy.modules["Class Icon"].frames[unit]) + auraFrame.frame:SetWidth(height) + auraFrame.frame:SetHeight(height) + auraFrame.cooldownFrame:ClearAllPoints() + auraFrame.cooldownFrame:SetAllPoints(auraFrame) - auraFrame.cooldown:SetWidth(width - width/16) - auraFrame.cooldown:SetHeight(height - height/16) auraFrame.cooldown:ClearAllPoints() auraFrame.cooldown:SetPoint("CENTER", auraFrame, "CENTER") + auraFrame.cooldown:SetWidth(width - width/16) + auraFrame.cooldown:SetHeight(height - height/16) auraFrame.cooldown:SetAlpha(Gladdy.db.auraCooldownAlpha) auraFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") @@ -235,16 +281,49 @@ function Auras:UpdateInterruptFrame(unit) return end - local width, height = Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor, Gladdy.db.classIconSize + local width, height + + if Gladdy.db.auraInterruptDetached then + width, height = Gladdy.db.auraInterruptSize * Gladdy.db.auraInterruptWidthFactor, Gladdy.db.auraInterruptSize + interruptFrame:ClearAllPoints() + Gladdy:SetPosition(interruptFrame, unit, "auraInterruptXOffset", "auraInterruptYOffset", true, Auras) + if (unit == "arena1") then + Gladdy:CreateMover(interruptFrame, "auraInterruptXOffset", "auraInterruptYOffset", L["Interrupts"], + {"TOPLEFT", "TOPLEFT"}, + width, + height, + 0, + 0) + end + else + if Gladdy.db.auraDetached then + width, height = Gladdy.db.auraSize * Gladdy.db.auraWidthFactor, Gladdy.db.auraSize + interruptFrame:ClearAllPoints() + interruptFrame:SetAllPoints(self.frames[unit]) + if interruptFrame.mover then + interruptFrame.mover:Hide() + end + else + width, height = Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor, Gladdy.db.classIconSize + interruptFrame:ClearAllPoints() + interruptFrame:SetPoint("TOPLEFT", Gladdy.modules["Class Icon"].frames[unit], "TOPLEFT") + if interruptFrame.mover then + interruptFrame.mover:Hide() + end + end + end interruptFrame:SetWidth(width) interruptFrame:SetHeight(height) - interruptFrame:SetAllPoints(Gladdy.modules["Class Icon"].frames[unit]) + interruptFrame.frame:SetWidth(width) + interruptFrame.frame:SetHeight(height) + interruptFrame.cooldownFrame:ClearAllPoints() + interruptFrame.cooldownFrame:SetAllPoints(interruptFrame.frame) - interruptFrame.cooldown:SetWidth(width - width/16) - interruptFrame.cooldown:SetHeight(height - height/16) interruptFrame.cooldown:ClearAllPoints() interruptFrame.cooldown:SetPoint("CENTER", interruptFrame, "CENTER") + interruptFrame.cooldown:SetWidth(width - width/16) + interruptFrame.cooldown:SetHeight(height - height/16) interruptFrame.cooldown:SetAlpha(Gladdy.db.auraCooldownAlpha) interruptFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") @@ -265,9 +344,15 @@ function Auras:UpdateInterruptFrame(unit) end function Auras:ResetUnit(unit) - self.frames[unit]:UnregisterAllEvents() + self.frames[unit].interruptFrame.active = false + self.frames[unit].active = false self:AURA_FADE(unit, AURA_TYPE_DEBUFF) self:AURA_FADE(unit, AURA_TYPE_BUFF) + self.frames[unit]:UnregisterAllEvents() + self.frames[unit]:Hide() + self.frames[unit].interruptFrame:Hide() + self.frames[unit].interruptFrame.priority = nil + self.frames[unit].interruptFrame.spellSchool = nil end function Auras:Test(unit) @@ -275,6 +360,10 @@ function Auras:Test(unit) self:AURA_FADE(unit, AURA_TYPE_BUFF) self:AURA_FADE(unit, AURA_TYPE_DEBUFF) + if not self.frames[unit]:IsShown() then + self.frames[unit]:Show() + self.frames[unit].interruptFrame:Show() + end --Auras local enabledDebuffs, enabledBuffs, testauras = {}, {} @@ -310,6 +399,8 @@ function Auras:Test(unit) self:AURA_GAIN(unit,v.value.track, spellid, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) end end + -- /run LibStub("Gladdy").modules["Auras"]:Test("arena1") + -- /run LibStub("Gladdy"):JoinedArena() --Interrupts if (unit == "arena1" or unit == "arena3") then @@ -333,10 +424,15 @@ function Auras:Test(unit) end function Auras:JOINED_ARENA() - --[[for i=1, Gladdy.curBracket do - self.frames["arena" .. i]:RegisterUnitEvent("UNIT_AURA", "arena" .. i) - self.frames["arena" .. i]:SetScript("OnEvent", Auras.OnEvent) - end--]] + for i=1, Gladdy.curBracket do + local unit = "arena" .. i + self.frames[unit].interruptFrame.active = false + self.frames[unit].active = false + self:AURA_FADE(unit, AURA_TYPE_DEBUFF) + self:AURA_FADE(unit, AURA_TYPE_BUFF) + self.frames[unit].frame:Show() + self.frames[unit].interruptFrame.frame:Show() + end end function Auras:AURA_GAIN(unit, auraType, spellID, spellName, icon, duration, expirationTime, count, debuffType) @@ -418,7 +514,7 @@ end function Auras:SPELL_INTERRUPT(unit,spellID,spellName,spellSchool,extraSpellId,extraSpellName,extraSpellSchool) local auraFrame = self.frames[unit] - local interruptFrame = auraFrame and auraFrame.interruptFrame + local interruptFrame = auraFrame ~= nil and auraFrame.interruptFrame local button = Gladdy.buttons[unit] if (not interruptFrame) then return @@ -532,6 +628,158 @@ function Auras:GetOptions() name = L["Frame"], order = 3, args = { + detachedAuraMode = { + type = "group", + name = L["Detached Aura"], + order = 4, + args = { + headerDetachedMode = { + type = "header", + name = L["Detached Mode"], + order = 1, + }, + auraDetached = Gladdy:option({ + type = "toggle", + name = L["Aura Detached"], + order = 2, + width = "full" + }), + headerAuraSize = { + type = "header", + name = L["Size"], + order = 10, + }, + auraSize = Gladdy:option({ + type = "range", + name = L["Aura size"], + disabled = function() + return not Gladdy.db.auraDetached + end, + min = 3, + max = 100, + step = 0.1, + order = 11, + width = "full", + }), + auraWidthFactor = Gladdy:option({ + type = "range", + name = L["Aura width factor"], + disabled = function() + return not Gladdy.db.auraDetached + end, + min = 0.5, + max = 2, + step = 0.05, + order = 12, + width = "full", + }), + headerAuraPosition = { + type = "header", + name = L["Position"], + order = 20, + }, + auraXOffset = Gladdy:option({ + type = "range", + name = L["Aura X Offset"], + disabled = function() + return not Gladdy.db.auraDetached + end, + min = -1000, + max = 1000, + step = 0.01, + order = 21, + width = "full", + }), + auraYOffset = Gladdy:option({ + type = "range", + name = L["Aura Y Offset"], + disabled = function() + return not Gladdy.db.auraDetached + end, + min = -1000, + max = 1000, + step = 0.01, + order = 22, + width = "full", + }), + } + }, + detachedInterruptMode = { + type = "group", + name = L["Detached Interrupt"], + order = 5, + args = { + headerDetachedMode = { + type = "header", + name = L["Detached Mode"], + order = 1, + }, + auraInterruptDetached = Gladdy:option({ + type = "toggle", + name = L["Interrupt Detached"], + order = 2, + width = "full" + }), + headerAuraSize = { + type = "header", + name = L["Size"], + order = 10, + }, + auraInterruptSize = Gladdy:option({ + type = "range", + name = L["Interrupt size"], + disabled = function() + return not Gladdy.db.auraInterruptDetached + end, + min = 3, + max = 100, + step = 0.1, + order = 11, + width = "full", + }), + auraInterruptWidthFactor = Gladdy:option({ + type = "range", + name = L["Interrupt width factor"], + disabled = function() + return not Gladdy.db.auraInterruptDetached + end, + min = 0.5, + max = 2, + step = 0.05, + order = 12, + width = "full", + }), + headerAuraPosition = { + type = "header", + name = L["Position"], + order = 20, + }, + auraInterruptXOffset = Gladdy:option({ + type = "range", + name = L["Interrupt X Offset"], + disabled = function() + return not Gladdy.db.auraInterruptDetached + end, + min = -1000, + max = 1000, + step = 0.01, + order = 21, + width = "full", + }), + auraInterruptYOffset = Gladdy:option({ + type = "range", + name = L["Interrupt Y Offset"], + disabled = function() + return not Gladdy.db.auraInterruptDetached + end, + min = -1000, + max = 1000, + step = 0.01, + order = 22, + width = "full", + }), + } + }, cooldown = { type = "group", name = L["Cooldown"], -- 2.39.5 From 91f7fcb998e5d7df5eee11bd5f2dc9413786f5ff Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 02:25:11 +0100 Subject: [PATCH 081/268] classIcon add enable option --- Modules/Classicon.lua | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index 8890d5b..6599650 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -5,6 +5,7 @@ local CreateFrame = CreateFrame local GetSpellInfo = GetSpellInfo local L = Gladdy.L local Classicon = Gladdy:NewModule("Class Icon", 81, { + classIconEnabled = true, classIconSize = 60 + 20 + 1, classIconWidthFactor = 0.9, classIconBorderStyle = "Interface\\AddOns\\Gladdy\\Images\\Border_rounded_blp", @@ -129,6 +130,11 @@ function Classicon:UpdateFrame(unit) classIcon.texture.overlay:SetTexture(Gladdy.db.classIconBorderStyle) classIcon.texture.overlay:SetVertexColor(Gladdy.db.classIconBorderColor.r, Gladdy.db.classIconBorderColor.g, Gladdy.db.classIconBorderColor.b, Gladdy.db.classIconBorderColor.a) + if Gladdy.db.classIconEnabled then + classIcon:Show() + else + classIcon:Hide() + end end function Classicon:ENEMY_SPOTTED(unit) @@ -170,11 +176,16 @@ function Classicon:GetOptions() name = L["Class Icon"], order = 2, }, + classIconEnabled = Gladdy:option({ + type = "toggle", + name = L["Class Icon Enabled"], + order = 3, + }), classIconSpecIcon = { type = "toggle", name = L["Show Spec Icon"], desc = L["Shows Spec Icon once spec is detected"], - order = 3, + order = 4, get = function() return Gladdy.db.classIconSpecIcon end, set = function(_, value) Gladdy.db.classIconSpecIcon = value @@ -208,9 +219,9 @@ function Classicon:GetOptions() classIconSize = Gladdy:option({ type = "range", name = L["Icon size"], - min = 1, + min = 3, max = 100, - step = 1, + step = .1, order = 3, width = "full", }), -- 2.39.5 From 2c4308712d987f09c537d4b8010799f3cd84b246 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 02:25:40 +0100 Subject: [PATCH 082/268] hide AnnouncementFrame when not in arena --- Modules/ArenaCountDown.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index 38b6076..c02c72d 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -92,6 +92,7 @@ end function ACDFrame:JOINED_ARENA() if Gladdy.db.countdown then + self.ACDNumFrame:Show() self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") self:SetScript("OnEvent", ACDFrame.OnEvent) self.endTime = GetTime() + 70 @@ -152,6 +153,7 @@ function ACDFrame:Reset() self:UnregisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") self:SetScript("OnUpdate", nil) self.hidden = true; + self.ACDNumFrame:Hide() self.ACDNumTens:Hide(); self.ACDNumOnes:Hide(); self.ACDNumOne:Hide(); -- 2.39.5 From b351bd9c2317021e49bd2082fafeb50f31de027b Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 07:33:20 +0100 Subject: [PATCH 083/268] update Readme v2.00 --- README.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b427e3d..801c4c2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Gladdy - TBC ### The most powerful arena addon for WoW TBC 2.5.1 -## [v1.22-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v1.22-Release/Gladdy_TBC-Classic_v1.22-Release.zip) +## [v2.00-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v2.00-Release/Gladdy_TBC-Classic_v2.00-Release.zip) ###### Please consider donating if you like my work @@ -68,9 +68,63 @@ Thank you! - **Klimp** (thanks for all the suggestions and active feedback) - **the whole TBC addons 2.4.3 discord** (thanks for the support and great community, especially the MVPs) - **Hydra** (thanks for constructive feedback and suggestions) +- **Xyz** (thanks for suggestions) ### Changes +### v2.00-Release +- major release version set to v2 + - this will mean, that export strings will still be backwards compatible, but not forward (v2 String cant be imported into v1 Strings but vice versa) +- big overhaul of positioning elements added! All elements besides HP and PowerBar can be moved separately + - added Mover Frames for Auras, Interrupts, (De)Buffs, CastBar, ClassIcon, CombatIndicator, Cooldowns, DRs, Pets, Racial, Trinket + - this will hopefully make configuration a lot easier +- SpecDetection: + - fixed spec detection for Paladins + - added following spells for better spec detection: + - Expose Weakness (Survival Hunter) + - Slow (Arcane Mage) + - Improved Blink (Fire Mage) + - Vindication (Retribution Paladin) + - Holy Shield (Protection Paladin) + - Vampiric Embrace (Shadow Priest) + - Blade Flurry (Combat Rogue) + - Unleashed Rage (Enhancement Shaman) + - Flurry (Enhancement Shaman) + - Shamanistic Rage (Enhancement Shaman) + - Healing Way (Restoration Shaman) + - Totem of Wrath (Elemental Shaman) + - Dark Pact (Affliction Warlock) + - Conflagate (Destruction Warlock) + - Shield Slam (Protection Warrior) +- Cooldowns: + - added Fear Ward and Fear Ward Cooldown Detection in case it was used before arena + - added following cooldowns: + - Scare Beast (Hunter) + - Feign Death (Hunter) + - Viper Sting (Hunter) + - Flare (Hunter) + - Fear Ward (Priest) + - Shadow Word: Death (Priest) + - Evocation (Mage) + - Grounding Totem (Shaman) + - Spell Lock (Warlock) + - Devour Magic (Warlock) + - Intercept (Warrior) +- Auras/Interrupts: + - can now be detached from ClassIcon and positioned/scaled anywhere separately + - added Auras: + - Scare Beast (Hunter) + - Fear Ward (Priest) +- Pixel Perfect option added (makes your Gladdy Frames pixel perfect - no more wierd scaling interferences) +- Pets can be grouped (not perfect yet, but a first step) +- added DR-Level Text (thanks https://github.com/ManneN1) +- added zhCN Locale (thanks https://github.com/veiz) +- Shadowsight: + - reset timer when buff was taken + - add a configurable 2nd timer or show one timer with closest CD +- fixed some DR-categories (Hibernate/Chastice/Dragonsbreath/ImpConcussiveShot/Counterattack) +- ClassIcon can be disabled + ### v1.22-Release - fixed import for some localizations not working - added cooldown number alpha configurations for Auras, BuffsDebuffs, Cooldowns, Diminishings, Racial & Trinket -- 2.39.5 From 61e49ffb8c0fc738b8abf98c8ad35245937c2d4d Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 16:09:47 +0100 Subject: [PATCH 084/268] fix auras not showing --- Modules/Auras.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 2e694cd..cb75260 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -430,8 +430,8 @@ function Auras:JOINED_ARENA() self.frames[unit].active = false self:AURA_FADE(unit, AURA_TYPE_DEBUFF) self:AURA_FADE(unit, AURA_TYPE_BUFF) - self.frames[unit].frame:Show() - self.frames[unit].interruptFrame.frame:Show() + self.frames[unit]:Show() + self.frames[unit].interruptFrame:Show() end end -- 2.39.5 From 978ba56f85a6fbf800d4b38117b6d9999678ed9a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 16:11:10 +0100 Subject: [PATCH 085/268] fix cooldowns not showing on reloadui during arena --- Gladdy.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gladdy.lua b/Gladdy.lua index 53160f2..e378938 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -422,6 +422,7 @@ function Gladdy:PLAYER_REGEN_ENABLED() self.startTest = nil end self.frame:Show() + self:SendMessage("JOINED_ARENA") self.showFrame = nil end if self.hideFrame then @@ -508,13 +509,13 @@ function Gladdy:JoinedArena() end end - self:SendMessage("JOINED_ARENA") if InCombatLockdown() then Gladdy:Print("Gladdy frames show as soon as you leave combat") self.showFrame = true else self:UpdateFrame() self.frame:Show() + self:SendMessage("JOINED_ARENA") end for i=1, self.curBracket do self.buttons["arena" .. i]:SetAlpha(1) -- 2.39.5 From 114a7b14e48b824883647f86d768e0c39b6295e0 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 16:15:53 +0100 Subject: [PATCH 086/268] fix CLEU destUnit events --- EventListener.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index aef0ae1..257bf5d 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -103,19 +103,19 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() if destUnit then -- diminish tracker - if (Gladdy.db.drEnabled and (eventType == "SPELL_AURA_REMOVED" or eventType == "SPELL_AURA_REFRESH")) then + if Gladdy.buttons[destUnit] and (Gladdy.db.drEnabled and (eventType == "SPELL_AURA_REMOVED" or eventType == "SPELL_AURA_REFRESH")) then Diminishings:AuraFade(destUnit, spellID) end -- death detection - if (eventType == "UNIT_DIED" or eventType == "PARTY_KILL" or eventType == "SPELL_INSTAKILL") then + if (Gladdy.buttons[destUnit] and eventType == "UNIT_DIED" or eventType == "PARTY_KILL" or eventType == "SPELL_INSTAKILL") then Gladdy:SendMessage("UNIT_DEATH", destUnit) end -- spec detection - if not Gladdy.buttons[destUnit].class or not Gladdy.buttons[destUnit].race then + if Gladdy.buttons[destUnit] and (not Gladdy.buttons[destUnit].class or not Gladdy.buttons[destUnit].race) then Gladdy:SpotEnemy(destUnit, true) end --interrupt detection - if eventType == "SPELL_INTERRUPT" then + if Gladdy.buttons[destUnit] and eventType == "SPELL_INTERRUPT" then Gladdy:SendMessage("SPELL_INTERRUPT", destUnit,spellID,spellName,spellSchool,extraSpellId,extraSpellName,extraSpellSchool) end end -- 2.39.5 From 6954fb05d02d74db659a841b103b451d82b75db4 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 16:18:11 +0100 Subject: [PATCH 087/268] shadowsight timer fix timer tracking when friendly units take buff --- EventListener.lua | 7 +++++-- Modules/ShadowsightTimer.lua | 3 +-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 257bf5d..8f985a5 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -98,8 +98,11 @@ end function EventListener:COMBAT_LOG_EVENT_UNFILTERED() -- timestamp,eventType,hideCaster,sourceGUID,sourceName,sourceFlags,sourceRaidFlags,destGUID,destName,destFlags,destRaidFlags,spellId,spellName,spellSchool local _,eventType,_,sourceGUID,_,_,_,destGUID,_,_,_,spellID,spellName,spellSchool,extraSpellId,extraSpellName,extraSpellSchool = CombatLogGetCurrentEventInfo() - local srcUnit = Gladdy.guids[sourceGUID] - local destUnit = Gladdy.guids[destGUID] + local srcUnit = Gladdy.guids[sourceGUID] -- can be a PET + local destUnit = Gladdy.guids[destGUID] -- can be a PET + if (Gladdy.db.shadowsightTimerEnabled and eventType == "SPELL_AURA_APPLIED" and spellID == 34709) then + Gladdy.modules["Shadowsight Timer"]:AURA_GAIN(nil, nil, 34709) + end if destUnit then -- diminish tracker diff --git a/Modules/ShadowsightTimer.lua b/Modules/ShadowsightTimer.lua index d16c21d..d25dfc3 100644 --- a/Modules/ShadowsightTimer.lua +++ b/Modules/ShadowsightTimer.lua @@ -33,7 +33,6 @@ end function ShadowsightTimer:Initialize() self.locale = Gladdy:GetArenaTimer() self:RegisterMessage("JOINED_ARENA") - self:RegisterMessage("AURA_GAIN") self:CreateAnchor() end @@ -146,7 +145,7 @@ function ShadowsightTimer:JOINED_ARENA() end function ShadowsightTimer:AURA_GAIN(unit, auraType, spellID) - if (spellID == 34709) then + if (spellID == 34709 and Gladdy.db.shadowsightTimerEnabled) then self:Start(Gladdy.db.shadowsightTimerResetTime, self:GetHiddenTimer()) end end -- 2.39.5 From 55860fc1570b7c00241ea2f33000f20222f0d040 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 16:18:34 +0100 Subject: [PATCH 088/268] fix fear ward cooldown tracking --- EventListener.lua | 1 + Modules/Cooldowns.lua | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 8f985a5..23cd832 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -82,6 +82,7 @@ function Gladdy:SpotEnemy(unit, auraScan) for arenaUnit,v in pairs(self.buttons) do if (UnitIsUnit(arenaUnit, unitCaster)) then Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, expirationTime - GetTime()) + -- /run LibStub("Gladdy").modules["Cooldowns"]:CooldownUsed("arena5", "PRIEST", 6346, 10) end end end diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 3ca104e..76f2648 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -258,7 +258,7 @@ function Cooldowns:SPEC_DETECTED(unit, spec) self:DetectSpec(unit, spec) end -function Cooldowns:CooldownStart(button, spellId, duration) +function Cooldowns:CooldownStart(button, spellId, duration, start) -- starts timer frame if not duration or duration == nil or type(duration) ~= "number" then return @@ -267,8 +267,8 @@ function Cooldowns:CooldownStart(button, spellId, duration) if (button.spellCooldownFrame["icon" .. i].spellId == spellId) then local frame = button.spellCooldownFrame["icon" .. i] frame.active = true - frame.timeLeft = duration - if (not Gladdy.db.cooldownDisableCircle) then frame.cooldown:SetCooldown(GetTime(), duration) end + frame.timeLeft = start and start - GetTime() + duration or duration + if (not Gladdy.db.cooldownDisableCircle) then frame.cooldown:SetCooldown(start or GetTime(), duration) end frame:SetScript("OnUpdate", function(self, elapsed) self.timeLeft = self.timeLeft - elapsed local timeLeft = ceil(self.timeLeft) @@ -519,7 +519,7 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId, expirationTimeInSecond if (Gladdy.db.cooldown) then -- start cooldown - self:CooldownStart(button, spellId, expirationTimeInSeconds or cd) + self:CooldownStart(button, spellId, cd, expirationTimeInSeconds and (GetTime() + expirationTimeInSeconds - cd) or nil) end --[[ announcement -- 2.39.5 From 2edca9b11e15a6ce5d718539c20a118c033fd776 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 16:33:49 +0100 Subject: [PATCH 089/268] readme --- README.md | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 801c4c2..112f909 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ The goal is to make Gladdy highly configurable in it's appearance. Everything ca - [AlexFolland](https://github.com/AlexFolland) - [dfherr](https://github.com/dfherr) - [miraage](https://github.com/miraage) +- [veiz](https://github.com/veiz) Thank you! @@ -73,12 +74,16 @@ Thank you! ### Changes ### v2.00-Release -- major release version set to v2 +This is a packed release with new features and bugfixes. Most importantly, positioning of all elements has been redone with movable frames. +Thank you for the great feedback and active contribution. + +**Here is a list of all changes:** +- **major release version set to v2** - this will mean, that export strings will still be backwards compatible, but not forward (v2 String cant be imported into v1 Strings but vice versa) -- big overhaul of positioning elements added! All elements besides HP and PowerBar can be moved separately +- **big overhaul of positioning elements added! All elements besides HP and PowerBar can be moved separately** - added Mover Frames for Auras, Interrupts, (De)Buffs, CastBar, ClassIcon, CombatIndicator, Cooldowns, DRs, Pets, Racial, Trinket - this will hopefully make configuration a lot easier -- SpecDetection: +- **SpecDetection:** - fixed spec detection for Paladins - added following spells for better spec detection: - Expose Weakness (Survival Hunter) @@ -96,7 +101,7 @@ Thank you! - Dark Pact (Affliction Warlock) - Conflagate (Destruction Warlock) - Shield Slam (Protection Warrior) -- Cooldowns: +- **Cooldowns:** - added Fear Ward and Fear Ward Cooldown Detection in case it was used before arena - added following cooldowns: - Scare Beast (Hunter) @@ -110,20 +115,25 @@ Thank you! - Spell Lock (Warlock) - Devour Magic (Warlock) - Intercept (Warrior) -- Auras/Interrupts: +- **Auras/Interrupts:** - can now be detached from ClassIcon and positioned/scaled anywhere separately - added Auras: - Scare Beast (Hunter) - Fear Ward (Priest) -- Pixel Perfect option added (makes your Gladdy Frames pixel perfect - no more wierd scaling interferences) -- Pets can be grouped (not perfect yet, but a first step) -- added DR-Level Text (thanks https://github.com/ManneN1) -- added zhCN Locale (thanks https://github.com/veiz) -- Shadowsight: +- **Shadowsight:** - reset timer when buff was taken - - add a configurable 2nd timer or show one timer with closest CD -- fixed some DR-categories (Hibernate/Chastice/Dragonsbreath/ImpConcussiveShot/Counterattack) -- ClassIcon can be disabled + - add a configurable 2nd timer or show one timer with the closest CD +- **fixed some DR-categories** (Hibernate / Chastice / Dragonsbreath / ImpConcussiveShot / Counterattack) +- **Pixel Perfect option added** (makes your Gladdy Frames pixel perfect - no more wierd scaling interferences) +- **Pets can be grouped** (not perfect yet, but a first step) +- **added DR-Level Text** (thanks https://github.com/ManneN1) +- **added zhCN Locale** (thanks https://github.com/veiz) +- **ClassIcon can be disabled** +- **add interrupt announcement** +- **detect SpellLock and Devour Magic cooldowns properly** +- **minor fixes:** + - fixed reloading during arena to properly show all frames + - fix grow up positioning ### v1.22-Release - fixed import for some localizations not working -- 2.39.5 From 242c45b8c49f7a3131b8f1b7ddf01994f292f60f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 20:21:53 +0100 Subject: [PATCH 090/268] frame strata option added for all visual elements --- Constants.lua | 22 ++++ Frame.lua | 3 +- Modules/ArenaCountDown.lua | 30 +++++- Modules/Auras.lua | 110 +++++++++++++++++++ Modules/BuffsDebuffs.lua | 47 +++++++- Modules/Castbar.lua | 49 ++++++++- Modules/Classicon.lua | 64 +++++++++-- Modules/CombatIndicator.lua | 42 +++++++- Modules/Cooldowns.lua | 56 +++++++++- Modules/Diminishings.lua | 55 +++++++++- Modules/Healthbar.lua | 44 +++++++- Modules/Highlight.lua | 203 ++++++++++++++++++++++++----------- Modules/Pets.lua | 44 +++++++- Modules/Powerbar.lua | 46 +++++++- Modules/Racial.lua | 72 ++++++++----- Modules/ShadowsightTimer.lua | 169 ++++++++++++++++++++++------- Modules/Trinket.lua | 78 ++++++++++++-- 17 files changed, 957 insertions(+), 177 deletions(-) diff --git a/Constants.lua b/Constants.lua index 7efeeee..d04dcda 100644 --- a/Constants.lua +++ b/Constants.lua @@ -1234,4 +1234,26 @@ Gladdy.newDefaults = { ["castBarXOffset"] = -235.900146484375, ["castBarYOffset"] = -30.5, }, +} + +Gladdy.frameStrata = { + BACKGROUND = L["Background"] .. "(0)", + LOW = L["Low"] .. "(1)", + MEDIUM = L["Medium"] .. "(2)", + HIGH = L["High"] .. "(3)", + DIALOG = L["Dialog"] .. "(4)", + FULLSCREEN = L["Fullscreen"] .. "(5)", + FULLSCREEN_DIALOG = L["Fullscreen Dialog"] .. "(6)", + TOOLTIP = L["Tooltip"] .. "(7)", +} + +Gladdy.frameStrataSorting = { + [1] = "BACKGROUND", + [2] = "LOW", + [3] = "MEDIUM", + [4] = "HIGH", + [5] = "DIALOG", + [6] = "FULLSCREEN", + [7] = "FULLSCREEN_DIALOG", + [8] = "TOOLTIP", } \ No newline at end of file diff --git a/Frame.lua b/Frame.lua index e6d58e0..7f86b67 100644 --- a/Frame.lua +++ b/Frame.lua @@ -395,7 +395,7 @@ function Gladdy:CreateMover(frame, xConfig, yConfig, name, points, width, height frame:EnableMouse(false) frame:SetMovable(true) frame.mover = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate") - frame.mover:SetFrameStrata("DIALOG") + frame.mover:SetFrameStrata("TOOLTIP") frame.mover:SetPoint(points[1], frame, points[2], xOffset or 0, yOffset or 0) frame.mover:SetHeight(height or frame:GetHeight()) frame.mover:SetWidth(width or frame:GetWidth()) @@ -412,6 +412,7 @@ function Gladdy:CreateMover(frame, xConfig, yConfig, name, points, width, height frame.mover.border:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = 2 }) frame.mover.border:SetAllPoints(frame.mover) frame.mover.border:SetBackdropBorderColor(0,1,0,1) + frame.mover.border:SetFrameStrata("TOOLTIP") frame.mover.text = frame.mover.border:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") frame.mover.text:SetText(name) diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index c02c72d..dda004f 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -6,7 +6,9 @@ local Gladdy = LibStub("Gladdy") local L = Gladdy.L local ACDFrame = Gladdy:NewModule("Arena Countdown", nil, { countdown = true, - arenaCountdownSize = 256 + arenaCountdownSize = 256, + arenaCountdownFrameStrata = "HIGH", + arenaCountdownFrameLevel = 50, }) function ACDFrame:OnEvent(event, ...) @@ -51,6 +53,11 @@ function ACDFrame:Initialize() self.faction = UnitFactionGroup("player") end +function ACDFrame:UpdateFrameOnce() + self.ACDNumFrame:SetFrameStrata(Gladdy.db.arenaCountdownFrameStrata) + self.ACDNumFrame:SetFrameLevel(Gladdy.db.arenaCountdownFrameLevel) +end + function ACDFrame.OnUpdate(self, elapse) if (self.countdown > 0 and Gladdy.db.countdown) then self.hidden = false; @@ -182,5 +189,26 @@ function ACDFrame:GetOptions() step = 16, width = "full", }), + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 5, + }, + arenaCountdownFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 6, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + }), + arenaCountdownFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 7, + width = "full", + }), } end diff --git a/Modules/Auras.lua b/Modules/Auras.lua index cb75260..367bbf4 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -52,6 +52,10 @@ local Auras = Gladdy:NewModule("Auras", nil, { auraInterruptYOffset = 0, auraInterruptSize = 60 + 20 + 1, auraInterruptWidthFactor = 0.9, + auraFrameStrata = "MEDIUM", + auraFrameLevel = 5, + auraInterruptFrameStrata = "MEDIUM", + auraInterruptFrameLevel = 5, }) function Auras:Initialize() @@ -223,6 +227,16 @@ function Auras:UpdateFrame(unit) if Gladdy.db.auraDetached then width, height = Gladdy.db.auraSize * Gladdy.db.auraWidthFactor, Gladdy.db.auraSize + + auraFrame:SetFrameStrata(Gladdy.db.auraFrameStrata) + auraFrame:SetFrameLevel(Gladdy.db.auraFrameLevel) + auraFrame.frame:SetFrameStrata(Gladdy.db.auraFrameStrata) + auraFrame.frame:SetFrameLevel(Gladdy.db.auraFrameLevel) + auraFrame.cooldown:SetFrameStrata(Gladdy.db.auraFrameStrata) + auraFrame.cooldown:SetFrameLevel(Gladdy.db.auraFrameLevel + 1) + auraFrame.cooldownFrame:SetFrameStrata(Gladdy.db.auraFrameStrata) + auraFrame.cooldownFrame:SetFrameLevel(Gladdy.db.auraFrameLevel + 2) + auraFrame:ClearAllPoints() Gladdy:SetPosition(auraFrame, unit, "auraXOffset", "auraYOffset", true, Auras) if (unit == "arena1") then @@ -235,6 +249,16 @@ function Auras:UpdateFrame(unit) end else width, height = Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor, Gladdy.db.classIconSize + + auraFrame:SetFrameStrata(Gladdy.db.classIconFrameStrata) + auraFrame:SetFrameLevel(Gladdy.db.classIconFrameLevel + 1) + auraFrame.frame:SetFrameStrata(Gladdy.db.classIconFrameStrata) + auraFrame.frame:SetFrameLevel(Gladdy.db.classIconFrameLevel + 1) + auraFrame.cooldown:SetFrameStrata(Gladdy.db.classIconFrameStrata) + auraFrame.cooldown:SetFrameLevel(Gladdy.db.classIconFrameLevel + 2) + auraFrame.cooldownFrame:SetFrameStrata(Gladdy.db.classIconFrameStrata) + auraFrame.cooldownFrame:SetFrameLevel(Gladdy.db.classIconFrameLevel + 3) + auraFrame:ClearAllPoints() auraFrame:SetPoint("TOPLEFT", Gladdy.modules["Class Icon"].frames[unit], "TOPLEFT") if auraFrame.mover then @@ -285,6 +309,16 @@ function Auras:UpdateInterruptFrame(unit) if Gladdy.db.auraInterruptDetached then width, height = Gladdy.db.auraInterruptSize * Gladdy.db.auraInterruptWidthFactor, Gladdy.db.auraInterruptSize + + interruptFrame:SetFrameStrata(Gladdy.db.auraInterruptFrameStrata) + interruptFrame:SetFrameLevel(Gladdy.db.auraInterruptFrameLevel) + interruptFrame.frame:SetFrameStrata(Gladdy.db.auraInterruptFrameStrata) + interruptFrame.frame:SetFrameLevel(Gladdy.db.auraInterruptFrameLevel) + interruptFrame.cooldown:SetFrameStrata(Gladdy.db.auraInterruptFrameStrata) + interruptFrame.cooldown:SetFrameLevel(Gladdy.db.auraInterruptFrameLevel + 1) + interruptFrame.cooldownFrame:SetFrameStrata(Gladdy.db.auraInterruptFrameStrata) + interruptFrame.cooldownFrame:SetFrameLevel(Gladdy.db.auraInterruptFrameLevel + 2) + interruptFrame:ClearAllPoints() Gladdy:SetPosition(interruptFrame, unit, "auraInterruptXOffset", "auraInterruptYOffset", true, Auras) if (unit == "arena1") then @@ -298,6 +332,16 @@ function Auras:UpdateInterruptFrame(unit) else if Gladdy.db.auraDetached then width, height = Gladdy.db.auraSize * Gladdy.db.auraWidthFactor, Gladdy.db.auraSize + + interruptFrame:SetFrameStrata(Gladdy.db.auraFrameStrata) + interruptFrame:SetFrameLevel(Gladdy.db.auraFrameLevel) + interruptFrame.frame:SetFrameStrata(Gladdy.db.auraFrameStrata) + interruptFrame.frame:SetFrameLevel(Gladdy.db.auraFrameLevel) + interruptFrame.cooldown:SetFrameStrata(Gladdy.db.auraFrameStrata) + interruptFrame.cooldown:SetFrameLevel(Gladdy.db.auraFrameLevel + 1) + interruptFrame.cooldownFrame:SetFrameStrata(Gladdy.db.auraFrameStrata) + interruptFrame.cooldownFrame:SetFrameLevel(Gladdy.db.auraFrameLevel + 2) + interruptFrame:ClearAllPoints() interruptFrame:SetAllPoints(self.frames[unit]) if interruptFrame.mover then @@ -305,6 +349,16 @@ function Auras:UpdateInterruptFrame(unit) end else width, height = Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor, Gladdy.db.classIconSize + + interruptFrame:SetFrameStrata(Gladdy.db.classIconFrameStrata) + interruptFrame:SetFrameLevel(Gladdy.db.classIconFrameLevel + 1) + interruptFrame.frame:SetFrameStrata(Gladdy.db.classIconFrameStrata) + interruptFrame.frame:SetFrameLevel(Gladdy.db.classIconFrameLevel + 1) + interruptFrame.cooldown:SetFrameStrata(Gladdy.db.classIconFrameStrata) + interruptFrame.cooldown:SetFrameLevel(Gladdy.db.classIconFrameLevel + 2) + interruptFrame.cooldownFrame:SetFrameStrata(Gladdy.db.classIconFrameStrata) + interruptFrame.cooldownFrame:SetFrameLevel(Gladdy.db.classIconFrameLevel + 3) + interruptFrame:ClearAllPoints() interruptFrame:SetPoint("TOPLEFT", Gladdy.modules["Class Icon"].frames[unit], "TOPLEFT") if interruptFrame.mover then @@ -702,6 +756,34 @@ function Auras:GetOptions() order = 22, width = "full", }), + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 30, + }, + auraFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + disabled = function() + return not Gladdy.db.auraDetached + end, + order = 32, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + auraFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + disabled = function() + return not Gladdy.db.auraDetached + end, + min = 0, + max = 500, + step = 1, + order = 33, + width = "full", + }), } }, detachedInterruptMode = { @@ -778,6 +860,34 @@ function Auras:GetOptions() order = 22, width = "full", }), + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 30, + }, + auraInterruptFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + disabled = function() + return not Gladdy.db.auraDetached + end, + order = 32, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + auraInterruptFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + disabled = function() + return not Gladdy.db.auraDetached + end, + min = 0, + max = 500, + step = 1, + order = 33, + width = "full", + }), } }, cooldown = { diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 81ff806..8c75649 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -50,6 +50,8 @@ local BuffsDebuffs = Gladdy:NewModule("Buffs and Debuffs", nil, { buffsBorderColorDisease = Gladdy:GetAuraTypeColor()["disease"], buffsBorderColorForm = Gladdy:GetAuraTypeColor()["form"], buffsBorderColorAura = Gladdy:GetAuraTypeColor()["aura"], + buffFrameStrata = "MEDIUM", + buffsFrameLevel = 9, }) local spellSchoolToOptionValueTable @@ -232,11 +234,15 @@ end function BuffsDebuffs:CreateFrame(unit) local debuffFrame = CreateFrame("Frame", "GladdyDebuffs" .. unit, Gladdy.buttons[unit]) + debuffFrame:SetFrameStrata(Gladdy.db.buffFrameStrata) + debuffFrame:SetFrameLevel(Gladdy.db.buffsFrameLevel) debuffFrame:SetMovable(true) debuffFrame:SetHeight(Gladdy.db.buffsIconSize) debuffFrame:SetWidth(1) debuffFrame.unit = unit local buffFrame = CreateFrame("Frame", "GladdyBuffs" .. unit, Gladdy.buttons[unit]) + buffFrame:SetFrameStrata(Gladdy.db.buffFrameStrata) + buffFrame:SetFrameLevel(Gladdy.db.buffsFrameLevel) buffFrame:SetMovable(true) buffFrame:SetHeight(Gladdy.db.buffsIconSize) buffFrame:SetWidth(1) @@ -271,6 +277,11 @@ local function styleIcon(aura, auraType) aura.cooldowncircle:SetAlpha(Gladdy.db.buffsCooldownAlpha) end + aura:SetFrameStrata(Gladdy.db.buffFrameStrata) + aura:SetFrameLevel(Gladdy.db.buffsFrameLevel) + aura.cooldowncircle:SetFrameLevel(Gladdy.db.buffsFrameLevel + 1) + aura.overlay:SetFrameLevel(Gladdy.db.buffsFrameLevel + 2) + aura.border:SetTexture(Gladdy.db.buffsBorderStyle) aura.border:SetVertexColor(spellSchoolToOptionValue(aura.spellSchool)) aura.cooldown:SetFont(Gladdy:SMFetch("font", "buffsFont"), (Gladdy.db.buffsIconSize/2 - 1) * Gladdy.db.buffsFontScale, "OUTLINE") @@ -388,18 +399,19 @@ function BuffsDebuffs:AddAura(unit, spellID, auraType, duration, timeLeft, stack else aura = CreateFrame("Frame") aura:EnableMouse(false) - aura:SetFrameLevel(3) + aura:SetFrameStrata(Gladdy.db.buffFrameStrata) + aura:SetFrameLevel(Gladdy.db.buffsFrameLevel) aura.texture = aura:CreateTexture(nil, "BACKGROUND") aura.texture:SetMask("Interface\\AddOns\\Gladdy\\Images\\mask") aura.texture:SetAllPoints(aura) aura.cooldowncircle = CreateFrame("Cooldown", nil, aura, "CooldownFrameTemplate") - aura.cooldowncircle:SetFrameLevel(4) + aura.cooldowncircle:SetFrameLevel(Gladdy.db.buffsFrameLevel + 1) aura.cooldowncircle.noCooldownCount = true -- disable OmniCC aura.cooldowncircle:SetAllPoints(aura) aura.cooldowncircle:SetReverse(true) aura.cooldowncircle:SetHideCountdownNumbers(true) aura.overlay = CreateFrame("Frame", nil, aura) - aura.overlay:SetFrameLevel(5) + aura.overlay:SetFrameLevel(Gladdy.db.buffsFrameLevel + 2) aura.overlay:SetAllPoints(aura) aura.border = aura.overlay:CreateTexture(nil, "OVERLAY") aura.border:SetAllPoints(aura) @@ -878,6 +890,35 @@ function BuffsDebuffs:GetOptions() }), }, }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 6, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + buffFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + buffsFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, }, }, debuffList = { diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index f4c6086..9a16ff2 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -41,6 +41,8 @@ local Castbar = Gladdy:NewModule("Cast Bar", 70, { castBarTimerFormat = "LEFT", castBarSparkEnabled = true, castBarSparkColor = { r = 1, g = 1, b = 1, a = 1 }, + castBarFrameStrata = "MEDIUM", + castBarFrameLevel = 5, }) function Castbar:Initialize() @@ -60,19 +62,24 @@ function Castbar:CreateFrame(unit) castBar:EnableMouse(false) castBar:SetMovable(true) castBar.unit = unit + castBar:SetFrameStrata(Gladdy.db.castBarFrameStrata) + castBar:SetFrameLevel(Gladdy.db.castBarFrameLevel) castBar.backdrop = CreateFrame("Frame", nil, castBar, BackdropTemplateMixin and "BackdropTemplate") castBar.backdrop:SetAllPoints(castBar) castBar.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) castBar.backdrop:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) - castBar.backdrop:SetFrameLevel(1) + castBar.backdrop:SetFrameStrata(Gladdy.db.castBarFrameStrata) + castBar.backdrop:SetFrameLevel(Gladdy.db.castBarFrameLevel - 1) castBar.bar = CreateFrame("StatusBar", nil, castBar) castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) castBar.bar:SetStatusBarColor(Gladdy.db.castBarColor.r, Gladdy.db.castBarColor.g, Gladdy.db.castBarColor.b, Gladdy.db.castBarColor.a) castBar.bar:SetMinMaxValues(0, 100) castBar.bar:SetFrameLevel(0) + castBar.bar:SetFrameStrata(Gladdy.db.castBarFrameStrata) + castBar.bar:SetFrameLevel(Gladdy.db.castBarFrameLevel) castBar.spark = castBar:CreateTexture(nil, "OVERLAY") castBar.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark") @@ -88,6 +95,8 @@ function Castbar:CreateFrame(unit) castBar.bg:SetAllPoints(castBar.bar) castBar.icon = CreateFrame("Frame", nil, castBar) + castBar.icon:SetFrameStrata(Gladdy.db.castBarFrameStrata) + castBar.icon:SetFrameLevel(Gladdy.db.castBarFrameLevel) castBar.icon.texture = castBar.icon:CreateTexture(nil, "BACKGROUND") castBar.icon.texture:SetMask("Interface\\AddOns\\Gladdy\\Images\\mask") castBar.icon.texture:SetAllPoints(castBar.icon) @@ -129,6 +138,15 @@ function Castbar:UpdateFrame(unit) return end + castBar:SetFrameStrata(Gladdy.db.castBarFrameStrata) + castBar:SetFrameLevel(Gladdy.db.castBarFrameLevel) + castBar.backdrop:SetFrameStrata(Gladdy.db.castBarFrameStrata) + castBar.backdrop:SetFrameLevel(Gladdy.db.castBarFrameLevel - 1) + castBar.bar:SetFrameStrata(Gladdy.db.castBarFrameStrata) + castBar.bar:SetFrameLevel(Gladdy.db.castBarFrameLevel) + castBar.icon:SetFrameStrata(Gladdy.db.castBarFrameStrata) + castBar.icon:SetFrameLevel(Gladdy.db.castBarFrameLevel) + castBar:SetWidth(Gladdy.db.castBarWidth) castBar:SetHeight(Gladdy.db.castBarHeight) castBar.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), @@ -793,6 +811,35 @@ function Castbar:GetOptions() }), } }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 6, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + castBarFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + castBarFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 1, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, }, }, } diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index 6599650..01099a6 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -13,6 +13,8 @@ local Classicon = Gladdy:NewModule("Class Icon", 81, { classIconSpecIcon = false, classIconXOffset = 0, classIconYOffset = 0, + classIconFrameStrata = "MEDIUM", + classIconFrameLevel = 5, }) local classIconPath = "Interface\\Addons\\Gladdy\\Images\\Classes\\" @@ -111,6 +113,9 @@ function Classicon:UpdateFrame(unit) return end + classIcon:SetFrameStrata(Gladdy.db.classIconFrameStrata) + classIcon:SetFrameLevel(Gladdy.db.classIconFrameLevel) + classIcon:SetWidth(Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor) classIcon:SetHeight(Gladdy.db.classIconSize) @@ -239,29 +244,37 @@ function Classicon:GetOptions() position = { type = "group", name = L["Position"], - order = 1, + order = 3, args = { headerPosition = { type = "header", name = L["Position"], order = 5, }, - classIconPos = Gladdy:option({ - type = "select", - name = L["Icon position"], - desc = L["This changes positions with trinket"], - order = 6, - values = { - ["LEFT"] = L["Left"], - ["RIGHT"] = L["Right"], - }, + classIconXOffset = Gladdy:option({ + type = "range", + name = L["Horizontal offset"], + order = 11, + min = -800, + max = 800, + step = 0.1, + width = "full", + }), + classIconYOffset = Gladdy:option({ + type = "range", + name = L["Vertical offset"], + order = 12, + min = -800, + max = 800, + step = 0.1, + width = "full", }), }, }, border = { type = "group", name = L["Border"], - order = 1, + order = 2, args = { headerBorder = { type = "header", @@ -283,6 +296,35 @@ function Classicon:GetOptions() }), }, }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 4, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + classIconFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + classIconFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, }, }, } diff --git a/Modules/CombatIndicator.lua b/Modules/CombatIndicator.lua index 73a016d..5647178 100644 --- a/Modules/CombatIndicator.lua +++ b/Modules/CombatIndicator.lua @@ -14,6 +14,8 @@ local CombatIndicator = Gladdy:NewModule("Combat Indicator", nil, { ciYOffset = -31, ciBorderStyle = "Interface\\AddOns\\Gladdy\\Images\\Border_rounded_blp", ciBorderColor = { r = 0, g = 0, b = 0, a = 1 }, + ciFrameStrata = "HIGH", + ciFrameLevel = 5, }) function CombatIndicator:Initialize() @@ -36,7 +38,8 @@ function CombatIndicator:CreateFrame(unit) local ciFrame = CreateFrame("Frame", "GladdyCombatindicator" .. unit, button) ciFrame:EnableMouse(false) ciFrame:SetMovable(true) - ciFrame:SetFrameStrata("HIGH") + ciFrame:SetFrameStrata(Gladdy.db.ciFrameStrata) + ciFrame:SetFrameLevel(Gladdy.db.ciFrameLevel) ciFrame:SetHeight(Gladdy.db.ciSize) ciFrame:SetWidth(Gladdy.db.ciSize * Gladdy.db.ciWidthFactor) @@ -60,6 +63,10 @@ function CombatIndicator:UpdateFrame(unit) if (not button or not ciFrame) then return end + + ciFrame:SetFrameStrata(Gladdy.db.ciFrameStrata) + ciFrame:SetFrameLevel(Gladdy.db.ciFrameLevel) + ciFrame:SetHeight(Gladdy.db.ciSize) ciFrame:SetWidth(Gladdy.db.ciSize * Gladdy.db.ciWidthFactor) ciFrame.border:SetTexture(Gladdy.db.ciBorderStyle) @@ -166,7 +173,7 @@ function CombatIndicator:GetOptions() position = { type = "group", name = L["Position"], - order = 4, + order = 3, args = { header = { type = "header", @@ -196,7 +203,7 @@ function CombatIndicator:GetOptions() border = { type = "group", name = L["Border"], - order = 4, + order = 2, args = { header = { type = "header", @@ -218,6 +225,35 @@ function CombatIndicator:GetOptions() }), }, }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 5, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + ciFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + ciFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, }, }, } diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 76f2648..268762d 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -67,6 +67,8 @@ local Cooldowns = Gladdy:NewModule("Cooldowns", nil, { cooldownDisableCircle = false, cooldownCooldownAlpha = 1, cooldownCooldowns = getDefaultCooldown(), + cooldownFrameStrata = "MEDIUM", + cooldownFrameLevel = 3, }) function Cooldowns:Initialize() @@ -95,10 +97,13 @@ function Cooldowns:CreateFrame(unit) local spellCooldownFrame = CreateFrame("Frame", nil, button) spellCooldownFrame:EnableMouse(false) spellCooldownFrame:SetMovable(true) + spellCooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + spellCooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel) for x = 1, 14 do local icon = CreateFrame("Frame", nil, spellCooldownFrame) icon:EnableMouse(false) - icon:SetFrameLevel(3) + icon:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon:SetFrameLevel(Gladdy.db.cooldownFrameLevel) icon.texture = icon:CreateTexture(nil, "BACKGROUND") icon.texture:SetMask("Interface\\AddOns\\Gladdy\\Images\\mask") icon.texture:SetAllPoints(icon) @@ -106,14 +111,16 @@ function Cooldowns:CreateFrame(unit) icon.cooldown = CreateFrame("Cooldown", nil, icon, "CooldownFrameTemplate") icon.cooldown.noCooldownCount = true - icon.cooldown:SetFrameLevel(4) + icon.cooldown:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon.cooldown:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 1) icon.cooldown:SetReverse(false) icon.cooldown:SetHideCountdownNumbers(true) icon.cooldownFrame = CreateFrame("Frame", nil, icon) icon.cooldownFrame:ClearAllPoints() icon.cooldownFrame:SetAllPoints(icon) - icon.cooldownFrame:SetFrameLevel(5) + icon.cooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon.cooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 2) icon.border = icon.cooldownFrame:CreateTexture(nil, "OVERLAY") icon.border:SetAllPoints(icon) @@ -136,6 +143,8 @@ function Cooldowns:UpdateFrame(unit) if (Gladdy.db.cooldown) then button.spellCooldownFrame:SetHeight(Gladdy.db.cooldownSize) button.spellCooldownFrame:SetWidth(1) + button.spellCooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + button.spellCooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel) button.spellCooldownFrame:Show() Gladdy:SetPosition(button.spellCooldownFrame, unit, "cooldownXOffset", "cooldownYOffset", Cooldowns:LegacySetPosition(button, unit), Cooldowns) @@ -149,6 +158,14 @@ function Cooldowns:UpdateFrame(unit) local o = 1 for j = 1, 14 do local icon = button.spellCooldownFrame["icon" .. j] + + icon:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon:SetFrameLevel(Gladdy.db.cooldownFrameLevel) + icon.cooldown:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon.cooldown:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 1) + icon.cooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon.cooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 2) + icon:SetHeight(Gladdy.db.cooldownSize) icon:SetWidth(Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor) icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") @@ -676,7 +693,7 @@ function Cooldowns:GetOptions() position = { type = "group", name = L["Position"], - order = 4, + order = 5, args = { header = { type = "header", @@ -740,7 +757,7 @@ function Cooldowns:GetOptions() border = { type = "group", name = L["Border"], - order = 5, + order = 4, args = { header = { type = "header", @@ -762,6 +779,35 @@ function Cooldowns:GetOptions() }), }, }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 6, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + cooldownFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + cooldownFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, }, }, cooldowns = { diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index a2b89f1..98af424 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -50,6 +50,8 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { drWidthFactor = 1, drCategories = defaultCategories(), drDuration = 18, + drFrameStrata = "MEDIUM", + drFrameLevel = 3, }) local function getDiminishColor(dr) @@ -81,12 +83,15 @@ function Diminishings:CreateFrame(unit) local drFrame = CreateFrame("Frame", nil, Gladdy.buttons[unit]) drFrame:EnableMouse(false) drFrame:SetMovable(true) + drFrame:SetFrameStrata(Gladdy.db.drFrameStrata) + drFrame:SetFrameLevel(Gladdy.db.drFrameLevel) for i = 1, 16 do local icon = CreateFrame("Frame", "GladdyDr" .. unit .. "Icon" .. i, drFrame) icon:Hide() icon:EnableMouse(false) - icon:SetFrameLevel(3) + icon:SetFrameStrata(Gladdy.db.drFrameStrata) + icon:SetFrameLevel(Gladdy.db.drFrameLevel) icon.texture = icon:CreateTexture(nil, "BACKGROUND") icon.texture:SetMask("Interface\\AddOns\\Gladdy\\Images\\mask") icon.texture:SetAllPoints(icon) @@ -114,13 +119,15 @@ function Diminishings:CreateFrame(unit) icon.cooldown = CreateFrame("Cooldown", nil, icon, "CooldownFrameTemplate") icon.cooldown.noCooldownCount = true --Gladdy.db.trinketDisableOmniCC icon.cooldown:SetHideCountdownNumbers(true) - icon.cooldown:SetFrameLevel(4) + icon.cooldown:SetFrameStrata(Gladdy.db.drFrameStrata) + icon.cooldown:SetFrameLevel(Gladdy.db.drFrameLevel + 1) icon.cooldownFrame = CreateFrame("Frame", nil, icon) icon.cooldownFrame:ClearAllPoints() icon.cooldownFrame:SetPoint("TOPLEFT", icon, "TOPLEFT") icon.cooldownFrame:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT") - icon.cooldownFrame:SetFrameLevel(5) + icon.cooldownFrame:SetFrameStrata(Gladdy.db.drFrameStrata) + icon.cooldownFrame:SetFrameLevel(Gladdy.db.drFrameLevel + 2) --icon.overlay = CreateFrame("Frame", nil, icon) --icon.overlay:SetAllPoints(icon) @@ -181,6 +188,8 @@ function Diminishings:UpdateFrame(unit) drFrame:SetWidth(Gladdy.db.drIconSize) drFrame:SetHeight(Gladdy.db.drIconSize) + drFrame:SetFrameStrata(Gladdy.db.drFrameStrata) + drFrame:SetFrameLevel(Gladdy.db.drFrameLevel) Gladdy:SetPosition(drFrame, unit, "drXOffset", "drYOffset", Diminishings:LegacySetPosition(drFrame, unit), Diminishings) @@ -199,6 +208,13 @@ function Diminishings:UpdateFrame(unit) icon:SetWidth(Gladdy.db.drIconSize * Gladdy.db.drWidthFactor) icon:SetHeight(Gladdy.db.drIconSize) + icon:SetFrameStrata(Gladdy.db.drFrameStrata) + icon:SetFrameLevel(Gladdy.db.drFrameLevel) + icon.cooldown:SetFrameStrata(Gladdy.db.drFrameStrata) + icon.cooldown:SetFrameLevel(Gladdy.db.drFrameLevel + 1) + icon.cooldownFrame:SetFrameStrata(Gladdy.db.drFrameStrata) + icon.cooldownFrame:SetFrameLevel(Gladdy.db.drFrameLevel + 2) + icon.text:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") icon.text:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) icon.timeText:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") @@ -541,7 +557,7 @@ function Diminishings:GetOptions() position = { type = "group", name = L["Position"], - order = 4, + order = 6, args = { headerPosition = { type = "header", @@ -618,7 +634,7 @@ function Diminishings:GetOptions() border = { type = "group", name = L["Border"], - order = 6, + order = 4, args = { headerBorder = { type = "header", @@ -673,6 +689,35 @@ function Diminishings:GetOptions() }), } }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 7, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + drFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + drFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, }, }, categories = { diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 8338a1a..78132cf 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -24,6 +24,8 @@ local Healthbar = Gladdy:NewModule("Health Bar", 100, { healthActual = false, healthMax = true, healthPercentage = true, + healthFrameStrata = "MEDIUM", + healthFrameLevel = 1, }) function Healthbar:Initialize() @@ -42,12 +44,14 @@ function Healthbar:CreateFrame(unit) healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "healthBarBorderStyle"), edgeSize = Gladdy.db.healthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.healthBarBorderColor.r, Gladdy.db.healthBarBorderColor.g, Gladdy.db.healthBarBorderColor.b, Gladdy.db.healthBarBorderColor.a) - healthBar:SetFrameLevel(1) + healthBar:SetFrameStrata(Gladdy.db.healthFrameStrata) + healthBar:SetFrameLevel(Gladdy.db.healthFrameLevel) healthBar.hp = CreateFrame("StatusBar", nil, healthBar) healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "healthBarTexture")) healthBar.hp:SetMinMaxValues(0, 100) - healthBar.hp:SetFrameLevel(0) + healthBar.hp:SetFrameStrata(Gladdy.db.healthFrameStrata) + healthBar.hp:SetFrameLevel(Gladdy.db.healthFrameLevel - 1) healthBar.bg = healthBar.hp:CreateTexture(nil, "BACKGROUND") healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "healthBarTexture")) @@ -150,6 +154,11 @@ function Healthbar:UpdateFrame(unit) return end + healthBar:SetFrameStrata(Gladdy.db.healthFrameStrata) + healthBar:SetFrameLevel(Gladdy.db.healthFrameLevel) + healthBar.hp:SetFrameStrata(Gladdy.db.healthFrameStrata) + healthBar.hp:SetFrameLevel(Gladdy.db.healthFrameLevel - 1) + healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "healthBarTexture")) healthBar.bg:SetVertexColor(Gladdy.db.healthBarBgColor.r, Gladdy.db.healthBarBgColor.g, Gladdy.db.healthBarBgColor.b, Gladdy.db.healthBarBgColor.a) @@ -445,10 +454,39 @@ function Healthbar:GetOptions() }), }, }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 4, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + healthFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + healthFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 1, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, healthValues = { type = "group", name = L["Health Bar Text"], - order = 4, + order = 5, args = { header = { type = "header", diff --git a/Modules/Highlight.lua b/Modules/Highlight.lua index 5cebb1a..0240caa 100644 --- a/Modules/Highlight.lua +++ b/Modules/Highlight.lua @@ -13,6 +13,8 @@ local Highlight = Gladdy:NewModule("Highlight", nil, { targetBorder = true, focusBorder = true, leaderBorder = true, + highlightFrameStrata = "MEDIUM", + highlightFrameLevel = 20, }) function Highlight:Initialize() @@ -56,17 +58,20 @@ function Highlight:CreateFrame(unit) local targetBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") targetBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) - --targetBorder:SetFrameStrata("MEDIUM") + targetBorder:SetFrameStrata(Gladdy.db.highlightFrameStrata) + targetBorder:SetFrameLevel(Gladdy.db.highlightFrameLevel) targetBorder:Hide() local focusBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") focusBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) - --focusBorder:SetFrameStrata("MEDIUM") + focusBorder:SetFrameStrata(Gladdy.db.highlightFrameStrata) + focusBorder:SetFrameLevel(Gladdy.db.highlightFrameLevel) focusBorder:Hide() local leaderBorder = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") leaderBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = Gladdy.db.highlightBorderSize }) - --leaderBorder:SetFrameStrata("MEDIUM") + leaderBorder:SetFrameStrata(Gladdy.db.highlightFrameStrata) + leaderBorder:SetFrameLevel(Gladdy.db.highlightFrameLevel) leaderBorder:Hide() local highlight = healthBar:CreateTexture(nil, "OVERLAY") @@ -96,6 +101,13 @@ function Highlight:UpdateFrame(unit) local width = Gladdy.db.barWidth + (Gladdy.db.highlightInset and 0 or borderSize * 2) local height = hpAndPowerHeight + (Gladdy.db.highlightInset and 0 or borderSize * 2) + button.targetBorder:SetFrameStrata(Gladdy.db.highlightFrameStrata) + button.targetBorder:SetFrameLevel(Gladdy.db.highlightFrameLevel) + button.focusBorder:SetFrameStrata(Gladdy.db.highlightFrameStrata) + button.focusBorder:SetFrameLevel(Gladdy.db.highlightFrameLevel) + button.leaderBorder:SetFrameStrata(Gladdy.db.highlightFrameStrata) + button.leaderBorder:SetFrameLevel(Gladdy.db.highlightFrameLevel) + button.targetBorder:SetWidth(width) button.targetBorder:SetHeight(height) button.targetBorder:ClearAllPoints() @@ -207,67 +219,130 @@ function Highlight:GetOptions() desc = L["Show Highlight border inside of frame"], order = 3, }), - highlightBorderSize = Gladdy:option({ - type = "range", - name = L["Border size"], - desc = L["Border size"], - order = 4, - min = 1, - max = 20, - step = 1, - width = "full", - }), - highlightBorderStyle = Gladdy:option({ - type = "select", - name = L["Border style"], - order = 5, - dialogControl = "LSM30_Border", - values = AceGUIWidgetLSMlists.border, - }), - headerColor = { - type = "header", - name = L["Colors"], - order = 6, + group = { + type = "group", + childGroups = "tree", + name = L["Frame"], + order = 3, + args = { + enabled = { + type = "group", + name = L["Enabled"], + order = 1, + args = { + headerEnable = { + type = "header", + name = L["Enabled"], + order = 10, + }, + highlight = Gladdy:option({ + type = "toggle", + name = L["Highlight target"], + desc = L["Toggle if the selected target should be highlighted"], + order = 11, + width = "full", + }), + targetBorder = Gladdy:option({ + type = "toggle", + name = L["Show border around target"], + desc = L["Toggle if a border should be shown around the selected target"], + order = 12, + width = "full", + }), + focusBorder = Gladdy:option({ + type = "toggle", + name = L["Show border around focus"], + desc = L["Toggle of a border should be shown around the current focus"], + order = 13, + width = "full", + }), + }, + }, + border = { + type = "group", + name = L["Border"], + order = 2, + args = { + headerHighlight = { + type = "header", + name = L["Border"], + order = 2, + }, + highlightBorderSize = Gladdy:option({ + type = "range", + name = L["Border size"], + desc = L["Border size"], + order = 4, + min = 1, + max = 20, + step = 1, + width = "full", + }), + highlightBorderStyle = Gladdy:option({ + type = "select", + name = L["Border style"], + order = 5, + dialogControl = "LSM30_Border", + values = AceGUIWidgetLSMlists.border, + }), + }, + }, + color = { + type = "group", + name = L["Color"], + order = 3, + args = { + headerColor = { + type = "header", + name = L["Colors"], + order = 6, + }, + targetBorderColor = Gladdy:colorOption({ + type = "color", + name = L["Target border color"], + desc = L["Color of the selected targets border"], + order = 7, + hasAlpha = true, + }), + focusBorderColor = Gladdy:colorOption({ + type = "color", + name = L["Focus border color"], + desc = L["Color of the focus border"], + order = 8, + hasAlpha = true, + }), + }, + }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 4, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + highlightFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + highlightFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 1, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, + }, }, - targetBorderColor = Gladdy:colorOption({ - type = "color", - name = L["Target border color"], - desc = L["Color of the selected targets border"], - order = 7, - hasAlpha = true, - }), - focusBorderColor = Gladdy:colorOption({ - type = "color", - name = L["Focus border color"], - desc = L["Color of the focus border"], - order = 8, - hasAlpha = true, - }), - headerEnable = { - type = "header", - name = L["Enabled"], - order = 10, - }, - highlight = Gladdy:option({ - type = "toggle", - name = L["Highlight target"], - desc = L["Toggle if the selected target should be highlighted"], - order = 11, - width = "full", - }), - targetBorder = Gladdy:option({ - type = "toggle", - name = L["Show border around target"], - desc = L["Toggle if a border should be shown around the selected target"], - order = 12, - width = "full", - }), - focusBorder = Gladdy:option({ - type = "toggle", - name = L["Show border around focus"], - desc = L["Toggle of a border should be shown around the current focus"], - order = 13, - width = "full", - }), } end \ No newline at end of file diff --git a/Modules/Pets.lua b/Modules/Pets.lua index b9406e9..fdd33b0 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -25,6 +25,8 @@ local Pets = Gladdy:NewModule("Pets", nil, { petYOffset = -62, petGroup = false, petMargin = 1, + petFrameStrata = "MEDIUM", + petFrameLevel = 5, }) function Pets:Initialize() @@ -156,7 +158,8 @@ function Pets:CreateFrame(unitId) healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "petHealthBarBorderStyle"), edgeSize = Gladdy.db.petHealthBarBorderSize }) healthBar:SetBackdropBorderColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) - healthBar:SetFrameLevel(1) + healthBar:SetFrameStrata(Gladdy.db.petFrameStrata) + healthBar:SetFrameLevel(Gladdy.db.petFrameLevel) healthBar:SetAllPoints(button) healthBar:SetAlpha(0) @@ -174,7 +177,8 @@ function Pets:CreateFrame(unitId) healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "petHealthBarTexture")) healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) healthBar.hp:SetMinMaxValues(0, 100) - healthBar.hp:SetFrameLevel(0) + healthBar.hp:SetFrameStrata(Gladdy.db.petFrameStrata) + healthBar.hp:SetFrameLevel(Gladdy.db.petFrameLevel - 1) healthBar.hp:SetAllPoints(healthBar) healthBar.bg = healthBar.hp:CreateTexture(nil, "BACKGROUND") @@ -245,6 +249,11 @@ function Pets:UpdateFrame(unitId) return end + healthBar:SetFrameStrata(Gladdy.db.petFrameStrata) + healthBar:SetFrameLevel(Gladdy.db.petFrameLevel) + healthBar.hp:SetFrameStrata(Gladdy.db.petFrameStrata) + healthBar.hp:SetFrameLevel(Gladdy.db.petFrameLevel - 1) + if not Gladdy.db.petEnabled then self.frames[unit]:Hide() else @@ -569,10 +578,39 @@ function Pets:GetOptions() }), } }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 6, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + petFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + petFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 1, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, healthValues = { type = "group", name = L["Health Values"], - order = 6, + order = 7, args = { header = { type = "header", diff --git a/Modules/Powerbar.lua b/Modules/Powerbar.lua index eaa961a..af76f5c 100644 --- a/Modules/Powerbar.lua +++ b/Modules/Powerbar.lua @@ -22,6 +22,8 @@ local Powerbar = Gladdy:NewModule("Power Bar", 90, { powerActual = true, powerMax = true, powerPercentage = false, + powerFrameStrata = "MEDIUM", + powerFrameLevel = 1, }) function Powerbar:Initialize() @@ -41,12 +43,14 @@ function Powerbar:CreateFrame(unit) powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "powerBarBorderStyle"), edgeSize = Gladdy.db.powerBarBorderSize }) powerBar:SetBackdropBorderColor(Gladdy.db.powerBarBorderColor.r, Gladdy.db.powerBarBorderColor.g, Gladdy.db.powerBarBorderColor.b, Gladdy.db.powerBarBorderColor.a) - powerBar:SetFrameLevel(1) + powerBar:SetFrameStrata(Gladdy.db.powerFrameStrata) + powerBar:SetFrameLevel(Gladdy.db.powerFrameLevel) powerBar.energy = CreateFrame("StatusBar", nil, powerBar) powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) powerBar.energy:SetMinMaxValues(0, 100) - powerBar.energy:SetFrameLevel(0) + powerBar.energy:SetFrameStrata(Gladdy.db.powerFrameStrata) + powerBar.energy:SetFrameLevel(Gladdy.db.powerFrameLevel - 1) powerBar.bg = powerBar.energy:CreateTexture(nil, "BACKGROUND") powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) @@ -139,10 +143,8 @@ function Powerbar:UpdateFrame(unit) if (not powerBar) then return end - local healthBar = Gladdy.modules["Health Bar"].frames[unit] - if not Gladdy.db.powerBarEnabled then powerBar:Hide() return @@ -171,6 +173,11 @@ function Powerbar:UpdateFrame(unit) powerBar.raceText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) powerBar.powerText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) + + powerBar:SetFrameStrata(Gladdy.db.powerFrameStrata) + powerBar:SetFrameLevel(Gladdy.db.powerFrameLevel) + powerBar.energy:SetFrameStrata(Gladdy.db.powerFrameStrata) + powerBar.energy:SetFrameLevel(Gladdy.db.powerFrameLevel - 1) end function Powerbar:ResetUnit(unit) @@ -455,10 +462,39 @@ function Powerbar:GetOptions() }), }, }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 4, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + powerFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + powerFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 1, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, powerValues = { type = "group", name = L["Power Bar Text"], - order = 4, + order = 5, args = { header = { type = "header", diff --git a/Modules/Racial.lua b/Modules/Racial.lua index b03c6d2..153c71f 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -18,6 +18,8 @@ local Racial = Gladdy:NewModule("Racial", 79, { racialDisableCircle = false, racialCooldownAlpha = 1, racialCooldownNumberAlpha = 1, + racialFrameStrata = "MEDIUM", + racialFrameLevel = 5, }) @@ -63,6 +65,9 @@ end function Racial:CreateFrame(unit) local racial = CreateFrame("Button", "GladdyTrinketButton" .. unit, Gladdy.buttons[unit]) racial:EnableMouse(false) + racial:SetFrameStrata(Gladdy.db.racialFrameStrata) + racial:SetFrameLevel(Gladdy.db.racialFrameLevel) + racial.texture = racial:CreateTexture(nil, "BACKGROUND") racial.texture:SetAllPoints(racial) racial.texture:SetMask("Interface\\AddOns\\Gladdy\\Images\\mask") @@ -76,6 +81,8 @@ function Racial:CreateFrame(unit) racial.cooldownFrame:ClearAllPoints() racial.cooldownFrame:SetPoint("TOPLEFT", racial, "TOPLEFT") racial.cooldownFrame:SetPoint("BOTTOMRIGHT", racial, "BOTTOMRIGHT") + racial.cooldownFrame:SetFrameStrata(Gladdy.db.racialFrameStrata) + racial.cooldownFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 1) racial.cooldownFont = racial.cooldownFrame:CreateFontString(nil, "OVERLAY") racial.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), 20, "OUTLINE") @@ -85,6 +92,9 @@ function Racial:CreateFrame(unit) racial.borderFrame = CreateFrame("Frame", nil, racial) racial.borderFrame:SetAllPoints(racial) + racial.borderFrame:SetFrameStrata(Gladdy.db.racialFrameStrata) + racial.borderFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 2) + racial.texture.overlay = racial.borderFrame:CreateTexture(nil, "OVERLAY") racial.texture.overlay:SetAllPoints(racial) racial.texture.overlay:SetTexture(Gladdy.db.racialBorderStyle) @@ -103,6 +113,13 @@ function Racial:UpdateFrame(unit) local width, height = Gladdy.db.racialSize * Gladdy.db.racialWidthFactor, Gladdy.db.racialSize + racial:SetFrameStrata(Gladdy.db.racialFrameStrata) + racial:SetFrameLevel(Gladdy.db.racialFrameLevel) + racial.cooldownFrame:SetFrameStrata(Gladdy.db.racialFrameStrata) + racial.cooldownFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 1) + racial.borderFrame:SetFrameStrata(Gladdy.db.racialFrameStrata) + racial.borderFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 2) + racial:SetWidth(width) racial:SetHeight(height) racial.cooldown:SetWidth(width - width/16) @@ -311,37 +328,13 @@ function Racial:GetOptions() position = { type = "group", name = L["Position"], - order = 4, + order = 5, args = { header = { type = "header", name = L["Icon position"], order = 4, }, - racialAnchor = Gladdy:option({ - type = "select", - name = L["Anchor"], - desc = L["This changes the anchor of the racial icon"], - order = 20, - values = { - ["trinket"] = L["Trinket"], - ["classIcon"] = L["Class Icon"], - ["healthBar"] = L["Health Bar"], - ["powerBar"] = L["Power Bar"], - }, - }), - racialPos = Gladdy:option({ - type = "select", - name = L["Icon position"], - desc = L["This changes position relative to its anchor of the racial icon"], - order = 21, - values = { - ["LEFT"] = L["Left"], - ["RIGHT"] = L["Right"], - ["TOP"] = L["Top"], - ["BOTTOM"] = L["Bottom"], - }, - }), racialXOffset = Gladdy:option({ type = "range", name = L["Horizontal offset"], @@ -387,6 +380,35 @@ function Racial:GetOptions() }), }, }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 6, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + racialFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + racialFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, }, }, } diff --git a/Modules/ShadowsightTimer.lua b/Modules/ShadowsightTimer.lua index d25dfc3..09d9631 100644 --- a/Modules/ShadowsightTimer.lua +++ b/Modules/ShadowsightTimer.lua @@ -21,6 +21,8 @@ local ShadowsightTimer = Gladdy:NewModule("Shadowsight Timer", nil, { shadowsightTimerStartTime = 91, shadowsightTimerResetTime = 120, shadowsightTimerShowTwoTimer = false, + shadowsightTimerFrameStrata = "HIGH", + shadowsightTimerFrameLevel = 20, }) -- /run LibStub("Gladdy").modules["Shadowsight Timer"]:AURA_GAIN(nil, nil, 34709) @@ -78,6 +80,9 @@ function ShadowsightTimer:CreateTimerFrame(anchor, name, points) self[name].font:SetPoint("LEFT", 5, 0) self[name].font:SetJustifyH("LEFT") self[name].font:SetTextColor(1, 0.8, 0) + + self[name]:SetFrameStrata(Gladdy.db.shadowsightTimerFrameStrata) + self[name]:SetFrameLevel(Gladdy.db.shadowsightTimerFrameLevel) end function ShadowsightTimer:CreateAnchor() @@ -102,6 +107,14 @@ end function ShadowsightTimer:UpdateFrameOnce() self.anchor:EnableMouse(not Gladdy.db.shadowsightTimerLocked) + + self.anchor:SetFrameStrata(Gladdy.db.shadowsightTimerFrameStrata) + self.anchor:SetFrameLevel(Gladdy.db.shadowsightTimerFrameLevel) + self.timerFrame1:SetFrameStrata(Gladdy.db.shadowsightTimerFrameStrata) + self.timerFrame1:SetFrameLevel(Gladdy.db.shadowsightTimerFrameLevel) + self.timerFrame2:SetFrameStrata(Gladdy.db.shadowsightTimerFrameStrata) + self.timerFrame2:SetFrameLevel(Gladdy.db.shadowsightTimerFrameLevel) + if Gladdy.db.shadowsightTimerEnabled then self.anchor:SetScale(Gladdy.db.shadowsightTimerScale) self.anchor:ClearAllPoints() @@ -268,7 +281,7 @@ end function ShadowsightTimer:GetOptions() return { - headerArenaCountdown = { + headerShadowsight = { type = "header", name = L["Shadowsight Timer"], order = 2, @@ -278,61 +291,143 @@ function ShadowsightTimer:GetOptions() name = L["Enabled"], --desc = L["Turns countdown before the start of an arena match on/off."], order = 3, - width = "full", }), shadowsightTimerLocked = Gladdy:option({ type = "toggle", name = L["Locked"], --desc = L["Turns countdown before the start of an arena match on/off."], order = 4, - width = "full", }), shadowsightTimerShowTwoTimer = Gladdy:option({ type = "toggle", name = L["Show two timers"], order = 5, - width = "full", }), shadowsightAnnounce = Gladdy:option({ type = "toggle", name = L["Announce"], --desc = L["Turns countdown before the start of an arena match on/off."], order = 6, - width = "full", }), - shadowsightTimerScale = Gladdy:option({ - type = "range", - name = L["Scale"], + group = { + type = "group", + childGroups = "tree", + name = L["Frame"], order = 7, - min = 0.1, - max = 5, - step = 0.1, - width = "full", - }), - headerTimer = { - type = "header", - name = L["Shadowsight CDs"], - order = 10, + args = { + general = { + type = "group", + name = L["Scale"], + order = 1, + args = { + header = { + type = "header", + name = L["Scale"], + order = 1, + }, + shadowsightTimerScale = Gladdy:option({ + type = "range", + name = L["Scale"], + order = 2, + min = 0.1, + max = 5, + step = 0.1, + width = "full", + }), + }, + }, + cooldown = { + type = "group", + name = L["Cooldown"], + order = 2, + args = { + header = { + type = "header", + name = L["Shadowsight CDs"], + order = 1, + }, + shadowsightTimerStartTime = Gladdy:option({ + type = "range", + name = L["Start Time"], + desc = L["Start time in seconds"], + min = 80, + max = 100, + order = 2, + step = 0.1, + width = "full", + }), + shadowsightTimerResetTime = Gladdy:option({ + type = "range", + name = L["Reset Time"], + desc = L["Reset time in seconds"], + min = 110, + max = 130, + order = 3, + step = 0.1, + width = "full", + }), + }, + }, + --[[font = { + type = "group", + name = L["Font"], + order = 3, + args = { + header = { + type = "header", + name = L["Font"], + order = 4, + }, + racialFont = Gladdy:option({ + type = "select", + name = L["Font"], + desc = L["Font of the cooldown"], + order = 11, + dialogControl = "LSM30_Font", + values = AceGUIWidgetLSMlists.font, + }), + racialFontScale = Gladdy:option({ + type = "range", + name = L["Font scale"], + desc = L["Scale of the font"], + order = 12, + min = 0.1, + max = 2, + step = 0.1, + width = "full", + }), + }, + },--]] + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 6, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + shadowsightTimerFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + shadowsightTimerFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, + }, }, - shadowsightTimerStartTime = Gladdy:option({ - type = "range", - name = L["Start Time"], - desc = L["Start time in seconds"], - min = 80, - max = 100, - order = 11, - step = 0.1, - width = "full", - }), - shadowsightTimerResetTime = Gladdy:option({ - type = "range", - name = L["Reset Time"], - desc = L["Reset time in seconds"], - min = 110, - max = 130, - order = 12, - step = 0.1, - width = "full", - }), } end \ No newline at end of file diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 928d30c..41a68ba 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -19,6 +19,8 @@ local Trinket = Gladdy:NewModule("Trinket", 80, { trinketCooldownNumberAlpha = 1, trinketXOffset = 0, trinketYOffset = 0, + trinketFrameStrata = "MEDIUM", + trinketFrameLevel = 5, }) function Trinket:Initialize() @@ -62,6 +64,9 @@ end function Trinket:CreateFrame(unit) local trinket = CreateFrame("Button", "GladdyTrinketButton" .. unit, Gladdy.buttons[unit]) trinket:EnableMouse(false) + trinket:SetFrameStrata(Gladdy.db.trinketFrameStrata) + trinket:SetFrameLevel(Gladdy.db.trinketFrameLevel) + trinket.texture = trinket:CreateTexture(nil, "BACKGROUND") trinket.texture:SetAllPoints(trinket) trinket.texture:SetTexture("Interface\\Icons\\INV_Jewelry_TrinketPVP_02") @@ -70,11 +75,15 @@ function Trinket:CreateFrame(unit) trinket.cooldown = CreateFrame("Cooldown", nil, trinket, "CooldownFrameTemplate") trinket.cooldown.noCooldownCount = true --Gladdy.db.trinketDisableOmniCC trinket.cooldown:SetHideCountdownNumbers(true) + trinket.cooldown:SetFrameStrata(Gladdy.db.trinketFrameStrata) + trinket.cooldown:SetFrameLevel(Gladdy.db.trinketFrameLevel + 1) trinket.cooldownFrame = CreateFrame("Frame", nil, trinket) trinket.cooldownFrame:ClearAllPoints() trinket.cooldownFrame:SetPoint("TOPLEFT", trinket, "TOPLEFT") trinket.cooldownFrame:SetPoint("BOTTOMRIGHT", trinket, "BOTTOMRIGHT") + trinket.cooldownFrame:SetFrameStrata(Gladdy.db.trinketFrameStrata) + trinket.cooldownFrame:SetFrameLevel(Gladdy.db.trinketFrameLevel + 2) trinket.cooldownFont = trinket.cooldownFrame:CreateFontString(nil, "OVERLAY") trinket.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), 20, "OUTLINE") @@ -84,6 +93,9 @@ function Trinket:CreateFrame(unit) trinket.borderFrame = CreateFrame("Frame", nil, trinket) trinket.borderFrame:SetAllPoints(trinket) + trinket.borderFrame:SetFrameStrata(Gladdy.db.trinketFrameStrata) + trinket.borderFrame:SetFrameLevel(Gladdy.db.trinketFrameLevel + 3) + trinket.texture.overlay = trinket.borderFrame:CreateTexture(nil, "OVERLAY") trinket.texture.overlay:SetAllPoints(trinket) trinket.texture.overlay:SetTexture(Gladdy.db.trinketBorderStyle) @@ -104,6 +116,15 @@ function Trinket:UpdateFrame(unit) local width, height = Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor, Gladdy.db.trinketSize + trinket:SetFrameStrata(Gladdy.db.trinketFrameStrata) + trinket:SetFrameLevel(Gladdy.db.trinketFrameLevel) + trinket.cooldown:SetFrameStrata(Gladdy.db.trinketFrameStrata) + trinket.cooldown:SetFrameLevel(Gladdy.db.trinketFrameLevel + 1) + trinket.cooldownFrame:SetFrameStrata(Gladdy.db.trinketFrameStrata) + trinket.cooldownFrame:SetFrameLevel(Gladdy.db.trinketFrameLevel + 2) + trinket.borderFrame:SetFrameStrata(Gladdy.db.trinketFrameStrata) + trinket.borderFrame:SetFrameLevel(Gladdy.db.trinketFrameLevel + 3) + trinket:SetWidth(width) trinket:SetHeight(height) trinket.cooldown:SetWidth(width - width/16) @@ -316,22 +337,30 @@ function Trinket:GetOptions() position = { type = "group", name = L["Position"], - order = 4, + order = 5, args = { header = { type = "header", name = L["Icon position"], order = 4, }, - trinketPos = Gladdy:option({ - type = "select", - name = L["Icon position"], - desc = L["This changes positions of the trinket"], - order = 21, - values = { - ["LEFT"] = L["Left"], - ["RIGHT"] = L["Right"], - }, + trinketXOffset = Gladdy:option({ + type = "range", + name = L["Horizontal offset"], + order = 23, + min = -800, + max = 800, + step = 0.1, + width = "full", + }), + trinketYOffset = Gladdy:option({ + type = "range", + name = L["Vertical offset"], + order = 24, + min = -800, + max = 800, + step = 0.1, + width = "full", }), }, }, @@ -360,6 +389,35 @@ function Trinket:GetOptions() }), }, }, + frameStrata = { + type = "group", + name = L["Frame Strata and Level"], + order = 6, + args = { + headerAuraLevel = { + type = "header", + name = L["Frame Strata and Level"], + order = 1, + }, + trinketFrameStrata = Gladdy:option({ + type = "select", + name = L["Frame Strata"], + order = 2, + values = Gladdy.frameStrata, + sorting = Gladdy.frameStrataSorting, + width = "full", + }), + trinketFrameLevel = Gladdy:option({ + type = "range", + name = L["Frame Level"], + min = 0, + max = 500, + step = 1, + order = 3, + width = "full", + }), + }, + }, }, }, } -- 2.39.5 From 1dd411fed760378853df35745fec61546faac1fc Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 20:57:53 +0100 Subject: [PATCH 091/268] green colored trinket option added --- Modules/Trinket.lua | 59 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 41a68ba..5bf0fda 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -9,6 +9,7 @@ local L = Gladdy.L local Trinket = Gladdy:NewModule("Trinket", 80, { trinketFont = "DorisPP", trinketFontScale = 1, + trinketFontEnabled = true, trinketEnabled = true, trinketSize = 60 + 20 + 1, trinketWidthFactor = 0.9, @@ -21,6 +22,7 @@ local Trinket = Gladdy:NewModule("Trinket", 80, { trinketYOffset = 0, trinketFrameStrata = "MEDIUM", trinketFrameLevel = 5, + trinketColored = false, }) function Trinket:Initialize() @@ -35,6 +37,9 @@ local function iconTimer(self, elapsed) self.active = false self.cooldown:Clear() Gladdy:SendMessage("TRINKET_READY", self.unit) + if Gladdy.db.trinketColored then + self:SetBackdropColor(0,1,0,1) + end else self.timeLeft = self.timeLeft - elapsed end @@ -57,12 +62,17 @@ local function iconTimer(self, elapsed) self.cooldownFont:SetTextColor(1, 0, 0, Gladdy.db.trinketCooldownNumberAlpha) self.cooldownFont:SetFont(Gladdy:SMFetch("font", "trinketFont"), (self:GetWidth()/2 - 1) * Gladdy.db.trinketFontScale, "OUTLINE") end - Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 10, true) + if Gladdy.db.trinketFontEnabled then + Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 10, true) + else + self.cooldownFont:SetText("") + end end end function Trinket:CreateFrame(unit) - local trinket = CreateFrame("Button", "GladdyTrinketButton" .. unit, Gladdy.buttons[unit]) + local trinket = CreateFrame("Button", "GladdyTrinketButton" .. unit, Gladdy.buttons[unit], BackdropTemplateMixin and "BackdropTemplate") + trinket:SetBackdrop({bgFile = "Interface\\AddOns\\Gladdy\\Images\\trinket" }) trinket:EnableMouse(false) trinket:SetFrameStrata(Gladdy.db.trinketFrameStrata) trinket:SetFrameLevel(Gladdy.db.trinketFrameLevel) @@ -114,6 +124,18 @@ function Trinket:UpdateFrame(unit) return end + if Gladdy.db.trinketColored then + if trinket.active then + trinket:SetBackdropColor(1,0,0,1) + else + trinket:SetBackdropColor(0,1,0,1) + end + trinket.texture:SetTexture() + else + trinket:SetBackdropColor(0,1,0,0) + trinket.texture:SetTexture("Interface\\Icons\\INV_Jewelry_TrinketPVP_02") + end + local width, height = Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor, Gladdy.db.trinketSize trinket:SetFrameStrata(Gladdy.db.trinketFrameStrata) @@ -151,7 +173,15 @@ function Trinket:UpdateFrame(unit) 0) end - if (Gladdy.db.trinketEnabled == false) then + trinket.cooldown:SetAlpha(Gladdy.db.trinketCooldownAlpha) + + if Gladdy.db.trinketDisableCircle then + trinket.cooldown:Hide() + else + trinket.cooldown:Show() + end + + if (not Gladdy.db.trinketEnabled) then trinket:Hide() else trinket:Show() @@ -215,6 +245,9 @@ function Trinket:Used(unit, startTime, duration) trinket.timeLeft = (startTime/1000.0 + duration/1000.0) - GetTime() if not Gladdy.db.trinketDisableCircle then trinket.cooldown:SetCooldown(startTime/1000.0, duration/1000.0) end trinket.active = true + if Gladdy.db.trinketColored then + trinket:SetBackdropColor(1,0,0,1) + end Gladdy:SendMessage("TRINKET_USED", unit) end end @@ -232,11 +265,17 @@ function Trinket:GetOptions() desc = L["Enable trinket icon"], order = 3, }), + trinketColored = Gladdy:option({ + type = "toggle", + name = L["Green colored trinket"], + desc = L["Shows a green icon when off CD and red when on CD."], + order = 4, + }), group = { type = "group", childGroups = "tree", name = L["Frame"], - order = 4, + order = 5, args = { general = { type = "group", @@ -312,13 +351,19 @@ function Trinket:GetOptions() header = { type = "header", name = L["Font"], - order = 4, + order = 1, }, + trinketFontEnabled = Gladdy:option({ + type = "toggle", + name = L["Font Enabled"], + order = 2, + width = "full", + }), trinketFont = Gladdy:option({ type = "select", name = L["Font"], desc = L["Font of the cooldown"], - order = 11, + order = 3, dialogControl = "LSM30_Font", values = AceGUIWidgetLSMlists.font, }), @@ -326,7 +371,7 @@ function Trinket:GetOptions() type = "range", name = L["Font scale"], desc = L["Scale of the font"], - order = 12, + order = 4, min = 0.1, max = 2, step = 0.1, -- 2.39.5 From 1e926024cee557ec91877146eed4113c9f7b121f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 20:58:20 +0100 Subject: [PATCH 092/268] green colored trinket option added --- Images/trinket.blp | Bin 0 -> 6660 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Images/trinket.blp diff --git a/Images/trinket.blp b/Images/trinket.blp new file mode 100644 index 0000000000000000000000000000000000000000..ad29aaa96e4871fc24994034db7f12f20e2c017b GIT binary patch literal 6660 zcmeHLOGs2v82)FpQbtDup$C$dxGFI+qBb*^HW>yMnN%c2MUX^IEu*wmv@j|Y!c3E( zHiZbes20tDMav=;ga|Y(Aqpqd>7mT&f875%j!Co_!Mq2~<2(QRyXT(a&h}lqH+cZS zo8j?TI8$#*$DW6MCH7SSz1WAbk7G|?jS7Ejxu}3X03BO65!62Q(HMktH&ndcOwD86 zxbyUK&-vlt{qif1@(TKb%~i$E_LlVo3lEBUTSNRvU=*6-LMPiXGnwMljCe6o3>JHOfoBzF)^cByvXJaqP zL$*G}pY{(xnEYs4?tj-#a?L;2u0!SY9H^NznWx7N&a?Pd(br#S4ShBPx!@N{T8*7-2HQ??D1SpXtsATsj`zMu^64Lv`d?OfI9^A= zjuEQ!!ML2CeT{+7guCAc*#EYEnfDLJ_`Elj$T^4y#9s3rtM6j{pFcc22drzXzxKdu z#uvLJzUptb`Z!K zTHn9spTvh_zF6va3YO>ZK(~G-#N|U7aL)%Zpls-U>0)KTJsaz^cA$I&M$riNxk?fh<`26b4#rMzvIKH*WlN0V!bfgX(ss+PpqFdQiH=_d?uVa z|KwR(YVud_sp7}=uM8}f=Qn9O4d5#{Z}oXjx!rH+H(9sp+-20KO=J63Z6nQ FzX3$kCJ_Jt literal 0 HcmV?d00001 -- 2.39.5 From 22526c03869c50d5556ba472f5e09ac2e4098904 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 21:04:25 +0100 Subject: [PATCH 093/268] cleanup --- Gladdy.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index e378938..416ba57 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -216,11 +216,11 @@ function Gladdy:DeleteUnknownOptions(tbl, refTbl, str) end for k,v in pairs(tbl) do if refTbl[k] == nil then - --Gladdy:Print("SavedVariable deleted:", str .. "." .. k, "not found!") + Gladdy:Debug("INFO", "SavedVariable deleted:", str .. "." .. k, "not found!") tbl[k] = nil else if type(v) ~= type(refTbl[k]) then - --Gladdy:Print("SavedVariable deleted:", str .. "." .. k, "type error!", "Expected", type(refTbl[k]), "but found", type(v)) + Gladdy:Debug("INFO", "SavedVariable deleted:", str .. "." .. k, "type error!", "Expected", type(refTbl[k]), "but found", type(v)) tbl[k] = nil elseif type(v) == "table" then Gladdy:DeleteUnknownOptions(v, refTbl[k], str .. "." .. k) -- 2.39.5 From 12abedfd0f0fd8b1890a390fe32d264eaac9451b Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 21:08:30 +0100 Subject: [PATCH 094/268] readme added features --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 112f909..baceaaa 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Thank you for the great feedback and active contribution. - **big overhaul of positioning elements added! All elements besides HP and PowerBar can be moved separately** - added Mover Frames for Auras, Interrupts, (De)Buffs, CastBar, ClassIcon, CombatIndicator, Cooldowns, DRs, Pets, Racial, Trinket - this will hopefully make configuration a lot easier + - all visible elements' FrameStrata and FrameLevel can be configured (overlap frames how you want it) - **SpecDetection:** - fixed spec detection for Paladins - added following spells for better spec detection: @@ -123,6 +124,7 @@ Thank you for the great feedback and active contribution. - **Shadowsight:** - reset timer when buff was taken - add a configurable 2nd timer or show one timer with the closest CD +- **Trinket: green/red option added** - **fixed some DR-categories** (Hibernate / Chastice / Dragonsbreath / ImpConcussiveShot / Counterattack) - **Pixel Perfect option added** (makes your Gladdy Frames pixel perfect - no more wierd scaling interferences) - **Pets can be grouped** (not perfect yet, but a first step) -- 2.39.5 From 061bc5859cdf421cc235d3f272abfaeccfe6ba8d Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 21:31:56 +0100 Subject: [PATCH 095/268] imp blink is Arcane --- Constants.lua | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Constants.lua b/Constants.lua index d04dcda..8bbd4c7 100644 --- a/Constants.lua +++ b/Constants.lua @@ -35,7 +35,7 @@ local specBuffs = { [GetSpellInfo(12043)] = L["Arcane"], -- Presence of Mind [GetSpellInfo(31589)] = L["Arcane"], -- Slow [GetSpellInfo(12472)] = L["Frost"], -- Icy Veins - [GetSpellInfo(46989)] = L["Fire"], -- Improved Blink + [GetSpellInfo(46989)] = L["Arcane"], -- Improved Blink -- PALADIN [GetSpellInfo(31836)] = L["Holy"], -- Light's Grace diff --git a/README.md b/README.md index baceaaa..19c87b6 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Thank you for the great feedback and active contribution. **Here is a list of all changes:** - **major release version set to v2** - - this will mean, that export strings will still be backwards compatible, but not forward (v2 String cant be imported into v1 Strings but vice versa) + - this will mean, that export strings will still be backwards compatible, but not forward (Gladdy v2.x String cant be imported into Gladdy v1.x but vice versa) - **big overhaul of positioning elements added! All elements besides HP and PowerBar can be moved separately** - added Mover Frames for Auras, Interrupts, (De)Buffs, CastBar, ClassIcon, CombatIndicator, Cooldowns, DRs, Pets, Racial, Trinket - this will hopefully make configuration a lot easier @@ -89,7 +89,7 @@ Thank you for the great feedback and active contribution. - added following spells for better spec detection: - Expose Weakness (Survival Hunter) - Slow (Arcane Mage) - - Improved Blink (Fire Mage) + - Improved Blink (Arcane Mage) - Vindication (Retribution Paladin) - Holy Shield (Protection Paladin) - Vampiric Embrace (Shadow Priest) @@ -100,7 +100,7 @@ Thank you for the great feedback and active contribution. - Healing Way (Restoration Shaman) - Totem of Wrath (Elemental Shaman) - Dark Pact (Affliction Warlock) - - Conflagate (Destruction Warlock) + - Conflagrate (Destruction Warlock) - Shield Slam (Protection Warrior) - **Cooldowns:** - added Fear Ward and Fear Ward Cooldown Detection in case it was used before arena -- 2.39.5 From 298ce642fc70584fbb00d32b1f6fed7881356bab Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 22:15:39 +0100 Subject: [PATCH 096/268] fixed racial cooldowncircle --- Modules/Racial.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Modules/Racial.lua b/Modules/Racial.lua index 153c71f..717e4d5 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -76,13 +76,15 @@ function Racial:CreateFrame(unit) racial.cooldown = CreateFrame("Cooldown", nil, racial, "CooldownFrameTemplate") racial.cooldown.noCooldownCount = true --Gladdy.db.racialDisableOmniCC racial.cooldown:SetHideCountdownNumbers(true) + racial.cooldown:SetFrameStrata(Gladdy.db.racialFrameStrata) + racial.cooldown:SetFrameLevel(Gladdy.db.racialFrameLevel + 1) racial.cooldownFrame = CreateFrame("Frame", nil, racial) racial.cooldownFrame:ClearAllPoints() racial.cooldownFrame:SetPoint("TOPLEFT", racial, "TOPLEFT") racial.cooldownFrame:SetPoint("BOTTOMRIGHT", racial, "BOTTOMRIGHT") racial.cooldownFrame:SetFrameStrata(Gladdy.db.racialFrameStrata) - racial.cooldownFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 1) + racial.cooldownFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 2) racial.cooldownFont = racial.cooldownFrame:CreateFontString(nil, "OVERLAY") racial.cooldownFont:SetFont(Gladdy:SMFetch("font", "racialFont"), 20, "OUTLINE") @@ -93,7 +95,7 @@ function Racial:CreateFrame(unit) racial.borderFrame = CreateFrame("Frame", nil, racial) racial.borderFrame:SetAllPoints(racial) racial.borderFrame:SetFrameStrata(Gladdy.db.racialFrameStrata) - racial.borderFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 2) + racial.borderFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 3) racial.texture.overlay = racial.borderFrame:CreateTexture(nil, "OVERLAY") racial.texture.overlay:SetAllPoints(racial) @@ -115,10 +117,12 @@ function Racial:UpdateFrame(unit) racial:SetFrameStrata(Gladdy.db.racialFrameStrata) racial:SetFrameLevel(Gladdy.db.racialFrameLevel) + racial.cooldown:SetFrameStrata(Gladdy.db.racialFrameStrata) + racial.cooldown:SetFrameLevel(Gladdy.db.racialFrameLevel + 1) racial.cooldownFrame:SetFrameStrata(Gladdy.db.racialFrameStrata) - racial.cooldownFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 1) + racial.cooldownFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 2) racial.borderFrame:SetFrameStrata(Gladdy.db.racialFrameStrata) - racial.borderFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 2) + racial.borderFrame:SetFrameLevel(Gladdy.db.racialFrameLevel + 3) racial:SetWidth(width) racial:SetHeight(height) @@ -178,7 +182,7 @@ function Racial:Used(unit, startTime, duration) end if not racial.active then racial.timeLeft = duration - if not Gladdy.db.trinketDisableCircle then racial.cooldown:SetCooldown(startTime, duration) end + if not Gladdy.db.racialDisableCircle then racial.cooldown:SetCooldown(startTime, duration) end racial.active = true end end -- 2.39.5 From d24b330411033747fffa755d2d035196b9383fbb Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 22:16:02 +0100 Subject: [PATCH 097/268] added option to hide castbar icon --- Modules/Castbar.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 9a16ff2..10526fc 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -33,6 +33,7 @@ local Castbar = Gladdy:NewModule("Cast Bar", 70, { castBarIconColor = { r = 0, g = 0, b = 0, a = 1 }, castBarBorderColor = { r = 0, g = 0, b = 0, a = 1 }, castBarFontColor = { r = 1, g = 1, b = 1, a = 1 }, + castBarIconEnabled = true, castBarGuesses = true, castBarXOffset = 0, castBarYOffset = 0, @@ -173,6 +174,11 @@ function Castbar:UpdateFrame(unit) castBar.icon:SetHeight(Gladdy.db.castBarIconSize) castBar.icon.texture:SetAllPoints(castBar.icon) castBar.icon:ClearAllPoints() + if Gladdy.db.castBarIconEnabled then + castBar.icon:Show() + else + castBar.icon:Hide() + end local rightMargin = 0 local leftMargin = 0 @@ -664,6 +670,12 @@ function Castbar:GetOptions() name = L["Icon Size"], order = 1, }, + castBarIconEnabled = option({ + type = "toggle", + name = L["Icon Enabled"], + order = 2, + width = "full", + }), castBarIconSize = option({ type = "range", name = L["Icon size"], -- 2.39.5 From e5151f16052a3cd304606b2842a4064d9bdd78d6 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 22:17:28 +0100 Subject: [PATCH 098/268] added option to hide castbar icon --- Modules/Castbar.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 10526fc..06d3ff7 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -423,7 +423,11 @@ function Castbar:CAST_START(unit, spell, icon, value, maxValue, test) castBar.spark:Show() end castBar:SetAlpha(1) - castBar.icon:Show() + if Gladdy.db.castBarIconEnabled then + castBar.icon:Show() + else + castBar.icon:Hide() + end end function Castbar:CAST_STOP(unit, ...) -- 2.39.5 From 61c50b3e3266b3e0eec428800389047ca68d14d1 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 22:18:34 +0100 Subject: [PATCH 099/268] readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 19c87b6..9f0084c 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,7 @@ Thank you for the great feedback and active contribution. - **Shadowsight:** - reset timer when buff was taken - add a configurable 2nd timer or show one timer with the closest CD +- **CastBar Icon can be enabled/disabled** - **Trinket: green/red option added** - **fixed some DR-categories** (Hibernate / Chastice / Dragonsbreath / ImpConcussiveShot / Counterattack) - **Pixel Perfect option added** (makes your Gladdy Frames pixel perfect - no more wierd scaling interferences) -- 2.39.5 From 99fa6c0664e12dee7e14274def472c5fff357ae8 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 22:20:53 +0100 Subject: [PATCH 100/268] readme added disclaimer --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9f0084c..ce7c701 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,8 @@ Thank you! This is a packed release with new features and bugfixes. Most importantly, positioning of all elements has been redone with movable frames. Thank you for the great feedback and active contribution. +####Attention: Once you install this version it will drastically change your current profile! You can't go back to an earlier version. Either back up your WTF or export your Profile before updating! + **Here is a list of all changes:** - **major release version set to v2** - this will mean, that export strings will still be backwards compatible, but not forward (Gladdy v2.x String cant be imported into Gladdy v1.x but vice versa) -- 2.39.5 From ea10481c13e9eb7f35fcb77d0462592f09268abd Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 22:39:06 +0100 Subject: [PATCH 101/268] configurable trinket color --- Modules/Trinket.lua | 34 ++++++++++++++++++++++++++++------ Options.lua | 4 ++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 5bf0fda..7a2ba38 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -23,6 +23,8 @@ local Trinket = Gladdy:NewModule("Trinket", 80, { trinketFrameStrata = "MEDIUM", trinketFrameLevel = 5, trinketColored = false, + trinketColoredCd = { r = 1, g = 0, b = 0, a = 1 }, + trinketColoredNoCd = { r = 0, g = 1, b = 0, a = 1 }, }) function Trinket:Initialize() @@ -38,7 +40,7 @@ local function iconTimer(self, elapsed) self.cooldown:Clear() Gladdy:SendMessage("TRINKET_READY", self.unit) if Gladdy.db.trinketColored then - self:SetBackdropColor(0,1,0,1) + self:SetBackdropColor(Gladdy:SetColor(Gladdy.db.trinketColoredNoCd)) end else self.timeLeft = self.timeLeft - elapsed @@ -126,13 +128,13 @@ function Trinket:UpdateFrame(unit) if Gladdy.db.trinketColored then if trinket.active then - trinket:SetBackdropColor(1,0,0,1) + trinket:SetBackdropColor(Gladdy:SetColor(Gladdy.db.trinketColoredCd)) else - trinket:SetBackdropColor(0,1,0,1) + trinket:SetBackdropColor(Gladdy:SetColor(Gladdy.db.trinketColoredNoCd)) end trinket.texture:SetTexture() else - trinket:SetBackdropColor(0,1,0,0) + trinket:SetBackdropColor(Gladdy:SetColor(Gladdy.db.trinketColoredNoCd)) trinket.texture:SetTexture("Interface\\Icons\\INV_Jewelry_TrinketPVP_02") end @@ -160,7 +162,7 @@ function Trinket:UpdateFrame(unit) trinket.texture:SetAllPoints(trinket) trinket.texture.overlay:SetTexture(Gladdy.db.trinketBorderStyle) - trinket.texture.overlay:SetVertexColor(Gladdy.db.trinketBorderColor.r, Gladdy.db.trinketBorderColor.g, Gladdy.db.trinketBorderColor.b, Gladdy.db.trinketBorderColor.a) + trinket.texture.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.trinketBorderColor)) Gladdy:SetPosition(trinket, unit, "trinketXOffset", "trinketYOffset", Trinket:LegacySetPosition(trinket, unit), Trinket) @@ -246,7 +248,7 @@ function Trinket:Used(unit, startTime, duration) if not Gladdy.db.trinketDisableCircle then trinket.cooldown:SetCooldown(startTime/1000.0, duration/1000.0) end trinket.active = true if Gladdy.db.trinketColored then - trinket:SetBackdropColor(1,0,0,1) + trinket:SetBackdropColor(Gladdy:SetColor(Gladdy.db.trinketColoredCd)) end Gladdy:SendMessage("TRINKET_USED", unit) end @@ -271,6 +273,26 @@ function Trinket:GetOptions() desc = L["Shows a green icon when off CD and red when on CD."], order = 4, }), + trinketColoredCd = Gladdy:colorOption({ + type = "color", + name = L["Colored trinket CD"], + desc = L["Color of the border"], + order = 5, + hasAlpha = true, + disabled = function() + return not Gladdy.db.trinketColored + end, + }), + trinketColoredNoCd = Gladdy:colorOption({ + type = "color", + name = L["Colored trinket No CD"], + desc = L["Color of the border"], + order = 6, + hasAlpha = true, + disabled = function() + return not Gladdy.db.trinketColored + end, + }), group = { type = "group", childGroups = "tree", diff --git a/Options.lua b/Options.lua index 0dd3bfe..ea4c3a3 100644 --- a/Options.lua +++ b/Options.lua @@ -104,6 +104,10 @@ function Gladdy:option(params) return defaults end +function Gladdy:SetColor(option) + return option.r, option.g, option.b, option.a +end + function Gladdy:colorOption(params) local defaults = { get = function(info) -- 2.39.5 From 042a8f78129a30188c4ec9cc552f7fe9d38796af Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 23:04:23 +0100 Subject: [PATCH 102/268] colored trinket option wording --- Modules/Trinket.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 7a2ba38..a21ab5e 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -269,8 +269,8 @@ function Trinket:GetOptions() }), trinketColored = Gladdy:option({ type = "toggle", - name = L["Green colored trinket"], - desc = L["Shows a green icon when off CD and red when on CD."], + name = L["Colored trinket"], + desc = L["Shows a solid colored icon when off/off CD."], order = 4, }), trinketColoredCd = Gladdy:colorOption({ -- 2.39.5 From 5f4bf034e583d4d84659abf4c78da688e33aade8 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 23:07:23 +0100 Subject: [PATCH 103/268] use Gladdy:SetColor for all color setters --- Frame.lua | 5 ++--- Modules/Auras.lua | 18 +++++++++--------- Modules/BuffsDebuffs.lua | 2 +- Modules/Castbar.lua | 28 ++++++++++++++-------------- Modules/Classicon.lua | 2 +- Modules/CombatIndicator.lua | 4 ++-- Modules/Cooldowns.lua | 10 +++++----- Modules/Diminishings.lua | 18 +++++++++--------- Modules/Healthbar.lua | 16 ++++++++-------- Modules/Highlight.lua | 6 +++--- Modules/Pets.lua | 26 +++++++++++++------------- Modules/Powerbar.lua | 16 ++++++++-------- Modules/Racial.lua | 2 +- 13 files changed, 76 insertions(+), 77 deletions(-) diff --git a/Frame.lua b/Frame.lua index 7f86b67..79a1354 100644 --- a/Frame.lua +++ b/Frame.lua @@ -39,7 +39,7 @@ function Gladdy:CreateFrame() self.frame.background = CreateFrame("Frame", nil, self.frame, BackdropTemplateMixin and "BackdropTemplate") self.frame.background:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = false, tileSize = 16}) self.frame.background:SetFrameStrata("BACKGROUND") - self.frame.background:SetBackdropColor(self.db.backgroundColor.r, self.db.backgroundColor.g, self.db.backgroundColor.b, self.db.backgroundColor.a) + self.frame.background:SetBackdropColor(Gladdy:SetColor(self.db.backgroundColor)) self.frame.background:SetAllPoints(self.frame) --self.frame.texture = self.frame:CreateTexture(nil, "OVERLAY") --self.frame.texture:SetAllPoints(self.frame) @@ -149,8 +149,7 @@ function Gladdy:UpdateFrame() self.frame:SetWidth(self.db.barWidth + highlightBorderSize) self.frame:SetHeight(height) self.frame:ClearAllPoints() - self.frame.background:SetBackdropColor(self.db.backgroundColor.r, self.db.backgroundColor.g, self.db.backgroundColor.b, self.db.backgroundColor.a) - --self.frame:SetBackdropColor(self.db.frameColor.r, self.db.frameColor.g, self.db.frameColor.b, self.db.frameColor.a) + self.frame.background:SetBackdropColor(Gladdy:SetColor(self.db.backgroundColor)) self.frame:ClearAllPoints() if (self.db.x == 0 and self.db.y == 0) then self.frame:SetPoint("CENTER") diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 367bbf4..7d903e4 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -108,7 +108,7 @@ function Auras:CreateFrame(unit) auraFrame.text = auraFrame.cooldownFrame:CreateFontString(nil, "OVERLAY") auraFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), 10, "OUTLINE") - auraFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) + auraFrame.text:SetTextColor(Gladdy:SetColor(Gladdy.db.auraFontColor)) --auraFrame.text:SetShadowOffset(1, -1) --auraFrame.text:SetShadowColor(0, 0, 0, 1) auraFrame.text:SetJustifyH("CENTER") @@ -181,7 +181,7 @@ function Auras:CreateInterrupt(unit) interruptFrame.text = interruptFrame.cooldownFrame:CreateFontString(nil, "OVERLAY") interruptFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), 10, "OUTLINE") - interruptFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) + interruptFrame.text:SetTextColor(Gladdy:SetColor(Gladdy.db.auraFontColor)) --auraFrame.text:SetShadowOffset(1, -1) --auraFrame.text:SetShadowColor(0, 0, 0, 1) interruptFrame.text:SetJustifyH("CENTER") @@ -280,13 +280,13 @@ function Auras:UpdateFrame(unit) auraFrame.cooldown:SetAlpha(Gladdy.db.auraCooldownAlpha) auraFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") - auraFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) + auraFrame.text:SetTextColor(Gladdy:SetColor(Gladdy.db.auraFontColor)) auraFrame.icon.overlay:SetTexture(Gladdy.db.auraBorderStyle) if auraFrame.track and auraFrame.track == AURA_TYPE_DEBUFF then - auraFrame.icon.overlay:SetVertexColor(Gladdy.db.auraDebuffBorderColor.r, Gladdy.db.auraDebuffBorderColor.g, Gladdy.db.auraDebuffBorderColor.b, Gladdy.db.auraDebuffBorderColor.a) + auraFrame.icon.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.auraDebuffBorderColor)) elseif auraFrame.track and auraFrame.track == AURA_TYPE_BUFF then - auraFrame.icon.overlay:SetVertexColor(Gladdy.db.auraBuffBorderColor.r, Gladdy.db.auraBuffBorderColor.g, Gladdy.db.auraBuffBorderColor.b, Gladdy.db.auraBuffBorderColor.a) + auraFrame.icon.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.auraBuffBorderColor)) else auraFrame.icon.overlay:SetVertexColor(0, 0, 0, 1) end @@ -381,7 +381,7 @@ function Auras:UpdateInterruptFrame(unit) interruptFrame.cooldown:SetAlpha(Gladdy.db.auraCooldownAlpha) interruptFrame.text:SetFont(Gladdy:SMFetch("font", "auraFont"), (width/2 - 1) * Gladdy.db.auraFontSizeScale, "OUTLINE") - interruptFrame.text:SetTextColor(Gladdy.db.auraFontColor.r, Gladdy.db.auraFontColor.g, Gladdy.db.auraFontColor.b, Gladdy.db.auraFontColor.a) + interruptFrame.text:SetTextColor(Gladdy:SetColor(Gladdy.db.auraFontColor)) interruptFrame.icon.overlay:SetTexture(Gladdy.db.auraBorderStyle) if interruptFrame.spellSchool then @@ -522,9 +522,9 @@ function Auras:AURA_GAIN(unit, auraType, spellID, spellName, icon, duration, exp auraFrame.icon.overlay:Show() auraFrame.cooldownFrame:Show() if auraType == AURA_TYPE_DEBUFF then - auraFrame.icon.overlay:SetVertexColor(Gladdy.db.auraDebuffBorderColor.r, Gladdy.db.auraDebuffBorderColor.g, Gladdy.db.auraDebuffBorderColor.b, Gladdy.db.auraDebuffBorderColor.a) + auraFrame.icon.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.auraDebuffBorderColor)) elseif auraType == AURA_TYPE_BUFF then - auraFrame.icon.overlay:SetVertexColor(Gladdy.db.auraBuffBorderColor.r, Gladdy.db.auraBuffBorderColor.g, Gladdy.db.auraBuffBorderColor.b, Gladdy.db.auraBuffBorderColor.a) + auraFrame.icon.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.auraBuffBorderColor)) else auraFrame.icon.overlay:SetVertexColor(Gladdy.db.frameBorderColor.r, Gladdy.db.frameBorderColor.g, Gladdy.db.frameBorderColor.b, Gladdy.db.frameBorderColor.a) end @@ -559,7 +559,7 @@ end function Auras:GetInterruptColor(extraSpellSchool) if not Gladdy.db.auraInterruptColorsEnabled then - return Gladdy.db.auraDebuffBorderColor.r, Gladdy.db.auraDebuffBorderColor.g, Gladdy.db.auraDebuffBorderColor.b, Gladdy.db.auraDebuffBorderColor.a + return Gladdy:SetColor(Gladdy.db.auraDebuffBorderColor) else local color = Gladdy.db.auraInterruptColors[extraSpellSchool] or Gladdy.db.auraInterruptColors["unknown"] return color.r, color.g, color.b, color.a diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 8c75649..d1575a9 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -62,7 +62,7 @@ local function spellSchoolToOptionValue(spellSchool) spellSchoolToOptionValueTable[spellSchool].b, spellSchoolToOptionValueTable[spellSchool].a else - return Gladdy.db.buffsBorderColor.r,Gladdy.db.buffsBorderColor.g,Gladdy.db.buffsBorderColor.b,Gladdy.db.buffsBorderColor.a + return Gladdy:SetColor(Gladdy.db.buffsBorderColor) end end diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 06d3ff7..644bfcd 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -70,13 +70,13 @@ function Castbar:CreateFrame(unit) castBar.backdrop:SetAllPoints(castBar) castBar.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) - castBar.backdrop:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) + castBar.backdrop:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.castBarBorderColor)) castBar.backdrop:SetFrameStrata(Gladdy.db.castBarFrameStrata) castBar.backdrop:SetFrameLevel(Gladdy.db.castBarFrameLevel - 1) castBar.bar = CreateFrame("StatusBar", nil, castBar) castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) - castBar.bar:SetStatusBarColor(Gladdy.db.castBarColor.r, Gladdy.db.castBarColor.g, Gladdy.db.castBarColor.b, Gladdy.db.castBarColor.a) + castBar.bar:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.castBarColor)) castBar.bar:SetMinMaxValues(0, 100) castBar.bar:SetFrameLevel(0) castBar.bar:SetFrameStrata(Gladdy.db.castBarFrameStrata) @@ -92,7 +92,7 @@ function Castbar:CreateFrame(unit) castBar.bg = castBar.bar:CreateTexture(nil, "BACKGROUND") castBar.bg:SetAlpha(1) castBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) - castBar.bg:SetVertexColor(Gladdy.db.castBarBgColor.r, Gladdy.db.castBarBgColor.g, Gladdy.db.castBarBgColor.b, Gladdy.db.castBarBgColor.a) + castBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.castBarBgColor)) castBar.bg:SetAllPoints(castBar.bar) castBar.icon = CreateFrame("Frame", nil, castBar) @@ -114,7 +114,7 @@ function Castbar:CreateFrame(unit) castBar.spellText = castBar:CreateFontString(nil, "LOW") castBar.spellText:SetFont(Gladdy:SMFetch("font", "auraFont"), Gladdy.db.castBarFontSize) - castBar.spellText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) + castBar.spellText:SetTextColor(Gladdy:SetColor(Gladdy.db.castBarFontColor)) castBar.spellText:SetShadowOffset(1, -1) castBar.spellText:SetShadowColor(0, 0, 0, 1) castBar.spellText:SetJustifyH("CENTER") @@ -122,7 +122,7 @@ function Castbar:CreateFrame(unit) castBar.timeText = castBar:CreateFontString(nil, "LOW") castBar.timeText:SetFont(Gladdy:SMFetch("font", "auraFont"), Gladdy.db.castBarFontSize) - castBar.timeText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) + castBar.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.castBarFontColor)) castBar.timeText:SetShadowOffset(1, -1) castBar.timeText:SetShadowColor(0, 0, 0, 1) castBar.timeText:SetJustifyH("CENTER") @@ -152,20 +152,20 @@ function Castbar:UpdateFrame(unit) castBar:SetHeight(Gladdy.db.castBarHeight) castBar.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "castBarBorderStyle"), edgeSize = Gladdy.db.castBarBorderSize }) - castBar.backdrop:SetBackdropBorderColor(Gladdy.db.castBarBorderColor.r, Gladdy.db.castBarBorderColor.g, Gladdy.db.castBarBorderColor.b, Gladdy.db.castBarBorderColor.a) + castBar.backdrop:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.castBarBorderColor)) castBar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) castBar.bar:ClearAllPoints() - castBar.bar:SetStatusBarColor(Gladdy.db.castBarColor.r, Gladdy.db.castBarColor.g, Gladdy.db.castBarColor.b, Gladdy.db.castBarColor.a) + castBar.bar:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.castBarColor)) castBar.bar:SetPoint("TOPLEFT", castBar, "TOPLEFT", (Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset)) castBar.bar:SetPoint("BOTTOMRIGHT", castBar, "BOTTOMRIGHT", -(Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.castBarBorderSize/Gladdy.db.statusbarBorderOffset)) castBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "castBarTexture")) - castBar.bg:SetVertexColor(Gladdy.db.castBarBgColor.r, Gladdy.db.castBarBgColor.g, Gladdy.db.castBarBgColor.b, Gladdy.db.castBarBgColor.a) + castBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.castBarBgColor)) if Gladdy.db.castBarSparkEnabled then castBar.spark:SetHeight(Gladdy.db.castBarHeight * 1.8) - castBar.spark:SetVertexColor(Gladdy.db.castBarSparkColor.r, Gladdy.db.castBarSparkColor.g, Gladdy.db.castBarSparkColor.b, Gladdy.db.castBarSparkColor.a) + castBar.spark:SetVertexColor(Gladdy:SetColor(Gladdy.db.castBarSparkColor)) else castBar.spark:SetAlpha(0) end @@ -193,13 +193,13 @@ function Castbar:UpdateFrame(unit) Gladdy:SetPosition(castBar, unit, "castBarXOffset", "castBarYOffset", Castbar:LegacySetPosition(castBar, unit, leftMargin, rightMargin), Castbar) castBar.spellText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize) - castBar.spellText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) + castBar.spellText:SetTextColor(Gladdy:SetColor(Gladdy.db.castBarFontColor)) castBar.timeText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize) - castBar.timeText:SetTextColor(Gladdy.db.castBarFontColor.r, Gladdy.db.castBarFontColor.g, Gladdy.db.castBarFontColor.b, Gladdy.db.castBarFontColor.a) + castBar.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.castBarFontColor)) castBar.icon.texture.overlay:SetTexture(Gladdy.db.castBarIconStyle) - castBar.icon.texture.overlay:SetVertexColor(Gladdy.db.castBarIconColor.r, Gladdy.db.castBarIconColor.g, Gladdy.db.castBarIconColor.b, Gladdy.db.castBarIconColor.a) + castBar.icon.texture.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.castBarIconColor)) if (unit == "arena1") then Gladdy:CreateMover(castBar, "castBarXOffset", "castBarYOffset", L["Cast Bar"], {"TOPLEFT", "TOPLEFT"}, Gladdy.db.castBarWidth, Gladdy.db.castBarHeight, 0, 0) @@ -409,7 +409,7 @@ function Castbar:CAST_START(unit, spell, icon, value, maxValue, test) castBar.channeling = test == "channel" end - castBar.bar:SetStatusBarColor(Gladdy.db.castBarColor.r, Gladdy.db.castBarColor.g, Gladdy.db.castBarColor.b, Gladdy.db.castBarColor.a) + castBar.bar:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.castBarColor)) castBar.value = value castBar.maxValue = maxValue castBar.bar:SetMinMaxValues(0, maxValue) @@ -594,7 +594,7 @@ function Castbar:GetOptions() desc = L["Height of the bar"], order = 3, min = 0, - max = 50, + max = 100, step = 1, width = "full", }), diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index 01099a6..906954c 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -134,7 +134,7 @@ function Classicon:UpdateFrame(unit) classIcon.texture:SetAllPoints(classIcon) classIcon.texture.overlay:SetTexture(Gladdy.db.classIconBorderStyle) - classIcon.texture.overlay:SetVertexColor(Gladdy.db.classIconBorderColor.r, Gladdy.db.classIconBorderColor.g, Gladdy.db.classIconBorderColor.b, Gladdy.db.classIconBorderColor.a) + classIcon.texture.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.classIconBorderColor)) if Gladdy.db.classIconEnabled then classIcon:Show() else diff --git a/Modules/CombatIndicator.lua b/Modules/CombatIndicator.lua index 5647178..dc2a693 100644 --- a/Modules/CombatIndicator.lua +++ b/Modules/CombatIndicator.lua @@ -51,7 +51,7 @@ function CombatIndicator:CreateFrame(unit) ciFrame.border = ciFrame:CreateTexture(nil, "OVERLAY") ciFrame.border:SetAllPoints(ciFrame) ciFrame.border:SetTexture(Gladdy.db.ciBorderStyle) - ciFrame.border:SetVertexColor(Gladdy.db.ciBorderColor.r, Gladdy.db.ciBorderColor.g, Gladdy.db.ciBorderColor.b, Gladdy.db.ciBorderColor.a) + ciFrame.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.ciBorderColor)) self.frames[unit] = ciFrame button.ciFrame = ciFrame @@ -70,7 +70,7 @@ function CombatIndicator:UpdateFrame(unit) ciFrame:SetHeight(Gladdy.db.ciSize) ciFrame:SetWidth(Gladdy.db.ciSize * Gladdy.db.ciWidthFactor) ciFrame.border:SetTexture(Gladdy.db.ciBorderStyle) - ciFrame.border:SetVertexColor(Gladdy.db.ciBorderColor.r, Gladdy.db.ciBorderColor.g, Gladdy.db.ciBorderColor.b, Gladdy.db.ciBorderColor.a) + ciFrame.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.ciBorderColor)) Gladdy:SetPosition(ciFrame, unit, "ciXOffset", "ciYOffset", CombatIndicator:LegacySetPosition(ciFrame, unit), CombatIndicator) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 268762d..b08fa83 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -125,11 +125,11 @@ function Cooldowns:CreateFrame(unit) icon.border = icon.cooldownFrame:CreateTexture(nil, "OVERLAY") icon.border:SetAllPoints(icon) icon.border:SetTexture(Gladdy.db.cooldownBorderStyle) - icon.border:SetVertexColor(Gladdy.db.cooldownBorderColor.r, Gladdy.db.cooldownBorderColor.g, Gladdy.db.cooldownBorderColor.b, Gladdy.db.cooldownBorderColor.a) + icon.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.cooldownBorderColor)) icon.cooldownFont = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") - icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) + icon.cooldownFont:SetTextColor(Gladdy:SetColor(Gladdy.db.cooldownFontColor)) icon.cooldownFont:SetAllPoints(icon) spellCooldownFrame["icon" .. x] = icon @@ -169,7 +169,7 @@ function Cooldowns:UpdateFrame(unit) icon:SetHeight(Gladdy.db.cooldownSize) icon:SetWidth(Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor) icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") - icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) + icon.cooldownFont:SetTextColor(Gladdy:SetColor(Gladdy.db.cooldownFontColor)) icon:ClearAllPoints() if (Gladdy.db.cooldownXGrowDirection == "LEFT") then if (j == 1) then @@ -217,10 +217,10 @@ function Cooldowns:UpdateFrame(unit) icon.cooldown:SetAlpha(Gladdy.db.cooldownCooldownAlpha) icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), (icon:GetWidth()/2 - 1) * Gladdy.db.cooldownFontScale, "OUTLINE") - icon.cooldownFont:SetTextColor(Gladdy.db.cooldownFontColor.r, Gladdy.db.cooldownFontColor.g, Gladdy.db.cooldownFontColor.b, Gladdy.db.cooldownFontColor.a) + icon.cooldownFont:SetTextColor(Gladdy:SetColor(Gladdy.db.cooldownFontColor)) icon.border:SetTexture(Gladdy.db.cooldownBorderStyle) - icon.border:SetVertexColor(Gladdy.db.cooldownBorderColor.r, Gladdy.db.cooldownBorderColor.g, Gladdy.db.cooldownBorderColor.b, Gladdy.db.cooldownBorderColor.a) + icon.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.cooldownBorderColor)) icon:Hide() end button.spellCooldownFrame:Show() diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 98af424..a83b2d9 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -56,11 +56,11 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { local function getDiminishColor(dr) if dr == 0.5 then - return Gladdy.db.drHalfColor.r, Gladdy.db.drHalfColor.g, Gladdy.db.drHalfColor.b, Gladdy.db.drHalfColor.a + return Gladdy:SetColor(Gladdy.db.drHalfColor) elseif dr == 0.25 then - return Gladdy.db.drQuarterColor.r, Gladdy.db.drQuarterColor.g, Gladdy.db.drQuarterColor.b, Gladdy.db.drQuarterColor.a + return Gladdy:SetColor(Gladdy.db.drQuarterColor) else - return Gladdy.db.drNullColor.r, Gladdy.db.drNullColor.g, Gladdy.db.drNullColor.b, Gladdy.db.drNullColor.a + return Gladdy:SetColor(Gladdy.db.drNullColor) end end @@ -138,7 +138,7 @@ function Diminishings:CreateFrame(unit) icon.text = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") icon.text:SetDrawLayer("OVERLAY") icon.text:SetFont(Gladdy:SMFetch("font", "drFont"), 10, "OUTLINE") - icon.text:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) + icon.text:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) icon.text:SetShadowOffset(1, -1) icon.text:SetShadowColor(0, 0, 0, 1) icon.text:SetJustifyH("CENTER") @@ -147,7 +147,7 @@ function Diminishings:CreateFrame(unit) icon.timeText = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") icon.timeText:SetDrawLayer("OVERLAY") icon.timeText:SetFont(Gladdy:SMFetch("font", "drFont"), 10, "OUTLINE") - icon.timeText:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) + icon.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) icon.timeText:SetShadowOffset(1, -1) icon.timeText:SetShadowColor(0, 0, 0, 1) icon.timeText:SetJustifyH("CENTER") @@ -216,9 +216,9 @@ function Diminishings:UpdateFrame(unit) icon.cooldownFrame:SetFrameLevel(Gladdy.db.drFrameLevel + 2) icon.text:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") - icon.text:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) + icon.text:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) icon.timeText:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") - icon.timeText:SetTextColor(Gladdy.db.drFontColor.r, Gladdy.db.drFontColor.g, Gladdy.db.drFontColor.b, Gladdy.db.drFontColor.a) + icon.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) icon.drLevelText:SetFont(Gladdy:SMFetch("font", "drLevelTextFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drLevelTextFontScale, "OUTLINE") @@ -235,7 +235,7 @@ function Diminishings:UpdateFrame(unit) if Gladdy.db.drBorderColorsEnabled then icon.border:SetVertexColor(getDiminishColor(icon.diminishing)) else - icon.border:SetVertexColor(Gladdy.db.drBorderColor.r, Gladdy.db.drBorderColor.g, Gladdy.db.drBorderColor.b, Gladdy.db.drBorderColor.a) + icon.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.drBorderColor)) end if Gladdy.db.drLevelTextEnabled then @@ -355,7 +355,7 @@ function Diminishings:AuraFade(unit, spellID) if Gladdy.db.drBorderColorsEnabled then lastIcon.border:SetVertexColor(getDiminishColor(lastIcon.diminishing)) else - lastIcon.border:SetVertexColor(Gladdy.db.drBorderColor.r, Gladdy.db.drBorderColor.g, Gladdy.db.drBorderColor.b, Gladdy.db.drBorderColor.a) + lastIcon.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.drBorderColor)) end lastIcon.cooldown:SetCooldown(GetTime(), Gladdy.db.drDuration) if Gladdy.db.drCategories[drCat].forceIcon then diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 78132cf..4d88014 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -43,7 +43,7 @@ function Healthbar:CreateFrame(unit) healthBar:EnableMouse(false) healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "healthBarBorderStyle"), edgeSize = Gladdy.db.healthBarBorderSize }) - healthBar:SetBackdropBorderColor(Gladdy.db.healthBarBorderColor.r, Gladdy.db.healthBarBorderColor.g, Gladdy.db.healthBarBorderColor.b, Gladdy.db.healthBarBorderColor.a) + healthBar:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.healthBarBorderColor)) healthBar:SetFrameStrata(Gladdy.db.healthFrameStrata) healthBar:SetFrameLevel(Gladdy.db.healthFrameLevel) @@ -58,7 +58,7 @@ function Healthbar:CreateFrame(unit) healthBar.bg:ClearAllPoints() healthBar.bg:SetAllPoints(healthBar.hp) healthBar.bg:SetAlpha(1) - healthBar.bg:SetVertexColor(Gladdy.db.healthBarBgColor.r, Gladdy.db.healthBarBgColor.g, Gladdy.db.healthBarBgColor.b, Gladdy.db.healthBarBgColor.a) + healthBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.healthBarBgColor)) healthBar.nameText = healthBar:CreateFontString(nil, "LOW", "GameFontNormalSmall") if (Gladdy.db.healthBarNameFontSize < 1) then @@ -68,7 +68,7 @@ function Healthbar:CreateFrame(unit) healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarNameFontSize) healthBar.nameText:Show() end - healthBar.nameText:SetTextColor(Gladdy.db.healthBarFontColor.r, Gladdy.db.healthBarFontColor.g, Gladdy.db.healthBarFontColor.b, Gladdy.db.healthBarFontColor.a) + healthBar.nameText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) healthBar.nameText:SetShadowOffset(1, -1) healthBar.nameText:SetShadowColor(0, 0, 0, 1) healthBar.nameText:SetJustifyH("CENTER") @@ -82,7 +82,7 @@ function Healthbar:CreateFrame(unit) healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarHealthFontSize) healthBar.healthText:Hide() end - healthBar.healthText:SetTextColor(Gladdy.db.healthBarFontColor.r, Gladdy.db.healthBarFontColor.g, Gladdy.db.healthBarFontColor.b, Gladdy.db.healthBarFontColor.a) + healthBar.healthText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) healthBar.healthText:SetShadowOffset(1, -1) healthBar.healthText:SetShadowColor(0, 0, 0, 1) healthBar.healthText:SetJustifyH("CENTER") @@ -160,11 +160,11 @@ function Healthbar:UpdateFrame(unit) healthBar.hp:SetFrameLevel(Gladdy.db.healthFrameLevel - 1) healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "healthBarTexture")) - healthBar.bg:SetVertexColor(Gladdy.db.healthBarBgColor.r, Gladdy.db.healthBarBgColor.g, Gladdy.db.healthBarBgColor.b, Gladdy.db.healthBarBgColor.a) + healthBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.healthBarBgColor)) healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "healthBarBorderStyle"), edgeSize = Gladdy.db.healthBarBorderSize }) - healthBar:SetBackdropBorderColor(Gladdy.db.healthBarBorderColor.r, Gladdy.db.healthBarBorderColor.g, Gladdy.db.healthBarBorderColor.b, Gladdy.db.healthBarBorderColor.a) + healthBar:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.healthBarBorderColor)) healthBar:ClearAllPoints() healthBar:SetPoint("TOPLEFT", Gladdy.buttons[unit], "TOPLEFT", 0, 0) healthBar:SetPoint("BOTTOMRIGHT", Gladdy.buttons[unit], "BOTTOMRIGHT") @@ -192,8 +192,8 @@ function Healthbar:UpdateFrame(unit) healthBar.nameText:Hide() end end - healthBar.nameText:SetTextColor(Gladdy.db.healthBarFontColor.r, Gladdy.db.healthBarFontColor.g, Gladdy.db.healthBarFontColor.b, Gladdy.db.healthBarFontColor.a) - healthBar.healthText:SetTextColor(Gladdy.db.healthBarFontColor.r, Gladdy.db.healthBarFontColor.g, Gladdy.db.healthBarFontColor.b, Gladdy.db.healthBarFontColor.a) + healthBar.nameText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) + healthBar.healthText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) end function Healthbar:ResetUnit(unit) diff --git a/Modules/Highlight.lua b/Modules/Highlight.lua index 0240caa..7430444 100644 --- a/Modules/Highlight.lua +++ b/Modules/Highlight.lua @@ -119,7 +119,7 @@ function Highlight:UpdateFrame(unit) end button.targetBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = borderSize }) - button.targetBorder:SetBackdropBorderColor(Gladdy.db.targetBorderColor.r, Gladdy.db.targetBorderColor.g, Gladdy.db.targetBorderColor.b, Gladdy.db.targetBorderColor.a) + button.targetBorder:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.targetBorderColor)) button.focusBorder:SetWidth(width) button.focusBorder:SetHeight(height) @@ -132,7 +132,7 @@ function Highlight:UpdateFrame(unit) end button.focusBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = borderSize }) - button.focusBorder:SetBackdropBorderColor(Gladdy.db.focusBorderColor.r, Gladdy.db.focusBorderColor.g, Gladdy.db.focusBorderColor.b, Gladdy.db.focusBorderColor.a) + button.focusBorder:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.focusBorderColor)) button.leaderBorder:SetWidth(width) button.leaderBorder:SetHeight(height) @@ -145,7 +145,7 @@ function Highlight:UpdateFrame(unit) end button.leaderBorder:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "highlightBorderStyle"), edgeSize = borderSize }) - button.leaderBorder:SetBackdropBorderColor(Gladdy.db.leaderBorderColor.r, Gladdy.db.leaderBorderColor.g, Gladdy.db.leaderBorderColor.b, Gladdy.db.leaderBorderColor.a) + button.leaderBorder:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.leaderBorderColor)) if Gladdy.frame.testing then Highlight:Test(unit) end diff --git a/Modules/Pets.lua b/Modules/Pets.lua index fdd33b0..fc703b0 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -70,7 +70,7 @@ function Pets:PET_SPOTTED(unit) Gladdy.guids[UnitGUID(unit)] = unit if Gladdy.db.petEnabled then self.frames[unit].healthBar:SetAlpha(1) - self.frames[unit].healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) + self.frames[unit].healthBar.hp:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.petHealthBarColor)) self.frames[unit].healthBar:SetScript("OnUpdate", function(self) self.hp:SetValue(UnitHealth(self.unit)) Pets:SetHealthText(self, UnitHealth(unit), UnitHealthMax(unit)) @@ -157,7 +157,7 @@ function Pets:CreateFrame(unitId) local healthBar = CreateFrame("Frame", nil, button, BackdropTemplateMixin and "BackdropTemplate") healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "petHealthBarBorderStyle"), edgeSize = Gladdy.db.petHealthBarBorderSize }) - healthBar:SetBackdropBorderColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) + healthBar:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.petHealthBarBorderColor)) healthBar:SetFrameStrata(Gladdy.db.petFrameStrata) healthBar:SetFrameLevel(Gladdy.db.petFrameLevel) healthBar:SetAllPoints(button) @@ -170,12 +170,12 @@ function Pets:CreateFrame(unitId) healthBar.portrait.border = healthBar:CreateTexture(nil, "OVERLAY") healthBar.portrait.border:SetAllPoints(healthBar.portrait) healthBar.portrait.border:SetTexture(Gladdy.db.classIconBorderStyle) - healthBar.portrait.border:SetVertexColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) + healthBar.portrait.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.petHealthBarBorderColor)) healthBar.hp = CreateFrame("StatusBar", nil, healthBar) healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "petHealthBarTexture")) - healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) + healthBar.hp:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.petHealthBarColor)) healthBar.hp:SetMinMaxValues(0, 100) healthBar.hp:SetFrameStrata(Gladdy.db.petFrameStrata) healthBar.hp:SetFrameLevel(Gladdy.db.petFrameLevel - 1) @@ -186,7 +186,7 @@ function Pets:CreateFrame(unitId) healthBar.bg:ClearAllPoints() healthBar.bg:SetAllPoints(healthBar.hp) healthBar.bg:SetAlpha(1) - healthBar.bg:SetVertexColor(Gladdy.db.petHealthBarBgColor.r, Gladdy.db.petHealthBarBgColor.g, Gladdy.db.petHealthBarBgColor.b, Gladdy.db.petHealthBarBgColor.a) + healthBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.petHealthBarBgColor)) healthBar.nameText = healthBar:CreateFontString(nil, "LOW", "GameFontNormalSmall") if (Gladdy.db.petHealthBarFontSize < 1) then @@ -196,7 +196,7 @@ function Pets:CreateFrame(unitId) healthBar.nameText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.nameText:Show() end - healthBar.nameText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) + healthBar.nameText:SetTextColor(Gladdy:SetColor(Gladdy.db.petHealthBarFontColor)) healthBar.nameText:SetShadowOffset(1, -1) healthBar.nameText:SetShadowColor(0, 0, 0, 1) healthBar.nameText:SetJustifyH("CENTER") @@ -210,7 +210,7 @@ function Pets:CreateFrame(unitId) healthBar.healthText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.healthText:Hide() end - healthBar.healthText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) + healthBar.healthText:SetTextColor(Gladdy:SetColor(Gladdy.db.petHealthBarFontColor)) healthBar.healthText:SetShadowOffset(1, -1) healthBar.healthText:SetShadowColor(0, 0, 0, 1) healthBar.healthText:SetJustifyH("CENTER") @@ -289,17 +289,17 @@ function Pets:UpdateFrame(unitId) healthBar.portrait.border:Show() end healthBar.portrait.border:SetTexture(Gladdy.db.petPortraitBorderStyle) - healthBar.portrait.border:SetVertexColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) + healthBar.portrait.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.petHealthBarBorderColor)) healthBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "petHealthBarTexture")) - healthBar.bg:SetVertexColor(Gladdy.db.petHealthBarBgColor.r, Gladdy.db.petHealthBarBgColor.g, Gladdy.db.petHealthBarBgColor.b, Gladdy.db.petHealthBarBgColor.a) + healthBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.petHealthBarBgColor)) healthBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "petHealthBarBorderStyle"), edgeSize = Gladdy.db.petHealthBarBorderSize }) - healthBar:SetBackdropBorderColor(Gladdy.db.petHealthBarBorderColor.r, Gladdy.db.petHealthBarBorderColor.g, Gladdy.db.petHealthBarBorderColor.b, Gladdy.db.petHealthBarBorderColor.a) + healthBar:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.petHealthBarBorderColor)) healthBar.hp:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "petHealthBarTexture")) - healthBar.hp:SetStatusBarColor(Gladdy.db.petHealthBarColor.r, Gladdy.db.petHealthBarColor.g, Gladdy.db.petHealthBarColor.b, Gladdy.db.petHealthBarColor.a) + healthBar.hp:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.petHealthBarColor)) healthBar.hp:ClearAllPoints() healthBar.hp:SetPoint("TOPLEFT", healthBar, "TOPLEFT", (Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset)) healthBar.hp:SetPoint("BOTTOMRIGHT", healthBar, "BOTTOMRIGHT", -(Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.petHealthBarBorderSize/Gladdy.db.statusbarBorderOffset)) @@ -315,8 +315,8 @@ function Pets:UpdateFrame(unitId) healthBar.healthText:SetFont(Gladdy:SMFetch("font", "petHealthBarFont"), Gladdy.db.petHealthBarFontSize) healthBar.healthText:Show() end - healthBar.nameText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) - healthBar.healthText:SetTextColor(Gladdy.db.petHealthBarFontColor.r, Gladdy.db.petHealthBarFontColor.g, Gladdy.db.petHealthBarFontColor.b, Gladdy.db.petHealthBarFontColor.a) + healthBar.nameText:SetTextColor(Gladdy:SetColor(Gladdy.db.petHealthBarFontColor)) + healthBar.healthText:SetTextColor(Gladdy:SetColor(Gladdy.db.petHealthBarFontColor)) if (unit == "arenapet1") then Gladdy:CreateMover(self.frames[unit], "petXOffset", "petYOffset", L["Pets"], {"TOPLEFT", "TOPLEFT"}) end diff --git a/Modules/Powerbar.lua b/Modules/Powerbar.lua index af76f5c..4e99810 100644 --- a/Modules/Powerbar.lua +++ b/Modules/Powerbar.lua @@ -42,7 +42,7 @@ function Powerbar:CreateFrame(unit) powerBar:EnableMouse(false) powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "powerBarBorderStyle"), edgeSize = Gladdy.db.powerBarBorderSize }) - powerBar:SetBackdropBorderColor(Gladdy.db.powerBarBorderColor.r, Gladdy.db.powerBarBorderColor.g, Gladdy.db.powerBarBorderColor.b, Gladdy.db.powerBarBorderColor.a) + powerBar:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.powerBarBorderColor)) powerBar:SetFrameStrata(Gladdy.db.powerFrameStrata) powerBar:SetFrameLevel(Gladdy.db.powerFrameLevel) @@ -56,11 +56,11 @@ function Powerbar:CreateFrame(unit) powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) powerBar.bg:ClearAllPoints() powerBar.bg:SetAllPoints(powerBar.energy) - powerBar.bg:SetVertexColor(Gladdy.db.powerBarBgColor.r, Gladdy.db.powerBarBgColor.g, Gladdy.db.powerBarBgColor.b, Gladdy.db.powerBarBgColor.a) + powerBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.powerBarBgColor)) powerBar.raceText = powerBar:CreateFontString(nil, "LOW") powerBar.raceText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) - powerBar.raceText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) + powerBar.raceText:SetTextColor(Gladdy:SetColor(Gladdy.db.powerBarFontColor)) powerBar.raceText:SetShadowOffset(1, -1) powerBar.raceText:SetShadowColor(0, 0, 0, 1) powerBar.raceText:SetJustifyH("CENTER") @@ -68,7 +68,7 @@ function Powerbar:CreateFrame(unit) powerBar.powerText = powerBar:CreateFontString(nil, "LOW") powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) - powerBar.powerText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) + powerBar.powerText:SetTextColor(Gladdy:SetColor(Gladdy.db.powerBarFontColor)) powerBar.powerText:SetShadowOffset(1, -1) powerBar.powerText:SetShadowColor(0, 0, 0, 1) powerBar.powerText:SetJustifyH("CENTER") @@ -152,7 +152,7 @@ function Powerbar:UpdateFrame(unit) powerBar:Show() end powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) - powerBar.bg:SetVertexColor(Gladdy.db.powerBarBgColor.r, Gladdy.db.powerBarBgColor.g, Gladdy.db.powerBarBgColor.b, Gladdy.db.powerBarBgColor.a) + powerBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.powerBarBgColor)) powerBar:SetWidth(healthBar:GetWidth()) powerBar:SetHeight(Gladdy.db.powerBarHeight) @@ -162,7 +162,7 @@ function Powerbar:UpdateFrame(unit) powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "powerBarBorderStyle"), edgeSize = Gladdy.db.powerBarBorderSize }) - powerBar:SetBackdropBorderColor(Gladdy.db.powerBarBorderColor.r, Gladdy.db.powerBarBorderColor.g, Gladdy.db.powerBarBorderColor.b, Gladdy.db.powerBarBorderColor.a) + powerBar:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.powerBarBorderColor)) powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) powerBar.energy:ClearAllPoints() @@ -170,9 +170,9 @@ function Powerbar:UpdateFrame(unit) powerBar.energy:SetPoint("BOTTOMRIGHT", powerBar, "BOTTOMRIGHT", -(Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset)) powerBar.raceText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) - powerBar.raceText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) + powerBar.raceText:SetTextColor(Gladdy:SetColor(Gladdy.db.powerBarFontColor)) powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) - powerBar.powerText:SetTextColor(Gladdy.db.powerBarFontColor.r, Gladdy.db.powerBarFontColor.g, Gladdy.db.powerBarFontColor.b, Gladdy.db.powerBarFontColor.a) + powerBar.powerText:SetTextColor(Gladdy:SetColor(Gladdy.db.powerBarFontColor)) powerBar:SetFrameStrata(Gladdy.db.powerFrameStrata) powerBar:SetFrameLevel(Gladdy.db.powerFrameLevel) diff --git a/Modules/Racial.lua b/Modules/Racial.lua index 717e4d5..533aa6b 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -137,7 +137,7 @@ function Racial:UpdateFrame(unit) racial.texture:SetAllPoints(racial) racial.texture.overlay:SetTexture(Gladdy.db.racialBorderStyle) - racial.texture.overlay:SetVertexColor(Gladdy.db.racialBorderColor.r, Gladdy.db.racialBorderColor.g, Gladdy.db.racialBorderColor.b, Gladdy.db.racialBorderColor.a) + racial.texture.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.racialBorderColor)) Gladdy:SetPosition(racial, unit, "racialXOffset", "racialYOffset", Racial:LegacySetPosition(racial, unit), Racial) -- 2.39.5 From b22756b6ab0c9766616e50ed800d5151d94b55c2 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 23:09:01 +0100 Subject: [PATCH 104/268] readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ce7c701..33dcec8 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,8 @@ Thank you for the great feedback and active contribution. - reset timer when buff was taken - add a configurable 2nd timer or show one timer with the closest CD - **CastBar Icon can be enabled/disabled** -- **Trinket: green/red option added** +- **Trinket solid color option added** + - color for Trinket on/off CD can bi configured (red/green by default) - **fixed some DR-categories** (Hibernate / Chastice / Dragonsbreath / ImpConcussiveShot / Counterattack) - **Pixel Perfect option added** (makes your Gladdy Frames pixel perfect - no more wierd scaling interferences) - **Pets can be grouped** (not perfect yet, but a first step) -- 2.39.5 From 83763aa0165b4c3b91cf05c3c0aa3b4aa075bb82 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Wed, 12 Jan 2022 23:17:35 +0100 Subject: [PATCH 105/268] fix colored trinket option toggle --- Modules/Trinket.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index a21ab5e..99af23c 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -134,7 +134,7 @@ function Trinket:UpdateFrame(unit) end trinket.texture:SetTexture() else - trinket:SetBackdropColor(Gladdy:SetColor(Gladdy.db.trinketColoredNoCd)) + trinket:SetBackdropColor(0,0,0,0) trinket.texture:SetTexture("Interface\\Icons\\INV_Jewelry_TrinketPVP_02") end -- 2.39.5 From 0d9e9735daf3d7e68fdfc0461227780c4922766f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 13 Jan 2022 23:11:06 +0100 Subject: [PATCH 106/268] add unregister messages to gladdy messages --- Gladdy.lua | 10 ++++++++++ Modules/Announcements.lua | 1 + 2 files changed, 11 insertions(+) diff --git a/Gladdy.lua b/Gladdy.lua index 416ba57..eb14d39 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -191,6 +191,16 @@ function Gladdy:NewModule(name, priority, defaults) self.messages[message] = func or message end + module.UnregisterMessage = function(self, message) + self.messages[message] = nil + end + + module.UnregisterAllMessages = function(self) + for msg,_ in pairs(self.messages) do + self.messages[msg] = nil + end + end + module.GetOptions = function() return nil end diff --git a/Modules/Announcements.lua b/Modules/Announcements.lua index 3c8b376..27de5f1 100644 --- a/Modules/Announcements.lua +++ b/Modules/Announcements.lua @@ -53,6 +53,7 @@ function Announcements:Initialize() end function Announcements:Reset() + self:UnregisterAllMessages() self.enemy = {} self.throttled = {} end -- 2.39.5 From 9dbab9939f2734d5b386eca9bf10b561ff9e88aa Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 13 Jan 2022 23:11:33 +0100 Subject: [PATCH 107/268] mover disabled on module disabled --- Frame.lua | 6 +- Modules/BuffsDebuffs.lua | 8 +- Modules/Castbar.lua | 9 +- Modules/Classicon.lua | 2 +- Modules/CombatIndicator.lua | 5 +- Modules/Cooldowns.lua | 2 +- Modules/Diminishings.lua | 315 +++++++++++++++++++++--------------- Modules/Racial.lua | 3 +- Modules/Trinket.lua | 2 +- 9 files changed, 211 insertions(+), 141 deletions(-) diff --git a/Frame.lua b/Frame.lua index 79a1354..c4e2d41 100644 --- a/Frame.lua +++ b/Frame.lua @@ -448,7 +448,11 @@ function Gladdy:CreateMover(frame, xConfig, yConfig, name, points, width, height frame.mover:SetWidth(width or frame:GetWidth()) end if self.frame and self.frame.testing and self.db.showMover then - frame.mover:Show() + if (activated ~= nil and not Gladdy.db[activated]) then + frame.mover:Hide() + else + frame.mover:Show() + end else frame.mover:Hide() end diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index d1575a9..45a960a 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -297,8 +297,8 @@ function BuffsDebuffs:UpdateFrame(unit) if (unit == "arena1") then Gladdy:CreateMover(self.frames[unit].debuffFrame, "buffsXOffset", "buffsYOffset", L["Debuffs"], {"TOPRIGHT", "TOPRIGHT"}, - Gladdy.db.buffsIconSize * Gladdy.db.buffsWidthFactor, - Gladdy.db.buffsIconSize, 0, 0) + Gladdy.db.buffsIconSize * Gladdy.db.buffsWidthFactor, Gladdy.db.buffsIconSize, + 0, 0, "buffsEnabled") if not Gladdy.db.buffsEnabled then self.frames[unit].debuffFrame.mover:Hide() end @@ -310,8 +310,8 @@ function BuffsDebuffs:UpdateFrame(unit) if (unit == "arena1") then Gladdy:CreateMover(self.frames[unit].buffFrame, "buffsBuffsXOffset", "buffsBuffsYOffset", L["Buffs"], {"TOPRIGHT", "TOPRIGHT"}, - Gladdy.db.buffsBuffsIconSize * Gladdy.db.buffsBuffsWidthFactor, - Gladdy.db.buffsBuffsIconSize, 0, 0) + Gladdy.db.buffsBuffsIconSize * Gladdy.db.buffsBuffsWidthFactor, Gladdy.db.buffsBuffsIconSize, + 0, 0, "buffsEnabled") if not Gladdy.db.buffsEnabled then self.frames[unit].buffFrame.mover:Hide() end diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 644bfcd..7302b1d 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -202,7 +202,12 @@ function Castbar:UpdateFrame(unit) castBar.icon.texture.overlay:SetVertexColor(Gladdy:SetColor(Gladdy.db.castBarIconColor)) if (unit == "arena1") then - Gladdy:CreateMover(castBar, "castBarXOffset", "castBarYOffset", L["Cast Bar"], {"TOPLEFT", "TOPLEFT"}, Gladdy.db.castBarWidth, Gladdy.db.castBarHeight, 0, 0) + Gladdy:CreateMover(castBar, "castBarXOffset", "castBarYOffset", L["Cast Bar"], + {"TOPLEFT", "TOPLEFT"}, Gladdy.db.castBarWidth, Gladdy.db.castBarHeight, + 0, 0, "castBarEnabled") + end + if not Gladdy.db.castBarEnabled then + self:CAST_STOP(unit) end end @@ -414,6 +419,7 @@ function Castbar:CAST_START(unit, spell, icon, value, maxValue, test) castBar.maxValue = maxValue castBar.bar:SetMinMaxValues(0, maxValue) castBar.bar:SetValue(value) + castBar.icon:SetAlpha(1) castBar.icon.texture:SetTexture(icon) castBar.spellText:SetText(spell) castBar.timeText:SetText(maxValue) @@ -440,6 +446,7 @@ function Castbar:CAST_STOP(unit, ...) castBar.channeling = nil castBar.value = 0 castBar.maxValue = 0 + castBar.icon:SetAlpha(0) castBar.icon.texture:SetTexture("") castBar.spellText:SetText("") castBar.timeText:SetText("") diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index 906954c..c419ab8 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -127,7 +127,7 @@ function Classicon:UpdateFrame(unit) Gladdy.db.classIconSize * Gladdy.db.classIconWidthFactor, Gladdy.db.classIconSize, 0, - 0) + 0, "classIconEnabled") end classIcon.texture:ClearAllPoints() diff --git a/Modules/CombatIndicator.lua b/Modules/CombatIndicator.lua index dc2a693..4ac51ee 100644 --- a/Modules/CombatIndicator.lua +++ b/Modules/CombatIndicator.lua @@ -82,7 +82,10 @@ function CombatIndicator:UpdateFrame(unit) ciFrame:Show() end if (unit == "arena1") then - Gladdy:CreateMover(ciFrame, "ciXOffset", "ciYOffset", L["Combat Indicator"], {"TOPLEFT", "TOPLEFT"}) + Gladdy:CreateMover(ciFrame, "ciXOffset", "ciYOffset", L["Combat Indicator"], + {"TOPLEFT", "TOPLEFT"}, + Gladdy.db.ciSize * Gladdy.db.ciWidthFactor, Gladdy.db.ciSize, + 0, 0, "ciEnabled") end end diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index b08fa83..8c695af 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -152,7 +152,7 @@ function Cooldowns:UpdateFrame(unit) if (unit == "arena1") then Gladdy:CreateMover(button.spellCooldownFrame,"cooldownXOffset", "cooldownYOffset", L["Cooldown"], {"TOPLEFT", "TOPLEFT"}, - Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor, Gladdy.db.cooldownSize) + Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor, Gladdy.db.cooldownSize, 0, 0, "cooldown") end -- Update each cooldown icon local o = 1 diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index a83b2d9..a9836bd 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -28,6 +28,7 @@ local function defaultCategories() end local Diminishings = Gladdy:NewModule("Diminishings", nil, { drFont = "DorisPP", + drFontColorsEnabled = false, drFontColor = { r = 1, g = 1, b = 0, a = 1 }, drFontScale = 1, drGrowDirection = "RIGHT", @@ -46,7 +47,9 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { drNullColor = {r = 1, g = 0, b = 0, a = 1 }, drLevelTextEnabled = true, drLevelTextFont = "DorisPP", - drLevelTextFontScale = 0.8, + drLevelTextScale = 0.8, + drLevelTextColor = { r = 1, g = 1, b = 0, a = 1 }, + drLevelTextColorsEnabled = true, drWidthFactor = 1, drCategories = defaultCategories(), drDuration = 18, @@ -106,12 +109,12 @@ function Diminishings:CreateFrame(unit) self.dr = nil self.diminishing = 1.0 self.texture:SetTexture("") - self.text:SetText("") + self.timeText:SetText("") self:Hide() Diminishings:Positionate(unit) else self.timeLeft = self.timeLeft - elapsed - Gladdy:FormatTimer(self.text, self.timeLeft, self.timeLeft < 5) + Gladdy:FormatTimer(self.timeText, self.timeLeft, self.timeLeft < 5) end end end) @@ -135,15 +138,6 @@ function Diminishings:CreateFrame(unit) icon.border:SetTexture("Interface\\AddOns\\Gladdy\\Images\\Border_rounded_blp") icon.border:SetAllPoints(icon) - icon.text = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") - icon.text:SetDrawLayer("OVERLAY") - icon.text:SetFont(Gladdy:SMFetch("font", "drFont"), 10, "OUTLINE") - icon.text:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) - icon.text:SetShadowOffset(1, -1) - icon.text:SetShadowColor(0, 0, 0, 1) - icon.text:SetJustifyH("CENTER") - icon.text:SetPoint("CENTER") - icon.timeText = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") icon.timeText:SetDrawLayer("OVERLAY") icon.timeText:SetFont(Gladdy:SMFetch("font", "drFont"), 10, "OUTLINE") @@ -199,7 +193,7 @@ function Diminishings:UpdateFrame(unit) Gladdy.db.drIconSize * Gladdy.db.drWidthFactor, Gladdy.db.drIconSize, 0, - 0) + 0, "drEnabled") end for i = 1, 16 do @@ -215,12 +209,19 @@ function Diminishings:UpdateFrame(unit) icon.cooldownFrame:SetFrameStrata(Gladdy.db.drFrameStrata) icon.cooldownFrame:SetFrameLevel(Gladdy.db.drFrameLevel + 2) - icon.text:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") - icon.text:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) icon.timeText:SetFont(Gladdy:SMFetch("font", "drFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drFontScale, "OUTLINE") - icon.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) + if Gladdy.db.drFontColorsEnabled then + icon.timeText:SetTextColor(getDiminishColor(icon.diminishing)) + else + icon.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) + end - icon.drLevelText:SetFont(Gladdy:SMFetch("font", "drLevelTextFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drLevelTextFontScale, "OUTLINE") + icon.drLevelText:SetFont(Gladdy:SMFetch("font", "drLevelTextFont"), (Gladdy.db.drIconSize/2 - 1) * Gladdy.db.drLevelTextScale, "OUTLINE") + if Gladdy.db.drLevelTextColorsEnabled then + icon.drLevelText:SetTextColor(getDiminishColor(icon.diminishing)) + else + icon.drLevelText:SetTextColor(Gladdy:SetColor(Gladdy.db.drLevelTextColor)) + end icon.cooldown:SetWidth(icon:GetWidth() - icon:GetWidth()/16) icon.cooldown:SetHeight(icon:GetHeight() - icon:GetHeight()/16) @@ -284,7 +285,6 @@ function Diminishings:ResetUnit(unit) icon.active = false icon.timeLeft = 0 icon.texture:SetTexture("") - icon.text:SetText("") icon.timeText:SetText("") icon:Hide() end @@ -363,11 +363,23 @@ function Diminishings:AuraFade(unit, spellID) else lastIcon.texture:SetTexture(select(3, GetSpellInfo(spellID))) end + + if Gladdy.db.drFontColorsEnabled then + lastIcon.timeText:SetTextColor(getDiminishColor(lastIcon.diminishing)) + else + lastIcon.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.drFontColor)) + end + + lastIcon.drLevelText:SetText(getDiminishText(lastIcon.diminishing)) + if Gladdy.db.drLevelTextColorsEnabled then + lastIcon.drLevelText:SetTextColor(getDiminishColor(lastIcon.diminishing)) + else + lastIcon.drLevelText:SetTextColor(Gladdy:SetColor(Gladdy.db.drLevelTextColor)) + end + lastIcon.active = true self:Positionate(unit) lastIcon:Show() - lastIcon.drLevelText:SetText(getDiminishText(lastIcon.diminishing)) - lastIcon.drLevelText:SetTextColor(getDiminishColor(lastIcon.diminishing)) end function Diminishings:Positionate(unit) @@ -519,34 +531,42 @@ function Diminishings:GetOptions() }, font = { type = "group", - name = L["Font"], + name = L["Cooldown Font"], order = 3, args = { headerFont = { type = "header", - name = L["Font"], - order = 10, + name = L["Cooldown Font"], + order = 1, }, - drFont = Gladdy:option({ - type = "select", - name = L["Font"], - desc = L["Font of the cooldown"], - order = 11, - dialogControl = "LSM30_Font", - values = AceGUIWidgetLSMlists.font, + drFontColorsEnabled = Gladdy:option({ + type = "toggle", + name = L["Enable DR Colors as Font Color"], + desc = L["Shows the current DR Level on the DR icon."], + order = 2, + width = "full", }), drFontColor = Gladdy:colorOption({ type = "color", name = L["Font color"], desc = L["Color of the text"], - order = 13, + order = 3, hasAlpha = true, + width = "full", + }), + drFont = Gladdy:option({ + type = "select", + name = L["Font"], + desc = L["Font of the cooldown"], + order = 4, + dialogControl = "LSM30_Font", + values = AceGUIWidgetLSMlists.font, }), drFontScale = Gladdy:option({ type = "range", name = L["Font scale"], desc = L["Scale of the text"], - order = 12, + order = 5, min = 0.1, max = 2, step = 0.1, @@ -554,10 +574,142 @@ function Diminishings:GetOptions() }), } }, + levelText = { + type = "group", + name = L["DR Font"], + order = 4, + args = { + headerBorder = { + type = "header", + name = L["DR Font"], + order = 1, + }, + drLevelTextEnabled = Gladdy:option({ + type = "toggle", + name = L["Enable DR Font"], + desc = L["Shows the current DR Level on the DR icon."], + order = 2, + width = "full", + }), + drLevelTextColorsEnabled = Gladdy:option({ + type = "toggle", + name = L["Enable DR Colors as Font Color"], + desc = L["Shows the current DR Level on the DR icon."], + order = 3, + width = "full", + disabled = function() + return not Gladdy.db.drLevelTextEnabled + end, + }), + drLevelTextColor = Gladdy:colorOption({ + type = "color", + name = L["DR Font color"], + desc = L["Color of the font"], + order = 4, + hasAlpha = true, + disabled = function() + return not Gladdy.db.drLevelTextEnabled + end, + }), + drLevelTextFont = Gladdy:option({ + type = "select", + name = L["Font"], + desc = L["Font of the DR Font"], + order = 5, + dialogControl = "LSM30_Font", + values = AceGUIWidgetLSMlists.font, + width = "full", + disabled = function() + return not Gladdy.db.drLevelTextEnabled + end, + }), + drLevelTextScale = Gladdy:option({ + type = "range", + name = L["Font scale"], + desc = L["Scale of the text"], + order = 6, + min = 0.1, + max = 2, + step = 0.1, + width = "full", + disabled = function() + return not Gladdy.db.drLevelTextEnabled + end, + }), + }, + }, + border = { + type = "group", + name = L["Border"], + order = 5, + args = { + headerBorder = { + type = "header", + name = L["Border"], + order = 1, + }, + drBorderColorsEnabled = Gladdy:option({ + type = "toggle", + name = L["Enable DR Colors as Border Color"], + desc = L["Colors borders of DRs in respective DR Colors"], + order = 2, + width = "full", + }), + drBorderColor = Gladdy:colorOption({ + type = "color", + name = L["Border color"], + desc = L["Color of the border"], + order = 3, + disabled = function() + return Gladdy.db.drBorderColorsEnabled + end, + hasAlpha = true, + }), + drBorderStyle = Gladdy:option({ + type = "select", + name = L["Border style"], + order = 4, + values = Gladdy:GetIconStyles() + }), + } + }, + levelColors = { + type = "group", + name = L["DR Colors"], + order = 6, + args = { + headerColors = { + type = "header", + name = L["DR Colors"], + order = 10, + }, + drHalfColor = Gladdy:colorOption({ + type = "color", + name = L["Half"], + desc = L["Color of the border"], + order = 42, + hasAlpha = true, + }), + drQuarterColor = Gladdy:colorOption({ + type = "color", + name = L["Quarter"], + desc = L["Color of the border"], + order = 43, + hasAlpha = true, + }), + drNullColor = Gladdy:colorOption({ + type = "color", + name = L["Immune"], + desc = L["Color of the border"], + order = 44, + hasAlpha = true, + }), + }, + }, position = { type = "group", name = L["Position"], - order = 6, + order = 7, args = { headerPosition = { type = "header", @@ -594,105 +746,10 @@ function Diminishings:GetOptions() }), }, }, - level = { - type = "group", - name = L["Level Text"], - order = 5, - args = { - headerBorder = { - type = "header", - name = L["DR Level"], - order = 1, - }, - drLevelTextEnabled = Gladdy:option({ - type = "toggle", - name = L["DR Level Text Enabled"], - desc = L["Shows the current DR Level on the DR icon."], - order = 2, - width = "full", - }), - drLevelTextFont = Gladdy:option({ - type = "select", - name = L["Font"], - desc = L["Font of the cooldown"], - order = 3, - dialogControl = "LSM30_Font", - values = AceGUIWidgetLSMlists.font, - }), - drLevelTextFontScale = Gladdy:option({ - type = "range", - name = L["Font scale"], - desc = L["Scale of the text"], - order = 4, - min = 0.1, - max = 2, - step = 0.1, - width = "full", - }), - }, - }, - border = { - type = "group", - name = L["Border"], - order = 4, - args = { - headerBorder = { - type = "header", - name = L["Border"], - order = 30, - }, - drBorderStyle = Gladdy:option({ - type = "select", - name = L["Border style"], - order = 31, - values = Gladdy:GetIconStyles() - }), - drBorderColor = Gladdy:colorOption({ - type = "color", - name = L["Border color"], - desc = L["Color of the border"], - order = 32, - hasAlpha = true, - }), - headerBorderColors = { - type = "header", - name = L["DR Border Colors"], - order = 40, - }, - drBorderColorsEnabled = Gladdy:option({ - type = "toggle", - name = L["Dr Border Colors Enabled"], - desc = L["Colors borders of DRs in respective DR-color below"], - order = 41, - width = "full", - }), - drHalfColor = Gladdy:colorOption({ - type = "color", - name = L["Half"], - desc = L["Color of the border"], - order = 42, - hasAlpha = true, - }), - drQuarterColor = Gladdy:colorOption({ - type = "color", - name = L["Quarter"], - desc = L["Color of the border"], - order = 43, - hasAlpha = true, - }), - drNullColor = Gladdy:colorOption({ - type = "color", - name = L["Immune"], - desc = L["Color of the border"], - order = 44, - hasAlpha = true, - }), - } - }, frameStrata = { type = "group", name = L["Frame Strata and Level"], - order = 7, + order = 8, args = { headerAuraLevel = { type = "header", diff --git a/Modules/Racial.lua b/Modules/Racial.lua index 533aa6b..7838b9b 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -146,8 +146,7 @@ function Racial:UpdateFrame(unit) {"TOPLEFT", "TOPLEFT"}, Gladdy.db.racialSize * Gladdy.db.racialWidthFactor, Gladdy.db.racialSize, - 0, - 0) + 0, 0, "racialEnabled") end if (Gladdy.db.racialEnabled == false) then diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 99af23c..0c316e1 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -172,7 +172,7 @@ function Trinket:UpdateFrame(unit) Gladdy.db.trinketSize * Gladdy.db.trinketWidthFactor, Gladdy.db.trinketSize, 0, - 0) + 0, "trinketEnabled") end trinket.cooldown:SetAlpha(Gladdy.db.trinketCooldownAlpha) -- 2.39.5 From cf485a91a1f831b2af57870d78321460bf518029 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 13 Jan 2022 23:12:34 +0100 Subject: [PATCH 108/268] cleanup --- Modules/BuffsDebuffs.lua | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 45a960a..1574c54 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -299,9 +299,6 @@ function BuffsDebuffs:UpdateFrame(unit) {"TOPRIGHT", "TOPRIGHT"}, Gladdy.db.buffsIconSize * Gladdy.db.buffsWidthFactor, Gladdy.db.buffsIconSize, 0, 0, "buffsEnabled") - if not Gladdy.db.buffsEnabled then - self.frames[unit].debuffFrame.mover:Hide() - end end --BUFFS @@ -312,9 +309,6 @@ function BuffsDebuffs:UpdateFrame(unit) {"TOPRIGHT", "TOPRIGHT"}, Gladdy.db.buffsBuffsIconSize * Gladdy.db.buffsBuffsWidthFactor, Gladdy.db.buffsBuffsIconSize, 0, 0, "buffsEnabled") - if not Gladdy.db.buffsEnabled then - self.frames[unit].buffFrame.mover:Hide() - end end for i=1, #self.frames[unit].auras[AURA_TYPE_BUFF] do -- 2.39.5 From 038688bd5b77733798bf5067674c055b82506966 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 13 Jan 2022 23:37:09 +0100 Subject: [PATCH 109/268] fix Gladdy:Hide() should call Gladdy:Reset() --- Frame.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Frame.lua b/Frame.lua index c4e2d41..4baab81 100644 --- a/Frame.lua +++ b/Frame.lua @@ -270,6 +270,7 @@ function Gladdy:HideFrame() self.startTest = nil self.hideFrame = true else + self:Reset() self.frame:Hide() end -- 2.39.5 From fd37f588ac4af197a9f59ac9debad5940fe335fe Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 13 Jan 2022 23:42:42 +0100 Subject: [PATCH 110/268] readme Attention --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 33dcec8..e76dc02 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # Gladdy - TBC ### The most powerful arena addon for WoW TBC 2.5.1 + +--- + ## [v2.00-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v2.00-Release/Gladdy_TBC-Classic_v2.00-Release.zip) ###### Please consider donating if you like my work @@ -71,13 +74,16 @@ Thank you! - **Hydra** (thanks for constructive feedback and suggestions) - **Xyz** (thanks for suggestions) +--- + ### Changes ### v2.00-Release + This is a packed release with new features and bugfixes. Most importantly, positioning of all elements has been redone with movable frames. Thank you for the great feedback and active contribution. -####Attention: Once you install this version it will drastically change your current profile! You can't go back to an earlier version. Either back up your WTF or export your Profile before updating! +***Attention: Once you install this version it will drastically change your current profile! You can't go back to an earlier version. Either back up your WTF or export your Profile before updating!*** **Here is a list of all changes:** - **major release version set to v2** -- 2.39.5 From 5f94e971f01ed2d8aa8bb88625c46533edbaff38 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 13 Jan 2022 23:45:46 +0100 Subject: [PATCH 111/268] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e76dc02..66c0797 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ Thank you for the great feedback and active contribution. **Here is a list of all changes:** - **major release version set to v2** - - this will mean, that export strings will still be backwards compatible, but not forward (Gladdy v2.x String cant be imported into Gladdy v1.x but vice versa) + - this will mean, that export strings will still be backwards compatible, but not forward (Gladdy v2.x String can't be imported into Gladdy v1.x but vice versa) - **big overhaul of positioning elements added! All elements besides HP and PowerBar can be moved separately** - added Mover Frames for Auras, Interrupts, (De)Buffs, CastBar, ClassIcon, CombatIndicator, Cooldowns, DRs, Pets, Racial, Trinket - this will hopefully make configuration a lot easier -- 2.39.5 From 7ce6cdd5e0078821f8e066268a24f49fa6693016 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 13 Jan 2022 23:48:54 +0100 Subject: [PATCH 112/268] readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 66c0797..2c4d356 100644 --- a/README.md +++ b/README.md @@ -134,9 +134,9 @@ Thank you for the great feedback and active contribution. - add a configurable 2nd timer or show one timer with the closest CD - **CastBar Icon can be enabled/disabled** - **Trinket solid color option added** - - color for Trinket on/off CD can bi configured (red/green by default) + - color for Trinket on/off CD can be configured (red/green by default) - **fixed some DR-categories** (Hibernate / Chastice / Dragonsbreath / ImpConcussiveShot / Counterattack) -- **Pixel Perfect option added** (makes your Gladdy Frames pixel perfect - no more wierd scaling interferences) +- **Pixel Perfect option added** (makes your Gladdy Frames pixel perfect - no more weird scaling interferences) - **Pets can be grouped** (not perfect yet, but a first step) - **added DR-Level Text** (thanks https://github.com/ManneN1) - **added zhCN Locale** (thanks https://github.com/veiz) -- 2.39.5 From cd64e8b4818b2ceca30d6d908ef08a73b9d8c9fd Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 00:36:46 +0100 Subject: [PATCH 113/268] add Mir pixel perfect edited profil --- Images/BasicProfiles/Mir1_edited.blp | Bin 0 -> 175956 bytes ImportStrings.lua | 4 ++++ Modules/Castbar.lua | 4 ++-- Modules/XiconProfiles.lua | 19 +++++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 Images/BasicProfiles/Mir1_edited.blp diff --git a/Images/BasicProfiles/Mir1_edited.blp b/Images/BasicProfiles/Mir1_edited.blp new file mode 100644 index 0000000000000000000000000000000000000000..1e2797bf23af93cb7dc251a851e64546b53a98af GIT binary patch literal 175956 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%0AE^JNu-uC3%J|w& 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 DtFY_{ literal 0 HcmV?d00001 diff --git a/ImportStrings.lua b/ImportStrings.lua index b2c8dba..effd467 100644 --- a/ImportStrings.lua +++ b/ImportStrings.lua @@ -26,4 +26,8 @@ end function Gladdy:GetMirProfile() return "4XzT80SCBJZKpm75XfXpee4OvsCIRnXXRLtntQAkndLeTf3ir6LKAZ45qE2)AGUbjejLIyIZLiAsGgn6Ur)pYc2I7xmF5(hEOEM9FUEvzXTPRxNx84IBylMxLw8y2R2KT6l3w(1SQzPv3N9pnlMTy(Q06g4pNvwToR6vLBlRSqk1nRLlUjAX8hD)BL9FBwmFnmOYTRl)AXLBFAdoU1vVoVoD52SxLxTABwiyFmeKrxihhOnv5fFjR5qOSCX8nzPBB2aW5M0Dzxvw0mp)FZwCdhMAXt3x2KT72TPnz1ou5YTFn9567tREmRjBTD6vPRYt3EBz9I53D9BF39wm1bLvPa8rmh34ZBEgEZ8RlAYQEiDv2FE561FSO(pF7wGi(8FE9U0hZQ)tCS)1B3wwdGSEtkqgQZFCtZ957ay0c1o(GNw92QYV(68QSvn5LfTyZ)Fwvn83)1U0)3YQ)Qy)o3SF8WXo7J3F)h)GBdxLTR0Tbwm)1Lv513E7I5pL185pcRuwZIB(nfhOZ7RsFFEDZRZEiD)2glPxLKez)nRWsExB5ppvLdqO55f3iJS0)0vFba6BM9PRUYYq4jCUyAtHXfXXtBkczsK5OtHf3oL21isePN2AehlM4ExWuk20McxOmYPnfbJXsoN9EifwFcY14mLyPEIRcpMNm19IKDCcglAaBuejJpoBCe(U2OpU0Oyu2UupXnHugjpoPA0fHfjp(ImY(wZ48PHujSjk8cYHhFgm(WtuAP6SocgSRncTAAyvmxE8zm(IOmtLwXL84PUv0IPQLtdRYexePyYhB1QtCa5i6t48JlmYhkmYnGEUPi9YmXrtLAPmjhFRp6zkUYON6uIILtLaNKmrryM4e2rgxrA0uTjacxMZsVyOnbU54Ntgrvkpk6eS9JOEpEQQHatv8jUkSiEYj28JzfHFcRcJVgM4KJRJ)iwq5Nqb5rCEksF8DY4IW6KPkEjKsZeNcdusC8PmkIznvprhieGfLJlsoMMOKOtiFno9IhpvxAfIKPA2si4rtsfjxyobboE4eIJoHs7ro9QIMOl2jt2mQqimhFrgLBiJLIJlWpchxjNKaIsmvRHMOPsO0k5evMOzNqF1yI5k1PC1AeHJe904DnTXD3lirxaP)HpmXOJh9SnQ5UOxdNXQTP1U0kmitbxj1ArsuCCc4MNWAy9HFlwmEG(D5H4EmKF7cgGZU47VsMWzmJsbM24MyvcaqP2gSE)0AGOAhcDje7lIuJL(Il0wu4jkbiVlZg5oYPW8mCBw1QSIgiuFlw5hxxAhSSiiC735tkXzNZehO(q6)0rD7Mz9B64UvU8v875RB2Cv6QMshsBWq6DPMOA)tn4SGf8gw3Q288tzlMF7MNRZxLU1TYmhw4Xi7gT)WFx52NdgkSur0WVigEcMIS)uUkVk7GPehfScQbJ)YQvPfJpd3cO7pHBsB2tlr0fGf(WnH7VHjjgStM7sfdnl3cmyPMVV4lfLFTO)u)e9AKzrmo)gIPgqaQkRB6TqDlI9ay(LfR2aSUUKxzLCd4YDNVoGtZOZZzRFDMBi2LwhbgnMzDokXKyFWEGW4EJguSpZN6b4HeBuzWV2SWmZQ8q5Mj3a61SJN(1fy8mRgsHBCmbNPDZ3boxiQ2PXGyJCV2GViMjCdJ(ogeOD58RNneVzohgW1tAyUfIhLGisedFqirazJ9AMZblesQeTgHGqIdWgQ1mVXE3APtW5QIzm3N8Vaqp3V4EbdvXodoHMkbIwczKJ8PnChaCbc4aDI0TyA)Q787d3Prke2efvQKitbu5HyrSX4gRKrOm6Sb8qS29bLMGLkX99KiIkc8t3dcGWJBAUYncNfm3QbET5(chxuUNGBtS1mhDfxk0Z(zizY9GrJKnxQMCZvJ7(yo(lMEOzoRFj0lICpOqiW1ib1Uiizbqp8bJb3k28MGiOGKrviTNRej0wIJVWK4MkW7qckiuJduHpKGteZjHf0rAexmOOQIKfzW2OvO2bsftq8igkietIma5cxCDmodqwc5ijilHyC4xbIoIYmLBljureuK0HSi3pGlsoepItqfy7mcHyinhCPffffcsyHhtKsdrjtm0bbj(aMad7Bs0jeEiqwkdpRWt4Oym8dbLegsBsek64gttcYXejHth7SXl4WXe)jzego)mSBoIKrJZRxH51JGuAbUnur06ICeLo2HXcgjXd0z8WrcncINNWiXhcnHTirItCNidSqF22x7Nj(bkBNGllTQ0Ri7gKRs1Z3u(1RQYZkwdwnxIPP)tpHLzW7uZR8ojD4R91CXIqBo07bQWdyDg(2FFFz52M8N(2FxvUVynynHQFWbfd5mlQIFUwhyogrmyF2vyhxbtE)BUcg(2sRbPXiKVAFvD2bqKDGVwQdD37JLvTg6UigDPzyLmADTACCEmEtBnrcDw9zGdhZngUa0jAKGUvT1hsGd)plUsl1kHIdkYatF2i1XV0Fd26m13XFYLLnnL7(qA1J5foFtMtvZQ32l4TDvkQXvTQVJGoSoT7ylDZ67WuePdrAhqCu6oVFxL3s7(njOWRL5Cgsnl)(v5Q94CpX2eVxD0Uu496RffNM8oE(WwPqR866Q3LU9HZyhqrFyp1oPQa6oHMT(VwU9PXINcpd4H(i4Xf8HC3aCz6S2Ow(rOuCzEDzXOsvQfbf1DkS7x)Cr6U8v4WNzv0SVOXPLAwNwNHvjUv)Lx2tffQHOLD7RmnDGjqzUtsYQhgepw5ujcaARfyhOmD()3(0QSV93xTF72V93)(M8MmcZ7qgmuRdcWLq4(oLJJ8h98wVOEd2m(17pcu3EGyuFePncC7U3BK5qBLyCQs3Xh30HjcQ(Axl87X(nLpsfIshqpVUOgJnVlyLoAxFZT)HBZEGMGUbhQI(ZbK7LqOop6odDWH7XjGUD5LRA2dQJBRRVNwUC0aK77dGvSXMEaFWvlTs99jXGnqGY)iOYoZf(v92SSNSpeKcMhkRwL5j)52FVb8slYG2CBQ2w3SV4CMtSr5u1vvSU)uwESPOv4YSjTA35SgkBcmTRrzzZ5m(yW4iHt9NYXXjj3HtpVABzr25Skkge6G1VTvPnatR(CMdNf7OwRb9zwVWoRTJkkbJ9p9CgDSbrR1vPpwwuVSklfobDgtus42xoVDc34OXRxDoJwXKoKkF3tWBoRP4LsEilT6CgVnw)fUKx0E(3PAjWe8Pnney(1PE3(qqAZ4DQPc1)L)tPt1EKFq)cr2p7AiM4Kf96kkeNerdnvE9UD7lY6zKgcpeTwAtfL3kiQ)bHK2QzoVxo7ID9efGHohHUbiVdwTRkXtWNY1Yv590X9d0Ssh4MIV3GA1v6eyvXXNSeIn2W14NQvhCJHZeNS87wWKCQsotRKnfjNEm6Otu)aCijFVbi4jNODpCJP5WKaFEXJ0gR4BkY25cumTOa4bRY2bkTC0BYC7DzPRDdOM8MjZpdAaFQg584jlNfRmBYhFkTQXM42S69vKZ2K9myA1DZ4(nWq2agKDU53k32lUKhQapMPisqNcBhvVoAl08D)WyDNfmwfmR2tI5UTwpxfEpgp5YEU6q(Te1Ec2ny7rK0gVVrwz3HUx0)yfOsilTxGPEhELlccnLwOqVlhKA)VxW5D1T4mKnwx9)aUL2CQ48swmAKTDvFGwXapg9E29H0)XQDR(wGgNxqd3rCcuH4(7ES)n5RZMTn)F)30kylb(nxK2b1bkyxxDd4u9PtjtxGcNzqf0UYkx)LZGqEGJMosX9F0gFDOitdCwBtDx)DEEgzgSu9fFVlBleqvrdmKx9MBU)n3DiYpAs(dp1qhS772PpEBlJU9KOPJn8dO2N6r1(5ujKXpXCT0g(r)6tf3UVc70wpU)5oouyK2TwHx3hVwxfsXO50gOMugeQwy4BOwRrI6SxiI4zPa8Bam(bO2hyKLqzFuU2nziBim631v)Xy6u7N5iRw)zbNP60l7n4q(RfCwVnw57aKVZMafFTRgBZ3bU4Vja7ckaQvFOVqRDcUt5W0qp2S6wELpxbuNChRged7zP0nKBkAXVHS)rYVGDVHC6bQ3wowv58oQ(JlrGKEQaWRYBJcVlIE0vs(bACUK8BySSQ48JaBsB4RTvhuWmyv9WEy2(qKMgJV2pT18XM5DCWsSyAunFGPQPAKPPP6RPNR9PMfwGIiSQacjvPebttfksqdraci0S9Lm0wzp7d(AgYI0uPjumFnkIPY1jPQecVbRArIVsc6eScloVbj0KQDjwEgSLiTVW1QJoKYeDybcDEKAhlpMklzuevMpfwsN261is81IL3vafFz8ueJqGWxa7AK(Zui1UT8lCUVuFQwSIynIijvDePGQVPstvouXWQJYK(cNKy4eAiPsSiz(YgXWYkInW0mFh64gmv2oakk3SuerRT6Hq4aoKW1rmUrkn(60rLe1vrPtyFK3zFmu13anpq4)v5l33K11pdGZWB3UyoOAZMi35415ybmH15pKdovo3EkTPbcRAU1YjLQzmp6l8D5qpGCL1P0XHbVdgoxxTGqmciU0nOV93)xIXHthywJkvwVW3)ehdsYPaP4tbP4Paj1PGKAkqk5uqkzkqsFkiPNcKmNcsMPajSLepgOSUxF2WQn0RppSfSWSv6cl0(NGUY(nvwAy5e2x3uUZLH85wRcNYp8iCLDGLfd2i(faxnBq)0ojWEHXxfKyXaGlIsg0(Ltc6hfPh04SViGvl6N4IxcWQKdAhZxcWYII)La3yXGUE)LaSAo)Nsq7iGLp8AcnjWAZ03J0VuM)cKFfkv)EkDsq)OYV)Ci9X4Cdt82lby5XMb3zVxc4QzdAy3jb2lyeRZ0gJBlOTLn4Na0hJapSh)FjaRoM1pzNtcSxawgct9SrfkdhB6Nu3jb8JB34xcPGP)vW4eCZGoX(LaUy4o)eW9ciuOqHylVuFOG8VIJ06H3CSxcWYIFHnGcdSne7WCMEqkeoD6gcYV8KI)V21dc(mcL)5dBWM(Xn9zhEFqYkdZBBDtAZ(6LEu2dlBV70LFJ7CEy2VWD9sp)Q8rthxaXjSJKCPejTI6KaUoQDs0RKr2Sye0Nzh2ox3ww1uLMh2chhKiPjrrpiJkDBB6AUp36NUZn639jxGNWt7SnKL9Yf5kM2VF5D3D9hd(qmhl37Tx((lF9130(bmiE4dF4Y3(MU3Iq527U(nZVV9TcUiXqq)9F8v)3TFW1tLwYXDF66x3nCxBbdV(Up(2p1bBmKB41ZF3LF4YqmXMpaNC8bLl5NL61VOjFi9X8vhCwYBBK6rOlC7L022Ny65bK1ESSFPJoDXeCZa76O(jRlqa7NLGekc3LC1TzPWiPJcZgMm9U)ZOGKQ7sJhm02m7Y8B5UgyXVE9VplHLBS)13z2GYE4)FgcFnZ8zx5d5f57s3MBRviDLcCt2sKfqqvuNDtnxFehBaxBrGN5YMe158mSRGzrytxReuY6msSTYnkFVx77jznLIoFceBt1LG5ZLKstTPSu019ZydzBKut(NOOBQac2ig2r82M1KGMMY7MuJ9bUIAJEjnsJgZ2vSGsgPmHwFbbbkZGSyzIpZDypyhRn(oEhX02ecQm0(N6U(yUVR6P0aYJeyU1ukcO(m8XzuY2aebZQyIpjGsQLVBtzhmc362MYozmqgrOa0kpssDzoEPfAZYRfRj2l1H8julT7tYRfdCRSHY2lETsue3NYNlljYNQwKcsqLsMjtJPcLNOqudwnCasdUC8idLbtaxrCKO4MeuosrxkbypqcAAgEHbeC)fgiIUBkcjbFy9ClhdZaliGHzVui0g6wsiWSIsBa7Y3sZO84Ixbckl4X0LoXNP0yfMk9y)nZqsP21yWKRMGxIb6kkyrrpferaWSI7f0LDWsIqXzk53rrOmOuHGtGxfeUHUbg(2H3NuxJKU6ijsFg2JO7AqeUv5cTUvUhXDefa5gIjl9PSUlt1yIQtO7aadgcsWazy8YyO9suXTmocJ0indGjEzl4(BqaLl52KvRXRaGcV1emK5bs6(dsgQJ)d10EgTA06GAicXre20bNrPPpSQQNNrmwakewZ63UpRUoR2UDw67WObxqXdl4zxBkFF5L2sIDTZhVE3VYFCBzpf8FWthwMp7ho8ooUk33RYWEAX)5fSSRtb" +end + +function Gladdy:GetMirEditedProfile() + return "4XzT8S1CBBZS)yopxp4obF0oooXZjXXFrotBNPJAPLOT5jYI(qs1u3hYV9VfyxqcErkIjo5HizsGfl277IfAjF5nlxSU6SYQ15vVQCtzL7bzlVqzTYeMwNOfkzsIz5D)IwUCXTlVIVCX9()VY9)nlxSQSCZ6YVS9hci1pKbWOU4(hAUP4X8QlQYEmFrtvwt2YfV9Y38wyDYQBolBmU6adasMhKmpizE8ch)V9H7URoVz5f)IwLO020ebGpcl3HoQe32)8I6SB3K)QIQvBYxEw3sDF8YWorDWf6T5oSF5vc9Yfpv(Lb7H3)6ZV8tVF5IhYZ208am8RGxEr52Mff)BoShGjT9PBkBYF86nzn51NU5PhYoDZxYEU(MSQ7ZBYxV8waW5nV1dHRZRwLVTj7EpchyHlAEg2blUCBtE1DzRY)JtxV(dBR)J3SjB96N)JlFegF9FGJ9pFZMY66XKEy)SXHrNiM4Dpu(LB(sP)7o052DaX9m3)9ksk4nvLF58IQ8vnfLBxU4JaRdiF)DEvn83)5Jz)FLv)52DpcKjGOURklWECeu3F7r9QDp18RfRBE4ISvnLo68jPE6tv(JLvoQ2YfNxwvuF91a5FtwD9LRk36P3Vl)VZ3S8kncT3vu3CE(Dz72044IMKeM7Z8To(9AhL7PQcaqnpV8kfGbaZA1Nby)6Z(0fx44TcBIC)tXX1gnfUqQ1ZBvKQew6XSkTRbtYSZBn06dSrMgR4gdFEtrinPQ5nfjNZtoM9Emf2EaY1KRIrQm7DgPJPVALDMiLqlsM7wxX3p9LZgHvsgy)6yWQWeSPw5EhVCsPeLDMBcLIP2pPAYfHZu7FrMyFB5cX8qQe(mL1tsN7sWTkZrPZgnLuPD)sHtR1koGC7KlIoXoZDIqj0ZCNyKhqqCFKlX(Tkon5sjNRAo3AMlIjbHR9lnkglnksb7IZr8LNQz7xnC69Hjnz)B9jvQeMu7CNctRMlb2fg38MHCUoqfS56dbeUspkdJX(qeP7xpzcBPcg7aS99XfNVvf5CfvewXmXljtCa)ctVkkPy)w53J3nZbOWtOyjv65A2wKWS7NXpPqpeGYbKhftGvQ05kaNieZK(6CTpZao4GLR9JytRWNWoafEYPiLc2SS2jLjZ1jNqONDC5Y0dS51Jrln7aw5NqD3WMBm8sz6(NY0XbPfhieIPJ2sRK7xGFcLkJAw6GGVQKzQNNYMlPYAuZu9WYtM1Uwymhk4Sj23mXbwHXtaMcKkoKS7UNC5bpz5lOurDOhvIG9L5AxnkugzIeqglljfYoq4QrHz)LgWT2nvfB)CEtib8R294T5v(X4lnYdasTXHytwocAY)Eil8FHDcJXaNJSegyFrhHKZP(oSr1iHWUFpkD)iIIViixybEG2WH8OaNToVTWMpTDCoC41DCN1(hCD261fBXAjHfJOdlpDxvgIPtvIOtSEMORqnrfVbsfLkrtubwMGb)XCyx4(MZNbZlmmO8dRNU(pTKZaL4cq)jHNA5qoTPqOLAyxdKYXLEPjRIwXuy7Sn)lVl75YDnoAbIXtUEGuBr2MEftH3r6NAg9QcJNqwduXR4DKYMNFkF5IRF456IvzBOI4rf07wKHFLy4WFB5MNJgk7Kugn8t0mxnaVsnCkxuuL3BkAw0kygn(tRwLTD6z4xa7WjCvwZoAjyNarffVj8)nmj5ODYcpNHMLFbgTul2T9ZBbX9Ht9t0Jr9csAmSH4MreGQY6Mblu3I0mu5oYGZ6QivLUQ0nuoWBulF955(H4wEldCEEMZGysAI7lqCYq2HUNyHGzpluJh4ljUSzHpDL76mxINg)mfPG1D34Pp9Lu4mNFcPFCCPGB9Z3doFY9(PbwC8pofFGMl9dJEpM8SB5cRNl14Z8HoHRNkL7xiNTl8to(fPcbKl26Z8UDrizsSwecsfoaxoQNfciXVw2eCUgnN7Fv4ba65)e3lyoEUzii00ir0sQyEYNnv4bGpdkpOtu(fZgwDF0a4oLzqytuuLrHmfWwlIfAWwH7lkoHYyyxWx0w)lmwcwMe)7tyeve4N(VibcpUPfg)i8(X9RgezP)ncCrfbcURcIN5PR4sHPeDgsM8Fj1IKnFn98Z1I7ETa)elS2z(yasOhW8FXGqqyrcQBrqYcGE4xstXTIRItickjzuds7fGZtAljWhKM4NkW7qckiuJd0GFHe5WA54anZI4skkQAizrNX5wHApinCjXJ4OGGMezaYfU4wnodqwc5ijilHyC4BDg)rWyiPdoYonmgIGerqH6C(SPD7aMGapW)5eMXrIpeJpQFHkyGCLMiPemejPKcHc)cwbi)YBtsO1brljYHfGCossvsek(sa5NI0qQDCljqRjsJGu)Czq5rXKGgncdFTQ8yQ)9KDfon8eEWEcc)ebQrzq5uoT9mwnAOcIC1tjKCshG46qG5445KCeHNWMJ4yjEvZOWbo6dzAOx6iRUo)O4H7yNi4KEGLp84WO49QDN3Yfvf5BxdopV15nF795V6H8vF(vH4iCpoY)p5dGhp2RPDLdRAp)PEhyeE(qF9VUbctRP4PV(xqGTBx7CJ4H3n5)tt0oRdgh5bKrb)nm83IrHm1UAdgQN61)y6UDmn9v7QQZNGWgI4Z4zXf)t(gi4U7Yx1eytdwT2dzJIo94yyTNnv8rA9meLmyuuaAAPMuUMbgYHOAHOK)hiExijwTcKhnmLYYcVz42QnqRVrSS3w20u(47ZQUVylefqAB09d2ErpLoRp)XR14pMXVHKpSsT7zhLZfvX3BIbCklQ2do1LtqrBUqGjxHcmpQS6uqLMtPcf4x7dfJyk3(TpyYwf(bsYjHGaPTTmeKyloppvauLXDMVozU1vVnBZDhXoik1NzD0UE1381)5TBEQFW(DkBJtPevr60wNk5GAWG07l)B80FjapX(4eXyXLO9Y8LvyT8ZyfJYI6YTtkMA6M169OdpT4Y5pVn7XIv4WdMh6t5ceOGKfs8UacKrjH4aHOlvkDAyJ0ASmiM7kovNT5wbjNvp3c2t4cTr7DIOorpi3SbOLxu25WaaXkVxHqYb9m1V4)Fxwv(x)Rl2TzZx)RF9HIM8b8CcKblrDLsaZLSvbfIxfcauYsbJAPQeFTkuDWAyUg4SN0(sfP5CFKge8zKRJFBA1xh9yCJce5u(0TBbvHvETUEs8JYio4p1r9c(v7hoqeFaysEaazHA7qsSkgkJ0WnciNEbeWdNtTzsl34YToQN3kWGn17E9f3mSFggQa2LlxhFzyqi)2Yl(fJwAvG7gfKpcKOHxAKnWKyheIDFfxIMBH0dV3BmPNvUPvp9uRtx1SdCvDBGFpiGObfwyysQoXxxzBcjKERJknKvnwjyQsymD33eyc96LMPTHfzEiYeUxr2hTvxV7iwg1WpDbGfKEgf507Z(h367WYrX0qwj)9UkcA1AG)jKsimbx6aOBWo5aVqRhrCfzg0T3M9kGJ1mYgo2gvdnIE5JpUBB(aZ3qokOYORMib7JidfxkNyVhsX75u6ztR5pjdzD15avWl(Ff3og7UOS6XVvCpRkgiK9D0lu9Cy2taloAUiSBwqV2BZLGEqS4iJSCcgAWMpRFIcVEB(J(SeYiJEpMVTXxuNQ86DvKzgVsv9t5B20UfPN4DAKhacfL4NQZx3LIHxHm3vtQNYQAEUDuFmpB9ZO2k831Dt4MhG1(bWCJp8okOXylmKSr)iuXhUVkAFNxqke5QjggXXZ6zwT6r2ei)qPWcP2BuPclzvUT45aFiEJoWOV9KHrm9Dif0tgBOn73v6keNdb6TmKphwB9K7CotwkWZBautYAcEqC04X24JYUAKX32YZpWJ05F4xVk2wtRYGl7IvbHsheqEq85iOD1WNZKAoy9IIDbTRp)egImdhzmjkKmKweTJigBx2eqw(AR2albeGMp6mvhpTEO)GJk74N6o4eYon8pH)SlW08C2PZQOifespx8)aMcAougwjD6(BqHIZcN2bknOtqwYbIpOJa)(S7lwnvoXHqKprmmf9ygdeENMjHO7SsU1KQNMXmkfyYXyViDdvHieOByjbVHU9wnKt(7k2M3f4zGBEB3XRm5UDGXduboooKag8rVOJ7z3vUAhrLWiLxNF2MI)9FZQwtwCJN3hGnvWBMZqW4ddAdKkY2gWx5nF46(w47OeRkgfZjrbgfeW6QRGOZpC5N8084C29rpuGRx0zo6Su)5JWptazAJflsiQNPIIjcQOX5tWlM2DuMwJYkzklZYHGr960ktFjn0C9(eYI3atEAgDkFARIzyCvcpjXsT2TBTk6gIbu8LPUsRBLwg3ViuWKb(uS3J(D1(SSZt9vDV2Qpwy(HzwBP2ecgMPdMiYG8X0jjQeW(JmKpgmKRlRa2vrtesexzbuKrhsvEpvcZP36pTSfpwwcg06hMuVd2nK0waZmkTLRmPmEQvkIXSE1zlwjEqUROw0yNyhv5tos6CV9txLBh7w4WkMKxQrj43RYPd2URRgiOkDh)rcZYs7L5wumo8a7kwQfW1Ehr(RGyiUhwKCFyGRAQ2u3SZxXKO(C4UYQv5HuElw5dfxQtn(ADvTD9WPC7(MI1GL79HmmO9V1AyCTwKBna5PJz8GwULwG6McSuVF75y9RXNRpMrleP(vOEvwdiiCCZHR9uQ1f1ok92JARaPYHsOpVAt52JANy4jAIJmKGTFoII8UVZjxd7jxpSCeRfKTPNQTE1XmAdx5XSDzhZO1P4(4U8SQJz8UJEAztK68B2Lxxds0Dr5nzSbT1ddC7Ntbreme(DyvVx07X1Y67hkdkV0Hd2S31FIY3FuZ)0fTpSzdNeqBg4tFak9RFqRzMJW8kT4JaB0bmeh4qBf2ARGq7JIggfro610T(nU)uMmQT3YIRz9U6MYh9rwUWjU)TSp3qGLR5SHT72lbCT8rDr3Sa7jPHcORLJaUKLmQLmNf03lspQrxFraRvoS)aFjalKf)pdWYz6FkWvlh1u7VeG1kg1w2VeGvm(AanlW6Ys6E6Zk8Zi5xPXmS)pNf03R87pgsVpoNRdAE5bRqNo6k89saxiq7FiI7jCI1L2AOVf0UGw(ba9(iWJVILVeG1Q5dB95zb2tapdX1Ao1eldRth2FXZc473VXpfsb3(ZGXjHOL)HiX7ZgS5h0t0jCtpHyhV02xq(NHkTD8fd7LaSq(fVSylmWn5zqyKhoDwE7u2BfV4ufV6FAuXnLDVKQpphsa5H81ynUgh0A)6(398(X(E44KJtji6WXJsIpCq8q2QJ2y)UlbCoxjs0qiCctIaBlhiy1(hetOOjMOK6hvHK(NUWRwVx(sC40ZV64D82O6oeh5DxTEUUSoCkbdlYhegFE2G(NIGV7m5RqXnpE6BAyp72nAjeqk17Mu7ZYeyN1P1yl6rnUNRXFXhWW2Q0FRSpZ3)OP(w3l1e6Usf1THwQldnudT6(LBWpxj3q99RXsnGOs21xJylxMQO24nXq9Imcwgh75vbNzjOztXUoM6pwH2IDJOIgzQfBhz35Q7xKKqtLQsiersGYDHsD)TwLGVGHt1bZqZTsOSWLHUhtryLsnsRweAGwbIxcMe7(vJHaQHhAntTrqic2kOjHw7vrD1jNJBkjmcCt5Vgr(Va0tekarlGKuFKI9NSeirTunIptndBc19Q(lYoHb(vof3f4EqyiXaMIOCy7nd0CKusq1yPU3f7aDrIbrny1WbOsXLtWsPMXgWvehjkEAckqzO(p2v)zryKijqe6nyg1g6IuStKHLZVACSjvTuNwd)nUxesbkDXyyBzRXUhN2nCfrvcD4mhB7u8c05EUjL2FCQnLvgQNItXMUnbBXwQxKDiyG(HuxTahh1vZoceUIy7yNGpwYyOGOYGltQc7k722DvrDoBkXXLwSHybgcJ6LygTxHLIAcxAPiuir22p5MqFiNqD1p1fVWtOMUgBhzbiaJIJgUnOgOB5Be4S0RazySzFj9rJI4JuldlvKuHH6qAK7bs6bfPuQNExvC0vT9((N(5zF4MB(GRP3AYA2vFBWbuOs3QtedmA)9xkOo720pxjlCNqV386B)0v386p6(2J((6mH5Rh2IF90p(Xl)q0laEJVWAxF67o98lVQ9f4pwiWlE)PV51DpfHY1F8YxV4M2NkbUukb939Hx9)2(cpDhE(5F8txEE3W936a4XF8dV5tDWwA0AF7BT4TN((tJXefxHbGmSj68BvUGHI64nO1l8irPhjpvsoxcx6GGDP2lzqWDs7LmW1H3OKnzGIUKbJ9Mali147IW1jXFtiDFPTN4j7xWQGnNFRFgUKgIeCutZoCBv4Kf(W1vb84qDdVpkxCLi3JYeYmTcB)(wFnWqOMTp0t7TxzLeK(yzKgKG(Iiy)P1DuA4kxitz9V0kGjoeQcTQVnUwB0TgHAv4f01XO9Afa630vhs01N)KJi3Th3dodEphC3FHWRiFhHlCeemGK6JFYJGLm(061Q13x7vlq6LSCFXl65ryRTV5gFr5CVjLMnxXdS4uYExRNYGvBUoC7Ic3Aal5ULSib8Es6JI2XgIljyNfVmQ(N4W1itsF)2lUDu3y8WSpJQ(rNEv5KXNYNk2YBWz6cJpRbaZT7AY7UKG(MlYLlYwx7oVa)5RcSauUU4UI8k3BGj04SW6sqGm2IhL9YWvhCaqUWDG9tddrhm8hRVdeYjaXP(b91)6)ronC6aZASG2RxgUuI7dsQ5aj9HGKEoqYCiizMdKsoeKsMdKShcs25aP0dbP05aj836G9bkxpzC0WQzz7VNyTzZ6Dz516VPxY59(DfOXBY8q)Eh5hJ3A93amjh6NDgALgxRYHJX7O4Wdj5BnaWA(b(nFItf7D4X731TSnX9Swt(2MhQ7D0(ThPDOT27FzSdXomSwdX9Dt89mct)LAdliKL2h1MW(7l2w8y2McxNn2DvnUP8uxo)x6Rxb2(AD1VGSEoSNEI6SOJO)DEkQNOMQYbdA22HB44Q444brx1H4gozWv4)73RJhDPUxMWWEDguBfBAwU8)(7QXTTi" end \ No newline at end of file diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 7302b1d..3bf8f65 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -601,7 +601,7 @@ function Castbar:GetOptions() desc = L["Height of the bar"], order = 3, min = 0, - max = 100, + max = 200, step = 1, width = "full", }), @@ -611,7 +611,7 @@ function Castbar:GetOptions() desc = L["Width of the bars"], order = 4, min = 0, - max = 300, + max = 600, step = 1, width = "full", }), diff --git a/Modules/XiconProfiles.lua b/Modules/XiconProfiles.lua index bd12442..573634e 100644 --- a/Modules/XiconProfiles.lua +++ b/Modules/XiconProfiles.lua @@ -152,5 +152,24 @@ function XiconProfiles:GetOptions() width = "full", order = 15, }, + headerProfileMirEdited = { + type = "header", + name = "Mir's " .. L["Profile"] .. " edited", + order = 16, + }, + mirProfileEdited = { + type = "execute", + func = function() + Gladdy.dbi:ResetProfile(Gladdy.dbi:GetCurrentProfile()) + applyProfile(Gladdy:GetMirEditedProfile()) + end, + name = " ", + desc = "Mir's " .. L["Profile"], + image = "Interface\\AddOns\\Gladdy\\Images\\BasicProfiles\\Mir1_edited.blp", + imageWidth = 350, + imageHeight = 175, + width = "full", + order = 17, + }, } end \ No newline at end of file -- 2.39.5 From 47a15bd2a17a1b5313a1898d3fe2c28b1a155420 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 00:39:46 +0100 Subject: [PATCH 114/268] dump version --- Gladdy.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gladdy.lua b/Gladdy.lua index eb14d39..24dc74a 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -27,7 +27,7 @@ local LibStub = LibStub --------------------------- -local MAJOR, MINOR = "Gladdy", 4 +local MAJOR, MINOR = "Gladdy", 5 local Gladdy = LibStub:NewLibrary(MAJOR, MINOR) local L Gladdy.version_major_num = 2 -- 2.39.5 From 89a5511fb93f577998725d672b992f2c257c1918 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 03:06:02 +0100 Subject: [PATCH 115/268] perception cd tracking improved (rogue out of stealth) --- EventListener.lua | 9 +++++++++ Modules/Racial.lua | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 23cd832..4d97d35 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -86,6 +86,9 @@ function Gladdy:SpotEnemy(unit, auraScan) end end end + if Gladdy.cooldownBuffs.racials[spellName] then + Gladdy:SendMessage("RACIAL_USED", unit, expirationTime, spellName) + end if Gladdy.specBuffs[spellName] then -- Check for auras that detect a spec local unitPet = string_gsub(unit, "%d$", "pet%1") if UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster) then @@ -216,6 +219,9 @@ Gladdy.exceptionNames = { -- TODO MOVE ME TO CLASSBUFFS LIB Gladdy.cooldownBuffs = { [GetSpellInfo(6346)] = { cd = 180, spellId = 6346 }, -- Fear Ward + racials = { + [GetSpellInfo(20600)] = { cd = 180, spellId = 20600 }, -- Perception + } } function EventListener:UNIT_AURA(unit) @@ -243,6 +249,9 @@ function EventListener:UNIT_AURA(unit) end end end + if Gladdy.cooldownBuffs.racials[spellName] then + Gladdy:SendMessage("RACIAL_USED", unit, spellName, expirationTime, spellName) + end if not button.spec and Gladdy.specBuffs[spellName] then local unitPet = string_gsub(unit, "%d$", "pet%1") if unitCaster and (UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster)) then diff --git a/Modules/Racial.lua b/Modules/Racial.lua index 7838b9b..ec5e237 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -165,13 +165,17 @@ function Racial:JOINED_ARENA() end) end -function Racial:RACIAL_USED(unit) +function Racial:RACIAL_USED(unit, expirationTime, spellName) local racial = self.frames[unit] local button = Gladdy.buttons[unit] if (not racial or not button or not button.race) then return end - Racial:Used(unit, GetTime(), Gladdy:Racials()[button.race].duration) + if expirationTime and Gladdy:Racials()[button.race].spellName ~= spellName then + return + end + local startTime = (expirationTime and expirationTime - Gladdy:Racials()[button.race].duration) or GetTime() + Racial:Used(unit, startTime, Gladdy:Racials()[button.race].duration) end function Racial:Used(unit, startTime, duration) -- 2.39.5 From ddccf7a62eb5bf4dda28792241c172af8044e8bf Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 03:14:02 +0100 Subject: [PATCH 116/268] frFR localization by Macumba --- Lang.lua | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) diff --git a/Lang.lua b/Lang.lua index 740b673..3ae287d 100644 --- a/Lang.lua +++ b/Lang.lua @@ -1413,6 +1413,359 @@ elseif GetLocale() == "zhCN" then L["Background Color of the frame"] = "框架的背景顏色" L["Gladdy"] = "Gladdy框架" --Line 210, 709, 727 +elseif GetLocale() == "frFR" then + -- Announcements.lua + L["Announcements"] = "ANNONCE" + L["RESURRECTING: %s (%s)"] = "EN TRAIN DE RESSUSCITER: %s (%s)" + L["SPEC DETECTED: %s - %s (%s)"] = "SPEC DETECTÉ: %s - %s (%s)" + L["LOW HEALTH: %s (%s)"] = "VIE BASSE: %s (%s)" + L["TRINKET USED: %s (%s)"] = "TRINKET UTILISÉ: %s (%s)" + L["TRINKET READY: %s (%s)"] = "TRINKET PRÊT: %s (%s)" + L["DRINKING: %s (%s)"] = "EN TRAIN DE BOIRE: %s (%s)" + L["Self"] = "Soi" + L["Party"] = "Groupe" + L["Raid Warning"] = "Avertissement de raid" + L["Blizzard's Floating Combat Text"] = "Texte de combat flottant de Blizzard" + L["Trinket used"] = "Trinket utilisé" + L["Announce when an enemy's trinket is used"] = "Annonce quand un trinket ennemie est utilisé" + L["Trinket ready"] = "Trinket prêt" + L["Announce when an enemy's trinket is ready again"] = "Annonce quand un trinket ennemie est prêt de nouveau" + L["Drinking"] = "En train de boire" + L["Announces when enemies sit down to drink"] = "Annonce quand les ennemies s'assoient pour boire" + L["Resurrection"] = "Resurrection" + L["Announces when an enemy tries to resurrect a teammate"] = "Annonce quand un ennemie essaie de ressusciter un membre de son groupe" + L["New enemies"] = "Nouveaux ennemis" + L["Announces when new enemies are discovered"] = "Annonce quand les ennemies sont découverts" + L["Spec Detection"] = "Détection des SPEC" + L["Announces when the spec of an enemy was detected"] = "Annonce quand une spec d'un ennemie est détecté" + L["Low health"] = "Vie Basse" + L["Announces when an enemy drops below a certain health threshold"] = "Annonce quand un ennemie tombe en dessous d'un certain seuil de points de vie" + L["Low health threshold"] = "Seuil de points de vie bas" + L["Choose how low an enemy must be before low health is announced"] = "Choisissez à quel point un ennemi doit être bas avant d'annoncer une santé faible" + L["Destination"] = "Destination" + L["Choose how your announcements are displayed"] = "Choisissez comment vos annonces sont affichées" + + -- ArenaCountDown.lua + L["Arena Countdown"] = "Compte à rebours de l'arène" + L["Turn on/off"] = "Activer / désactiver" + L["Turns countdown before the start of an arena match on/off."] = "Active / désactive le compte à rebours avant le début d'un match d'arène" + L["Size"] = "Taille" + + -- Auras.lua + L["Auras"] = "Auras" + L["Frame"] = "Cadre" + L["Cooldown"] = "Temps de recharge" + L["No Cooldown Circle"] = "Pas de Balayage du temps de recharge" + L["Cooldown circle alpha"] = "Alpha du Balayage du temps de recharge" + L["Font"] = "Police de caractère" + L["Font of the cooldown"] = "Police du temps de recharge" + L["Font scale"] = "Échelle de police" + L["Scale of the text"] = "Échelle du texte" + L["Font color"] = "Couleur de la police" + L["Color of the text"] = "Couleur du texte" + L["Border"] = "Bordure" + L["Border style"] = "Style de bordure" + L["Buff color"] = "Couleur des buff" + L["Debuff color"] = "Couleur des Debuff" + L["Check All"] = "Vérifie tout" + L["Uncheck All"] = "Décocher tout" + L["Enabled"] = "Activé" + L["Priority"] = "Priorité" + + -- BuffsDebuffs.lua + L["Buffs and Debuffs"] = "Buffs et Debuffs" + L["Enable"] = "Activé" + L["Enabled Buffs and Debuffs module"] = "Module de buffs et debuffs activés" + L["Show CC"] = "Montrer les CC" + L["Shows all debuffs, which are displayed on the ClassIcon as well"] = "Montrer tout les debuffs, qui sont affichés sur l'icone de classe aussi" + L["Buffs"] = "Buffs" + L["Size & Padding"] = "Taille et remplissage" + L["Icon Size"] = "Taille de l'icône" + L["Size of the DR Icons"] = "Taille des icones de DR" + L["Icon Width Factor"] = "Facteur de largeur d'icône" + L["Stretches the icon"] = "Étire l'icône" + L["Icon Padding"] = "Remplissage d'icônes" + L["Space between Icons"] = "Espace entre les icônes" + L["Position"] = "Position" + L["Aura Position"] = "Position de l'aura" + L["Position of the aura icons"] = "Position de l'icône de l'aura" + L["Top"] = "Haut" + L["Bottom"] = "Bas" + L["Left"] = "Gauche" + L["Right"] = "Droite" + L["Grow Direction"] = "Direction de croissance" + L["Grow Direction of the aura icons"] = "Direction de croissance de l'icônr de l'aura" + L["Horizontal offset"] = "Décalage horizontal" + L["Vertical offset"] = "Décalage verticale" + L["Alpha"] = "Alpha" + L["Debuffs"] = "Debuffs" + L["Dynamic Timer Color"] = "Couleur de la minuterie dynamique" + L["Show dynamic color on cooldown numbers"] = "Afficher la couleur dynamique sur les numéros de recharge" + L["Color of the cooldown timer and stacks"] = "Couleur du temps de recharge et des piles" + L["Spell School Colors"] = "Couleurs de l'école de sorts" + L["Spell School Colors Enabled"] = "Couleurs de l'école de sorts" + L["Show border colors by spell school"] = "Afficher les couleurs des bordures par école de sorts" + L["Curse"] = "Malédiction" + L["Color of the border"] = "Couleur de la bordure" + L["Magic"] = "Magique" + L["Poison"] = "Poison" + L["Physical"] = "Physique" + L["Immune"] = "Immunisé" + L["Disease"] = "Maladie" + L["Aura"] = "Aura" + L["Form"] = "Forme" + + -- Castbar.lua + L["Cast Bar"] = "Barre d'incantation" + L["Bar"] = "Barre" + L["Bar Size"] = "Taille de la barre" + L["Bar height"] = "Hauteur de la barre" + L["Height of the bar"] = "Hauteur de la barre" + L["Bar width"] = "Largeur de la barre" + L["Width of the bars"] = "Largeur de la barre" + L["Texture"] = "Texture" + L["Bar texture"] = "Texture de la barre" + L["Texture of the bar"] = "Texture de la barre" + L["Bar color"] = "Couleur de la barre" + L["Color of the cast bar"] = "Couleur de la barre d'incantation" + L["Background color"] = "Couleur de l'Arrière plan" + L["Color of the cast bar background"] = "Couleur de l'Arrière plan de la barre d'incantation" + L["Border size"] = "taille de la bordure" + L["Status Bar border"] = "Bordure de la barre de statut" + L["Status Bar border color"] = "Couleur de la bordure de la barre de statut" + L["Icon"] = "Icone" + L["Icon size"] = "Taille de l'icone" + L["Icon border"] = "Bordure de l'icone" + L["Icon border color"] = "Couleur de la bordure de l'icone" + L["Spark"] = "Etincelle" + L["Spark enabled"] = "Etincelle activé" + L["Spark color"] = "Couleur de l'étincelle" + L["Color of the cast bar spark"] = "Couleur de l'étincelle de la barre d'incantation" + L["Font of the castbar"] = "Police de la barre d'incantation" + L["Font size"] = "Taille de la police" + L["Size of the text"] = "Taille du texte" + L["Format"] = "Format" + L["Timer Format"] = "Format du timer" + L["Remaining"] = "Restant" + L["Total"] = "Total" + L["Both"] = "Les deux" + L["Castbar position"] = "Position de la barre d'incantation" + L["Icon position"] = "Position de l'icone" + L["Offsets"] = "Décalage" + + -- Classicon.lua + L["Class Icon"] = "Icone de la classe" + L["Balance"] = "Equilibre" + L["Feral"] = "Combat farouche" + L["Restoration"] = "Restauration" + L["Beast Mastery"] = "Maîtrise des bêtes" + L["Marksmanship"] = "Précision" + L["Survival"] = "Survie" + L["Arcane"] = "Arcane" + L["Fire"] = "Feu" + L["Frost"] = "Givre" + L["Holy"] = "Sacré" + L["Retribution"] = "Vindicte" + L["Protection"] = "Protection" + L["Discipline"] = "Discipline" + L["Shadow"] = "Ombre" + L["Assassination"] = "Assassinat" + L["Combat"] = "Combat" + L["Subtlety"] = "Finesse" + L["Elemental"] = "Elementaire" + L["Enhancement"] = "Amélioration" + L["Affliction"] = "Affliction" + L["Demonology"] = "Démonologie" + L["Destruction"] = "Destruction" + L["Arms"] = "Armes" + L["Fury"] = "Fureur" + L["Show Spec Icon"] = "Afficher l'icone des spécialisations" + L["Shows Spec Icon once spec is detected"] = "Afficher l'icone des spécialisations une fois que les spé sont détectés" + L["Icon width factor"] = "Facteur de largeur d'icône" + L["This changes positions with trinket"] = "Cela change de position avec le trinket" + L["Border color"] = "Couleur de la bordure" + + --CombatIndicator.lua + L["Combat Indicator"] = "Indicateur de combat" + L["Enable Combat Indicator icon"] = "Activer l'icone de l'indicateur de combat" + L["Anchor"] = "Ancre" + L["This changes the anchor of the ci icon"] = "Cela change l'ancre de l'icône de l'indicateur de combat" + L["This changes position relative to its anchor of the ci icon"] = "Cela change la position par rapport à son ancre de l'icône de l'indicateur de combat" + + -- Cooldowns.lua + L["Cooldowns"] = "Temps de recharge (CD)" + L["COOLDOWN USED: %s (%s) used %s - %s sec. cooldown"] = "CD utilisé : %s (%s) utilisé %s - %s sec. cd" + L["Enabled cooldown module"] = "Module du temps de recharge activé" + L["Cooldown size"] = "Taille du temps de recharge" + L["Size of each cd icon"] = "Taille de chaque icone de CD" + L["Max Icons per row"] = "Nombre maximal d'icônes par ligne" + L["Scale of the font"] = "Échelle de la police" + L["Anchor of the cooldown icons"] = "Ancre de l'icone du temps de recharge" + L["Grow Direction of the cooldown icons"] = "Direction de croissance des icônes de temps de recharge" + L["Offset"] = "Décalage" + + -- Diminishings.lua + L["Diminishings"] = "Rendements décroissants (DR)" + L["Enabled DR module"] = "Activer le module DR" + L["DR Cooldown position"] = "Position du temps de recharge des DR" + L["Position of the cooldown icons"] = "Position des icones de temps de recharge" + L["DR Border Colors"] = "Couleur de la bordure des DR" + L["Dr Border Colors Enabled"] = "Couleur de la bordure des DR activé" + L["Colors borders of DRs in respective DR-color below"] = "Couleurs des bordures des DR dans la couleur DR respective ci-dessous" + L["Half"] = "Demi" + L["Quarter"] = "Quart" + L["Categories"] = "Catégories" + L["Force Icon"] = "Forcer les icones" + L["Icon of the DR"] = "Icones des DR" + + -- ExportImport.lua + L["Export Import"] = "Exporter Importer" + L["Profile Export Import"] = "Profile de l'Exporter Importer" + + -- Healthbar.lua + L["Health Bar"] = "Barre de vie" + L["DEAD"] = "MORT" + L["LEAVE"] = "QUITTER" + L["General"] = "Général" + L["Color of the status bar background"] = "Couleur de l'arrière-plan de la barre d'état" + L["Font of the bar"] = "Police de la barre" + L["Name font size"] = "Taille de la police du nom" + L["Size of the name text"] = "Taille du texte du nom" + L["Health font size"] = "Taille de la police de la santé" + L["Size of the health text"] = "Taille du texte de la santé" + L["Size of the border"] = "Taille de la bordure" + L["Health Bar Text"] = "Texte de la barre de santé" + L["Show name text"] = "Afficher le texte du nom" + L["Show the units name"] = "Afficher le nom des unités" + L["Show ArenaX"] = "Afficher ArenaX" + L["Show Arena1-5 as name instead"] = "Afficher Arena1-5 comme nom à la place" + L["Show the actual health"] = "Afficher la santé réelle" + L["Show the actual health on the health bar"] = "Afficher la santé réelle sur la barre de santé" + L["Show max health"] = "Afficher la santé maximale" + L["Show max health on the health bar"] = "Afficher la santé maximale sur la barre de santé" + L["Show health percentage"] = "Afficher le pourcentage de santé" + L["Show health percentage on the health bar"] = "Afficher le pourcentage de santé sur la barre de santé" + + -- Highlight.lua + L["Highlight"] = "Surbrillance" + L["Show Inside"] = "Afficher dedans" + L["Show Highlight border inside of frame"] = "Afficher la bordure de surbrillance à l'intérieur du cadre" + L["Colors"] = "Couleurs" + L["Target border color"] = "Couleur de la bordure cible" + L["Color of the selected targets border"] = "Couleur de la bordure des cibles sélectionnées" + L["Focus border color"] = "Couleur de la bordure du Focus" + L["Color of the focus border"] = "Couleur de la bordure du Focus" + L["Highlight target"] = "Mettre la cible en surbrillance" + L["Toggle if the selected target should be highlighted"] = "Basculer si la cible sélectionnée doit être mise en surbrillance" + L["Show border around target"] = "Afficher la bordure autour de la cible" + L["Toggle if a border should be shown around the selected target"] = "Basculer si une bordure doit être affichée autour de la cible sélectionnée" + L["Show border around focus"] = "Afficher la bordure autour du focus" + L["Toggle of a border should be shown around the current focus"] = "La bascule d'une bordure doit être affichée autour du focus actuel" + + -- Pets.lua + L["Pets"] = "Familier" + L["Enables Pets module"] = "Activer le module familier (pet)" + L["Width of the bar"] = "Largeur de la barre" + L["Health color"] = "Couleur de la santé" + L["Color of the status bar"] = "Couleur de la barre d'état" + L["Portrait"] = "Portrait" + L["Health Values"] = "Valeurs de santé" + + -- Powerbar.lua + L["Power Bar"] = "Barre de puissance" + L["Power Bar Text"] = "Texte de la barre de puissance" + L["Power Texts"] = "Textes de puissance" + L["Show race"] = "Afficher la race" + L["Show spec"] = "Afficher la spé" + L["Show the actual power"] = "Afficher la puissance actuelle" + L["Show the actual power on the power bar"] = "Afficher la puissance actuelle sur la barre de puissance" + L["Show max power"] = "Afficher la puissance maximale" + L["Show max power on the power bar"] = "Afficher la puissance maximale sur la barre de puissance" + L["Show power percentage"] = "Afficher le pourcentage de puissance" + L["Show power percentage on the power bar"] = "Afficher le pourcentage de puissance sur la barre de puissance" + + -- Racial.lua + L["Racial"] = "Raciale" + L["Enable racial icon"] = "Activer l'icone du raciale" + L["This changes the anchor of the racial icon"] = "Cela change l'ancre de l'icône du raciale" + L["This changes position relative to its anchor of the racial icon"] = "Cela change de position par rapport à son ancre de l'icône du raciale" + + -- TotemPlates.lua + L["Totem Plates"] = "Totem Plates" + L["Customize Totems"] = "Personnaliser les totems" + L["Custom totem name"] = "Personnaliser le nom des totems" + L["Totem General"] = "Totem Général" + L["Turns totem icons instead of nameplates on or off. (Requires reload)"] = "Active ou désactive les icônes totem au lieu des nameplates. (Nécessite un rechargement)" + L["Show friendly"] = "Montrer les amis" + L["Show enemy"] = "Montrer les ennemies" + L["Totem size"] = "Taille du totem" + L["Size of totem icons"] = "Taille de l'icone du totem" + L["Font of the custom totem name"] = "Police du nom du totem personnalisé" + L["Apply alpha when no target"] = "Appliquer l'alpha en l'absence de cible" + L["Always applies alpha, even when you don't have a target. Else it is 1."] = "Applique toujours l'alpha, même lorsque vous n'avez pas de cible. Sinon c'est 1." + L["Apply alpha when targeted"] = "Appliquer l'alpha lorsque ciblé" + L["Always applies alpha, even when you target the totem. Else it is 1."] = "Applique toujours l'alpha, même lorsque vous ciblez le totem. Sinon c'est 1." + L["All totem border alphas (configurable per totem)"] = "Tous les alphas de bordure de totem (configurables par totem)" + L["Totem icon border style"] = "Style de bordure d'icône totem" + L["All totem border color"] = "Toutes les couleurs de bordure de totem" + + -- Trinket.lua + L["Trinket"] = "Trinket (Bijoux PvP)" + L["Enable trinket icon"] = "Activer l'icone du trinket" + L["This changes positions of the trinket"] = "Cela change les positions du trinket" + + -- XiconProfiles.lua + L["Profile"] = "Profile" + + -- Frame.lua + L["Gladdy - drag to move"] = "Gladdy - faites glisser pour déplacer" + + -- Gladdy.lua + L["Welcome to Gladdy!"] = "Bienvenue chez Gladdy !" + L["First run has been detected, displaying test frame."] = "La première exécution a été détectée, affichant la trame de test." + L["Valid slash commands are:"] = "Les commandes de slash valides sont :" + L["If this is not your first run please lock or move the frame to prevent this from happening."] = "S'il ne s'agit pas de votre première utilisation, veuillez verrouiller ou déplacer le cadre pour éviter que cela ne se produise." + + -- Options.lua + L["settings"] = "paramètres" + L["Reset module"] = "Réinitialiser le module" + L["Reset module to defaults"] = "Réinitialiser le module" + L["No settings"] = "Pas de paramètres" + L["Module has no settings"] = "Le module n'a pas de paramètres" + L["General settings"] = "Paramètres général" + L["Lock frame"] = "Verouiller le cadre" + L["Toggle if frame can be moved"] = "Cliquez si le cadre peut être bougé" + L["Grow frame upwards"] = "Agrandir le cadre vers le haut" + L["If enabled the frame will grow upwards instead of downwards"] = "Si activé, le cadre grandira vers le haut au lieu de vers le bas" + L["Down"] = "Vers la bas" + L["Up"] = "Vers le haut" + L["Frame General"] = "Cadre général" + L["Frame scale"] = "Taille du cadre" + L["Scale of the frame"] = "Taille du cadre" + L["Frame padding"] = "Remplissage du cadre" + L["Padding of the frame"] = "Remplissage du cadre" + L["Frame width"] = "Largeur du cadre" + L["Margin"] = "Marge" + L["Margin between each button"] = "Marge entre chaque bouton" + L["Cooldown General"] = "Temps de recharge Général" + L["Font General"] = "Police Général" + L["General Font"] = "Police Général" + L["Font color text"] = "Texte de la couleur de la police" + L["Font color timer"] = "Texte de la couleur de la police" + L["Color of the timers"] = "Couleur des minuteurs" + L["Icons General"] = "Icônes Général" + L["Icon border style"] = "Style de bordure d'icône" + L["This changes the border style of all icons"] = "Cela change le style de bordure de toutes les icônes" + L["This changes the border color of all icons"] = "Cela change la couleur de bordure de toutes les icônes" + L["Statusbar General"] = "Barre d'état Général" + L["Statusbar texture"] = "Texture de la Barre d'état" + L["This changes the texture of all statusbar frames"] = "Cela change la texture de tous les cadres de la barre d'état" + L["Statusbar border style"] = "Style de bordure de la barre d'état" + L["This changes the border style of all statusbar frames"] = "Cela modifie le style de bordure de tous les cadres de la barre d'état" + L["Statusbar border offset divider (smaller is higher offset)"] = "Diviseur de décalage de bordure de barre d'état (le plus petit est le décalage le plus élevé)" + L["Offset of border to statusbar (in case statusbar shows beyond the border)"] = "Décalage de la bordure par rapport à la barre d'état (au cas où la barre d'état s'afficherait au-delà de la bordure)" + L["Statusbar border color"] = "Couleur de la bordure de la barre d'état" + L["This changes the border color of all statusbar frames"] = "Cela change la couleur de la bordure de tous les cadres de la barre d'état" end -- 2.39.5 From 35e119160a69d610428961177c8be07b2e7e174e Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 05:51:39 +0100 Subject: [PATCH 117/268] no more restoration warlocks --- Modules/Cooldowns.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 8c695af..4dea4e9 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -345,6 +345,12 @@ function Cooldowns:DetectSpec(unit, spec) end if button.class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) or button.class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) + or button.class == "ROGUE" and notIn(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) + or button.class == "WARLOCK" and notIn(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) + or button.class == "PRIEST" and notIn(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) + or button.class == "MAGE" and notIn(spec, {L["Frost"], L["Fire"], L["Arcane"]}) + or button.class == "DRUID" and notIn(spec, {L["Restoration"], L["Feral"], L["Balance"]}) + or button.class == "HUNTER" and notIn(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) or button.class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then return end -- 2.39.5 From 4583cbdf24ba69f267a4b26cb04d65116e0d2833 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 05:51:56 +0100 Subject: [PATCH 118/268] add Flat Statusbar texture --- Gladdy.lua | 1 + Images/UI-StatusBar.blp | Bin 0 -> 1564 bytes 2 files changed, 1 insertion(+) create mode 100644 Images/UI-StatusBar.blp diff --git a/Gladdy.lua b/Gladdy.lua index 24dc74a..32fb1e3 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -268,6 +268,7 @@ function Gladdy:OnInitialize() self.LSM:Register("statusbar", "Smooth", "Interface\\AddOns\\Gladdy\\Images\\Smooth") self.LSM:Register("statusbar", "Minimalist", "Interface\\AddOns\\Gladdy\\Images\\Minimalist") self.LSM:Register("statusbar", "LiteStep", "Interface\\AddOns\\Gladdy\\Images\\LiteStep.tga") + self.LSM:Register("statusbar", "Flat", "Interface\\AddOns\\Gladdy\\Images\\UI-StatusBar") self.LSM:Register("border", "Gladdy Tooltip round", "Interface\\AddOns\\Gladdy\\Images\\UI-Tooltip-Border_round_selfmade") self.LSM:Register("border", "Gladdy Tooltip squared", "Interface\\AddOns\\Gladdy\\Images\\UI-Tooltip-Border_square_selfmade") self.LSM:Register("font", "DorisPP", "Interface\\AddOns\\Gladdy\\Images\\DorisPP.TTF") diff --git a/Images/UI-StatusBar.blp b/Images/UI-StatusBar.blp new file mode 100644 index 0000000000000000000000000000000000000000..0e8013c217fb76c5e08156932d91c0a0d6a32927 GIT binary patch literal 1564 zcmZ?r2{2-0U|?WkU|@6r(i}iMg$0ON85phr@fRRwVPjz60b&s#CJF!zbO0(;0Ac|k z2AK)NK;|eI4S~@R7!3iOArSvxeBXZ{7^TSz2a%=!|F2s0|36+D7`|Y6H2N2m{|`t5 E0G#DDBme*a literal 0 HcmV?d00001 -- 2.39.5 From 4885e11b106e4c3fb55ab4fdc7fc0d3031b82b33 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 06:20:06 +0100 Subject: [PATCH 119/268] fix avenging wrath resets Divine Shield to 60s when Divine Shield CD > 60 --- Modules/Cooldowns.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 4dea4e9..9c8b190 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -534,7 +534,17 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId, expirationTimeInSecond for spellID,_ in pairs(cooldown.sharedCD) do if (spellID ~= "cd") then - self:CooldownStart(button, spellID, sharedCD) + local skip = false + for i = 1, button.lastCooldownSpell do + local icon = button.spellCooldownFrame["icon" .. i] + if (icon.spellId == spellID and icon.active and icon.timeLeft > sharedCD) then + skip = true + break + end + end + if not skip then + self:CooldownStart(button, spellID, sharedCD) + end end end end -- 2.39.5 From 016327c6599602fe33651d2ee12235b529c76069 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 06:35:49 +0100 Subject: [PATCH 120/268] add Conflagrate cd --- Constants.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Constants.lua b/Constants.lua index 8bbd4c7..87f9878 100644 --- a/Constants.lua +++ b/Constants.lua @@ -922,6 +922,7 @@ local cooldownList = { [27277] = 8, -- Devour Magic [30414] = { cd = 20, spec = L["Destruction"], }, -- Shadowfury [17877] = { cd = 15, spec = L["Destruction"], }, -- Shadowburn + [30912] = { cd = 10, spec = L["Destruction"], }, -- Conflagrate [18708] = { cd = 900, spec = L["Demonology"], }, -- Feldom }, -- 2.39.5 From 2d58d3fb7738bec9020532fa4e1e0d12ecf8af9f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 14 Jan 2022 06:50:39 +0100 Subject: [PATCH 121/268] add Tree of Life druid spec detection --- Constants.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Constants.lua b/Constants.lua index 87f9878..0a5704e 100644 --- a/Constants.lua +++ b/Constants.lua @@ -20,6 +20,7 @@ local specBuffs = { [GetSpellInfo(24858)] = L["Restoration"], -- Moonkin Form; Dreamstate spec in TBC equals Restoration [GetSpellInfo(17007)] = L["Feral"], -- Leader of the Pack [GetSpellInfo(16188)] = L["Restoration"], -- Nature's Swiftness + [GetSpellInfo(33891)] = L["Restoration"], -- Tree of Life -- HUNTER [GetSpellInfo(34692)] = L["Beast Mastery"], -- The Beast Within @@ -97,6 +98,7 @@ local specSpells = { [GetSpellInfo(33987)] = L["Feral"], -- Mangle (Bear) [GetSpellInfo(18562)] = L["Restoration"], -- Swiftmend [GetSpellInfo(16188)] = L["Restoration"], -- Nature's Swiftness + [GetSpellInfo(33891)] = L["Restoration"], -- Tree of Life -- HUNTER [GetSpellInfo(19577)] = L["Beast Mastery"], -- Intimidation -- 2.39.5 From 19eba81faa2814b72fef20db0dd8e58dc4922621 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 25 Jan 2022 19:58:51 +0100 Subject: [PATCH 122/268] shadowsight fix enabled/disabled --- Modules/ShadowsightTimer.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Modules/ShadowsightTimer.lua b/Modules/ShadowsightTimer.lua index 09d9631..8843cc2 100644 --- a/Modules/ShadowsightTimer.lua +++ b/Modules/ShadowsightTimer.lua @@ -148,13 +148,15 @@ end --------------------------- function ShadowsightTimer:JOINED_ARENA() - self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") - self:SetScript("OnEvent", ShadowsightTimer.OnEvent) - for i=1,2 do - self["timerFrame" .. i].font:SetText("1:30") - self["timerFrame" .. i].font:SetTextColor(1, 0.8, 0) + if Gladdy.db.shadowsightTimerEnabled then + self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") + self:SetScript("OnEvent", ShadowsightTimer.OnEvent) + for i=1,2 do + self["timerFrame" .. i].font:SetText("1:30") + self["timerFrame" .. i].font:SetTextColor(1, 0.8, 0) + end + self.anchor:Show() end - self.anchor:Show() end function ShadowsightTimer:AURA_GAIN(unit, auraType, spellID) -- 2.39.5 From 9266274c1646adaa0a28bc3312429555516d3bb6 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 25 Jan 2022 20:01:42 +0100 Subject: [PATCH 123/268] legacy to newlayout fix when frame has width = 0 or height = 0 --- Frame.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Frame.lua b/Frame.lua index 4baab81..84f5453 100644 --- a/Frame.lua +++ b/Frame.lua @@ -368,6 +368,10 @@ function Gladdy:SetPosition(frame, unit, xOffsetDB, yOffsetDB, newLayout, module if (not newLayout) then --Gladdy:Debug("INFO", name, "old X/Y:", frame:GetCenter()) local xOffset, yOffset = frame:GetLeft(), frame:GetTop() + if not xOffset or not yOffset then + xOffset = frame:GetCenter() - frame:GetWidth()/2 + yOffset = select(2, frame:GetCenter()) + frame:GetHeight()/2 + end local x,y = button.healthBar:GetLeft(), button.healthBar:GetTop() local newXOffset = math_abs(x - xOffset) * (x > xOffset and -1 or 1) local newYOffset = math_abs(y - yOffset) * (y > yOffset and -1 or 1) -- 2.39.5 From 37902e37e793026c2e578bbaefe68caf20165026 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 25 Jan 2022 20:03:17 +0100 Subject: [PATCH 124/268] hide countdown frame when not used --- Modules/ArenaCountDown.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index dda004f..6218064 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -26,7 +26,7 @@ function ACDFrame:Initialize() ACDNumFrame:SetHeight(512) ACDNumFrame:SetWidth(512) ACDNumFrame:SetPoint("CENTER", 0, 256) - ACDNumFrame:Show() + ACDNumFrame:Hide() self.ACDNumFrame = ACDNumFrame local ACDNumTens = ACDNumFrame:CreateTexture("ACDNumTens", "HIGH") @@ -88,6 +88,7 @@ function ACDFrame.OnUpdate(self, elapse) self.countdown = self.countdown - elapse; else self.hidden = true; + self.ACDNumFrame:Hide() self.ACDNumTens:Hide(); self.ACDNumOnes:Hide(); self.ACDNumOne:Hide(); -- 2.39.5 From 27eeade50744adca5306dc2ed8b1aa4b578c8ee4 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 25 Jan 2022 20:40:42 +0100 Subject: [PATCH 125/268] better class icons --- Images/Classes/INV_Hammer_01.blp | Bin 23016 -> 6660 bytes Images/Classes/INV_Sword_27.blp | Bin 23016 -> 6660 bytes Images/Classes/INV_ThrowingKnife_04.blp | Bin 6660 -> 6660 bytes Images/Classes/Spell_Nature_Drowsy.blp | Bin 6660 -> 6660 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Images/Classes/INV_Hammer_01.blp b/Images/Classes/INV_Hammer_01.blp index 3f73ae7b4c5efe88442c1247acbbb340c184652b..0eb729fe65f4142ea0d44696003319a197c9f978 100644 GIT binary patch literal 6660 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 Y-Fa(Y%-{Bz&0Mub=#d?X==;Eb0mbRiX#fBK literal 23016 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 diff --git a/Images/Classes/INV_ThrowingKnife_04.blp b/Images/Classes/INV_ThrowingKnife_04.blp index 51ba1239d4e3ff7a406c445442890342d97b40cf..39678daf07ac3d9c74d84406052be4130aebc140 100644 GIT binary patch literal 6660 zcmb7J4^&h29{({Q?|=!I92M!fA$w1hiDXmpoMZ#*m46b!%Lr*Or=|#ss6ARDQy~8! zT0Um^vJPsfO=k6SW}1QEpVu+Lo=q$bCZI!6hsPGAzt32eI#`#3+z` zufB0Ki+yK>%^J?~10E>P35!^|(an#hT;cdxS#I3n^#BYWJYgiu5B>+a;{ZBa2X-)S z|9QmzJD&R@fA4BL!}-r+)_GPR=mEVTm)OMH_f!XVobZQRVD4x>UgN?uoCs$M(>yVJ zhqsEWGGA*I81MI1ecQn0H_W9S(cfSD%V8WIevkKaSlPW-`-%PT&mF(=@+-XqeOcng zW?t@{AN-AMC{^EFW4jJbu=C%!;`ZZPexH|TdDt-pKWsjw6*oBlK(F!5R!+|)iH7r! z!GrZ%bowWE{`tIj;?%HqFJ@fi_(6~Hln>|M;=#N;=#_pnnBzyTuWEn6`oIqO+s7Kh z1NHHAG;StmpY@d+ZaILND|o+qjs|e{ejd&H(|(Alc>=pi<+BTEJ3-6Yhi5xu7Elk%*DWbhZiEhYrpOhgQAsX=T zvjcJ0@9ESZ@Y_Is3NNqqz*fL+{ZJ+b<3G|z{Bi3e*ey>pfxJd89+i=+-6+JMxm$5C zG(8XEr7bcf7h4oy|NZ*uu_+m;J%DeZ%;gTs}z|+LX^Ps z`EDsnO-)S)oV^MmU#pGyzjb~|jG@~s2Kt5M4MCd1zHY!JGS>dQRKTA0JTYxSNSSlD z1M)#zu>H(8-vs#wyVaCJk&^@X@S2;td$$jfe5`oUCsb2-+X(cHBh|=|Wj+S@V=?QG zW*%Tq`}1&qm2!nY(4%oa($iB?0DJO(myD2DVYLDMUh>VD{9Hpb;6YQdeZxcIj}Mm* zdJ@pE+f9^jHJXd2Bk$P-Z`i5%L z(@Fi##z>KNT|4Q4Vc+N|+GdReeIaKZ>e9XTC4iSEAv8}zlX`o`ug3jk!VL=i^{ZqQ zP6xp&w>s2Xja35l#NxBDR)1qY;K6H4VvPA3!taP3Xm7S&Iw1Z4kN7?P>3Cj6`CA10 z&st88=!^FM1nebSmL|QXZBznoY#OJRi)%9h@35A{=4%CiJoP^b2k3DYQq&lY^15Gze4(D$nI zzp)BQX&vArmj}h;cx`|`eQQx<;qAS|pDHZ>xcO3t&x6?ClOR8_QcYQ{!ui<=l`9wzZQSPs)6gd z!Rfaw4-e2kx!$sh&M=Vp=M*oQVcmJ92IzT}_@5fEkUAap&mar-A=l9P^d@VhqsdCM=q*B{^_H)^(`V{ zece@mbF9Wtfq?#fnYTaP+h+uPMiDQjH4n!Eu2bw27v3r*{Q58*(qydb272H&eYkN$ z5$T87%O1b}d-ne;<#;~2lr-pzb+$^yMVa#fPr&JB1`uYX>LvkLfgmJN&_=VL(qJ^NpT>%DK^da_={2dnY<_2D7VClafX zMeNc5)(5YrG}=$edFgcMDSW?RNWb_*go_m>n(&`!&J=n33;pzSSHn(CdUreMyXL%q zxJY3o`8e*_xJ`4do8;pw#|zct{QXIPU3Dg(%e4#ff6=IWCM8|yFTDN_sQ;7WM@Zgp z{`%nc*OqaJoi;1t$^-`^%-~Oi8Ay zhWIxy{!Zr30x7P)g`AJ5cy|8Ne|ny83&!i4P3Y$~JpYa6Uef;`2k)W!7^N@xyLe<# zucf`bm`|d#%EJt{dMnMAMEC@SiV?AF8xz$okdGTo1$fumYW7zH}Ju!ujrM z*OBIg((o-n?_sJMqpiaH|Gt_1^+0veO%G(_)#(gcd=Q!u zy%34-1GvEGQ4RA52mN#IGyp2yF83VCU?|1R<1?DZYmjZnyK7W}-w<-ZE z@c9CvjCFv&!272euYc8u@n@xI8$|zHa`~uJ?on0Rkg)giE_6+;5# zhSKP-3B4MLGWzUfKDQ}kUKx3{n}B|&pd>OeDLEOir+s$62^o5g%zy78YNXMITYx|D zJtR_|bdvgg;HWA{yEEkrpkHxN>o!+*k@J2^!}Wlla%+e`iz4Hn36w~P|DO4;!~6Y; z-d@r_dVIbva77zI|MUov*!0@n?SOYR?(y5;CG20v9p;^R=f@EKtInkjrD6%G*M$Sc zBhpgY{6Au981%@Tq^9Q2ze)PpM~3egctV5z=_6FALMh-gVRb>##miV#yHt;QTV=~s=Rvz=vDYUF}YDg`t3gcJt=QVyAh0DB zpy!sWQR6TT*)N|vd>w65T1kDC=UPGyTZDW@Z{HjI`ttltR=$sEWgM|8^y}r69?&;E ztR=`+tt9=rrusT1^7iAglbLp@*?UB$Dw76*?Zx|on5!2`*tLlrpUluv2XCE<=1~u0 z$*v80-bD82hNF$X6SY~j1$|sL`kc#4rpq)xmX$DgLt)2vs~1Hc*kd+x|H*;z&T51X Ina$?^1AbGh#Q*>R literal 6660 zcmeHLe^k@g6@Lk#egmc^R3=4tmLORbiIm!4ai>Z^+tq4C;7cgRkPz)bftH5a##ovN zQfmR-Jj8XU_GneKMpNxH{o#*7gTlHN*w)5$)shs^P*Bot%^|ZS-@OR;eKF@$yZ?Rq zJ^JDPdiTD2@4JueWw{S=5JFsvBg(@6hQDSW{-)wD0e|-+^dF!%`!X4=2{7#VHI3}--z;?jn_P{*0C#G&^pX|psrU9^x$5e!Wa&v!K=IC%B z63`B`vJvl}rVEZUUot;2L1yGELQ=j>2KJ|RFU~9|DH;WQH4{;V>Q#FIJE$>vz~R1* z^^y2Q;+2hJWQmWL1OI!w#i*#LNCmi}8lh;rlgKx&s!ulttbCw%<<|<8rceNIy(Da} zpa^iJy-0lDTL{T3uMaWzFsaOQ%pTf?P?2WiMhI}VO+v|Jm6f3H-3?c@!-GdiJf3@u zm#8!int{G`x&j&3TR#MRfFItEvH)gyN9`%AsM>J=|vIlJjVkM<=RPDsp}u>0+dQWdMQvw2!qE?X=GZ9N*zpH0<+~ z0bZAfP=WI2^F@L4%Q7LKx~uW|OvsPt8@&p((k=jfxm!9i?XhM9;Co-LPd6KsB%i#Q zx7v&Jf3ogY|0B<1=+P`H*2d=NL$-7GhtgsXgS~v)y1dnDmmILGcaBcVcW40bwAW`E z)a-sD_1_7H_vdt4i2kZZZ)SUGRW9gXx3oUJ_tAyN0Y9lrmYCLiNPf)3^Arx}NuZ}< zefaowfFsZUPWySi80V+lVgdQ5eSgiA2^!h~pS&d?b_f+57&yBvAay?$4e}1>Enl3RC|5t1&TWa6+RU6Rt zEpv1lM=Yt|xVLgdO0|K+BRLKsWyp$vKPpa(oOH+ocum|V)R0X|;(snti%N_EBEO<3 z3kjt0B>$eRKe#~OhQuJhqMkz;jYi`C|C|3cK7{-@AwgfD*CGD?dqWZ6qV7H+H;p}y zfAtRL4Zp*lhyJba@}wvKo(25(y+5eyKSnilu`gGvM>GY(A~L zkpj3~wx4hMu7U9DW@wSJr)<|HnQQAvK0I49Q;3iM7yJKIGpX(OmhU;?j`ghoP z$hJBr2mKdFJZAnj={~nwMf5+oCy9F5WHN!i$o$X3{yXskdX6Xy>Hjly8gTf0TAse1GbG5!cG*LsUk8qERyx1pd=LUh2gBJnh}SeVbHH;xjtJ ze-ZZw5Ae_Z;CyAw9NB!pXMFQo8)R&JU+i(rFlfxA9%jzn7poug9R>cwc)ltv)o1`m zo_}P&p~TqUym>0iP`)QGI#bLzYiwVFAw)$XUP!~k8_C*N*PQs!+xWt=ZO5Z z-xL4NCFY3ai&|TOzE;*JDl9I&40z~SPK?~n=39t)W(nf*NxVV~-KjKq_5%MYZ+@pj zu#otF!Kdq#wth(H7e~5$h|AtDU$`{_O;%fYe?I)DhrfJgg27=HwzGtS_iTr2NrU2Guv`i1$*?MlD+ZU%C zKnUocnX;$Kol4Tbg3Pxwa6HKV80G`7(ZkMn7e`LIa~hIf2l-Lvs4LCR)_-7R%OQ=& zY-RS~*H0>QPfETR&wmCr3ZTun)X|dJc%CttYQpjzjCdE7jZh)?@VGzMLY;VirjeES z7pBu_Uj%09zsGdj1pZm`IKmh!L--$<#}y)Lh~O3(Pt0XldOyZE7=*rdAujg3P}UAk@-y znar=Lcpk(PND0IYwdMA;AJ{RSpF5jAio+h6jQ>q zK8)wtVtp5onPn9mDk|+aZur5Dg<8rK@OS_Z1eE^u3ynP##`@mscP(Q)Y1j{?mnZdGnjJ z#ekdeepKpWa-W3XYdD-1pjS02sFtp6`vG@VccgFdE+qFw!zw&KT^T0*Ez{ky6$o6kBRF?xd(tZ-YZ!A+Utp|EkoB}D;Tyo$4anH9LdC=zv`kUUP zHO1E+IRSV>Pe)~x?ENcsu^--(P33sWms!C0Nfong!swz3cBgI3+pTFRF*XqBr0`xVNixJv{ z>pK-|z$pn1ap diff --git a/Images/Classes/Spell_Nature_Drowsy.blp b/Images/Classes/Spell_Nature_Drowsy.blp index 355c6dd59f9c946ee479bf47b2e1d48b5ff08caf..420120bfe08dadc89e9b1d32a1ce5c5f7c438037 100644 GIT binary patch literal 6660 zcmai&3se(V8h|gcu7QZqqqKBum&7)^phdze3hk)`+wPHSS5Sr|G?D;aTi{p$OB;fi zfMCl*+wv%uP^BP<34s=gtqR1g_OUDM+DgRQ@~AaHA0XWtpeUKWGvU91?CCn^40FEx z|NZa(x_9odaZA*n-4H??uA7?}KbgDy9(*suw=cdQK&S`bH}HK6-}n3;E8Ok!#tPU5 z!iL58!64jstTc`Bw=b+%^$v5niQlR|ec-bCMtJ?E*PE94S;F6m5uVw;=5jbc&N2K* z;63NIt~rl?U!z;}QFC~5zW?Z^1wG+jK@PcKc9s=;1Kl3Oc0X8)3MMr$^>{c3hs{t_ z*TqH5laVvem#wE#m}koJExwFCu#X#B<{XdE`TVP_Tsy0eLLJPEWv`zcb^z~PB6^S+ z5B_`4#sPAs4$MU_a6FxVSF^teE59D0S^pi(IM3JvJ75>aMfE%8cQps|ya$T2&*+C8 z@hTtqgdM_8g=MY`zr$0^R@qT&v5QRxl?xj^ndfp_`~!3S9gJMgvhSF~&-)LK$r!!g zx=JS;;~r#)Dn{ktM7? zvYr0;7PbfTfWLNTB77mcLylH$X6I*}W&X^L1AcS6p3Uo>Q;XU8`W|-pGxDt?{!cc$ zvGX2>`2CB*Zgo!37irw;L7E(65vc@ z1lNa&XEq;{k&mRxtSpc}nj}Dx_yR8QN61uB;R7tW{EUpEOo6~zT`Lo)9g`&9@wbM> z65BV|LC%fF{;O(84!Ds_erUoYn=sGN#Q)97E4(cgK^`z(+V)HWg%bdLv@ca=3Rv9< zJTTUj!1GW_fz9^k{iUz&An_*RchD`WVim}b;RI6(DUmbrCg2O?uJJFz{^IaS{8Q&k z(tRjvJ?IaNh3E!Xx|4kPO>Rk`rW(BIKLmOif3>;OJlE8sS&V=cfUH9``Lk&GAR;dp7MeJ{0uOJ$D? zg8s8f{CV*&cBy|PuAfgxh!FHUEhXtTlZmk1vbL@@W%p)~S9h;WKoaMA$<#H3))*-b z$dC4oh-q^W8SmF0qRXW9BtMFwrNx0JNgU{hkMU&6LA@C`>_SO`#@Ol9pD-p{BxVvX zZ4FXWGt+6H?>Bj?l%hHNfgkJoG*qop?E`)^3C)Y&wf^@VwEE8&cx3%uGnS+mUY{cU zS8eeweKIMH_-o7xi2gA}sRH|p%Ue|Q2{UGR?xk?bS+Iy%&qV5fGFdY#g3%~)s2ItThk$I9|(qdOVzM|;W? z(|Rq)voEahr8Lg{Cf0!aol+C|a45ry*Fm4D_uTdWQ{4Rcdruk?+}#UvLI14jP;R`$ zM*3lIgNKYV@rZrP-mYX?C8t0?+!7$0oH3Jpn1`f>(N!K~e>3-ekSC2AA*`W~hq{{- z3K;J<_Ba2=nqp`DCpJe1+0|;0@9XDAHqNPc_|V_P9G;o%2a2KADm&s3f1a=mZ;Dqc zN&hT%S^t49^`|?%Q%8+PvcF9j+8g2}7QzoUG#4tR5@P>w+eH-)m*hv&x3*5`*SIaA?e&{bQo8UKC<+_LpX2Wwa_IBMI~aqCX3*K6~~$ z@S+F-_ZzvKtnYv2^0^$7h4`16U=p6>2sefBqReNQ#j zsE7HoyMn7Mo&Jr$?_6A)nO4i^13z}bbY?N{$qeANt!2B`3q5Lp&m38uo1KwH>e*5_ zB38u9$@*U@OX81p9=QtoilMIL^SPd6|9q%#vy76&lK1ao+`kwJC;1AvdD{YsK65@n ztLj_8-WFVMm;Rsk{*NhB9e8`)ADcnn)cR|axwEnxxU}l!Oucj}6L?LTEeEY~)@%GN zOQwg1(FpQi&yQufbF}Axx0SyA5>hHjK4h9DYPx2M)XSFtyeM8O)qwtl0da#&6}`Y; zcNx>uQfM1+dQk*7F5?^m4#4LheB2@V$ma{VUYZ=zf6RV2H~wc`-hUq*^W4tkIqUz# zhs$*97kSN|o@l!N_!mWpGf37`*lU;a8egv`{!g8~ncHJ_C;Qn07esmEQ`4m0J^D4Z z&z!lh9Q>sWtCFesK`rpf{ZEI|irzl}e|6~dO^O_v^hawE$JZ+;WF5%ws}8Q}RSkX& z{AKA=e7VYLuOyw_4+lZMD|LSSI3M%sf4HeR4!3_H=vNuHRpni?k$(QF$;V&`;w=EV zy8TeDO3R*M*`Mw+)p<7cHd0tEEla_aN-|8z;vi}{*D&LjYQbE=iRhO1` z(qKgl)C^jtY&=_sij?drLW;l@Ed3R{Pu=dJfM7ysnzk)sJ2z z{nlD^_<%>Jyawcz2TO})W~N9#pVGarwu_zbSM{NLv#FeqNq%;#U(V!sc#!pcrA{Ax zTeFYY%kJ8(&c1lD80`OC)c%@RWen+;$4tA`>a5*+K|VkJar&o3KCZv<6v*G&bIhM( z^d#@ErL~@0JesKikW(c^(VdSjnE}39u_U9hx0m$4v|==w_Glq&(s?GTyo`j)%erKq zNKg1w9dFzC$W6kh5B(_PjXL*}kOKF}@qPXE*6VlUFEBqQT=aARLd^Fqx_yqm zjkEeoHU8c^xJLmA&M4t{>-G2xZT7(N?{5SEkt;C{kiT$Ba$*H%B}uh-ki zerX=Nz^7@2+>B@*ZKmnVc)s|IZX4(~1Pi#^wte{}@J!$4WGcs#oHzDbj*BUYo%FlH z_9P$APWFqe_DB3}9Xtf%{f3T*uKMR*1@Kbc3U9fDG63`9BDhxT@Ca~uK0*TnEu`O{ z>o%qzJfZ&=$YXTJ#WjjK=QH}5X!^uKvL54yV#*?W`^kPi-L+G6+oMqmJ)Lh6FsvA_eP&-+u;oEG2-L!EDC=3cTNyxVXf*c9TNzppu?Hc=Wo4f-=Z zqSBDl`X7KF?-(ycMK5gyHYOK{mMiSU-g6fBNV$9)Ij^P2BE0`3kr01gh*;sR)fOFu z@%LBk3|Ls;od4YxpK6M7C*S9-rRxrOge)ZI_w1fus$}u8B%d)QJH^TuHDtfD;PYc) z{n4vnf0^z{-`F^%7WlQWjot+X1tq}Jrl$jhLSa3yyy0Z6{lhyufFEplyY4lG^Zz?9 z7yA@k`sad2Kz_L3i#$p(xd?b^eo4YB!}gzmUoo6Mz(sE=flt-#43^8KxIb>w=V)}> zEA_l@;1jQs^Mq*64PV4``0UkIe1ngdH{qqlSU!it>ObMHrk(PMIxBzi9JZC!fxeku zY(`&Xnj2i=?(NvMrZY&72e|V zE1*t?whIG<0pFj1A3FO|qCfPpy#cIh_e^XRd!+)O>H1wj1|=cq|Fgyy!v2waf}FRr z+W%AJHofyD&=0BRMn3&X^{c=?7bW@HELYh2+Uf7;i8`Uc&E5HaSyzqorFHI)>yKIe zr)$qR@^_QoaIO6YKP6F3-I+CLs(T@f$_jp**_)Va0!y;wqM1HI7Kpx5jF3knS# A7XSbN delta 2834 zcmeH|Z%k8H6u@sQWe-ZVY^y#ala?@sMmABa;^lkKId6lwjqOHM*sj2Qi9ORkVu0;IMq-m45?(M84e0*{P_RxKdC_wdlQVM zUI2h$WTNgx`Rk1N@){Kra%BxLhEd+6KHfFF5GXbx4VXD63HFTmZ^JC*}Gp zdr>DiWsrlmmH8_>dCy=6os4?o8@7;FiXHR_3gfFBPbkDe$F(WIWh5k_8Z-^uo)QP0 z`ZpyWB~CffLC@dk@7c@mImtmAP)~jLRO*SR)IrbjJLee0N8`eV{ubjzRlG5XMgY4% zhr{q9%=C=F3f)o($+9xPELzwqi7}X8yuoVWG1Qw`Fc1wMb@xtw5f}kG@vxx50ZKd9 z`YTX=NU|7EnoRK!7v-V*L!@UI&_trPukvTyEMGl7lrQ57FboTbKddt11z+}ez-{sk zfUlA-KS71?eMK#0T}(#G8UQJn z0j|P=I$PZc{&AUG|HwE19KUmY<w;lt*fPl5!ydI+yP@?Csg zMn(qVaF~z?Pwsn_FzkEDuypuKnsC^)-3wvxi4?-{5!(=bDum_VF9(Vh(y%ZYUje38 zD6Ka~@(H9_a<>$x_lik?gXQ<$uX3J!op8T<_C{t~&T+y=?HdxIYiAYVV}D%BE-r<9 zOW$Fi>Sr^qU9H4Gb1*_GlZAy5?mHu(8l$432$!^NtjSE#xCp1)V{4RM=eUmtTAX%% zuoCnv|A^=-vh~q#Ww?t7m)K_{YE~!d2(#IV3MxulXd??NO9ayJ@Nm8YmI?p@0s{C7 zj5hvxpdU{7me`*@Fn@QjQnZI~b-m&Ek?F}=!p4dv@tNycKH;aPb>xE=Jd~Y5c|Uq*Or7^x=7B0*Z3^=*tmXy^QvEcGfGXi2FTrEW%hg77z&)D*PD44}8D6|dRKRTQ-K z5;dG+4p6)%e$Y%7Zuga^cFGF&V`lN+;ciLR>G(-G_!&#rB?TDhzdgVagy&il(yrb) z8ASMOOGizRYjhLg$+gtdcQ4l#5{@m_(H7&6o*s{)Pry^t_cH{0Tlto0>wk}v?{Q&f zJwA3r@Uou<&T$4-IIFAss~KCfTtm;j5iO=AvD#;I7r|59!f^9l`L;BNH$fLHYDriY zVJasZoa!i#pnrDlX>vQUz1wLsycbv4lgEE6HkN*n#c1%iWg-{w^9^lTO-TL%obaeu -- 2.39.5 From 66931e18f96e7169c9535f8c1e1774710c08aa84 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 25 Jan 2022 20:41:32 +0100 Subject: [PATCH 126/268] fix castbar width/height being 0 on import --- Modules/Castbar.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 3bf8f65..38f0ff0 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -879,6 +879,12 @@ function Castbar:LegacySetPosition(castBar, unit, leftMargin, rightMargin) return Gladdy.db.newLayout end castBar:ClearAllPoints() + if Gladdy.db.castBarWidth <= 0 then + castBar:SetWidth(0.1) + end + if Gladdy.db.castBarHeight <= 0 then + castBar:SetHeight(0.1) + end local horizontalMargin = (Gladdy.db.highlightInset and 0 or Gladdy.db.highlightBorderSize) + Gladdy.db.padding if (Gladdy.db.castBarPos == "LEFT") then local anchor = Gladdy:GetAnchor(unit, "LEFT") -- 2.39.5 From 5ceedb53dea7fb5c2d04dac0d85a3ce718e57d4a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 25 Jan 2022 20:42:33 +0100 Subject: [PATCH 127/268] temp fix for legacy xOffset yOffset not present --- Frame.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Frame.lua b/Frame.lua index 84f5453..2713510 100644 --- a/Frame.lua +++ b/Frame.lua @@ -369,8 +369,8 @@ function Gladdy:SetPosition(frame, unit, xOffsetDB, yOffsetDB, newLayout, module --Gladdy:Debug("INFO", name, "old X/Y:", frame:GetCenter()) local xOffset, yOffset = frame:GetLeft(), frame:GetTop() if not xOffset or not yOffset then - xOffset = frame:GetCenter() - frame:GetWidth()/2 - yOffset = select(2, frame:GetCenter()) + frame:GetHeight()/2 + xOffset = frame:GetCenter()-- - frame:GetWidth()/2 + yOffset = select(2, frame:GetCenter())-- + frame:GetHeight()/2 end local x,y = button.healthBar:GetLeft(), button.healthBar:GetTop() local newXOffset = math_abs(x - xOffset) * (x > xOffset and -1 or 1) -- 2.39.5 From 0b512af2b7ba5f537e8f56bf27d89db6c53bb6af Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 27 Jan 2022 01:02:31 +0100 Subject: [PATCH 128/268] cooldowns first refactor: - no more lastCooldownSpell - unused icons are in iconCache for later reuse - only create as many icons as needed - no more weired indexing - cleanup duplicate code - testmode cleanup --- Modules/Cooldowns.lua | 569 ++++++++++++++++++++---------------------- 1 file changed, 269 insertions(+), 300 deletions(-) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 9c8b190..61ec21a 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -1,4 +1,4 @@ -local type, pairs, ipairs, ceil, tonumber, mod, tostring, upper, select = type, pairs, ipairs, ceil, tonumber, mod, tostring, string.upper, select +local type, pairs, ipairs, ceil, tonumber, mod, tostring, upper, select, tinsert, tremove = type, pairs, ipairs, ceil, tonumber, mod, tostring, string.upper, select, tinsert, tremove local GetTime = GetTime local CreateFrame = CreateFrame local RACE_ICON_TCOORDS = { @@ -74,6 +74,7 @@ local Cooldowns = Gladdy:NewModule("Cooldowns", nil, { function Cooldowns:Initialize() self.cooldownSpellIds = {} self.spellTextures = {} + self.iconCache = {} for _,spellTable in pairs(Gladdy:GetCooldownList()) do for spellId,_ in pairs(spellTable) do local spellName, _, texture = GetSpellInfo(spellId) @@ -91,6 +92,10 @@ function Cooldowns:Initialize() self:RegisterMessage("UNIT_DESTROYED") end +--------------------- +-- Frame +--------------------- + function Cooldowns:CreateFrame(unit) local button = Gladdy.buttons[unit] -- Cooldown frame @@ -99,42 +104,105 @@ function Cooldowns:CreateFrame(unit) spellCooldownFrame:SetMovable(true) spellCooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) spellCooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel) - for x = 1, 14 do - local icon = CreateFrame("Frame", nil, spellCooldownFrame) + spellCooldownFrame.icons = {} + button.spellCooldownFrame = spellCooldownFrame +end + +function Cooldowns:CreateIcon() -- returns iconFrame + local icon + if (#self.iconCache > 0) then + icon = tremove(self.iconCache, #self.iconCache) + else + icon = CreateFrame("Frame") icon:EnableMouse(false) - icon:SetFrameStrata(Gladdy.db.cooldownFrameStrata) - icon:SetFrameLevel(Gladdy.db.cooldownFrameLevel) + icon.texture = icon:CreateTexture(nil, "BACKGROUND") icon.texture:SetMask("Interface\\AddOns\\Gladdy\\Images\\mask") icon.texture:SetAllPoints(icon) icon.cooldown = CreateFrame("Cooldown", nil, icon, "CooldownFrameTemplate") icon.cooldown.noCooldownCount = true - - icon.cooldown:SetFrameStrata(Gladdy.db.cooldownFrameStrata) - icon.cooldown:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 1) icon.cooldown:SetReverse(false) icon.cooldown:SetHideCountdownNumbers(true) icon.cooldownFrame = CreateFrame("Frame", nil, icon) icon.cooldownFrame:ClearAllPoints() icon.cooldownFrame:SetAllPoints(icon) - icon.cooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) - icon.cooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 2) icon.border = icon.cooldownFrame:CreateTexture(nil, "OVERLAY") icon.border:SetAllPoints(icon) - icon.border:SetTexture(Gladdy.db.cooldownBorderStyle) - icon.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.cooldownBorderColor)) icon.cooldownFont = icon.cooldownFrame:CreateFontString(nil, "OVERLAY") - icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") - icon.cooldownFont:SetTextColor(Gladdy:SetColor(Gladdy.db.cooldownFontColor)) icon.cooldownFont:SetAllPoints(icon) - spellCooldownFrame["icon" .. x] = icon + self:UpdateIcon(icon) + end + return icon +end + +function Cooldowns:UpdateIcon(icon) + icon:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon:SetFrameLevel(Gladdy.db.cooldownFrameLevel) + icon.cooldown:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon.cooldown:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 1) + icon.cooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) + icon.cooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 2) + + icon:SetHeight(Gladdy.db.cooldownSize) + icon:SetWidth(Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor) + icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") + icon.cooldownFont:SetTextColor(Gladdy:SetColor(Gladdy.db.cooldownFontColor)) + + icon.cooldown:SetWidth(icon:GetWidth() - icon:GetWidth()/16) + icon.cooldown:SetHeight(icon:GetHeight() - icon:GetHeight()/16) + icon.cooldown:ClearAllPoints() + icon.cooldown:SetPoint("CENTER", icon, "CENTER") + icon.cooldown:SetAlpha(Gladdy.db.cooldownCooldownAlpha) + + icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), (icon:GetWidth()/2 - 1) * Gladdy.db.cooldownFontScale, "OUTLINE") + icon.cooldownFont:SetTextColor(Gladdy:SetColor(Gladdy.db.cooldownFontColor)) + + icon.border:SetTexture(Gladdy.db.cooldownBorderStyle) + icon.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.cooldownBorderColor)) +end + +function Cooldowns:IconsSetPoint(button) + for i,icon in ipairs(button.spellCooldownFrame.icons) do + icon:SetParent(button.spellCooldownFrame) + icon:ClearAllPoints() + if (Gladdy.db.cooldownXGrowDirection == "LEFT") then + if (i == 1) then + icon:SetPoint("LEFT", button.spellCooldownFrame, "LEFT", 0, 0) + elseif (mod(i-1,Gladdy.db.cooldownMaxIconsPerLine) == 0) then + if (Gladdy.db.cooldownYGrowDirection == "DOWN") then + icon:SetPoint("TOP", button.spellCooldownFrame.icons[i-Gladdy.db.cooldownMaxIconsPerLine], "BOTTOM", 0, -Gladdy.db.cooldownIconPadding) + else + icon:SetPoint("BOTTOM", button.spellCooldownFrame.icons[i-Gladdy.db.cooldownMaxIconsPerLine], "TOP", 0, Gladdy.db.cooldownIconPadding) + end + else + icon:SetPoint("RIGHT", button.spellCooldownFrame.icons[i-1], "LEFT", -Gladdy.db.cooldownIconPadding, 0) + end + end + if (Gladdy.db.cooldownXGrowDirection == "RIGHT") then + if (i == 1) then + icon:SetPoint("LEFT", button.spellCooldownFrame, "LEFT", 0, 0) + elseif (mod(i-1,Gladdy.db.cooldownMaxIconsPerLine) == 0) then + if (Gladdy.db.cooldownYGrowDirection == "DOWN") then + icon:SetPoint("TOP", button.spellCooldownFrame.icons[i-Gladdy.db.cooldownMaxIconsPerLine], "BOTTOM", 0, -Gladdy.db.cooldownIconPadding) + else + icon:SetPoint("BOTTOM", button.spellCooldownFrame.icons[i-Gladdy.db.cooldownMaxIconsPerLine], "TOP", 0, Gladdy.db.cooldownIconPadding) + end + else + icon:SetPoint("LEFT", button.spellCooldownFrame.icons[i-1], "RIGHT", Gladdy.db.cooldownIconPadding, 0) + end + end + end +end + +function Cooldowns:UpdateFrameOnce() + for _,icon in ipairs(self.iconCache) do + Cooldowns:UpdateIcon(icon) end - button.spellCooldownFrame = spellCooldownFrame end function Cooldowns:UpdateFrame(unit) @@ -145,7 +213,6 @@ function Cooldowns:UpdateFrame(unit) button.spellCooldownFrame:SetWidth(1) button.spellCooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) button.spellCooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel) - button.spellCooldownFrame:Show() Gladdy:SetPosition(button.spellCooldownFrame, unit, "cooldownXOffset", "cooldownYOffset", Cooldowns:LegacySetPosition(button, unit), Cooldowns) @@ -155,92 +222,65 @@ function Cooldowns:UpdateFrame(unit) Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor, Gladdy.db.cooldownSize, 0, 0, "cooldown") end -- Update each cooldown icon - local o = 1 - for j = 1, 14 do - local icon = button.spellCooldownFrame["icon" .. j] - - icon:SetFrameStrata(Gladdy.db.cooldownFrameStrata) - icon:SetFrameLevel(Gladdy.db.cooldownFrameLevel) - icon.cooldown:SetFrameStrata(Gladdy.db.cooldownFrameStrata) - icon.cooldown:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 1) - icon.cooldownFrame:SetFrameStrata(Gladdy.db.cooldownFrameStrata) - icon.cooldownFrame:SetFrameLevel(Gladdy.db.cooldownFrameLevel + 2) - - icon:SetHeight(Gladdy.db.cooldownSize) - icon:SetWidth(Gladdy.db.cooldownSize * Gladdy.db.cooldownWidthFactor) - icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), Gladdy.db.cooldownSize / 2 * Gladdy.db.cooldownFontScale, "OUTLINE") - icon.cooldownFont:SetTextColor(Gladdy:SetColor(Gladdy.db.cooldownFontColor)) - icon:ClearAllPoints() - if (Gladdy.db.cooldownXGrowDirection == "LEFT") then - if (j == 1) then - icon:SetPoint("LEFT", button.spellCooldownFrame, "LEFT", 0, 0) - elseif (mod(j-1,Gladdy.db.cooldownMaxIconsPerLine) == 0) then - if (Gladdy.db.cooldownYGrowDirection == "DOWN") then - icon:SetPoint("TOP", button.spellCooldownFrame["icon" .. o], "BOTTOM", 0, -Gladdy.db.cooldownIconPadding) - else - icon:SetPoint("BOTTOM", button.spellCooldownFrame["icon" .. o], "TOP", 0, Gladdy.db.cooldownIconPadding) - end - o = o + tonumber(Gladdy.db.cooldownMaxIconsPerLine) - else - icon:SetPoint("RIGHT", button.spellCooldownFrame["icon" .. j - 1], "LEFT", -Gladdy.db.cooldownIconPadding, 0) - end - end - if (Gladdy.db.cooldownXGrowDirection == "RIGHT") then - if (j == 1) then - icon:SetPoint("LEFT", button.spellCooldownFrame, "LEFT", 0, 0) - elseif (mod(j-1,Gladdy.db.cooldownMaxIconsPerLine) == 0) then - if (Gladdy.db.cooldownYGrowDirection == "DOWN") then - icon:SetPoint("TOP", button.spellCooldownFrame["icon" .. o], "BOTTOM", 0, -Gladdy.db.cooldownIconPadding) - else - icon:SetPoint("BOTTOM", button.spellCooldownFrame["icon" .. o], "TOP", 0, Gladdy.db.cooldownIconPadding) - end - o = o + tonumber(Gladdy.db.cooldownMaxIconsPerLine) - else - icon:SetPoint("LEFT", button.spellCooldownFrame["icon" .. j - 1], "RIGHT", Gladdy.db.cooldownIconPadding, 0) - end - end - - if (icon.active) then - icon.active = false - icon.cooldown:SetCooldown(GetTime(), 0) - icon.cooldownFont:SetText("") - icon:SetScript("OnUpdate", nil) - end - icon.spellId = nil - icon:SetAlpha(1) - icon.texture:SetTexture("Interface\\Icons\\Spell_Holy_PainSupression") - - icon.cooldown:SetWidth(icon:GetWidth() - icon:GetWidth()/16) - icon.cooldown:SetHeight(icon:GetHeight() - icon:GetHeight()/16) - icon.cooldown:ClearAllPoints() - icon.cooldown:SetPoint("CENTER", icon, "CENTER") - icon.cooldown:SetAlpha(Gladdy.db.cooldownCooldownAlpha) - - icon.cooldownFont:SetFont(Gladdy:SMFetch("font", "cooldownFont"), (icon:GetWidth()/2 - 1) * Gladdy.db.cooldownFontScale, "OUTLINE") - icon.cooldownFont:SetTextColor(Gladdy:SetColor(Gladdy.db.cooldownFontColor)) - - icon.border:SetTexture(Gladdy.db.cooldownBorderStyle) - icon.border:SetVertexColor(Gladdy:SetColor(Gladdy.db.cooldownBorderColor)) - icon:Hide() + for _,icon in pairs(button.spellCooldownFrame.icons) do + self:UpdateIcon(icon) end + self:IconsSetPoint(button) button.spellCooldownFrame:Show() else button.spellCooldownFrame:Hide() end - if (Gladdy.frame.testing) then - self:Test(unit) +end + +function Cooldowns:ResetUnit(unit) + local button = Gladdy.buttons[unit] + if not button then + return + end + for i=#button.spellCooldownFrame.icons,1,-1 do + self:ClearIcon(button, i) end end +function Cooldowns:ClearIcon(button, index, spellId, icon) + if index then + icon = tremove(button.spellCooldownFrame.icons, index) + else + for i=#button.spellCooldownFrame.icons,1,-1 do + if icon then + if button.spellCooldownFrame.icons[i] == icon then + icon = tremove(button.spellCooldownFrame.icons, index) + end + end + if not icon and spellId then + if button.spellCooldownFrame.icons[i].spellId == spellId then + icon = tremove(button.spellCooldownFrame.icons, index) + end + end + end + end + icon:ClearAllPoints() + icon:SetParent(nil) + icon:Hide() + icon.spellId = nil + icon.active = false + icon.cooldown:Hide() + icon.cooldownFont:SetText("") + icon:SetScript("OnUpdate", nil) + tinsert(self.iconCache, icon) +end + +--------------------- +-- Test +--------------------- + function Cooldowns:Test(unit) local button = Gladdy.buttons[unit] if Gladdy.db.cooldown then button.spellCooldownFrame:Show() - button.lastCooldownSpell = 1 self:UpdateTestCooldowns(unit) else button.spellCooldownFrame:Hide() - button.lastCooldownSpell = 1 self:UpdateTestCooldowns(unit) end @@ -250,11 +290,9 @@ function Cooldowns:UpdateTestCooldowns(unit) local button = Gladdy.buttons[unit] if (button.testSpec and button.testSpec == Gladdy.testData[unit].testSpec) then - button.lastCooldownSpell = 1 self:UpdateCooldowns(button) button.spec = nil self:DetectSpec(unit, button.testSpec) - button.test = true -- use class spells for spellId,_ in pairs(Gladdy:GetCooldownList()[button.class]) do @@ -267,6 +305,10 @@ function Cooldowns:UpdateTestCooldowns(unit) end end +--------------------- +-- Events +--------------------- + function Cooldowns:ENEMY_SPOTTED(unit) self:UpdateCooldowns(Gladdy.buttons[unit]) end @@ -275,18 +317,25 @@ function Cooldowns:SPEC_DETECTED(unit, spec) self:DetectSpec(unit, spec) end +function Cooldowns:UNIT_DESTROYED(unit) + +end + +--------------------- +-- Cooldown Start/Ready +--------------------- + function Cooldowns:CooldownStart(button, spellId, duration, start) -- starts timer frame if not duration or duration == nil or type(duration) ~= "number" then return end - for i = 1, button.lastCooldownSpell + 1 do - if (button.spellCooldownFrame["icon" .. i].spellId == spellId) then - local frame = button.spellCooldownFrame["icon" .. i] - frame.active = true - frame.timeLeft = start and start - GetTime() + duration or duration - if (not Gladdy.db.cooldownDisableCircle) then frame.cooldown:SetCooldown(start or GetTime(), duration) end - frame:SetScript("OnUpdate", function(self, elapsed) + for _,icon in pairs(button.spellCooldownFrame.icons) do + if (icon.spellId == spellId) then + icon.active = true + icon.timeLeft = start and start - GetTime() + duration or duration + if (not Gladdy.db.cooldownDisableCircle) then icon.cooldown:SetCooldown(start or GetTime(), duration) end + icon:SetScript("OnUpdate", function(self, elapsed) self.timeLeft = self.timeLeft - elapsed local timeLeft = ceil(self.timeLeft) if timeLeft >= 540 then @@ -298,26 +347,25 @@ function Cooldowns:CooldownStart(button, spellId, duration, start) end Gladdy:FormatTimer(self.cooldownFont, self.timeLeft, self.timeLeft < 0) if (self.timeLeft <= 0) then - Cooldowns:CooldownReady(button, spellId, frame) + Cooldowns:CooldownReady(button, spellId, icon) end if (self.timeLeft <= 0) then - Cooldowns:CooldownReady(button, spellId, frame) + Cooldowns:CooldownReady(button, spellId, icon) end end) + --C_VoiceChat.SpeakText(2, GetSpellInfo(spellId), 3, 4, 100) end end end function Cooldowns:CooldownReady(button, spellId, frame) if (frame == false) then - for i = 1, button.lastCooldownSpell do - frame = button.spellCooldownFrame["icon" .. i] - - if (frame.spellId == spellId) then - frame.active = false - frame.cooldown:Hide() - frame.cooldownFont:SetText("") - frame:SetScript("OnUpdate", nil) + for _,icon in pairs(button.spellCooldownFrame.icons) do + if (icon.spellId == spellId) then + icon.active = false + icon.cooldown:Hide() + icon.cooldownFont:SetText("") + icon:SetScript("OnUpdate", nil) end end else @@ -328,175 +376,6 @@ function Cooldowns:CooldownReady(button, spellId, frame) end end -local function notIn(spec, list) - for _,v in ipairs(list) do - if spec == v then - return false - end - end - return true -end - -function Cooldowns:DetectSpec(unit, spec) - - local button = Gladdy.buttons[unit] - if (not button or not spec or button.spec) then - return - end - if button.class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) - or button.class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) - or button.class == "ROGUE" and notIn(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) - or button.class == "WARLOCK" and notIn(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) - or button.class == "PRIEST" and notIn(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) - or button.class == "MAGE" and notIn(spec, {L["Frost"], L["Fire"], L["Arcane"]}) - or button.class == "DRUID" and notIn(spec, {L["Restoration"], L["Feral"], L["Balance"]}) - or button.class == "HUNTER" and notIn(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) - or button.class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then - return - end - - button.spec = spec - if not button.test then - Gladdy:SendMessage("UNIT_SPEC", unit, spec) - end - - - -- update cooldown tracker - --[[ - All of this could possibly be handled in a "once they're used, they show up"-manner - but I PERSONALLY prefer it this way. It also meant less work and makes spec-specific cooldowns easier - ]] - if (Gladdy.db.cooldown) then - local class = Gladdy.buttons[unit].class - for k, v in pairs(Gladdy:GetCooldownList()[class]) do - if Gladdy.db.cooldownCooldowns[tostring(k)] then - --if (self.db.cooldownList[k] ~= false and self.db.cooldownList[class] ~= false) then - if (type(v) == "table" and ((v.spec ~= nil and v.spec == spec) or (v.notSpec ~= nil and v.notSpec ~= spec))) then - local sharedCD = false - if (type(v) == "table" and v.sharedCD ~= nil and v.sharedCD.cd == nil) then - for spellId, _ in pairs(v.sharedCD) do - for i = 1, button.lastCooldownSpell do - local icon = button.spellCooldownFrame["icon" .. i] - if (icon.spellId == spellId) then - sharedCD = true - end - end - end - end - if sharedCD then - return - end - - local icon = button.spellCooldownFrame["icon" .. button.lastCooldownSpell] - icon:Show() - icon.texture:SetTexture(self.spellTextures[k]) - icon.spellId = k - button.spellCooldownFrame["icon" .. button.lastCooldownSpell] = icon - button.lastCooldownSpell = button.lastCooldownSpell + 1 - end - end - end - end - ---------------------- - --- RACE FUNCTIONALITY - ---------------------- - local race = Gladdy.buttons[unit].race - if Gladdy:GetCooldownList()[race] then - for k, v in pairs(Gladdy:GetCooldownList()[race]) do - if Gladdy.db.cooldownCooldowns[tostring(k)] then - --if (self.db.cooldownList[k] ~= false and self.db.cooldownList[class] ~= false) then - if (type(v) == "table" and ((v.spec ~= nil and v.spec == spec) or (v.notSpec ~= nil and v.notSpec ~= spec))) then - local sharedCD = false - if (type(v) == "table" and v.sharedCD ~= nil and v.sharedCD.cd == nil) then - for spellId, _ in pairs(v.sharedCD) do - for i = 1, button.lastCooldownSpell do - local icon = button.spellCooldownFrame["icon" .. i] - if (icon.spellId == spellId) then - sharedCD = true - end - end - end - end - if sharedCD then - return - end - - local icon = button.spellCooldownFrame["icon" .. button.lastCooldownSpell] - icon:Show() - icon.texture:SetTexture(self.spellTextures[k]) - icon.spellId = k - button.spellCooldownFrame["icon" .. button.lastCooldownSpell] = icon - button.lastCooldownSpell = button.lastCooldownSpell + 1 - end - end - end - end -end - -function Cooldowns:ResetUnit(unit) - Gladdy.buttons[unit].lastCooldownSpell = nil - Gladdy.buttons[unit].test = nil -end - -function Cooldowns:UNIT_DESTROYED(unit) - -end - -function Cooldowns:UpdateCooldowns(button) - local class = button.class - local race = button.race - if ( not button.lastCooldownSpell) then - button.lastCooldownSpell = 1 - end - - if (Gladdy.db.cooldown) then - for k, v in pairs(Gladdy:GetCooldownList()[class]) do - if Gladdy.db.cooldownCooldowns[tostring(k)] then - if (type(v) ~= "table" or (type(v) == "table" and v.spec == nil and v.notSpec == nil)) then - -- see if we have shared cooldowns without a cooldown defined - -- e.g. hunter traps have shared cooldowns, so only display one trap instead all of them - local sharedCD = false - if (type(v) == "table" and v.sharedCD ~= nil and v.sharedCD.cd == nil) then - for spellId, _ in pairs(v.sharedCD) do - for i = 1, button.lastCooldownSpell do - local icon = button.spellCooldownFrame["icon" .. i] - if (icon.spellId == spellId) then - sharedCD = true - end - end - end - end - - if (not sharedCD) then - local icon = button.spellCooldownFrame["icon" .. button.lastCooldownSpell] - icon:Show() - icon.spellId = k - icon.texture:SetTexture(self.spellTextures[k]) - button.spellCooldownFrame["icon" .. button.lastCooldownSpell] = icon - button.lastCooldownSpell = button.lastCooldownSpell + 1 - end - end - end - end - ---- - -- RACE FUNCTIONALITY - ---- - - for k, v in pairs(Gladdy:GetCooldownList()[race]) do - if Gladdy.db.cooldownCooldowns[tostring(k)] then - if (type(v) ~= "table" or (type(v) == "table" and v.spec == nil and v.notSpec == nil)) then - local icon = button.spellCooldownFrame["icon" .. button.lastCooldownSpell] - icon:Show() - icon.spellId = k - icon.texture:SetTexture(self.spellTextures[k]) - button.spellCooldownFrame["icon" .. button.lastCooldownSpell] = icon - button.lastCooldownSpell = button.lastCooldownSpell + 1 - end - end - end - end -end - function Cooldowns:CooldownUsed(unit, unitClass, spellId, expirationTimeInSeconds) local button = Gladdy.buttons[unit] if not button then @@ -535,8 +414,7 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId, expirationTimeInSecond for spellID,_ in pairs(cooldown.sharedCD) do if (spellID ~= "cd") then local skip = false - for i = 1, button.lastCooldownSpell do - local icon = button.spellCooldownFrame["icon" .. i] + for _,icon in pairs(button.spellCooldownFrame.icons) do if (icon.spellId == spellID and icon.active and icon.timeLeft > sharedCD) then skip = true break @@ -566,6 +444,119 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId, expirationTimeInSecond end ]] end +--------------------- +-- Detect Spec +--------------------- + +local function notIn(spec, list) + for _,v in ipairs(list) do + if spec == v then + return false + end + end + return true +end + +function Cooldowns:DetectSpec(unit, spec) + local button = Gladdy.buttons[unit] + if (not button or not spec or button.spec) then + return + end + if button.class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) + or button.class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) + or button.class == "ROGUE" and notIn(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) + or button.class == "WARLOCK" and notIn(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) + or button.class == "PRIEST" and notIn(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) + or button.class == "MAGE" and notIn(spec, {L["Frost"], L["Fire"], L["Arcane"]}) + or button.class == "DRUID" and notIn(spec, {L["Restoration"], L["Feral"], L["Balance"]}) + or button.class == "HUNTER" and notIn(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) + or button.class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then + return + end + if not button.spec then + button.spec = spec + Gladdy:SendMessage("UNIT_SPEC", unit, spec) + Cooldowns:UpdateCooldowns(button) + end +end + +function Cooldowns:AddCooldown(spellID, value, button) + -- see if we have shared cooldowns without a cooldown defined + -- e.g. hunter traps have shared cooldowns, so only display one trap instead all of them + local sharedCD = false + if (type(value) == "table" and value.sharedCD ~= nil and value.sharedCD.cd == nil) then + for spellId, _ in pairs(value.sharedCD) do + for _,icon in pairs(button.spellCooldownFrame.icons) do + if (icon.spellId == spellId) then + sharedCD = true + end + end + end + end + for _,icon in pairs(button.spellCooldownFrame.icons) do + if (icon and icon.spellId == spellID) then + sharedCD = true + end + end + if (not sharedCD) then + local icon = self:CreateIcon() + icon:Show() + icon.spellId = spellID + icon.texture:SetTexture(self.spellTextures[spellID]) + tinsert(button.spellCooldownFrame.icons, icon) + self:IconsSetPoint(button) + Gladdy:Debug("Cooldowns:AddCooldown", button.unit, GetSpellInfo(spellID)) + end +end + +function Cooldowns:UpdateCooldowns(button) + local class = button.class + local race = button.race + local spec = button.spec + if not class or not race then + return + end + + if spec then + if class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) + or class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) + or class == "ROGUE" and notIn(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) + or class == "WARLOCK" and notIn(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) + or class == "PRIEST" and notIn(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) + or class == "MAGE" and notIn(spec, {L["Frost"], L["Fire"], L["Arcane"]}) + or class == "DRUID" and notIn(spec, {L["Restoration"], L["Feral"], L["Balance"]}) + or class == "HUNTER" and notIn(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) + or class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then + return + end + end + + for k, v in pairs(Gladdy:GetCooldownList()[class]) do + if Gladdy.db.cooldownCooldowns[tostring(k)] then + if (type(v) ~= "table" or (type(v) == "table" and v.spec == nil)) then + Cooldowns:AddCooldown(k, v, button) + end + if (type(v) == "table" and v.spec ~= nil and v.spec == spec) then + Cooldowns:AddCooldown(k, v, button) + end + end + end + for k, v in pairs(Gladdy:GetCooldownList()[button.race]) do + if Gladdy.db.cooldownCooldowns[tostring(k)] then + if (type(v) ~= "table" or (type(v) == "table" and v.spec == nil)) then + Cooldowns:AddCooldown(k, v, button) + end + if (type(v) == "table" and v.spec ~= nil and v.spec == spec) then + Cooldowns:AddCooldown(k, v, button) + end + end + end +end + +--------------------- +-- Options +--------------------- + function Cooldowns:GetOptions() return { headerCooldown = { @@ -900,28 +891,6 @@ function Cooldowns:GetCooldownOptions() return group end -function Gladdy:UpdateTestCooldowns(i) - local unit = "arena" .. i - local button = Gladdy.buttons[unit] - - if (button.testSpec and button.testSpec == Gladdy.testData[unit].testSpec) then - button.lastCooldownSpell = 1 - Cooldowns:UpdateCooldowns(button) - button.spec = nil - Cooldowns:DetectSpec(unit, button.testSpec) - - -- use class spells - for spellID,_ in pairs(Gladdy:GetCooldownList()[button.class]) do - --k is spellId - Cooldowns:CooldownUsed(unit, button.class, spellID) - end - -- use race spells - for spellID,_ in pairs(Gladdy:GetCooldownList()[button.race]) do - Cooldowns:CooldownUsed(unit, button.race, spellID) - end - end -end - --------------------------- -- LAGACY HANDLER -- 2.39.5 From 23729f5960e7b3c45c5278d0ec037895d534300e Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 27 Jan 2022 01:30:28 +0100 Subject: [PATCH 129/268] move DetectSpec to EventListener --- EventListener.lua | 64 +++++++++++++++++++++++++-------- Modules/Cooldowns.lua | 84 ++++++++++--------------------------------- 2 files changed, 67 insertions(+), 81 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 4d97d35..c7f2172 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -1,4 +1,4 @@ -local select, string_gsub, tostring, pairs = select, string.gsub, tostring, pairs +local select, string_gsub, tostring, pairs, ipairs = select, string.gsub, tostring, pairs, ipairs local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo local AURA_TYPE_DEBUFF = AURA_TYPE_DEBUFF @@ -11,10 +11,11 @@ local FindAuraByName = AuraUtil.FindAuraByName local GetTime = GetTime local Gladdy = LibStub("Gladdy") +local L = Gladdy.L local Cooldowns = Gladdy.modules["Cooldowns"] local Diminishings = Gladdy.modules["Diminishings"] -local EventListener = Gladdy:NewModule("EventListener", nil, { +local EventListener = Gladdy:NewModule("EventListener", 100, { test = true, }) @@ -51,12 +52,6 @@ function EventListener:Reset() self:SetScript("OnEvent", nil) end -function Gladdy:DetectSpec(unit, spec) - if spec then - self.modules["Cooldowns"]:DetectSpec(unit, spec) - end -end - function Gladdy:SpotEnemy(unit, auraScan) local button = self.buttons[unit] if not unit or not button then @@ -92,7 +87,7 @@ function Gladdy:SpotEnemy(unit, auraScan) if Gladdy.specBuffs[spellName] then -- Check for auras that detect a spec local unitPet = string_gsub(unit, "%d$", "pet%1") if UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster) then - Gladdy:DetectSpec(unit, Gladdy.specBuffs[spellName]) + EventListener:DetectSpec(unit, Gladdy.specBuffs[spellName]) end end end @@ -144,7 +139,7 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() unitClass = Gladdy.buttons[srcUnit].race end Cooldowns:CooldownUsed(srcUnit, unitClass, spellId) - Gladdy:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) + self:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) end end @@ -157,7 +152,7 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() Gladdy:SpotEnemy(srcUnit, true) end if not Gladdy.buttons[srcUnit].spec then - Gladdy:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) + self:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) end end end @@ -255,7 +250,7 @@ function EventListener:UNIT_AURA(unit) if not button.spec and Gladdy.specBuffs[spellName] then local unitPet = string_gsub(unit, "%d$", "pet%1") if unitCaster and (UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster)) then - Gladdy:DetectSpec(unit, Gladdy.specBuffs[spellName]) + self:DetectSpec(unit, Gladdy.specBuffs[spellName]) end end if Gladdy.exceptionNames[spellID] then @@ -271,7 +266,7 @@ function EventListener:UNIT_SPELLCAST_START(unit) if Gladdy.buttons[unit] then local spellName = UnitCastingInfo(unit) if Gladdy.specSpells[spellName] and not Gladdy.buttons[unit].spec then - Gladdy:DetectSpec(unit, Gladdy.specSpells[spellName]) + self:DetectSpec(unit, Gladdy.specSpells[spellName]) end end end @@ -280,7 +275,7 @@ function EventListener:UNIT_SPELLCAST_CHANNEL_START(unit) if Gladdy.buttons[unit] then local spellName = UnitChannelInfo(unit) if Gladdy.specSpells[spellName] and not Gladdy.buttons[unit].spec then - Gladdy:DetectSpec(unit, Gladdy.specSpells[spellName]) + self:DetectSpec(unit, Gladdy.specSpells[spellName]) end end end @@ -289,7 +284,46 @@ function EventListener:UNIT_SPELLCAST_SUCCEEDED(unit) if Gladdy.buttons[unit] then local spellName = UnitCastingInfo(unit) if Gladdy.specSpells[spellName] and not Gladdy.buttons[unit].spec then - Gladdy:DetectSpec(unit, Gladdy.specSpells[spellName]) + self:DetectSpec(unit, Gladdy.specSpells[spellName]) end end end + +local function notIn(spec, list) + for _,v in ipairs(list) do + if spec == v then + return false + end + end + return true +end + +function EventListener:DetectSpec(unit, spec) + local button = Gladdy.buttons[unit] + if (not button or not spec or button.spec) then + return + end + if button.class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) + or button.class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) + or button.class == "ROGUE" and notIn(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) + or button.class == "WARLOCK" and notIn(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) + or button.class == "PRIEST" and notIn(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) + or button.class == "MAGE" and notIn(spec, {L["Frost"], L["Fire"], L["Arcane"]}) + or button.class == "DRUID" and notIn(spec, {L["Restoration"], L["Feral"], L["Balance"]}) + or button.class == "HUNTER" and notIn(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) + or button.class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then + return + end + if not button.spec then + button.spec = spec + Gladdy:SendMessage("UNIT_SPEC", unit, spec) + end +end + +function EventListener:Test(unit) + local button = Gladdy.buttons[unit] + if (Gladdy.testData[unit].testSpec) then + button.spec = nil + self:DetectSpec(unit, button.testSpec) + end +end diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 61ec21a..64ccdfb 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -278,30 +278,22 @@ function Cooldowns:Test(unit) local button = Gladdy.buttons[unit] if Gladdy.db.cooldown then button.spellCooldownFrame:Show() - self:UpdateTestCooldowns(unit) else button.spellCooldownFrame:Hide() - self:UpdateTestCooldowns(unit) end - + self:UpdateTestCooldowns(unit) end function Cooldowns:UpdateTestCooldowns(unit) local button = Gladdy.buttons[unit] - - if (button.testSpec and button.testSpec == Gladdy.testData[unit].testSpec) then - self:UpdateCooldowns(button) - button.spec = nil - self:DetectSpec(unit, button.testSpec) - - -- use class spells - for spellId,_ in pairs(Gladdy:GetCooldownList()[button.class]) do - self:CooldownUsed(unit, button.class, spellId) - end - -- use race spells - for spellId,_ in pairs(Gladdy:GetCooldownList()[button.race]) do - self:CooldownUsed(unit, button.race, spellId) - end + self:UpdateCooldowns(button) + -- use class spells + for spellId,_ in pairs(Gladdy:GetCooldownList()[button.class]) do + self:CooldownUsed(unit, button.class, spellId) + end + -- use race spells + for spellId,_ in pairs(Gladdy:GetCooldownList()[button.race]) do + self:CooldownUsed(unit, button.race, spellId) end end @@ -310,11 +302,17 @@ end --------------------- function Cooldowns:ENEMY_SPOTTED(unit) + if (not Gladdy.buttons[unit]) then + return + end self:UpdateCooldowns(Gladdy.buttons[unit]) end -function Cooldowns:SPEC_DETECTED(unit, spec) - self:DetectSpec(unit, spec) +function Cooldowns:SPEC_DETECTED(unit) + if (not Gladdy.buttons[unit]) then + return + end + self:UpdateCooldowns(Gladdy.buttons[unit]) end function Cooldowns:UNIT_DESTROYED(unit) @@ -445,41 +443,9 @@ function Cooldowns:CooldownUsed(unit, unitClass, spellId, expirationTimeInSecond end --------------------- --- Detect Spec +-- Update Cooldowns --------------------- -local function notIn(spec, list) - for _,v in ipairs(list) do - if spec == v then - return false - end - end - return true -end - -function Cooldowns:DetectSpec(unit, spec) - local button = Gladdy.buttons[unit] - if (not button or not spec or button.spec) then - return - end - if button.class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) - or button.class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) - or button.class == "ROGUE" and notIn(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) - or button.class == "WARLOCK" and notIn(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) - or button.class == "PRIEST" and notIn(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) - or button.class == "MAGE" and notIn(spec, {L["Frost"], L["Fire"], L["Arcane"]}) - or button.class == "DRUID" and notIn(spec, {L["Restoration"], L["Feral"], L["Balance"]}) - or button.class == "HUNTER" and notIn(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) - or button.class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then - return - end - if not button.spec then - button.spec = spec - Gladdy:SendMessage("UNIT_SPEC", unit, spec) - Cooldowns:UpdateCooldowns(button) - end -end - function Cooldowns:AddCooldown(spellID, value, button) -- see if we have shared cooldowns without a cooldown defined -- e.g. hunter traps have shared cooldowns, so only display one trap instead all of them @@ -517,20 +483,6 @@ function Cooldowns:UpdateCooldowns(button) return end - if spec then - if class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) - or class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) - or class == "ROGUE" and notIn(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) - or class == "WARLOCK" and notIn(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) - or class == "PRIEST" and notIn(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) - or class == "MAGE" and notIn(spec, {L["Frost"], L["Fire"], L["Arcane"]}) - or class == "DRUID" and notIn(spec, {L["Restoration"], L["Feral"], L["Balance"]}) - or class == "HUNTER" and notIn(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) - or class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then - return - end - end - for k, v in pairs(Gladdy:GetCooldownList()[class]) do if Gladdy.db.cooldownCooldowns[tostring(k)] then if (type(v) ~= "table" or (type(v) == "table" and v.spec == nil)) then -- 2.39.5 From ce3812d2341e6d74ed13ae94c738bf98385ee6a9 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 27 Jan 2022 01:51:02 +0100 Subject: [PATCH 130/268] improve warrior icon --- Images/Classes/INV_Sword_27.blp | Bin 6660 -> 6660 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Images/Classes/INV_Sword_27.blp b/Images/Classes/INV_Sword_27.blp index eea39b6e845a50ec28eeb5b8da7591bcee74aac2..c9249b6fa650a63e3c04ab7e646c669d247b2b95 100644 GIT binary patch delta 1943 zcmah}TTE0}6y5UxE(`<1d!|sG8yw5<2sV|3X&VZ}+Jb3fTC-EpAvI+idK5X?gjpr&<$!e3pdm~-hF7UI!+(LPmL>|-JYu$=v446}YRrb#cl zq>3%M_m}KILun)g`2dx2maEV563c9jmz^54a-N%9jps&2f>F9UIoaIf&sL6m5+2M} zD3Uwh%lVb9+%YX1h&dimgifksH^V8f%)He6NK3ip_hm-oh^~&>nuxo|@&ihqZMcm0 z?ljS(X?297@pJ^6%{$dPe_+aCy^eXoB&a9#Pq&rpA=g6i6abqvaC?IBc^~Mz#qiD$ zSTb{1RLJ@L!v2{3@J_jHClMTERFB`Hy z$SOpmn)O@WU~=22d=_|c5cS=ZBEKA8hKl*&zGfV~jQ?~lh@BakpE15zII8oa9Bs0O z_O)xp*crg5nz95*lA@+$%Xqdo6C{;74|QvckWahDVH^}e0#M2r8wXVsckzT$cXFIA z^OxalSsyAhV)`lsDYGt=F1!{nY&`}*3~b{Dq)rhmfi*QsKMnq^8C~!jN;u={FvaCd z5?1<1on|N~-@l*FooUVzYDl0q|8#WS&wwWUzw#HMf&^*`m{*$tH446PU>Pn-t`Y&Y z1~v|V}Nzl0D^_(hQ@5< zoi8)UFxnRxwPr2d4_>zdY$HDkSQx+yWaLaUfb01CJ5XC>db**ZBg`4(e!{nHnbj9d zSf%E;bTXw%!cf-_Scm&D9&Q3CtNjI|$S8Z*xM(p|SHH89lMkaWqV^iwt@Uu?#F0Zh zd-SHCNs`=YXkD~jczETAm=@)hP#XajG4VOOeb+9uF2*j zT|XRt5#Z>J_jcUJ>~oWi=`T=~zkNFw=!-=Fx7)>W>Fkz7Y|(#$Gw>wMl}=u@I`T^L zc|8~1F{VZ~zLF)(-MxE@XUARNnvmJ_swJTKp&>Q(g+=<+D;81LhZp@_bNL4zKp&eT zYX4KT({EP@*nK*cz62VhF2BIbm9+&jTEKfd2d&n?Uf!YqgA11pCHZBNkJPTQ=Y8Mj z+*-fAetW}D@lCISdrwMk?fUFtKoKhpAojRUlr9H=#GQ?cp)Wkwe%+76_QnGf8DE*| zv5?Uc{gl#a^>UhkIfEDgF^SvU`i*hInU;)-;G`%gtP(vI^{9mK_z&*PAX-o0xE^rA zE25}?{bPay34kX=5t&~T^%^|0Suh5a{j`wB(*{oFVX9cGt;}kbk^E>!iHbOu7Yfzx z=0sDjoD=#*zB_jqHj1MR;JtqZWtAkvmuLsa1x3THK${5jFM5CTA@fOhg?ZwgfazXb z#QAVh9BP%v-l4n8D%oC}pqanO3TSVHK|G1C{_5ThybG8w;Eg4n21^I2p4G8k@u7~& zgN1xnSA8Lv>Ve~%Z~wvh?mkA3MHlIW0bGIrB<4~B)HnHYCoh+G zX72S^;BCp4Tu5(6+HGMxG?`0zlTJ7sSC)wSVZQ#h`qOszm-4ADYxiU%S*PZ39NwuM zAFYJct?|)BEdVr*)Y!)Eh6TYg{w?DUe%@9HyL<{^jBl_t^;#Wg1i;AR%3cw`oKdvY zO?d~KaC4q^!{W zdt>WJcdIHo-)KbcI^)R1#k}s7Y0Vmtg8}W*RF0G+fRj>Qnhnetu*q*(T*ko$&b3L; zm0_?3TC<*mANzmAeKlFuL8UXF zbcceLxSyM{!Jin=F2gB6NC{q+>fN6qGs?W9>zxFdSy1lPDVCJi3-x$y?On|AnFCw= z9S+AZ?AkOS(!&#>Dl5L!_|4R-!Em9)z4r@vpn)}S*~6V)^Obh zE_-}^ye)k_=TbDdE060H3D$l{W)lKWAO@)5|9M`Ko`0_xTUd?5jH!}J*$CgRc8E@<$1-99gjF!p#1V_O<=Ff({7-%>V!Z -- 2.39.5 From d8391b0f66badbe323a0a2d340c29ff80ccc0d72 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 27 Jan 2022 14:00:59 +0100 Subject: [PATCH 131/268] Anouncements + Gladdy RegisterMessages --- EventListener.lua | 4 ++-- Gladdy.lua | 12 ++++++++++ Modules/Announcements.lua | 50 +++++++++++++++++++++++---------------- Modules/Auras.lua | 2 +- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index c7f2172..0086627 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -15,7 +15,7 @@ local L = Gladdy.L local Cooldowns = Gladdy.modules["Cooldowns"] local Diminishings = Gladdy.modules["Diminishings"] -local EventListener = Gladdy:NewModule("EventListener", 100, { +local EventListener = Gladdy:NewModule("EventListener", 10, { test = true, }) @@ -214,6 +214,7 @@ Gladdy.exceptionNames = { -- TODO MOVE ME TO CLASSBUFFS LIB Gladdy.cooldownBuffs = { [GetSpellInfo(6346)] = { cd = 180, spellId = 6346 }, -- Fear Ward + -- TODO sprint, shadowstep racials = { [GetSpellInfo(20600)] = { cd = 180, spellId = 20600 }, -- Perception } @@ -257,7 +258,6 @@ function EventListener:UNIT_AURA(unit) spellName = Gladdy.exceptionNames[spellID] end Gladdy:SendMessage("AURA_GAIN", unit, auraType, spellID, spellName, texture, duration, expirationTime, count, debuffType, i) - Gladdy:Call("Announcements", "CheckDrink", unit, spellName) end end end diff --git a/Gladdy.lua b/Gladdy.lua index 32fb1e3..63c5d17 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -187,6 +187,12 @@ function Gladdy:NewModule(name, priority, defaults) module.defaults = defaults or {} module.messages = {} + module.RegisterMessages = function(self, ...) + for _,message in pairs({...}) do + self.messages[message] = message + end + end + module.RegisterMessage = function(self, message, func) self.messages[message] = func or message end @@ -195,6 +201,12 @@ function Gladdy:NewModule(name, priority, defaults) self.messages[message] = nil end + module.UnregisterMessages = function(self, ...) + for _,message in pairs({...}) do + self.messages[message] = nil + end + end + module.UnregisterAllMessages = function(self) for msg,_ in pairs(self.messages) do self.messages[msg] = nil diff --git a/Modules/Announcements.lua b/Modules/Announcements.lua index 27de5f1..5cb0066 100644 --- a/Modules/Announcements.lua +++ b/Modules/Announcements.lua @@ -16,7 +16,7 @@ local UnitName = UnitName local Gladdy = LibStub("Gladdy") local L = Gladdy.L -local Announcements = Gladdy:NewModule("Announcements", nil, { +local Announcements = Gladdy:NewModule("Announcements", 101, { announcements = { drinks = true, resurrections = true, @@ -42,18 +42,20 @@ function Announcements:Initialize() [GetSpellInfo(20777)] = true, } - self:RegisterMessage("CAST_START") - self:RegisterMessage("ENEMY_SPOTTED") - self:RegisterMessage("UNIT_SPEC") - self:RegisterMessage("UNIT_HEALTH") - self:RegisterMessage("TRINKET_USED") - self:RegisterMessage("TRINKET_READY") - self:RegisterMessage("SHADOWSIGHT") - self:RegisterMessage("SPELL_INTERRUPT") + self:RegisterMessage("JOINED_ARENA") end function Announcements:Reset() - self:UnregisterAllMessages() + self:UnregisterMessages( + "CAST_START", + "ENEMY_SPOTTED", + "UNIT_SPEC", + "AURA_GAIN", + "UNIT_HEALTH", + "TRINKET_USED", + "TRINKET_READY", + "SHADOWSIGHT", + "SPELL_INTERRUPT") self.enemy = {} self.throttled = {} end @@ -63,17 +65,25 @@ function Announcements:Test(unit) if (not button) then return end - - if (unit == "arena1") then - self:UNIT_SPEC(unit, button.testSpec) - elseif (unit == "arena2") then - self:CheckDrink(unit, self.DRINK_AURA) - elseif (unit == "arena3") then - self:UNIT_HEALTH(unit, button.health, button.healthMax) - self:ENEMY_SPOTTED(unit) + self:JOINED_ARENA() + if unit == "arena1" then + self:AURA_GAIN(unit, nil, nil, self.DRINK_AURA) end end +function Announcements:JOINED_ARENA() + self:RegisterMessages( + "CAST_START", + "ENEMY_SPOTTED", + "UNIT_SPEC", + "AURA_GAIN", + "UNIT_HEALTH", + "TRINKET_USED", + "TRINKET_READY", + "SHADOWSIGHT", + "SPELL_INTERRUPT") +end + function Announcements:CAST_START(unit, spell) local button = Gladdy.buttons[unit] if (not button or not Gladdy.db.announcements.resurrections) then @@ -149,13 +159,13 @@ function Announcements:SPELL_INTERRUPT(destUnit,spellID,spellName,spellSchool,ex self:Send(L["INTERRUPTED: %s (%s)"]:format(extraSpellName, button.name or ""), nil, RAID_CLASS_COLORS[button.class]) end -function Announcements:CheckDrink(unit, aura) +function Announcements:AURA_GAIN(unit, auraType, spellID, spellName) local button = Gladdy.buttons[unit] if (not button or not Gladdy.db.announcements.drinks) then return end - if (aura == self.DRINK_AURA) then + if (spellName == self.DRINK_AURA) then self:Send(L["DRINKING: %s (%s)"]:format(button.name, button.classLoc), 3, RAID_CLASS_COLORS[button.class]) end end diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 7d903e4..5d33667 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -472,7 +472,7 @@ function Auras:Test(unit) local extraSpellSchool = spellSchools[rand(1, #spellSchools)] spellid = tonumber(enabledInterrupts[rand(1, #enabledInterrupts)]) spellName = select(1, GetSpellInfo(spellid)) - self:SPELL_INTERRUPT(unit,spellid, spellName, "physical", spellid, spellName, extraSpellSchool) + Gladdy:SendMessage("SPELL_INTERRUPT", unit,spellid, spellName, "physical", spellid, spellName, extraSpellSchool) end end end -- 2.39.5 From 41b299e0b1c118846f6ec633a89cd6768335cbcf Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 5 Feb 2022 04:16:44 +0100 Subject: [PATCH 132/268] initial TotemPulse --- Modules/TotemPulse.lua | 476 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 476 insertions(+) create mode 100644 Modules/TotemPulse.lua diff --git a/Modules/TotemPulse.lua b/Modules/TotemPulse.lua new file mode 100644 index 0000000..a2a49a9 --- /dev/null +++ b/Modules/TotemPulse.lua @@ -0,0 +1,476 @@ +local C_NamePlate = C_NamePlate +local Gladdy = LibStub("Gladdy") +local L = Gladdy.L +local tremove, tinsert = tremove, tinsert +local GetSpellInfo, CreateFrame = GetSpellInfo, CreateFrame +local GetTime, GetPlayerInfoByGUID, UnitIsEnemy, UnitGUID = GetTime, GetPlayerInfoByGUID, UnitIsEnemy, UnitGUID +local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo + +local cooldowns = { + [2484] = 3, --Earthbind + [8143] = 4, -- Tremor + [8166] = 4, -- Poison Cleansing + [8170] = 4, -- Disease Cleansing + [1535] = { cd = 4, once = true }, -- Fire Nova 1 + [8498] = { cd = 4, once = true }, -- Fire Nova 2 + [8499] = { cd = 4, once = true }, -- Fire Nova 3 + [11314] = { cd = 4, once = true }, -- Fire Nova 4 + [11315] = { cd = 4, once = true }, -- Fire Nova 5 + [25546] = { cd = 4, once = true }, -- Fire Nova 6 + [25547] = { cd = 4, once = true }, -- Fire Nova 7 + [8190] = 2, -- Magma 1 + [10585] = 2, -- Magma 2 + [10586] = 2, -- Magma 3 + [10587] = 2, -- Magma 4 + [25552] = 2, -- Magma 5 + [5394] = 2, -- Healing Stream 1 + [6375] = 2, -- Healing Stream 2 + [6377] = 2, -- Healing Stream 3 + [10462] = 2, -- Healing Stream 4 + [10463] = 2, -- Healing Stream 5 + [25567] = 2, -- Healing Stream 6 + [5675] = 2, -- Mana Spring 1 + [10495] = 2, -- Mana Spring 2 + [10496] = 2, -- Mana Spring 3 + [10497] = 2, -- Mana Spring 4 + [25570] = 2, -- Mana Spring 5 +} + +local ninetyDegreeInRad = 90 * math.pi / 180 + +--------------------------------------------------- + +-- Core + +--------------------------------------------------- + + +local TotemPulse = Gladdy:NewModule("Totem Pulse", nil, { + totemPulseEnabled = true, + totemPulseEnabledShowFriendly = true, + totemPulseEnabledShowEnemy = true, + totemPulseAttachToTotemPlate = true, + totemPulseStyle = "", -- "COOLDOWN", "COOLDOWNREVERSE", "BARVERTICAL", "BARHORIZONTAL" + totemPulseTextColor = { r = 1, g = 1, b = 1, a = 0 }, + --bar + totemPulseBarWidth = 40, + totemPulseBarHeight = 20, + totemPulseBarColor = { r = 1, g = 0, b = 0, a = 1 }, + totemPulseBarBgColor = { r = 0, g = 1, b = 0, a = 1 }, + totemPulseBarBorderColor = { r = 0, g = 0, b = 0, a = 1 }, + totemPulseBarBorderSize = 5, + totemPulseBarBorderStyle = "Gladdy Tooltip squared", + totemPulseBarTexture = "Smooth", + --cooldown + totemPulseCooldownAlpha = 1, +}) + +function TotemPulse.OnEvent(self, event, ...) + TotemPulse[event](self, ...) +end + +function TotemPulse:Initialize() + self.cooldowns = cooldowns + self.timeStamps = {} + self.cooldownCache = {} + self.barCache = {} + self.activeFrames = { bars = {}, cooldowns = {} } + self:SetScript("OnEvent", self.OnEvent) + self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") + self:RegisterEvent("NAME_PLATE_UNIT_REMOVED") + self:RegisterEvent("NAME_PLATE_UNIT_ADDED") + self:RegisterEvent("UNIT_NAME_UPDATE") +end + +--------------------------------------------------- + +-- EVENTS + +--------------------------------------------------- + +function TotemPulse:COMBAT_LOG_EVENT_UNFILTERED() + local _,eventType,_,sourceGUID,_,_,_,destGUID,_,_,_,spellID,spellName,spellSchool,extraSpellId,extraSpellName,extraSpellSchool = CombatLogGetCurrentEventInfo() + print(eventType, spellName, spellID, destGUID) + if eventType == "SPELL_SUMMON" then + if cooldowns[spellID] then + print(eventType, spellName, spellID, GetPlayerInfoByGUID(sourceGUID)) + self.timeStamps[destGUID] = { timeStamp = GetTime(), spellID = spellID } + end + elseif eventType == "UNIT_DESTROYED" then + self.timeStamps[destGUID] = nil + end +end + +function TotemPulse:NAME_PLATE_UNIT_REMOVED(unitId) + local nameplate = C_NamePlate.GetNamePlateForUnit(unitId) + if nameplate.totemTick then + print("NAME_PLATE_UNIT_REMOVED", nameplate.totemTick) + nameplate.totemTick:SetScript("OnUpdate", nil) + nameplate.totemTick:Hide() + nameplate.totemTick:SetParent(nil) + tinsert(nameplate.totemTick.bar and self.barCache or self.cooldownCache, nameplate.totemTick) + self.activeFrames.bars[nameplate.totemTick] = nil + self.activeFrames.cooldowns[nameplate.totemTick] = nil + nameplate.totemTick = nil + end +end + +function TotemPulse:NAME_PLATE_UNIT_ADDED(unitId) + self:OnUnitAdded(unitId, "NAME_PLATE_UNIT_ADDED") +end + +function TotemPulse:UNIT_NAME_UPDATE(unitId) + self:OnUnitAdded(unitId, "UNIT_NAME_UPDATE") +end + +function TotemPulse:OnUnitAdded(unitId, event) + local isEnemy = UnitIsEnemy("player", unitId) + local guid = UnitGUID(unitId) + + local nameplate = C_NamePlate.GetNamePlateForUnit(unitId) + + if nameplate then + print(event, self.timeStamps[guid], nameplate.totemTick) + if self.timeStamps[guid] then + self:AddTimerFrame(nameplate, self.timeStamps[guid], Gladdy.db.totemPulseAttachToTotemPlate and nameplate.gladdyTotemFrame) + else + if nameplate.totemTick then + nameplate.totemTick:SetScript("OnUpdate", nil) + nameplate.totemTick:Hide() + nameplate.totemTick:SetParent(nil) + tinsert(nameplate.totemTick.bar and self.barCache or self.cooldownCache, nameplate.totemTick) + self.activeFrames.bars[nameplate.totemTick] = nil + self.activeFrames.cooldowns[nameplate.totemTick] = nil + nameplate.totemTick = nil + end + end + end +end + +--------------------------------------------------- + +-- FRAMES + +--------------------------------------------------- + +function TotemPulse:CreateCooldownFrame(gladdyTotemFrame) + local totemTick + + if gladdyTotemFrame then + if #self.cooldownCache > 0 then + totemTick = tremove(self.cooldownCache, #self.cooldownCache) + else + Gladdy:Print("TotemPulse:CreateCooldownFrame()", "CreateCooldown") + totemTick = CreateFrame("Cooldown", nil, nil, "CooldownFrameTemplate") + totemTick.noCooldownCount = true + totemTick:SetFrameStrata("MEDIUM") + totemTick:SetFrameLevel(4) + totemTick:SetReverse(true) + totemTick:SetHideCountdownNumbers(true) + totemTick:SetAlpha(Gladdy.db.totemPulseCooldownAlpha) + + totemTick.text = totemTick:CreateFontString(nil, "OVERLAY") + totemTick.text:SetPoint("LEFT", totemTick, "LEFT", 4, 0) + totemTick.text:SetFont("Fonts\\FRIZQT__.TTF", 16, "OUTLINE") + totemTick.text:SetJustifyH("LEFT") + totemTick.text:SetShadowOffset(1, -1) + totemTick.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) + end + else + if #self.barCache > 0 then + Gladdy:Print("TotemPulse:CreateCooldownFrame()", #self.barCache) + totemTick = tremove(self.barCache, #self.barCache) + else + Gladdy:Print("TotemPulse:CreateCooldownFrame()", "CreateBar") + totemTick = CreateFrame("Frame", nil) + + totemTick:SetWidth(Gladdy.db.totemPulseBarWidth) + totemTick:SetHeight(Gladdy.db.totemPulseBarHeight) + + totemTick.backdrop = CreateFrame("Frame", nil, totemTick, BackdropTemplateMixin and "BackdropTemplate") + totemTick.backdrop:SetAllPoints(totemTick) + totemTick.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "totemPulseBarBorderStyle"), + edgeSize = Gladdy.db.totemPulseBarBorderSize }) + totemTick.backdrop:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBorderColor)) + totemTick.backdrop:SetFrameLevel(1) + --totemTick.backdrop:SetFrameStrata(Gladdy.db.castBarFrameStrata) + --totemTick.backdrop:SetFrameLevel(Gladdy.db.castBarFrameLevel - 1) + + totemTick.bar = CreateFrame("StatusBar", nil, totemTick) + totemTick.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) + totemTick.bar:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.totemPulseBarColor)) + totemTick.bar:SetOrientation("Vertical") + totemTick.bar:SetFrameLevel(0) + totemTick.bar:SetPoint("TOPLEFT", totemTick, "TOPLEFT", (Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset)) + totemTick.bar:SetPoint("BOTTOMRIGHT", totemTick, "BOTTOMRIGHT", -(Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset)) + + totemTick.spark = totemTick.bar:CreateTexture(nil, "OVERLAY") + totemTick.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark") + totemTick.spark:SetBlendMode("ADD") + totemTick.spark:SetWidth(8) + totemTick.spark:SetHeight(40) + totemTick.spark.position = 0 + totemTick.spark:SetRotation(ninetyDegreeInRad) + + totemTick.bg = totemTick.bar:CreateTexture(nil, "BACKGROUND") + totemTick.bg:SetTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) + totemTick.bg:SetAllPoints(totemTick.bar) + totemTick.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBgColor)) + + totemTick.text = totemTick.bar:CreateFontString(nil, "OVERLAY") + totemTick.text:SetPoint("LEFT", totemTick, "LEFT", 4, 0) + totemTick.text:SetFont("Fonts\\FRIZQT__.TTF", 16, "OUTLINE") + totemTick.text:SetJustifyH("LEFT") + totemTick.text:SetShadowOffset(1, -1) + totemTick.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) + end + end + return totemTick +end + +function TotemPulse:AddTimerFrame(nameplate, timestamp, gladdyTotemFrame) + if nameplate:IsShown() and cooldowns[timestamp.spellID] then + if not nameplate.totemTick then + nameplate.totemTick = TotemPulse:CreateCooldownFrame(gladdyTotemFrame) + end + nameplate.totemTick:SetParent(nameplate) + nameplate.totemTick:ClearAllPoints() + if gladdyTotemFrame then + nameplate.totemTick:SetPoint("TOPLEFT", gladdyTotemFrame, "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) + nameplate.totemTick:SetPoint("BOTTOMRIGHT", gladdyTotemFrame, "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) + else + nameplate.totemTick:SetPoint("TOP", nameplate, "BOTTOM") + end + + local cd = type(cooldowns[timestamp.spellID]) == "table" and cooldowns[timestamp.spellID].cd or cooldowns[timestamp.spellID] + local once = type(cooldowns[timestamp.spellID]) == "table" + local cooldown = (timestamp.timeStamp - GetTime()) % cd + + if not gladdyTotemFrame then + nameplate.totemTick.bar:SetMinMaxValues(0, cd) + nameplate.totemTick.bar:SetValue(cooldown) + self.activeFrames.bars[nameplate.totemTick] = nameplate.totemTick + else + self.activeFrames.cooldowns[nameplate.totemTick] = nameplate.totemTick + end + + nameplate.totemTick.timestamp = timestamp.timeStamp + nameplate.totemTick.maxValue = cd + nameplate.totemTick.value = cooldown + nameplate.totemTick.once = once + + print("once", once, " - totemTick.once", nameplate.totemTick.once, " - cd off", math.abs(timestamp.timeStamp - GetTime()) > cd) + if once and GetTime() - timestamp.timeStamp > cd then + nameplate.totemTick:SetScript("OnUpdate", nil) + nameplate.totemTick:Hide() + print("nameplate.totemTick:Hide()") + else + nameplate.totemTick:SetScript("OnUpdate", function(totemTick, elapsed) + totemTick.now = GetTime() + totemTick.value = (totemTick.timestamp - totemTick.now) % totemTick.maxValue + if totemTick.once and totemTick.now - totemTick.timestamp >= totemTick.maxValue then + totemTick:SetScript("OnUpdate", nil) + print("OnUpdate totemTick:Hide()") + totemTick:Hide() + end + if not totemTick.bar and not (totemTick.once and totemTick.now - totemTick.timestamp >= totemTick.maxValue) then + totemTick:SetCooldown(totemTick.now - totemTick.value, totemTick.maxValue) + elseif totemTick.bar then + totemTick.spark.position = (totemTick.value / totemTick.maxValue) * totemTick.bar:GetHeight() + if ( totemTick.spark.position < 0 ) then + totemTick.spark.position = 0 + end + totemTick.spark:SetPoint("CENTER", totemTick.bar, "BOTTOM", 0, totemTick.spark.position) + totemTick.bar:SetValue(totemTick.value) + end + totemTick.text:SetFormattedText("%.1f", totemTick.value) + end) + print("nameplate.totemTick:Show()") + nameplate.totemTick:Show() + end + else + if nameplate.totemTick then + nameplate.totemTick:SetScript("OnUpdate", nil) + nameplate.totemTick:Hide() + nameplate.totemTick:SetParent(nil) + tinsert(nameplate.totemTick.bar and self.barCache or self.cooldownCache, nameplate.totemTick) + self.activeFrames.bars[nameplate.totemTick] = nil + self.activeFrames.cooldowns[nameplate.totemTick] = nil + nameplate.totemTick = nil + end + end +end + +function TotemPulse:UpdateBar(bar) + bar:SetWidth(Gladdy.db.totemPulseBarWidth) + bar:SetHeight(Gladdy.db.totemPulseBarHeight) + + bar.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "totemPulseBarBorderStyle"), + edgeSize = Gladdy.db.totemPulseBarBorderSize }) + bar.backdrop:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBorderColor)) + + bar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) + bar.bar:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.totemPulseBarColor)) + bar.bar:SetOrientation("Vertical") + bar.bar:SetPoint("TOPLEFT", bar, "TOPLEFT", (Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset)) + bar.bar:SetPoint("BOTTOMRIGHT", bar, "BOTTOMRIGHT", -(Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset)) + + bar.spark:SetWidth(8) + bar.spark:SetHeight(40) + bar.spark:SetRotation(ninetyDegreeInRad) + + bar.bg:SetTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) + bar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBgColor)) + + bar.text:SetFont("Fonts\\FRIZQT__.TTF", 16, "OUTLINE") + bar.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) +end + +function TotemPulse:UpdateCooldown(cooldown) + cooldown:SetReverse(true) + cooldown:SetAlpha(Gladdy.db.totemPulseCooldownAlpha) + cooldown.text:SetFont("Fonts\\FRIZQT__.TTF", 16, "OUTLINE") + cooldown.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) +end + +function TotemPulse:UpdateFrameOnce() + for _,bar in pairs(self.activeFrames.bars) do + self:UpdateBar(bar) + end + for _,cooldown in pairs(self.activeFrames.cooldowns) do + self:UpdateCooldown(cooldown) + end + for _,bar in pairs(self.barCache) do + self:UpdateBar(bar) + end + for _,cooldown in pairs(self.cooldownCache) do + self:UpdateCooldown(cooldown) + end +end + +--------------------------------------------------- + +-- TEST + +--------------------------------------------------- + + +--------------------------------------------------- + +-- OPTIONS + +--------------------------------------------------- + +function TotemPulse:GetOptions() + return { + headerClassicon = { + type = "header", + name = L["Totem Pulse"], + order = 2, + }, + totemPulseEnabled = Gladdy:option({ + type = "toggle", + name = L["Totem Pulse Enabled"], + order = 3, + }), + totemPulseAttachToTotemPlate = Gladdy:option({ + type = "toggle", + name = L["Attach to Totem Plates"], + order = 4, + }), + group = { + type = "group", + childGroups = "tree", + name = L["Frame"], + order = 4, + args = { + barFrame = { + type = "group", + name = L["Bar"], + order = 1, + args = { + headerSize = { + type = "header", + name = L["Bar Size"], + order = 1, + }, + totemPulseBarHeight = Gladdy:option({ + type = "range", + name = L["Bar height"], + desc = L["Height of the bar"], + order = 3, + min = 0.1, + max = 200, + step = .1, + width = "full", + }), + totemPulseBarWidth = Gladdy:option({ + type = "range", + name = L["Bar width"], + desc = L["Width of the bars"], + order = 4, + min = 0.1, + max = 600, + step = .1, + width = "full", + }), + headerTexture = { + type = "header", + name = L["Texture"], + order = 5, + }, + totemPulseBarTexture = Gladdy:option({ + type = "select", + name = L["Bar texture"], + desc = L["Texture of the bar"], + order = 9, + dialogControl = "LSM30_Statusbar", + values = AceGUIWidgetLSMlists.statusbar, + }), + totemPulseBarColor = Gladdy:colorOption({ + type = "color", + name = L["Bar color"], + desc = L["Color of the cast bar"], + order = 10, + hasAlpha = true, + }), + totemPulseBarBgColor = Gladdy:colorOption({ + type = "color", + name = L["Background color"], + desc = L["Color of the cast bar background"], + order = 11, + hasAlpha = true, + }), + headerBorder = { + type = "header", + name = L["Border"], + order = 12, + }, + totemPulseBarBorderSize = Gladdy:option({ + type = "range", + name = L["Border size"], + order = 13, + min = 0.5, + max = Gladdy.db.castBarHeight/2, + step = 0.5, + width = "full", + }), + totemPulseBarBorderStyle = Gladdy:option({ + type = "select", + name = L["Status Bar border"], + order = 51, + dialogControl = "LSM30_Border", + values = AceGUIWidgetLSMlists.border, + }), + totemPulseBarBorderColor = Gladdy:colorOption({ + type = "color", + name = L["Status Bar border color"], + order = 52, + hasAlpha = true, + }), + }, + }, + }, + }, + } +end \ No newline at end of file -- 2.39.5 From 803abd6f076b9407302da681e271dca2785b186a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 5 Feb 2022 04:17:03 +0100 Subject: [PATCH 133/268] initial TotemPulse --- Gladdy.toc | 1 + 1 file changed, 1 insertion(+) diff --git a/Gladdy.toc b/Gladdy.toc index 5113781..5dfaf9b 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -26,6 +26,7 @@ Modules\Clicks.lua Modules\Diminishings.lua Modules\Highlight.lua Modules\TotemPlates.lua +Modules\TotemPulse.lua Modules\Trinket.lua Modules\Racial.lua Modules\Cooldowns.lua -- 2.39.5 From 09bfb996815dd2a2a7995b18010245e2d3c428c2 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 5 Feb 2022 04:17:41 +0100 Subject: [PATCH 134/268] add improved wingclip, entrapment, disarm to DRs --- Libs/DRData-1.0/DRData-1.0.lua | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Libs/DRData-1.0/DRData-1.0.lua b/Libs/DRData-1.0/DRData-1.0.lua index 6b7d0e7..a3a3c8d 100644 --- a/Libs/DRData-1.0/DRData-1.0.lua +++ b/Libs/DRData-1.0/DRData-1.0.lua @@ -182,7 +182,13 @@ Data.spells = { --[[ RANDOM ROOTS ]]-- -- Improved Hamstring [23694] = "rndroot", - + + -- Entrapment (Hunter Talent) + [19185] = "rndroot", + + -- Improved Wingclip + [19229] = "rndroot", + -- Frostbite [12494] = "rndroot", @@ -244,7 +250,10 @@ Data.spells = { [10912] = "charm", -- Counterattack - [19306] = "counterattack" + [19306] = "counterattack", + + -- Disarm + [676] = "disarm", } -- DR Category names @@ -267,7 +276,8 @@ Data.typeNames = { ["repentance"] = "Repentance", ["dragonsbreath"] = "Dragon's Breath", ["ua"] = "Unstable Affliction Silence", - ["counterattack"] = "Counterattack Immobilize" + ["counterattack"] = "Counterattack Immobilize", + ["disarm"] = "Disarm" } -- Categories that have DR in PvE as well as PvP -- 2.39.5 From 5212479daec0b1757cb8c1d830a2c758df21b55c Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 5 Feb 2022 04:19:53 +0100 Subject: [PATCH 135/268] completely hide nameplate TotemPlates added --- Modules/TotemPlates.lua | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/Modules/TotemPlates.lua b/Modules/TotemPlates.lua index f87053d..5570b97 100644 --- a/Modules/TotemPlates.lua +++ b/Modules/TotemPlates.lua @@ -98,6 +98,18 @@ local function GetTotemColorDefaultOptions() end) for i=1,#indexedList do defaultDB["totem" .. indexedList[i].id] = {color = indexedList[i].color, enabled = indexedList[i].enabled, alpha = 0.6, customText = ""} + options["npTotemsHideDisabledTotems"] = { + order = 1, + name = L["Hide Disabled Totem Plates"], + desc = L["Hide Disabled Totem Plates"], + type = "toggle", + width = "full", + get = function() return Gladdy.dbi.profile.npTotemsHideDisabledTotems end, + set = function(_, value) + Gladdy.dbi.profile.npTotemsHideDisabledTotems = value + Gladdy:UpdateFrame() + end + } options["totem" .. indexedList[i].id] = { order = i+1, name = select(1, GetSpellInfo(indexedList[i].id)), @@ -198,7 +210,8 @@ local TotemPlates = Gladdy:NewModule("Totem Plates", nil, { npTotemPlatesAlpha = 0.6, npTotemPlatesAlphaAlways = false, npTotemPlatesAlphaAlwaysTargeted = false, - npTotemColors = select(1, GetTotemColorDefaultOptions()) + npTotemColors = select(1, GetTotemColorDefaultOptions()), + npTotemsHideDisabledTotems = false, }) LibStub("AceHook-3.0"):Embed(TotemPlates) @@ -295,6 +308,18 @@ function TotemPlates:UpdateFrameOnce() nameplate.gladdyTotemFrame:Hide() self:ToggleAddon(nameplate, true) end + if Gladdy.db.npTotems and Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].enabled then + nameplate.gladdyTotemFrame:Show() + self:ToggleAddon(nameplate) + end + if Gladdy.db.npTotems and not Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].enabled then + nameplate.gladdyTotemFrame:Hide() + self:ToggleAddon(nameplate, true) + end + if Gladdy.db.npTotems and not Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].enabled and Gladdy.db.npTotemsHideDisabledTotems then + nameplate.gladdyTotemFrame:Hide() + self:ToggleAddon(nameplate) + end end for _,gladdyTotemFrame in ipairs(self.totemPlateCache) do gladdyTotemFrame:SetWidth(Gladdy.db.npTotemPlatesSize * Gladdy.db.npTotemPlatesWidthFactor) @@ -395,7 +420,7 @@ function TotemPlates:ToggleAddon(nameplate, show) end function TotemPlates.OnUpdate(self) - if (UnitIsUnit("mouseover", self.unitID) or UnitIsUnit("target", self.unitID)) then + if (UnitIsUnit("mouseover", self.unitID) or UnitIsUnit("target", self.unitID)) and Gladdy.db.npTotemColors["totem" .. self.totemDataEntry.id].alpha > 0 then self.selectionHighlight:SetAlpha(.25) else self.selectionHighlight:SetAlpha(0) @@ -452,6 +477,14 @@ function TotemPlates:OnUnitEvent(unitID) TotemPlates:SetTotemAlpha(nameplate.gladdyTotemFrame, unitID) self:ToggleAddon(nameplate) self.activeTotemNameplates[unitID] = nameplate + elseif totemDataEntry and not Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].enabled and Gladdy.db.npTotemsHideDisabledTotems then + if nameplate.gladdyTotemFrame then + nameplate.gladdyTotemFrame:Hide() + nameplate.gladdyTotemFrame:SetParent(nil) + tinsert(self.totemPlateCache, nameplate.gladdyTotemFrame) + nameplate.gladdyTotemFrame = nil + end + self:ToggleAddon(nameplate) else self:ToggleAddon(nameplate, true) end -- 2.39.5 From 86337919b880f7c62992dd6227106eaf8f14268d Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 12 Feb 2022 02:08:51 +0100 Subject: [PATCH 136/268] fix UnitIsUnit errors when unitCaster is nil --- EventListener.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 0086627..75cbba1 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -73,7 +73,7 @@ function Gladdy:SpotEnemy(unit, auraScan) if ( not spellName ) then break end - if Gladdy.cooldownBuffs[spellName] then -- Check for auras that detect used CDs (like Fear Ward) + if Gladdy.cooldownBuffs[spellName] and unitCaster then -- Check for auras that detect used CDs (like Fear Ward) for arenaUnit,v in pairs(self.buttons) do if (UnitIsUnit(arenaUnit, unitCaster)) then Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, expirationTime - GetTime()) @@ -84,7 +84,7 @@ function Gladdy:SpotEnemy(unit, auraScan) if Gladdy.cooldownBuffs.racials[spellName] then Gladdy:SendMessage("RACIAL_USED", unit, expirationTime, spellName) end - if Gladdy.specBuffs[spellName] then -- Check for auras that detect a spec + if Gladdy.specBuffs[spellName] and unitCaster then -- Check for auras that detect a spec local unitPet = string_gsub(unit, "%d$", "pet%1") if UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster) then EventListener:DetectSpec(unit, Gladdy.specBuffs[spellName]) @@ -238,7 +238,7 @@ function EventListener:UNIT_AURA(unit) Gladdy:SendMessage("AURA_GAIN_LIMIT", unit, auraType, n - 1) break end - if Gladdy.cooldownBuffs[spellName] then -- Check for auras that hint used CDs (like Fear Ward) + if Gladdy.cooldownBuffs[spellName] and unitCaster then -- Check for auras that hint used CDs (like Fear Ward) for arenaUnit,v in pairs(Gladdy.buttons) do if (UnitIsUnit(arenaUnit, unitCaster)) then Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, expirationTime - GetTime()) @@ -248,7 +248,7 @@ function EventListener:UNIT_AURA(unit) if Gladdy.cooldownBuffs.racials[spellName] then Gladdy:SendMessage("RACIAL_USED", unit, spellName, expirationTime, spellName) end - if not button.spec and Gladdy.specBuffs[spellName] then + if not button.spec and Gladdy.specBuffs[spellName] and unitCaster then local unitPet = string_gsub(unit, "%d$", "pet%1") if unitCaster and (UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster)) then self:DetectSpec(unit, Gladdy.specBuffs[spellName]) -- 2.39.5 From 3e59a03ce98887699f15010c2229d86c79b7181f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 15 Feb 2022 22:59:21 +0100 Subject: [PATCH 137/268] disable options for disabled module + (un)register messages when enabled/disabled --- Modules/ArenaCountDown.lua | 18 +++++++++++++++--- Modules/BuffsDebuffs.lua | 37 +++++++++++++++++++++++++++++------- Modules/Castbar.lua | 16 ++++++++++++++-- Modules/Classicon.lua | 20 ++++++++++++++++--- Modules/CombatIndicator.lua | 13 ++++++++++++- Modules/Diminishings.lua | 5 ++++- Modules/Pets.lua | 25 +++++++++++++++++++----- Modules/Powerbar.lua | 30 +++++++++++++++++++++++++---- Modules/Racial.lua | 19 +++++++++++++++--- Modules/RangeCheck.lua | 20 ++++++++++++++++--- Modules/ShadowsightTimer.lua | 14 +++++++++++++- Modules/Trinket.lua | 21 +++++++++++++------- 12 files changed, 198 insertions(+), 40 deletions(-) diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index 6218064..4f7e5df 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -47,13 +47,22 @@ function ACDFrame:Initialize() ACDNumOne:SetPoint("CENTER", ACDNumFrame, "CENTER", 0, 0) self.ACDNumOne = ACDNumOne - self:RegisterMessage("JOINED_ARENA") - self:RegisterMessage("ENEMY_SPOTTED") - self:RegisterMessage("UNIT_SPEC") + if Gladdy.db.countdown then + self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("UNIT_SPEC") + end self.faction = UnitFactionGroup("player") end function ACDFrame:UpdateFrameOnce() + if Gladdy.db.countdown then + self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("UNIT_SPEC") + else + self:UnregisterAllMessages() + end self.ACDNumFrame:SetFrameStrata(Gladdy.db.arenaCountdownFrameStrata) self.ACDNumFrame:SetFrameLevel(Gladdy.db.arenaCountdownFrameLevel) end @@ -189,6 +198,7 @@ function ACDFrame:GetOptions() max = 512, step = 16, width = "full", + disabled = function() return not Gladdy.db.countdown end, }), headerAuraLevel = { type = "header", @@ -201,6 +211,7 @@ function ACDFrame:GetOptions() order = 6, values = Gladdy.frameStrata, sorting = Gladdy.frameStrataSorting, + disabled = function() return not Gladdy.db.countdown end, }), arenaCountdownFrameLevel = Gladdy:option({ type = "range", @@ -210,6 +221,7 @@ function ACDFrame:GetOptions() step = 1, order = 7, width = "full", + disabled = function() return not Gladdy.db.countdown end, }), } end diff --git a/Modules/BuffsDebuffs.lua b/Modules/BuffsDebuffs.lua index 1574c54..a61fb95 100644 --- a/Modules/BuffsDebuffs.lua +++ b/Modules/BuffsDebuffs.lua @@ -76,13 +76,16 @@ function BuffsDebuffs:Initialize() self.icons = {} self.trackedCC = {} self.framePool = {} - self:RegisterMessage("JOINED_ARENA") - self:RegisterMessage("UNIT_DESTROYED") - self:RegisterMessage("UNIT_DEATH") - self:RegisterMessage("AURA_FADE") - self:RegisterMessage("AURA_GAIN") - self:RegisterMessage("AURA_GAIN_LIMIT") - self:SetScript("OnEvent", BuffsDebuffs.OnEvent) + if Gladdy.db.buffsEnabled then + self:RegisterMessages( + "JOINED_ARENA", + "UNIT_DESTROYED", + "UNIT_DEATH", + "AURA_FADE", + "AURA_GAIN", + "AURA_GAIN_LIMIT") + self:SetScript("OnEvent", BuffsDebuffs.OnEvent) + end spellSchoolToOptionValueTable = { curse = Gladdy.db.buffsBorderColorCurse, magic = Gladdy.db.buffsBorderColorMagic, @@ -290,6 +293,22 @@ local function styleIcon(aura, auraType) aura.stacks:SetTextColor(Gladdy.db.buffsFontColor.r, Gladdy.db.buffsFontColor.g, Gladdy.db.buffsFontColor.b, 1) end +function BuffsDebuffs:UpdateFrameOnce() + if Gladdy.db.buffsEnabled then + self:RegisterMessages( + "JOINED_ARENA", + "UNIT_DESTROYED", + "UNIT_DEATH", + "AURA_FADE", + "AURA_GAIN", + "AURA_GAIN_LIMIT") + self:SetScript("OnEvent", BuffsDebuffs.OnEvent) + else + self:UnregisterAllMessages() + self:SetScript("OnEvent", nil) + end +end + function BuffsDebuffs:UpdateFrame(unit) --DEBUFFS self.frames[unit].debuffFrame:SetHeight(Gladdy.db.buffsIconSize) @@ -485,12 +504,14 @@ function BuffsDebuffs:GetOptions() name = L["Show CC"], desc = L["Shows all debuffs, which are displayed on the ClassIcon as well"], order = 4, + disabled = function() return not Gladdy.db.buffsEnabled end, }), group = { type = "group", childGroups = "tree", name = L["Frame"], order = 5, + disabled = function() return not Gladdy.db.buffsEnabled end, args = { buffs = { type = "group", @@ -919,6 +940,7 @@ function BuffsDebuffs:GetOptions() name = L["Debuff Lists"], type = "group", order = 11, + disabled = function() return not Gladdy.db.buffsEnabled end, childGroups = "tree", args = select(1, Gladdy:GetAuras(AURA_TYPE_DEBUFF)), set = function(info, state) @@ -934,6 +956,7 @@ function BuffsDebuffs:GetOptions() name = L["Buff Lists"], type = "group", order = 12, + disabled = function() return not Gladdy.db.buffsEnabled end, childGroups = "tree", args = select(1, Gladdy:GetAuras(AURA_TYPE_BUFF)), set = function(info, state) diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 38f0ff0..24fc6a7 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -48,8 +48,10 @@ local Castbar = Gladdy:NewModule("Cast Bar", 70, { function Castbar:Initialize() self.frames = {} - self:RegisterMessage("UNIT_DEATH") - self:RegisterMessage("JOINED_ARENA") + if Gladdy.db.castBarEnabled then + self:RegisterMessage("UNIT_DEATH") + self:RegisterMessage("JOINED_ARENA") + end end --------------------------- @@ -133,6 +135,15 @@ function Castbar:CreateFrame(unit) self:ResetUnit(unit) end +function Castbar:UpdateFrameOnce() + if Gladdy.db.castBarEnabled then + self:RegisterMessage("UNIT_DEATH") + self:RegisterMessage("JOINED_ARENA") + else + self:UnregisterAllMessages() + end +end + function Castbar:UpdateFrame(unit) local castBar = self.frames[unit] if (not castBar) then @@ -584,6 +595,7 @@ function Castbar:GetOptions() childGroups = "tree", name = L["Frame"], order = 4, + disabled = function() return not Gladdy.db.castBarEnabled end, args = { barFrame = { type = "group", diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index c419ab8..e20ce46 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -82,9 +82,21 @@ local specIcons = { function Classicon:Initialize() self.frames = {} - self:RegisterMessage("ENEMY_SPOTTED") - self:RegisterMessage("UNIT_DEATH") - self:RegisterMessage("UNIT_SPEC") + if Gladdy.db.classIconEnabled then + self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("UNIT_DEATH") + self:RegisterMessage("UNIT_SPEC") + end +end + +function Classicon:UpdateFrameOnce() + if Gladdy.db.classIconEnabled then + self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("UNIT_DEATH") + self:RegisterMessage("UNIT_SPEC") + else + self:UnregisterAllMessages() + end end function Classicon:CreateFrame(unit) @@ -191,6 +203,7 @@ function Classicon:GetOptions() name = L["Show Spec Icon"], desc = L["Shows Spec Icon once spec is detected"], order = 4, + disabled = function() return not Gladdy.db.classIconEnabled end, get = function() return Gladdy.db.classIconSpecIcon end, set = function(_, value) Gladdy.db.classIconSpecIcon = value @@ -210,6 +223,7 @@ function Classicon:GetOptions() childGroups = "tree", name = L["Frame"], order = 4, + disabled = function() return not Gladdy.db.classIconEnabled end, args = { size = { type = "group", diff --git a/Modules/CombatIndicator.lua b/Modules/CombatIndicator.lua index 4ac51ee..276bcaf 100644 --- a/Modules/CombatIndicator.lua +++ b/Modules/CombatIndicator.lua @@ -20,7 +20,9 @@ local CombatIndicator = Gladdy:NewModule("Combat Indicator", nil, { function CombatIndicator:Initialize() self.frames = {} - self:RegisterMessage("JOINED_ARENA") + if Gladdy.db.ciEnabled then + self:RegisterMessage("JOINED_ARENA") + end self.updateInterval = 0.05 self.combatIndicatorIcon = select(3, GetSpellInfo(674)) end @@ -57,6 +59,14 @@ function CombatIndicator:CreateFrame(unit) button.ciFrame = ciFrame end +function CombatIndicator:UpdateFrameOnce() + if Gladdy.db.ciEnabled then + self:RegisterMessage("JOINED_ARENA") + else + self:UnregisterAllMessages() + end +end + function CombatIndicator:UpdateFrame(unit) local button = Gladdy.buttons[unit] local ciFrame = self.frames[unit] @@ -133,6 +143,7 @@ function CombatIndicator:GetOptions() childGroups = "tree", name = L["Frame"], order = 4, + disabled = function() return not Gladdy.db.ciEnabled end, args = { general = { type = "group", diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index a9836bd..32337ef 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -79,7 +79,7 @@ end function Diminishings:Initialize() self.frames = {} - self:RegisterMessage("UNIT_DEATH", "ResetUnit", "AURA_FADE", "UNIT_DESTROYED") + self:RegisterMessage("UNIT_DESTROYED") end function Diminishings:CreateFrame(unit) @@ -434,6 +434,7 @@ function Diminishings:GetOptions() name = L["DR Duration"], desc = L["Change the DR Duration in seconds (DR is dynamic between 15-20s)"], order = 4, + disabled = function() return not Gladdy.db.drEnabled end, min = 15, max = 20, step = .1, @@ -443,6 +444,7 @@ function Diminishings:GetOptions() childGroups = "tree", name = L["Frame"], order = 5, + disabled = function() return not Gladdy.db.drEnabled end, args = { icon = { type = "group", @@ -781,6 +783,7 @@ function Diminishings:GetOptions() type = "group", name = L["Categories"], order = 6, + disabled = function() return not Gladdy.db.drEnabled end, args = Diminishings:CategoryOptions(), }, } diff --git a/Modules/Pets.lua b/Modules/Pets.lua index fc703b0..5a7eca1 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -31,11 +31,25 @@ local Pets = Gladdy:NewModule("Pets", nil, { function Pets:Initialize() self.frames = {} - self:RegisterMessage("JOINED_ARENA") - self:RegisterMessage("PET_SPOTTED") - self:RegisterMessage("PET_DESTROYED") - self:RegisterMessage("PET_STEALTH") - self:RegisterMessage("ENEMY_SPOTTED") + if Gladdy.db.petEnabled then + self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("PET_SPOTTED") + self:RegisterMessage("PET_DESTROYED") + self:RegisterMessage("PET_STEALTH") + self:RegisterMessage("ENEMY_SPOTTED") + end +end + +function Pets:UpdateFrameOnce() + if Gladdy.db.petEnabled then + self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("PET_SPOTTED") + self:RegisterMessage("PET_DESTROYED") + self:RegisterMessage("PET_STEALTH") + self:RegisterMessage("ENEMY_SPOTTED") + else + self:UnregisterAllMessages() + end end function Pets:JOINED_ARENA() @@ -380,6 +394,7 @@ function Pets:GetOptions() childGroups = "tree", name = L["Frame"], order = 3, + disabled = function() return not Gladdy.db.petEnabled end, args = { general = { type = "group", diff --git a/Modules/Powerbar.lua b/Modules/Powerbar.lua index 4e99810..5f48021 100644 --- a/Modules/Powerbar.lua +++ b/Modules/Powerbar.lua @@ -29,10 +29,23 @@ local Powerbar = Gladdy:NewModule("Power Bar", 90, { function Powerbar:Initialize() self.frames = {} - self:RegisterMessage("ENEMY_SPOTTED") - self:RegisterMessage("UNIT_SPEC") - self:RegisterMessage("UNIT_DEATH") - self:RegisterMessage("UNIT_DESTROYED") + if Gladdy.db.powerBarEnabled then + self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("UNIT_SPEC") + self:RegisterMessage("UNIT_DEATH") + self:RegisterMessage("UNIT_DESTROYED") + end +end + +function Powerbar:UpdateFrameOnce() + if Gladdy.db.powerBarEnabled then + self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("UNIT_SPEC") + self:RegisterMessage("UNIT_DEATH") + self:RegisterMessage("UNIT_DESTROYED") + else + self:UnregisterAllMessages() + end end function Powerbar:CreateFrame(unit) @@ -147,8 +160,16 @@ function Powerbar:UpdateFrame(unit) if not Gladdy.db.powerBarEnabled then powerBar:Hide() + powerBar:UnregisterEvent("UNIT_POWER_UPDATE") + powerBar:UnregisterEvent("UNIT_MAXPOWER") + powerBar:UnregisterEvent("UNIT_DISPLAYPOWER") + powerBar:SetScript("OnEvent", nil) return else + powerBar:RegisterUnitEvent("UNIT_POWER_UPDATE", unit) + powerBar:RegisterUnitEvent("UNIT_MAXPOWER", unit) + powerBar:RegisterUnitEvent("UNIT_DISPLAYPOWER", unit) + powerBar:SetScript("OnEvent", Powerbar.OnEvent) powerBar:Show() end powerBar.bg:SetTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) @@ -351,6 +372,7 @@ function Powerbar:GetOptions() childGroups = "tree", name = L["Frame"], order = 4, + disabled = function() return not Gladdy.db.powerBarEnabled end, args = { general = { type = "group", diff --git a/Modules/Racial.lua b/Modules/Racial.lua index ec5e237..e9dff61 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -26,9 +26,21 @@ local Racial = Gladdy:NewModule("Racial", 79, { function Racial:Initialize() self.frames = {} - self:RegisterMessage("JOINED_ARENA") - self:RegisterMessage("ENEMY_SPOTTED") - self:RegisterMessage("RACIAL_USED") + if Gladdy.db.racialEnabled then + self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("RACIAL_USED") + end +end + +function Racial:UpdateFrameOnce() + if Gladdy.db.racialEnabled then + self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("RACIAL_USED") + else + self:UnregisterAllMessages() + end end local function iconTimer(self,elapsed) @@ -235,6 +247,7 @@ function Racial:GetOptions() childGroups = "tree", name = L["Frame"], order = 4, + disabled = function() return not Gladdy.db.racialEnabled end, args = { general = { type = "group", diff --git a/Modules/RangeCheck.lua b/Modules/RangeCheck.lua index 3e95600..36cdcfc 100644 --- a/Modules/RangeCheck.lua +++ b/Modules/RangeCheck.lua @@ -52,12 +52,24 @@ local RangeCheck = Gladdy:NewModule("Range Check", nil, { }) function RangeCheck:Initialize() - self:RegisterMessage("JOINED_ARENA") - self:RegisterMessage("ENEMY_STEALTH") - self:RegisterMessage("ENEMY_SPOTTED") + if Gladdy.db.rangeCheckEnabled then + self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("ENEMY_STEALTH") + self:RegisterMessage("ENEMY_SPOTTED") + end self.playerClass = select(2, UnitClass("player")) end +function RangeCheck:UpdateFrameOnce() + if Gladdy.db.rangeCheckEnabled then + self:RegisterMessage("JOINED_ARENA") + self:RegisterMessage("ENEMY_STEALTH") + self:RegisterMessage("ENEMY_SPOTTED") + else + self:UnregisterAllMessages() + end +end + function RangeCheck:Reset() self.test = nil end @@ -268,6 +280,7 @@ function RangeCheck:GetOptions() childGroups = "tree", name = L["General"], order = 5, + disabled = function() return not Gladdy.db.rangeCheckEnabled end, args = { general = { type = "group", @@ -340,6 +353,7 @@ function RangeCheck:GetOptions() childGroups = "tree", name = L["Spells"], order = 5, + disabled = function() return not Gladdy.db.rangeCheckEnabled end, args = RangeCheck:GetSpells(), }, } diff --git a/Modules/ShadowsightTimer.lua b/Modules/ShadowsightTimer.lua index 8843cc2..9606f86 100644 --- a/Modules/ShadowsightTimer.lua +++ b/Modules/ShadowsightTimer.lua @@ -34,8 +34,10 @@ end function ShadowsightTimer:Initialize() self.locale = Gladdy:GetArenaTimer() - self:RegisterMessage("JOINED_ARENA") self:CreateAnchor() + if Gladdy.db.shadowsightTimerEnabled then + self:RegisterMessage("JOINED_ARENA") + end end function ShadowsightTimer:Reset() @@ -106,6 +108,12 @@ function ShadowsightTimer:CreateAnchor() end function ShadowsightTimer:UpdateFrameOnce() + if Gladdy.db.shadowsightTimerEnabled then + self:RegisterMessage("JOINED_ARENA") + else + self:UnregisterAllMessages() + end + self.anchor:EnableMouse(not Gladdy.db.shadowsightTimerLocked) self.anchor:SetFrameStrata(Gladdy.db.shadowsightTimerFrameStrata) @@ -299,23 +307,27 @@ function ShadowsightTimer:GetOptions() name = L["Locked"], --desc = L["Turns countdown before the start of an arena match on/off."], order = 4, + disabled = function() return not Gladdy.db.shadowsightTimerEnabled end, }), shadowsightTimerShowTwoTimer = Gladdy:option({ type = "toggle", name = L["Show two timers"], order = 5, + disabled = function() return not Gladdy.db.shadowsightTimerEnabled end, }), shadowsightAnnounce = Gladdy:option({ type = "toggle", name = L["Announce"], --desc = L["Turns countdown before the start of an arena match on/off."], order = 6, + disabled = function() return not Gladdy.db.shadowsightTimerEnabled end, }), group = { type = "group", childGroups = "tree", name = L["Frame"], order = 7, + disabled = function() return not Gladdy.db.shadowsightTimerEnabled end, args = { general = { type = "group", diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 0c316e1..13f7f49 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -29,8 +29,17 @@ local Trinket = Gladdy:NewModule("Trinket", 80, { function Trinket:Initialize() self.frames = {} + if Gladdy.db.trinketEnabled then + self:RegisterMessage("JOINED_ARENA") + end +end - self:RegisterMessage("JOINED_ARENA") +function Trinket:UpdateFrameOnce() + if Gladdy.db.trinketEnabled then + self:RegisterMessage("JOINED_ARENA") + else + self:UnregisterAllMessages() + end end local function iconTimer(self, elapsed) @@ -272,6 +281,7 @@ function Trinket:GetOptions() name = L["Colored trinket"], desc = L["Shows a solid colored icon when off/off CD."], order = 4, + disabled = function() return not Gladdy.db.trinketEnabled end, }), trinketColoredCd = Gladdy:colorOption({ type = "color", @@ -279,9 +289,7 @@ function Trinket:GetOptions() desc = L["Color of the border"], order = 5, hasAlpha = true, - disabled = function() - return not Gladdy.db.trinketColored - end, + disabled = function() return not Gladdy.db.trinketEnabled end, }), trinketColoredNoCd = Gladdy:colorOption({ type = "color", @@ -289,15 +297,14 @@ function Trinket:GetOptions() desc = L["Color of the border"], order = 6, hasAlpha = true, - disabled = function() - return not Gladdy.db.trinketColored - end, + disabled = function() return not Gladdy.db.trinketEnabled end, }), group = { type = "group", childGroups = "tree", name = L["Frame"], order = 5, + disabled = function() return not Gladdy.db.trinketEnabled end, args = { general = { type = "group", -- 2.39.5 From 051571f4efd33241e4be7c9b7ef3391fa9b471a9 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 15 Feb 2022 23:17:51 +0100 Subject: [PATCH 138/268] change identifying totems by name to identifying by guid (npcId) - faster and localization independent --- Constants.lua | 342 +++++++++++++++++++++++++++++++++++++++- Modules/TotemPlates.lua | 281 +++++++++++++++++---------------- 2 files changed, 484 insertions(+), 139 deletions(-) diff --git a/Constants.lua b/Constants.lua index 0a5704e..8df815c 100644 --- a/Constants.lua +++ b/Constants.lua @@ -1,4 +1,4 @@ -local tbl_sort, select = table.sort, select +local tbl_sort, select, string_lower = table.sort, select, string.lower local GetSpellInfo = GetSpellInfo local GetItemInfo = GetItemInfo @@ -1259,4 +1259,342 @@ Gladdy.frameStrataSorting = { [6] = "FULLSCREEN", [7] = "FULLSCREEN_DIALOG", [8] = "TOOLTIP", -} \ No newline at end of file +} + + +--------------------- +-- TOTEM STUFF +--------------------- + +local totemData = { + -- Fire + [string_lower("Searing Totem")] = {id = 3599,texture = select(3, GetSpellInfo(3599)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Flametongue Totem")] = {id = 8227,texture = select(3, GetSpellInfo(8227)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Magma Totem")] = {id = 8190,texture = select(3, GetSpellInfo(8190)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 2}, + [string_lower("Fire Nova Totem")] = {id = 1535,texture = select(3, GetSpellInfo(1535)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = { cd = 4, once = true }}, + [string_lower("Totem of Wrath")] = {id = 30706,texture = select(3, GetSpellInfo(30706)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Fire Elemental Totem")] = {id = 32982,texture = select(3, GetSpellInfo(32982)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Frost Resistance Totem")] = {id = 8181,texture = select(3, GetSpellInfo(8181)), color = {r = 0, g = 0, b = 0, a = 1}}, + -- Water + [string_lower("Fire Resistance Totem")] = {id = 8184,texture = select(3, GetSpellInfo(8184)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Poison Cleansing Totem")] = {id = 8166,texture = select(3, GetSpellInfo(8166)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 4}, + [string_lower("Disease Cleansing Totem")] = {id = 8170,texture = select(3, GetSpellInfo(8170)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 4}, + [string_lower("Healing Stream Totem")] = {id = 5394,texture = select(3, GetSpellInfo(5394)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 2}, + [string_lower("Mana Tide Totem")] = {id = 16190,texture = select(3, GetSpellInfo(16190)), color = {r = 0.078, g = 0.9, b = 0.16, a = 1}}, + [string_lower("Mana Spring Totem")] = {id = 5675,texture = select(3, GetSpellInfo(5675)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 2}, + -- Earth + [string_lower("Earthbind Totem")] = {id = 2484,texture = select(3, GetSpellInfo(2484)), color = {r = 0.5, g = 0.5, b = 0.5, a = 1}, pulse = 3}, + [string_lower("Stoneclaw Totem")] = {id = 5730,texture = select(3, GetSpellInfo(5730)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 2}, + [string_lower("Stoneskin Totem")] = {id = 8071,texture = select(3, GetSpellInfo(8071)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Strength of Earth Totem")] = {id = 8075,texture = select(3, GetSpellInfo(8075)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Earth Elemental Totem")] = {id = 33663,texture = select(3, GetSpellInfo(33663)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Tremor Totem")] = {id = 8143,texture = select(3, GetSpellInfo(8143)), color = {r = 1, g = 0.9, b = 0.1, a = 1}, pulse = 3}, + -- Air + [string_lower("Grounding Totem")] = {id = 8177,texture = select(3, GetSpellInfo(8177)), color = {r = 0, g = 0.53, b = 0.92, a = 1}}, + [string_lower("Grace of Air Totem")] = {id = 8835,texture = select(3, GetSpellInfo(8835)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Nature Resistance Totem")] = {id = 10595,texture = select(3, GetSpellInfo(10595)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Windfury Totem")] = {id = 8512,texture = select(3, GetSpellInfo(8512)), color = {r = 0.96, g = 0, b = 0.07, a = 1}}, + [string_lower("Sentry Totem")] = {id = 6495, texture = select(3, GetSpellInfo(6495)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Windwall Totem")] = {id = 15107,texture = select(3, GetSpellInfo(15107)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Wrath of Air Totem")] = {id = 3738,texture = select(3, GetSpellInfo(3738)), color = {r = 0, g = 0, b = 0, a = 1}}, + [string_lower("Tranquil Air Totem")] = {id = 25908,texture = select(3, GetSpellInfo(25908)), color = {r = 0, g = 0, b = 0, a = 1}}, +} + +local totemSpellIdToPulse = { + [GetSpellInfo(totemData[string_lower("Earthbind Totem")].id)] = totemData[string_lower("Earthbind Totem")].pulse, + [2484] = totemData[string_lower("Earthbind Totem")].pulse, + [GetSpellInfo(totemData[string_lower("Tremor Totem")].id)] = totemData[string_lower("Tremor Totem")].pulse, + [8143] = totemData[string_lower("Tremor Totem")].pulse, + [GetSpellInfo(totemData[string_lower("Poison Cleansing Totem")].id)] = totemData[string_lower("Poison Cleansing Totem")].pulse, + [8166] = totemData[string_lower("Poison Cleansing Totem")].pulse, + [GetSpellInfo(totemData[string_lower("Disease Cleansing Totem")].id)] = totemData[string_lower("Disease Cleansing Totem")].pulse, + [8170] = totemData[string_lower("Disease Cleansing Totem")].pulse, + [GetSpellInfo(totemData[string_lower("Fire Nova Totem")].id)] = totemData[string_lower("Fire Nova Totem")].pulse, + [1535] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 1 + [8498] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 2 + [8499] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 3 + [11314] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 4 + [11315] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 5 + [25546] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 6 + [25547] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 7 + [GetSpellInfo(totemData[string_lower("Magma Totem")].id)] = totemData[string_lower("Magma Totem")].pulse, + [8190] = totemData[string_lower("Magma Totem")].pulse, -- Rank 1 + [10585] = totemData[string_lower("Magma Totem")].pulse, -- Rank 2 + [10586] = totemData[string_lower("Magma Totem")].pulse, -- Rank 3 + [10587] = totemData[string_lower("Magma Totem")].pulse, -- Rank 4 + [25552] = totemData[string_lower("Magma Totem")].pulse, -- Rank 5 + [GetSpellInfo(totemData[string_lower("Healing Stream Totem")].id)] = totemData[string_lower("Healing Stream Totem")].pulse, + [5394] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 1 + [6375] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 2 + [6377] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 3 + [10462] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 4 + [10463] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 5 + [25567] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 6 + [GetSpellInfo(totemData[string_lower("Mana Spring Totem")].id)] = totemData[string_lower("Mana Spring Totem")].pulse, + [5675] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 1 + [10495] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 2 + [10496] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 3 + [10497] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 4 + [25570] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 5 + [GetSpellInfo(totemData[string_lower("Stoneclaw Totem")].id)] = totemData[string_lower("Stoneclaw Totem")].pulse, + [5730] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 1 + [6390] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 2 + [6391] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 3 + [6392] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 4 + [10427] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 5 + [10428] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 6 + [25525] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 7 +} + +local totemNpcIdsToTotemData = { + --fire + [2523] = totemData[string_lower("Searing Totem")], + [3902] = totemData[string_lower("Searing Totem")], + [3903] = totemData[string_lower("Searing Totem")], + [3904] = totemData[string_lower("Searing Totem")], + [7400] = totemData[string_lower("Searing Totem")], + [7402] = totemData[string_lower("Searing Totem")], + [15480] = totemData[string_lower("Searing Totem")], + [31162] = totemData[string_lower("Searing Totem")], + [31164] = totemData[string_lower("Searing Totem")], + [31165] = totemData[string_lower("Searing Totem")], + [21995] = totemData[string_lower("Searing Totem")], + [22209] = totemData[string_lower("Searing Totem")], + [22895] = totemData[string_lower("Searing Totem")], + [22896] = totemData[string_lower("Searing Totem")], + [34687] = totemData[string_lower("Searing Totem")], + [36532] = totemData[string_lower("Searing Totem")], + [43423] = totemData[string_lower("Searing Totem")], + [67380] = totemData[string_lower("Searing Totem")], + [73477] = totemData[string_lower("Searing Totem")], + [79238] = totemData[string_lower("Searing Totem")], + [22896] = totemData[string_lower("Searing Totem")], + [84519] = totemData[string_lower("Searing Totem")], + [110730] = totemData[string_lower("Searing Totem")], + [132178] = totemData[string_lower("Searing Totem")], + + [5950] = totemData[string_lower("Flametongue Totem")], + [6012] = totemData[string_lower("Flametongue Totem")], + [7423] = totemData[string_lower("Flametongue Totem")], + [10557] = totemData[string_lower("Flametongue Totem")], + [15485] = totemData[string_lower("Flametongue Totem")], + [31132] = totemData[string_lower("Flametongue Totem")], + [31133] = totemData[string_lower("Flametongue Totem")], + [31158] = totemData[string_lower("Flametongue Totem")], + [42605] = totemData[string_lower("Flametongue Totem")], + + [5929] = totemData[string_lower("Magma Totem")], + [7464] = totemData[string_lower("Magma Totem")], + [7465] = totemData[string_lower("Magma Totem")], + [7466] = totemData[string_lower("Magma Totem")], + [15484] = totemData[string_lower("Magma Totem")], + [31166] = totemData[string_lower("Magma Totem")], + [31167] = totemData[string_lower("Magma Totem")], + [32887] = totemData[string_lower("Magma Totem")], + [42211] = totemData[string_lower("Magma Totem")], + [71335] = totemData[string_lower("Magma Totem")], + [71925] = totemData[string_lower("Magma Totem")], + [73085] = totemData[string_lower("Magma Totem")], + [73093] = totemData[string_lower("Magma Totem")], + [73268] = totemData[string_lower("Magma Totem")], + [88971] = totemData[string_lower("Magma Totem")], + [97369] = totemData[string_lower("Magma Totem")], + [98676] = totemData[string_lower("Magma Totem")], + + [5879] = totemData[string_lower("Fire Nova Totem")], + [6110] = totemData[string_lower("Fire Nova Totem")], + [6111] = totemData[string_lower("Fire Nova Totem")], + [7844] = totemData[string_lower("Fire Nova Totem")], + [7845] = totemData[string_lower("Fire Nova Totem")], + [14662] = totemData[string_lower("Fire Nova Totem")], + [15482] = totemData[string_lower("Fire Nova Totem")], + [15483] = totemData[string_lower("Fire Nova Totem")], + [24320] = totemData[string_lower("Fire Nova Totem")], + [32775] = totemData[string_lower("Fire Nova Totem")], + [32776] = totemData[string_lower("Fire Nova Totem")], + + [17539] = totemData[string_lower("Totem of Wrath")], + [22970] = totemData[string_lower("Totem of Wrath")], + [22971] = totemData[string_lower("Totem of Wrath")], + [30652] = totemData[string_lower("Totem of Wrath")], + [30653] = totemData[string_lower("Totem of Wrath")], + [30654] = totemData[string_lower("Totem of Wrath")], + + [15439] = totemData[string_lower("Fire Elemental Totem")], + [40830] = totemData[string_lower("Fire Elemental Totem")], + [41337] = totemData[string_lower("Fire Elemental Totem")], + [41346] = totemData[string_lower("Fire Elemental Totem")], + [72301] = totemData[string_lower("Fire Elemental Totem")], + + [5926] = totemData[string_lower("Frost Resistance Totem")], + [7412] = totemData[string_lower("Frost Resistance Totem")], + [7413] = totemData[string_lower("Frost Resistance Totem")], + [15486] = totemData[string_lower("Frost Resistance Totem")], + [31171] = totemData[string_lower("Frost Resistance Totem")], + [31172] = totemData[string_lower("Frost Resistance Totem")], + + -- Water + [5927] = totemData[string_lower("Fire Resistance Totem")], + [7424] = totemData[string_lower("Fire Resistance Totem")], + [7425] = totemData[string_lower("Fire Resistance Totem")], + [15487] = totemData[string_lower("Fire Resistance Totem")], + [31169] = totemData[string_lower("Fire Resistance Totem")], + [31170] = totemData[string_lower("Fire Resistance Totem")], + + [5923] = totemData[string_lower("Poison Cleansing Totem")], + [22487] = totemData[string_lower("Poison Cleansing Totem")], + + [5924] = totemData[string_lower("Disease Cleansing Totem")], + + [3527] = totemData[string_lower("Healing Stream Totem")], + [3906] = totemData[string_lower("Healing Stream Totem")], + [3907] = totemData[string_lower("Healing Stream Totem")], + [3908] = totemData[string_lower("Healing Stream Totem")], + [3909] = totemData[string_lower("Healing Stream Totem")], + [14664] = totemData[string_lower("Healing Stream Totem")], + [15488] = totemData[string_lower("Healing Stream Totem")], + [18235] = totemData[string_lower("Healing Stream Totem")], + [31181] = totemData[string_lower("Healing Stream Totem")], + [31182] = totemData[string_lower("Healing Stream Totem")], + [31185] = totemData[string_lower("Healing Stream Totem")], + [34686] = totemData[string_lower("Healing Stream Totem")], + [36542] = totemData[string_lower("Healing Stream Totem")], + [37810] = totemData[string_lower("Healing Stream Totem")], + [38428] = totemData[string_lower("Healing Stream Totem")], + [47077] = totemData[string_lower("Healing Stream Totem")], + [72309] = totemData[string_lower("Healing Stream Totem")], + [72457] = totemData[string_lower("Healing Stream Totem")], + [73890] = totemData[string_lower("Healing Stream Totem")], + [74433] = totemData[string_lower("Healing Stream Totem")], + [97508] = totemData[string_lower("Healing Stream Totem")], + [112567] = totemData[string_lower("Healing Stream Totem")], + [120357] = totemData[string_lower("Healing Stream Totem")], + [128539] = totemData[string_lower("Healing Stream Totem")], + [132049] = totemData[string_lower("Healing Stream Totem")], + + [10467] = totemData[string_lower("Mana Tide Totem")], + [11100] = totemData[string_lower("Mana Tide Totem")], + [11101] = totemData[string_lower("Mana Tide Totem")], + [17061] = totemData[string_lower("Mana Tide Totem")], + + [3573] = totemData[string_lower("Mana Spring Totem")], + [7414] = totemData[string_lower("Mana Spring Totem")], + [7415] = totemData[string_lower("Mana Spring Totem")], + [7416] = totemData[string_lower("Mana Spring Totem")], + [15304] = totemData[string_lower("Mana Spring Totem")], + [15489] = totemData[string_lower("Mana Spring Totem")], + [31186] = totemData[string_lower("Mana Spring Totem")], + [31189] = totemData[string_lower("Mana Spring Totem")], + [31190] = totemData[string_lower("Mana Spring Totem")], + + -- Earth + [2630] = totemData[string_lower("Earthbind Totem")], + [22486] = totemData[string_lower("Earthbind Totem")], + [40233] = totemData[string_lower("Earthbind Totem")], + [74737] = totemData[string_lower("Earthbind Totem")], + [79155] = totemData[string_lower("Earthbind Totem")], + + [3579] = totemData[string_lower("Stoneclaw Totem")], + [3911] = totemData[string_lower("Stoneclaw Totem")], + [3912] = totemData[string_lower("Stoneclaw Totem")], + [3913] = totemData[string_lower("Stoneclaw Totem")], + [7398] = totemData[string_lower("Stoneclaw Totem")], + [7399] = totemData[string_lower("Stoneclaw Totem")], + [14870] = totemData[string_lower("Stoneclaw Totem")], + [15478] = totemData[string_lower("Stoneclaw Totem")], + [31120] = totemData[string_lower("Stoneclaw Totem")], + [31121] = totemData[string_lower("Stoneclaw Totem")], + [31122] = totemData[string_lower("Stoneclaw Totem")], + [40258] = totemData[string_lower("Stoneclaw Totem")], + [102402] = totemData[string_lower("Stoneclaw Totem")], + + [5873] = totemData[string_lower("Stoneskin Totem")], + [5919] = totemData[string_lower("Stoneskin Totem")], + [5920] = totemData[string_lower("Stoneskin Totem")], + [7366] = totemData[string_lower("Stoneskin Totem")], + [7367] = totemData[string_lower("Stoneskin Totem")], + [7368] = totemData[string_lower("Stoneskin Totem")], + [14663] = totemData[string_lower("Stoneskin Totem")], + [15470] = totemData[string_lower("Stoneskin Totem")], + [15474] = totemData[string_lower("Stoneskin Totem")], + [18177] = totemData[string_lower("Stoneskin Totem")], + [21994] = totemData[string_lower("Stoneskin Totem")], + [31175] = totemData[string_lower("Stoneskin Totem")], + [31176] = totemData[string_lower("Stoneskin Totem")], + [36550] = totemData[string_lower("Stoneskin Totem")], + [40267] = totemData[string_lower("Stoneskin Totem")], + [41967] = totemData[string_lower("Stoneskin Totem")], + + [5874] = totemData[string_lower("Strength of Earth Totem")], + [5921] = totemData[string_lower("Strength of Earth Totem")], + [5922] = totemData[string_lower("Strength of Earth Totem")], + [7403] = totemData[string_lower("Strength of Earth Totem")], + [15464] = totemData[string_lower("Strength of Earth Totem")], + [15479] = totemData[string_lower("Strength of Earth Totem")], + [21992] = totemData[string_lower("Strength of Earth Totem")], + [30647] = totemData[string_lower("Strength of Earth Totem")], + [31129] = totemData[string_lower("Strength of Earth Totem")], + [40266] = totemData[string_lower("Strength of Earth Totem")], + + [15430] = totemData[string_lower("Earth Elemental Totem")], + [24649] = totemData[string_lower("Earth Elemental Totem")], + [39387] = totemData[string_lower("Earth Elemental Totem")], + [40247] = totemData[string_lower("Earth Elemental Totem")], + [72307] = totemData[string_lower("Earth Elemental Totem")], + + [5913] = totemData[string_lower("Tremor Totem")], + [41938] = totemData[string_lower("Tremor Totem")], + [41939] = totemData[string_lower("Tremor Totem")], + + -- Air + [5925] = totemData[string_lower("Grounding Totem")], + [128537] = totemData[string_lower("Grounding Totem")], + [136251] = totemData[string_lower("Grounding Totem")], + + [7486] = totemData[string_lower("Grace of Air Totem")], + [7487] = totemData[string_lower("Grace of Air Totem")], + [15463] = totemData[string_lower("Grace of Air Totem")], + + [7467] = totemData[string_lower("Nature Resistance Totem")], + [7468] = totemData[string_lower("Nature Resistance Totem")], + [7469] = totemData[string_lower("Nature Resistance Totem")], + [15490] = totemData[string_lower("Nature Resistance Totem")], + [31173] = totemData[string_lower("Nature Resistance Totem")], + [31174] = totemData[string_lower("Nature Resistance Totem")], + + [6112] = totemData[string_lower("Windfury Totem")], + [7483] = totemData[string_lower("Windfury Totem")], + [7484] = totemData[string_lower("Windfury Totem")], + [14666] = totemData[string_lower("Windfury Totem")], + [15496] = totemData[string_lower("Windfury Totem")], + [15497] = totemData[string_lower("Windfury Totem")], + [22897] = totemData[string_lower("Windfury Totem")], + [41940] = totemData[string_lower("Windfury Totem")], + [41941] = totemData[string_lower("Windfury Totem")], + [80703] = totemData[string_lower("Windfury Totem")], + [105690] = totemData[string_lower("Windfury Totem")], + [133684] = totemData[string_lower("Windfury Totem")], + + [3968] = totemData[string_lower("Sentry Totem")], + [28938] = totemData[string_lower("Sentry Totem")], + [40187] = totemData[string_lower("Sentry Totem")], + [69505] = totemData[string_lower("Sentry Totem")], + [70413] = totemData[string_lower("Sentry Totem")], + [71145] = totemData[string_lower("Sentry Totem")], + [147410] = totemData[string_lower("Sentry Totem")], + + [9687] = totemData[string_lower("Windwall Totem")], + [9688] = totemData[string_lower("Windwall Totem")], + [9689] = totemData[string_lower("Windwall Totem")], + [15492] = totemData[string_lower("Windwall Totem")], + + [15447] = totemData[string_lower("Wrath of Air Totem")], + [36556] = totemData[string_lower("Wrath of Air Totem")], + + [15803] = totemData[string_lower("Tranquil Air Totem")], +} + +function Gladdy:GetTotemData() + return totemData, totemNpcIdsToTotemData, totemSpellIdToPulse +end + diff --git a/Modules/TotemPlates.lua b/Modules/TotemPlates.lua index 5570b97..8c1a0ee 100644 --- a/Modules/TotemPlates.lua +++ b/Modules/TotemPlates.lua @@ -1,103 +1,29 @@ -local select, pairs, string_lower, tremove, tinsert, format, string_gsub, ipairs = select, pairs, string.lower, tremove, tinsert, format, string.gsub, ipairs -local UnitExists, UnitIsUnit, UnitName, UnitIsEnemy = UnitExists, UnitIsUnit, UnitName, UnitIsEnemy +local select, pairs, tremove, tinsert, format, strsplit, tonumber, ipairs = select, pairs, tremove, tinsert, format, strsplit, tonumber, ipairs +local UnitExists, UnitIsUnit, UnitIsEnemy, UnitGUID = UnitExists, UnitIsUnit, UnitIsEnemy, UnitGUID local C_NamePlate = C_NamePlate local Gladdy = LibStub("Gladdy") local L = Gladdy.L local GetSpellInfo, CreateFrame = GetSpellInfo, CreateFrame +local totemData, npcIdToTotemData = Gladdy:GetTotemData() --------------------------------------------------- --- Constants +-- Option Helpers --------------------------------------------------- -local totemData = { - -- Fire - [string_lower("Searing Totem")] = {id = 3599,texture = select(3, GetSpellInfo(3599)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Searing Totem - [string_lower("Flametongue Totem")] = {id = 8227,texture = select(3, GetSpellInfo(8227)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Flametongue Totem - [string_lower("Magma Totem")] = {id = 8190,texture = select(3, GetSpellInfo(8190)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Magma Totem - [string_lower("Fire Nova Totem")] = {id = 1535,texture = select(3, GetSpellInfo(1535)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Fire Nova Totem - [string_lower("Totem of Wrath")] = {id = 30706,texture = select(3, GetSpellInfo(30706)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 1}, -- Totem of Wrath - [string_lower("Fire Elemental Totem")] = {id = 32982,texture = select(3, GetSpellInfo(32982)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Fire Elemental Totem - [string_lower("Frost Resistance Totem")] = {id = 8181,texture = select(3, GetSpellInfo(8181)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Frost Resistance Totem - -- Water - [string_lower("Fire Resistance Totem")] = {id = 8184,texture = select(3, GetSpellInfo(8184)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Fire Resistance Totem - [string_lower("Poison Cleansing Totem")] = {id = 8166,texture = select(3, GetSpellInfo(8166)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Poison Cleansing Totem - [string_lower("Disease Cleansing Totem")] = {id = 8170,texture = select(3, GetSpellInfo(8170)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Disease Cleansing Totem - [string_lower("Healing Stream Totem")] = {id = 5394,texture = select(3, GetSpellInfo(5394)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Healing Stream Totem - [string_lower("Mana Tide Totem")] = {id = 16190,texture = select(3, GetSpellInfo(16190)), color = {r = 0.078, g = 0.9, b = 0.16, a = 1}, enabled = true, priority = 3}, -- Mana Tide Totem - [string_lower("Mana Spring Totem")] = {id = 5675,texture = select(3, GetSpellInfo(5675)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 1}, -- Mana Spring Totem - -- Earth - [string_lower("Earthbind Totem")] = {id = 2484,texture = select(3, GetSpellInfo(2484)), color = {r = 0.5, g = 0.5, b = 0.5, a = 1}, enabled = true, priority = 1}, -- Earthbind Totem - [string_lower("Stoneclaw Totem")] = {id = 5730,texture = select(3, GetSpellInfo(5730)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Stoneclaw Totem - [string_lower("Stoneskin Totem")] = {id = 8071,texture = select(3, GetSpellInfo(8071)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Stoneskin Totem - [string_lower("Strength of Earth Totem")] = {id = 8075,texture = select(3, GetSpellInfo(8075)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Strength of Earth Totem - [string_lower("Earth Elemental Totem")] = {id = 33663,texture = select(3, GetSpellInfo(33663)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Earth Elemental Totem - [string_lower("Tremor Totem")] = {id = 8143,texture = select(3, GetSpellInfo(8143)), color = {r = 1, g = 0.9, b = 0.1, a = 1}, enabled = true, priority = 3}, -- Tremor Totem - -- Air - [string_lower("Grounding Totem")] = {id = 8177,texture = select(3, GetSpellInfo(8177)), color = {r = 0, g = 0.53, b = 0.92, a = 1}, enabled = true, priority = 3}, -- Grounding Totem - [string_lower("Grace of Air Totem")] = {id = 8835,texture = select(3, GetSpellInfo(8835)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Grace of Air Totem - [string_lower("Nature Resistance Totem")] = {id = 10595,texture = select(3, GetSpellInfo(10595)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Nature Resistance Totem - [string_lower("Windfury Totem")] = {id = 8512,texture = select(3, GetSpellInfo(8512)), color = {r = 0.96, g = 0, b = 0.07, a = 1}, enabled = true, priority = 2}, -- Windfury Totem - [string_lower("Sentry Totem")] = {id = 6495, texture = select(3, GetSpellInfo(6495)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Sentry Totem - [string_lower("Windwall Totem")] = {id = 15107,texture = select(3, GetSpellInfo(15107)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Windwall Totem - [string_lower("Wrath of Air Totem")] = {id = 3738,texture = select(3, GetSpellInfo(3738)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Wrath of Air Totem - [string_lower("Tranquil Air Totem")] = {id = 25908,texture = select(3, GetSpellInfo(25908)), color = {r = 0, g = 0, b = 0, a = 1}, enabled = true, priority = 0}, -- Tranquil Air Totem -} -local localizedTotemData = { - ["default"] = { - [string_lower(select(1, GetSpellInfo(3599)))] = totemData[string_lower("Searing Totem")], -- Searing Totem - [string_lower(select(1, GetSpellInfo(8227)))] = totemData[string_lower("Flametongue Totem")], -- Flametongue Totem - [string_lower(select(1, GetSpellInfo(8190)))] = totemData[string_lower("Magma Totem")], -- Magma Totem - [string_lower(select(1, GetSpellInfo(1535)))] = totemData[string_lower("Fire Nova Totem")], -- Fire Nova Totem - [string_lower(select(1, GetSpellInfo(30706)))] = totemData[string_lower("Totem of Wrath")], -- Totem of Wrath - [string_lower(select(1, GetSpellInfo(32982)))] = totemData[string_lower("Fire Elemental Totem")], -- Fire Elemental Totem - [string_lower(select(1, GetSpellInfo(8181)))] = totemData[string_lower("Frost Resistance Totem")], -- Frost Resistance Totem - -- Water - [string_lower(select(1, GetSpellInfo(8184)))] = totemData[string_lower("Fire Resistance Totem")], -- Fire Resistance Totem - [string_lower(select(1, GetSpellInfo(8166)))] = totemData[string_lower("Poison Cleansing Totem")], -- Poison Cleansing Totem - [string_lower(select(1, GetSpellInfo(8170)))] = totemData[string_lower("Disease Cleansing Totem")], -- Disease Cleansing Totem - [string_lower(select(1, GetSpellInfo(5394)))] = totemData[string_lower("Healing Stream Totem")], -- Healing Stream Totem - [string_lower(select(1, GetSpellInfo(16190)))] = totemData[string_lower("Mana Tide Totem")], -- Mana Tide Totem - [string_lower(select(1, GetSpellInfo(5675)))] = totemData[string_lower("Mana Spring Totem")], -- Mana Spring Totem - -- Earth - [string_lower(select(1, GetSpellInfo(2484)))] = totemData[string_lower("Earthbind Totem")], -- Earthbind Totem - [string_lower(select(1, GetSpellInfo(5730)))] = totemData[string_lower("Stoneclaw Totem")], -- Stoneclaw Totem - [string_lower(select(1, GetSpellInfo(8071)))] = totemData[string_lower("Stoneskin Totem")], -- Stoneskin Totem - [string_lower(select(1, GetSpellInfo(8075)))] = totemData[string_lower("Strength of Earth Totem")], -- Strength of Earth Totem - [string_lower(select(1, GetSpellInfo(33663)))] = totemData[string_lower("Earth Elemental Totem")], -- Earth Elemental Totem - [string_lower(select(1, GetSpellInfo(8143)))] = totemData[string_lower("Tremor Totem")], -- Tremor Totem - -- Air - [string_lower(select(1, GetSpellInfo(8177)))] = totemData[string_lower("Grounding Totem")], -- Grounding Totem - [string_lower(select(1, GetSpellInfo(8835)))] = totemData[string_lower("Grace of Air Totem")], -- Grace of Air Totem - [string_lower(select(1, GetSpellInfo(10595)))] = totemData[string_lower("Nature Resistance Totem")], -- Nature Resistance Totem - [string_lower(select(1, GetSpellInfo(8512)))] = totemData[string_lower("Windfury Totem")], -- Windfury Totem - [string_lower(select(1, GetSpellInfo(6495)))] = totemData[string_lower("Sentry Totem")], -- Sentry Totem - [string_lower(select(1, GetSpellInfo(15107)))] = totemData[string_lower("Windwall Totem")], -- Windwall Totem - [string_lower(select(1, GetSpellInfo(3738)))] = totemData[string_lower("Wrath of Air Totem")], -- Wrath of Air Totem - [string_lower(select(1, GetSpellInfo(25908)))] = totemData[string_lower("Tranquil Air Totem")], -- Tranquil Air Totem - }, - ["frFR"] = { - [string_lower("Totem d'\195\169lementaire de terre")] = totemData[string_lower("Earth Elemental Totem")], -- Earth Elemental Totem - [string_lower("Totem d'\195\169lementaire de feu")] = totemData[string_lower("Fire Elemental Totem")], -- Fire Elemental Totem - }, - ["ruRU"] = { - [string_lower("")] = totemData[string_lower("Sentry Totem")], -- Sentry Totem - } -} - local function GetTotemColorDefaultOptions() local defaultDB = {} local options = {} local indexedList = {} for k,v in pairs(totemData) do - tinsert(indexedList, {name = k, id = v.id, color = v.color, texture = v.texture, enabled = v.enabled}) + tinsert(indexedList, {name = k, id = v.id, color = v.color, texture = v.texture}) end table.sort(indexedList, function (a, b) return a.name < b.name end) for i=1,#indexedList do - defaultDB["totem" .. indexedList[i].id] = {color = indexedList[i].color, enabled = indexedList[i].enabled, alpha = 0.6, customText = ""} + defaultDB["totem" .. indexedList[i].id] = {color = indexedList[i].color, enabled = true, alpha = 0.6, customText = ""} options["npTotemsHideDisabledTotems"] = { order = 1, name = L["Hide Disabled Totem Plates"], @@ -186,17 +112,13 @@ local function GetTotemColorDefaultOptions() return defaultDB, options, indexedList end -function Gladdy:GetTotemColors() - return GetTotemColorDefaultOptions() -end - --------------------------------------------------- -- Core --------------------------------------------------- -local TotemPlates = Gladdy:NewModule("Totem Plates", nil, { +local TotemPlates = Gladdy:NewModule("Totem Plates", 2, { npTotems = true, npTotemsShowFriendly = true, npTotemsShowEnemy = true, @@ -214,9 +136,6 @@ local TotemPlates = Gladdy:NewModule("Totem Plates", nil, { npTotemsHideDisabledTotems = false, }) -LibStub("AceHook-3.0"):Embed(TotemPlates) -LibStub("AceTimer-3.0"):Embed(TotemPlates) - function TotemPlates.OnEvent(self, event, ...) TotemPlates[event](self, ...) end @@ -225,19 +144,18 @@ function TotemPlates:Initialize() self.numChildren = 0 self.activeTotemNameplates = {} self.totemPlateCache = {} - self:RegisterEvent("PLAYER_ENTERING_WORLD") - self:RegisterEvent("NAME_PLATE_UNIT_ADDED") - self:RegisterEvent("NAME_PLATE_UNIT_REMOVED") - self:RegisterEvent("PLAYER_TARGET_CHANGED") - self:RegisterEvent("UNIT_NAME_UPDATE") - self:SetScript("OnEvent", TotemPlates.OnEvent) + if Gladdy.db.npTotems then + self:RegisterEvent("PLAYER_ENTERING_WORLD") + self:RegisterEvent("NAME_PLATE_UNIT_ADDED") + self:RegisterEvent("NAME_PLATE_UNIT_REMOVED") + self:RegisterEvent("PLAYER_TARGET_CHANGED") + self:SetScript("OnEvent", TotemPlates.OnEvent) + end if Gladdy.db.npTotems and Gladdy.db.npTotemsShowEnemy then - --GetCVar("nameplateShowEnemyTotems") - --SetCVar("nameplateShowEnemyTotems", true); + SetCVar("nameplateShowEnemyTotems", true); end if Gladdy.db.npTotems and Gladdy.db.npTotemsShowFriendly then - --GetCVar("nameplateShowFriendlyTotems") - --SetCVar("nameplateShowFriendlyTotems", true); + SetCVar("nameplateShowFriendlyTotems", true); end self.addon = "Blizzard" if (IsAddOnLoaded("Plater")) then @@ -261,17 +179,67 @@ function TotemPlates:Initialize() end end +--------------------------------------------------- + +-- Events + +--------------------------------------------------- + function TotemPlates:PLAYER_ENTERING_WORLD() self.numChildren = 0 self.activeTotemNameplates = {} end -function TotemPlates:Reset() - --self:CancelAllTimers() - --self:UnhookAll() +function TotemPlates:PLAYER_TARGET_CHANGED() + for k,nameplate in pairs(self.activeTotemNameplates) do + TotemPlates:SetTotemAlpha(nameplate.gladdyTotemFrame, k) + end end +function TotemPlates:NAME_PLATE_UNIT_ADDED(unitID) + self:OnUnitEvent(unitID) +end + +function TotemPlates:NAME_PLATE_UNIT_REMOVED(unitID) + local nameplate = C_NamePlate.GetNamePlateForUnit(unitID) + self.activeTotemNameplates[unitID] = nil + --self:ToggleAddon(nameplate, true) + if nameplate.gladdyTotemFrame then + nameplate.gladdyTotemFrame:Hide() + nameplate.gladdyTotemFrame:SetParent(nil) + tinsert(self.totemPlateCache, nameplate.gladdyTotemFrame) + nameplate.gladdyTotemFrame = nil + end +end + +--------------------------------------------------- + +-- Gladdy Call + +--------------------------------------------------- + function TotemPlates:UpdateFrameOnce() + if Gladdy.db.npTotems then + self:RegisterEvent("PLAYER_ENTERING_WORLD") + self:RegisterEvent("NAME_PLATE_UNIT_ADDED") + self:RegisterEvent("NAME_PLATE_UNIT_REMOVED") + self:RegisterEvent("PLAYER_TARGET_CHANGED") + self:SetScript("OnEvent", TotemPlates.OnEvent) + else + self:UnregisterEvent("PLAYER_ENTERING_WORLD") + self:UnregisterEvent("NAME_PLATE_UNIT_ADDED") + self:UnregisterEvent("NAME_PLATE_UNIT_REMOVED") + self:UnregisterEvent("PLAYER_TARGET_CHANGED") + self:SetScript("OnEvent", nil) + end + + if Gladdy.db.npTotems and Gladdy.db.npTotemsShowEnemy then + SetCVar("nameplateShowEnemyTotems", true); + end + if Gladdy.db.npTotems and Gladdy.db.npTotemsShowFriendly then + SetCVar("nameplateShowFriendlyTotems", true); + end + for k,nameplate in pairs(self.activeTotemNameplates) do local totemDataEntry = nameplate.gladdyTotemFrame.totemDataEntry nameplate.gladdyTotemFrame:SetWidth(Gladdy.db.npTotemPlatesSize * Gladdy.db.npTotemPlatesWidthFactor) @@ -398,11 +366,7 @@ function TotemPlates:GetAddonFrame(nameplate) end end -function TotemPlates:PLAYER_TARGET_CHANGED() - for k,nameplate in pairs(self.activeTotemNameplates) do - TotemPlates:SetTotemAlpha(nameplate.gladdyTotemFrame, k) - end -end + function TotemPlates:ToggleAddon(nameplate, show) local addonFrames = { self:GetAddonFrame(nameplate) } @@ -448,12 +412,14 @@ function TotemPlates:OnUnitEvent(unitID) self:ToggleAddon(nameplate, true) return end - local nameplateName = UnitName(unitID) - local totemName = string_gsub(nameplateName, "^%s+", "") --trim - totemName = string_gsub(totemName, "%s+$", "") --trim - totemName = string_gsub(totemName, "%s+[I,V,X]+$", "") --trim rank - totemName = string_lower(totemName) - local totemDataEntry = localizedTotemData["default"][totemName] or localizedTotemData["frFR"][totemName] or localizedTotemData["ruRU"][totemName] + local npcType, _, _, _, _, npcId = strsplit("-", UnitGUID(unitID)) + if npcType ~= "Creature" then + return + end + local totemDataEntry = npcIdToTotemData[tonumber(npcId)] + if not totemDataEntry then + return + end if totemDataEntry and Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].enabled then-- modify this nameplates if #self.totemPlateCache > 0 then nameplate.gladdyTotemFrame = tremove(self.totemPlateCache, #self.totemPlateCache) @@ -490,27 +456,6 @@ function TotemPlates:OnUnitEvent(unitID) end end -function TotemPlates:NAME_PLATE_UNIT_ADDED(...) - self:OnUnitEvent(...) -end - -function TotemPlates:UNIT_NAME_UPDATE(...) - self:OnUnitEvent(...) -end - -function TotemPlates:NAME_PLATE_UNIT_REMOVED(...) - local unitID = ... - local nameplate = C_NamePlate.GetNamePlateForUnit(unitID) - self.activeTotemNameplates[unitID] = nil - --self:ToggleAddon(nameplate, true) - if nameplate.gladdyTotemFrame then - nameplate.gladdyTotemFrame:Hide() - nameplate.gladdyTotemFrame:SetParent(nil) - tinsert(self.totemPlateCache, nameplate.gladdyTotemFrame) - nameplate.gladdyTotemFrame = nil - end -end - function TotemPlates:SetTotemAlpha(gladdyTotemFrame, unitID) local targetExists = UnitExists("target") local totemDataEntry = gladdyTotemFrame.totemDataEntry @@ -535,6 +480,64 @@ end --------------------------------------------------- +-- Test + +--------------------------------------------------- + +function TotemPlates:TestOnce() + if not self.testFrame then + self.testFrame = CreateFrame("Frame", nil, UIParent) + self.testFrame:SetWidth(1) + self.testFrame:SetHeight(32) + self.testFrame:SetPoint("CENTER", UIParent, "CENTER", 0, -140) + end + local totemDataEntry = npcIdToTotemData[5913] + self.testFrame:Show() + if not self.testFrame.gladdyTotemFrame then + if #self.totemPlateCache > 0 then + self.testFrame.gladdyTotemFrame = tremove(self.totemPlateCache, #self.totemPlateCache) + else + self:CreateTotemFrame(self.testFrame) + self.testFrame.gladdyTotemFrame:SetScript("OnHide", nil) + self.testFrame.gladdyTotemFrame:SetScript("OnUpdate", nil) + end + end + if Gladdy.db.npTotems then + self.testFrame.gladdyTotemFrame.unitID = "player" + self.testFrame.gladdyTotemFrame.totemDataEntry = totemDataEntry + self.testFrame.gladdyTotemFrame.parent = self.testFrame + self.testFrame.gladdyTotemFrame:SetParent(self.testFrame) + self.testFrame.gladdyTotemFrame:ClearAllPoints() + self.testFrame.gladdyTotemFrame:SetPoint("CENTER", self.testFrame, "CENTER", 0, 0) + self.testFrame.gladdyTotemFrame.totemIcon:SetTexture(totemDataEntry.texture) + self.testFrame.gladdyTotemFrame.totemBorder:SetVertexColor(Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].color.r, + Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].color.g, + Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].color.b, + Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].color.a) + self.testFrame.gladdyTotemFrame.totemName:SetText(Gladdy.db.npTotemColors["totem" .. totemDataEntry.id].customText or "") + self.testFrame.gladdyTotemFrame.parent = self.testFrame + self.testFrame.gladdyTotemFrame:Show() + self.activeTotemNameplates["player"] = self.testFrame + else + self.testFrame.gladdyTotemFrame:Hide() + end +end + +function TotemPlates:Reset() + if self.testFrame then + if self.testFrame.gladdyTotemFrame then + self.testFrame.gladdyTotemFrame:Hide() + self.testFrame.gladdyTotemFrame:SetParent(nil) + tinsert(self.totemPlateCache, self.testFrame.gladdyTotemFrame) + self.testFrame.gladdyTotemFrame = nil + end + self.testFrame:Hide() + self.activeTotemNameplates["player"] = nil + end +end + +--------------------------------------------------- + -- Interface options --------------------------------------------------- @@ -549,21 +552,23 @@ function TotemPlates:GetOptions() npTotems = Gladdy:option({ type = "toggle", name = L["Enabled"], - desc = L["Turns totem icons instead of nameplates on or off. (Requires reload)"], + desc = L["Turns totem icons instead of nameplates on or off."], order = 3, width = 0.9, }), npTotemsShowFriendly = Gladdy:option({ type = "toggle", name = L["Show friendly"], - desc = L["Turns totem icons instead of nameplates on or off. (Requires reload)"], + desc = L["Turns totem icons instead of nameplates on or off."], + disabled = function() return not Gladdy.db.npTotems end, order = 4, width = 0.65, }), npTotemsShowEnemy = Gladdy:option({ type = "toggle", name = L["Show enemy"], - desc = L["Turns totem icons instead of nameplates on or off. (Requires reload)"], + desc = L["Turns totem icons instead of nameplates on or off."], + disabled = function() return not Gladdy.db.npTotems end, order = 5, width = 0.6, }), @@ -571,6 +576,7 @@ function TotemPlates:GetOptions() type = "group", childGroups = "tree", name = L["Frame"], + disabled = function() return not Gladdy.db.npTotems end, order = 4, args = { icon = { @@ -765,7 +771,8 @@ function TotemPlates:GetOptions() name = L["Customize Totems"], type = "group", childGroups = "tree", - args = select(2, Gladdy:GetTotemColors()) + disabled = function() return not Gladdy.db.npTotems end, + args = select(2, GetTotemColorDefaultOptions()) }, } end \ No newline at end of file -- 2.39.5 From 27573b75306c789239dc7e92503866dbc205fc66 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:37:42 +0100 Subject: [PATCH 139/268] cooldown refactor + positioning --- Constants.lua | 55 ++++++-- Images/downarrow.blp | Bin 0 -> 2564 bytes Images/uparrow.blp | Bin 0 -> 2564 bytes Modules/Cooldowns.lua | 307 ++++++++++++++++++++++++++++++------------ 4 files changed, 268 insertions(+), 94 deletions(-) create mode 100644 Images/downarrow.blp create mode 100644 Images/uparrow.blp diff --git a/Constants.lua b/Constants.lua index 8df815c..3f39ba3 100644 --- a/Constants.lua +++ b/Constants.lua @@ -13,6 +13,34 @@ tbl_sort(Gladdy.CLASSES) Gladdy.RACES = {"Scourge", "BloodElf", "Tauren", "Orc", "Troll", "NightElf", "Draenei", "Human", "Gnome", "Dwarf"} tbl_sort(Gladdy.RACES) +local RACE_ICON_TCOORDS = { + ["HUMAN_MALE"] = {0, 0.125, 0, 0.25}, + ["DWARF_MALE"] = {0.125, 0.25, 0, 0.25}, + ["GNOME_MALE"] = {0.25, 0.375, 0, 0.25}, + ["NIGHTELF_MALE"] = {0.375, 0.5, 0, 0.25}, + + ["TAUREN_MALE"] = {0, 0.125, 0.25, 0.5}, + ["SCOURGE_MALE"] = {0.125, 0.25, 0.25, 0.5}, + ["TROLL_MALE"] = {0.25, 0.375, 0.25, 0.5}, + ["ORC_MALE"] = {0.375, 0.5, 0.25, 0.5}, + + ["HUMAN_FEMALE"] = {0, 0.125, 0.5, 0.75}, + ["DWARF_FEMALE"] = {0.125, 0.25, 0.5, 0.75}, + ["GNOME_FEMALE"] = {0.25, 0.375, 0.5, 0.75}, + ["NIGHTELF_FEMALE"] = {0.375, 0.5, 0.5, 0.75}, + + ["TAUREN_FEMALE"] = {0, 0.125, 0.75, 1.0}, + ["SCOURGE_FEMALE"] = {0.125, 0.25, 0.75, 1.0}, + ["TROLL_FEMALE"] = {0.25, 0.375, 0.75, 1.0}, + ["ORC_FEMALE"] = {0.375, 0.5, 0.75, 1.0}, + + ["BLOODELF_MALE"] = {0.5, 0.625, 0.25, 0.5}, + ["BLOODELF_FEMALE"] = {0.5, 0.625, 0.75, 1.0}, + + ["DRAENEI_MALE"] = {0.5, 0.625, 0, 0.25}, + ["DRAENEI_FEMALE"] = {0.5, 0.625, 0.5, 0.75}, +} + local specBuffs = { -- DRUID [GetSpellInfo(45283)] = L["Restoration"], -- Natural Perfection @@ -958,23 +986,28 @@ local cooldownList = { [19503] = 30, -- Scatter Shot [14327] = 30, -- Scare Beast [19263] = 300, -- Deterrence; not on BM but can't do 2 specs - [14311] = { cd = 30, -- Freezing Trap - sharedCD = { - [13809] = true, -- Frost Trap - [34600] = true, -- Snake Trap - }, - }, + + [13809] = { cd = 30, -- Frost Trap sharedCD = { [14311] = true, -- Freezing Trap [34600] = true, -- Snake Trap }, + icon = select(3, GetSpellInfo(14311)), + }, + [14311] = { cd = 30, -- Freezing Trap + sharedCD = { + [13809] = true, -- Frost Trap + [34600] = true, -- Snake Trap + }, + icon = select(3, GetSpellInfo(14311)), }, [34600] = { cd = 30, -- Snake Trap sharedCD = { [14311] = true, -- Freezing Trap [13809] = true, -- Frost Trap }, + icon = select(3, GetSpellInfo(14311)), }, [34490] = { cd = 20, spec = L["Marksmanship"], }, -- Silencing Shot [19386] = { cd = 60, spec = L["Survival"], }, -- Wyvern Sting @@ -1024,19 +1057,19 @@ local cooldownList = { }, ["NightElf"] = { - [2651] = { cd = 180, spec = L["Discipline"], }, -- Elune's Grace - [10797] = { cd = 30, spec = L["Discipline"], }, -- Star Shards + [2651] = { cd = 180, spec = L["Discipline"], class = "PRIEST"}, -- Elune's Grace + [10797] = { cd = 30, spec = L["Discipline"], class = "PRIEST"}, -- Star Shards }, ["Draenei"] = { - [32548] = { cd = 300, spec = L["Discipline"], }, -- Hymn of Hope + [32548] = { cd = 300, spec = L["Discipline"], class = "PRIEST"}, -- Hymn of Hope }, ["Human"] = { - [13908] = { cd = 600, spec = L["Discipline"], }, -- Desperate Prayer + [13908] = { cd = 600, spec = L["Discipline"], class = "PRIEST"}, -- Desperate Prayer }, ["Gnome"] = { }, ["Dwarf"] = { - [13908] = { cd = 600, spec = L["Discipline"], }, -- Desperate Prayer + [13908] = { cd = 600, spec = L["Discipline"], class = "PRIEST"}, -- Desperate Prayer }, } function Gladdy:GetCooldownList() diff --git a/Images/downarrow.blp b/Images/downarrow.blp new file mode 100644 index 0000000000000000000000000000000000000000..464f90c425313603346b6165e22ea5d2adf9bdd7 GIT binary patch literal 2564 zcmbtVeM}Tb6n}SM1RKfGHfc;S?46#~s%b3RXqw7_B9eaab)(p50$8c?N84x{+8Tot zFnci-L}_npWR!Ddr%rMW*IX9CVdfb%%704^%j;)S6pZ=Ox>SvftO&t@tsdE5~bx?D!(xSheZpUL28a_R50j;E`b@9#F@6lSG z65LDn7S4!=tVw@>{+jFt!XDEemP$;%BxEn&7iD{GKS#hkmmY?H_JV$IeizmY}G}ruD^1StlQ-q74LR~Dj{4Bi!iiki@ z`6giWk$3M^QO}gSgQ8wmzE^X03w&W*=J~=GQ)4O;4Iy3{{*wMxX)CG2p#G}#t3UtD zP8;ILiD$+BZF64~?IFAO|B(LVOR^NFsORC=MSfOX<%1a_PI&tFB0r8ob+(`V*{r{; z`)vThd#XNH*n=4-&;7Q*Wl7RM8uvhwu!kjYjo-m|7LS$h10q6!Z=z6#4 z_x%fHA3Rtt{S`CsKPx{G_V@oD5O&Kwg<^HC+b8ySbV+{8ezC`OlXznJ!OSly#{T7U z>2ICSiQgbm53%7$dlaWVC4LSbjRy~71xlb=L0;tVD^`2-e4%gf8cuLOb^m`xEn(ust4zpgGvI^!EWJx1NHh& zrKg#<3^fOub`2md@FKq)ZCx(NMtM^H;&REao%410{63ZH!*A(2=MjF6cSJ@F1*Xkw zZ{$NfFw_+Axo;}48u^+uAD&E1dg`H^XJotRM=BthwlGgJDyo~tr?&or=5jDg9Xc9YD$PG)sa^=(ES(5It zd>CDEeCHXXeq*c=yT;`T1}_^M@!tW@!zDJxRz$H4=0U6N7pxCsYuD%X<$X(|YMBDH zSy@?{=2I^jzwtv|RSw1`615K1Z+yc8vj^=bl_LE{z{6ZAzo!56YUx7_19S_u7 zbiM=IJeZ+j z1Um^=EyH{fx7y~48#uI8#)ITzgJCT^R#IJ(z$P{_+RWaRGrLP1tn%ZJ!as%8 zVD;EF& literal 0 HcmV?d00001 diff --git a/Images/uparrow.blp b/Images/uparrow.blp new file mode 100644 index 0000000000000000000000000000000000000000..421372b7c810453a844e162cc1f536fff565be44 GIT binary patch literal 2564 zcmbtVe@xV67=P}-0GsTnwseE|-r13)t`)Y)nsA_qE{h-DE81*RC{+H)rfW2;@l*G` zRpKw|4w;xi^S)e`8!P2ZG{isbZnO?IOHYZAH63J2E4PEU=Xu}n7x0#4^Lh93-sgRO ze4gidpW|{@6+UMI0CT*_q~J;WKrHTf+z9~vxQB7y!W}ykmG>j)4;a*ehh^H1+~yqN zzYF>{dq_-Womf@`?;`XkqM`f{Y%#&o~%&;#l^U zhIykaV*0aRa7z6govGP7UXYpw5MBoje^wjxH?z%HHldoY(ihN4dO8=4Jh_R^ie&#@ zvNv!}EaXl31N1cH?<4Hc?P0OR}Lk%_2|x zN0)x#B7ceLlHwV0jJSrM<*KYBI-J2%Wf?nGy z>BkrDCq#dfZwE!cjC==Iz9;a-F`4J%AH+pBLD zi1*B%0$~q&oI?A{0+%OB|H-(A5`{fH|I*kkjA!r|`A!fK3S>z=%eG4BT! z$~lu>RUO`^u?=Dq8U-RF$#{1{!=e zV8FP@W$9N1=yOk8>u`K#7yzmgIL7hjlzSxg_e1T722Fm zXNTXV(u&VT1IC!YLseC`yX#yjfQDGp5Ub6TdhL?xrnP%Jz|*LYG>$h$aJBoakheTP zKL)vJP4*+2U$FC*!`l=4-8Qrz7#QHhO{=Zb2KgxW%fF#Q@@tWAk~=a`A-J{idVL?KwxZ)^YY5NQtU4dpv0Ax zrBV1u1&zm~zTCD$+Ve)fZnu58+2jM*xONRQC9d)$87go=y{R)@1j1U22Qk=Q{5rT(bVO`D?K#{%REIUD!QXq`>PaH~8hS3*Yx_ zrxKqq&KPeAe}>Rq7F6KPYR07ZX|v()7`3#66?;L$0kGuNadtXcO$j6 1) then + local current = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + local next + for k,v in pairs(Gladdy.db.cooldownCooldownsOrder[class]) do + if v == current - 1 then + next = k + end + end + Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] - 1 + Gladdy.db.cooldownCooldownsOrder[class][next] = Gladdy.db.cooldownCooldownsOrder[class][next] + 1 + Gladdy.options.args["Cooldowns"].args.cooldowns.args[class].args[tostring(spellId)].order = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + Gladdy.options.args["Cooldowns"].args.cooldowns.args[class].args[next].order = Gladdy.db.cooldownCooldownsOrder[class][next] + Gladdy:UpdateFrame() + end + end, + }, + downarrow = { + type = "execute", + name = "", + order = 3, + width = 0.1, + image = "Interface\\Addons\\Gladdy\\Images\\downarrow", + imageWidth = 20, + imageHeight = 20, + func = function() + if (Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] < tblLength) then + local current = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + local next + for k,v in pairs(Gladdy.db.cooldownCooldownsOrder[class]) do + if v == current + 1 then + next = k + end + end + Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + 1 + Gladdy.db.cooldownCooldownsOrder[class][next] = Gladdy.db.cooldownCooldownsOrder[class][next] - 1 + Gladdy.options.args["Cooldowns"].args.cooldowns.args[class].args[tostring(spellId)].order = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + Gladdy.options.args["Cooldowns"].args.cooldowns.args[class].args[next].order = Gladdy.db.cooldownCooldownsOrder[class][next] + Gladdy:UpdateFrame() + end + end, + } + } } - o = o + 1 end p = p + i end for i,race in ipairs(Gladdy.RACES) do - group[race] = { - type = "group", - name = L[race], - order = i + p, - icon = "Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Races", - iconCoords = RACE_ICON_TCOORDS[upper(race) .. "_FEMALE"], - args = {} - } - local o = 1 for spellId,cooldown in pairs(Gladdy:GetCooldownList()[race]) do - group[race].args[tostring(spellId)] = { - type = "toggle", - name = select(1, GetSpellInfo(spellId)) .. (type(cooldown) == "table" and cooldown.spec and (" - " .. cooldown.spec) or ""), - order = o, - width = "full", - image = select(3, GetSpellInfo(spellId)), - get = function() - return Gladdy.db.cooldownCooldowns[tostring(spellId)] - end, - set = function(_, value) - Gladdy.db.cooldownCooldowns[tostring(spellId)] = value - Gladdy:UpdateFrame() - end + local tblLength = tableLength(Gladdy.db.cooldownCooldownsOrder[cooldown.class]) + local class = cooldown.class + group[class].args[tostring(spellId)] = { + name = "", + type = "group", + inline = true, + order = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)], + args = { + toggle = { + type = "toggle", + name = select(1, GetSpellInfo(spellId)) .. (type(cooldown) == "table" and cooldown.spec and (" - " .. cooldown.spec) or ""), + order = 1, + width = 1.1, + image = select(3, GetSpellInfo(spellId)), + get = function() + return Gladdy.db.cooldownCooldowns[tostring(spellId)] + end, + set = function(_, value) + Gladdy.db.cooldownCooldowns[tostring(spellId)] = value + Gladdy:UpdateFrame() + end + }, + uparrow = { + type = "execute", + name = "", + order = 2, + width = 0.1, + image = "Interface\\Addons\\Gladdy\\Images\\uparrow", + imageWidth = 20, + imageHeight = 20, + func = function() + if (Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] > 1) then + local current = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + local next + for k,v in pairs(Gladdy.db.cooldownCooldownsOrder[class]) do + if v == current - 1 then + next = k + end + end + Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] - 1 + Gladdy.db.cooldownCooldownsOrder[class][next] = Gladdy.db.cooldownCooldownsOrder[class][next] + 1 + Gladdy.options.args["Cooldowns"].args.cooldowns.args[class].args[tostring(spellId)].order = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + Gladdy.options.args["Cooldowns"].args.cooldowns.args[class].args[next].order = Gladdy.db.cooldownCooldownsOrder[class][next] + Gladdy:UpdateFrame() + end + end, + }, + downarrow = { + type = "execute", + name = "", + order = 3, + width = 0.1, + image = "Interface\\Addons\\Gladdy\\Images\\downarrow", + imageWidth = 20, + imageHeight = 20, + func = function() + if (Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] < tblLength) then + local current = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + local next + for k,v in pairs(Gladdy.db.cooldownCooldownsOrder[class]) do + if v == current + 1 then + next = k + end + end + Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + 1 + Gladdy.db.cooldownCooldownsOrder[class][next] = Gladdy.db.cooldownCooldownsOrder[class][next] - 1 + Gladdy.options.args["Cooldowns"].args.cooldowns.args[class].args[tostring(spellId)].order = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] + Gladdy.options.args["Cooldowns"].args.cooldowns.args[class].args[next].order = Gladdy.db.cooldownCooldownsOrder[class][next] + Gladdy:UpdateFrame() + end + end, + } + } } - o = o + 1 end end return group -- 2.39.5 From 907c64a864f33b97e0ff1648d2dec5da134f58ba Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:38:05 +0100 Subject: [PATCH 140/268] grouping first step --- Modules/Classicon.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index e20ce46..d9c476a 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -15,6 +15,8 @@ local Classicon = Gladdy:NewModule("Class Icon", 81, { classIconYOffset = 0, classIconFrameStrata = "MEDIUM", classIconFrameLevel = 5, + classIconGroup = false, + classIconGroupDirection = "RIGHT" }) local classIconPath = "Interface\\Addons\\Gladdy\\Images\\Classes\\" @@ -133,6 +135,14 @@ function Classicon:UpdateFrame(unit) Gladdy:SetPosition(classIcon, unit, "classIconXOffset", "classIconYOffset", Classicon:LegacySetPosition(classIcon, unit), Classicon) + if (Gladdy.db.classIconGroup) then + if (unit ~= "arena1") then + local previousUnit = "arena" .. string.gsub(unit, "arena", "") - 1 + self.frames[unit]:ClearAllPoints() + self.frames[unit]:SetPoint("LEFT", self.frames[previousUnit], "RIGHT", 0, 0) + end + end + if (unit == "arena1") then Gladdy:CreateMover(classIcon, "classIconXOffset", "classIconYOffset", L["Class Icon"], {"TOPLEFT", "TOPLEFT"}, -- 2.39.5 From b14406f75f2ac3d9674f63ac25c5f9437db18e7c Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:38:28 +0100 Subject: [PATCH 141/268] totempulse --- Modules/TotemPulse.lua | 641 +++++++++++++++++++++++++++++++---------- 1 file changed, 489 insertions(+), 152 deletions(-) diff --git a/Modules/TotemPulse.lua b/Modules/TotemPulse.lua index a2a49a9..6cc6c5e 100644 --- a/Modules/TotemPulse.lua +++ b/Modules/TotemPulse.lua @@ -1,57 +1,120 @@ +local select, pairs, tremove, tinsert, format, strsplit, tonumber = select, pairs, tremove, tinsert, format, strsplit, tonumber local C_NamePlate = C_NamePlate local Gladdy = LibStub("Gladdy") local L = Gladdy.L -local tremove, tinsert = tremove, tinsert local GetSpellInfo, CreateFrame = GetSpellInfo, CreateFrame -local GetTime, GetPlayerInfoByGUID, UnitIsEnemy, UnitGUID = GetTime, GetPlayerInfoByGUID, UnitIsEnemy, UnitGUID +local GetTime, UnitIsEnemy, UnitGUID = GetTime, UnitIsEnemy, UnitGUID local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo -local cooldowns = { - [2484] = 3, --Earthbind - [8143] = 4, -- Tremor - [8166] = 4, -- Poison Cleansing - [8170] = 4, -- Disease Cleansing - [1535] = { cd = 4, once = true }, -- Fire Nova 1 - [8498] = { cd = 4, once = true }, -- Fire Nova 2 - [8499] = { cd = 4, once = true }, -- Fire Nova 3 - [11314] = { cd = 4, once = true }, -- Fire Nova 4 - [11315] = { cd = 4, once = true }, -- Fire Nova 5 - [25546] = { cd = 4, once = true }, -- Fire Nova 6 - [25547] = { cd = 4, once = true }, -- Fire Nova 7 - [8190] = 2, -- Magma 1 - [10585] = 2, -- Magma 2 - [10586] = 2, -- Magma 3 - [10587] = 2, -- Magma 4 - [25552] = 2, -- Magma 5 - [5394] = 2, -- Healing Stream 1 - [6375] = 2, -- Healing Stream 2 - [6377] = 2, -- Healing Stream 3 - [10462] = 2, -- Healing Stream 4 - [10463] = 2, -- Healing Stream 5 - [25567] = 2, -- Healing Stream 6 - [5675] = 2, -- Mana Spring 1 - [10495] = 2, -- Mana Spring 2 - [10496] = 2, -- Mana Spring 3 - [10497] = 2, -- Mana Spring 4 - [25570] = 2, -- Mana Spring 5 -} +--------------------------------------------------- +-- Helper + +--------------------------------------------------- + +local totemData, npcIdToTotemData, cooldowns = Gladdy:GetTotemData() local ninetyDegreeInRad = 90 * math.pi / 180 +local function TotemOptions() + local defaultDB = {} + local options = {} + local indexedList = {} + for k,v in pairs(totemData) do + if v.pulse then + tinsert(indexedList, {name = k, id = v.id, color = v.color, texture = v.texture}) + end + end + table.sort(indexedList, function (a, b) + return a.name < b.name + end) + for i=1,#indexedList do + defaultDB["totem" .. indexedList[i].id] = {enabled = true, attachToGladdyTotemFrame = true, style = "COOLDOWN", reverse = false} + options["totem" .. indexedList[i].id] = { + order = i+1, + name = select(1, GetSpellInfo(indexedList[i].id)), + --inline = true, + width = "3.0", + type = "group", + icon = indexedList[i].texture, + args = { + headerTotemConfig = { + type = "header", + name = format("|T%s:20|t %s", indexedList[i].texture, select(1, GetSpellInfo(indexedList[i].id))), + order = 1, + }, + enabled = { + order = 2, + name = L["Enabled"], + desc = "Enable " .. format("|T%s:20|t %s", indexedList[i].texture, select(1, GetSpellInfo(indexedList[i].id))), + type = "toggle", + width = "full", + get = function() return Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].enabled end, + set = function(_, value) + Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].enabled = value + Gladdy:UpdateFrame() + end + }, + attachToGladdyTotemFrame = { + order = 3, + disabled = function() return not Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].enabled end, + name = L["Attach To TotemPlate"], + desc = "Attach " .. format("|T%s:20|t %s", indexedList[i].texture, select(1, GetSpellInfo(indexedList[i].id))) .. " To TotemPlate", + type = "toggle", + width = "full", + get = function() return Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].attachToGladdyTotemFrame end, + set = function(_, value) + Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].attachToGladdyTotemFrame = value + Gladdy:UpdateFrame() + end + }, + style = { + type = "select", + name = L["Style"], + order = 4, + values = { + COOLDOWN = L["Cooldown"], + Vertical = L["Bar vertical"], + Horizontal = L["Bar horizontal"] + }, + get = function() return Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].style end, + set = function(_, value) + Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].style = value + Gladdy:UpdateFrame() + end + }, + reverse = { + order = 5, + disabled = function() return not Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].enabled end, + name = L["Reverse"], + type = "toggle", + width = "full", + get = function() return Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].reverse end, + set = function(_, value) + Gladdy.dbi.profile.totemPulseTotems["totem" .. indexedList[i].id].reverse = value + Gladdy:UpdateFrame() + end + }, + } + } + end + return options,defaultDB +end + --------------------------------------------------- -- Core --------------------------------------------------- - -local TotemPulse = Gladdy:NewModule("Totem Pulse", nil, { +local TotemPulse = Gladdy:NewModule("Totem Pulse", 1, { totemPulseEnabled = true, totemPulseEnabledShowFriendly = true, totemPulseEnabledShowEnemy = true, - totemPulseAttachToTotemPlate = true, totemPulseStyle = "", -- "COOLDOWN", "COOLDOWNREVERSE", "BARVERTICAL", "BARHORIZONTAL" - totemPulseTextColor = { r = 1, g = 1, b = 1, a = 0 }, + --text + totemPulseTextColor = { r = 1, g = 1, b = 1, a = 1 }, + totemPulseTextSize = 14, + totemPulseTextFont = "DorisPP", --bar totemPulseBarWidth = 40, totemPulseBarHeight = 20, @@ -60,9 +123,15 @@ local TotemPulse = Gladdy:NewModule("Totem Pulse", nil, { totemPulseBarBorderColor = { r = 0, g = 0, b = 0, a = 1 }, totemPulseBarBorderSize = 5, totemPulseBarBorderStyle = "Gladdy Tooltip squared", - totemPulseBarTexture = "Smooth", + totemPulseBarTexture = "Flat", + totemPulseBarReverse = false, --cooldown + totemPulseCooldownWidth = 40, + totemPulseCooldownHeight = 20, totemPulseCooldownAlpha = 1, + totemPulseCooldownReverse = true, + --totems + totemPulseTotems = select(2, TotemOptions()) }) function TotemPulse.OnEvent(self, event, ...) @@ -70,16 +139,18 @@ function TotemPulse.OnEvent(self, event, ...) end function TotemPulse:Initialize() - self.cooldowns = cooldowns self.timeStamps = {} self.cooldownCache = {} self.barCache = {} self.activeFrames = { bars = {}, cooldowns = {} } - self:SetScript("OnEvent", self.OnEvent) - self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") - self:RegisterEvent("NAME_PLATE_UNIT_REMOVED") - self:RegisterEvent("NAME_PLATE_UNIT_ADDED") - self:RegisterEvent("UNIT_NAME_UPDATE") + if Gladdy.db.totemPulseEnabled then + self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") + self:RegisterEvent("NAME_PLATE_UNIT_REMOVED") + self:RegisterEvent("NAME_PLATE_UNIT_ADDED") + self:RegisterEvent("UNIT_NAME_UPDATE") + self:SetScript("OnEvent", self.OnEvent) + end + self:RegisterEvent("PLAYER_ENTERING_WORLD") end --------------------------------------------------- @@ -88,23 +159,46 @@ end --------------------------------------------------- +function TotemPulse:PLAYER_ENTERING_WORLD() + self.timeStamps = {} +end + function TotemPulse:COMBAT_LOG_EVENT_UNFILTERED() - local _,eventType,_,sourceGUID,_,_,_,destGUID,_,_,_,spellID,spellName,spellSchool,extraSpellId,extraSpellName,extraSpellSchool = CombatLogGetCurrentEventInfo() - print(eventType, spellName, spellID, destGUID) - if eventType == "SPELL_SUMMON" then - if cooldowns[spellID] then - print(eventType, spellName, spellID, GetPlayerInfoByGUID(sourceGUID)) - self.timeStamps[destGUID] = { timeStamp = GetTime(), spellID = spellID } - end - elseif eventType == "UNIT_DESTROYED" then + local _,eventType,_,sourceGUID,_,_,_,destGUID,_,_,_,spellID,spellName = CombatLogGetCurrentEventInfo() + local pulse = cooldowns[spellID] or cooldowns[spellName] + local npcId = tonumber(select(6, strsplit("-", destGUID)), 10) + if eventType == "UNIT_DESTROYED" and self.timeStamps[destGUID] then self.timeStamps[destGUID] = nil end + if (eventType == "SWING_DAMAGE" or eventType == "SPELL_DAMAGE") and self.timeStamps[destGUID] and npcIdToTotemData[npcId] then + self.timeStamps[destGUID] = nil + end + if not pulse then + return + end + if eventType == "SPELL_CAST_SUCCESS" then + self.timeStamps[sourceGUID] = { timeStamp = GetTime(), pulse = pulse } + end + if eventType == "SPELL_SUMMON" then + if not npcIdToTotemData[npcId] then + return + end + if not Gladdy.dbi.profile.totemPulseTotems["totem" .. npcIdToTotemData[npcId].id].enabled then + return + end + if self.timeStamps[sourceGUID] then + self.timeStamps[destGUID] = self.timeStamps[sourceGUID] + self.timeStamps[destGUID].id = npcIdToTotemData[npcId].id + self.timeStamps[sourceGUID] = nil + else + self.timeStamps[destGUID] = { timeStamp = GetTime(), pulse = pulse, id = npcIdToTotemData[npcId].id } + end + end end function TotemPulse:NAME_PLATE_UNIT_REMOVED(unitId) local nameplate = C_NamePlate.GetNamePlateForUnit(unitId) if nameplate.totemTick then - print("NAME_PLATE_UNIT_REMOVED", nameplate.totemTick) nameplate.totemTick:SetScript("OnUpdate", nil) nameplate.totemTick:Hide() nameplate.totemTick:SetParent(nil) @@ -123,16 +217,18 @@ function TotemPulse:UNIT_NAME_UPDATE(unitId) self:OnUnitAdded(unitId, "UNIT_NAME_UPDATE") end -function TotemPulse:OnUnitAdded(unitId, event) +function TotemPulse:OnUnitAdded(unitId) local isEnemy = UnitIsEnemy("player", unitId) local guid = UnitGUID(unitId) + if strsplit("-", guid) ~= "Creature" then + return + end local nameplate = C_NamePlate.GetNamePlateForUnit(unitId) - if nameplate then - print(event, self.timeStamps[guid], nameplate.totemTick) - if self.timeStamps[guid] then - self:AddTimerFrame(nameplate, self.timeStamps[guid], Gladdy.db.totemPulseAttachToTotemPlate and nameplate.gladdyTotemFrame) + if nameplate and (isEnemy and Gladdy.db.totemPulseEnabledShowEnemy or not isEnemy and Gladdy.db.totemPulseEnabledShowFriendly) then + if self.timeStamps[guid] and strsplit("-", guid) then + self:AddTimerFrame(nameplate, self.timeStamps[guid]) else if nameplate.totemTick then nameplate.totemTick:SetScript("OnUpdate", nil) @@ -153,35 +249,41 @@ end --------------------------------------------------- -function TotemPulse:CreateCooldownFrame(gladdyTotemFrame) +function TotemPulse:CreateCooldownFrame(style) local totemTick - if gladdyTotemFrame then + if style == "COOLDOWN" then if #self.cooldownCache > 0 then totemTick = tremove(self.cooldownCache, #self.cooldownCache) else - Gladdy:Print("TotemPulse:CreateCooldownFrame()", "CreateCooldown") - totemTick = CreateFrame("Cooldown", nil, nil, "CooldownFrameTemplate") - totemTick.noCooldownCount = true + totemTick = CreateFrame("Frame") + totemTick:SetWidth(Gladdy.db.totemPulseCooldownWidth) + totemTick:SetHeight(Gladdy.db.totemPulseCooldownHeight) + totemTick.cd = CreateFrame("Cooldown", nil, totemTick, "CooldownFrameTemplate") + totemTick.cd:SetAllPoints(totemTick) + totemTick.cd.noCooldownCount = true totemTick:SetFrameStrata("MEDIUM") totemTick:SetFrameLevel(4) - totemTick:SetReverse(true) - totemTick:SetHideCountdownNumbers(true) - totemTick:SetAlpha(Gladdy.db.totemPulseCooldownAlpha) + totemTick.cd:SetReverse(Gladdy.db.totemPulseCooldownReverse) + totemTick.cd:SetHideCountdownNumbers(true) + totemTick.cd:SetAlpha(Gladdy.db.totemPulseCooldownAlpha) - totemTick.text = totemTick:CreateFontString(nil, "OVERLAY") - totemTick.text:SetPoint("LEFT", totemTick, "LEFT", 4, 0) - totemTick.text:SetFont("Fonts\\FRIZQT__.TTF", 16, "OUTLINE") - totemTick.text:SetJustifyH("LEFT") + totemTick.textFrame = CreateFrame("Frame", nil, totemTick) + totemTick.textFrame:SetAllPoints(totemTick) + totemTick.text = totemTick.textFrame:CreateFontString(nil, "OVERLAY") + totemTick.text:SetPoint("CENTER", totemTick.textFrame, "CENTER") + totemTick.text:SetFont(Gladdy:SMFetch("font", "totemPulseTextFont"), Gladdy.db.totemPulseTextSize, "OUTLINE") + totemTick.text:SetJustifyH("CENTER") totemTick.text:SetShadowOffset(1, -1) totemTick.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) end else if #self.barCache > 0 then - Gladdy:Print("TotemPulse:CreateCooldownFrame()", #self.barCache) totemTick = tremove(self.barCache, #self.barCache) + totemTick.bar:SetOrientation(style) + totemTick.spark:SetRotation(style == "Vertical" and ninetyDegreeInRad or 0) + totemTick.spark:SetHeight(style == "Vertical" and Gladdy.db.totemPulseBarWidth or Gladdy.db.totemPulseBarHeight) else - Gladdy:Print("TotemPulse:CreateCooldownFrame()", "CreateBar") totemTick = CreateFrame("Frame", nil) totemTick:SetWidth(Gladdy.db.totemPulseBarWidth) @@ -193,24 +295,21 @@ function TotemPulse:CreateCooldownFrame(gladdyTotemFrame) edgeSize = Gladdy.db.totemPulseBarBorderSize }) totemTick.backdrop:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBorderColor)) totemTick.backdrop:SetFrameLevel(1) - --totemTick.backdrop:SetFrameStrata(Gladdy.db.castBarFrameStrata) - --totemTick.backdrop:SetFrameLevel(Gladdy.db.castBarFrameLevel - 1) totemTick.bar = CreateFrame("StatusBar", nil, totemTick) totemTick.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) totemTick.bar:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.totemPulseBarColor)) - totemTick.bar:SetOrientation("Vertical") + totemTick.bar:SetOrientation(style) totemTick.bar:SetFrameLevel(0) - totemTick.bar:SetPoint("TOPLEFT", totemTick, "TOPLEFT", (Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset)) - totemTick.bar:SetPoint("BOTTOMRIGHT", totemTick, "BOTTOMRIGHT", -(Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset)) + totemTick.bar:SetAllPoints(totemTick) totemTick.spark = totemTick.bar:CreateTexture(nil, "OVERLAY") totemTick.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark") totemTick.spark:SetBlendMode("ADD") totemTick.spark:SetWidth(8) - totemTick.spark:SetHeight(40) + totemTick.spark:SetHeight(style == "Vertical" and Gladdy.db.totemPulseBarWidth or Gladdy.db.totemPulseBarHeight) totemTick.spark.position = 0 - totemTick.spark:SetRotation(ninetyDegreeInRad) + totemTick.spark:SetRotation(style == "Vertical" and ninetyDegreeInRad or 0) totemTick.bg = totemTick.bar:CreateTexture(nil, "BACKGROUND") totemTick.bg:SetTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) @@ -218,9 +317,9 @@ function TotemPulse:CreateCooldownFrame(gladdyTotemFrame) totemTick.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBgColor)) totemTick.text = totemTick.bar:CreateFontString(nil, "OVERLAY") - totemTick.text:SetPoint("LEFT", totemTick, "LEFT", 4, 0) - totemTick.text:SetFont("Fonts\\FRIZQT__.TTF", 16, "OUTLINE") - totemTick.text:SetJustifyH("LEFT") + totemTick.text:SetPoint("CENTER", totemTick, "CENTER", 0, 0) + totemTick.text:SetFont(Gladdy:SMFetch("font", "totemPulseTextFont"), Gladdy.db.totemPulseTextSize, "OUTLINE") + totemTick.text:SetJustifyH("CENTER") totemTick.text:SetShadowOffset(1, -1) totemTick.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) end @@ -228,64 +327,52 @@ function TotemPulse:CreateCooldownFrame(gladdyTotemFrame) return totemTick end -function TotemPulse:AddTimerFrame(nameplate, timestamp, gladdyTotemFrame) - if nameplate:IsShown() and cooldowns[timestamp.spellID] then +function TotemPulse:AddTimerFrame(nameplate, timestamp, test) + if (nameplate:IsShown() or test) and timestamp then + local gladdyTotemFrame = Gladdy.db.totemPulseTotems["totem" .. timestamp.id].attachToGladdyTotemFrame and nameplate.gladdyTotemFrame if not nameplate.totemTick then - nameplate.totemTick = TotemPulse:CreateCooldownFrame(gladdyTotemFrame) + nameplate.totemTick = TotemPulse:CreateCooldownFrame(Gladdy.db.totemPulseTotems["totem" .. timestamp.id].style) end - nameplate.totemTick:SetParent(nameplate) - nameplate.totemTick:ClearAllPoints() - if gladdyTotemFrame then + nameplate.totemTick:SetParent(nameplate.gladdyTotemFrame or nameplate) + --nameplate.totemTick:ClearAllPoints() + --[[if gladdyTotemFrame then nameplate.totemTick:SetPoint("TOPLEFT", gladdyTotemFrame, "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) nameplate.totemTick:SetPoint("BOTTOMRIGHT", gladdyTotemFrame, "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) + if nameplate.totemTick.bar then + nameplate.totemTick.spark:SetHeight(Gladdy.db.totemPulseTotems["totem" .. timestamp.id].style == "Vertical" and gladdyTotemFrame:GetWidth() or gladdyTotemFrame:GetHeight()) + end else - nameplate.totemTick:SetPoint("TOP", nameplate, "BOTTOM") - end + nameplate.totemTick:SetPoint("TOP", nameplate.gladdyTotemFrame, "BOTTOM", 0, -5) + if nameplate.totemTick.bar then + nameplate.totemTick.spark:SetHeight(Gladdy.db.totemPulseTotems["totem" .. timestamp.id].style == "Vertical" and Gladdy.db.totemPulseBarWidth or Gladdy.db.totemPulseBarHeight) + end + end--]] - local cd = type(cooldowns[timestamp.spellID]) == "table" and cooldowns[timestamp.spellID].cd or cooldowns[timestamp.spellID] - local once = type(cooldowns[timestamp.spellID]) == "table" + local cd = type(timestamp.pulse) == "table" and timestamp.pulse.cd or timestamp.pulse + local once = type(timestamp.pulse) == "table" local cooldown = (timestamp.timeStamp - GetTime()) % cd - if not gladdyTotemFrame then - nameplate.totemTick.bar:SetMinMaxValues(0, cd) - nameplate.totemTick.bar:SetValue(cooldown) - self.activeFrames.bars[nameplate.totemTick] = nameplate.totemTick - else - self.activeFrames.cooldowns[nameplate.totemTick] = nameplate.totemTick - end - nameplate.totemTick.timestamp = timestamp.timeStamp nameplate.totemTick.maxValue = cd nameplate.totemTick.value = cooldown nameplate.totemTick.once = once + nameplate.totemTick.id = timestamp.id + + if nameplate.totemTick.bar then + self:UpdateBarPartial(nameplate.totemTick) + nameplate.totemTick.bar:SetMinMaxValues(0, cd) + nameplate.totemTick.bar:SetValue(cooldown) + self.activeFrames.bars[nameplate.totemTick] = nameplate.totemTick + else + self:UpdateCooldown(nameplate.totemTick) + self.activeFrames.cooldowns[nameplate.totemTick] = nameplate.totemTick + end - print("once", once, " - totemTick.once", nameplate.totemTick.once, " - cd off", math.abs(timestamp.timeStamp - GetTime()) > cd) if once and GetTime() - timestamp.timeStamp > cd then nameplate.totemTick:SetScript("OnUpdate", nil) nameplate.totemTick:Hide() - print("nameplate.totemTick:Hide()") else - nameplate.totemTick:SetScript("OnUpdate", function(totemTick, elapsed) - totemTick.now = GetTime() - totemTick.value = (totemTick.timestamp - totemTick.now) % totemTick.maxValue - if totemTick.once and totemTick.now - totemTick.timestamp >= totemTick.maxValue then - totemTick:SetScript("OnUpdate", nil) - print("OnUpdate totemTick:Hide()") - totemTick:Hide() - end - if not totemTick.bar and not (totemTick.once and totemTick.now - totemTick.timestamp >= totemTick.maxValue) then - totemTick:SetCooldown(totemTick.now - totemTick.value, totemTick.maxValue) - elseif totemTick.bar then - totemTick.spark.position = (totemTick.value / totemTick.maxValue) * totemTick.bar:GetHeight() - if ( totemTick.spark.position < 0 ) then - totemTick.spark.position = 0 - end - totemTick.spark:SetPoint("CENTER", totemTick.bar, "BOTTOM", 0, totemTick.spark.position) - totemTick.bar:SetValue(totemTick.value) - end - totemTick.text:SetFormattedText("%.1f", totemTick.value) - end) - print("nameplate.totemTick:Show()") + nameplate.totemTick:SetScript("OnUpdate", TotemPulse.TotemPulseOnUpdate) nameplate.totemTick:Show() end else @@ -301,39 +388,175 @@ function TotemPulse:AddTimerFrame(nameplate, timestamp, gladdyTotemFrame) end end -function TotemPulse:UpdateBar(bar) +function TotemPulse:SetSparkPosition(totemTick, referenceSize, vertical) + if not Gladdy.db.totemPulseTotems["totem" .. totemTick.id].reverse then + totemTick.bar:SetValue(totemTick.maxValue - totemTick.value) + totemTick.spark.position = referenceSize / 2 - (totemTick.value / totemTick.maxValue) * referenceSize + if ( totemTick.spark.position < -referenceSize / 2 ) then + totemTick.spark.position = -referenceSize / 2 + end + else + totemTick.bar:SetValue(totemTick.value) + totemTick.spark.position = referenceSize / 2 - ((totemTick.maxValue - totemTick.value) / totemTick.maxValue) * referenceSize + if ( totemTick.spark.position > referenceSize / 2 ) then + totemTick.spark.position = referenceSize / 2 + end + end + totemTick.spark:SetPoint("CENTER", totemTick.bar, "CENTER", vertical and 0 or totemTick.spark.position, vertical and totemTick.spark.position or 0) +end + +function TotemPulse.TotemPulseOnUpdate(totemTick) + totemTick.now = GetTime() + totemTick.value = (totemTick.timestamp - totemTick.now) % totemTick.maxValue + if totemTick.once and totemTick.now - totemTick.timestamp >= totemTick.maxValue then + totemTick:SetScript("OnUpdate", nil) + totemTick:Hide() + end + if not totemTick.bar and not (totemTick.once and totemTick.now - totemTick.timestamp >= totemTick.maxValue) then + if Gladdy.db.totemPulseTotems["totem" .. totemTick.id].reverse then + totemTick.cd:SetCooldown(totemTick.now - totemTick.value, totemTick.maxValue) + else + totemTick.cd:SetCooldown(totemTick.now - (totemTick.maxValue - totemTick.value), totemTick.maxValue) + end + elseif totemTick.bar then + if Gladdy.db.totemPulseTotems["totem" .. totemTick.id].style == "Vertical" then + TotemPulse:SetSparkPosition(totemTick, totemTick.bar:GetHeight(), true) + else + TotemPulse:SetSparkPosition(totemTick, totemTick.bar:GetWidth(), false) + end + end + totemTick.text:SetFormattedText("%.1f", totemTick.value) +end + +--------------------------------------------------- + +-- Update Styles + +--------------------------------------------------- + +function TotemPulse:UpdateBarPartial(bar) + local style = bar.id and Gladdy.db.totemPulseTotems["totem" .. bar.id].style + bar:SetWidth(Gladdy.db.totemPulseBarWidth) bar:SetHeight(Gladdy.db.totemPulseBarHeight) + bar.spark:SetWidth(8) + bar.spark:SetHeight(style == "Vertical" and Gladdy.db.totemPulseBarWidth or Gladdy.db.totemPulseBarHeight) + bar.spark:SetRotation(style == "Vertical" and ninetyDegreeInRad or 0) + + if (bar:GetParent()) then + if bar:GetParent().gladdyTotemFrame then + bar:SetParent(bar:GetParent().gladdyTotemFrame) + else + bar:SetParent(bar:GetParent()) + end + --[[if bar.id and Gladdy.db.totemPulseTotems["totem" .. bar.id].attachToGladdyTotemFrame then + if not bar:GetParent().totemIcon and bar:GetParent().gladdyTotemFrame then + bar:SetParent(bar:GetParent().gladdyTotemFrame) + end + elseif bar.id and not Gladdy.db.totemPulseTotems["totem" .. bar.id].attachToGladdyTotemFrame then + if bar:GetParent().totemIcon then + bar:SetParent(bar:GetParent():GetParent()) + end + end--]] + bar:ClearAllPoints() + if (bar.id and bar:GetParent().totemIcon and Gladdy.db.totemPulseTotems["totem" .. bar.id].attachToGladdyTotemFrame) then + bar:SetPoint("TOPLEFT", bar:GetParent(), "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) + bar:SetPoint("BOTTOMRIGHT", bar:GetParent(), "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) + if style then + bar.spark:SetHeight(style == "Vertical" and bar:GetParent():GetWidth() or bar:GetParent():GetHeight()) + end + else + bar:SetPoint("TOP", bar:GetParent(), "BOTTOM", 0, 0) + end + end + bar.bar:SetOrientation(style ~= "COOLDOWN" and style or bar.bar:GetOrientation()) +end + +function TotemPulse:UpdateBar(bar) + self:UpdateBarPartial(bar) + bar.backdrop:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "totemPulseBarBorderStyle"), edgeSize = Gladdy.db.totemPulseBarBorderSize }) bar.backdrop:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBorderColor)) bar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) bar.bar:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.totemPulseBarColor)) - bar.bar:SetOrientation("Vertical") - bar.bar:SetPoint("TOPLEFT", bar, "TOPLEFT", (Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset)) - bar.bar:SetPoint("BOTTOMRIGHT", bar, "BOTTOMRIGHT", -(Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.totemPulseBarBorderSize/Gladdy.db.statusbarBorderOffset)) - - bar.spark:SetWidth(8) - bar.spark:SetHeight(40) - bar.spark:SetRotation(ninetyDegreeInRad) + bar.bar:SetAllPoints(bar) bar.bg:SetTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) bar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBgColor)) - bar.text:SetFont("Fonts\\FRIZQT__.TTF", 16, "OUTLINE") + bar.text:SetFont(Gladdy:SMFetch("font", "totemPulseTextFont"), Gladdy.db.totemPulseTextSize, "OUTLINE") bar.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) end function TotemPulse:UpdateCooldown(cooldown) - cooldown:SetReverse(true) - cooldown:SetAlpha(Gladdy.db.totemPulseCooldownAlpha) - cooldown.text:SetFont("Fonts\\FRIZQT__.TTF", 16, "OUTLINE") + cooldown:SetWidth(Gladdy.db.totemPulseCooldownWidth) + cooldown:SetHeight(Gladdy.db.totemPulseCooldownHeight) + + if cooldown:GetParent() then + --[[if cooldown.id and Gladdy.db.totemPulseTotems["totem" .. cooldown.id].attachToGladdyTotemFrame then + if not cooldown:GetParent().totemIcon and cooldown:GetParent().gladdyTotemFrame then + cooldown:SetParent(cooldown:GetParent().gladdyTotemFrame) + end + elseif cooldown.id and not Gladdy.db.totemPulseTotems["totem" .. cooldown.id].attachToGladdyTotemFrame then + if cooldown:GetParent().totemIcon then + cooldown:SetParent(cooldown:GetParent():GetParent()) + end + end--]] + if cooldown:GetParent().gladdyTotemFrame then + cooldown:SetParent(cooldown:GetParent().gladdyTotemFrame) + else + cooldown:SetParent(cooldown:GetParent()) + end + cooldown:ClearAllPoints() + if cooldown.id and Gladdy.db.totemPulseTotems["totem" .. cooldown.id].attachToGladdyTotemFrame and cooldown:GetParent().totemIcon then + cooldown:SetPoint("TOPLEFT", cooldown:GetParent(), "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) + cooldown:SetPoint("BOTTOMRIGHT", cooldown:GetParent(), "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) + else + cooldown:SetPoint("TOP", cooldown:GetParent(), "BOTTOM", 0, -0.5) + end + end + + cooldown.cd:SetCooldown(0,0) + cooldown.cd:SetReverse(Gladdy.db.totemPulseCooldownReverse) + cooldown.cd:SetAlpha(Gladdy.db.totemPulseCooldownAlpha) + cooldown.text:SetFont(Gladdy:SMFetch("font", "totemPulseTextFont"), Gladdy.db.totemPulseTextSize, "OUTLINE") cooldown.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) end function TotemPulse:UpdateFrameOnce() + if Gladdy.frame.testing then + TotemPulse:TestOnce() + end + if Gladdy.db.totemPulseEnabled then + self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") + self:RegisterEvent("NAME_PLATE_UNIT_REMOVED") + self:RegisterEvent("NAME_PLATE_UNIT_ADDED") + self:RegisterEvent("UNIT_NAME_UPDATE") + self:SetScript("OnEvent", self.OnEvent) + else + for _,bar in pairs(self.activeFrames.bars) do + bar:SetScript("OnUpdate", nil) + bar:Hide() + bar:SetParent(nil) + tinsert(self.barCache, bar) + self.activeFrames.bars[bar] = nil + end + for _,cooldown in pairs(self.activeFrames.cooldowns) do + cooldown:SetScript("OnUpdate", nil) + cooldown:Hide() + cooldown:SetParent(nil) + tinsert(self.cooldownCache, cooldown) + self.activeFrames.cooldowns[cooldown] = nil + end + self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") + self:UnregisterEvent("NAME_PLATE_UNIT_REMOVED") + self:UnregisterEvent("NAME_PLATE_UNIT_ADDED") + self:UnregisterEvent("UNIT_NAME_UPDATE") + self:SetScript("OnEvent", nil) + end for _,bar in pairs(self.activeFrames.bars) do self:UpdateBar(bar) end @@ -354,6 +577,40 @@ end --------------------------------------------------- +function TotemPulse:TestOnce() + local totemPlatesTestFrame = Gladdy.modules["Totem Plates"].testFrame + if totemPlatesTestFrame then + if totemPlatesTestFrame.totemTick + and (Gladdy.db.totemPulseTotems["totem" .. npcIdToTotemData[5913].id].style == "COOLDOWN" and totemPlatesTestFrame.totemTick.bar + or Gladdy.db.totemPulseTotems["totem" .. npcIdToTotemData[5913].id].style ~= "COOLDOWN" and not totemPlatesTestFrame.totemTick.bar) then + totemPlatesTestFrame.totemTick:SetScript("OnUpdate", nil) + totemPlatesTestFrame.totemTick:Hide() + totemPlatesTestFrame.totemTick:SetParent(nil) + totemPlatesTestFrame.totemTick.id = nil + tinsert(totemPlatesTestFrame.totemTick.bar and self.barCache or self.cooldownCache, totemPlatesTestFrame.totemTick) + self.activeFrames.bars[totemPlatesTestFrame.totemTick] = nil + self.activeFrames.cooldowns[totemPlatesTestFrame.totemTick] = nil + totemPlatesTestFrame.totemTick = nil + end + + local timestamp = { timeStamp = GetTime(), pulse = npcIdToTotemData[5913].pulse, id = npcIdToTotemData[5913].id } + TotemPulse:AddTimerFrame(totemPlatesTestFrame, timestamp, true) + self.testFrame = totemPlatesTestFrame.totemTick + end +end + +function TotemPulse:Reset() + if self.testFrame then + self.testFrame:SetScript("OnUpdate", nil) + self.testFrame:Hide() + self.testFrame:SetParent(nil) + tinsert(self.testFrame.bar and self.barCache or self.cooldownCache, self.testFrame) + self.activeFrames.bars[self.testFrame] = nil + self.activeFrames.cooldowns[self.testFrame] = nil + self.testFrame = nil + Gladdy.modules["Totem Plates"].testFrame.totemTick = nil + end +end --------------------------------------------------- @@ -373,32 +630,28 @@ function TotemPulse:GetOptions() name = L["Totem Pulse Enabled"], order = 3, }), - totemPulseAttachToTotemPlate = Gladdy:option({ - type = "toggle", - name = L["Attach to Totem Plates"], - order = 4, - }), group = { type = "group", childGroups = "tree", name = L["Frame"], order = 4, + disabled = function() return not Gladdy.db.totemPulseEnabled end, args = { barFrame = { type = "group", name = L["Bar"], - order = 1, + order = 2, args = { headerSize = { type = "header", - name = L["Bar Size"], - order = 1, + name = L["Size"], + order = 10, }, totemPulseBarHeight = Gladdy:option({ type = "range", name = L["Bar height"], desc = L["Height of the bar"], - order = 3, + order = 11, min = 0.1, max = 200, step = .1, @@ -407,8 +660,8 @@ function TotemPulse:GetOptions() totemPulseBarWidth = Gladdy:option({ type = "range", name = L["Bar width"], - desc = L["Width of the bars"], - order = 4, + desc = L["Width of the bar"], + order = 12, min = 0.1, max = 600, step = .1, @@ -417,13 +670,13 @@ function TotemPulse:GetOptions() headerTexture = { type = "header", name = L["Texture"], - order = 5, + order = 20, }, totemPulseBarTexture = Gladdy:option({ type = "select", name = L["Bar texture"], desc = L["Texture of the bar"], - order = 9, + order = 21, dialogControl = "LSM30_Statusbar", values = AceGUIWidgetLSMlists.statusbar, }), @@ -431,25 +684,25 @@ function TotemPulse:GetOptions() type = "color", name = L["Bar color"], desc = L["Color of the cast bar"], - order = 10, + order = 22, hasAlpha = true, }), totemPulseBarBgColor = Gladdy:colorOption({ type = "color", name = L["Background color"], desc = L["Color of the cast bar background"], - order = 11, + order = 23, hasAlpha = true, }), headerBorder = { type = "header", name = L["Border"], - order = 12, + order = 30, }, totemPulseBarBorderSize = Gladdy:option({ type = "range", name = L["Border size"], - order = 13, + order = 31, min = 0.5, max = Gladdy.db.castBarHeight/2, step = 0.5, @@ -458,19 +711,103 @@ function TotemPulse:GetOptions() totemPulseBarBorderStyle = Gladdy:option({ type = "select", name = L["Status Bar border"], - order = 51, + order = 32, dialogControl = "LSM30_Border", values = AceGUIWidgetLSMlists.border, }), totemPulseBarBorderColor = Gladdy:colorOption({ type = "color", name = L["Status Bar border color"], - order = 52, + order = 33, + hasAlpha = true, + }), + }, + }, + cooldownFrame = { + type = "group", + name = L["Cooldown"], + order = 3, + args = { + headerSize = { + type = "header", + name = L["Frame"], + order = 10, + }, + totemPulseCooldownHeight = Gladdy:option({ + type = "range", + name = L["Height"], + order = 11, + min = 0.1, + max = 200, + step = .1, + width = "full", + }), + totemPulseCooldownWidth = Gladdy:option({ + type = "range", + name = L["Width"], + order = 12, + min = 0.1, + max = 600, + step = .1, + width = "full", + }), + totemPulseCooldownAlpha = Gladdy:option({ + type = "range", + name = L["Alpha"], + order = 21, + min = 0.1, + max = 1, + step = .1, + width = "full", + }), + + }, + }, + text = { + type = "group", + name = L["Text"], + order = 4, + args = { + headerSize = { + type = "header", + name = L["Text"], + order = 10, + }, + totemPulseTextSize = Gladdy:option({ + type = "range", + name = L["Size"], + order = 11, + min = 0.5, + max = 30, + step = 0.5, + width = "full", + }), + totemPulseTextFont = Gladdy:option({ + type = "select", + name = L["Font"], + desc = L["Font of the bar"], + order = 12, + dialogControl = "LSM30_Font", + values = AceGUIWidgetLSMlists.font, + }), + totemPulseTextColor = Gladdy:colorOption({ + type = "color", + name = L["Font color"], + desc = L["Color of the text"], + order = 13, hasAlpha = true, }), }, }, }, }, + customizeTotems = { + order = 50, + name = L["Customize Totems"], + type = "group", + childGroups = "tree", + disabled = function() return not Gladdy.db.totemPulseEnabled end, + args = select(1, TotemOptions()) + }, } end \ No newline at end of file -- 2.39.5 From ad4ba087f52c900b1d4da1e3102e8a070d630164 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:38:50 +0100 Subject: [PATCH 142/268] config frame totemplate ignore parent scale --- Modules/TotemPlates.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/TotemPlates.lua b/Modules/TotemPlates.lua index 8c1a0ee..690c2d5 100644 --- a/Modules/TotemPlates.lua +++ b/Modules/TotemPlates.lua @@ -490,6 +490,7 @@ function TotemPlates:TestOnce() self.testFrame:SetWidth(1) self.testFrame:SetHeight(32) self.testFrame:SetPoint("CENTER", UIParent, "CENTER", 0, -140) + self.testFrame:SetIgnoreParentScale(true) end local totemDataEntry = npcIdToTotemData[5913] self.testFrame:Show() -- 2.39.5 From 34b0a18d9a4842e81e531cd212320503a3a54b6d Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:39:03 +0100 Subject: [PATCH 143/268] Util --- Gladdy.toc | 1 + Util.lua | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 Util.lua diff --git a/Gladdy.toc b/Gladdy.toc index 5dfaf9b..9fe7adc 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -15,6 +15,7 @@ Frame.lua Options.lua Constants.lua ImportStrings.lua +Util.lua Modules\Announcements.lua Modules\Healthbar.lua diff --git a/Util.lua b/Util.lua new file mode 100644 index 0000000..204e9d0 --- /dev/null +++ b/Util.lua @@ -0,0 +1,143 @@ +local pairs, ipairs = pairs, ipairs +local floor = math.floor +local str_find, str_gsub, str_sub, tinsert = string.find, string.gsub, string.sub, table.insert +local Gladdy = LibStub("Gladdy") +local L = Gladdy.L + +--------------------------- + +-- TAGS + +--------------------------- + +local tags = { + ["current"] = true, + ["max"] = true, + ["percent"] = true, + ["race"] = "race", + ["class"] = "class", + ["arena"] = true, + ["name"] = "name", + ["status"] = true, + ["spec"] = "spec", +} + +local function str_extract(s, pattern) + local t = {} -- table to store the indices + local i, j = 0,0 + while true do + i, j = str_find(s, pattern, i+1) -- find 'next' occurrence + if i == nil then break end + tinsert(t, str_sub(s, i, j)) + end + return t +end + +--TODO optimize this function as it's being called often! +local function getTagText(unit, tag, current, max, status) + local button = Gladdy.buttons[unit] + if not button then + return + end + + if str_find(tag, "percent") then + return current and max and floor(current * 100 / max) .. "%%" or "" + elseif str_find(tag, "current") then + return current or "" + elseif str_find(tag, "max") then + return max or "" + elseif str_find(tag, "status") then + if str_find(tag, "%|") and status == nil then + return nil + else + return status or "" + end + elseif str_find(tag, "name") then + return button.name or "" + elseif str_find(tag, "class") then + return button.classLoc or "" + elseif str_find(tag, "race") then + return button.raceLoc or "" + elseif str_find(tag, "arena") then + return str_gsub(unit, "arena", "") + elseif str_find(tag, "spec") then + if str_find(tag, "%|") and button.spec == nil then + return nil + else + return button.spec or "" + end + end +end + +function Gladdy:SetTag(unit, tagOption, current, max, status) + local button = self.buttons[unit] + if not button then + return + end + + local returnStr = tagOption + + local t = str_extract(returnStr, "%[[^%[].-%]") + for _, tag in ipairs(t) do + local replace + if str_find(tag, "|") then -- or operator + local indicators = str_extract(tag, "[%[|%|]%a+[%||%]]") + local replaces = {} + for _, indicator in ipairs(indicators) do + tinsert(replaces, getTagText(unit, indicator, current, max, status)) + end + replace = replaces[#replaces] + else + replace = getTagText(unit, tag, current, max, status) + end + + if replace then + local find = str_gsub(tag, "%[", "%%[") + find = str_gsub(find, "%]", "%%]") + find = str_gsub(find, "%|", "%%|") + returnStr = str_gsub(returnStr, find, replace) + end + end + return returnStr +end + +function Gladdy:GetTagOption(name, order, enabledOption, func, toggle) + if toggle then + return func({ + type = "toggle", + name = name, + order = order, + width = "full", + desc = L["Custom Tags:\n".. + "\n|cff1ac742[current]|r - Shows current\n" .. + "\n|cff1ac742[max]|r - Shows max\n" .. + "\n|cff1ac742[percent]|r - Shows percent\n" .. + "\n|cff1ac742[name]|r - Shows name\n" .. + "\n|cff1ac742[arena]|r - Shows arena number\n" .. + "\n|cff1ac742[status]|r - Shows status (eg DEATH)\n" .. + "\n|cff1ac742[race]|r - Shows race\n" .. + "\n|cff1ac742[class]|r - Shows class\n" .. + "\n|cff1ac742[spec]|r - Shows spec\n\n" .. + "Can be combined with OR operator like |cff1ac742[percent|status]|r. The last valid option will be used.\n"], + }) + else + return func({ + type = "input", + name = name, + order = order, + width = "full", + disabled = function() return not Gladdy.db[enabledOption] end, + desc = L["Custom Tags:\n".. + "\n|cff1ac742[current]|r - Shows current\n" .. + "\n|cff1ac742[max]|r - Shows max\n" .. + "\n|cff1ac742[percent]|r - Shows percent\n" .. + "\n|cff1ac742[name]|r - Shows name\n" .. + "\n|cff1ac742[arena]|r - Shows arena number\n" .. + "\n|cff1ac742[status]|r - Shows status (eg DEATH)\n" .. + "\n|cff1ac742[race]|r - Shows race\n" .. + "\n|cff1ac742[class]|r - Shows class\n" .. + "\n|cff1ac742[spec]|r - Shows spec\n\n" .. + "Can be combined with OR operator like |cff1ac742[percent|status]|r. The last valid option will be used.\n"], + }) + end +end \ No newline at end of file -- 2.39.5 From d23d749f1ec4e65cd1c4dc2461d786866603b98f Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:39:20 +0100 Subject: [PATCH 144/268] add disarm riposte to dr data --- Libs/DRData-1.0/DRData-1.0.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Libs/DRData-1.0/DRData-1.0.lua b/Libs/DRData-1.0/DRData-1.0.lua index a3a3c8d..4bfc95c 100644 --- a/Libs/DRData-1.0/DRData-1.0.lua +++ b/Libs/DRData-1.0/DRData-1.0.lua @@ -254,6 +254,7 @@ Data.spells = { -- Disarm [676] = "disarm", + [14251] = "disarm", } -- DR Category names -- 2.39.5 From 3c82edc441f63ad6cd3fdedbc5abf657a9aab6e5 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:40:00 +0100 Subject: [PATCH 145/268] detect certain racials and spells when used in stealth --- EventListener.lua | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 75cbba1..e98ae44 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -15,7 +15,7 @@ local L = Gladdy.L local Cooldowns = Gladdy.modules["Cooldowns"] local Diminishings = Gladdy.modules["Diminishings"] -local EventListener = Gladdy:NewModule("EventListener", 10, { +local EventListener = Gladdy:NewModule("EventListener", 101, { test = true, }) @@ -76,13 +76,13 @@ function Gladdy:SpotEnemy(unit, auraScan) if Gladdy.cooldownBuffs[spellName] and unitCaster then -- Check for auras that detect used CDs (like Fear Ward) for arenaUnit,v in pairs(self.buttons) do if (UnitIsUnit(arenaUnit, unitCaster)) then - Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, expirationTime - GetTime()) + Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, Gladdy.cooldownBuffs[spellName].cd(expirationTime - GetTime())) -- /run LibStub("Gladdy").modules["Cooldowns"]:CooldownUsed("arena5", "PRIEST", 6346, 10) end end end - if Gladdy.cooldownBuffs.racials[spellName] then - Gladdy:SendMessage("RACIAL_USED", unit, expirationTime, spellName) + if Gladdy.cooldownBuffs.racials[spellName] and Gladdy.cooldownBuffs.racials[spellName] then + Gladdy:SendMessage("RACIAL_USED", unit, spellName, Gladdy.cooldownBuffs.racials[spellName].cd(expirationTime - GetTime()), spellName) end if Gladdy.specBuffs[spellName] and unitCaster then -- Check for auras that detect a spec local unitPet = string_gsub(unit, "%d$", "pet%1") @@ -213,10 +213,22 @@ Gladdy.exceptionNames = { -- TODO MOVE ME TO CLASSBUFFS LIB } Gladdy.cooldownBuffs = { - [GetSpellInfo(6346)] = { cd = 180, spellId = 6346 }, -- Fear Ward - -- TODO sprint, shadowstep + [GetSpellInfo(6346)] = { cd = function(expTime) -- 180s uptime == cd + return expTime + end, spellId = 6346 }, -- Fear Ward + [GetSpellInfo(11305)] = { cd = function(expTime) -- 15s uptime + return 180 - (15 - expTime) + end, spellId = 11305 }, -- Sprint + [GetSpellInfo(36554)] = { cd = function(expTime) -- 3s uptime + return 30 - (3 - expTime) + end, spellId = 36554 }, -- Shadowstep + [GetSpellInfo(26889)] = { cd = function(expTime) -- 3s uptime + return 180 - (10 - expTime) + end, spellId = 26889 }, -- Vanish racials = { - [GetSpellInfo(20600)] = { cd = 180, spellId = 20600 }, -- Perception + [GetSpellInfo(20600)] = { cd = function(expTime) -- 20s uptime + return GetTime() - (20 - expTime) + end, spellId = 20600 }, -- Perception } } @@ -241,12 +253,12 @@ function EventListener:UNIT_AURA(unit) if Gladdy.cooldownBuffs[spellName] and unitCaster then -- Check for auras that hint used CDs (like Fear Ward) for arenaUnit,v in pairs(Gladdy.buttons) do if (UnitIsUnit(arenaUnit, unitCaster)) then - Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, expirationTime - GetTime()) + Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, Gladdy.cooldownBuffs[spellName].cd(expirationTime - GetTime())) end end end - if Gladdy.cooldownBuffs.racials[spellName] then - Gladdy:SendMessage("RACIAL_USED", unit, spellName, expirationTime, spellName) + if Gladdy.cooldownBuffs.racials[spellName] and Gladdy.cooldownBuffs.racials[spellName] then + Gladdy:SendMessage("RACIAL_USED", unit, spellName, Gladdy.cooldownBuffs.racials[spellName].cd(expirationTime - GetTime()), spellName) end if not button.spec and Gladdy.specBuffs[spellName] and unitCaster then local unitPet = string_gsub(unit, "%d$", "pet%1") -- 2.39.5 From 8fa481affe46f3674d6c599fc08da97fa05dea80 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:40:23 +0100 Subject: [PATCH 146/268] racial cleanup --- Modules/Racial.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/Racial.lua b/Modules/Racial.lua index e9dff61..ac8bc50 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -169,7 +169,6 @@ function Racial:UpdateFrame(unit) end function Racial:JOINED_ARENA() - self:RegisterEvent("ARENA_COOLDOWNS_UPDATE") self:SetScript("OnEvent", function(self, event, ...) if self[event] then self[event](self, ...) @@ -186,7 +185,7 @@ function Racial:RACIAL_USED(unit, expirationTime, spellName) if expirationTime and Gladdy:Racials()[button.race].spellName ~= spellName then return end - local startTime = (expirationTime and expirationTime - Gladdy:Racials()[button.race].duration) or GetTime() + local startTime = expirationTime or GetTime() Racial:Used(unit, startTime, Gladdy:Racials()[button.race].duration) end -- 2.39.5 From 26241d73d626fb3be2862271535136daf2f16960 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:40:47 +0100 Subject: [PATCH 147/268] add test once and adjust testdata --- Gladdy.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 63c5d17..808b2c3 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -289,11 +289,11 @@ function Gladdy:OnInitialize() L = self.L self.testData = { - ["arena1"] = { name = "Swift", raceLoc = L["NightElf"], classLoc = L["Warrior"], class = "WARRIOR", health = 9635, healthMax = 14207, power = 76, powerMax = 100, powerType = 1, testSpec = L["Arms"], race = "NightElf" }, - ["arena2"] = { name = "Vilden", raceLoc = L["Undead"], classLoc = L["Mage"], class = "MAGE", health = 10969, healthMax = 11023, power = 7833, powerMax = 10460, powerType = 0, testSpec = L["Frost"], race = "Scourge" }, - ["arena3"] = { name = "Krymu", raceLoc = L["Human"], classLoc = L["Rogue"], class = "ROGUE", health = 1592, healthMax = 11740, power = 45, powerMax = 110, powerType = 3, testSpec = L["Subtlety"], race = "Human" }, - ["arena4"] = { name = "Talmon", raceLoc = L["Human"], classLoc = L["Warlock"], class = "WARLOCK", health = 10221, healthMax = 14960, power = 9855, powerMax = 9855, powerType = 0, testSpec = L["Demonology"], race = "Human" }, - ["arena5"] = { name = "Hydra", raceLoc = L["Undead"], classLoc = L["Priest"], class = "PRIEST", health = 11960, healthMax = 11960, power = 2515, powerMax = 10240, powerType = 0, testSpec = L["Discipline"], race = "Human" }, + ["arena1"] = { name = "Swift", raceLoc = L["NightElf"], classLoc = L["Hunter"], class = "HUNTER", health = 67, healthMax = 100, power = 76, powerMax = 100, powerType = 1, testSpec = L["Marksmanship"], race = "NightElf" }, + ["arena2"] = { name = "Vilden", raceLoc = L["Undead"], classLoc = L["Mage"], class = "MAGE", health = 99, healthMax = 100, power = 7833, powerMax = 10460, powerType = 0, testSpec = L["Frost"], race = "Scourge" }, + ["arena3"] = { name = "Krymu", raceLoc = L["Human"], classLoc = L["Rogue"], class = "ROGUE", health = 13, healthMax = 100, power = 45, powerMax = 110, powerType = 3, testSpec = L["Subtlety"], race = "Human" }, + ["arena4"] = { name = "Talmon", raceLoc = L["Human"], classLoc = L["Warlock"], class = "WARLOCK", health = 68, healthMax = 100, power = 9855, powerMax = 9855, powerType = 0, testSpec = L["Demonology"], race = "Human" }, + ["arena5"] = { name = "Hydra", raceLoc = L["Undead"], classLoc = L["Priest"], class = "PRIEST", health = 100, healthMax = 100, power = 2515, powerMax = 10240, powerType = 0, testSpec = L["Discipline"], race = "Human" }, } self.cooldownSpellIds = {} @@ -407,6 +407,9 @@ function Gladdy:Test() button:SetAlpha(1) end + for _, module in self:IterModules() do + self:Call(module, "TestOnce") + end end end -- 2.39.5 From d6351dbe883a80289340a202bc9c47250ac4eb07 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:41:25 +0100 Subject: [PATCH 148/268] add riposte, disarm, will of the forsaken to auras --- Constants.lua | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Constants.lua b/Constants.lua index 3f39ba3..eecf7f6 100644 --- a/Constants.lua +++ b/Constants.lua @@ -579,7 +579,13 @@ local importantAuras = { priority = 10, spellID = 26669, }, - + -- Riposte + [GetSpellInfo(14251)] = { + track = AURA_TYPE_DEBUFF, + duration = 6, + priority = 20, + spellID = 14251, + }, -- Fear [GetSpellInfo(5782)] = { @@ -708,6 +714,13 @@ local importantAuras = { spellSchool = "magic", spellID = 12292, }, + --Disarm + [GetSpellInfo(676)] = { + track = AURA_TYPE_DEBUFF, + duration = 10, + priority = 20, + spellID = 676, + }, -- Grounding Totem Effect [GetSpellInfo(8178)] = { @@ -805,6 +818,13 @@ local importantAuras = { spellID = 5024, altName = select(1, GetSpellInfo(5024)) .. " - " .. (select(1, GetItemInfo(4984)) or "Skull of Impending Doom"), }, + -- Will of the Forsaken + [GetSpellInfo(7744)] = { + track = AURA_TYPE_BUFF, + duration = 5, + priority = 15, + spellID = 7744, + }, } function Gladdy:GetImportantAuras() return importantAuras -- 2.39.5 From 24bb84663fef9ac0e0198a80b2d903592164fec7 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:41:54 +0100 Subject: [PATCH 149/268] configurable health bar text by tags --- Modules/Healthbar.lua | 218 +++++++++++++++++++++++++++++------------- 1 file changed, 154 insertions(+), 64 deletions(-) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 4d88014..1bc2e5a 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -1,5 +1,6 @@ -local pairs = pairs +local pairs, ipairs = pairs, ipairs local floor = math.floor +local str_find, str_gsub, str_sub, tinsert = string.find, string.gsub, string.sub, table.insert local UnitHealth, UnitHealthMax, UnitName, UnitExists, UnitIsDeadOrGhost = UnitHealth, UnitHealthMax, UnitName, UnitExists, UnitIsDeadOrGhost local CreateFrame = CreateFrame @@ -26,12 +27,23 @@ local Healthbar = Gladdy:NewModule("Health Bar", 100, { healthPercentage = true, healthFrameStrata = "MEDIUM", healthFrameLevel = 1, + healthCustomTagsEnabled = false, + healthTextRight = "[percent|status]", + healthTextLeft = "[name]", + healthTextRight = "[percent|status]", + healthTextLeftOutline = false, + healthTextRightOutline = false, + healthTextLeftVOffset = 0, + healthTextLeftHOffset = 5, + healthTextRightVOffset = 0, + healthTextRightHOffset = -5, }) function Healthbar:Initialize() self.frames = {} self:RegisterMessage("JOINED_ARENA") self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("UNIT_SPEC") self:RegisterMessage("UNIT_DESTROYED") self:RegisterMessage("UNIT_DEATH") end @@ -65,28 +77,28 @@ function Healthbar:CreateFrame(unit) healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarNameFont"), 1) healthBar.nameText:Hide() else - healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarNameFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarNameFontSize, Gladdy.db.healthTextLeftOutline and "OUTLINE") healthBar.nameText:Show() end healthBar.nameText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) healthBar.nameText:SetShadowOffset(1, -1) healthBar.nameText:SetShadowColor(0, 0, 0, 1) healthBar.nameText:SetJustifyH("CENTER") - healthBar.nameText:SetPoint("LEFT", 5, 0) + healthBar.nameText:SetPoint("LEFT", Gladdy.db.healthTextLeftHOffset, Gladdy.db.healthTextLeftVOffset) healthBar.healthText = healthBar:CreateFontString(nil, "LOW") if (Gladdy.db.healthBarHealthFontSize < 1) then healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), 1) healthBar.healthText:Hide() else - healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarHealthFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarHealthFontSize, Gladdy.db.healthTextRightOutline and "OUTLINE") healthBar.healthText:Hide() end healthBar.healthText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) healthBar.healthText:SetShadowOffset(1, -1) healthBar.healthText:SetShadowColor(0, 0, 0, 1) healthBar.healthText:SetJustifyH("CENTER") - healthBar.healthText:SetPoint("RIGHT", -5, 0) + healthBar.healthText:SetPoint("RIGHT", Gladdy.db.healthTextRightHOffset, Gladdy.db.healthTextRightVOffset) healthBar.unit = unit self.frames[unit] = healthBar @@ -100,17 +112,7 @@ end function Healthbar.OnEvent(self, event, unit) local isDead = UnitExists(unit) and UnitIsDeadOrGhost(unit) - if event == "UNIT_HEALTH" then - if isDead then - Gladdy:SendMessage("UNIT_DEATH", unit) - return - end - local health = UnitHealth(unit) - local healthMax = UnitHealthMax(unit) - self.hp:SetMinMaxValues(0, healthMax) - self.hp:SetValue(UnitHealth(unit)) - Healthbar:SetHealthText(self, health, healthMax) - elseif event == "UNIT_MAXHEALTH" then + if event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH" then if isDead then Gladdy:SendMessage("UNIT_DEATH", unit) return @@ -119,13 +121,13 @@ function Healthbar.OnEvent(self, event, unit) local healthMax = UnitHealthMax(unit) self.hp:SetMinMaxValues(0, healthMax) self.hp:SetValue(health) - Healthbar:SetHealthText(self, health, healthMax) + self.hp.current = health + Healthbar:SetText(unit, health, healthMax) + --Healthbar:SetHealthText(self, health, healthMax) elseif event == "UNIT_NAME_UPDATE" then local name = UnitName(unit) Gladdy.buttons[unit].name = name - if Gladdy.db.healthName and not Gladdy.db.healthNameToArenaId then - self.nameText:SetText(name) - end + Healthbar:SetText(unit, self.hp.current, 100) end if not Gladdy.buttons[unit].class then Gladdy:SpotEnemy(unit, true) @@ -134,20 +136,42 @@ end function Healthbar:SetHealthText(healthBar, health, healthMax) local healthText = "" - local healthPercentage = floor(health * 100 / healthMax) + local healthPercentage = health and healthMax and floor(health * 100 / healthMax) if health == 0 and UnitExists(healthBar.unit) and UnitIsDeadOrGhost(healthBar.unit) then self:UNIT_DEATH(healthBar.unit) return end - - if (Gladdy.db.healthPercentage) then + if (Gladdy.db.healthPercentage and healthPercentage) then healthText = ("%d%%"):format(healthPercentage) end - healthBar.healthText:SetText(healthText) end +function Healthbar:SetText(unit, health, healthMax, status) + local button = Gladdy.buttons[unit] + if not Gladdy.buttons[unit] then + return + end + if Gladdy.db.healthCustomTagsEnabled then + button.healthBar.nameText:SetText(Gladdy:SetTag(unit, Gladdy.db.healthTextLeft, health, healthMax, status)) + button.healthBar.healthText:SetText(Gladdy:SetTag(unit, Gladdy.db.healthTextRight, health, healthMax, status)) + else + if Gladdy.db.healthName then + if Gladdy.db.healthNameToArenaId then + button.healthBar.nameText:SetText(str_gsub(unit, "arena", "")) + else + button.healthBar.nameText:SetText(Gladdy.buttons[unit].name) + end + end + if status then + button.healthBar.healthText:SetText(status) + else + Healthbar:SetHealthText(button.healthBar, health, healthMax) + end + end +end + function Healthbar:UpdateFrame(unit) local healthBar = self.frames[unit] if (not healthBar) then @@ -178,14 +202,14 @@ function Healthbar:UpdateFrame(unit) healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), 1) healthBar.healthText:Hide() else - healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarHealthFontSize) + healthBar.healthText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarHealthFontSize, Gladdy.db.healthTextRightOutline and "OUTLINE") healthBar.healthText:Show() end if (Gladdy.db.healthBarNameFontSize < 1) then healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarNameFont"), 1) healthBar.nameText:Hide() else - healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarNameFontSize) + healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarNameFontSize, Gladdy.db.healthTextLeftOutline and "OUTLINE") if Gladdy.db.healthName then healthBar.nameText:Show() else @@ -194,6 +218,8 @@ function Healthbar:UpdateFrame(unit) end healthBar.nameText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) healthBar.healthText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) + healthBar.nameText:SetPoint("LEFT", Gladdy.db.healthTextLeftHOffset, Gladdy.db.healthTextLeftVOffset) + healthBar.healthText:SetPoint("RIGHT", Gladdy.db.healthTextRightHOffset, Gladdy.db.healthTextRightVOffset) end function Healthbar:ResetUnit(unit) @@ -206,6 +232,7 @@ function Healthbar:ResetUnit(unit) healthBar.nameText:SetText("") healthBar.healthText:SetText("") healthBar.hp:SetValue(0) + healthBar.hp.current = 0 end function Healthbar:Test(unit) @@ -215,17 +242,30 @@ function Healthbar:Test(unit) return end - self:JOINED_ARENA() + --self:JOINED_ARENA() + Gladdy:SendMessage("UNIT_HEALTH", unit, button.health, button.healthMax) + healthBar.hp.current = button.health self:ENEMY_SPOTTED(unit) - self:UNIT_HEALTH(unit, button.health, button.healthMax) + self:SetText(unit, button.health, button.healthMax) + healthBar.hp:SetValue(button.health) + if unit == "arena1" then + self:UNIT_DEATH(unit) + --self:SetText(unit, button.health, button.healthMax, L["DEAD"]) + end +end + +function Healthbar:UNIT_SPEC(unit) + local button = Gladdy.buttons[unit] + if not button then + return + end + self:SetText(unit, button.healthBar.hp.current, 100) + --button.healthBar.nameText:SetText(Gladdy:SetTag(unit, Gladdy.db.healthTextLeft, button.health, button.healthMax)) end function Healthbar:JOINED_ARENA() - if Gladdy.db.healthNameToArenaId and Gladdy.db.healthName then - for i=1,Gladdy.curBracket do - local healthBar = self.frames["arena" .. i] - healthBar.nameText:SetText(i) - end + for i=1,Gladdy.curBracket do + self:SetText("arena" .. i, nil, nil) end end @@ -241,10 +281,9 @@ function Healthbar:ENEMY_SPOTTED(unit) local healthMax = UnitHealthMax(unit) healthBar.hp:SetMinMaxValues(0, healthMax) healthBar.hp:SetValue(health) - Healthbar:SetHealthText(healthBar, health, healthMax) - end - if button.name and Gladdy.db.healthName and not Gladdy.db.healthNameToArenaId then - healthBar.nameText:SetText(button.name) + healthBar.hp.current = health + Healthbar:SetText(unit, health, healthMax) + --Healthbar:SetHealthText(healthBar, health, healthMax) end if button.class then @@ -252,27 +291,6 @@ function Healthbar:ENEMY_SPOTTED(unit) end end -function Healthbar:UNIT_HEALTH(unit, health, healthMax) - local healthBar = self.frames[unit] - if (not healthBar) then - return - end - if not Gladdy.buttons[unit].class then - Gladdy:SpotEnemy(unit, true) - end - Gladdy:SendMessage("UNIT_HEALTH", unit, health, healthMax) - - local healthPercentage = floor(health * 100 / healthMax) - local healthText = "" - - if (Gladdy.db.healthPercentage) then - healthText = ("%d%%"):format(healthPercentage) - end - - healthBar.healthText:SetText(healthText) - healthBar.hp:SetValue(healthPercentage) -end - function Healthbar:UNIT_DEATH(unit) local healthBar = self.frames[unit] if (not healthBar) then @@ -280,7 +298,8 @@ function Healthbar:UNIT_DEATH(unit) end healthBar.hp:SetValue(0) - healthBar.healthText:SetText(L["DEAD"]) + healthBar.hp.current = 0 + Healthbar:SetText(unit, 0, 100, L["DEAD"]) end function Healthbar:UNIT_DESTROYED(unit) @@ -290,6 +309,7 @@ function Healthbar:UNIT_DESTROYED(unit) end healthBar.hp:SetValue(0) + healthBar.hp.current = 0 healthBar.healthText:SetText(L["LEAVE"]) healthBar.nameText:SetText("") end @@ -307,8 +327,10 @@ local function option(params) if Gladdy.db.healthBarBorderSize > Gladdy.db.healthBarHeight/2 then Gladdy.db.healthBarBorderSize = Gladdy.db.healthBarHeight/2 end - for i=1,Gladdy.curBracket do - Healthbar:Test("arena" .. i) + if Gladdy.frame.testing then + for i=1,Gladdy.curBracket do + Healthbar:Test("arena" .. i) + end end Gladdy:UpdateFrame() end, @@ -396,11 +418,28 @@ function Healthbar:GetOptions() order = 12, hasAlpha = true, }), + healthTextLeftOutline = option({ + type = "toggle", + name = L["Left Font Outline"], + order = 13, + width = "full", + }), + healthTextRightOutline = option({ + type = "toggle", + name = L["Right Font Outline"], + order = 14, + width = "full", + }), + headerSize = { + type = "header", + name = L["Size"], + order = 20, + }, healthBarNameFontSize = option({ type = "range", name = L["Name font size"], desc = L["Size of the name text"], - order = 13, + order = 21, step = 0.1, min = 0, max = 20, @@ -410,12 +449,53 @@ function Healthbar:GetOptions() type = "range", name = L["Health font size"], desc = L["Size of the health text"], - order = 14, + order = 22, step = 0.1, min = 0, max = 20, width = "full", }), + headerLeftText = { + type = "header", + name = L["Offsets"], + order = 30, + }, + healthTextLeftVOffset = option({ + type = "range", + name = L["Left Text Vertical Offset"], + order = 31, + step = 0.1, + min = -200, + max = 200, + width = "full", + }), + healthTextLeftHOffset = option({ + type = "range", + name = L["Left Text Horizontal Offset"], + order = 32, + step = 0.1, + min = -200, + max = 200, + width = "full", + }), + healthTextRightVOffset = option({ + type = "range", + name = L["Right Text Vertical Offset"], + order = 33, + step = 0.1, + min = -200, + max = 200, + width = "full", + }), + healthTextRightHOffset = option({ + type = "range", + name = L["Right Text Horizontal Offset"], + order = 34, + step = 0.1, + min = -200, + max = 200, + width = "full", + }), }, }, border = { @@ -499,6 +579,7 @@ function Healthbar:GetOptions() desc = L["Show the units name"], order = 2, width = "full", + disabled = function() return Gladdy.db.healthCustomTagsEnabled end, }), healthNameToArenaId = option({ type = "toggle", @@ -506,7 +587,7 @@ function Healthbar:GetOptions() desc = L["Show 1-5 as name instead"], order = 3, width = "full", - disabled = function() return not Gladdy.db.healthName end + disabled = function() return not Gladdy.db.healthName or Gladdy.db.healthCustomTagsEnabled end, }), healthPercentage = option({ type = "toggle", @@ -514,7 +595,16 @@ function Healthbar:GetOptions() desc = L["Show health percentage on the health bar"], order = 6, width = "full", + disabled = function() return Gladdy.db.healthCustomTagsEnabled end, }), + header = { + type = "header", + name = L["Custom Tags"], + order = 10, + }, + healthCustomTagsEnabled = Gladdy:GetTagOption(L["Custom Tags Enabled"], 11, nil, option, true), + healthTextLeft = Gladdy:GetTagOption(L["Left Text"], 12, "healthCustomTagsEnabled", option), + healthTextRight = Gladdy:GetTagOption(L["Right Text"], 13, "healthCustomTagsEnabled", option), }, }, }, -- 2.39.5 From 2f20d305b677b5514a2401e60f1afafcc1711721 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 3 Mar 2022 23:42:35 +0100 Subject: [PATCH 150/268] unified lang commented out --- Lang.lua | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Lang.lua b/Lang.lua index 3ae287d..caf2d58 100644 --- a/Lang.lua +++ b/Lang.lua @@ -28,6 +28,34 @@ L["Troll"] = C_CreatureInfo.GetRaceInfo(8).raceName L["Blood Elf"] = C_CreatureInfo.GetRaceInfo(10).raceName L["Draenei"] = C_CreatureInfo.GetRaceInfo(11).raceName +--Specs +--[[ +L["Balance"] = BALANCE +L["Combat"] = COMBAT_LABEL +L["Fire"] = STRING_SCHOOL_FIRE +L["Arcane"] = STRING_SCHOOL_ARCANE +L["Shadow"] = STRING_SCHOOL_SHADOW +L["Holy"] = STRING_SCHOOL_HOLY +L["Elemental"] = STRING_SCHOOL_ELEMENTAL + + +--Modules +--L["Announcements"] = CHAT_ANNOUNCE +L["Auras"] = COMBAT_TEXT_SHOW_AURAS_TEXT +L["Cast Bar"] = SHOW_ENEMY_CAST +L["Buffs and Debuffs"] = BUFFOPTIONS_LABEL +--L["Class Icon"] = CLASS .. " " .. EMBLEM_SYMBOL +--L["Clicks"] = +L["Cooldowns"] = CAPACITANCE_SHIPMENT_COOLDOWN:gsub(": %%s", "") +--L["Export Import"] = +--L["Healthbar"] +L["Highlight"] = HIGHLIGHTING:gsub(":", "") +L["Pet"] = PET_TYPE_PET +--L["Racial"] = RACE .. " " .. ABILITIES +--L["Range Check"] = +L["Trinket"] = TRINKET0SLOT +--]] + if (GetLocale() == "ruRU") then -- Specs L["Balance"] = "Баланс" -- 2.39.5 From d348b87ddf4b56b783c952f7c8b144af101573ef Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Thu, 24 Mar 2022 20:23:50 +0100 Subject: [PATCH 151/268] switch UNIT_HEALTH to UNIT_HEALTH_FREQUENT --- Modules/Healthbar.lua | 2 +- Modules/Pets.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 1bc2e5a..4523a87 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -104,7 +104,7 @@ function Healthbar:CreateFrame(unit) self.frames[unit] = healthBar button.healthBar = healthBar self:ResetUnit(unit) - healthBar:RegisterUnitEvent("UNIT_HEALTH", unit) + healthBar:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", unit) healthBar:RegisterUnitEvent("UNIT_MAXHEALTH", unit) healthBar:RegisterUnitEvent("UNIT_NAME_UPDATE", unit) healthBar:SetScript("OnEvent", Healthbar.OnEvent) diff --git a/Modules/Pets.lua b/Modules/Pets.lua index 5a7eca1..d54ceab 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -233,7 +233,7 @@ function Pets:CreateFrame(unitId) healthBar.unit = unit button.healthBar = healthBar - healthBar:RegisterUnitEvent("UNIT_HEALTH", unit) + healthBar:RegisterUnitEvent("UNIT_HEALTH_FREQUENT", unit) healthBar:RegisterUnitEvent("UNIT_MAXHEALTH", unit) healthBar:RegisterUnitEvent("UNIT_PORTRAIT_UPDATE", unit) healthBar:RegisterUnitEvent("UNIT_NAME_UPDATE", unit) -- 2.39.5 From 1a8cd81f7a81888b63ffcb477b7a9374793834df Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 00:00:44 +0100 Subject: [PATCH 152/268] fix totemtick set parent and SetPoint --- Modules/TotemPlates.lua | 1 + Modules/TotemPulse.lua | 94 ++++++++++++++--------------------------- 2 files changed, 33 insertions(+), 62 deletions(-) diff --git a/Modules/TotemPlates.lua b/Modules/TotemPlates.lua index 690c2d5..942115d 100644 --- a/Modules/TotemPlates.lua +++ b/Modules/TotemPlates.lua @@ -306,6 +306,7 @@ end function TotemPlates:CreateTotemFrame(nameplate) nameplate.gladdyTotemFrame = CreateFrame("Frame") + nameplate.gladdyTotemFrame:SetFrameLevel(1) nameplate.gladdyTotemFrame:SetIgnoreParentAlpha(true) nameplate.gladdyTotemFrame:SetWidth(Gladdy.db.npTotemPlatesSize * Gladdy.db.npTotemPlatesWidthFactor) nameplate.gladdyTotemFrame:SetHeight(Gladdy.db.npTotemPlatesSize) diff --git a/Modules/TotemPulse.lua b/Modules/TotemPulse.lua index 6cc6c5e..cd2fd2d 100644 --- a/Modules/TotemPulse.lua +++ b/Modules/TotemPulse.lua @@ -1,10 +1,12 @@ local select, pairs, tremove, tinsert, format, strsplit, tonumber = select, pairs, tremove, tinsert, format, strsplit, tonumber +local type = type local C_NamePlate = C_NamePlate local Gladdy = LibStub("Gladdy") local L = Gladdy.L local GetSpellInfo, CreateFrame = GetSpellInfo, CreateFrame local GetTime, UnitIsEnemy, UnitGUID = GetTime, UnitIsEnemy, UnitGUID local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo +local UIParent = UIParent --------------------------------------------------- @@ -118,10 +120,10 @@ local TotemPulse = Gladdy:NewModule("Totem Pulse", 1, { --bar totemPulseBarWidth = 40, totemPulseBarHeight = 20, - totemPulseBarColor = { r = 1, g = 0, b = 0, a = 1 }, - totemPulseBarBgColor = { r = 0, g = 1, b = 0, a = 1 }, + totemPulseBarColor = { r = 1, g = 0, b = 0, a = .5 }, + totemPulseBarBgColor = { r = 0, g = 1, b = 0, a = .5 }, totemPulseBarBorderColor = { r = 0, g = 0, b = 0, a = 1 }, - totemPulseBarBorderSize = 5, + totemPulseBarBorderSize = 4, totemPulseBarBorderStyle = "Gladdy Tooltip squared", totemPulseBarTexture = "Flat", totemPulseBarReverse = false, @@ -329,24 +331,10 @@ end function TotemPulse:AddTimerFrame(nameplate, timestamp, test) if (nameplate:IsShown() or test) and timestamp then - local gladdyTotemFrame = Gladdy.db.totemPulseTotems["totem" .. timestamp.id].attachToGladdyTotemFrame and nameplate.gladdyTotemFrame if not nameplate.totemTick then nameplate.totemTick = TotemPulse:CreateCooldownFrame(Gladdy.db.totemPulseTotems["totem" .. timestamp.id].style) end - nameplate.totemTick:SetParent(nameplate.gladdyTotemFrame or nameplate) - --nameplate.totemTick:ClearAllPoints() - --[[if gladdyTotemFrame then - nameplate.totemTick:SetPoint("TOPLEFT", gladdyTotemFrame, "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) - nameplate.totemTick:SetPoint("BOTTOMRIGHT", gladdyTotemFrame, "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) - if nameplate.totemTick.bar then - nameplate.totemTick.spark:SetHeight(Gladdy.db.totemPulseTotems["totem" .. timestamp.id].style == "Vertical" and gladdyTotemFrame:GetWidth() or gladdyTotemFrame:GetHeight()) - end - else - nameplate.totemTick:SetPoint("TOP", nameplate.gladdyTotemFrame, "BOTTOM", 0, -5) - if nameplate.totemTick.bar then - nameplate.totemTick.spark:SetHeight(Gladdy.db.totemPulseTotems["totem" .. timestamp.id].style == "Vertical" and Gladdy.db.totemPulseBarWidth or Gladdy.db.totemPulseBarHeight) - end - end--]] + nameplate.totemTick:SetParent(nameplate) local cd = type(timestamp.pulse) == "table" and timestamp.pulse.cd or timestamp.pulse local once = type(timestamp.pulse) == "table" @@ -444,30 +432,21 @@ function TotemPulse:UpdateBarPartial(bar) bar.spark:SetHeight(style == "Vertical" and Gladdy.db.totemPulseBarWidth or Gladdy.db.totemPulseBarHeight) bar.spark:SetRotation(style == "Vertical" and ninetyDegreeInRad or 0) - if (bar:GetParent()) then - if bar:GetParent().gladdyTotemFrame then - bar:SetParent(bar:GetParent().gladdyTotemFrame) - else - bar:SetParent(bar:GetParent()) - end - --[[if bar.id and Gladdy.db.totemPulseTotems["totem" .. bar.id].attachToGladdyTotemFrame then - if not bar:GetParent().totemIcon and bar:GetParent().gladdyTotemFrame then - bar:SetParent(bar:GetParent().gladdyTotemFrame) - end - elseif bar.id and not Gladdy.db.totemPulseTotems["totem" .. bar.id].attachToGladdyTotemFrame then - if bar:GetParent().totemIcon then - bar:SetParent(bar:GetParent():GetParent()) - end - end--]] + + if bar:GetParent() and bar:GetParent() ~= UIParent then + local gladdyTotemFrame = bar:GetParent().gladdyTotemFrame and bar:GetParent().gladdyTotemFrame + local nameplate = bar:GetParent() bar:ClearAllPoints() - if (bar.id and bar:GetParent().totemIcon and Gladdy.db.totemPulseTotems["totem" .. bar.id].attachToGladdyTotemFrame) then - bar:SetPoint("TOPLEFT", bar:GetParent(), "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) - bar:SetPoint("BOTTOMRIGHT", bar:GetParent(), "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) + if bar.id and gladdyTotemFrame and gladdyTotemFrame:IsShown() and Gladdy.db.totemPulseTotems["totem" .. bar.id].attachToGladdyTotemFrame then + bar:SetPoint("TOPLEFT", gladdyTotemFrame, "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) + bar:SetPoint("BOTTOMRIGHT", gladdyTotemFrame, "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) if style then - bar.spark:SetHeight(style == "Vertical" and bar:GetParent():GetWidth() or bar:GetParent():GetHeight()) + bar.spark:SetHeight(style == "Vertical" and gladdyTotemFrame:GetWidth() or gladdyTotemFrame:GetHeight()) end + elseif bar.id and gladdyTotemFrame and gladdyTotemFrame:IsShown() and not Gladdy.db.totemPulseTotems["totem" .. bar.id].attachToGladdyTotemFrame then + bar:SetPoint("TOP", gladdyTotemFrame, "BOTTOM", 0, -0.5) else - bar:SetPoint("TOP", bar:GetParent(), "BOTTOM", 0, 0) + bar:SetPoint("TOP", nameplate, "BOTTOM", 0, -0.5) end end bar.bar:SetOrientation(style ~= "COOLDOWN" and style or bar.bar:GetOrientation()) @@ -495,35 +474,26 @@ function TotemPulse:UpdateCooldown(cooldown) cooldown:SetWidth(Gladdy.db.totemPulseCooldownWidth) cooldown:SetHeight(Gladdy.db.totemPulseCooldownHeight) - if cooldown:GetParent() then - --[[if cooldown.id and Gladdy.db.totemPulseTotems["totem" .. cooldown.id].attachToGladdyTotemFrame then - if not cooldown:GetParent().totemIcon and cooldown:GetParent().gladdyTotemFrame then - cooldown:SetParent(cooldown:GetParent().gladdyTotemFrame) - end - elseif cooldown.id and not Gladdy.db.totemPulseTotems["totem" .. cooldown.id].attachToGladdyTotemFrame then - if cooldown:GetParent().totemIcon then - cooldown:SetParent(cooldown:GetParent():GetParent()) - end - end--]] - if cooldown:GetParent().gladdyTotemFrame then - cooldown:SetParent(cooldown:GetParent().gladdyTotemFrame) - else - cooldown:SetParent(cooldown:GetParent()) - end - cooldown:ClearAllPoints() - if cooldown.id and Gladdy.db.totemPulseTotems["totem" .. cooldown.id].attachToGladdyTotemFrame and cooldown:GetParent().totemIcon then - cooldown:SetPoint("TOPLEFT", cooldown:GetParent(), "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) - cooldown:SetPoint("BOTTOMRIGHT", cooldown:GetParent(), "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) - else - cooldown:SetPoint("TOP", cooldown:GetParent(), "BOTTOM", 0, -0.5) - end - end - cooldown.cd:SetCooldown(0,0) cooldown.cd:SetReverse(Gladdy.db.totemPulseCooldownReverse) cooldown.cd:SetAlpha(Gladdy.db.totemPulseCooldownAlpha) + cooldown.text:SetFont(Gladdy:SMFetch("font", "totemPulseTextFont"), Gladdy.db.totemPulseTextSize, "OUTLINE") cooldown.text:SetTextColor(Gladdy:SetColor(Gladdy.db.totemPulseTextColor)) + + if cooldown:GetParent() and cooldown:GetParent() ~= UIParent then + local gladdyTotemFrame = cooldown:GetParent().gladdyTotemFrame and cooldown:GetParent().gladdyTotemFrame + local nameplate = cooldown:GetParent() + cooldown:ClearAllPoints() + if cooldown.id and gladdyTotemFrame and gladdyTotemFrame:IsShown() and Gladdy.db.totemPulseTotems["totem" .. cooldown.id].attachToGladdyTotemFrame then + cooldown:SetPoint("TOPLEFT", gladdyTotemFrame, "TOPLEFT", Gladdy.db.npTotemPlatesSize/16, -Gladdy.db.npTotemPlatesSize/16) + cooldown:SetPoint("BOTTOMRIGHT", gladdyTotemFrame, "BOTTOMRIGHT", -Gladdy.db.npTotemPlatesSize/16, Gladdy.db.npTotemPlatesSize/16) + elseif cooldown.id and gladdyTotemFrame and gladdyTotemFrame:IsShown() and not Gladdy.db.totemPulseTotems["totem" .. cooldown.id].attachToGladdyTotemFrame then + cooldown:SetPoint("TOP", gladdyTotemFrame, "BOTTOM", 0, -0.5) + else + cooldown:SetPoint("TOP", nameplate, "BOTTOM", 0, -0.5) + end + end end function TotemPulse:UpdateFrameOnce() -- 2.39.5 From c6c3d230742f634377cb5035e14d8c571f4444ba Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 00:01:18 +0100 Subject: [PATCH 153/268] add custom tags to PowerBar --- Modules/ExportImport.lua | 1 + Modules/Healthbar.lua | 13 +- Modules/Powerbar.lua | 331 ++++++++++++++++++++++++--------------- Util.lua | 11 +- 4 files changed, 217 insertions(+), 139 deletions(-) diff --git a/Modules/ExportImport.lua b/Modules/ExportImport.lua index 3cc5676..d049d48 100644 --- a/Modules/ExportImport.lua +++ b/Modules/ExportImport.lua @@ -111,6 +111,7 @@ local deletedOptions = { -- backwards compatibility trinketPos = true, padding = true, growUp = true, + powerBarFontSize = true, } local function checkIsDeletedOption(k, str, msg, errorFound, errorMsg) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 4523a87..2e91cba 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -28,7 +28,6 @@ local Healthbar = Gladdy:NewModule("Health Bar", 100, { healthFrameStrata = "MEDIUM", healthFrameLevel = 1, healthCustomTagsEnabled = false, - healthTextRight = "[percent|status]", healthTextLeft = "[name]", healthTextRight = "[percent|status]", healthTextLeftOutline = false, @@ -122,12 +121,13 @@ function Healthbar.OnEvent(self, event, unit) self.hp:SetMinMaxValues(0, healthMax) self.hp:SetValue(health) self.hp.current = health + self.hp.max = healthMax Healthbar:SetText(unit, health, healthMax) --Healthbar:SetHealthText(self, health, healthMax) elseif event == "UNIT_NAME_UPDATE" then local name = UnitName(unit) Gladdy.buttons[unit].name = name - Healthbar:SetText(unit, self.hp.current, 100) + Healthbar:SetText(unit, self.hp.current, self.hp.max) end if not Gladdy.buttons[unit].class then Gladdy:SpotEnemy(unit, true) @@ -245,6 +245,7 @@ function Healthbar:Test(unit) --self:JOINED_ARENA() Gladdy:SendMessage("UNIT_HEALTH", unit, button.health, button.healthMax) healthBar.hp.current = button.health + healthBar.hp.max = button.healthMax self:ENEMY_SPOTTED(unit) self:SetText(unit, button.health, button.healthMax) healthBar.hp:SetValue(button.health) @@ -259,7 +260,7 @@ function Healthbar:UNIT_SPEC(unit) if not button then return end - self:SetText(unit, button.healthBar.hp.current, 100) + self:SetText(unit, button.healthBar.hp.current, button.healthBar.hp.max) --button.healthBar.nameText:SetText(Gladdy:SetTag(unit, Gladdy.db.healthTextLeft, button.health, button.healthMax)) end @@ -282,6 +283,7 @@ function Healthbar:ENEMY_SPOTTED(unit) healthBar.hp:SetMinMaxValues(0, healthMax) healthBar.hp:SetValue(health) healthBar.hp.current = health + healthBar.hp.max = healthMax Healthbar:SetText(unit, health, healthMax) --Healthbar:SetHealthText(healthBar, health, healthMax) end @@ -310,8 +312,7 @@ function Healthbar:UNIT_DESTROYED(unit) healthBar.hp:SetValue(0) healthBar.hp.current = 0 - healthBar.healthText:SetText(L["LEAVE"]) - healthBar.nameText:SetText("") + Healthbar:SetText(unit, 0, 100, L["LEAVE"]) end local function option(params) @@ -455,7 +456,7 @@ function Healthbar:GetOptions() max = 20, width = "full", }), - headerLeftText = { + headerOffsets = { type = "header", name = L["Offsets"], order = 30, diff --git a/Modules/Powerbar.lua b/Modules/Powerbar.lua index 5f48021..786ca59 100644 --- a/Modules/Powerbar.lua +++ b/Modules/Powerbar.lua @@ -16,7 +16,8 @@ local Powerbar = Gladdy:NewModule("Power Bar", 90, { powerBarBorderColor = { r = 0, g = 0, b = 0, a = 1 }, powerBarFontColor = { r = 1, g = 1, b = 1, a = 1 }, powerBarBgColor = { r = 0.3, g = 0.3, b = 0.3, a = 0.7 }, - powerBarFontSize = 10, + powerBarRaceFontSize = 10, + powerBarPowerFontSize = 10, powerShowSpec = true, powerShowRace = true, powerActual = true, @@ -24,6 +25,15 @@ local Powerbar = Gladdy:NewModule("Power Bar", 90, { powerPercentage = false, powerFrameStrata = "MEDIUM", powerFrameLevel = 1, + powerCustomTagsEnabled = false, + powerTextLeft = "[spec] [race]", + powerTextRight = "[current]/[max]", + powerTextLeftOutline = false, + powerTextRightOutline = false, + powerTextLeftVOffset = 1, + powerTextLeftHOffset = 5, + powerTextRightVOffset = 1, + powerTextRightHOffset = -5, }) function Powerbar:Initialize() @@ -72,85 +82,31 @@ function Powerbar:CreateFrame(unit) powerBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.powerBarBgColor)) powerBar.raceText = powerBar:CreateFontString(nil, "LOW") - powerBar.raceText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) + powerBar.raceText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarRaceFontSize, Gladdy.db.powerTextLeftOutline and "OUTLINE") powerBar.raceText:SetTextColor(Gladdy:SetColor(Gladdy.db.powerBarFontColor)) powerBar.raceText:SetShadowOffset(1, -1) powerBar.raceText:SetShadowColor(0, 0, 0, 1) powerBar.raceText:SetJustifyH("CENTER") - powerBar.raceText:SetPoint("LEFT", 5, 1) + powerBar.raceText:SetPoint("LEFT", Gladdy.db.powerTextLeftHOffset, Gladdy.db.powerTextLeftVOffset) powerBar.powerText = powerBar:CreateFontString(nil, "LOW") - powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) + powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarPowerFontSize, Gladdy.db.powerTextRightOutline and "OUTLINE") powerBar.powerText:SetTextColor(Gladdy:SetColor(Gladdy.db.powerBarFontColor)) powerBar.powerText:SetShadowOffset(1, -1) powerBar.powerText:SetShadowColor(0, 0, 0, 1) powerBar.powerText:SetJustifyH("CENTER") - powerBar.powerText:SetPoint("RIGHT", -5, 1) + powerBar.powerText:SetPoint("RIGHT", Gladdy.db.powerTextRightHOffset, Gladdy.db.powerTextRightVOffset) button.powerBar = powerBar self.frames[unit] = powerBar self:ResetUnit(unit) + powerBar.unit = unit powerBar:RegisterUnitEvent("UNIT_POWER_UPDATE", unit) powerBar:RegisterUnitEvent("UNIT_MAXPOWER", unit) powerBar:RegisterUnitEvent("UNIT_DISPLAYPOWER", unit) powerBar:SetScript("OnEvent", Powerbar.OnEvent) end -function Powerbar.OnEvent(powerBar, event, unit) - if event == "UNIT_POWER_UPDATE" then - Powerbar:SetPower(powerBar, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) - elseif event == "UNIT_MAXPOWER" then - Powerbar:SetPower(powerBar, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) - elseif event == "UNIT_DISPLAYPOWER" then - Powerbar:SetPower(powerBar, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) - end -end - -function Powerbar:SetPower(powerBar, power, powerMax, powerType) - local powerPercentage = floor(power * 100 / powerMax) - local powerText - - if (Gladdy.db.powerActual) then - powerText = powerMax > 999 and ("%.1fk"):format(power / 1000) or power - end - - if (Gladdy.db.powerMax) then - local text = powerMax > 999 and ("%.1fk"):format(powerMax / 1000) or powerMax - if (powerText) then - powerText = ("%s/%s"):format(powerText, text) - else - powerText = text - end - end - - if (Gladdy.db.powerPercentage) then - if (powerText) then - powerText = ("%s (%d%%)"):format(powerText, powerPercentage) - else - powerText = ("%d%%"):format(powerPercentage) - end - end - - if (powerType == 1 and powerBar.powerType ~= powerType) then - powerBar.energy:SetStatusBarColor(1, 0, 0, 1) - powerBar.powerColor = {r = 1, g = 0, b = 0} - powerBar.powerType = powerType - elseif (powerType == 3 and powerBar.powerType ~= powerType) then - powerBar.energy:SetStatusBarColor(1, 1, 0, 1) - powerBar.powerColor = {r = 1, g = 1, b = 0} - powerBar.powerType = powerType - elseif powerBar.powerType ~= powerType then - powerBar.energy:SetStatusBarColor(.18, .44, .75, 1) - powerBar.powerColor = {r = .18, g = .44, b = .75} - powerBar.powerType = powerType - end - - powerBar.powerText:SetText(powerText) - powerBar.energy:SetMinMaxValues(0, powerMax) - powerBar.energy:SetValue(power) - -end - function Powerbar:UpdateFrame(unit) local powerBar = self.frames[unit] if (not powerBar) then @@ -182,7 +138,7 @@ function Powerbar:UpdateFrame(unit) powerBar:SetPoint("TOPLEFT", healthBar, "BOTTOMLEFT", 0, -1) powerBar:SetBackdrop({ edgeFile = Gladdy:SMFetch("border", "powerBarBorderStyle"), - edgeSize = Gladdy.db.powerBarBorderSize }) + edgeSize = Gladdy.db.powerBarBorderSize }) powerBar:SetBackdropBorderColor(Gladdy:SetColor(Gladdy.db.powerBarBorderColor)) powerBar.energy:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "powerBarTexture")) @@ -190,10 +146,13 @@ function Powerbar:UpdateFrame(unit) powerBar.energy:SetPoint("TOPLEFT", powerBar, "TOPLEFT", (Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset), -(Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset)) powerBar.energy:SetPoint("BOTTOMRIGHT", powerBar, "BOTTOMRIGHT", -(Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset), (Gladdy.db.powerBarBorderSize/Gladdy.db.statusbarBorderOffset)) - powerBar.raceText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) + powerBar.raceText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarRaceFontSize, Gladdy.db.powerTextLeftOutline and "OUTLINE") powerBar.raceText:SetTextColor(Gladdy:SetColor(Gladdy.db.powerBarFontColor)) - powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarFontSize) + powerBar.raceText:SetPoint("LEFT", Gladdy.db.powerTextLeftHOffset, Gladdy.db.powerTextLeftVOffset) + + powerBar.powerText:SetFont(Gladdy:SMFetch("font", "powerBarFont"), Gladdy.db.powerBarPowerFontSize, Gladdy.db.powerTextRightOutline and "OUTLINE") powerBar.powerText:SetTextColor(Gladdy:SetColor(Gladdy.db.powerBarFontColor)) + powerBar.powerText:SetPoint("RIGHT", Gladdy.db.powerTextRightHOffset, Gladdy.db.powerTextRightVOffset) powerBar:SetFrameStrata(Gladdy.db.powerFrameStrata) powerBar:SetFrameLevel(Gladdy.db.powerFrameLevel) @@ -201,6 +160,83 @@ function Powerbar:UpdateFrame(unit) powerBar.energy:SetFrameLevel(Gladdy.db.powerFrameLevel - 1) end +function Powerbar.OnEvent(powerBar, event, unit) + if event == "UNIT_POWER_UPDATE" then + Powerbar:SetPower(powerBar, unit, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) + elseif event == "UNIT_MAXPOWER" then + Powerbar:SetPower(powerBar, unit, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) + elseif event == "UNIT_DISPLAYPOWER" then + Powerbar:SetPower(powerBar, unit, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) + end +end + +function Powerbar:SetText(unit, power, powerMax, status) + local button = Gladdy.buttons[unit] + if not Gladdy.buttons[unit] then + return + end + local powerBar = button.powerBar + if Gladdy.db.powerCustomTagsEnabled then + powerBar.powerText:SetText(Gladdy:SetTag(unit, Gladdy.db.powerTextRight, power, powerMax, status)) + powerBar.raceText:SetText(Gladdy:SetTag(unit, Gladdy.db.powerTextLeft, power, powerMax, status)) + else + if power then + local powerPercentage = floor(power * 100 / powerMax) + local powerText + if (Gladdy.db.powerActual) then + powerText = powerMax > 999 and ("%.1fk"):format(power / 1000) or power + end + if (Gladdy.db.powerMax) then + local text = powerMax > 999 and ("%.1fk"):format(powerMax / 1000) or powerMax + if (powerText) then + powerText = ("%s/%s"):format(powerText, text) + else + powerText = text + end + end + if (Gladdy.db.powerPercentage) then + if (powerText) then + powerText = ("%s (%d%%)"):format(powerText, powerPercentage) + else + powerText = ("%d%%"):format(powerPercentage) + end + end + powerBar.powerText:SetText(powerText) + end + + local raceText = Gladdy.db.powerShowRace and button.raceLoc or "" + if (button.spec and Gladdy.db.powerShowSpec) then + raceText = button.spec .. " " .. raceText + end + powerBar.raceText:SetText(raceText) + end +end + +function Powerbar:SetPower(powerBar, unit, power, powerMax, powerType, status) + Powerbar:SetText(unit, power, powerMax, status) + powerBar.energy.current = power + powerBar.energy.max = powerMax + powerBar.energy.powerType = powerType + + if (powerType == 1 and powerBar.powerType ~= powerType) then + powerBar.energy:SetStatusBarColor(1, 0, 0, 1) + powerBar.powerColor = {r = 1, g = 0, b = 0} + powerBar.powerType = powerType + elseif (powerType == 3 and powerBar.powerType ~= powerType) then + powerBar.energy:SetStatusBarColor(1, 1, 0, 1) + powerBar.powerColor = {r = 1, g = 1, b = 0} + powerBar.powerType = powerType + elseif powerBar.powerType ~= powerType then + powerBar.energy:SetStatusBarColor(.18, .44, .75, 1) + powerBar.powerColor = {r = .18, g = .44, b = .75} + powerBar.powerType = powerType + end + + powerBar.energy:SetMinMaxValues(0, powerMax) + powerBar.energy:SetValue(power) + +end + function Powerbar:ResetUnit(unit) local powerBar = self.frames[unit] if (not powerBar) then @@ -222,8 +258,14 @@ function Powerbar:Test(unit) return end + powerBar.energy.current = button.power + powerBar.energy.max = button.powerMax + powerBar.energy.powerType = button.powerType self:ENEMY_SPOTTED(unit) self:UNIT_POWER(unit, button.power, button.powerMax, button.powerType) + if unit == "arena1" then + self:UNIT_DEATH(unit) + end end function Powerbar:ENEMY_SPOTTED(unit) @@ -233,13 +275,6 @@ function Powerbar:ENEMY_SPOTTED(unit) return end - local raceText = Gladdy.db.powerShowRace and button.raceLoc or "" - - if (button.spec and Gladdy.db.powerShowSpec) then - raceText = button.spec .. " " .. raceText - end - - powerBar.raceText:SetText(raceText) if UnitExists(unit) then Powerbar:SetPower(powerBar, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) end @@ -251,13 +286,10 @@ function Powerbar:UNIT_SPEC(unit, spec) if (not powerBar or not button) then return end - local raceText = Gladdy.db.powerShowRace and button.raceLoc or "" - if (button.spec and Gladdy.db.powerShowSpec) then - raceText = spec .. " " .. raceText + if UnitExists(unit) then + Powerbar:SetPower(powerBar, unit, powerBar.energy.current, powerBar.energy.max, powerBar.energy.powerType) end - - powerBar.raceText:SetText(raceText) end function Powerbar:UNIT_POWER(unit, power, powerMax, powerType) @@ -269,44 +301,7 @@ function Powerbar:UNIT_POWER(unit, power, powerMax, powerType) if not Gladdy.buttons[unit].class then Gladdy:SpotEnemy(unit, true) end - - local powerPercentage = floor(power * 100 / powerMax) - local powerText - - if (Gladdy.db.powerActual) then - powerText = powerMax > 999 and ("%.1fk"):format(power / 1000) or power - end - - if (Gladdy.db.powerMax) then - local text = powerMax > 999 and ("%.1fk"):format(powerMax / 1000) or powerMax - if (powerText) then - powerText = ("%s/%s"):format(powerText, text) - else - powerText = text - end - end - - if (Gladdy.db.powerPercentage) then - if (powerText) then - powerText = ("%s (%d%%)"):format(powerText, powerPercentage) - else - powerText = ("%d%%"):format(powerPercentage) - end - end - - if (powerType == 1) then - powerBar.energy:SetStatusBarColor(1, 0, 0, 1) - powerBar.powerColor = {r = 1, g = 0, b = 0} - elseif (powerType == 3) then - powerBar.energy:SetStatusBarColor(1, 1, 0, 1) - powerBar.powerColor = {r = 1, g = 1, b = 0} - else - powerBar.energy:SetStatusBarColor(.18, .44, .75, 1) - powerBar.powerColor = {r = .18, g = .44, b = .75} - end - - powerBar.powerText:SetText(powerText) - powerBar.energy:SetValue(powerPercentage) + Powerbar:SetPower(powerBar, unit, power, powerMax, powerType) end function Powerbar:UNIT_DEATH(unit) @@ -314,9 +309,7 @@ function Powerbar:UNIT_DEATH(unit) if (not powerBar) then return end - - powerBar.energy:SetValue(0) - powerBar.powerText:SetText("0%") + Powerbar:SetPower(powerBar, unit, 0, powerBar.energy.max, powerBar.energy.powerType, L["DEAD"]) end function Powerbar:UNIT_DESTROYED(unit) @@ -324,8 +317,7 @@ function Powerbar:UNIT_DESTROYED(unit) if (not powerBar) then return end - powerBar.energy:SetValue(0) - powerBar.powerText:SetText("0%") + Powerbar:SetPower(powerBar, unit, 0, powerBar.energy.max, powerBar.energy.powerType, L["LEAVE"]) end local function option(params) @@ -341,8 +333,10 @@ local function option(params) if Gladdy.db.powerBarBorderSize > Gladdy.db.powerBarHeight/2 then Gladdy.db.powerBarBorderSize = Gladdy.db.powerBarHeight/2 end - for i=1,Gladdy.curBracket do - Powerbar:Test("arena" .. i) + if Gladdy.frame.testing then + for i=1,Gladdy.curBracket do + Powerbar:Test("arena" .. i) + end end Gladdy:UpdateFrame() end, @@ -436,16 +430,84 @@ function Powerbar:GetOptions() order = 12, hasAlpha = true, }), - powerBarFontSize = option({ - type = "range", - name = L["Font size"], - desc = L["Size of the text"], + powerTextLeftOutline = option({ + type = "toggle", + name = L["Left Font Outline"], order = 13, + width = "full", + }), + powerTextRightOutline = option({ + type = "toggle", + name = L["Right Font Outline"], + order = 14, + width = "full", + }), + headerSize = { + type = "header", + name = L["Size"], + order = 20, + }, + powerBarRaceFontSize = option({ + type = "range", + name = L["Race font size"], + desc = L["Size of the race text"], + order = 21, step = 0.1, - min = 1, + min = 0, max = 20, width = "full", }), + powerBarPowerFontSize = option({ + type = "range", + name = L["Power font size"], + desc = L["Size of the power text"], + order = 22, + step = 0.1, + min = 0, + max = 20, + width = "full", + }), + headerOffsets = { + type = "header", + name = L["Offsets"], + order = 30, + }, + powerTextLeftVOffset = option({ + type = "range", + name = L["Left Text Vertical Offset"], + order = 31, + step = 0.1, + min = -200, + max = 200, + width = "full", + }), + powerTextLeftHOffset = option({ + type = "range", + name = L["Left Text Horizontal Offset"], + order = 32, + step = 0.1, + min = -200, + max = 200, + width = "full", + }), + powerTextRightVOffset = option({ + type = "range", + name = L["Right Text Vertical Offset"], + order = 33, + step = 0.1, + min = -200, + max = 200, + width = "full", + }), + powerTextRightHOffset = option({ + type = "range", + name = L["Right Text Horizontal Offset"], + order = 34, + step = 0.1, + min = -200, + max = 200, + width = "full", + }), }, }, border = { @@ -528,31 +590,44 @@ function Powerbar:GetOptions() name = L["Show race"], desc = L["Show race"], order = 2, + disabled = function() return Gladdy.db.powerCustomTagsEnabled end, }), powerShowSpec= option({ type = "toggle", name = L["Show spec"], desc = L["Show spec"], order = 3, + disabled = function() return Gladdy.db.powerCustomTagsEnabled end, }), powerActual = option({ type = "toggle", name = L["Show the actual power"], desc = L["Show the actual power on the power bar"], - order = 31, + order = 4, + disabled = function() return Gladdy.db.powerCustomTagsEnabled end, }), powerMax = option({ type = "toggle", name = L["Show max power"], desc = L["Show max power on the power bar"], - order = 32, + order = 5, + disabled = function() return Gladdy.db.powerCustomTagsEnabled end, }), powerPercentage = option({ type = "toggle", name = L["Show power percentage"], desc = L["Show power percentage on the power bar"], - order = 33, + order = 6, + disabled = function() return Gladdy.db.powerCustomTagsEnabled end, }), + header = { + type = "header", + name = L["Custom Tags"], + order = 10, + }, + powerCustomTagsEnabled = Gladdy:GetTagOption(L["Custom Tags Enabled"], 11, nil, option, true), + powerTextLeft = Gladdy:GetTagOption(L["Left Text"], 12, "powerCustomTagsEnabled", option), + powerTextRight = Gladdy:GetTagOption(L["Right Text"], 13, "powerCustomTagsEnabled", option), }, }, }, diff --git a/Util.lua b/Util.lua index 204e9d0..947a877 100644 --- a/Util.lua +++ b/Util.lua @@ -43,9 +43,9 @@ local function getTagText(unit, tag, current, max, status) if str_find(tag, "percent") then return current and max and floor(current * 100 / max) .. "%%" or "" elseif str_find(tag, "current") then - return current or "" + return current and max > 999 and ("%.1fk"):format(current / 1000) or current or "" elseif str_find(tag, "max") then - return max or "" + return max and max > 999 and ("%.1fk"):format(max / 1000) or max or "" elseif str_find(tag, "status") then if str_find(tag, "%|") and status == nil then return nil @@ -55,11 +55,12 @@ local function getTagText(unit, tag, current, max, status) elseif str_find(tag, "name") then return button.name or "" elseif str_find(tag, "class") then - return button.classLoc or "" + return button.classLoc or "" elseif str_find(tag, "race") then - return button.raceLoc or "" + return button.raceLoc or "" elseif str_find(tag, "arena") then - return str_gsub(unit, "arena", "") + local str,found = str_gsub(unit, "arena", "") + return found == 1 and str or "" elseif str_find(tag, "spec") then if str_find(tag, "%|") and button.spec == nil then return nil -- 2.39.5 From 10caa05e314cf3d7ac18deaa933ab1369e36c213 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 00:02:25 +0100 Subject: [PATCH 154/268] cooldowns test only active icons --- Modules/Cooldowns.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 3b8bf5a..5bcee89 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -311,13 +311,17 @@ end function Cooldowns:UpdateTestCooldowns(unit) local button = Gladdy.buttons[unit] self:UpdateCooldowns(button) - -- use class spells - for spellId,_ in pairs(Gladdy:GetCooldownList()[button.class]) do - self:CooldownUsed(unit, button.class, spellId) + + local orderedIcons = {} + for _,icon in pairs(button.spellCooldownFrame.icons) do + tinsert(orderedIcons, icon) end - -- use race spells - for spellId,_ in pairs(Gladdy:GetCooldownList()[button.race]) do - self:CooldownUsed(unit, button.race, spellId) + tbl_sort(orderedIcons, function(a, b) + return Gladdy.db.cooldownCooldownsOrder[button.class][tostring(a.spellId)] < Gladdy.db.cooldownCooldownsOrder[button.class][tostring(b.spellId)] + end) + + for _,icon in ipairs(orderedIcons) do + self:CooldownUsed(unit, button.class, icon.spellId) end end -- 2.39.5 From 5b32b8c79311edd403a0e125afb83fdc6d95c1fc Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 15:59:43 +0100 Subject: [PATCH 155/268] grouping auras, interrupts, classicon, racial, trinket --- Modules/Auras.lua | 97 +++++++++++++++++++++++++++++++++++++++++-- Modules/Classicon.lua | 38 ++++++++++++++--- Modules/Cooldowns.lua | 15 +++++-- Modules/Pets.lua | 10 ++--- Modules/Racial.lua | 42 ++++++++++++++++++- Modules/Trinket.lua | 40 +++++++++++++++++- 6 files changed, 222 insertions(+), 20 deletions(-) diff --git a/Modules/Auras.lua b/Modules/Auras.lua index 5d33667..bbe428a 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -1,5 +1,5 @@ local pairs, ipairs, select, tinsert, tbl_sort, tostring, tonumber, rand = pairs, ipairs, select, tinsert, table.sort, tostring, tonumber, math.random - +local str_gsub = string.gsub local GetSpellInfo = GetSpellInfo local GetSpellDescription = GetSpellDescription local CreateFrame, GetTime = CreateFrame, GetTime @@ -56,6 +56,10 @@ local Auras = Gladdy:NewModule("Auras", nil, { auraFrameLevel = 5, auraInterruptFrameStrata = "MEDIUM", auraInterruptFrameLevel = 5, + auraGroup = false, + auraGroupDirection = "DOWN", + auraInterruptGroup = false, + auraInterruptGroupDirection = "DOWN", }) function Auras:Initialize() @@ -239,6 +243,23 @@ function Auras:UpdateFrame(unit) auraFrame:ClearAllPoints() Gladdy:SetPosition(auraFrame, unit, "auraXOffset", "auraYOffset", true, Auras) + + if (Gladdy.db.auraGroup) then + if (unit ~= "arena1") then + local previousUnit = "arena" .. str_gsub(unit, "arena", "") - 1 + self.frames[unit]:ClearAllPoints() + if Gladdy.db.auraGroupDirection == "RIGHT" then + self.frames[unit]:SetPoint("LEFT", self.frames[previousUnit], "RIGHT", 0, 0) + elseif Gladdy.db.auraGroupDirection == "LEFT" then + self.frames[unit]:SetPoint("RIGHT", self.frames[previousUnit], "LEFT", 0, 0) + elseif Gladdy.db.auraGroupDirection == "UP" then + self.frames[unit]:SetPoint("BOTTOM", self.frames[previousUnit], "TOP", 0, 0) + elseif Gladdy.db.auraGroupDirection == "DOWN" then + self.frames[unit]:SetPoint("TOP", self.frames[previousUnit], "BOTTOM", 0, 0) + end + end + end + if (unit == "arena1") then Gladdy:CreateMover(auraFrame, "auraXOffset", "auraYOffset", L["Auras"], {"TOPLEFT", "TOPLEFT"}, @@ -321,6 +342,23 @@ function Auras:UpdateInterruptFrame(unit) interruptFrame:ClearAllPoints() Gladdy:SetPosition(interruptFrame, unit, "auraInterruptXOffset", "auraInterruptYOffset", true, Auras) + + if (Gladdy.db.auraInterruptGroup) then + if (unit ~= "arena1") then + local previousUnit = "arena" .. str_gsub(unit, "arena", "") - 1 + self.frames[unit].interruptFrame:ClearAllPoints() + if Gladdy.db.auraInterruptGroupDirection == "RIGHT" then + self.frames[unit].interruptFrame:SetPoint("LEFT", self.frames[previousUnit].interruptFrame, "RIGHT", 0, 0) + elseif Gladdy.db.auraInterruptGroupDirection == "LEFT" then + self.frames[unit].interruptFrame:SetPoint("RIGHT", self.frames[previousUnit].interruptFrame, "LEFT", 0, 0) + elseif Gladdy.db.auraInterruptGroupDirection == "UP" then + self.frames[unit].interruptFrame:SetPoint("BOTTOM", self.frames[previousUnit].interruptFrame, "TOP", 0, 0) + elseif Gladdy.db.auraInterruptGroupDirection == "DOWN" then + self.frames[unit].interruptFrame:SetPoint("TOP", self.frames[previousUnit].interruptFrame, "BOTTOM", 0, 0) + end + end + end + if (unit == "arena1") then Gladdy:CreateMover(interruptFrame, "auraInterruptXOffset", "auraInterruptYOffset", L["Interrupts"], {"TOPLEFT", "TOPLEFT"}, @@ -682,10 +720,63 @@ function Auras:GetOptions() name = L["Frame"], order = 3, args = { + groupOptions = { + type = "group", + name = L["Group"], + order = 4, + args = { + headerAuras = { + type = "header", + name = L["Auras"], + order = 1, + }, + auraGroup = Gladdy:option({ + type = "toggle", + name = L["Group"] .. " " .. L["Auras"], + order = 2, + disabled = function() return not Gladdy.db.auraDetached end, + }), + auraGroupDirection = Gladdy:option({ + type = "select", + name = L["Group direction"], + order = 3, + values = { + ["RIGHT"] = L["Right"], + ["LEFT"] = L["Left"], + ["UP"] = L["Up"], + ["DOWN"] = L["Down"], + }, + disabled = function() return not Gladdy.db.auraGroup or not Gladdy.db.auraDetached end, + }), + headerInterrupts = { + type = "header", + name = L["Interrupts"], + order = 4, + }, + auraInterruptGroup = Gladdy:option({ + type = "toggle", + name = L["Group"] .. " " .. L["Interrupts"], + order = 5, + disabled = function() return not Gladdy.db.auraInterruptDetached end, + }), + auraInterruptGroupDirection = Gladdy:option({ + type = "select", + name = L["Group direction"], + order = 6, + values = { + ["RIGHT"] = L["Right"], + ["LEFT"] = L["Left"], + ["UP"] = L["Up"], + ["DOWN"] = L["Down"], + }, + disabled = function() return not Gladdy.db.auraInterruptGroup or not Gladdy.db.auraInterruptDetached end, + }), + } + }, detachedAuraMode = { type = "group", name = L["Detached Aura"], - order = 4, + order = 5, args = { headerDetachedMode = { type = "header", @@ -789,7 +880,7 @@ function Auras:GetOptions() detachedInterruptMode = { type = "group", name = L["Detached Interrupt"], - order = 5, + order = 6, args = { headerDetachedMode = { type = "header", diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index d9c476a..abaa060 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -1,4 +1,4 @@ -local select = select +local select, str_gsub = select, string.gsub local Gladdy = LibStub("Gladdy") local CreateFrame = CreateFrame @@ -16,7 +16,7 @@ local Classicon = Gladdy:NewModule("Class Icon", 81, { classIconFrameStrata = "MEDIUM", classIconFrameLevel = 5, classIconGroup = false, - classIconGroupDirection = "RIGHT" + classIconGroupDirection = "DOWN" }) local classIconPath = "Interface\\Addons\\Gladdy\\Images\\Classes\\" @@ -137,9 +137,17 @@ function Classicon:UpdateFrame(unit) if (Gladdy.db.classIconGroup) then if (unit ~= "arena1") then - local previousUnit = "arena" .. string.gsub(unit, "arena", "") - 1 + local previousUnit = "arena" .. str_gsub(unit, "arena", "") - 1 self.frames[unit]:ClearAllPoints() - self.frames[unit]:SetPoint("LEFT", self.frames[previousUnit], "RIGHT", 0, 0) + if Gladdy.db.classIconGroupDirection == "RIGHT" then + self.frames[unit]:SetPoint("LEFT", self.frames[previousUnit], "RIGHT", 0, 0) + elseif Gladdy.db.classIconGroupDirection == "LEFT" then + self.frames[unit]:SetPoint("RIGHT", self.frames[previousUnit], "LEFT", 0, 0) + elseif Gladdy.db.classIconGroupDirection == "UP" then + self.frames[unit]:SetPoint("BOTTOM", self.frames[previousUnit], "TOP", 0, 0) + elseif Gladdy.db.classIconGroupDirection == "DOWN" then + self.frames[unit]:SetPoint("TOP", self.frames[previousUnit], "BOTTOM", 0, 0) + end end end @@ -228,11 +236,31 @@ function Classicon:GetOptions() end end }, + classIconGroup = Gladdy:option({ + type = "toggle", + name = L["Group"] .. " " .. L["Class Icon"], + order = 5, + disabled = function() return not Gladdy.db.classIconEnabled end, + }), + classIconGroupDirection = Gladdy:option({ + type = "select", + name = L["Group direction"], + order = 6, + values = { + ["RIGHT"] = L["Right"], + ["LEFT"] = L["Left"], + ["UP"] = L["Up"], + ["DOWN"] = L["Down"], + }, + disabled = function() + return not Gladdy.db.classIconGroup or not Gladdy.db.classIconEnabled + end, + }), group = { type = "group", childGroups = "tree", name = L["Frame"], - order = 4, + order = 7, disabled = function() return not Gladdy.db.classIconEnabled end, args = { size = { diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index 5bcee89..e915321 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -236,6 +236,7 @@ function Cooldowns:UpdateFrame(unit) end if (Gladdy.db.cooldownGroup) then + --TODO fix overlapping if (unit ~= "arena1") then local previousUnit = "arena" .. string.gsub(unit, "arena", "") - 1 self.frames[unit]:ClearAllPoints() @@ -552,6 +553,12 @@ function Cooldowns:GetOptions() desc = L["Enabled cooldown module"], order = 2, }), + cooldownGroup = Gladdy:option({ + type = "toggle", + name = L["Group"] .. " " .. L["Cooldown"], + order = 3, + disabled = function() return not Gladdy.db.cooldown end, + }), group = { type = "group", childGroups = "tree", @@ -858,8 +865,8 @@ function Cooldowns:GetCooldownOptions() order = 2, width = 0.1, image = "Interface\\Addons\\Gladdy\\Images\\uparrow", - imageWidth = 20, - imageHeight = 20, + imageWidth = 15, + imageHeight = 15, func = function() if (Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] > 1) then local current = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] @@ -883,8 +890,8 @@ function Cooldowns:GetCooldownOptions() order = 3, width = 0.1, image = "Interface\\Addons\\Gladdy\\Images\\downarrow", - imageWidth = 20, - imageHeight = 20, + imageWidth = 15, + imageHeight = 15, func = function() if (Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] < tblLength) then local current = Gladdy.db.cooldownCooldownsOrder[class][tostring(spellId)] diff --git a/Modules/Pets.lua b/Modules/Pets.lua index d54ceab..4e9d648 100644 --- a/Modules/Pets.lua +++ b/Modules/Pets.lua @@ -389,6 +389,11 @@ function Pets:GetOptions() desc = L["Enables Pets module"], order = 3, }), + petGroup = option({ + type = "toggle", + name = L["Group Pets"], + order = 4, + }), group = { type = "group", childGroups = "tree", @@ -426,11 +431,6 @@ function Pets:GetOptions() step = 1, width = "full", }), - petGroup = option({ - type = "toggle", - name = L["Group Pets"], - order = 5, - }), petMargin = option({ type = "range", name = L["Margin"], diff --git a/Modules/Racial.lua b/Modules/Racial.lua index ac8bc50..335b3fe 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -1,4 +1,4 @@ -local ceil = ceil +local ceil, str_gsub = ceil, string.gsub local CreateFrame = CreateFrame local GetTime = GetTime @@ -20,6 +20,8 @@ local Racial = Gladdy:NewModule("Racial", 79, { racialCooldownNumberAlpha = 1, racialFrameStrata = "MEDIUM", racialFrameLevel = 5, + racialGroup = false, + racialGroupDirection = "DOWN", }) @@ -153,6 +155,22 @@ function Racial:UpdateFrame(unit) Gladdy:SetPosition(racial, unit, "racialXOffset", "racialYOffset", Racial:LegacySetPosition(racial, unit), Racial) + if (Gladdy.db.racialGroup) then + if (unit ~= "arena1") then + local previousUnit = "arena" .. str_gsub(unit, "arena", "") - 1 + self.frames[unit]:ClearAllPoints() + if Gladdy.db.racialGroupDirection == "RIGHT" then + self.frames[unit]:SetPoint("LEFT", self.frames[previousUnit], "RIGHT", 0, 0) + elseif Gladdy.db.racialGroupDirection == "LEFT" then + self.frames[unit]:SetPoint("RIGHT", self.frames[previousUnit], "LEFT", 0, 0) + elseif Gladdy.db.racialGroupDirection == "UP" then + self.frames[unit]:SetPoint("BOTTOM", self.frames[previousUnit], "TOP", 0, 0) + elseif Gladdy.db.racialGroupDirection == "DOWN" then + self.frames[unit]:SetPoint("TOP", self.frames[previousUnit], "BOTTOM", 0, 0) + end + end + end + if (unit == "arena1") then Gladdy:CreateMover(racial,"racialXOffset", "racialYOffset", L["Racial"], {"TOPLEFT", "TOPLEFT"}, @@ -241,11 +259,31 @@ function Racial:GetOptions() desc = L["Enable racial icon"], order = 3, }), + racialGroup = Gladdy:option({ + type = "toggle", + name = L["Group"] .. " " .. L["Racial"], + order = 4, + disabled = function() return not Gladdy.db.racialEnabled end, + }), + racialGroupDirection = Gladdy:option({ + type = "select", + name = L["Group direction"], + order = 5, + values = { + ["RIGHT"] = L["Right"], + ["LEFT"] = L["Left"], + ["UP"] = L["Up"], + ["DOWN"] = L["Down"], + }, + disabled = function() + return not Gladdy.db.racialGroup or not Gladdy.db.racialEnabled + end, + }), group = { type = "group", childGroups = "tree", name = L["Frame"], - order = 4, + order = 6, disabled = function() return not Gladdy.db.racialEnabled end, args = { general = { diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index 13f7f49..fd14d10 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -1,4 +1,4 @@ -local ceil = ceil +local ceil, str_gsub = ceil, string.gsub local C_PvP = C_PvP local CreateFrame = CreateFrame @@ -25,6 +25,8 @@ local Trinket = Gladdy:NewModule("Trinket", 80, { trinketColored = false, trinketColoredCd = { r = 1, g = 0, b = 0, a = 1 }, trinketColoredNoCd = { r = 0, g = 1, b = 0, a = 1 }, + trinketGroup = false, + trinketGroupDirection = "DOWN", }) function Trinket:Initialize() @@ -175,6 +177,22 @@ function Trinket:UpdateFrame(unit) Gladdy:SetPosition(trinket, unit, "trinketXOffset", "trinketYOffset", Trinket:LegacySetPosition(trinket, unit), Trinket) + if (Gladdy.db.trinketGroup) then + if (unit ~= "arena1") then + local previousUnit = "arena" .. str_gsub(unit, "arena", "") - 1 + self.frames[unit]:ClearAllPoints() + if Gladdy.db.trinketGroupDirection == "RIGHT" then + self.frames[unit]:SetPoint("LEFT", self.frames[previousUnit], "RIGHT", 0, 0) + elseif Gladdy.db.trinketGroupDirection == "LEFT" then + self.frames[unit]:SetPoint("RIGHT", self.frames[previousUnit], "LEFT", 0, 0) + elseif Gladdy.db.trinketGroupDirection == "UP" then + self.frames[unit]:SetPoint("BOTTOM", self.frames[previousUnit], "TOP", 0, 0) + elseif Gladdy.db.trinketGroupDirection == "DOWN" then + self.frames[unit]:SetPoint("TOP", self.frames[previousUnit], "BOTTOM", 0, 0) + end + end + end + if (unit == "arena1") then Gladdy:CreateMover(trinket,"trinketXOffset", "trinketYOffset", L["Trinket"], {"TOPLEFT", "TOPLEFT"}, @@ -299,6 +317,26 @@ function Trinket:GetOptions() hasAlpha = true, disabled = function() return not Gladdy.db.trinketEnabled end, }), + trinketGroup = Gladdy:option({ + type = "toggle", + name = L["Group Class Icons"], + order = 7, + disabled = function() return not Gladdy.db.trinketEnabled end, + }), + trinketGroupDirection = Gladdy:option({ + type = "select", + name = L["Group direction"], + order = 8, + values = { + ["RIGHT"] = L["Right"], + ["LEFT"] = L["Left"], + ["UP"] = L["Up"], + ["DOWN"] = L["Down"], + }, + disabled = function() + return not Gladdy.db.trinketGroup or not Gladdy.db.trinketEnabled + end, + }), group = { type = "group", childGroups = "tree", -- 2.39.5 From eddd7588f426e1bac71bf4e4fc47dc2812336786 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 16:36:27 +0100 Subject: [PATCH 156/268] #31 frames expand a centric point option added --- Frame.lua | 9 +++++++-- Options.lua | 9 ++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Frame.lua b/Frame.lua index 2713510..e236d2e 100644 --- a/Frame.lua +++ b/Frame.lua @@ -134,6 +134,8 @@ function Gladdy:UpdateFrame() local height = (self.db.healthBarHeight + powerBarHeight) * teamSize + (self.db.highlightInset and 0 or self.db.highlightBorderSize * 2 * teamSize) + self.db.bottomMargin * (teamSize - 1) + local singleFrameHeight = self.db.healthBarHeight + powerBarHeight + + (self.db.highlightInset and 0 or self.db.highlightBorderSize * 2) + self.db.bottomMargin -- Highlight margin = margin + highlightBorderSize @@ -155,10 +157,13 @@ function Gladdy:UpdateFrame() self.frame:SetPoint("CENTER") else local scale = self.frame:GetEffectiveScale() + local growMiddle = self.db.growMiddle and teamSize > 0 and teamSize / 2 >= 1 and (teamSize - 1) * (singleFrameHeight / 2) or 0 if (self.db.growDirection == "TOP") then - self.frame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", self.db.x / scale, self.db.y / scale) + self.frame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", self.db.x / scale, (self.db.y / scale) - growMiddle) + elseif self.db.growDirection == "BOTTOM" then + self.frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", self.db.x / scale, (self.db.y / scale) + growMiddle) else - self.frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", self.db.x / scale, self.db.y / scale) + self.frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", self.db.x / scale, (self.db.y / scale)) end end diff --git a/Options.lua b/Options.lua index ea4c3a3..78f78e1 100644 --- a/Options.lua +++ b/Options.lua @@ -48,6 +48,7 @@ Gladdy.defaults = { x = 0, y = 0, growDirection = "BOTTOM", + growMiddle = false, frameScale = 1, pixelPerfect = false, barWidth = 180, @@ -311,7 +312,7 @@ function Gladdy:SetupOptions() group = { type = "group", name = L["General"], - order = 5, + order = 6, childGroups = "tree", args = { frameGeneral = { @@ -322,6 +323,12 @@ function Gladdy:SetupOptions() headerFrame = { type = "header", name = L["Frame General"], + order = 2, + }, + growMiddle = { + type = "toggle", + name = L["Grow Middle"], + desc = L["Frames expand along a centric anchor"], order = 3, }, pixelPerfect = { -- 2.39.5 From 15fb697258d93e454120de4bc8d74aef7588866a Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 17:02:37 +0100 Subject: [PATCH 157/268] readme + version --- Gladdy.lua | 2 +- Gladdy.toc | 6 +++--- README.md | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 808b2c3..0270772 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -31,7 +31,7 @@ local MAJOR, MINOR = "Gladdy", 5 local Gladdy = LibStub:NewLibrary(MAJOR, MINOR) local L Gladdy.version_major_num = 2 -Gladdy.version_minor_num = 0.00 +Gladdy.version_minor_num = 0.10 Gladdy.version_num = Gladdy.version_major_num + Gladdy.version_minor_num Gladdy.version_releaseType = RELEASE_TYPES.release Gladdy.version = PREFIX .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType diff --git a/Gladdy.toc b/Gladdy.toc index 9fe7adc..098d2c1 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -1,7 +1,7 @@ -## Interface: 20503 +## Interface: 20504 ## Title: Gladdy - TBC -## Version: 2.00-Release -## Notes: The most powerful arena AddOn for WoW 2.5.3 +## Version: 2.10-Release +## Notes: The most powerful arena AddOn for WoW 2.5.4 ## Author: XiconQoo, DnB_Junkee, Knall ## X-Email: contact me on discord Knall#1751 ## SavedVariables: GladdyXZ diff --git a/README.md b/README.md index 2c4d356..9fc6876 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Gladdy - TBC -### The most powerful arena addon for WoW TBC 2.5.1 +### The most powerful arena addon for WoW TBC 2.5.4 --- -## [v2.00-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v2.00-Release/Gladdy_TBC-Classic_v2.00-Release.zip) +## [v2.10-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v2.10-Release/Gladdy_TBC-Classic_v2.10-Release.zip) ###### Please consider donating if you like my work @@ -78,6 +78,36 @@ Thank you! ### Changes +### v2.10-Release + +- **Totems**: + - added new module **TotemPulse** (sorry Shamans) + - displays pulse ticks on all totems that have a pulse mechanic (e.g. tremor totem) + - either cooldown or bar style + - attaches to TotemPlates if enabled (con be configured individually by totem) + - completely hide totem nameplate option added + - added a dummy totemplate in config mode + - totem detection is completely localization independent now +- **Cooldowns**: + - completely refactored to fix general bugs + - can now be ordered individually + - some cooldown tracking improved for units coming out of stealth (e.g. perception, sprint, shadowstep) +- **Custom Text Tags** + - PowerBar and HealthBar can now have custom tags. Check it out + - also the texts can be moved to achieve a Blizzlike style with names above HealthBar +- general improvements to spec detection + - no more restoration warlocks :D + - tree of life spec detection should work now +- fix Announcements +- added grouping option for Auras (+ Interrupts) in detached mode, ClassIcon, Cooldowns, Trinket, Racial +- added a "Grow Middle" option, which aligns the gladdy frames on a centric point +- added frFR localization by Macumba +- added Flat statusbar texture +- added some auras (e.g. disarm) +- added disarm DRs +- improved some class icons +- fixed health bug since 2.5.4 + ### v2.00-Release This is a packed release with new features and bugfixes. Most importantly, positioning of all elements has been redone with movable frames. -- 2.39.5 From f283ea994a6586fe845f002591cb2cf158c861c3 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 17:16:17 +0100 Subject: [PATCH 158/268] updated Mir Profile --- ImportStrings.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ImportStrings.lua b/ImportStrings.lua index effd467..fef1286 100644 --- a/ImportStrings.lua +++ b/ImportStrings.lua @@ -25,7 +25,7 @@ function Gladdy:GetRukkProfile() end function Gladdy:GetMirProfile() - return "4XzT80SCBJZKpm75XfXpee4OvsCIRnXXRLtntQAkndLeTf3ir6LKAZ45qE2)AGUbjejLIyIZLiAsGgn6Ur)pYc2I7xmF5(hEOEM9FUEvzXTPRxNx84IBylMxLw8y2R2KT6l3w(1SQzPv3N9pnlMTy(Q06g4pNvwToR6vLBlRSqk1nRLlUjAX8hD)BL9FBwmFnmOYTRl)AXLBFAdoU1vVoVoD52SxLxTABwiyFmeKrxihhOnv5fFjR5qOSCX8nzPBB2aW5M0Dzxvw0mp)FZwCdhMAXt3x2KT72TPnz1ou5YTFn9567tREmRjBTD6vPRYt3EBz9I53D9BF39wm1bLvPa8rmh34ZBEgEZ8RlAYQEiDv2FE561FSO(pF7wGi(8FE9U0hZQ)tCS)1B3wwdGSEtkqgQZFCtZ957ay0c1o(GNw92QYV(68QSvn5LfTyZ)Fwvn83)1U0)3YQ)Qy)o3SF8WXo7J3F)h)GBdxLTR0Tbwm)1Lv513E7I5pL185pcRuwZIB(nfhOZ7RsFFEDZRZEiD)2glPxLKez)nRWsExB5ppvLdqO55f3iJS0)0vFba6BM9PRUYYq4jCUyAtHXfXXtBkczsK5OtHf3oL21isePN2AehlM4ExWuk20McxOmYPnfbJXsoN9EifwFcY14mLyPEIRcpMNm19IKDCcglAaBuejJpoBCe(U2OpU0Oyu2UupXnHugjpoPA0fHfjp(ImY(wZ48PHujSjk8cYHhFgm(WtuAP6SocgSRncTAAyvmxE8zm(IOmtLwXL84PUv0IPQLtdRYexePyYhB1QtCa5i6t48JlmYhkmYnGEUPi9YmXrtLAPmjhFRp6zkUYON6uIILtLaNKmrryM4e2rgxrA0uTjacxMZsVyOnbU54Ntgrvkpk6eS9JOEpEQQHatv8jUkSiEYj28JzfHFcRcJVgM4KJRJ)iwq5Nqb5rCEksF8DY4IW6KPkEjKsZeNcdusC8PmkIznvprhieGfLJlsoMMOKOtiFno9IhpvxAfIKPA2si4rtsfjxyobboE4eIJoHs7ro9QIMOl2jt2mQqimhFrgLBiJLIJlWpchxjNKaIsmvRHMOPsO0k5evMOzNqF1yI5k1PC1AeHJe904DnTXD3lirxaP)HpmXOJh9SnQ5UOxdNXQTP1U0kmitbxj1ArsuCCc4MNWAy9HFlwmEG(D5H4EmKF7cgGZU47VsMWzmJsbM24MyvcaqP2gSE)0AGOAhcDje7lIuJL(Il0wu4jkbiVlZg5oYPW8mCBw1QSIgiuFlw5hxxAhSSiiC735tkXzNZehO(q6)0rD7Mz9B64UvU8v875RB2Cv6QMshsBWq6DPMOA)tn4SGf8gw3Q288tzlMF7MNRZxLU1TYmhw4Xi7gT)WFx52NdgkSur0WVigEcMIS)uUkVk7GPehfScQbJ)YQvPfJpd3cO7pHBsB2tlr0fGf(WnH7VHjjgStM7sfdnl3cmyPMVV4lfLFTO)u)e9AKzrmo)gIPgqaQkRB6TqDlI9ay(LfR2aSUUKxzLCd4YDNVoGtZOZZzRFDMBi2LwhbgnMzDokXKyFWEGW4EJguSpZN6b4HeBuzWV2SWmZQ8q5Mj3a61SJN(1fy8mRgsHBCmbNPDZ3boxiQ2PXGyJCV2GViMjCdJ(ogeOD58RNneVzohgW1tAyUfIhLGisedFqirazJ9AMZblesQeTgHGqIdWgQ1mVXE3APtW5QIzm3N8Vaqp3V4EbdvXodoHMkbIwczKJ8PnChaCbc4aDI0TyA)Q787d3Prke2efvQKitbu5HyrSX4gRKrOm6Sb8qS29bLMGLkX99KiIkc8t3dcGWJBAUYncNfm3QbET5(chxuUNGBtS1mhDfxk0Z(zizY9GrJKnxQMCZvJ7(yo(lMEOzoRFj0lICpOqiW1ib1Uiizbqp8bJb3k28MGiOGKrviTNRej0wIJVWK4MkW7qckiuJduHpKGteZjHf0rAexmOOQIKfzW2OvO2bsftq8igkietIma5cxCDmodqwc5ijilHyC4xbIoIYmLBljureuK0HSi3pGlsoepItqfy7mcHyinhCPffffcsyHhtKsdrjtm0bbj(aMad7Bs0jeEiqwkdpRWt4Oym8dbLegsBsek64gttcYXejHth7SXl4WXe)jzego)mSBoIKrJZRxH51JGuAbUnur06ICeLo2HXcgjXd0z8WrcncINNWiXhcnHTirItCNidSqF22x7Nj(bkBNGllTQ0Ri7gKRs1Z3u(1RQYZkwdwnxIPP)tpHLzW7uZR8ojD4R91CXIqBo07bQWdyDg(2FFFz52M8N(2FxvUVynynHQFWbfd5mlQIFUwhyogrmyF2vyhxbtE)BUcg(2sRbPXiKVAFvD2bqKDGVwQdD37JLvTg6UigDPzyLmADTACCEmEtBnrcDw9zGdhZngUa0jAKGUvT1hsGd)plUsl1kHIdkYatF2i1XV0Fd26m13XFYLLnnL7(qA1J5foFtMtvZQ32l4TDvkQXvTQVJGoSoT7ylDZ67WuePdrAhqCu6oVFxL3s7(njOWRL5Cgsnl)(v5Q94CpX2eVxD0Uu496RffNM8oE(WwPqR866Q3LU9HZyhqrFyp1oPQa6oHMT(VwU9PXINcpd4H(i4Xf8HC3aCz6S2Ow(rOuCzEDzXOsvQfbf1DkS7x)Cr6U8v4WNzv0SVOXPLAwNwNHvjUv)Lx2tffQHOLD7RmnDGjqzUtsYQhgepw5ujcaARfyhOmD()3(0QSV93xTF72V93)(M8MmcZ7qgmuRdcWLq4(oLJJ8h98wVOEd2m(17pcu3EGyuFePncC7U3BK5qBLyCQs3Xh30HjcQ(Axl87X(nLpsfIshqpVUOgJnVlyLoAxFZT)HBZEGMGUbhQI(ZbK7LqOop6odDWH7XjGUD5LRA2dQJBRRVNwUC0aK77dGvSXMEaFWvlTs99jXGnqGY)iOYoZf(v92SSNSpeKcMhkRwL5j)52FVb8slYG2CBQ2w3SV4CMtSr5u1vvSU)uwESPOv4YSjTA35SgkBcmTRrzzZ5m(yW4iHt9NYXXjj3HtpVABzr25Skkge6G1VTvPnatR(CMdNf7OwRb9zwVWoRTJkkbJ9p9CgDSbrR1vPpwwuVSklfobDgtus42xoVDc34OXRxDoJwXKoKkF3tWBoRP4LsEilT6CgVnw)fUKx0E(3PAjWe8Pnney(1PE3(qqAZ4DQPc1)L)tPt1EKFq)cr2p7AiM4Kf96kkeNerdnvE9UD7lY6zKgcpeTwAtfL3kiQ)bHK2QzoVxo7ID9efGHohHUbiVdwTRkXtWNY1Yv590X9d0Ssh4MIV3GA1v6eyvXXNSeIn2W14NQvhCJHZeNS87wWKCQsotRKnfjNEm6Otu)aCijFVbi4jNODpCJP5WKaFEXJ0gR4BkY25cumTOa4bRY2bkTC0BYC7DzPRDdOM8MjZpdAaFQg584jlNfRmBYhFkTQXM42S69vKZ2K9myA1DZ4(nWq2agKDU53k32lUKhQapMPisqNcBhvVoAl08D)WyDNfmwfmR2tI5UTwpxfEpgp5YEU6q(Te1Ec2ny7rK0gVVrwz3HUx0)yfOsilTxGPEhELlccnLwOqVlhKA)VxW5D1T4mKnwx9)aUL2CQ48swmAKTDvFGwXapg9E29H0)XQDR(wGgNxqd3rCcuH4(7ES)n5RZMTn)F)30kylb(nxK2b1bkyxxDd4u9PtjtxGcNzqf0UYkx)LZGqEGJMosX9F0gFDOitdCwBtDx)DEEgzgSu9fFVlBleqvrdmKx9MBU)n3DiYpAs(dp1qhS772PpEBlJU9KOPJn8dO2N6r1(5ujKXpXCT0g(r)6tf3UVc70wpU)5oouyK2TwHx3hVwxfsXO50gOMugeQwy4BOwRrI6SxiI4zPa8Bam(bO2hyKLqzFuU2nziBim631v)Xy6u7N5iRw)zbNP60l7n4q(RfCwVnw57aKVZMafFTRgBZ3bU4Vja7ckaQvFOVqRDcUt5W0qp2S6wELpxbuNChRged7zP0nKBkAXVHS)rYVGDVHC6bQ3wowv58oQ(JlrGKEQaWRYBJcVlIE0vs(bACUK8BySSQ48JaBsB4RTvhuWmyv9WEy2(qKMgJV2pT18XM5DCWsSyAunFGPQPAKPPP6RPNR9PMfwGIiSQacjvPebttfksqdraci0S9Lm0wzp7d(AgYI0uPjumFnkIPY1jPQecVbRArIVsc6eScloVbj0KQDjwEgSLiTVW1QJoKYeDybcDEKAhlpMklzuevMpfwsN261is81IL3vafFz8ueJqGWxa7AK(Zui1UT8lCUVuFQwSIynIijvDePGQVPstvouXWQJYK(cNKy4eAiPsSiz(YgXWYkInW0mFh64gmv2oakk3SuerRT6Hq4aoKW1rmUrkn(60rLe1vrPtyFK3zFmu13anpq4)v5l33K11pdGZWB3UyoOAZMi35415ybmH15pKdovo3EkTPbcRAU1YjLQzmp6l8D5qpGCL1P0XHbVdgoxxTGqmciU0nOV93)xIXHthywJkvwVW3)ehdsYPaP4tbP4Paj1PGKAkqk5uqkzkqsFkiPNcKmNcsMPajSLepgOSUxF2WQn0RppSfSWSv6cl0(NGUY(nvwAy5e2x3uUZLH85wRcNYp8iCLDGLfd2i(faxnBq)0ojWEHXxfKyXaGlIsg0(Ltc6hfPh04SViGvl6N4IxcWQKdAhZxcWYII)La3yXGUE)LaSAo)Nsq7iGLp8AcnjWAZ03J0VuM)cKFfkv)EkDsq)OYV)Ci9X4Cdt82lby5XMb3zVxc4QzdAy3jb2lyeRZ0gJBlOTLn4Na0hJapSh)FjaRoM1pzNtcSxawgct9SrfkdhB6Nu3jb8JB34xcPGP)vW4eCZGoX(LaUy4o)eW9ciuOqHylVuFOG8VIJ06H3CSxcWYIFHnGcdSne7WCMEqkeoD6gcYV8KI)V21dc(mcL)5dBWM(Xn9zhEFqYkdZBBDtAZ(6LEu2dlBV70LFJ7CEy2VWD9sp)Q8rthxaXjSJKCPejTI6KaUoQDs0RKr2Sye0Nzh2ox3ww1uLMh2chhKiPjrrpiJkDBB6AUp36NUZn639jxGNWt7SnKL9Yf5kM2VF5D3D9hd(qmhl37Tx((lF9130(bmiE4dF4Y3(MU3Iq527U(nZVV9TcUiXqq)9F8v)3TFW1tLwYXDF66x3nCxBbdV(Up(2p1bBmKB41ZF3LF4YqmXMpaNC8bLl5NL61VOjFi9X8vhCwYBBK6rOlC7L022Ny65bK1ESSFPJoDXeCZa76O(jRlqa7NLGekc3LC1TzPWiPJcZgMm9U)ZOGKQ7sJhm02m7Y8B5UgyXVE9VplHLBS)13z2GYE4)FgcFnZ8zx5d5f57s3MBRviDLcCt2sKfqqvuNDtnxFehBaxBrGN5YMe158mSRGzrytxReuY6msSTYnkFVx77jznLIoFceBt1LG5ZLKstTPSu019ZydzBKut(NOOBQac2ig2r82M1KGMMY7MuJ9bUIAJEjnsJgZ2vSGsgPmHwFbbbkZGSyzIpZDypyhRn(oEhX02ecQm0(N6U(yUVR6P0aYJeyU1ukcO(m8XzuY2aebZQyIpjGsQLVBtzhmc362MYozmqgrOa0kpssDzoEPfAZYRfRj2l1H8julT7tYRfdCRSHY2lETsue3NYNlljYNQwKcsqLsMjtJPcLNOqudwnCasdUC8idLbtaxrCKO4MeuosrxkbypqcAAgEHbeC)fgiIUBkcjbFy9ClhdZaliGHzVui0g6wsiWSIsBa7Y3sZO84Ixbckl4X0LoXNP0yfMk9y)nZqsP21yWKRMGxIb6kkyrrpferaWSI7f0LDWsIqXzk53rrOmOuHGtGxfeUHUbg(2H3NuxJKU6ijsFg2JO7AqeUv5cTUvUhXDefa5gIjl9PSUlt1yIQtO7aadgcsWazy8YyO9suXTmocJ0indGjEzl4(BqaLl52KvRXRaGcV1emK5bs6(dsgQJ)d10EgTA06GAicXre20bNrPPpSQQNNrmwakewZ63UpRUoR2UDw67WObxqXdl4zxBkFF5L2sIDTZhVE3VYFCBzpf8FWthwMp7ho8ooUk33RYWEAX)5fSSRtb" + return "4XzT8STDBBRLFmZZ1djaji5Jw2XjznjYESCoTD1g1qlrBRjYIEiPoPURzLV9zFdKG3ueRDFjrweyJ9nSVtT0F5nlxSUywEX6SIZY3MxGFr6Y5(lxC7YlcJsuXMWapTxqIVx8Y7(Pq9Yf3p6tkg7jvlxu(q668VvU5(hQUzZJzfxNT9Q8n7QGJ6MlV663)23Dt)fDrr6JzlQksRsxU4DWAwUyvAz1S0XW55Ei(H)Bb(Vvi5DwE(waQ7oD7tpWR7HS0TvpCt2FwDnEulx8BpLvSkBx1)xzvA1(YpVCXt5FlROEf)RlV7UYSkAZvfB291SQlY3v9MDP3UnB9YznO19UOK3jbdJuYQFxgD8ZvA5aBrVF8nN)(p9r4jzvVJqyNDyaGvLxL94v73wMbp46S)Dwrz2YBDw)vmrLEFgIHcEpMWoWyuHHEkpvqyGpaFqWfqc7rEsXypzaHnqWBZOtALimEBr((NoFtr2QQn57wU48l)55dSVhY)2nFlN(msd3UhKdZW)5Sg48nhWi6riVa(7)4X0)N8I)y3(hbEmqR7ls)fRK0J)73VRkROy)tv)8M1vpCr6QQCuiDsYYf7E6MIShZlqjnGG5fBkV6kGc2Mww((v57iH1ha((2LZdzO9HnLvNNDx6(TviZ1ef5H)FwJEYtfBaav98Y5bOiSiD1xby)MzF6IlqgNkosp(w8dhyl(kDy40ofDqKxYXCk1NbCDoEANry4biKHXkFJXFABrPnjbtBlAFF)OJH2D5WXhGDn4Py0bMr3rsF(Byq8erkvOkAQKEG)48xFVEyLjACAqn4b4feoUAYa6vXjX6rxVEOJWpqfoormiw5NegnoZDqoLVxW482b4uX(k10oHi)jE7au0pGHbvFvQ4aZrDh3LrPJhxIp8TC1b0Zh8qcJINiRsbI8jsjrrhs(nG9Ty946HdRHedy1XCeo0HkCQUd8HqPMODxnOkooTR6R7Qsa7UtrzhUp5nvULjjACr4Gx0vMK4PUfVWGjAN2p6a24gEh6P6Gw5nvFukpVdisgtFm5Om966wtLm(vXbULOdcNQvlFpv0bqR(kxAp1bCjm8zOIvtKBz0t9ALkYlE8TmO6OwR8M2fRaTAIoQGWmoGmCGB7Wzm1yz0bbjtuLxR1jJBDCyUfe7Wedbcs1CQUsI8oGg8WgvIuQjQqQ1rt1pQpy2EQiMo5aBjSVOhsuBsofnEtmTIGaVGXfHdseqCVt02iKPPE8lIdOXBcM2fKq1bIBAqukXBQCQytWe1PI9pGD0H8QBmhk8VbOBZuVnbB6PSkkrESSdWt3KU94YR3n1ze5BLj(V6KIoLWFDo7kiZPvBwS5VYOmULkAylfW89pEBwHtvEGJBlEKdwvfzZ2d7IaiOMWKeJksh5fKywE3pbHg4uQOpKDx1L7R2UzhvLL6Ya0RGkxeehdWimmcIowJbyWvhBWcbj4UlnNwb42T7RYkb4nNs2P8PSTBxUy5IDaLSCXnPf3dlEXJ5R3C3MSc8jWgQqgoq4PcVVIxgY4gaixKVAF5WWq1aJ7OvbGqpaioLw03)Y)HEy40aM1BkzTkasbhcsbtbsHhcsHtbsMdbjZuGu0HGu0uGu8HGu8uGuYHGuYuGe79CmqHMvoAyvvxgu8wKtPuBzmO28YAAzxLUE9MD3ZfTKkgyZTVtH9X3ahQwWNetgSWQS6uhvmX5h6wS0BhQA1WTt8t4w8idFDk)3y13w5wF7AJgU337v0t4ERCwjaHSl7BFi9589viVHX1bnOX2FBvgty33xK)TpUz96TSrlMHp4(BX2jgAJ9hMLw98tG0(QhEUCZQ0TeB1NyXw2T1sJ7YFx(2NDwQ3jjEYYpje(K1EG7wUaCF0AlHEoNGP36pTyv6UH3HF9fj3nmpTAVCeENazC4se0FJ276rjli5KSl6a6Dul2V7R7aZ5D36NKVMT7lALwcY30JbuKxw15GAoKQUU2CCKUUW5Iut1Y7QvqUYZwFEgTe84J9GigNHjSfLeHFasommH(MyiUGz2ATcFicRse8)yzNNHf0Xq7uLaX0GRx(Fk0Uzy0rAAD(ALFmTFcCujZOTf5rRNIMh3NVMwM8CUOu4XzppSKtZOeg4ZliXNoiLxeJiE(8h0bmGWI7mJISJHKjkoMHGoGxawlNz2k0qNvCeVxtOVp9i7xaOh9)mTW1cb3HsqtJMrlDGhX(ItueaOknqGokGoSy7PtbCYuQNHHTWrdmbSqbILGXcicfATb(ckZ5AaFimMEGjwGLjIEEKNWfb5j9bnW4zIwzOvqrVsNgKec9efFOkldhRK)mIVYhfxEIzmBI(qsmZ2OARt7nMP(qf))CbUNrr(gjFHh9bddbvmZqXdHzla6XFijHjfm9cgb1IoQH59kJosijf)fjr0wbzhZqbLAEHg(dIkhxJue0EXmUKWQQgrx0hiJALAcKgFTiJ8zfHqrLbyx8HhhY7a0Lyjselsebh)uGPZOSVr0o8zXPXZJrqHjeW35OQoHuGNsapvhCgZ8zMVNptfr8fmqVkuyPcmurjYfIa(dCLvPJpoksohgT0Sewb65mlnqZqHkDcTfTrU25hlk0HcRrjx)W6gqOyK9gnddQgWeMspxSR4llpY3ApHHFKIVrzy9uFH8mXHSHQWi(YH2xUdisDTwOnFrpsWtG4ejweD10jSGJURYD9z3j8fofL4bcs5hMIqT1(cXLIf3UoDvg2ksg2yOwfP7Up7ShYw91ZSXvGo5DIrq8m47U2Re4H4kVui(T9G)CkilAhy6oou0d2UppTUBtoDqhPWYA1R6JMl7GoDAcBD75XSYENnykimST5OJnKw6Y5pBp2FC3ZZVv8HgIzV5pH42YkUdYF1km7E0oTJhFuF6ONi0TtYUnG(zmTt)OaqtuJU3mXyl0bT9f)j(KaWciE7oqPc8ONO6tw1HJ9dI892Ciw8h)iKs4MDqScb1za3H8C(2MU2Zzs(dKBW5utXiFdJ8ykA(UiTVuDH6jKWdZ83Y7U4NccHOtmErHWD(iTchZeWArT4AmC0rMC7pEkcQTk0rTpYgPOq3ABKKiCB00r1t5YAWYodusTk7pf2wJ6iVIXxjNJPFndVN8U0T3DeeTtcxqOMGWDbfX)DGPLF)01RVCx5V)2Tqkwp)7V)ritOYFNLF)bKe2U1zR)JB3(uVPNXPMiGEor9BtRYkLcXGxSQlZXGjEu(aKIs()MNWdbdhGwor1xnZHEMUogBRYA50jrZPObD(ZqoWBwXl3AWODMHwIFS5qYjDuiYqhl11kfiVgbUC3CSCL7CUKghobnGc2kYXGnRbwQkAal(F3NwK99VCX(TB)(x(5h2uL1rGjGulKCd(ZPCwFRm0pgcMh43XEEbgp7LslS6MecV7Pm8zbJo8z88in8tCkZ2Vm8fDKl2F(FC8XF6UDWnGv0LTwk5DPPA1jKNBDi3o6c2KG(e(IV4KecyUblBkWzTTerKJsZlk2KTBnKu9mhj673Hsas7Tdj(H3CXnDhAPU3aBxKZ)LJhkrJR(YbYPoUs8(lGvAJjaU)5bzweeBIdifIiRGV)1bNkilwtQ9A(R9XPoA7dYREZUShFU39KHja(0h7UfxqeNNsc1Z2xcovVj9(6N0yfS8DBwNDUuVl(BWN2GNN5EVGlX(6IUkup4AdGkAXIhZZH131mSRuRwTO14aoSzvhRAoEwiBsuyK2ioVied4ojiuLegcPwOqHzYsN5wSjytRcVd7syk11vI5d6OE9Yj11TbZErRFlWRh)OagTUFHK0962iQxd4g73BqIMeypjX6dlu3d4AVOETlEsqFuKUx3BFvaBSUBtVEnaRjOxJJFnaRVx4)iWnu3B2oEnaBSQ3Ga8Aawv)UTojWI(SUx()c()D0F1gt3MAojOpQ(7ldPhtYHfi71hSQWKEtk7RbCJ971X4jb2t8frxsDaS1G2lQ7evojqpgdU)Km)Aa24q)UTPEsG9eWZGBYXjgxD4WKUnnFsaFC)g)JWk8J)NqWPvj9grZxd46BEHEIoX30sjgLLXTvK)N4kDC)5J81aS(HVYoqHfUAJnR7Lu4Rs4NNTPyvRgawp1d)uCqqGsR8v(bHYypGHO)uZKrm)NIL3DcUDrtVKoorx62aYMy3BAufL6eNGKxtK0eVPayuNbzHv1Rqc8lgu3cJ9(hFC)USoAqW1BwdcB6NyhSDXeDkNrtO6sQYDRIJ7A5KsQZfow7Pd9dcsI0qwX(u0Y2CYB3QzzNssFXcH4YHOPEPt(PH2i1)y6F2m9ndpPl1KrNCqdWeooheSuAqZ9JTDzxEStkP)ANSk)0v9z4xKx844QOCviTWJr5ULKM02NHuRt6uuPeDlyXFJsw1kvo3kWAZuHWGXQUUBwFzJmnrU8y3Iw2aLBy5SJi)LsvTRDvVeATVqs1eoL3LbsERJzNwtbyf2Pe1HhF(kSXq6dot(iyIo0CLlNu)OW6UMyVdmaF8sI(rlqRIoWKj6lHXAvgoYQ6Zx5AU3sBxUooG1kR5oh7AnLO42MRg2YcqslTxc3UwEmuHpWVkwZW2DLWnwVPDSEXYASTFLEnKWVW2(vFL0mv6DbAwD7xbxCCVZuQ46duAjOQUr744jpZTBHECl6GtHBBj2zrBBM5LObxdshuT9XhB3o(bBJ899IL(esbiqRn02uDUhQ6GaUXKHAP7WWsK2qA72xDZ8Jy(dP3i4ptr(Cdb53qc8lO38bcBt8A3oFs3LWGqzicaMS0J7yBdQd4orQm2oXQmmAd3XKwJA7EBKD6kunTcvXGZiDaUEWl8WIRmJ43SmIElPMrTBxlD60WItEyyNrSUy7hem329vTxG0auLhJOktS0O0aBRB9fbAIT98b2VblPk9bFFEcc4XAh)MqrVqlABaWmeMBygozQH2QMBDln2R0XeYqNNsvg3wsDInvQ06JGds6gqrw5(cXYgvanA4ZQTPHBUuQVDM9QKyF9tLShe2rjvD0mCUAEkTaU2Bx11zPRFMlDk83LnB4MhGZ(b4YizjNIUAGx5ZbQm5HQV4ydR6DKxfUHBu8Fd51M9uWog((xUbav1MN((xkPk4Vw8ixJqA1YMrKfSMLTEE(zRhWdTt8zTxFDXRTbh5(EqVUOPDCqqoGmosfgJnRNRnOXTXXorDeHXUqJvk)Tn9QT3S(2TMYFOU5UTkcVeUIh17M2nSqI3Kh6yi(K0kBfX73RQt3(T0N7uJw3cVEX2usjy6ba3eLE732E3Qg3CMwve3Wi43l9BTCsltka7fPtdRk7e3u)AS3I0A3QXWEySVJwF7GTxxCgW3UhCGstP8IvvfBlR2VRJp27YHiDTTbzZkkktihBd1P0IDR7ULBhBlXg(g4dPCmM)OZWG2OWZipV6ywFi2Dc(akR2WZjWpEpX0z81YJz1GbF(eEE128Dh1by8JOOxkxLwbM7oUJXN)5wy9Msu4S7OOEdwbiEthj)vHt5gfp)E0smGF47gWrTrTre(DLnJl8due2T6yoadKilU69PhZQdtyw8DzPfhZ6X5HIdwCG20I7YPJ0xLxAn206wNt)ECYAZPFXmiCY6yDXFJufE728YYU92ZDuzAn2bh0bdL1H1qd7K6cd4t3tNeebXKeBscT28QPpfeDkSL)BW3u1HMAKOgtnRDkmbekrcCn2aSC4K4FBj8CAQnoouK)P(ub5oiPMr(lof7WpmXZtBsmXGLAYnvChxb)n40TskZTRLnjtw7jehzdNh5mEaqMdOwt5vGFoSOc0(ihJog1B5nE5IFdd95ZF)l)gOiL9zBPdApqp1tKWiVbm9QreDgnZewDlFX)OEUaAFg45oYqPBVLCjWsST18ehYEkEt7LcMfi9ObNjhRoOkSjXoZXKO8CvEbGZBEXjJlJu9m7avRH4HKjBvgUypfp3H2OILXAehlA(l84Ho1M0geUFcfVo4VuM90azwmJLKF6L1gKzGeITjwgpZaDZuFYjfMeid5CeNVIehVYZNNiyfKrMaT4ejvno2FiapoJMazLqMjeWRZlZMoMFqKn7abussxqwdr2ezJTW0o6VckRKmeH7P0ktKXmouzhVyj7jLNMtN1yeGAt)b8dAKSOI4SEISd(CGmZR1j0aRGjkB2ubHa)KHcW0SiPnBko)zBU2iwlYzzuHJKz71MInIb0jNi5AlP(iQbso0(rE20JzwPavjtpi3kEQyJmXssH8GiRG08K8gtKrvhWvghfoEseRqzKPZgObw(IRKzbk7Kt7jdPVkHteeoo60858wJL5qh(BMwuAv78Jd58qfQXpq4k1fGq3ojYqtIqF(YqChyKCet4CeJ4KFLj1grql)J5UHsDkKz(gzq8jYLBiI)Any2xXWrY0nGNz96HbwYMhEaFq6yo3yqG4j537j0kCuYiklhLGcr66PT3yNsBMVfjt(Sp8nsrp4koOafywD0MbpOqfwl3eWflpc0H5rHwUpkjARSduToq0kmY8JBKC3v2lsj2jEoRYolO(ovsStvO79EJG5ppZnEM21g1AmT)pmwys3FDW3nfhx(XbGseCDXpkko230klYbh1g78EIODTD(KUoxMKrDjSPApPhXGaAtY0MO4h3SBZJPB3u28S3UpRSmRuytnj5IJi(dtCAIDhItsCPcSXM1XLSB15bxKzPDgaABiybsj6nU(uDlt(2SuaoJmQEd0Lh3FKVOcQ0zYd5GFA5M(y4ZobFCelVlh4JP3Vz1aSwQCle9RQ3ggH5P1T8QSPgftxHsQoJ7SZkYAhP16I573UD0GK7quThoBEou7ffxZCIAr((vdO5wOtfcCgVUUHZ5Ez(i0uBxfCrzn0iPns9bA2YUJh5HZbP1p)FsNcx29nbVHyQnS5y6Ht6QFRrTlT7KGgouXzS)E7nBGc3FjfEjWzE3NMFZBUg)exy55GdAPy5ycyujRXUWXv6DUzjxtv83QoUePZJSotGCpT10LEPv5IUs5iWvwFoyZMl2oM6dfpgYz4I2ZIJF(0RV(9xY4dfbfUhQk84w46oJ4f3KaK9XXmI4dvlxeDWggmxlr3qOm1SH50C2ohVJ)MT3bhb8xxD6ho983pNIgMk6pHqy8o4bZTTajFoKhIwPMBG4a6zdHo3LdIJq1oNPKpE6BFdtgyjTjWsrZXypwVFgUyT1r6GJSJWwS1c4rX1qNKiuJbOJG6QaYm4Wbq0KB)bZZvEehhqGllwX04nf5B3YF88R)07pNWkQo4eUqHdtugfQoEiu18rKIdANisQW(izWTKGzMNxKMTlBddC8kdK7c)hVDx(JYhV663)Mf3qNk1edIGOmiiflkSlctO2lGNph6fXlOy2izbgmfItChxi1kUNlSubd(fzlC7qMtL(58VLwic6zBZZxxl2b1SpC5z)xKyNAFfIjC)ROJG6hbbxQ3ceJNAAdINCBNigp1Ljs2sDLyo5DAX7o9JNsQuuplOhtTnIbnguosAuZFiitjeqCakalM1(U9pMUJX2RV8TFI1LWw(q3IO23qsiQ9eK(a1pleP5MNq6du7Dy9gSbh81ncRqHa1Sdwfgt9HehuFG4lTuRxMtfF6gimMmgDG)QYTw1vz7QEOCidqo24KzQ44IE4win17jJPTQ(7WvRU9Gz07LVV90A0GJYuBCZYXNDnSGHpCtoBMNwp5WbFwj7b4SlV8dsNtQ)TnTA54dV3ldIdnLSVmio08V9YG4qJr2ldIdnqOVmio0aX(YG4qJF1ldIdn5v)DHy1Y2dxY5ziGAYoP9lNt34P69Y8LVPmF3YHIr3SS7quDuXl9WM1zZ2U5V(R0I1saz1LDUvuKD712VIjKb21G8P9dbZPgf)c9eUS1lUZKcfUvbZwx0oeSzUVvB3KFkIQVFD3Io2GWJ1ap(hhNbKanVuUowQgmZJEgnBVHU)GaV5LYk6Qgu2Q2)TtrY9zT7r89J3op)gLNMkYk)qfVa7NozSUjC1hP3r0ipQzhUXnYpiuXDnXjap6bC4BvnXNXFldLMivOVLJ0OD4c0dOAzu5eofVC635ax)18xt(QBfxGGjyqg01Z7Bp5AZU8MBUetLzttHhmjb4m6fGbvRcG4K4xCTMRjos7o90(WPSrC82Zm4Yf)2kCGg2v95)ZF7X0)8ZTCGVCGFNPDAZEKYeegH9BjqLezA9(u1qo4pUayntXiO88IT)GD39fxwYhZRfcWVRpgJNsRt8Xxb5if)wjNmuVwocYF9W)CZyVu3nWc3HWYHB4oYu1VbC32FedoS1W2J3WGddHtU28mV2ypx2D3II5mldhrc8U8W6kgzFNUEYzqiB9GBhkgS2T2duSWFoM(CFb9qkvVutwnMrUM0(q(JBvIAmNxR57(opxTC5)pOQQLw" end function Gladdy:GetMirEditedProfile() -- 2.39.5 From a8a6002f47cba046f4bcb30ec945e3a13f39a888 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 17:56:53 +0100 Subject: [PATCH 159/268] fixed UNIT_HEALTH_FREQUENT --- Modules/Healthbar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 2e91cba..4b05cc9 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -111,7 +111,7 @@ end function Healthbar.OnEvent(self, event, unit) local isDead = UnitExists(unit) and UnitIsDeadOrGhost(unit) - if event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH" then + if event == "UNIT_HEALTH_FREQUENT" or event == "UNIT_MAXHEALTH" then if isDead then Gladdy:SendMessage("UNIT_DEATH", unit) return -- 2.39.5 From d43d8e9284b840215441c3c046262b3804d7ce3b Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 17:57:04 +0100 Subject: [PATCH 160/268] updated Mir Profile --- ImportStrings.lua | 4 ++-- README.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ImportStrings.lua b/ImportStrings.lua index fef1286..fc1d475 100644 --- a/ImportStrings.lua +++ b/ImportStrings.lua @@ -25,9 +25,9 @@ function Gladdy:GetRukkProfile() end function Gladdy:GetMirProfile() - return "4XzT8STDBBRLFmZZ1djaji5Jw2XjznjYESCoTD1g1qlrBRjYIEiPoPURzLV9zFdKG3ueRDFjrweyJ9nSVtT0F5nlxSUywEX6SIZY3MxGFr6Y5(lxC7YlcJsuXMWapTxqIVx8Y7(Pq9Yf3p6tkg7jvlxu(q668VvU5(hQUzZJzfxNT9Q8n7QGJ6MlV663)23Dt)fDrr6JzlQksRsxU4DWAwUyvAz1S0XW55Ei(H)Bb(Vvi5DwE(waQ7oD7tpWR7HS0TvpCt2FwDnEulx8BpLvSkBx1)xzvA1(YpVCXt5FlROEf)RlV7UYSkAZvfB291SQlY3v9MDP3UnB9YznO19UOK3jbdJuYQFxgD8ZvA5aBrVF8nN)(p9r4jzvVJqyNDyaGvLxL94v73wMbp46S)Dwrz2YBDw)vmrLEFgIHcEpMWoWyuHHEkpvqyGpaFqWfqc7rEsXypzaHnqWBZOtALimEBr((NoFtr2QQn57wU48l)55dSVhY)2nFlN(msd3UhKdZW)5Sg48nhWi6riVa(7)4X0)N8I)y3(hbEmqR7ls)fRK0J)73VRkROy)tv)8M1vpCr6QQCuiDsYYf7E6MIShZlqjnGG5fBkV6kGc2Mww((v57iH1ha((2LZdzO9HnLvNNDx6(TviZ1ef5H)FwJEYtfBaav98Y5bOiSiD1xby)MzF6IlqgNkosp(w8dhyl(kDy40ofDqKxYXCk1NbCDoEANry4biKHXkFJXFABrPnjbtBlAFF)OJH2D5WXhGDn4Py0bMr3rsF(Byq8erkvOkAQKEG)48xFVEyLjACAqn4b4feoUAYa6vXjX6rxVEOJWpqfoormiw5NegnoZDqoLVxW482b4uX(k10oHi)jE7au0pGHbvFvQ4aZrDh3LrPJhxIp8TC1b0Zh8qcJINiRsbI8jsjrrhs(nG9Ty946HdRHedy1XCeo0HkCQUd8HqPMODxnOkooTR6R7Qsa7UtrzhUp5nvULjjACr4Gx0vMK4PUfVWGjAN2p6a24gEh6P6Gw5nvFukpVdisgtFm5Om966wtLm(vXbULOdcNQvlFpv0bqR(kxAp1bCjm8zOIvtKBz0t9ALkYlE8TmO6OwR8M2fRaTAIoQGWmoGmCGB7Wzm1yz0bbjtuLxR1jJBDCyUfe7Wedbcs1CQUsI8oGg8WgvIuQjQqQ1rt1pQpy2EQiMo5aBjSVOhsuBsofnEtmTIGaVGXfHdseqCVt02iKPPE8lIdOXBcM2fKq1bIBAqukXBQCQytWe1PI9pGD0H8QBmhk8VbOBZuVnbB6PSkkrESSdWt3KU94YR3n1ze5BLj(V6KIoLWFDo7kiZPvBwS5VYOmULkAylfW89pEBwHtvEGJBlEKdwvfzZ2d7IaiOMWKeJksh5fKywE3pbHg4uQOpKDx1L7R2UzhvLL6Ya0RGkxeehdWimmcIowJbyWvhBWcbj4UlnNwb42T7RYkb4nNs2P8PSTBxUy5IDaLSCXnPf3dlEXJ5R3C3MSc8jWgQqgoq4PcVVIxgY4gaixKVAF5WWq1aJ7OvbGqpaioLw03)Y)HEy40aM1BkzTkasbhcsbtbsHhcsHtbsMdbjZuGu0HGu0uGu8HGu8uGuYHGuYuGe79CmqHMvoAyvvxgu8wKtPuBzmO28YAAzxLUE9MD3ZfTKkgyZTVtH9X3ahQwWNetgSWQS6uhvmX5h6wS0BhQA1WTt8t4w8idFDk)3y13w5wF7AJgU337v0t4ERCwjaHSl7BFi9589viVHX1bnOX2FBvgty33xK)TpUz96TSrlMHp4(BX2jgAJ9hMLw98tG0(QhEUCZQ0TeB1NyXw2T1sJ7YFx(2NDwQ3jjEYYpje(K1EG7wUaCF0AlHEoNGP36pTyv6UH3HF9fj3nmpTAVCeENazC4se0FJ276rjli5KSl6a6Dul2V7R7aZ5D36NKVMT7lALwcY30JbuKxw15GAoKQUU2CCKUUW5Iut1Y7QvqUYZwFEgTe84J9GigNHjSfLeHFasommH(MyiUGz2ATcFicRse8)yzNNHf0Xq7uLaX0GRx(Fk0Uzy0rAAD(ALFmTFcCujZOTf5rRNIMh3NVMwM8CUOu4XzppSKtZOeg4ZliXNoiLxeJiE(8h0bmGWI7mJISJHKjkoMHGoGxawlNz2k0qNvCeVxtOVp9i7xaOh9)mTW1cb3HsqtJMrlDGhX(ItueaOknqGokGoSy7PtbCYuQNHHTWrdmbSqbILGXcicfATb(ckZ5AaFimMEGjwGLjIEEKNWfb5j9bnW4zIwzOvqrVsNgKec9efFOkldhRK)mIVYhfxEIzmBI(qsmZ2OARt7nMP(qf))CbUNrr(gjFHh9bddbvmZqXdHzla6XFijHjfm9cgb1IoQH59kJosijf)fjr0wbzhZqbLAEHg(dIkhxJue0EXmUKWQQgrx0hiJALAcKgFTiJ8zfHqrLbyx8HhhY7a0Lyjselsebh)uGPZOSVr0o8zXPXZJrqHjeW35OQoHuGNsapvhCgZ8zMVNptfr8fmqVkuyPcmurjYfIa(dCLvPJpoksohgT0Sewb65mlnqZqHkDcTfTrU25hlk0HcRrjx)W6gqOyK9gnddQgWeMspxSR4llpY3ApHHFKIVrzy9uFH8mXHSHQWi(YH2xUdisDTwOnFrpsWtG4ejweD10jSGJURYD9z3j8fofL4bcs5hMIqT1(cXLIf3UoDvg2ksg2yOwfP7Up7ShYw91ZSXvGo5DIrq8m47U2Re4H4kVui(T9G)CkilAhy6oou0d2UppTUBtoDqhPWYA1R6JMl7GoDAcBD75XSYENnykimST5OJnKw6Y5pBp2FC3ZZVv8HgIzV5pH42YkUdYF1km7E0oTJhFuF6ONi0TtYUnG(zmTt)OaqtuJU3mXyl0bT9f)j(KaWciE7oqPc8ONO6tw1HJ9dI892Ciw8h)iKs4MDqScb1za3H8C(2MU2Zzs(dKBW5utXiFdJ8ykA(UiTVuDH6jKWdZ83Y7U4NccHOtmErHWD(iTchZeWArT4AmC0rMC7pEkcQTk0rTpYgPOq3ABKKiCB00r1t5YAWYodusTk7pf2wJ6iVIXxjNJPFndVN8U0T3DeeTtcxqOMGWDbfX)DGPLF)01RVCx5V)2Tqkwp)7V)ritOYFNLF)bKe2U1zR)JB3(uVPNXPMiGEor9BtRYkLcXGxSQlZXGjEu(aKIs()MNWdbdhGwor1xnZHEMUogBRYA50jrZPObD(ZqoWBwXl3AWODMHwIFS5qYjDuiYqhl11kfiVgbUC3CSCL7CUKghobnGc2kYXGnRbwQkAal(F3NwK99VCX(TB)(x(5h2uL1rGjGulKCd(ZPCwFRm0pgcMh43XEEbgp7LslS6MecV7Pm8zbJo8z88in8tCkZ2Vm8fDKl2F(FC8XF6UDWnGv0LTwk5DPPA1jKNBDi3o6c2KG(e(IV4KecyUblBkWzTTerKJsZlk2KTBnKu9mhj673Hsas7Tdj(H3CXnDhAPU3aBxKZ)LJhkrJR(YbYPoUs8(lGvAJjaU)5bzweeBIdifIiRGV)1bNkilwtQ9A(R9XPoA7dYREZUShFU39KHja(0h7UfxqeNNsc1Z2xcovVj9(6N0yfS8DBwNDUuVl(BWN2GNN5EVGlX(6IUkup4AdGkAXIhZZH131mSRuRwTO14aoSzvhRAoEwiBsuyK2ioVied4ojiuLegcPwOqHzYsN5wSjytRcVd7syk11vI5d6OE9Yj11TbZErRFlWRh)OagTUFHK0962iQxd4g73BqIMeypjX6dlu3d4AVOETlEsqFuKUx3BFvaBSUBtVEnaRjOxJJFnaRVx4)iWnu3B2oEnaBSQ3Ga8Aawv)UTojWI(SUx()c()D0F1gt3MAojOpQ(7ldPhtYHfi71hSQWKEtk7RbCJ971X4jb2t8frxsDaS1G2lQ7evojqpgdU)Km)Aa24q)UTPEsG9eWZGBYXjgxD4WKUnnFsaFC)g)JWk8J)NqWPvj9grZxd46BEHEIoX30sjgLLXTvK)N4kDC)5J81aS(HVYoqHfUAJnR7Lu4Rs4NNTPyvRgawp1d)uCqqGsR8v(bHYypGHO)uZKrm)NIL3DcUDrtVKoorx62aYMy3BAufL6eNGKxtK0eVPayuNbzHv1Rqc8lgu3cJ9(hFC)USoAqW1BwdcB6NyhSDXeDkNrtO6sQYDRIJ7A5KsQZfow7Pd9dcsI0qwX(u0Y2CYB3QzzNssFXcH4YHOPEPt(PH2i1)y6F2m9ndpPl1KrNCqdWeooheSuAqZ9JTDzxEStkP)ANSk)0v9z4xKx844QOCviTWJr5ULKM02NHuRt6uuPeDlyXFJsw1kvo3kWAZuHWGXQUUBwFzJmnrU8y3Iw2aLBy5SJi)LsvTRDvVeATVqs1eoL3LbsERJzNwtbyf2Pe1HhF(kSXq6dot(iyIo0CLlNu)OW6UMyVdmaF8sI(rlqRIoWKj6lHXAvgoYQ6Zx5AU3sBxUooG1kR5oh7AnLO42MRg2YcqslTxc3UwEmuHpWVkwZW2DLWnwVPDSEXYASTFLEnKWVW2(vFL0mv6DbAwD7xbxCCVZuQ46duAjOQUr744jpZTBHECl6GtHBBj2zrBBM5LObxdshuT9XhB3o(bBJ899IL(esbiqRn02uDUhQ6GaUXKHAP7WWsK2qA72xDZ8Jy(dP3i4ptr(Cdb53qc8lO38bcBt8A3oFs3LWGqzicaMS0J7yBdQd4orQm2oXQmmAd3XKwJA7EBKD6kunTcvXGZiDaUEWl8WIRmJ43SmIElPMrTBxlD60WItEyyNrSUy7hem329vTxG0auLhJOktS0O0aBRB9fbAIT98b2VblPk9bFFEcc4XAh)MqrVqlABaWmeMBygozQH2QMBDln2R0XeYqNNsvg3wsDInvQ06JGds6gqrw5(cXYgvanA4ZQTPHBUuQVDM9QKyF9tLShe2rjvD0mCUAEkTaU2Bx11zPRFMlDk83LnB4MhGZ(b4YizjNIUAGx5ZbQm5HQV4ydR6DKxfUHBu8Fd51M9uWog((xUbav1MN((xkPk4Vw8ixJqA1YMrKfSMLTEE(zRhWdTt8zTxFDXRTbh5(EqVUOPDCqqoGmosfgJnRNRnOXTXXorDeHXUqJvk)Tn9QT3S(2TMYFOU5UTkcVeUIh17M2nSqI3Kh6yi(K0kBfX73RQt3(T0N7uJw3cVEX2usjy6ba3eLE732E3Qg3CMwve3Wi43l9BTCsltka7fPtdRk7e3u)AS3I0A3QXWEySVJwF7GTxxCgW3UhCGstP8IvvfBlR2VRJp27YHiDTTbzZkkktihBd1P0IDR7ULBhBlXg(g4dPCmM)OZWG2OWZipV6ywFi2Dc(akR2WZjWpEpX0z81YJz1GbF(eEE128Dh1by8JOOxkxLwbM7oUJXN)5wy9Msu4S7OOEdwbiEthj)vHt5gfp)E0smGF47gWrTrTre(DLnJl8due2T6yoadKilU69PhZQdtyw8DzPfhZ6X5HIdwCG20I7YPJ0xLxAn206wNt)ECYAZPFXmiCY6yDXFJufE728YYU92ZDuzAn2bh0bdL1H1qd7K6cd4t3tNeebXKeBscT28QPpfeDkSL)BW3u1HMAKOgtnRDkmbekrcCn2aSC4K4FBj8CAQnoouK)P(ub5oiPMr(lof7WpmXZtBsmXGLAYnvChxb)n40TskZTRLnjtw7jehzdNh5mEaqMdOwt5vGFoSOc0(ihJog1B5nE5IFdd95ZF)l)gOiL9zBPdApqp1tKWiVbm9QreDgnZewDlFX)OEUaAFg45oYqPBVLCjWsST18ehYEkEt7LcMfi9ObNjhRoOkSjXoZXKO8CvEbGZBEXjJlJu9m7avRH4HKjBvgUypfp3H2OILXAehlA(l84Ho1M0geUFcfVo4VuM90azwmJLKF6L1gKzGeITjwgpZaDZuFYjfMeid5CeNVIehVYZNNiyfKrMaT4ejvno2FiapoJMazLqMjeWRZlZMoMFqKn7abussxqwdr2ezJTW0o6VckRKmeH7P0ktKXmouzhVyj7jLNMtN1yeGAt)b8dAKSOI4SEISd(CGmZR1j0aRGjkB2ubHa)KHcW0SiPnBko)zBU2iwlYzzuHJKz71MInIb0jNi5AlP(iQbso0(rE20JzwPavjtpi3kEQyJmXssH8GiRG08K8gtKrvhWvghfoEseRqzKPZgObw(IRKzbk7Kt7jdPVkHteeoo60858wJL5qh(BMwuAv78Jd58qfQXpq4k1fGq3ojYqtIqF(YqChyKCet4CeJ4KFLj1grql)J5UHsDkKz(gzq8jYLBiI)Any2xXWrY0nGNz96HbwYMhEaFq6yo3yqG4j537j0kCuYiklhLGcr66PT3yNsBMVfjt(Sp8nsrp4koOafywD0MbpOqfwl3eWflpc0H5rHwUpkjARSduToq0kmY8JBKC3v2lsj2jEoRYolO(ovsStvO79EJG5ppZnEM21g1AmT)pmwys3FDW3nfhx(XbGseCDXpkko230klYbh1g78EIODTD(KUoxMKrDjSPApPhXGaAtY0MO4h3SBZJPB3u28S3UpRSmRuytnj5IJi(dtCAIDhItsCPcSXM1XLSB15bxKzPDgaABiybsj6nU(uDlt(2SuaoJmQEd0Lh3FKVOcQ0zYd5GFA5M(y4ZobFCelVlh4JP3Vz1aSwQCle9RQ3ggH5P1T8QSPgftxHsQoJ7SZkYAhP16I573UD0GK7quThoBEou7ffxZCIAr((vdO5wOtfcCgVUUHZ5Ez(i0uBxfCrzn0iPns9bA2YUJh5HZbP1p)FsNcx29nbVHyQnS5y6Ht6QFRrTlT7KGgouXzS)E7nBGc3FjfEjWzE3NMFZBUg)exy55GdAPy5ycyujRXUWXv6DUzjxtv83QoUePZJSotGCpT10LEPv5IUs5iWvwFoyZMl2oM6dfpgYz4I2ZIJF(0RV(9xY4dfbfUhQk84w46oJ4f3KaK9XXmI4dvlxeDWggmxlr3qOm1SH50C2ohVJ)MT3bhb8xxD6ho983pNIgMk6pHqy8o4bZTTajFoKhIwPMBG4a6zdHo3LdIJq1oNPKpE6BFdtgyjTjWsrZXypwVFgUyT1r6GJSJWwS1c4rX1qNKiuJbOJG6QaYm4Wbq0KB)bZZvEehhqGllwX04nf5B3YF88R)07pNWkQo4eUqHdtugfQoEiu18rKIdANisQW(izWTKGzMNxKMTlBddC8kdK7c)hVDx(JYhV663)Mf3qNk1edIGOmiiflkSlctO2lGNph6fXlOy2izbgmfItChxi1kUNlSubd(fzlC7qMtL(58VLwic6zBZZxxl2b1SpC5z)xKyNAFfIjC)ROJG6hbbxQ3ceJNAAdINCBNigp1Ljs2sDLyo5DAX7o9JNsQuuplOhtTnIbnguosAuZFiitjeqCakalM1(U9pMUJX2RV8TFI1LWw(q3IO23qsiQ9eK(a1pleP5MNq6du7Dy9gSbh81ncRqHa1Sdwfgt9HehuFG4lTuRxMtfF6gimMmgDG)QYTw1vz7QEOCidqo24KzQ44IE4win17jJPTQ(7WvRU9Gz07LVV90A0GJYuBCZYXNDnSGHpCtoBMNwp5WbFwj7b4SlV8dsNtQ)TnTA54dV3ldIdnLSVmio08V9YG4qJr2ldIdnqOVmio0aX(YG4qJF1ldIdn5v)DHy1Y2dxY5ziGAYoP9lNt34P69Y8LVPmF3YHIr3SS7quDuXl9WM1zZ2U5V(R0I1saz1LDUvuKD712VIjKb21G8P9dbZPgf)c9eUS1lUZKcfUvbZwx0oeSzUVvB3KFkIQVFD3Io2GWJ1ap(hhNbKanVuUowQgmZJEgnBVHU)GaV5LYk6Qgu2Q2)TtrY9zT7r89J3op)gLNMkYk)qfVa7NozSUjC1hP3r0ipQzhUXnYpiuXDnXjap6bC4BvnXNXFldLMivOVLJ0OD4c0dOAzu5eofVC635ax)18xt(QBfxGGjyqg01Z7Bp5AZU8MBUetLzttHhmjb4m6fGbvRcG4K4xCTMRjos7o90(WPSrC82Zm4Yf)2kCGg2v95)ZF7X0)8ZTCGVCGFNPDAZEKYeegH9BjqLezA9(u1qo4pUayntXiO88IT)GD39fxwYhZRfcWVRpgJNsRt8Xxb5if)wjNmuVwocYF9W)CZyVu3nWc3HWYHB4oYu1VbC32FedoS1W2J3WGddHtU28mV2ypx2D3II5mldhrc8U8W6kgzFNUEYzqiB9GBhkgS2T2duSWFoM(CFb9qkvVutwnMrUM0(q(JBvIAmNxR57(opxTC5)pOQQLw" + return "4XzT8STDBJJKFm7ZDwcqsqWhTSJt8ztK9A5m9Kt3T6qlrBRnYsEjPM0Up7jF7BDdKGxKI4yNxIvibkuOQc1DW5Q53mF2YIjBlwMxC621BlWhKnFQA(SBNFECsQ2AIJccdIsvb2539lXHZND)EFtX(Et18zLpKTC73kxD)dv3S6X8IRZxF12vBQGL6MlV66lE37VP)GoVi7X8zvfzvzZN9EymZNTiRSAs2(W5Pbi(H)Bb(Vv1J)FE5D3vMxn)8FXgPItdccnPgRokudyyKD(ShYZwx9Wn5)v114YpF2V9uEXI8nv)FLvzv7k)J5ZEA73YlQhX)qGiUWvfR2818QZ3UP6TBYUDD(Y5tAq179rZG3eDqe9950YpvhklylAWhF7zx8PpcVjV69ec7nddaSQTv5pE1U1L5WlUo)FLxuMp)wyrYwSkdi4LZNjK6AiCfVnZUphXzN0WSQNxNpF2fBQYlUlBr(VFYYLxUP83F36SLlF(3V4ry8L)op2)8DR3wcq(2Daf50TBxd8Wn0AbCwyJjp5DfB390zRkYxuTA7M5Zo7YFDAFw(Sh2(TB(2w63icraDIpKb48npWi7hCRc)))8XS)NTf)5MDpcKqGGVRiZX6jsE75o5YBU5sGCU5PBkYFCBbYabeBBXQYRqmFDwz5fl2UH4bFaiNRNpnMH6hwvwDw(Dz7wxHCwtssa(38g2)tfRaav988PriNbybFfG9BN8PZph53ABs4(NIkEGPO0HXXJBvcJscspMvPEnGtU2XTgXXhyJmmwPmg14MIgoWgnUPeQuQKJzV7tHThGCn4QycJm7DgP9PVXr2rIu6yDYy36rQ9tFvb9WktY(3d6bxGGO49lMmGCLn1gU3Xho0sOI0X7FtmiwPsJt2pXDqkLkiA)02bOuwLwpUvirnYthGG(bumO7lszJmh1zCFcvOD)C8HpLRpGC(GlsCIDKKknWYh5ojj5q8Vb0Vzd3VC4WsiwaRoMLWBFOJhR5af410i17gcII7FVR7l7Qtb9UJryhopfmwQLjnz)SWbpORnP2XoLG4OrQNwLCaDCdpJWXAGwhmwBu6GGdWs2N8y6rP613SMoD)hfh4usyu8y1APc0jhaT6lCfgOpGjHHxdTvpsQLjCShR0jb29pLbfhdd1bJ7Gfe4XinubUzCaE4aN2H1yS(YegfLosr(WWW09RDCyQf47WiDbcIQCSMsscoGe8Wkvs06rkqggMmw7OkqT9yrSW0dmL4(S(4GdyyyGJ7MGrgwruuq0(zHdUja)EhPUXO4OW9FqCajEt04oGeRpGFtdIsPbJLsznrJuMYQoGE0HSQBmhY9Vb23MXEAcM0t5vua8nzt44IN3p0ze5xS6FJemaR0ML5l)ZBx)Kxu5n50jjrBaDkGpuPr6uWo)D)ciEIH1t5dzDwvE5jRF6HStw)TSNlB2dFUgeaNnrLAtaIFsqGnatCv08zpaBK14MzW0Wi59PgkrG7sXPPgDsysqukIhaY4LBPpKFx1L7QwVAdLwM6TsV0zDEK1cWioob87omH2syk2gkZrfzBUp)0hYx81By8bbDwfGC3Ud24aaNsXrv(u(61ZNb0fyRmF2nzf3dJD2JBxU6Uv5f4BGjuH8sfaaHTYZcZi1aW48Tl2vomi0nG4oAuaichaeNqd67F5)iCy40aMLRkz5vasrhcsrJbsXhcsXJbsMdbjZyGuYHGuYyGK9qqYogiLEiiLogiX2L3hOqfwhnSQQZBkEkYl3Ryk6iDlf7EQrX1sAyxbAywT5EoLXu6fBo9Dcmp(e4qju(nwsviMwwVeVIHK)q3CPE7qP8gusG)cNsaPsTtIf3xsY1(jjVwPXN9sSzV0OwLviRvQYBodR0MX(bvXX6j)1vlH3dmaq)esyW8O(XvlxUMvJXSGbNFlgbrIBuiXe5QNFc4)x9WZLRwKTMi0kIO7yaoDp(d)9Bx)S3qdEtAGm83ed)YPHWFkNd76wtjoWBfm9g)jflY2m8mu1hT8NW0SQDYse8gi6g)nb9)rnG92jZioNmlAb6TuZ2T5RB2(TnDN6NKhZwce5u3gsz6rak2ww1zHAwKQUg7Az0(KnlEa49IKcWSXdtEN3AstFxrfYxI8LNLtdbXjBa4Y6emIXK0e8hq0PXP0tSGJjtCj7f(rcMMk4VyEVNGzuYqZuNcovHJx(l5B5e09SqACQqTYsZNahLZoAAjb04PWjW5PcPHjVNZkgUCU1dZ51ekIfE9Isv0cPdsyejqX)imIbeMDPjKRLmKmjwldHWiEayYKM4sreTw2eEUMyLIEL7ba6r)L3lCYyWzOf00eYOvyuar(SPAcauQoiqNerlM1T6KhV8onWWWwOOrMiMPaUCWyb4idn2iLGYCWoWpIT0lmwbwMe69jbcve4N0pcbcpVP1gAeK7Z0QbrbrVrZlQ2rWXsjmHOR8sX5hzctMOFKAzYgLCFAUwE3hR5)YzyFc56DI8Ga6hggcAltqXfHjla6X)inL3ky8nmcgkYOgM2RnHjYwsZpinHMkW7yckiuZd0W)qe54K0IGoWY4sklQAezrfSnQfQjqAuHcpsXccXIidqU4f3gZZaKLyoscZsegh)w0Zwgmgr6qXSttqaJGcriIpZrP9c3bbAb8uI4zmtXe)afVls4dyGCvSqsfyOtsLder8p4u7slVnjrwhgTczoSgKZzsAuidfk3n0ucnYXoLveOJfsJwo(HjUGqXe3jAggusOjmLEVOxrjdpr50NWWprZNOmSCQs2EgBmROkoHpCeQKZacxpmu2BkrosWtyZjCSe6OPN3dhDfS7AAVJxoZw93GrE7a(Y8dJKO2eqHyNXHBxdbKH1cLHn6rgAW)tsWFUOno15ub(ypxiedhk)XELazeR5Hco8Tdm3tELrZaJpYBVvBPzC1pNm)G2zHH1QA4dsVhWWPp60PEWllAvDBxL0DTfagC37D(KbEZTElA4d3lD5mNUdRlVpxx1YntdXmw9xG7Fq0XGVAiqKGnzEcCWOvtaGyAFzPEmy)cD7xx8NXyxvjrGCAiA8ZqbadNfM9x4BIa9J4z)iTokGEJU)MQ2dUFG7Z3UfCO)XpcrFUAd4Er08bQXprFDvN3R7kaU86C2Tck61FWHiybR364zfCngZbeFSxjzbPUbni)IAYbrum4eJjijgunKeQXoFbuQ0w6Wl0)B)XT0qTMIohasCUukBYqNlNig2iZJlQCa2hpOMxPwm9xIBlhDKh24dNtXi3MGNlEF2672hxWt8ZlwTxq(F8I2Oj0P(56Hpiv3(jdgDs5dqCmB)xCRMiaEG9XB09LN82lJxyI1y1kOmwt4WNJ7rijPNZEgcDE1cE4I1Gouf3M3jOjegLN6vN8m4PON(6AbcuKXt7Z(cXUZ6ssByR8acxliZdUqlAL9Vz)V7YkY)(xoF361F)l)6dRQY7WWeqgkB5g8NJlT(4xSYco3d0BBqqKjWD6ZbRUbLWZEmn(w0EB8TO57RX3IiUSGc)ZHpKJuXwyhekBlB(NSzdi9VGoO1siV7EQwCcP5oZYT92Gvhe(g(qVyQeCGUblfRl(6rewoYnpVyv(MLqK3t84OxSPKt54YIoBXp82ZVPBxu19ey7CJ(p8SjjsC1hoqk1XLZ5)jOo2yIGZFbqKgrwJnYkPeUgzilmmc6LoBCD8Tr(5(4thj9bPtVDt(Jp37mYWipV6UZv3oygt8BQWvoLBcZ90DLG50BYUV0dg0HfetW8z5c9gZuZQMmEdUcBtvyOywGmbr5Whz4CKXYbyJr2Sbp1)WexOag5DjhqOqim6kCcUobYS3dEsrjKE2IQI1Lv7OuA4vgI72wSi3j7Uc)7uviywLmTvSzz3PC7(MI1WQyFiR4XJznmybCR4ClECZqJbFZlrz1k2DUF0CITwAv(A5XmAiegYHPfpVy92nh1cyuq8RymdlYQajOJBzuCh6cBDK9SP6yMe4OdBfe0nbleSAyfJoIjQddncZSy72QJJzgPPP0z87Nkhr0TLloMrBurejBx2Xm64uMaFxEwXXmEmO25vnUm1V9HdWdhnNkJn6uqA0aZmecYLQdvqVz75izTEysDVNRCh2nc64X68mWQaBBWZiV7G(0DpEBEXG(mqb75Iq88yma50OyDACCSoM6P605E9VCtiHodsEQ0eRA1jhMv5eMWf)DXpoInpMWcwBi60cwXGg)aDUgRIvbj)eGRvLCyW(gNBGVjvpwGRJtd(zqmSkUDpETbRnm(NaynrP)maRwAmHbal6O09YF5AlmwGhhMUpG)sWzRw)ZqiomiH7JPxz4AvCtq0hSkHaNkey1ybTki(NIurmMu7xFWcw)m7Hu8IGRv6SZxBWIM5F9bl2Ke)eaRvL8trDMY(ZGiyJv69P3j14d53awSgjWJLlxYRmohcUKUpK(LaxLz)wIGDVTRwcZyxaqq(NXXzRAV2oEjGf8i)1fBRQ9TRoJj2WGWyvee4xOcJde9ztUBtDs7DteGsAB4rDg3ggNUQyrR2a4ZEx1UOin4iRgCXwAhkmgCNlGiMsfmF2JGN9pmVojeiW6x6axMOAYwCtGQyhh2md)KuvaeOtXGu6Ldq((e2nl2x84J720o38GCxQiaIf1NSAv10(gDZOH4oBz3eM0odSEEWlCMxAFXrWVDhOSj)BFi75T7AOB(EJNkpRBS6eG(y2FXSbma)HB(TAXIo5xIsIGxZ5fIvblrhBXQRXbhyOCDoeu7MXskGGWGuUsYCl6ozUCn1MGvIlLR5FtLIdSYyCvgMUIw4dCvgwPL68s3tQj1vggmIYL1tRT1lOuTsDDpaGTU9e)czgWvpewfUIQyrpDvaNhsOfcNHEsDlgGDca(dxpgOcSsjmjDH0yJD17NlVByuexZ04qPW1WqKkK6kezDFgKW0hBaVmi(Z7ifxRs(2JGpGUvie2Mg0Utdujcjvhl93aqKLYVBD1opIlsQ24ksme8knetCSu1wxHLtCn(HUPkTAgCgP4019esagh5eIEZ8i6gKnH6eGqPiSgMDYnk8eI0zD)qWCxHHddIKAZQdyevBSsnCJCvvwjm0uxNde5EcMDx6hkf3CdCl)JpjwKlcfPnaygcZnmbhid8gbdONwgJR7vIzOZDWlJBZPIe3vR05B5Ks1OtYVycCD1wSAORl9QUveyvNun(sv70kDL(1u0PMN0F3UAY15za2A5lNU90LdS5Cg8Q6K37xkcVyvN8Th7BtPEhaSzr7xtfxVT3iCxf4AkaPVIy530Y4CR(VVIoMC4lUwLCu9haMKdDJUKvscL5aJH0sC4HK8JgaOw8a3jaAmvnsfhzbRB91jWpd38TY)wNLhhpjcRo6ag9DhacABFUor9UIk22ZNmP2lpcMu5mtXcUxNNT8zclWMyTM3JaQuk4vob5gR7FQKXBohA4VwMJDJ3tzfvyNmMxURqQmaLP(L40kBMXnpad5bWMiv55Q(v)3hTbHYbQCXHQ)W(s53DKkfUQ7u5uhYQpFuKp599VCdaQQvp99Vusv3BPCSPgHc1ZRVfa)Bw5026pigr3(FTUrb8QtRxnFA6UephxsqvbuZQlPe92oQ3ouh3(bUBpUTJ2kXLOGAhEAQOPGz81KauWNv5WoUoW8E4Cdy2iimnkbm7znPXcDPfJO2v6ZxJqjRUQpJNm7P2TUkUy)arYY1RPtEXVBiACa)sWILZFsKM(GF1KB5YpIP9loDR9w7gsi2pTrnHb1Qhg8yPPElo2UcE2HI7WC7xfwrmRxGoTqVEvdRRbxMl7ftcrwBA)P2va1VbIgytTNJAKbU(Un4x4WBRrvn4WmiI9FdNoRouZZK0Ogw2zT6aNMUHQHX1hJpIgCZ5Y)yKv7zOaw5R2wa((S6fhiLFbGB8zr4JE6qC4neQeQDPeI96dyiD0WjwHN9Qw9b08z)gAN4p((x(nGYM)hUGZ2ZNFKwT8LRXPu(h4UM4po9v1LYUrq1x8RHs1s8yXxVNidToVnmhR1MX)dHJJK07idU)gmEV6n(r01llCM0rew6R8jUUkpeIXuAVxPdRd0CZx68)w6TtS3W5heWDERl8qiWIukYGuJRbCJKgs1kHz1l(qigeXzEJv6r1OWMwFLd)mns607eoYijIbDGIBlAne7NanBQeuihLbe0mh7uKmsigic41ra6c8tfL4IdraLeEheFsIlKzRdMU(FwqzTelQjLHvQ0R1XAxpwlXPPdc5aNngbOUaT0kjQhar44RsCD)DK04V1HobJG3uU42IIb6jdfGO5qsxCBCK6UO6rSw4Zs)sNin4SlyEedOvovIQxcYsedKO1vjbUaXzsPavjMsikoU1Gtmwj8tUBS1qaLseQPs)6d4kJJcfpnHfOmslQd7bM)IJKjbAx7Jhi3ubDkhYjSC0QP4iKTsZ4d)FEVOd1TJepMJ4v2nQiHQuNQJW2HRgBsL9Ns6K9iJenAkhnAchMT0U6ic6OFm1nwYiI047ibIxroXgj8JddcybXiJetDe34(1DeTK3a4f8cfA5OWbgsGKjHazVclL0N2YsjOqsy9voW4AvDMULiT)TcEIKEfo3gAqaMfhD5kaeOIR5Bc4SYRazyUFWLZJsi9AxxLhgjsfgPj6nswc0UdsPsBFx3vBhNQU(EA5(AEnPnS86iwmEIj9Dc4Jz3VAXarzrUZtU6OfdOnr2ABCCgJq5RdEtF8AAbBeincN7ujjwRYiP4J9SzWguYLMz00wD4fPD9fyu2WLVczpmYwI25fUZZ0pUAZQhZwVQS5DVBxEzzEjr6D2K9BjlbN)S338mVgDLmERJCE17zG3JtnQDQeyf7TsV2WE7QYTBg0HotJfC)o)4iAuKk)yuQGOHFOSFpDYUk1Qb6pcjDUvw3tTeiHVJGj2iu24l6YIP7wV(W(Fst(H9egD7cn07wJ2(0x7Coim9ydDUYtUVUBq9IKS1hipVugm8x(pp0OwySBOld05VLxsr0ceI3)PP382RXFX55DkyftYDng0bLbzmh(CIxNAMZP4e)C6XzSCAItJ7uq7OKIv6wWY5aL8)Lt09uWNvo33yKyKtlyKVCo0zQ)VEY1xFXLm(qUzGZHskoofonWiEX5Sh32SJvi(q5zdrhm)9tdfxaiuMY9)uQdCNIYOVD9DWsa)VRo5dNC2ftjxgPCWtie6uaUWCveWTp7xaTxPAnG4aQ(hHox0bIIqPYM3jF8K39wEBGzyMal5YdJ9yg2y4IP6g3hS7pe2Iz6hxkoL2ehHs(hTeus(rIbBZertUAemnxhquCabUSybVhVPy7618pp76pDXzewrPLMWfYNrANr(ZIlcLCDePypBPnjLNDCBWviGjMNvKLVjFfdC0J8I7Z5)Z72S9r5NxD9fVD2n0Qs1uG2qKB2KGf5BcHju2(X1N9pHOfKJneVa94aXjUaiKyfxceMRGEiIKfU6etPMy8SVLvim6jR3UDznBheZ(WLN(FrSDQAsiMWLtIwcQ8aeCPu9teEQgkiEYvbIi8urFiElvKGPurBN9(t(4jKifvcb61uvCyqJEUIBnklReKjVMjka5fctAF)UhZ2Wy71x(UpXYsy(DPtru1uioevTasEGkVeI0CTmi5bQAlSCdwVb(4gHvitGQ9alcJXhqSdQSm8HwQsitP05EdyIoNrNQ5D7J8dNgIwFJwLc0oVBZf2OO2l3RhHQEove9ZjJ39bIZFATrOA)lCj6VDDJBDtCgkhudGXEoG1jVRTVre9629vlZNSE1F)3zflfBgZBU3g7VcRCgRrctR(PYlt7uh4(WnBzEcnEcM47kz21PxE5hKC(w)LHTAE72D61dIUEl81dIX9)GP(cHORHHE9GOU)x5OxieDDq4RheT9)ka(cHORFvEnGyvNZrNLJakV5An450kOfipRZnP05SBKeCJPrPr38R1sn1HvP1Ukj(oz2wt0K(fg4ZyasGUyiqzvmycWO5RN0GxAn(due)P5Pv1ekFpO6qwRLI6GB9ViE3S9euDYflN3TLs6FbNImgDCCa4Cf4dIYe0CbN2ZBk23BQWA50e3tloxZnt2trw)Gck8uYFROKV9e6W3EQ5lU00FbIdVMeHu)UbF4Nc821U6(HkSqGhMeWsoUCSkFTNNHL8Juf34i9J0nznjG61FFpA5xeR5lnGNRN0lyhlRA8CKFkdLgFOONY(a12rg6fuQiQ8C0Jho9TAW3tc(XKxeT8yrWe09h(7PZQ67agiCd8tQyHtv2o0p)k)8WOZ5F7MHA(SFBbw(Znv)X)5V9y2F9hEbv7hOuJJc89oWyc0HHPk8ckNO57SSxse(CN7J2NUQFztLi1c6wuXbBjHaF3q6DvjrrmMsinpLdp6g(OFnWBD9YRDbYpvjDlv5Hvu5V)gSAB(6tLTC3gaZReOhr4ZExp7o(cDK5662HcXUDvXabe8Ze1FmV1n3Cujnz4VHCVya5IN3RUqcbX)BeqNRVJ)1VUA(8))K2OVwc" end function Gladdy:GetMirEditedProfile() - return "4XzT8S1CBBZS)yopxp4obF0oooXZjXXFrotBNPJAPLOT5jYI(qs1u3hYV9VfyxqcErkIjo5HizsGfl277IfAjF5nlxSU6SYQ15vVQCtzL7bzlVqzTYeMwNOfkzsIz5D)IwUCXTlVIVCX9()VY9)nlxSQSCZ6YVS9hci1pKbWOU4(hAUP4X8QlQYEmFrtvwt2YfV9Y38wyDYQBolBmU6adasMhKmpizE8ch)V9H7URoVz5f)IwLO020ebGpcl3HoQe32)8I6SB3K)QIQvBYxEw3sDF8YWorDWf6T5oSF5vc9Yfpv(Lb7H3)6ZV8tVF5IhYZ208am8RGxEr52Mff)BoShGjT9PBkBYF86nzn51NU5PhYoDZxYEU(MSQ7ZBYxV8waW5nV1dHRZRwLVTj7EpchyHlAEg2blUCBtE1DzRY)JtxV(dBR)J3SjB96N)JlFegF9FGJ9pFZMY66XKEy)SXHrNiM4Dpu(LB(sP)7o052DaX9m3)9ksk4nvLF58IQ8vnfLBxU4JaRdiF)DEvn83)5Jz)FLv)52DpcKjGOURklWECeu3F7r9QDp18RfRBE4ISvnLo68jPE6tv(JLvoQ2YfNxwvuF91a5FtwD9LRk36P3Vl)VZ3S8kncT3vu3CE(Dz72044IMKeM7Z8To(9AhL7PQcaqnpV8kfGbaZA1Nby)6Z(0fx44TcBIC)tXX1gnfUqQ1ZBvKQew6XSkTRbtYSZBn06dSrMgR4gdFEtrinPQ5nfjNZtoM9Emf2EaY1KRIrQm7DgPJPVALDMiLqlsM7wxX3p9LZgHvsgy)6yWQWeSPw5EhVCsPeLDMBcLIP2pPAYfHZu7FrMyFB5cX8qQe(mL1tsN7sWTkZrPZgnLuPD)sHtR1koGC7KlIoXoZDIqj0ZCNyKhqqCFKlX(Tkon5sjNRAo3AMlIjbHR9lnkglnksb7IZr8LNQz7xnC69Hjnz)B9jvQeMu7CNctRMlb2fg38MHCUoqfS56dbeUspkdJX(qeP7xpzcBPcg7aS99XfNVvf5CfvewXmXljtCa)ctVkkPy)w53J3nZbOWtOyjv65A2wKWS7NXpPqpeGYbKhftGvQ05kaNieZK(6CTpZao4GLR9JytRWNWoafEYPiLc2SS2jLjZ1jNqONDC5Y0dS51Jrln7aw5NqD3WMBm8sz6(NY0XbPfhieIPJ2sRK7xGFcLkJAw6GGVQKzQNNYMlPYAuZu9WYtM1Uwymhk4Sj23mXbwHXtaMcKkoKS7UNC5bpz5lOurDOhvIG9L5AxnkugzIeqglljfYoq4QrHz)LgWT2nvfB)CEtib8R294T5v(X4lnYdasTXHytwocAY)Eil8FHDcJXaNJSegyFrhHKZP(oSr1iHWUFpkD)iIIViixybEG2WH8OaNToVTWMpTDCoC41DCN1(hCD261fBXAjHfJOdlpDxvgIPtvIOtSEMORqnrfVbsfLkrtubwMGb)XCyx4(MZNbZlmmO8dRNU(pTKZaL4cq)jHNA5qoTPqOLAyxdKYXLEPjRIwXuy7Sn)lVl75YDnoAbIXtUEGuBr2MEftH3r6NAg9QcJNqwduXR4DKYMNFkF5IRF456IvzBOI4rf07wKHFLy4WFB5MNJgk7Kugn8t0mxnaVsnCkxuuL3BkAw0kygn(tRwLTD6z4xa7WjCvwZoAjyNarffVj8)nmj5ODYcpNHMLFbgTul2T9ZBbX9Ht9t0Jr9csAmSH4MreGQY6Mblu3I0mu5oYGZ6QivLUQ0nuoWBulF955(H4wEldCEEMZGysAI7lqCYq2HUNyHGzpluJh4ljUSzHpDL76mxINg)mfPG1D34Pp9Lu4mNFcPFCCPGB9Z3doFY9(PbwC8pofFGMl9dJEpM8SB5cRNl14Z8HoHRNkL7xiNTl8to(fPcbKl26Z8UDrizsSwecsfoaxoQNfciXVw2eCUgnN7Fv4ba65)e3lyoEUzii00ir0sQyEYNnv4bGpdkpOtu(fZgwDF0a4oLzqytuuLrHmfWwlIfAWwH7lkoHYyyxWx0w)lmwcwMe)7tyeve4N(VibcpUPfg)i8(X9RgezP)ncCrfbcURcIN5PR4sHPeDgsM8Fj1IKnFn98Z1I7ETa)elS2z(yasOhW8FXGqqyrcQBrqYcGE4xstXTIRItickjzuds7fGZtAljWhKM4NkW7qckiuJd0GFHe5WA54anZI4skkQAizrNX5wHApinCjXJ4OGGMezaYfU4wnodqwc5ijilHyC4BDg)rWyiPdoYonmgIGerqH6C(SPD7aMGapW)5eMXrIpeJpQFHkyGCLMiPemejPKcHc)cwbi)YBtsO1brljYHfGCossvsek(sa5NI0qQDCljqRjsJGu)Czq5rXKGgncdFTQ8yQ)9KDfon8eEWEcc)ebQrzq5uoT9mwnAOcIC1tjKCshG46qG5445KCeHNWMJ4yjEvZOWbo6dzAOx6iRUo)O4H7yNi4KEGLp84WO49QDN3Yfvf5BxdopV15nF795V6H8vF(vH4iCpoY)p5dGhp2RPDLdRAp)PEhyeE(qF9VUbctRP4PV(xqGTBx7CJ4H3n5)tt0oRdgh5bKrb)nm83IrHm1UAdgQN61)y6UDmn9v7QQZNGWgI4Z4zXf)t(gi4U7Yx1eytdwT2dzJIo94yyTNnv8rA9meLmyuuaAAPMuUMbgYHOAHOK)hiExijwTcKhnmLYYcVz42QnqRVrSS3w20u(47ZQUVylefqAB09d2ErpLoRp)XR14pMXVHKpSsT7zhLZfvX3BIbCklQ2do1LtqrBUqGjxHcmpQS6uqLMtPcf4x7dfJyk3(TpyYwf(bsYjHGaPTTmeKyloppvauLXDMVozU1vVnBZDhXoik1NzD0UE1381)5TBEQFW(DkBJtPevr60wNk5GAWG07l)B80FjapX(4eXyXLO9Y8LvyT8ZyfJYI6YTtkMA6M169OdpT4Y5pVn7XIv4WdMh6t5ceOGKfs8UacKrjH4aHOlvkDAyJ0ASmiM7kovNT5wbjNvp3c2t4cTr7DIOorpi3SbOLxu25WaaXkVxHqYb9m1V4)Fxwv(x)Rl2TzZx)RF9HIM8b8CcKblrDLsaZLSvbfIxfcauYsbJAPQeFTkuDWAyUg4SN0(sfP5CFKge8zKRJFBA1xh9yCJce5u(0TBbvHvETUEs8JYio4p1r9c(v7hoqeFaysEaazHA7qsSkgkJ0WnciNEbeWdNtTzsl34YToQN3kWGn17E9f3mSFggQa2LlxhFzyqi)2Yl(fJwAvG7gfKpcKOHxAKnWKyheIDFfxIMBH0dV3BmPNvUPvp9uRtx1SdCvDBGFpiGObfwyysQoXxxzBcjKERJknKvnwjyQsymD33eyc96LMPTHfzEiYeUxr2hTvxV7iwg1WpDbGfKEgf507Z(h367WYrX0qwj)9UkcA1AG)jKsimbx6aOBWo5aVqRhrCfzg0T3M9kGJ1mYgo2gvdnIE5JpUBB(aZ3qokOYORMib7JidfxkNyVhsX75u6ztR5pjdzD15avWl(Ff3og7UOS6XVvCpRkgiK9D0lu9Cy2taloAUiSBwqV2BZLGEqS4iJSCcgAWMpRFIcVEB(J(SeYiJEpMVTXxuNQ86DvKzgVsv9t5B20UfPN4DAKhacfL4NQZx3LIHxHm3vtQNYQAEUDuFmpB9ZO2k831Dt4MhG1(bWCJp8okOXylmKSr)iuXhUVkAFNxqke5QjggXXZ6zwT6r2ei)qPWcP2BuPclzvUT45aFiEJoWOV9KHrm9Dif0tgBOn73v6keNdb6TmKphwB9K7CotwkWZBautYAcEqC04X24JYUAKX32YZpWJ05F4xVk2wtRYGl7IvbHsheqEq85iOD1WNZKAoy9IIDbTRp)egImdhzmjkKmKweTJigBx2eqw(AR2albeGMp6mvhpTEO)GJk74N6o4eYon8pH)SlW08C2PZQOifespx8)aMcAougwjD6(BqHIZcN2bknOtqwYbIpOJa)(S7lwnvoXHqKprmmf9ygdeENMjHO7SsU1KQNMXmkfyYXyViDdvHieOByjbVHU9wnKt(7k2M3f4zGBEB3XRm5UDGXduboooKag8rVOJ7z3vUAhrLWiLxNF2MI)9FZQwtwCJN3hGnvWBMZqW4ddAdKkY2gWx5nF46(w47OeRkgfZjrbgfeW6QRGOZpC5N8084C29rpuGRx0zo6Su)5JWptazAJflsiQNPIIjcQOX5tWlM2DuMwJYkzklZYHGr960ktFjn0C9(eYI3atEAgDkFARIzyCvcpjXsT2TBTk6gIbu8LPUsRBLwg3ViuWKb(uS3J(D1(SSZt9vDV2Qpwy(HzwBP2ecgMPdMiYG8X0jjQeW(JmKpgmKRlRa2vrtesexzbuKrhsvEpvcZP36pTSfpwwcg06hMuVd2nK0waZmkTLRmPmEQvkIXSE1zlwjEqUROw0yNyhv5tos6CV9txLBh7w4WkMKxQrj43RYPd2URRgiOkDh)rcZYs7L5wumo8a7kwQfW1Ehr(RGyiUhwKCFyGRAQ2u3SZxXKO(C4UYQv5HuElw5dfxQtn(ADvTD9WPC7(MI1GL79HmmO9V1AyCTwKBna5PJz8GwULwG6McSuVF75y9RXNRpMrleP(vOEvwdiiCCZHR9uQ1f1ok92JARaPYHsOpVAt52JANy4jAIJmKGTFoII8UVZjxd7jxpSCeRfKTPNQTE1XmAdx5XSDzhZO1P4(4U8SQJz8UJEAztK68B2Lxxds0Dr5nzSbT1ddC7Ntbreme(DyvVx07X1Y67hkdkV0Hd2S31FIY3FuZ)0fTpSzdNeqBg4tFak9RFqRzMJW8kT4JaB0bmeh4qBf2ARGq7JIggfro610T(nU)uMmQT3YIRz9U6MYh9rwUWjU)TSp3qGLR5SHT72lbCT8rDr3Sa7jPHcORLJaUKLmQLmNf03lspQrxFraRvoS)aFjalKf)pdWYz6FkWvlh1u7VeG1kg1w2VeGvm(AanlW6Ys6E6Zk8Zi5xPXmS)pNf03R87pgsVpoNRdAE5bRqNo6k89saxiq7FiI7jCI1L2AOVf0UGw(ba9(iWJVILVeG1Q5dB95zb2tapdX1Ao1eldRth2FXZc473VXpfsb3(ZGXjHOL)HiX7ZgS5h0t0jCtpHyhV02xq(NHkTD8fd7LaSq(fVSylmWn5zqyKhoDwE7u2BfV4ufV6FAuXnLDVKQpphsa5H81ynUgh0A)6(398(X(E44KJtji6WXJsIpCq8q2QJ2y)UlbCoxjs0qiCctIaBlhiy1(hetOOjMOK6hvHK(NUWRwVx(sC40ZV64D82O6oeh5DxTEUUSoCkbdlYhegFE2G(NIGV7m5RqXnpE6BAyp72nAjeqk17Mu7ZYeyN1P1yl6rnUNRXFXhWW2Q0FRSpZ3)OP(w3l1e6Usf1THwQldnudT6(LBWpxj3q99RXsnGOs21xJylxMQO24nXq9Imcwgh75vbNzjOztXUoM6pwH2IDJOIgzQfBhz35Q7xKKqtLQsiersGYDHsD)TwLGVGHt1bZqZTsOSWLHUhtryLsnsRweAGwbIxcMe7(vJHaQHhAntTrqic2kOjHw7vrD1jNJBkjmcCt5Vgr(Va0tekarlGKuFKI9NSeirTunIptndBc19Q(lYoHb(vof3f4EqyiXaMIOCy7nd0CKusq1yPU3f7aDrIbrny1WbOsXLtWsPMXgWvehjkEAckqzO(p2v)zryKijqe6nyg1g6IuStKHLZVACSjvTuNwd)nUxesbkDXyyBzRXUhN2nCfrvcD4mhB7u8c05EUjL2FCQnLvgQNItXMUnbBXwQxKDiyG(HuxTahh1vZoceUIy7yNGpwYyOGOYGltQc7k722DvrDoBkXXLwSHybgcJ6LygTxHLIAcxAPiuir22p5MqFiNqD1p1fVWtOMUgBhzbiaJIJgUnOgOB5Be4S0RazySzFj9rJI4JuldlvKuHH6qAK7bs6bfPuQNExvC0vT9((N(5zF4MB(GRP3AYA2vFBWbuOs3QtedmA)9xkOo720pxjlCNqV386B)0v386p6(2J((6mH5Rh2IF90p(Xl)q0laEJVWAxF67o98lVQ9f4pwiWlE)PV51DpfHY1F8YxV4M2NkbUukb939Hx9)2(cpDhE(5F8txEE3W936a4XF8dV5tDWwA0AF7BT4TN((tJXefxHbGmSj68BvUGHI64nO1l8irPhjpvsoxcx6GGDP2lzqWDs7LmW1H3OKnzGIUKbJ9Mali147IW1jXFtiDFPTN4j7xWQGnNFRFgUKgIeCutZoCBv4Kf(W1vb84qDdVpkxCLi3JYeYmTcB)(wFnWqOMTp0t7TxzLeK(yzKgKG(Iiy)P1DuA4kxitz9V0kGjoeQcTQVnUwB0TgHAv4f01XO9Afa630vhs01N)KJi3Th3dodEphC3FHWRiFhHlCeemGK6JFYJGLm(061Q13x7vlq6LSCFXl65ryRTV5gFr5CVjLMnxXdS4uYExRNYGvBUoC7Ic3Aal5ULSib8Es6JI2XgIljyNfVmQ(N4W1itsF)2lUDu3y8WSpJQ(rNEv5KXNYNk2YBWz6cJpRbaZT7AY7UKG(MlYLlYwx7oVa)5RcSauUU4UI8k3BGj04SW6sqGm2IhL9YWvhCaqUWDG9tddrhm8hRVdeYjaXP(b91)6)ronC6aZASG2RxgUuI7dsQ5aj9HGKEoqYCiizMdKsoeKsMdKShcs25aP0dbP05aj836G9bkxpzC0WQzz7VNyTzZ6Dz516VPxY59(DfOXBY8q)Eh5hJ3A93amjh6NDgALgxRYHJX7O4Wdj5BnaWA(b(nFItf7D4X731TSnX9Swt(2MhQ7D0(ThPDOT27FzSdXomSwdX9Dt89mct)LAdliKL2h1MW(7l2w8y2McxNn2DvnUP8uxo)x6Rxb2(AD1VGSEoSNEI6SOJO)DEkQNOMQYbdA22HB44Q444brx1H4gozWv4)73RJhDPUxMWWEDguBfBAwU8)(7QXTTi" + return "4XzTC11DBBZK(hZEDYsasccEPLDCIpBISxlL32EARAOLOT1gzjVuuVjPN9KF778fib)srSj5MyfrGbdgmayMNNHAHAX8fZwvmzxXQ8IZ3Tzxb(fzlMQwm7UfxgNKQTM4OGWGOuvGDX9VioCXShg8jfd9KYfZ2)y2QDFA)6hESC(6NYlUnFZn7wVTegQ5xFZTx963mVBJUSi7P8zLfzLzlM9gOnlMTmBF5KSH05PbO(H)Bb(VLvT)xV((73NxU4YxyJuXPbbHMuJvhfQbnmYUy2J5zBkFCE(NlVfh(fZ(9NZlwMVT8)BFzw5H9)5IzpV7t5fvT4Fjseh4YI1B)yE5L72w(QTz3TjF1Ij1Q6d(QzWlJoQI(MCA4NQdLbSHn4DV6IRE)7GNKx(gsH96Hbew5UY8NU5WM95WdUn)FNxSpFXDWGKTCDgyW3VyMyQRKWn80m7HCuNLzYqUergJoooqhOJIJuWiclVrKlXapPyONuIk12hYp)X8LFSAUqMTD72aEbBFDXUdpFX6I8LLR3TDXSlU(xM21fz2J7(08pTJ(m277oalltW)58A58jpXiZF00a)))6PS)NDf)12dpbMCyIEOiZ5Qqlrn77KRNp)AW8V955f5pTRaxWbfBxX693CdO5BY2V)QL72sRzVfm)BwmnML6BxVV8I87ZoSPeTOMKKa8V51UlpxSgeu5xwmncxjHLSpcY(vtE)LxIwlTnjC4UOI7PlkDyC84gLWOKG0tzuQgdyNUDCJrC8rMi9RvkJrnUUOHn4rJRlHkLk5uM7(wy7rmx9okMWiZG9iTR9noYosLshRtg7upsnS9vf0rRmjdph09oabrXd7M0JFLn1goy7d7Biur64HNe9QvQ04KHnU9APubrdBB7XszvA94gHe1i3Dao6h5GbDxxkBK5K2J7BOcTdVI3)UC9r8Z7DqItSJ0uPHL8rotsso26xpNVzdh2pSFpelOvNYq4np0XJ96afeL1ip3neCfhEUR767QtHZDhJZoSFkySwltAYWlH9UrxBsTJTlbXrJ8CAvYroJR)Eeo2lO1bJ9okDqWrwsgYFm9Ko61)AnD6WBf7zxsyu8yp1sfOtoIA115kmqFKRe6Fm0w9iTwMWXUTsNeyhUl96oggQdg3glirLrErfeMXrwd7z3omgJnwMWOO0r6YhggMo8PJ9BTGyhgziqqwOJ9QKKGJ4b3)HkjA9iDiddtg79Ok4y7XQyHPhPlXDx6HSZg1LIMGrMwruuq0WlH9ojG4Eh5zJq6LHdVrShpEt042GeRpsCt9QsPbJ1sznrJ0NYQoY5O9DRUXCSW)6zEBg7UjOtpNxsjWxJ(WPLpVFQZOYlWI0ktBkl)Qe11Puk5e2hBYkZ3F2MNFm7SnFk7l7XXxE2EuXFegPn4O1lUkc8h)MdTOiiEM40uJojmjik1S4(xarf4bw0BZVV86dLBwVLWzPcbGoaOCzK1cYioobcmoeJTGXmRxOGeKlQudWnkrLAtGv6KGalcHIjPHTz26)oFXLgtGgoFfYz0eNOP2bH94AhQxEWtHOsC12Y8IIdpxVwTIA2nzRwTE7dmSpeIk1ZNZG(XZP(WC7LwA1hrUYdBkmlKhBd30D9HkimFXpHDjG8IAHLYq4iQ9XrSAz438WYPdYrLzfYyLQ86t)(PS23Rtd7E)lRxbppBzjSIJgge6O3TE1QnSJHSu1x)BSqqM49G9DQQ2ix(LNZxm7Mh)Y(1lZ2qgAfz0Dla4MG2n)n728fVMg8Y0aP5Vmg(e0LO2D5syw3OlXbEJGPt7pRyz22(7bna22DyAw5bzicEjeqN)KG()qNc7mtMrRCsVObOZqn7W2pUf2Y0URVx(AEVL4N6MqkthdqXU9LTgO6bPS9Xh(NtT(STlFew7fpfemtyZK3(TAKjB7QqhFMV6ICQjOozdGBPNGbjNKMGFacihY0f)glCw8eh(wWhsWmZH)Iq9nbtI2q9uNc3JGTx(lDD6e8gPqQDQqTYs9Nehbtb1TKaQ9ueuy)uHuZKNZabGdNB8W08NqbPXJxuQIgiDqcRibk(dHrSGWeQNq3MYsYKyTSecJ4gG5ppXLvmnw2eUVMyLIEK7la1J(lpx48pXEOf10eYQvyuaz(SPAsau2DKOtIObZ6gD6sEEMgyyzlw0iteVOahIZAbC1a12iLOYC8DWhIT0dmwrwMe65jbIvewpPpecgEEsRnulOigOrdc8JEIMhuTZGJONoHSR8qXPeoHnt0hsTSzJWZK6RLN9XA(VmOItOOnsKViG(GHLG2YguCqyZcOE8hst5PcgshRGHIpQHT9AtyImL08xKMqDfw7ydk4uZn0WFqC5yCPqrhyzDjLDvnIVOcMgvo1KinQqznsXocXIldyU4b3gZ9a8L4vKeEjrw44NI3VYIXiEhkE50eeWkOyeI49CuM(4miqlINWEK1mfB8du8SiH3Gb(vXIjvKHojv2qeXFGrZIgEBsImoSAfYRWAWpNnPrHSuO0vPUeAKTDkR4qhlMgTS9dZvJuXe3oAwgeUBKMspxoxrjnpr5opHLFIM3rzy)uLm9m2y(GQ4eEZrOs2diR6qCjC7vIFKONWKtwXsOTMErpCYK81(Q9wr5qbhn12tSmFZyZQUcOqUNXPB3MTmVkWlkQz8c)3lX76i26Cxqf4x7fcHCXHYVT3isg1AUPNTS8aCD)D1rew)SrtSiDPdE7k0Sg0eEYw5vfKAJH92kC8vfoY2AqXOJVumi534IedIHBZo86oCE1E948diHL(AHQrWLgAjy9NHG(YlUhIqZTe3sH85hfFu3zxNfwFo98Pa8lywaXWgFihaLkgYSMcRgCp(8IlXTUiVCW3MOXRh4N0EAvf523iS572vwU7P3Lv8W6Tqyfr9rNjzHDer6r8mSoVjNdNa6)Gu46gwyaRM6ObehJXSXWx7vscFvCxtXdvr5oC)ocIbCISnaoWefceZq1Y2qQO3AZDFB(CRoZO1MIexWLY0o0f8jk369bOBQSvoArlM(RCDFrCtpRtCdiVHDkSTh9wxv8MSn3FctAVS2GOtH12zusc3dh88hNTA11B3)hVEdKN2x(JREcsNA)FWlF)fK(Y2v5R(R728CNYAWlv1UjmZBWQoRP3Cv2)iKvZU)nZ1UOH9mxEPURxM38z8Uy8jznsrJZwDmEqx8LTzpTEj3C3bhntVS9o33L9W6L9DGeAPk4zAP3zYUTaqqL9vFd4cboYY(2HYgVLsrUJyHoaEFlPBsCzHWAQ4Em7)9qwr(x)WLh2S5RF4xECDzERvtrKUtOKvDLlf2QDSXklKhaSyaByJmuv8a3(xjR25VW9EmLrexZid8KbkJOiFOr(1(pfaTIn0oiR3gHhC22TW2JL0oXg7aApNQ81qBU7g8MbMWNxe(s(ub5(viw7ATKrLjjjkjeUDieZWrZxsy9p8rCdWv4llwNVDfK4(eVv5R2IRkK7ERP9BF1LZBx3jT3Y2eSQ)L3vBIxy1Uj06DAO09RlU8fgteSHnasujYASrKtsINYqxuXkOhaGYrpvx1(BD1NwE)9ANE128N(sN9n9R88Op0EngWf)Y2AD9(cAb)8d7HBLNN9qvR8Wu8nRxLFX6903lOmIXRTUc7UxajxajWajpIzwgdzsa(Yk6ORErGSA2EU)UngNvEM4aAqmxOOA79(O)boeIlZEA3oqmTVqOh3b34o9Wt3LxuBlKh7hHxLhkT5W7MXJFICGlOdgXJXh2HNyeTQ6OllSjlwb56arRztvu59f34aAki8kitJXexsH1M04yifnTazADP3vhQUB3VNVI4fubAhV8fMW8qSSPvOhiO8HuFj7MH3qmd6s9nYUavuXqMZ)eKRvLCCX(sNX)LP6XkCiL2GFggdRIzE8hTyTHX)eeRjk9NHy1chz9iw8wPhK)Eh)3rk84W0He(3JoB16FgoXHbjmL6)GLRvX8X1vSUabtfdSASIwfe)tXRigbB8hVyddnMbmfFxY1kfz0pAXgKO(jiwKoWFcI1Qs(PCCMY(ZWiyJv6Ho3j14l5xc3ynsHhl158pyDouNAhsP)EKRYm8nrWS32(ucZyhaWr(NX2zRAW7o(EeRk(h8fOLvX4X5Bf3i1PEqHjU)afzITzzGPFrXFYbUF(6ILnOP938EBrII0HALwfflfaaMKtdOn9avPlAUUm(RFsVucwRByXWu34BPi(PKZka715qYRLDaNHFZyAdDXvp90HTnbtfCdtf)rK7v6sSYAw2BNlYZEZHgjr0eFmFqLY)0BZ(YUd0uMAvt((PV6DzFUc7x)qStLVRtQ4scjUetOaTddszMZ4QWAYc5nrycY8qkZXznZybwPnoMWOQWh)chtykTWRfvk8tQycdUCIPXqRTvdOWoJUIZtS68M4tCtaZwcmkmdsijpog)4MecP4iKz5Oufz(e)GJtvvGvOSHoJHABSJFtMoRqihCM4RqHOoOjcJqoIxQ4vnHTp2aEyq9NNrkMBgUaHXVGk8xsBtdAYSQkrmP6yHpxWil0nADCfgXKcPnosX0gwTnXXclvoI0sCeDRRzLsZIZiKXvXbEaMF2eYEZRr0ljWeI5ZqH0jdVCY1c2eY0zDFq0ChryHbrcxu6awr1gRWzvKJfnLSGM6yknY9niev0hukMmxUQoXVjw8lcfVnqygsZnSbhmd8erfYSOrv9fnmXS05I0I1TfePyCU)FdmdAHnveESx9R(gsGbeNSo2IK4X56AQHYOn(tlxFcNYC5UINAEgJ7yE6cqIwdrqEVquLWr63DOmVUqx2)C(Mn4H)BrCYNnN4WybCGZQ13VoVaFc0HsevhyCYeaEyQow4k)Lwc5YDW9k9ldDTmUNAfw4j9iIZOg91p8Fe2VCQfZkbeOfUcRzijfngjfFmjfpgjzoMKmJrsjhtsjJrs2Jjj7yKu6XKu6yKexfWdjkKO3twwKRFlChBGy))acDAGDPppLUlRPapAYmDfWEW(18vt3D(QE2X6fQKCutdsfRdvPrzxYnToYSk0F9o1bzgnorznPrWLSUqO4E2aM0214isgG7DNSAot3(thGoFOsyLG6aU054VPpLYfFFdXKCSxbgzKKeUpsBO7CpEts(wnacY4ifrn1MYA)GtK27gV(3(aCZV2Z35UqXTOhHmQ2tSOUd3dAEFsfo9(Od3jEYmHvMNGifzyuzp2BZZw9fszWTJvUaO82luHLtdWDvD597z1Nb8LinjhlPVNZkkXYHmF)HcHFG9mLkq32x3J5pcn5riqtIg7YULsGxvgG(M9WFXXyHyiW1VNUPL3TrCl23D68Hg8zeF9dZbrvU(5V(H9eVFRK9OvkuOU1Pf9OQYrcc89vn4fqMY(816rLtD1N4fNrcM0fDpk)TmfiNCHL0MDP3wvFinOOtIPjOI7KA6mfDLRGCiIKSsN(UQ4FWjUVEZU97BTgu50E5MmAFt9rxqWDPHgigxngph)gUh4iNMxuV0apjimnkbIufojmwO0OlDp(frrfXVy1g5yORA9SlrN4JDYXJ4g)PXW5khuFOqD(Nxdr45Ye7L(8OGLZG3TmmhO3SRacwCTpV2IJwNmTBOuDO4Qv8IYYRNyjltD9r1KJt)AnQr9AC0Tr01SDdWf088SwfLKyWEzKeLlb)XDvZdnK(jS6)FdBllpwj4K4BXRPqFuUQncoOUoSQx9BSf67Da6AnpHT3U83hQabmPAypbKfzOjkkGQpiPabg4jfd9KYMClxhbK4a5DoMtPEx2NXt42FdCSdcIXuxrx5Dvyd0Ewm73X7E(ZV(HFhw0Y)thqgd8tbrDOrE7p(bSm4ksm1IAA7BIa1CHE4gB26(ZtYjgNq1K8ek2gNTTZMEVkiS6UU4fnkyn6QdxKf8biuXXpXvA8HqgSsnklLjEGMRGuxs1sbQIf4o)fbC5d7W8jm0MsP7NACvrCKuvTwb7KoG(eQCzOBSsH2gfwx)UmMsPrs5QNWWDiWaOduCTDRvbwrA2ubPhg6aiLCgqKiPLPwg(IkyDCO5OIsCGliIsWSrfhL4WbZ6KPRiUfvwlamzszzLkfmES2vO4c4l6GqgnmJreQd9eTsGYaueg0KexjShjvVCfEiql4jLdmMOyWEYsbmAoL0bgdd)MdQouRL1zPOVtKQ02HqhQb0iNkq1jiNiUbceCQKah6ASPuKQauKYYaqPtmwbtjUKY1rPbcStPYlDaORSokw80e2HYi1zpmh41xSLSjq7Qb(a51TqNY4ibdhnAkg2lR8gfa)FEUGvljpne41IzySKzJksSkv4xg2edQytQm)us54hzeiMsziMsySZKAUhvqN9JTUXcmNs17JgiEez0kt4VomiGDeJmcqzr8BFqvzDlGbcpGhOqldTgE(TapyGmxHHsk2CzOevijS69MW4Q3E2ULi1WUc(gbZugWsn4aZUJoaabhQ4Q1nrCw5rGpmxu7Y(rbNoTR04dJeVcJ8MayeO)0UnsPsTR3nGo3pdtq7k9JpTes25X9Dd4WVwKkXCxMuFIQxo5uTv(CDLVmf3A5ouht3PFIg8IA1gbUwWMivcwHUUYYLdLQ3AEYvXU4DAvArA7l4)NFTwJF5NQdR70VKsM9V(q((950R7z19W(x85E9kPWbMF9nnY1HVWwh5IFV1BDAVaW6TeoQzVK5gp73aj7M)nIQs1nQQt8o52LmkhAuJRKpbP0PW23TE)UT9gCRPwvBsZvN3T0UXSExxkXECGCWxvm9WMnhpk0MbWuJPL)MLtW7656c29UA7FfqxWzhW9(Wf1Wr(PgE)uupSxDnfMdmsV59tN)QBXpXSRmfUMrymcZCH4TbdhLP7yQzbtSa(7ugZtW0e3rItHJVeInO31wM5bk0xMEPPWHfmJtinBuufyEZmZv807xo72BV6AwFO4aW(qurHDHjFb1lMPm0WWr(G6dHhhQoiRztdL7OjvMyCBkfB(u0)7vBUhgc4)DZzV9SlUAkfthX8fPq4T24aZC3HtF(IBAUsm8H6aE(mkDMQpYIqeiXZK3D2RFfpnqEDiXsXKWApIehlxKGjCEWXNqAlYVgoumrs0kcbsinee1AOXGVudvtMdq2MRdiloOaxxSKNJZl2Tzd)XlU99xDbPvezqKUqb1rZmkGtCqikTqLId9KMKe7w40G5LJnMxuKLVnFnlCmKzigA()86T7Es(4n3E1RMnNgvIjpAcrXbtowuWdKMqCSHJphabzlOipO1cmKauNyAhj3kM4rEvbdHdnlmNGtPxTIl(uwHSqpzZUDRQw2b3S3E95)x0YoXHlQjmjU0qqKYrYLiyJm8eZLOEYCVsgEIQvATLOMBkLd(S3C27oJCPiI7OhtCNYIgdTeNAeASKKPWAjlafMaBAFZHNY2YA7Tx)63Z(sioW0UiIdtAfI4OJ8hisDrLMzqK8hiooz)gKLpE7gPv4IaX4h7cJbWtlhezO8MwI)XPeSVZHRDZz1PCrJAKUdF9ENSwDXxBuIQHtPcrR3TE76NY2SMWjTzjUFCSsA8JXPCw9I21rC9X6nHnwUOn24q)Ot6I3bz(9anunqTQFugQVKP19iDlYdVBo9UjPBKB1c6X1RYNSz9F)3zfRK5XIEELn6nUae)UZQk259vbsDCMCLAjF(IMLHOh0)zLLzlFC(oEXHApjt8z751TZV(63kOpx9BbA5IMvj4poj6kj3FCsmU7p5LFNs0vND)4KOU7VtnFNs0v4T)4KOT7VJBFNs0vMx)iKyzRTsxKJcQhO38)j3TMJsFu3ACE0Xp7QjFm1B1xv08aJjD5N43WSNGd1H49uXWDjgn)ksfp8pdnC9mWZPvfNdp9bqPP6Fy2YYIn7lpSTL98(DflZDV5rRX)cr5fNAORxl2UQDxUBOUynCcdpMXLQX3AmmyeaLmt2Nwp04VYc8qSVCndw(3QpXwlnkFC)P0AiGuUus(YYn72EsdGrLq3FUFj4zMxCAdJI)1QgM64YZ2YtPtgSsJlfylZlO9bF8u6Oom0ilMf72vEAlMr0RGr72pSvoISBRwEkT2OIit2HStP1XPSb((8SItP94VEb82963i257odVm9kMY52)c9uNP266C1BCwr9R2V3vN9MlBN05A2H2NKS(Fq68nbZyTeGtq3KS33LGSV3HRg3F5xz6ziL5KtFDEMprVw5jb06GFcF8dI18cQxMz0d48UkRtSI)wwk1PyqFlNIqzJ48PhqqPv6Lhe3C6hmLsVaT5VMcYU0pGErtWSdiFi4CAWrGyyFQQDnb34nr3b3tR3Ds)FxNgdDwnl(1fZ(9LyffST8p)p)9NY(8F2lLJKNqABA37ToC8GSW7TBUbDuTQiHA)mEYi1xBBM6p(1HEUO9avwdCBcAwKj9gcTmAl8)fkOX2R2f5l)6awFXV0V2nZRidobmF8HuJMoE)kC16D(UnYunzugwLXcb7p9G9XNlXM)QV9pFtCd4W8qNSfesCWkxghfefQsJJ12OO4u3BjzR3Wt)F9ckxS4))kE61Zb" end \ No newline at end of file diff --git a/README.md b/README.md index 9fc6876..4c269b9 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ Thank you! - added disarm DRs - improved some class icons - fixed health bug since 2.5.4 +- updated Mir Profile ### v2.00-Release -- 2.39.5 From 3d4479cc06fb74bd00abdd260a2787abf7a2c052 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 22:25:54 +0100 Subject: [PATCH 161/268] castbar font outline option added --- Modules/Castbar.lua | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 24fc6a7..05ec33b 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -25,6 +25,7 @@ local Castbar = Gladdy:NewModule("Cast Bar", 70, { castBarIconSize = 22, castBarBorderSize = 8, castBarFontSize = 12, + castBarFontOutline = false, castBarTexture = "Smooth", castBarIconStyle = "Interface\\AddOns\\Gladdy\\Images\\Border_rounded_blp", castBarBorderStyle = "Gladdy Tooltip round", @@ -115,7 +116,7 @@ function Castbar:CreateFrame(unit) end castBar.spellText = castBar:CreateFontString(nil, "LOW") - castBar.spellText:SetFont(Gladdy:SMFetch("font", "auraFont"), Gladdy.db.castBarFontSize) + castBar.spellText:SetFont(Gladdy:SMFetch("font", "auraFont"), Gladdy.db.castBarFontSize, Gladdy.db.castBarFontOutline and "OUTLINE") castBar.spellText:SetTextColor(Gladdy:SetColor(Gladdy.db.castBarFontColor)) castBar.spellText:SetShadowOffset(1, -1) castBar.spellText:SetShadowColor(0, 0, 0, 1) @@ -123,7 +124,7 @@ function Castbar:CreateFrame(unit) castBar.spellText:SetPoint("LEFT", 7, 0) -- Text of the spell castBar.timeText = castBar:CreateFontString(nil, "LOW") - castBar.timeText:SetFont(Gladdy:SMFetch("font", "auraFont"), Gladdy.db.castBarFontSize) + castBar.timeText:SetFont(Gladdy:SMFetch("font", "auraFont"), Gladdy.db.castBarFontSize, Gladdy.db.castBarFontOutline and "OUTLINE") castBar.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.castBarFontColor)) castBar.timeText:SetShadowOffset(1, -1) castBar.timeText:SetShadowColor(0, 0, 0, 1) @@ -203,10 +204,10 @@ function Castbar:UpdateFrame(unit) Gladdy:SetPosition(castBar, unit, "castBarXOffset", "castBarYOffset", Castbar:LegacySetPosition(castBar, unit, leftMargin, rightMargin), Castbar) - castBar.spellText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize) + castBar.spellText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize, Gladdy.db.castBarFontOutline and "OUTLINE") castBar.spellText:SetTextColor(Gladdy:SetColor(Gladdy.db.castBarFontColor)) - castBar.timeText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize) + castBar.timeText:SetFont(Gladdy:SMFetch("font", "castBarFont"), Gladdy.db.castBarFontSize, Gladdy.db.castBarFontOutline and "OUTLINE") castBar.timeText:SetTextColor(Gladdy:SetColor(Gladdy.db.castBarFontColor)) castBar.icon.texture.overlay:SetTexture(Gladdy.db.castBarIconStyle) @@ -785,6 +786,12 @@ function Castbar:GetOptions() max = 20, width = "full", }), + castBarFontOutline = option({ + type = "toggle", + name = L["Outline"], + order = 5, + width = "full", + }), headerFormat = { type = "header", name = L["Format"], -- 2.39.5 From 7d77054a7b355f6c55b39694bde79db89b6a8434 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 22:33:27 +0100 Subject: [PATCH 162/268] update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4c269b9..b2fa01b 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ The goal is to make Gladdy highly configurable in it's appearance. Everything ca - **Range Check** (checks the range to a unit by a configurable spell) - **Shadowsight Timer** (shows a little movable frame with time left until Shadow Eyes spawn) - **TotemPlates** (show totem icons instead of normal nameplates, compatible with **Plater, NeatPlates, KUI, ThreatPlates, ElvUI, TukUI**) +- **TotemPulse** (shows pulse on TotemPlate icon or beneath nameplate) - **Trinket** (tracks trinket usage) - **VersionCheck** (checks if you use an older version that your teammate) - **XiconProfiles** (predefined profiles to start your configuration from) @@ -106,6 +107,7 @@ Thank you! - added some auras (e.g. disarm) - added disarm DRs - improved some class icons +- added font OUTLINE option for Health-/Power-/CastBar texts - fixed health bug since 2.5.4 - updated Mir Profile -- 2.39.5 From 2720e25cea522d13014e9d2d8cc349fc09449870 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 25 Mar 2022 22:34:04 +0100 Subject: [PATCH 163/268] fix ArenaCooldown not showing --- Modules/ArenaCountDown.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index 4f7e5df..a8dfb51 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -70,7 +70,7 @@ end function ACDFrame.OnUpdate(self, elapse) if (self.countdown > 0 and Gladdy.db.countdown) then self.hidden = false; - + self.ACDNumFrame:Show() if ((floor(self.countdown) ~= floor(self.countdown - elapse)) and (floor(self.countdown - elapse) >= 0)) then local str = tostring(floor(self.countdown - elapse)); @@ -109,7 +109,6 @@ end function ACDFrame:JOINED_ARENA() if Gladdy.db.countdown then - self.ACDNumFrame:Show() self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") self:SetScript("OnEvent", ACDFrame.OnEvent) self.endTime = GetTime() + 70 -- 2.39.5 From cb6de72b93ec436508efd83bc625800227c35ecc Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 26 Mar 2022 00:11:34 +0100 Subject: [PATCH 164/268] version string trailing zeros --- Gladdy.lua | 6 +++--- Modules/VersionCheck.lua | 14 +++++++------- Options.lua | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 0270772..5c4f93a 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -17,7 +17,7 @@ local IsActiveBattlefieldArena = IsActiveBattlefieldArena local IsInInstance = IsInInstance local GetNumArenaOpponents = GetNumArenaOpponents local RELEASE_TYPES = { alpha = "Alpha", beta = "Beta", release = "Release"} -local PREFIX = "TBC-Classic_v" +local PREFIX = "Gladdy v" local VERSION_REGEX = PREFIX .. "(%d+%.%d+)%-(%a)" local LibStub = LibStub @@ -27,14 +27,14 @@ local LibStub = LibStub --------------------------- -local MAJOR, MINOR = "Gladdy", 5 +local MAJOR, MINOR = "Gladdy", 6 local Gladdy = LibStub:NewLibrary(MAJOR, MINOR) local L Gladdy.version_major_num = 2 Gladdy.version_minor_num = 0.10 Gladdy.version_num = Gladdy.version_major_num + Gladdy.version_minor_num Gladdy.version_releaseType = RELEASE_TYPES.release -Gladdy.version = PREFIX .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType +Gladdy.version = PREFIX .. string.format("%.2f", Gladdy.version_num) .. "-" .. Gladdy.version_releaseType Gladdy.VERSION_REGEX = VERSION_REGEX Gladdy.debug = false diff --git a/Modules/VersionCheck.lua b/Modules/VersionCheck.lua index 9bbe922..c86c465 100644 --- a/Modules/VersionCheck.lua +++ b/Modules/VersionCheck.lua @@ -1,4 +1,4 @@ -local tonumber, tostring = tonumber, tostring +local tonumber, tostring, str_format = tonumber, tostring, string.format local UnitName = UnitName local IsInGroup, IsInRaid = IsInGroup, IsInRaid @@ -24,11 +24,11 @@ end function VersionCheck:JOINED_ARENA() self:RegisterComm("GladdyVCheck", VersionCheck.OnCommReceived) if IsInRaid(LE_PARTY_CATEGORY_HOME) then - self:SendCommMessage("GladdyVCheck", tostring(Gladdy.version_num), "RAID", self.playerName) + self:SendCommMessage("GladdyVCheck", str_format("%.2f", Gladdy.version_num), "RAID", self.playerName) elseif IsInGroup(LE_PARTY_CATEGORY_INSTANCE) or IsInRaid(LE_PARTY_CATEGORY_INSTANCE) then - self:SendCommMessage("GladdyVCheck", tostring(Gladdy.version_num), "INSTANCE_CHAT", self.playerName) + self:SendCommMessage("GladdyVCheck", str_format("%.2f", Gladdy.version_num), "INSTANCE_CHAT", self.playerName) elseif IsInGroup(LE_PARTY_CATEGORY_HOME) then - self:SendCommMessage("GladdyVCheck", tostring(Gladdy.version_num), "PARTY", self.playerName) + self:SendCommMessage("GladdyVCheck", str_format("%.2f", Gladdy.version_num), "PARTY", self.playerName) end end @@ -41,9 +41,9 @@ end function VersionCheck.OnCommReceived(prefix, message, distribution, sender) if sender ~= VersionCheck.playerName then - local addonVersion = Gladdy.version_num - message = tonumber(message) - if message and message <= Gladdy.version_num then + local addonVersion = str_format("%.2f", Gladdy.version_num) + local message_num = tonumber(message) or 0 + if message and message_num <= Gladdy.version_num then --Gladdy:Print("Version", "\"".. addonVersion.."\"", "is up to date") else Gladdy:Warn("Current version", "\"".. addonVersion.."\"", "is outdated. Most recent version is", "\"".. message.."\"") diff --git a/Options.lua b/Options.lua index 78f78e1..5268dc6 100644 --- a/Options.lua +++ b/Options.lua @@ -1,5 +1,5 @@ local type, pairs, tinsert, tsort = type, pairs, table.insert, table.sort -local tostring, str_match, tonumber, string_format = tostring, string.match, tonumber, string.format +local tostring, str_match, tonumber, str_format = tostring, string.match, tonumber, string.format local ceil, floor = ceil, floor local ReloadUI = ReloadUI @@ -31,7 +31,7 @@ function Gladdy:FormatTimer(fontString, timeLeft, milibreakpoint, showSeconds) else if time >= 60 then if showSeconds then - fontString:SetText(floor(timeLeft / 60) .. ":" .. string_format("%02.f", floor(timeLeft - floor(timeLeft / 60) * 60))) + fontString:SetText(floor(timeLeft / 60) .. ":" .. str_format("%02.f", floor(timeLeft - floor(timeLeft / 60) * 60))) else fontString:SetText(ceil(ceil(time / 60)) .. "m") end @@ -279,7 +279,7 @@ function Gladdy:SetupOptions() order = 5, width = 1, type = "description", - name = " Gladdy v" .. Gladdy.version_num .. "-" .. Gladdy.version_releaseType + name = " " .. Gladdy.version }, general = { type = "group", -- 2.39.5 From 80eee574a90c7c1178e4d1d5d4f0a038eb254c61 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 26 Mar 2022 00:16:13 +0100 Subject: [PATCH 165/268] cleanup ArenaCountDown --- Modules/ArenaCountDown.lua | 64 ++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/Modules/ArenaCountDown.lua b/Modules/ArenaCountDown.lua index a8dfb51..0902f51 100644 --- a/Modules/ArenaCountDown.lua +++ b/Modules/ArenaCountDown.lua @@ -22,30 +22,30 @@ function ACDFrame:Initialize() self.texturePath = "Interface\\AddOns\\Gladdy\\Images\\Countdown\\"; local ACDNumFrame = CreateFrame("Frame", "ACDNumFrame", UIParent) - ACDNumFrame:EnableMouse(false) - ACDNumFrame:SetHeight(512) - ACDNumFrame:SetWidth(512) - ACDNumFrame:SetPoint("CENTER", 0, 256) - ACDNumFrame:Hide() self.ACDNumFrame = ACDNumFrame + self.ACDNumFrame:EnableMouse(false) + self.ACDNumFrame:SetHeight(Gladdy.db.arenaCountdownSize) + self.ACDNumFrame:SetWidth(Gladdy.db.arenaCountdownSize) + self.ACDNumFrame:SetPoint("CENTER", 0, 128) + self.ACDNumFrame:Hide() local ACDNumTens = ACDNumFrame:CreateTexture("ACDNumTens", "HIGH") - ACDNumTens:SetWidth(256) - ACDNumTens:SetHeight(256) - ACDNumTens:SetPoint("CENTER", ACDNumFrame, "CENTER", -50, 0) self.ACDNumTens = ACDNumTens + self.ACDNumTens:SetWidth(Gladdy.db.arenaCountdownSize) + self.ACDNumTens:SetHeight(Gladdy.db.arenaCountdownSize) + self.ACDNumTens:SetPoint("CENTER", self.ACDNumFrame, "CENTER", -(Gladdy.db.arenaCountdownSize/8 + Gladdy.db.arenaCountdownSize/8/2), 0) local ACDNumOnes = ACDNumFrame:CreateTexture("ACDNumOnes", "HIGH") - ACDNumOnes:SetWidth(256) - ACDNumOnes:SetHeight(256) - ACDNumOnes:SetPoint("CENTER", ACDNumFrame, "CENTER", 50, 0) self.ACDNumOnes = ACDNumOnes + self.ACDNumOnes:SetWidth(Gladdy.db.arenaCountdownSize) + self.ACDNumOnes:SetHeight(Gladdy.db.arenaCountdownSize) + self.ACDNumOnes:SetPoint("CENTER", self.ACDNumFrame, "CENTER", (Gladdy.db.arenaCountdownSize/8 + Gladdy.db.arenaCountdownSize/8/2), 0) local ACDNumOne = ACDNumFrame:CreateTexture("ACDNumOne", "HIGH") - ACDNumOne:SetWidth(256) - ACDNumOne:SetHeight(256) - ACDNumOne:SetPoint("CENTER", ACDNumFrame, "CENTER", 0, 0) self.ACDNumOne = ACDNumOne + self.ACDNumOne:SetWidth(Gladdy.db.arenaCountdownSize) + self.ACDNumOne:SetHeight(Gladdy.db.arenaCountdownSize) + self.ACDNumOne:SetPoint("CENTER", self.ACDNumFrame, "CENTER", 0, 0) if Gladdy.db.countdown then self:RegisterMessage("JOINED_ARENA") @@ -65,6 +65,22 @@ function ACDFrame:UpdateFrameOnce() end self.ACDNumFrame:SetFrameStrata(Gladdy.db.arenaCountdownFrameStrata) self.ACDNumFrame:SetFrameLevel(Gladdy.db.arenaCountdownFrameLevel) + + self.ACDNumFrame:SetHeight(Gladdy.db.arenaCountdownSize) + self.ACDNumFrame:SetWidth(Gladdy.db.arenaCountdownSize) + self.ACDNumFrame:SetPoint("CENTER", 0, 128) + + self.ACDNumTens:SetWidth(Gladdy.db.arenaCountdownSize) + self.ACDNumTens:SetHeight(Gladdy.db.arenaCountdownSize) + self.ACDNumTens:SetPoint("CENTER", self.ACDNumFrame, "CENTER", -(Gladdy.db.arenaCountdownSize/8 + Gladdy.db.arenaCountdownSize/8/2), 0) + + self.ACDNumOnes:SetWidth(Gladdy.db.arenaCountdownSize) + self.ACDNumOnes:SetHeight(Gladdy.db.arenaCountdownSize) + self.ACDNumOnes:SetPoint("CENTER", self.ACDNumFrame, "CENTER", (Gladdy.db.arenaCountdownSize/8 + Gladdy.db.arenaCountdownSize/8/2), 0) + + self.ACDNumOne:SetWidth(Gladdy.db.arenaCountdownSize) + self.ACDNumOne:SetHeight(Gladdy.db.arenaCountdownSize) + self.ACDNumOne:SetPoint("CENTER", self.ACDNumFrame, "CENTER", 0, 0) end function ACDFrame.OnUpdate(self, elapse) @@ -140,25 +156,7 @@ function ACDFrame:CHAT_MSG_BG_SYSTEM_NEUTRAL(msg) end end -function ACDFrame:UpdateFrame() - self.ACDNumFrame:SetHeight(Gladdy.db.arenaCountdownSize) - self.ACDNumFrame:SetWidth(Gladdy.db.arenaCountdownSize) - self.ACDNumFrame:SetPoint("CENTER", 0, 128) - - self.ACDNumTens:SetWidth(Gladdy.db.arenaCountdownSize) - self.ACDNumTens:SetHeight(Gladdy.db.arenaCountdownSize) - self.ACDNumTens:SetPoint("CENTER", self.ACDNumFrame, "CENTER", -(Gladdy.db.arenaCountdownSize/8 + Gladdy.db.arenaCountdownSize/8/2), 0) - - self.ACDNumOnes:SetWidth(Gladdy.db.arenaCountdownSize) - self.ACDNumOnes:SetHeight(Gladdy.db.arenaCountdownSize) - self.ACDNumOnes:SetPoint("CENTER", self.ACDNumFrame, "CENTER", (Gladdy.db.arenaCountdownSize/8 + Gladdy.db.arenaCountdownSize/8/2), 0) - - self.ACDNumOne:SetWidth(Gladdy.db.arenaCountdownSize) - self.ACDNumOne:SetHeight(Gladdy.db.arenaCountdownSize) - self.ACDNumOne:SetPoint("CENTER", self.ACDNumFrame, "CENTER", 0, 0) -end - -function ACDFrame:Test() +function ACDFrame:TestOnce() self.countdown = 30 self:JOINED_ARENA() end -- 2.39.5 From 9afc359b57d1edab4088e043307867fe26611301 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 26 Mar 2022 02:07:11 +0100 Subject: [PATCH 166/268] intercept cd adjusted --- Constants.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Constants.lua b/Constants.lua index eecf7f6..0dd133b 100644 --- a/Constants.lua +++ b/Constants.lua @@ -995,7 +995,7 @@ local cooldownList = { [18499] = 30, -- Berserker Rage --[2565] = 60, -- Shield Block [12292] = { cd = 180, spec = L["Arms"], }, -- Death Wish - [20252] = { cd = 30, [L["Arms"]] = 20 }, -- Intercept + [20252] = { cd = 25, [L["Arms"]] = 15 }, -- Intercept [12975] = { cd = 180, spec = L["Protection"], }, -- Last Stand [12809] = { cd = 30, spec = L["Protection"], }, -- Concussion Blow -- 2.39.5 From 6f50bc96eff2eace7c0c0f41bd2bb2d50b2b01bc Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 26 Mar 2022 18:21:58 +0100 Subject: [PATCH 167/268] Healthbar show nametext when custom tags enabled --- Modules/Healthbar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 4b05cc9..f611a42 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -210,7 +210,7 @@ function Healthbar:UpdateFrame(unit) healthBar.nameText:Hide() else healthBar.nameText:SetFont(Gladdy:SMFetch("font", "healthBarFont"), Gladdy.db.healthBarNameFontSize, Gladdy.db.healthTextLeftOutline and "OUTLINE") - if Gladdy.db.healthName then + if Gladdy.db.healthName or Gladdy.db.healthCustomTagsEnabled then healthBar.nameText:Show() else healthBar.nameText:Hide() -- 2.39.5 From 73a54b448964ef7052e9daf58cc860e3cbe81354 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 26 Mar 2022 18:22:21 +0100 Subject: [PATCH 168/268] detect spec before CD used --- EventListener.lua | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index e98ae44..fe2701e 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -73,6 +73,12 @@ function Gladdy:SpotEnemy(unit, auraScan) if ( not spellName ) then break end + if Gladdy.specBuffs[spellName] and unitCaster then -- Check for auras that detect a spec + local unitPet = string_gsub(unit, "%d$", "pet%1") + if UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster) then + EventListener:DetectSpec(unit, Gladdy.specBuffs[spellName]) + end + end if Gladdy.cooldownBuffs[spellName] and unitCaster then -- Check for auras that detect used CDs (like Fear Ward) for arenaUnit,v in pairs(self.buttons) do if (UnitIsUnit(arenaUnit, unitCaster)) then @@ -84,12 +90,6 @@ function Gladdy:SpotEnemy(unit, auraScan) if Gladdy.cooldownBuffs.racials[spellName] and Gladdy.cooldownBuffs.racials[spellName] then Gladdy:SendMessage("RACIAL_USED", unit, spellName, Gladdy.cooldownBuffs.racials[spellName].cd(expirationTime - GetTime()), spellName) end - if Gladdy.specBuffs[spellName] and unitCaster then -- Check for auras that detect a spec - local unitPet = string_gsub(unit, "%d$", "pet%1") - if UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster) then - EventListener:DetectSpec(unit, Gladdy.specBuffs[spellName]) - end - end end end end @@ -126,6 +126,12 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() if (not UnitExists(srcUnit)) then return end + if not Gladdy.buttons[srcUnit].class or not Gladdy.buttons[srcUnit].race then + Gladdy:SpotEnemy(srcUnit, true) + end + if not Gladdy.buttons[srcUnit].spec then + self:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) + end if (eventType == "SPELL_CAST_SUCCESS" or eventType == "SPELL_AURA_APPLIED") then local unitRace = Gladdy.buttons[srcUnit].race -- cooldown tracker @@ -147,13 +153,6 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() Gladdy:SendMessage("RACIAL_USED", srcUnit) end end - - if not Gladdy.buttons[srcUnit].class or not Gladdy.buttons[srcUnit].race then - Gladdy:SpotEnemy(srcUnit, true) - end - if not Gladdy.buttons[srcUnit].spec then - self:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) - end end end @@ -250,6 +249,12 @@ function EventListener:UNIT_AURA(unit) Gladdy:SendMessage("AURA_GAIN_LIMIT", unit, auraType, n - 1) break end + if not button.spec and Gladdy.specBuffs[spellName] and unitCaster then + local unitPet = string_gsub(unit, "%d$", "pet%1") + if unitCaster and (UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster)) then + self:DetectSpec(unit, Gladdy.specBuffs[spellName]) + end + end if Gladdy.cooldownBuffs[spellName] and unitCaster then -- Check for auras that hint used CDs (like Fear Ward) for arenaUnit,v in pairs(Gladdy.buttons) do if (UnitIsUnit(arenaUnit, unitCaster)) then @@ -260,12 +265,6 @@ function EventListener:UNIT_AURA(unit) if Gladdy.cooldownBuffs.racials[spellName] and Gladdy.cooldownBuffs.racials[spellName] then Gladdy:SendMessage("RACIAL_USED", unit, spellName, Gladdy.cooldownBuffs.racials[spellName].cd(expirationTime - GetTime()), spellName) end - if not button.spec and Gladdy.specBuffs[spellName] and unitCaster then - local unitPet = string_gsub(unit, "%d$", "pet%1") - if unitCaster and (UnitIsUnit(unit, unitCaster) or UnitIsUnit(unitPet, unitCaster)) then - self:DetectSpec(unit, Gladdy.specBuffs[spellName]) - end - end if Gladdy.exceptionNames[spellID] then spellName = Gladdy.exceptionNames[spellID] end -- 2.39.5 From f1fde07e6c2e0ec786d91dd67fc007dec0ab63f8 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sat, 26 Mar 2022 18:22:42 +0100 Subject: [PATCH 169/268] optional dependencies nameplate addons added --- Gladdy.toc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gladdy.toc b/Gladdy.toc index 098d2c1..73dc6f7 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -5,7 +5,7 @@ ## Author: XiconQoo, DnB_Junkee, Knall ## X-Email: contact me on discord Knall#1751 ## SavedVariables: GladdyXZ -## OptionalDeps: SharedMedia, Blizzard_CombatLog, Blizzard_ArenaUI, Blizzard_CombatText +## OptionalDeps: SharedMedia, Blizzard_CombatLog, Blizzard_ArenaUI, Blizzard_CombatText, Plater, Kui_Nameplates, NeatPlates, TidyPlates_ThreatPlates, Tukui, ElvUI embeds.xml -- 2.39.5 From 29c3a7596cdba8a8cb5fb8fcb3320ae806a761f7 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 18:50:02 +0200 Subject: [PATCH 170/268] - fix cooldowns not showing when spec detected - fix nature's swiftness cd starts when buff fades (shaman + druid) - change order (always detect spec before cd usage) --- Constants.lua | 6 ++++-- EventListener.lua | 27 +++++++++++++++++++-------- Modules/Cooldowns.lua | 14 ++++---------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Constants.lua b/Constants.lua index 0dd133b..1132b0d 100644 --- a/Constants.lua +++ b/Constants.lua @@ -107,6 +107,7 @@ local specBuffs = { -- WARLOCK [GetSpellInfo(19028)] = L["Demonology"], -- Soul Link [GetSpellInfo(23759)] = L["Demonology"], -- Master Demonologist + [GetSpellInfo(35696)] = L["Demonology"], -- Demonic Knowledge [GetSpellInfo(30302)] = L["Destruction"], -- Nether Protection [GetSpellInfo(34935)] = L["Destruction"], -- Backlash @@ -125,7 +126,7 @@ local specSpells = { [GetSpellInfo(33983)] = L["Feral"], -- Mangle (Cat) [GetSpellInfo(33987)] = L["Feral"], -- Mangle (Bear) [GetSpellInfo(18562)] = L["Restoration"], -- Swiftmend - [GetSpellInfo(16188)] = L["Restoration"], -- Nature's Swiftness + [GetSpellInfo(17116)] = L["Restoration"], -- Nature's Swiftness [GetSpellInfo(33891)] = L["Restoration"], -- Tree of Life -- HUNTER @@ -182,7 +183,7 @@ local specSpells = { [GetSpellInfo(17364)] = L["Enhancement"], -- Stormstrike [GetSpellInfo(16190)] = L["Restoration"], -- Mana Tide Totem [GetSpellInfo(32594)] = L["Restoration"], -- Earth Shield - --[GetSpellInfo(16188)] = L["Restoration"], -- Nature's Swiftness + [GetSpellInfo(16188)] = L["Restoration"], -- Nature's Swiftness -- WARLOCK [GetSpellInfo(30405)] = L["Affliction"], -- Unstable Affliction @@ -190,6 +191,7 @@ local specSpells = { --[GetSpellInfo(30911)] = L["Affliction"], -- Siphon Life [GetSpellInfo(30414)] = L["Destruction"], -- Shadowfury [GetSpellInfo(30912)] = L["Destruction"], -- Conflagrate + [GetSpellInfo(18708)] = L["Demonology"], -- Fel Domination -- WARRIOR [GetSpellInfo(30330)] = L["Arms"], -- Mortal Strike diff --git a/EventListener.lua b/EventListener.lua index fe2701e..8db9ddc 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -57,13 +57,15 @@ function Gladdy:SpotEnemy(unit, auraScan) if not unit or not button then return end - button.raceLoc = UnitRace(unit) - button.race = select(2, UnitRace(unit)) - button.classLoc = select(1, UnitClass(unit)) - button.class = select(2, UnitClass(unit)) - button.name = UnitName(unit) button.stealthed = false - Gladdy.guids[UnitGUID(unit)] = unit + if UnitExists(unit) then + button.raceLoc = UnitRace(unit) + button.race = select(2, UnitRace(unit)) + button.classLoc = select(1, UnitClass(unit)) + button.class = select(2, UnitClass(unit)) + button.name = UnitName(unit) + Gladdy.guids[UnitGUID(unit)] = unit + end if button.class and button.race then Gladdy:SendMessage("ENEMY_SPOTTED", unit) end @@ -138,14 +140,19 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() if Gladdy.db.cooldown and Cooldowns.cooldownSpellIds[spellName] then local unitClass local spellId = Cooldowns.cooldownSpellIds[spellName] -- don't use spellId from combatlog, in case of different spellrank + if spellID == 16188 or spellID == 17116 then -- Nature's Swiftness (same name for druid and shaman) + spellId = spellID + end if Gladdy.db.cooldownCooldowns[tostring(spellId)] then if (Gladdy:GetCooldownList()[Gladdy.buttons[srcUnit].class][spellId]) then unitClass = Gladdy.buttons[srcUnit].class else unitClass = Gladdy.buttons[srcUnit].race end - Cooldowns:CooldownUsed(srcUnit, unitClass, spellId) self:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) + if spellID ~= 16188 and spellID ~= 17116 then -- Nature's Swiftness CD starts when buff fades + Cooldowns:CooldownUsed(srcUnit, unitClass, spellId) + end end end @@ -153,6 +160,9 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() Gladdy:SendMessage("RACIAL_USED", srcUnit) end end + if (eventType == "SPELL_AURA_REMOVED" and (spellID ~= 16188 or spellID ~= 17116) and Gladdy.buttons[srcUnit].class) then + Cooldowns:CooldownUsed(srcUnit, Gladdy.buttons[srcUnit].class, spellID) + end end end @@ -333,8 +343,9 @@ end function EventListener:Test(unit) local button = Gladdy.buttons[unit] - if (Gladdy.testData[unit].testSpec) then + if (button and Gladdy.testData[unit].testSpec) then button.spec = nil + Gladdy:SpotEnemy(unit, false) self:DetectSpec(unit, button.testSpec) end end diff --git a/Modules/Cooldowns.lua b/Modules/Cooldowns.lua index e915321..c07e7d3 100644 --- a/Modules/Cooldowns.lua +++ b/Modules/Cooldowns.lua @@ -91,7 +91,7 @@ function Cooldowns:Initialize() end end self:RegisterMessage("ENEMY_SPOTTED") - self:RegisterMessage("SPEC_DETECTED") + self:RegisterMessage("UNIT_SPEC") self:RegisterMessage("UNIT_DEATH") self:RegisterMessage("UNIT_DESTROYED") end @@ -299,21 +299,14 @@ end function Cooldowns:Test(unit) if Gladdy.frame.testing then - local button = Gladdy.buttons[unit] - if Gladdy.db.cooldown then - button.spellCooldownFrame:Show() - else - button.spellCooldownFrame:Hide() - end self:UpdateTestCooldowns(unit) end end function Cooldowns:UpdateTestCooldowns(unit) local button = Gladdy.buttons[unit] - self:UpdateCooldowns(button) - local orderedIcons = {} + for _,icon in pairs(button.spellCooldownFrame.icons) do tinsert(orderedIcons, icon) end @@ -337,7 +330,7 @@ function Cooldowns:ENEMY_SPOTTED(unit) self:UpdateCooldowns(Gladdy.buttons[unit]) end -function Cooldowns:SPEC_DETECTED(unit) +function Cooldowns:UNIT_SPEC(unit) if (not Gladdy.buttons[unit]) then return end @@ -854,6 +847,7 @@ function Cooldowns:GetCooldownOptions() Gladdy.db.cooldownCooldowns[tostring(spellId)] = value for unit in pairs(Gladdy.buttons) do Cooldowns:ResetUnit(unit) + Cooldowns:UpdateCooldowns(Gladdy.buttons[unit]) Cooldowns:Test(unit) end Gladdy:UpdateFrame() -- 2.39.5 From 96c42b15221162fc9c89b30b039163f6942e58a2 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 18:50:46 +0200 Subject: [PATCH 171/268] fix totempulse bar background not showing --- Modules/TotemPulse.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/TotemPulse.lua b/Modules/TotemPulse.lua index cd2fd2d..ff511e4 100644 --- a/Modules/TotemPulse.lua +++ b/Modules/TotemPulse.lua @@ -313,7 +313,7 @@ function TotemPulse:CreateCooldownFrame(style) totemTick.spark.position = 0 totemTick.spark:SetRotation(style == "Vertical" and ninetyDegreeInRad or 0) - totemTick.bg = totemTick.bar:CreateTexture(nil, "BACKGROUND") + totemTick.bg = totemTick:CreateTexture(nil, "ARTWORK") totemTick.bg:SetTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) totemTick.bg:SetAllPoints(totemTick.bar) totemTick.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBgColor)) @@ -461,7 +461,6 @@ function TotemPulse:UpdateBar(bar) bar.bar:SetStatusBarTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) bar.bar:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.totemPulseBarColor)) - bar.bar:SetAllPoints(bar) bar.bg:SetTexture(Gladdy:SMFetch("statusbar", "totemPulseBarTexture")) bar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.totemPulseBarBgColor)) -- 2.39.5 From 02e9b2e41a86ce4f7019d285f2efbdd84a5a3a29 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 18:51:04 +0200 Subject: [PATCH 172/268] add diminish group option --- Modules/Diminishings.lua | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Modules/Diminishings.lua b/Modules/Diminishings.lua index 32337ef..ec9fa76 100644 --- a/Modules/Diminishings.lua +++ b/Modules/Diminishings.lua @@ -1,5 +1,6 @@ local select = select local pairs,ipairs,tbl_sort,tinsert,format,rand = pairs,ipairs,table.sort,tinsert,format,math.random +local str_gsub = string.gsub local GetSpellInfo = GetSpellInfo local CreateFrame = CreateFrame @@ -55,6 +56,8 @@ local Diminishings = Gladdy:NewModule("Diminishings", nil, { drDuration = 18, drFrameStrata = "MEDIUM", drFrameLevel = 3, + drGroup = false, + drGroupDirection = "DOWN" }) local function getDiminishColor(dr) @@ -187,6 +190,22 @@ function Diminishings:UpdateFrame(unit) Gladdy:SetPosition(drFrame, unit, "drXOffset", "drYOffset", Diminishings:LegacySetPosition(drFrame, unit), Diminishings) + if (Gladdy.db.drGroup) then + if (unit ~= "arena1") then + local previousUnit = "arena" .. str_gsub(unit, "arena", "") - 1 + self.frames[unit]:ClearAllPoints() + if Gladdy.db.classIconGroupDirection == "RIGHT" then + self.frames[unit]:SetPoint("LEFT", self.frames[previousUnit], "RIGHT", 0, 0) + elseif Gladdy.db.classIconGroupDirection == "LEFT" then + self.frames[unit]:SetPoint("RIGHT", self.frames[previousUnit], "LEFT", 0, 0) + elseif Gladdy.db.classIconGroupDirection == "UP" then + self.frames[unit]:SetPoint("BOTTOM", self.frames[previousUnit], "TOP", 0, 0) + elseif Gladdy.db.classIconGroupDirection == "DOWN" then + self.frames[unit]:SetPoint("TOP", self.frames[previousUnit], "BOTTOM", 0, 0) + end + end + end + if (unit == "arena1") then Gladdy:CreateMover(drFrame,"drXOffset", "drYOffset", L["Diminishings"], Gladdy.db.drGrowDirection == "RIGHT" and {"TOPLEFT", "TOPLEFT"} or {"TOPRIGHT", "TOPRIGHT"}, @@ -439,6 +458,26 @@ function Diminishings:GetOptions() max = 20, step = .1, }), + drGroup = Gladdy:option({ + type = "toggle", + name = L["Group"] .. " " .. L["Class Icon"], + order = 5, + disabled = function() return not Gladdy.db.drEnabled end, + }), + drGroupDirection = Gladdy:option({ + type = "select", + name = L["Group direction"], + order = 6, + values = { + ["RIGHT"] = L["Right"], + ["LEFT"] = L["Left"], + ["UP"] = L["Up"], + ["DOWN"] = L["Down"], + }, + disabled = function() + return not Gladdy.db.drGroup or not Gladdy.db.drEnabled + end, + }), group = { type = "group", childGroups = "tree", -- 2.39.5 From dbaaccd3ecf5bce3255ed0bd70f11af0b66f4393 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 20:49:02 +0200 Subject: [PATCH 173/268] fix cooldowns out of stealth --- EventListener.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 8db9ddc..820f181 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -160,7 +160,7 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() Gladdy:SendMessage("RACIAL_USED", srcUnit) end end - if (eventType == "SPELL_AURA_REMOVED" and (spellID ~= 16188 or spellID ~= 17116) and Gladdy.buttons[srcUnit].class) then + if (eventType == "SPELL_AURA_REMOVED" and (spellID == 16188 or spellID == 17116) and Gladdy.buttons[srcUnit].class) then Cooldowns:CooldownUsed(srcUnit, Gladdy.buttons[srcUnit].class, spellID) end end @@ -226,11 +226,14 @@ Gladdy.cooldownBuffs = { return expTime end, spellId = 6346 }, -- Fear Ward [GetSpellInfo(11305)] = { cd = function(expTime) -- 15s uptime - return 180 - (15 - expTime) + return 300 - (15 - expTime) end, spellId = 11305 }, -- Sprint - [GetSpellInfo(36554)] = { cd = function(expTime) -- 3s uptime + [36554] = { cd = function(expTime) -- 3s uptime return 30 - (3 - expTime) - end, spellId = 36554 }, -- Shadowstep + end, spellId = 36554 }, -- Shadowstep speed buff + [36563] = { cd = function(expTime) -- 10s uptime + return 30 - (10 - expTime) + end, spellId = 36554 }, -- Shadowstep dmg buff [GetSpellInfo(26889)] = { cd = function(expTime) -- 3s uptime return 180 - (10 - expTime) end, spellId = 26889 }, -- Vanish @@ -265,10 +268,11 @@ function EventListener:UNIT_AURA(unit) self:DetectSpec(unit, Gladdy.specBuffs[spellName]) end end - if Gladdy.cooldownBuffs[spellName] and unitCaster then -- Check for auras that hint used CDs (like Fear Ward) + if (Gladdy.cooldownBuffs[spellName] or Gladdy.cooldownBuffs[spellID]) and unitCaster then -- Check for auras that hint used CDs (like Fear Ward) + local cooldownBuff = Gladdy.cooldownBuffs[spellID] or Gladdy.cooldownBuffs[spellName] for arenaUnit,v in pairs(Gladdy.buttons) do if (UnitIsUnit(arenaUnit, unitCaster)) then - Cooldowns:CooldownUsed(arenaUnit, v.class, Gladdy.cooldownBuffs[spellName].spellId, Gladdy.cooldownBuffs[spellName].cd(expirationTime - GetTime())) + Cooldowns:CooldownUsed(arenaUnit, v.class, cooldownBuff.spellId, cooldownBuff.cd(expirationTime - GetTime())) end end end -- 2.39.5 From 764c8a971b03b9b3865d6ecd4a1dfba94f813e04 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 20:51:07 +0200 Subject: [PATCH 174/268] fix poison/disease cleansing pulse timer --- Constants.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Constants.lua b/Constants.lua index 1132b0d..31589a3 100644 --- a/Constants.lua +++ b/Constants.lua @@ -1332,8 +1332,8 @@ local totemData = { [string_lower("Frost Resistance Totem")] = {id = 8181,texture = select(3, GetSpellInfo(8181)), color = {r = 0, g = 0, b = 0, a = 1}}, -- Water [string_lower("Fire Resistance Totem")] = {id = 8184,texture = select(3, GetSpellInfo(8184)), color = {r = 0, g = 0, b = 0, a = 1}}, - [string_lower("Poison Cleansing Totem")] = {id = 8166,texture = select(3, GetSpellInfo(8166)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 4}, - [string_lower("Disease Cleansing Totem")] = {id = 8170,texture = select(3, GetSpellInfo(8170)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 4}, + [string_lower("Poison Cleansing Totem")] = {id = 8166,texture = select(3, GetSpellInfo(8166)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 5}, + [string_lower("Disease Cleansing Totem")] = {id = 8170,texture = select(3, GetSpellInfo(8170)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 5}, [string_lower("Healing Stream Totem")] = {id = 5394,texture = select(3, GetSpellInfo(5394)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 2}, [string_lower("Mana Tide Totem")] = {id = 16190,texture = select(3, GetSpellInfo(16190)), color = {r = 0.078, g = 0.9, b = 0.16, a = 1}}, [string_lower("Mana Spring Totem")] = {id = 5675,texture = select(3, GetSpellInfo(5675)), color = {r = 0, g = 0, b = 0, a = 1}, pulse = 2}, -- 2.39.5 From eaf7c6a5176738bb743b615666643a648a29a6f4 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 20:51:28 +0200 Subject: [PATCH 175/268] remove Test from ClassIcon --- Modules/Classicon.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index abaa060..db4c792 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -191,10 +191,6 @@ function Classicon:UNIT_SPEC(unit, spec) classIcon.texture:SetTexture(specIcons[Gladdy.buttons[unit].class][spec]) end -function Classicon:Test(unit) - self:ENEMY_SPOTTED(unit) -end - function Classicon:ResetUnit(unit) local classIcon = self.frames[unit] if (not classIcon) then -- 2.39.5 From b8e75b68043975018d5094a09035cb930f6711a8 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 20:53:28 +0200 Subject: [PATCH 176/268] - health bar new option classcolored / customcolor / custom currentvalue gradient option added - move stealth from rangecheck to healthbar - custom stealth color added - powerbar fix eventhandling --- Modules/Healthbar.lua | 165 ++++++++++++++++++++++++++++++++++++----- Modules/Powerbar.lua | 14 ++-- Modules/RangeCheck.lua | 52 ++----------- Options.lua | 7 +- 4 files changed, 165 insertions(+), 73 deletions(-) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index f611a42..7889f66 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -1,5 +1,5 @@ local pairs, ipairs = pairs, ipairs -local floor = math.floor +local floor, abs = math.floor, math.abs local str_find, str_gsub, str_sub, tinsert = string.find, string.gsub, string.sub, table.insert local UnitHealth, UnitHealthMax, UnitName, UnitExists, UnitIsDeadOrGhost = UnitHealth, UnitHealthMax, UnitName, UnitExists, UnitIsDeadOrGhost @@ -17,6 +17,15 @@ local Healthbar = Gladdy:NewModule("Health Bar", 100, { healthBarBorderSize = 9, healthBarBorderColor = { r = 0, g = 0, b = 0, a = 1 }, healthBarBgColor = { r = 0, g = 0, b = 0, a = 0.4 }, + healthBarClassColored = true, + healthBarColoredByCurrentHp = false, + healthBarStatusBarColorMax = { r = 0, g = 1, b = 0, a = 1 }, + healthBarStatusBarColorMid = { r = 1, g = 1, b = 0, a = 1 }, + healthBarStatusBarColorMin = { r = 1, g = 0, b = 0, a = 1 }, + healthFrameStrata = "MEDIUM", + healthFrameLevel = 1, + healthBarStealthColor = { r = 0.66, g = 0.66, b = 0.66, a = 1 }, + --font healthBarFontColor = { r = 1, g = 1, b = 1, a = 1 }, healthBarNameFontSize = 12, healthBarHealthFontSize = 12, @@ -25,8 +34,6 @@ local Healthbar = Gladdy:NewModule("Health Bar", 100, { healthActual = false, healthMax = true, healthPercentage = true, - healthFrameStrata = "MEDIUM", - healthFrameLevel = 1, healthCustomTagsEnabled = false, healthTextLeft = "[name]", healthTextRight = "[percent|status]", @@ -42,6 +49,7 @@ function Healthbar:Initialize() self.frames = {} self:RegisterMessage("JOINED_ARENA") self:RegisterMessage("ENEMY_SPOTTED") + self:RegisterMessage("ENEMY_STEALTH") self:RegisterMessage("UNIT_SPEC") self:RegisterMessage("UNIT_DESTROYED") self:RegisterMessage("UNIT_DEATH") @@ -123,7 +131,7 @@ function Healthbar.OnEvent(self, event, unit) self.hp.current = health self.hp.max = healthMax Healthbar:SetText(unit, health, healthMax) - --Healthbar:SetHealthText(self, health, healthMax) + Healthbar:SetHealthStatusBarColor(unit, self.hp.current, self.hp.max) elseif event == "UNIT_NAME_UPDATE" then local name = UnitName(unit) Gladdy.buttons[unit].name = name @@ -134,6 +142,67 @@ function Healthbar.OnEvent(self, event, unit) end end +local function getGradient(start, ending, percentage, factor) + return start * abs(-2 * percentage + 1) + ending * factor +end + +-- /run LibStub("Gladdy").modules["Health Bar"]:SetHealthStatusBarColor("arena1", 51, 100) +local rMax, gMax, bMax, rMid, gMid, bMid, rMin, gMin, bMin, rNow, gNow, bNow, percentage, factor, stealthAlpha +function Healthbar:SetHealthStatusBarColor(unit, health, healthMax) + local button = Gladdy.buttons[unit] + if not button or not health or not healthMax then + return + end + + local healthBar = Gladdy.buttons[unit].healthBar + if not healthBar.hp.oorFactor then + healthBar.hp.oorFactor = 1 + end + + healthBar.hp:SetMinMaxValues(0, healthMax) + healthBar.hp:SetValue(health) + + if healthBar.hp.stealth then + stealthAlpha = Gladdy.db.healthBarStealthColor.a < Gladdy.db.healthBarBgColor.a and Gladdy.db.healthBarStealthColor.a or Gladdy.db.healthBarBgColor.a + healthBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.healthBarBgColor, nil, stealthAlpha)) + healthBar.hp:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.healthBarStealthColor)) + return + else + healthBar.bg:SetVertexColor(Gladdy:SetColor(Gladdy.db.healthBarBgColor)) + end + + if not Gladdy.db.healthBarClassColored then + if Gladdy.db.healthBarColoredByCurrentHp then + rMax, gMax, bMax = Gladdy:SetColor(Gladdy.db.healthBarStatusBarColorMax) + rMid, gMid, bMid = Gladdy:SetColor(Gladdy.db.healthBarStatusBarColorMid) + rMin, gMin, bMin = Gladdy:SetColor(Gladdy.db.healthBarStatusBarColorMin) + percentage = health / healthMax + if percentage == 0.5 then + rNow, gNow, bNow = Gladdy:SetColor(Gladdy.db.healthBarStatusBarColorMid, healthBar.hp.oorFactor) + elseif percentage < 0.5 then + factor = percentage * 2 + rNow = getGradient(rMin, rMid, percentage, factor) + gNow = getGradient(gMin, gMid, percentage, factor) + bNow = getGradient(bMin, bMid, percentage, factor) + elseif percentage > 0.5 then + factor = ((healthMax - health) / healthMax) * 2 + rNow = getGradient(rMax, rMid, percentage, factor) + gNow = getGradient(gMax, gMid, percentage, factor) + bNow = getGradient(bMax, bMid, percentage, factor) + end + healthBar.hp:SetStatusBarColor(rNow / healthBar.hp.oorFactor, gNow / healthBar.hp.oorFactor, bNow / healthBar.hp.oorFactor, 1) + else + healthBar.hp:SetStatusBarColor(Gladdy:SetColor(Gladdy.db.healthBarStatusBarColorMax, healthBar.hp.oorFactor)) + end + end + if button.class and Gladdy.db.healthBarClassColored then + healthBar.hp:SetStatusBarColor( + RAID_CLASS_COLORS[button.class].r / healthBar.hp.oorFactor, + RAID_CLASS_COLORS[button.class].g / healthBar.hp.oorFactor, + RAID_CLASS_COLORS[button.class].b / healthBar.hp.oorFactor, 1) + end +end + function Healthbar:SetHealthText(healthBar, health, healthMax) local healthText = "" local healthPercentage = health and healthMax and floor(health * 100 / healthMax) @@ -220,6 +289,8 @@ function Healthbar:UpdateFrame(unit) healthBar.healthText:SetTextColor(Gladdy:SetColor(Gladdy.db.healthBarFontColor)) healthBar.nameText:SetPoint("LEFT", Gladdy.db.healthTextLeftHOffset, Gladdy.db.healthTextLeftVOffset) healthBar.healthText:SetPoint("RIGHT", Gladdy.db.healthTextRightHOffset, Gladdy.db.healthTextRightVOffset) + + Healthbar:SetHealthStatusBarColor(unit, healthBar.hp.current, healthBar.hp.max) end function Healthbar:ResetUnit(unit) @@ -232,7 +303,8 @@ function Healthbar:ResetUnit(unit) healthBar.nameText:SetText("") healthBar.healthText:SetText("") healthBar.hp:SetValue(0) - healthBar.hp.current = 0 + healthBar.hp.current = nil + healthBar.hp.max = nil end function Healthbar:Test(unit) @@ -242,7 +314,6 @@ function Healthbar:Test(unit) return end - --self:JOINED_ARENA() Gladdy:SendMessage("UNIT_HEALTH", unit, button.health, button.healthMax) healthBar.hp.current = button.health healthBar.hp.max = button.healthMax @@ -251,7 +322,6 @@ function Healthbar:Test(unit) healthBar.hp:SetValue(button.health) if unit == "arena1" then self:UNIT_DEATH(unit) - --self:SetText(unit, button.health, button.healthMax, L["DEAD"]) end end @@ -266,7 +336,8 @@ end function Healthbar:JOINED_ARENA() for i=1,Gladdy.curBracket do - self:SetText("arena" .. i, nil, nil) + local unit = "arena" .. i + self:SetText(unit, self.frames[unit].hp.current, self.frames[unit].hp.max) end end @@ -284,13 +355,21 @@ function Healthbar:ENEMY_SPOTTED(unit) healthBar.hp:SetValue(health) healthBar.hp.current = health healthBar.hp.max = healthMax - Healthbar:SetText(unit, health, healthMax) - --Healthbar:SetHealthText(healthBar, health, healthMax) + end + Healthbar:SetText(unit, healthBar.hp.current, healthBar.hp.max) + Healthbar:SetHealthStatusBarColor(unit, healthBar.hp.current, healthBar.hp.max) +end + +function Healthbar:ENEMY_STEALTH(unit, stealth) + local healthBar = self.frames[unit] + local button = Gladdy.buttons[unit] + if (not healthBar or not button) then + return end - if button.class then - healthBar.hp:SetStatusBarColor(RAID_CLASS_COLORS[button.class].r, RAID_CLASS_COLORS[button.class].g, RAID_CLASS_COLORS[button.class].b, 1) - end + healthBar.hp.stealth = stealth + + Healthbar:SetHealthStatusBarColor(unit, healthBar.hp.current, healthBar.hp.max) end function Healthbar:UNIT_DEATH(unit) @@ -394,10 +473,62 @@ function Healthbar:GetOptions() }), }, }, + barColor = { + type = "group", + name = L["Bar Color"], + order = 2, + args = { + headerAuras = { + type = "header", + name = L["Color"], + order = 1, + }, + healthBarClassColored = Gladdy:option({ + type = "toggle", + name = L["Class colored health bar"], + order = 2, + width = "full", + }), + healthBarStealthColor = Gladdy:colorOption({ + type = "color", + name = L["Stealth Color"], + order = 3, + hasAlpha = true, + }), + healthBarColoredByCurrentHp = Gladdy:option({ + type = "toggle", + name = L["healthBarColoredByCurrentHp"], + order = 4, + width = "full", + disabled = function() return Gladdy.db.healthBarClassColored end, + }), + healthBarStatusBarColorMax = Gladdy:colorOption({ + type = "color", + name = L["100%"], + order = 5, + hasAlpha = false, + disabled = function() return Gladdy.db.healthBarClassColored end, + }), + healthBarStatusBarColorMid = Gladdy:colorOption({ + type = "color", + name = L["50%"], + order = 6, + hasAlpha = false, + disabled = function() return Gladdy.db.healthBarClassColored end, + }), + healthBarStatusBarColorMin = Gladdy:colorOption({ + type = "color", + name = L["0%"], + order = 7, + hasAlpha = false, + disabled = function() return Gladdy.db.healthBarClassColored end, + }), + }, + }, font = { type = "group", name = L["Font"], - order = 2, + order = 3, args = { header = { type = "header", @@ -502,7 +633,7 @@ function Healthbar:GetOptions() border = { type = "group", name = L["Border"], - order = 3, + order = 4, args = { header = { type = "header", @@ -538,7 +669,7 @@ function Healthbar:GetOptions() frameStrata = { type = "group", name = L["Frame Strata and Level"], - order = 4, + order = 5, args = { headerAuraLevel = { type = "header", @@ -567,7 +698,7 @@ function Healthbar:GetOptions() healthValues = { type = "group", name = L["Health Bar Text"], - order = 5, + order = 6, args = { header = { type = "header", diff --git a/Modules/Powerbar.lua b/Modules/Powerbar.lua index 786ca59..8a85a50 100644 --- a/Modules/Powerbar.lua +++ b/Modules/Powerbar.lua @@ -161,13 +161,9 @@ function Powerbar:UpdateFrame(unit) end function Powerbar.OnEvent(powerBar, event, unit) - if event == "UNIT_POWER_UPDATE" then - Powerbar:SetPower(powerBar, unit, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) - elseif event == "UNIT_MAXPOWER" then - Powerbar:SetPower(powerBar, unit, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) - elseif event == "UNIT_DISPLAYPOWER" then - Powerbar:SetPower(powerBar, unit, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) - end + powerBar.energy.powerType = select(1, UnitPowerType(unit)) + powerBar.energy.current, powerBar.energy.max = UnitPower(unit, powerBar.energy.powerType, true), UnitPowerMax(unit, powerBar.energy.powerType, true) + Powerbar:SetPower(powerBar, unit, powerBar.energy.current, powerBar.energy.max, powerBar.energy.powerType) end function Powerbar:SetText(unit, power, powerMax, status) @@ -276,7 +272,9 @@ function Powerbar:ENEMY_SPOTTED(unit) end if UnitExists(unit) then - Powerbar:SetPower(powerBar, UnitPower(unit, UnitPowerType(unit), true), UnitPowerMax(unit, UnitPowerType(unit), true), UnitPowerType(unit)) + powerBar.energy.powerType = select(1, UnitPowerType(unit)) + powerBar.energy.current, powerBar.energy.max = UnitPower(unit, powerBar.energy.powerType, true), UnitPowerMax(unit, powerBar.energy.powerType, true) + Powerbar:SetPower(powerBar, unit, powerBar.energy.current, powerBar.energy.max, powerBar.energy.powerType) end end diff --git a/Modules/RangeCheck.lua b/Modules/RangeCheck.lua index 36cdcfc..023cda9 100644 --- a/Modules/RangeCheck.lua +++ b/Modules/RangeCheck.lua @@ -17,6 +17,7 @@ local LibStub = LibStub local Gladdy = LibStub("Gladdy") local LSR = LibStub("SpellRange-1.0") local L = Gladdy.L +local HealthBar = Gladdy.modules["Health Bar"] local classSpells = { ["MAGE"] = 118, @@ -54,8 +55,6 @@ local RangeCheck = Gladdy:NewModule("Range Check", nil, { function RangeCheck:Initialize() if Gladdy.db.rangeCheckEnabled then self:RegisterMessage("JOINED_ARENA") - self:RegisterMessage("ENEMY_STEALTH") - self:RegisterMessage("ENEMY_SPOTTED") end self.playerClass = select(2, UnitClass("player")) end @@ -63,8 +62,6 @@ end function RangeCheck:UpdateFrameOnce() if Gladdy.db.rangeCheckEnabled then self:RegisterMessage("JOINED_ARENA") - self:RegisterMessage("ENEMY_STEALTH") - self:RegisterMessage("ENEMY_SPOTTED") else self:UnregisterAllMessages() end @@ -78,7 +75,6 @@ function RangeCheck:ResetUnit(unit) local button = Gladdy.buttons[unit] self:CancelTimer(button) self:SetColor(button, 1) - button.classColors = {} end function RangeCheck:Test(unit) @@ -86,11 +82,10 @@ function RangeCheck:Test(unit) if not button then return end - self:ENEMY_SPOTTED(unit) self.test = true button.lastState = 0 if Gladdy.db.rangeCheckEnabled then - if unit == "arena1" then + if unit == "arena2" or unit == "arena4" then --button.unit = "target" --self:CreateTimer(button) self:SetRangeAlpha(button, nil) @@ -113,18 +108,12 @@ function RangeCheck:SetColor(button, oorFac) return end - if not button.classColors.r then - if button.class then - button.classColors = { r = RAID_CLASS_COLORS[button.class].r, g = RAID_CLASS_COLORS[button.class].g, b = RAID_CLASS_COLORS[button.class].b } - else - button.classColors = { r = 0.66, g = 0.66, b = 0.66 } - end - end - if Gladdy.db.rangeCheckHealthBar then - button.healthBar.hp:SetStatusBarColor(button.classColors.r/oorFac, button.classColors.g/oorFac, button.classColors.b/oorFac, 1) + button.healthBar.hp.oorFactor = oorFac + HealthBar:SetHealthStatusBarColor(button.unit, button.healthBar.hp.current, button.healthBar.hp.max) else - button.healthBar.hp:SetStatusBarColor(button.classColors.r, button.classColors.g, button.classColors.b, 1) + button.healthBar.hp.oorFactor = 1 + HealthBar:SetHealthStatusBarColor(button.unit, button.healthBar.hp.current, button.healthBar.hp.max) end if Gladdy.db.rangeCheckHealthBarText then @@ -189,35 +178,6 @@ function RangeCheck:JOINED_ARENA() end end -function RangeCheck:ENEMY_STEALTH(unit, stealth) - local button = Gladdy.buttons[unit] - if not button then - return - end - button.lastState = 0 - if stealth then - button.classColors = { r = 0.66, g = 0.66, b = 0.66 } - if not Gladdy.db.rangeCheckEnabled then - button.healthBar.hp:SetStatusBarColor(0.66, 0.66, 0.66, 1) - end - else - if button.class then - button.classColors = { r = RAID_CLASS_COLORS[button.class].r, g = RAID_CLASS_COLORS[button.class].g, b = RAID_CLASS_COLORS[button.class].b } - if not Gladdy.db.rangeCheckEnabled then - button.healthBar.hp:SetStatusBarColor(RAID_CLASS_COLORS[button.class].r, RAID_CLASS_COLORS[button.class].g, RAID_CLASS_COLORS[button.class].b, 1) - end - end - end -end - -function RangeCheck:ENEMY_SPOTTED(unit) - local button = Gladdy.buttons[unit] - if (not button) then - return - end - button.classColors = { r = RAID_CLASS_COLORS[button.class].r, g = RAID_CLASS_COLORS[button.class].g, b = RAID_CLASS_COLORS[button.class].b } -end - function RangeCheck.CheckRange(self) local button = self.parent diff --git a/Options.lua b/Options.lua index 5268dc6..4a6aa57 100644 --- a/Options.lua +++ b/Options.lua @@ -105,8 +105,11 @@ function Gladdy:option(params) return defaults end -function Gladdy:SetColor(option) - return option.r, option.g, option.b, option.a +function Gladdy:SetColor(option, factor, altAlpha) + if not factor then + factor = 1 + end + return option.r / factor, option.g / factor, option.b / factor, altAlpha or option.a end function Gladdy:colorOption(params) -- 2.39.5 From c576adec2f7bf69e8f47232962eb0206b7b8aa68 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 20:53:52 +0200 Subject: [PATCH 177/268] test data updated --- Gladdy.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 5c4f93a..57cb8a1 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -289,11 +289,11 @@ function Gladdy:OnInitialize() L = self.L self.testData = { - ["arena1"] = { name = "Swift", raceLoc = L["NightElf"], classLoc = L["Hunter"], class = "HUNTER", health = 67, healthMax = 100, power = 76, powerMax = 100, powerType = 1, testSpec = L["Marksmanship"], race = "NightElf" }, + ["arena1"] = { name = "Swift", raceLoc = L["NightElf"], classLoc = L["Druid"], class = "DRUID", health = 67, healthMax = 100, power = 76, powerMax = 100, powerType = 1, testSpec = L["Restoration"], race = "NightElf" }, ["arena2"] = { name = "Vilden", raceLoc = L["Undead"], classLoc = L["Mage"], class = "MAGE", health = 99, healthMax = 100, power = 7833, powerMax = 10460, powerType = 0, testSpec = L["Frost"], race = "Scourge" }, - ["arena3"] = { name = "Krymu", raceLoc = L["Human"], classLoc = L["Rogue"], class = "ROGUE", health = 13, healthMax = 100, power = 45, powerMax = 110, powerType = 3, testSpec = L["Subtlety"], race = "Human" }, - ["arena4"] = { name = "Talmon", raceLoc = L["Human"], classLoc = L["Warlock"], class = "WARLOCK", health = 68, healthMax = 100, power = 9855, powerMax = 9855, powerType = 0, testSpec = L["Demonology"], race = "Human" }, - ["arena5"] = { name = "Hydra", raceLoc = L["Undead"], classLoc = L["Priest"], class = "PRIEST", health = 100, healthMax = 100, power = 2515, powerMax = 10240, powerType = 0, testSpec = L["Discipline"], race = "Human" }, + ["arena3"] = { name = "Krymu", raceLoc = L["Human"], classLoc = L["Rogue"], class = "ROGUE", health = 10, healthMax = 100, power = 45, powerMax = 110, powerType = 3, testSpec = L["Subtlety"], race = "Human" }, + ["arena4"] = { name = "Talmon", raceLoc = L["Human"], classLoc = L["Warlock"], class = "WARLOCK", health = 40, healthMax = 100, power = 9855, powerMax = 9855, powerType = 0, testSpec = L["Demonology"], race = "Human" }, + ["arena5"] = { name = "Hydra", raceLoc = L["Undead"], classLoc = L["Priest"], class = "PRIEST", health = 70, healthMax = 100, power = 2515, powerMax = 10240, powerType = 0, testSpec = L["Discipline"], race = "Human" }, } self.cooldownSpellIds = {} -- 2.39.5 From c408448aadb8764643e602b41cc7e1875968a235 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 20:57:53 +0200 Subject: [PATCH 178/268] health bar options update --- Modules/Healthbar.lua | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/Modules/Healthbar.lua b/Modules/Healthbar.lua index 7889f66..9e06a9e 100644 --- a/Modules/Healthbar.lua +++ b/Modules/Healthbar.lua @@ -464,13 +464,6 @@ function Healthbar:GetOptions() dialogControl = "LSM30_Statusbar", values = AceGUIWidgetLSMlists.statusbar, }), - healthBarBgColor = Gladdy:colorOption({ - type = "color", - name = L["Background color"], - desc = L["Color of the status bar background"], - order = 5, - hasAlpha = true, - }), }, }, barColor = { @@ -485,7 +478,7 @@ function Healthbar:GetOptions() }, healthBarClassColored = Gladdy:option({ type = "toggle", - name = L["Class colored health bar"], + name = L["Class colored"] .. " " .. L["Health Bar"], order = 2, width = "full", }), @@ -495,31 +488,43 @@ function Healthbar:GetOptions() order = 3, hasAlpha = true, }), + healthBarBgColor = Gladdy:colorOption({ + type = "color", + name = L["Background color"], + desc = L["Color of the status bar background"], + order = 4, + hasAlpha = true, + }), + headerAuras = { + type = "header", + name = L["Custom Colors"], + order = 10, + }, healthBarColoredByCurrentHp = Gladdy:option({ type = "toggle", - name = L["healthBarColoredByCurrentHp"], - order = 4, + name = L["Enable Custom Colors"], + order = 11, width = "full", disabled = function() return Gladdy.db.healthBarClassColored end, }), healthBarStatusBarColorMax = Gladdy:colorOption({ type = "color", name = L["100%"], - order = 5, + order = 12, hasAlpha = false, disabled = function() return Gladdy.db.healthBarClassColored end, }), healthBarStatusBarColorMid = Gladdy:colorOption({ type = "color", name = L["50%"], - order = 6, + order = 13, hasAlpha = false, disabled = function() return Gladdy.db.healthBarClassColored end, }), healthBarStatusBarColorMin = Gladdy:colorOption({ type = "color", name = L["0%"], - order = 7, + order = 14, hasAlpha = false, disabled = function() return Gladdy.db.healthBarClassColored end, }), -- 2.39.5 From 13a26d82c60b7c33339ba957fff025a8abf658d5 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Sun, 27 Mar 2022 21:04:47 +0200 Subject: [PATCH 179/268] bump version + readme changelog --- Gladdy.lua | 4 ++-- Gladdy.toc | 2 +- README.md | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Gladdy.lua b/Gladdy.lua index 57cb8a1..4478e48 100644 --- a/Gladdy.lua +++ b/Gladdy.lua @@ -27,11 +27,11 @@ local LibStub = LibStub --------------------------- -local MAJOR, MINOR = "Gladdy", 6 +local MAJOR, MINOR = "Gladdy", 7 local Gladdy = LibStub:NewLibrary(MAJOR, MINOR) local L Gladdy.version_major_num = 2 -Gladdy.version_minor_num = 0.10 +Gladdy.version_minor_num = 0.11 Gladdy.version_num = Gladdy.version_major_num + Gladdy.version_minor_num Gladdy.version_releaseType = RELEASE_TYPES.release Gladdy.version = PREFIX .. string.format("%.2f", Gladdy.version_num) .. "-" .. Gladdy.version_releaseType diff --git a/Gladdy.toc b/Gladdy.toc index 73dc6f7..a9c4720 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -1,6 +1,6 @@ ## Interface: 20504 ## Title: Gladdy - TBC -## Version: 2.10-Release +## Version: 2.11-Release ## Notes: The most powerful arena AddOn for WoW 2.5.4 ## Author: XiconQoo, DnB_Junkee, Knall ## X-Email: contact me on discord Knall#1751 diff --git a/README.md b/README.md index b2fa01b..036b6fe 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ --- -## [v2.10-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v2.10-Release/Gladdy_TBC-Classic_v2.10-Release.zip) +## [v2.11-Release Download Here](https://github.com/XiconQoo/Gladdy-TBC/releases/download/v2.11-Release/Gladdy_TBC-Classic_v2.11-Release.zip) ###### Please consider donating if you like my work @@ -79,6 +79,19 @@ Thank you! ### Changes +### v2.11-Release +- **Cooldowns** + - fixed cooldowns not showing properly for detected spec + - Nature's Swiftness (Druid/Shaman) now properly tracked + - improved cd out of stealth detection +- **HealthBar** + - added options class colored or custom colors + - custom colors for 100%, 50% 0% hp values added + - custom stealth color added +- add group option for DRs +- intercept cd adjusted (-5s for 4pc set bonus) +- totempulse minor adjustments + ### v2.10-Release - **Totems**: -- 2.39.5 From a87455e7bd93527c51593214de0b6f5c02f2b9ef Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 29 Jul 2022 07:41:55 +0200 Subject: [PATCH 180/268] Wrath: - separate TOC + Constants for BCC and Wrath - cooldowns, auras, spec detection, trinket/racial tracking --- Constants.lua => Constants_BCC.lua | 223 +---- Constants_Wrath.lua | 1334 +++++++++++++++++++++++++ Constants_shared.lua | 274 +++++ Gladdy.toc => Gladdy_BCC.toc | 5 +- Gladdy_Wrath.toc | 44 + Lang.lua | 1 + Libs/LibClassAuras-1.0/ClassBuffs.lua | 11 +- Modules/Auras.lua | 5 +- Modules/Classicon.lua | 6 + Modules/Racial.lua | 29 +- Modules/Trinket.lua | 68 +- Options.lua | 11 + 12 files changed, 1783 insertions(+), 228 deletions(-) rename Constants.lua => Constants_BCC.lua (87%) create mode 100644 Constants_Wrath.lua create mode 100644 Constants_shared.lua rename Gladdy.toc => Gladdy_BCC.toc (94%) create mode 100644 Gladdy_Wrath.toc diff --git a/Constants.lua b/Constants_BCC.lua similarity index 87% rename from Constants.lua rename to Constants_BCC.lua index 31589a3..e427565 100644 --- a/Constants.lua +++ b/Constants_BCC.lua @@ -2,44 +2,14 @@ local tbl_sort, select, string_lower = table.sort, select, string.lower local GetSpellInfo = GetSpellInfo local GetItemInfo = GetItemInfo -local GetLocale = GetLocale local Gladdy = LibStub("Gladdy") local L = Gladdy.L local AURA_TYPE_DEBUFF, AURA_TYPE_BUFF = AURA_TYPE_DEBUFF, AURA_TYPE_BUFF +Gladdy.expansion = "BCC" Gladdy.CLASSES = {"MAGE", "PRIEST", "DRUID", "SHAMAN", "PALADIN", "WARLOCK", "WARRIOR", "HUNTER", "ROGUE"} tbl_sort(Gladdy.CLASSES) -Gladdy.RACES = {"Scourge", "BloodElf", "Tauren", "Orc", "Troll", "NightElf", "Draenei", "Human", "Gnome", "Dwarf"} -tbl_sort(Gladdy.RACES) - -local RACE_ICON_TCOORDS = { - ["HUMAN_MALE"] = {0, 0.125, 0, 0.25}, - ["DWARF_MALE"] = {0.125, 0.25, 0, 0.25}, - ["GNOME_MALE"] = {0.25, 0.375, 0, 0.25}, - ["NIGHTELF_MALE"] = {0.375, 0.5, 0, 0.25}, - - ["TAUREN_MALE"] = {0, 0.125, 0.25, 0.5}, - ["SCOURGE_MALE"] = {0.125, 0.25, 0.25, 0.5}, - ["TROLL_MALE"] = {0.25, 0.375, 0.25, 0.5}, - ["ORC_MALE"] = {0.375, 0.5, 0.25, 0.5}, - - ["HUMAN_FEMALE"] = {0, 0.125, 0.5, 0.75}, - ["DWARF_FEMALE"] = {0.125, 0.25, 0.5, 0.75}, - ["GNOME_FEMALE"] = {0.25, 0.375, 0.5, 0.75}, - ["NIGHTELF_FEMALE"] = {0.375, 0.5, 0.5, 0.75}, - - ["TAUREN_FEMALE"] = {0, 0.125, 0.75, 1.0}, - ["SCOURGE_FEMALE"] = {0.125, 0.25, 0.75, 1.0}, - ["TROLL_FEMALE"] = {0.25, 0.375, 0.75, 1.0}, - ["ORC_FEMALE"] = {0.375, 0.5, 0.75, 1.0}, - - ["BLOODELF_MALE"] = {0.5, 0.625, 0.25, 0.5}, - ["BLOODELF_FEMALE"] = {0.5, 0.625, 0.75, 1.0}, - - ["DRAENEI_MALE"] = {0.5, 0.625, 0, 0.25}, - ["DRAENEI_FEMALE"] = {0.5, 0.625, 0.5, 0.75}, -} local specBuffs = { -- DRUID @@ -51,7 +21,7 @@ local specBuffs = { [GetSpellInfo(33891)] = L["Restoration"], -- Tree of Life -- HUNTER - [GetSpellInfo(34692)] = L["Beast Mastery"], -- The Beast Within + [GetSpellInfo(34471)] = L["Beast Mastery"], -- The Beast Within [GetSpellInfo(20895)] = L["Beast Mastery"], -- Spirit Bond [GetSpellInfo(34455)] = L["Beast Mastery"], -- Ferocious Inspiration [GetSpellInfo(27066)] = L["Marksmanship"], -- Trueshot Aura @@ -108,8 +78,8 @@ local specBuffs = { [GetSpellInfo(19028)] = L["Demonology"], -- Soul Link [GetSpellInfo(23759)] = L["Demonology"], -- Master Demonologist [GetSpellInfo(35696)] = L["Demonology"], -- Demonic Knowledge - [GetSpellInfo(30302)] = L["Destruction"], -- Nether Protection - [GetSpellInfo(34935)] = L["Destruction"], -- Backlash + [GetSpellInfo(30300)] = L["Destruction"], -- Nether Protection + [GetSpellInfo(34936)] = L["Destruction"], -- Backlash -- WARRIOR [GetSpellInfo(29838)] = L["Arms"], -- Second Wind @@ -338,11 +308,11 @@ local importantAuras = { spellID = 19577, }, -- The Beast Within - [GetSpellInfo(34692)] = { + [GetSpellInfo(34471)] = { track = AURA_TYPE_BUFF, duration = 18, priority = 20, - spellID = 34692, + spellID = 34471, }, @@ -846,35 +816,6 @@ function Gladdy:GetInterrupts() return interrupts end -local auraTypeColor = {} -auraTypeColor["none"] = { r = 0.80, g = 0, b = 0 , a = 1} -auraTypeColor["magic"] = { r = 0.20, g = 0.60, b = 1.00, a = 1} -auraTypeColor["curse"] = { r = 0.60, g = 0.00, b = 1.00, a = 1 } -auraTypeColor["disease"] = { r = 0.60, g = 0.40, b = 0, a = 1 } -auraTypeColor["poison"] = { r = 0.00, g = 0.60, b = 0, a = 1 } -auraTypeColor["immune"] = { r = 1.00, g = 0.02, b = 0.99, a = 1 } -auraTypeColor["form"] = auraTypeColor["none"] -auraTypeColor["aura"] = auraTypeColor["none"] -auraTypeColor[""] = auraTypeColor["none"] - -function Gladdy:GetAuraTypeColor() - return auraTypeColor -end - -local spellSchoolColors = {} -spellSchoolColors[1] = {r = 1, g = 1, b = 0, a = 1, type = "Physical"} --- "physical" 255, 255, 0 -spellSchoolColors[2] = {r = 1, g = 0.901, b = 0.501, a = 1, type = "Holy"} ---"holy" -- 255, 230, 128 -spellSchoolColors[4] = {r = 1, g = 0.501, b = 0, a = 1, type = "Fire"} ---"fire" -- 255, 128, 0 -spellSchoolColors[8] = {r = 0.302, g = 1, b = 0.302, a = 1, type = "Nature"} ---"nature" -- 77, 255, 77 -spellSchoolColors[16] = {r = 0.501, g = 1, b = 1, a = 1, type = "Frost"} ---"frost" -- 128, 255, 255 -spellSchoolColors[32] = {r = 0.501, g = 0.501, b = 1, a = 1, type = "Shadow"} ---"shadow" --128, 128, 255 -spellSchoolColors[64] = {r = 1, g = 0.501, b = 1, a = 1, type = "Arcane"} ---"arcane" -- 255, 128, 255 -spellSchoolColors["unknown"] = {r = 0, g = 0, b = 0, a = 1, type = "Unknown"} ---"unknown spell school" - -function Gladdy:GetSpellSchoolColors() - return spellSchoolColors -end - local cooldownList = { -- Spell Name Cooldown[, Spec] -- Mage @@ -1034,7 +975,7 @@ local cooldownList = { [34490] = { cd = 20, spec = L["Marksmanship"], }, -- Silencing Shot [19386] = { cd = 60, spec = L["Survival"], }, -- Wyvern Sting [19577] = { cd = 60, spec = L["Beast Mastery"], }, -- Intimidation - [38373] = { cd = 120, spec = L["Beast Mastery"], }, -- The Beast Within + [34471] = { cd = 120, spec = L["Beast Mastery"], }, -- The Beast Within [5384] = 30, -- Feign Death [3034] = 15, -- Viper Sting [1543] = 20, -- Flare @@ -1168,154 +1109,6 @@ function Gladdy:Racials() return racials end -local arenaTimer = { - ["default"] = { - [61] = "One minute until the Arena battle begins!", - [31] = "Thirty seconds until the Arena battle begins!", - [16] = "Fifteen seconds until the Arena battle begins!", - [0] = "The Arena battle has begun!", - }, - ["esES"] = { - [61] = "¡Un minuto hasta que dé comienzo la batalla en arena!", - [31] = "¡Treinta segundos hasta que comience la batalla en arena!", - [16] = "¡Quince segundos hasta que comience la batalla en arena!", - [0] = "¡La batalla en arena ha comenzado!", - }, - ["ptBR"] = { - [61] = "Um minuto até a batalha na Arena começar!", - [31] = "Trinta segundos até a batalha na Arena começar!", - [16] = "Quinze segundos até a batalha na Arena começar!", - [0] = "A batalha na Arena começou!", - }, - ["deDE"] = { - [61] = "Noch eine Minute bis der Arenakampf beginnt!", - [31] = "Noch dreißig Sekunden bis der Arenakampf beginnt!", - [16] = "Noch fünfzehn Sekunden bis der Arenakampf beginnt!", - [0] = "Der Arenakampf hat begonnen!", - }, - ["frFR"] = { - [61] = "Le combat d'arène commence dans une minute\194\160!", - [31] = "Le combat d'arène commence dans trente secondes\194\160!", - [16] = "Le combat d'arène commence dans quinze secondes\194\160!", - [0] = "Le combat d'arène commence\194\160!", - }, - ["ruRU"] = { - [61] = "Одна минута до начала боя на арене!", - [31] = "Тридцать секунд до начала боя на арене!", - [16] = "До начала боя на арене осталось 15 секунд.", - [0] = "Бой начался!", - }, - ["itIT"] = { -- TODO - -- Beta has no itIT version available? - }, - ["koKR"] = { - [61] = "투기장 전투 시작 1분 전입니다!", - [31] = "투기장 전투 시작 30초 전입니다!", - [16] = "투기장 전투 시작 15초 전입니다!", - [0] = "투기장 전투가 시작되었습니다!", - }, - ["zhCN"] = { - [61] = "竞技场战斗将在一分钟后开始!", - [31] = "竞技场战斗将在三十秒后开始!", - [16] = "竞技场战斗将在十五秒后开始!", - [0] = "竞技场的战斗开始了!", - }, - ["zhTW"] = { - [61] = "1分鐘後競技場戰鬥開始!", - [31] = "30秒後競技場戰鬥開始!", - [16] = "15秒後競技場戰鬥開始!", - [0] = "競技場戰鬥開始了!", - }, -} -arenaTimer["esMX"] = arenaTimer["esES"] -arenaTimer["ptPT"] = arenaTimer["ptBR"] - -function Gladdy:GetArenaTimer() - if arenaTimer[GetLocale()] then - return arenaTimer[GetLocale()] - else - return arenaTimer["default"] - end -end - -Gladdy.legacy = { - castBarPos = "LEFT", - buffsCooldownPos = "TOP", - buffsBuffsCooldownPos = "BOTTOM", - classIconPos = "LEFT", - ciAnchor = "healthBar", - ciPos = "TOP", - cooldownYPos = "TOP", - cooldownXPos = "LEFT", - drCooldownPos = "RIGHT", - racialAnchor = "trinket", - racialPos = "RIGHT", - trinketPos = "RIGHT", - padding = 1, - growUp = false, -} - -Gladdy.newDefaults = { - ["bottomMargin"] = 94.99996948242188, - ["newLayout"] = true, - Pets = { - ["petYOffset"] = -81.99993896484375, - ["petXOffset"] = 181, - }, - ClassIcon = { - ["classIconXOffset"] = -74.90008544921875, - }, - Racial = { - ["racialXOffset"] = 255.9000244140625, - }, - Trinket = { - ["trinketXOffset"] = 182, - }, - ["Combat Indicator"] = { - ["ciXOffset"] = 79.99993896484375, - ["ciYOffset"] = -10.99993896484375, - }, - Cooldowns = { - ["cooldownYOffset"] = 31, - }, - ["Buffs and Debuffs"] = { - ["buffsBuffsXOffset"] = 29, - ["buffsBuffsYOffset"] = -82.99993896484375, - ["buffsXOffset"] = 29, - ["buffsYOffset"] = 62.00006103515625, - }, - Diminishings = { - ["drXOffset"] = 329.7999877929688, - ["drYOffset"] = -22.5, - }, - ["Cast Bar"] = { - ["castBarXOffset"] = -235.900146484375, - ["castBarYOffset"] = -30.5, - }, -} - -Gladdy.frameStrata = { - BACKGROUND = L["Background"] .. "(0)", - LOW = L["Low"] .. "(1)", - MEDIUM = L["Medium"] .. "(2)", - HIGH = L["High"] .. "(3)", - DIALOG = L["Dialog"] .. "(4)", - FULLSCREEN = L["Fullscreen"] .. "(5)", - FULLSCREEN_DIALOG = L["Fullscreen Dialog"] .. "(6)", - TOOLTIP = L["Tooltip"] .. "(7)", -} - -Gladdy.frameStrataSorting = { - [1] = "BACKGROUND", - [2] = "LOW", - [3] = "MEDIUM", - [4] = "HIGH", - [5] = "DIALOG", - [6] = "FULLSCREEN", - [7] = "FULLSCREEN_DIALOG", - [8] = "TOOLTIP", -} - --------------------- -- TOTEM STUFF @@ -1427,6 +1220,7 @@ local totemNpcIdsToTotemData = { [84519] = totemData[string_lower("Searing Totem")], [110730] = totemData[string_lower("Searing Totem")], [132178] = totemData[string_lower("Searing Totem")], + [9637] = totemData[string_lower("Searing Totem")], [5950] = totemData[string_lower("Flametongue Totem")], [6012] = totemData[string_lower("Flametongue Totem")], @@ -1652,4 +1446,3 @@ local totemNpcIdsToTotemData = { function Gladdy:GetTotemData() return totemData, totemNpcIdsToTotemData, totemSpellIdToPulse end - diff --git a/Constants_Wrath.lua b/Constants_Wrath.lua new file mode 100644 index 0000000..818d432 --- /dev/null +++ b/Constants_Wrath.lua @@ -0,0 +1,1334 @@ +local tbl_sort, select, string_lower = table.sort, select, string.lower + +local GetSpellInfo = GetSpellInfo +local GetItemInfo = GetItemInfo + +local Gladdy = LibStub("Gladdy") +local L = Gladdy.L +local AURA_TYPE_DEBUFF, AURA_TYPE_BUFF = AURA_TYPE_DEBUFF, AURA_TYPE_BUFF + +Gladdy.expansion = "Wrath" +Gladdy.CLASSES = { "MAGE", "PRIEST", "DRUID", "SHAMAN", "PALADIN", "WARLOCK", "WARRIOR", "HUNTER", "ROGUE", "DEATHKNIGHT" } +tbl_sort(Gladdy.CLASSES) + +local specBuffs = { + -- WARRIOR + [GetSpellInfo(56638)] = L["Arms"], -- Taste for Blood + [GetSpellInfo(64976)] = L["Arms"], -- Juggernaut + [GetSpellInfo(57522)] = L["Arms"], -- Enrage + [GetSpellInfo(52437)] = L["Arms"], -- Sudden Death + [GetSpellInfo(46857)] = L["Arms"], -- Trauma + [GetSpellInfo(56112)] = L["Fury"], -- Furious Attacks + [GetSpellInfo(29801)] = L["Fury"], -- Rampage + [GetSpellInfo(46916)] = L["Fury"], -- Slam! + [GetSpellInfo(50227)] = L["Protection"], -- Sword and Board + [GetSpellInfo(50720)] = L["Protection"], -- Vigilance + [GetSpellInfo(74347)] = L["Protection"], -- Silenced - Gag Order + -- PALADIN + [GetSpellInfo(20375)] = L["Retribution"], -- Seal of Command + [GetSpellInfo(59578)] = L["Retribution"], -- The Art of War + [GetSpellInfo(31836)] = L["Holy"], -- Light's Grace + [GetSpellInfo(53563)] = L["Holy"], -- Beacon of Light + [GetSpellInfo(54149)] = L["Holy"], -- Infusion of Light + [GetSpellInfo(63529)] = L["Protection"], -- Silenced - Shield of the Templar + -- ROGUE + [GetSpellInfo(36554)] = L["Subtlety"], -- Shadowstep + [GetSpellInfo(44373)] = L["Subtlety"], -- Shadowstep Speed + [GetSpellInfo(36563)] = L["Subtlety"], -- Shadowstep DMG + [GetSpellInfo(51713)] = L["Subtlety"], -- Shadow Dance + [GetSpellInfo(31223)] = L["Subtlety"], -- Master of Subtlety + [GetSpellInfo(14278)] = L["Subtlety"], -- Ghostly Strike + [GetSpellInfo(51690)] = L["Combat"], -- Killing Spree + [GetSpellInfo(13877)] = L["Combat"], -- Blade Flurry + [GetSpellInfo(13750)] = L["Combat"], -- Adrenaline Rush + [GetSpellInfo(14177)] = L["Assassination"], -- Cold Blood + -- PRIEST + [GetSpellInfo(47788)] = L["Holy"], -- Guardian Spirit + [GetSpellInfo(52800)] = L["Discipline"], -- Borrowed Time + [GetSpellInfo(63944)] = L["Discipline"], -- Renewed Hope + [GetSpellInfo(15473)] = L["Shadow"], -- Shadowform + [GetSpellInfo(15286)] = L["Shadow"], -- Vampiric Embrace + -- DEATHKNIGHT + [GetSpellInfo(49222)] = L["Unholy"], -- Bone Shield + [GetSpellInfo(49016)] = L["Blood"], -- Hysteria + [GetSpellInfo(53138)] = L["Blood"], -- Abomination's Might + [GetSpellInfo(55610)] = L["Frost"], -- Imp. Icy Talons + -- MAGE + [GetSpellInfo(43039)] = L["Frost"], -- Ice Barrier + [GetSpellInfo(74396)] = L["Frost"], -- Fingers of Frost + [GetSpellInfo(57761)] = L["Frost"], -- Fireball! + [GetSpellInfo(11129)] = L["Fire"], -- Combustion + [GetSpellInfo(64346)] = L["Fire"], -- Fiery Payback + [GetSpellInfo(48108)] = L["Fire"], -- Hot Streak + [GetSpellInfo(54741)] = L["Fire"], -- Firestarter + [GetSpellInfo(55360)] = L["Fire"], -- Living Bomb + [GetSpellInfo(31583)] = L["Arcane"], -- Arcane Empowerment + [GetSpellInfo(44413)] = L["Arcane"], -- Incanter's Absorption + -- WARLOCK + [GetSpellInfo(30302)] = L["Destruction"], -- Nether Protection + [GetSpellInfo(63244)] = L["Destruction"], -- Pyroclasm + [GetSpellInfo(54277)] = L["Destruction"], -- Backdraft + [GetSpellInfo(47283)] = L["Destruction"], -- Empowered Imp + [GetSpellInfo(34936)] = L["Destruction"], -- Backlash + [GetSpellInfo(47193)] = L["Demonology"], -- Demonic Empowerment + [GetSpellInfo(64371)] = L["Affliction"], -- Eradication + -- SHAMAN + [GetSpellInfo(57663)] = L["Elemental"], -- Totem of Wrath + [GetSpellInfo(65264)] = L["Elemental"], -- Lava Flows + [GetSpellInfo(51470)] = L["Elemental"], -- Elemental Oath + [GetSpellInfo(52179)] = L["Elemental"], -- Astral Shift + [GetSpellInfo(49284)] = L["Restoration"], -- Earth Shield + [GetSpellInfo(53390)] = L["Restoration"], -- Tidal Waves + [GetSpellInfo(30809)] = L["Enhancement"], -- Unleashed Rage + [GetSpellInfo(53817)] = L["Enhancement"], -- Maelstrom Weapon + [GetSpellInfo(63685)] = L["Enhancement"], -- Freeze (Frozen Power) + -- HUNTER + [GetSpellInfo(20895)] = L["Beast Mastery"], -- Spirit Bond + [GetSpellInfo(19506)] = L["Marksmanship"], -- Trueshot Aura + -- DRUID + [GetSpellInfo(24932)] = L["Feral"], -- Leader of the Pack + [GetSpellInfo(34123)] = L["Restoration"], -- Tree of Life + [GetSpellInfo(24907)] = L["Balance"], -- Moonkin Aura + [GetSpellInfo(53251)] = L["Restoration"], -- Wild Growth +} +function Gladdy:GetSpecBuffs() + return specBuffs +end + +local specSpells = { + -- WARRIOR + [GetSpellInfo(47486)] = L["Arms"], -- Mortal Strike + [GetSpellInfo(46924)] = L["Arms"], -- Bladestorm + [GetSpellInfo(23881)] = L["Fury"], -- Bloodthirst + [GetSpellInfo(12809)] = L["Protection"], -- Concussion Blow + [GetSpellInfo(47498)] = L["Protection"], -- Devastate + [GetSpellInfo(46968)] = L["Protection"], -- Shockwave + [GetSpellInfo(50720)] = L["Protection"], -- Vigilance + -- PALADIN + [GetSpellInfo(48827)] = L["Protection"], -- Avenger's Shield + [GetSpellInfo(48825)] = L["Holy"], -- Holy Shock + [GetSpellInfo(53563)] = L["Holy"], -- Beacon of Light + [GetSpellInfo(35395)] = L["Retribution"], -- Crusader Strike + [GetSpellInfo(66006)] = L["Retribution"], -- Divine Storm + [GetSpellInfo(20066)] = L["Retribution"], -- Repentance + -- ROGUE + [GetSpellInfo(48666)] = L["Assassination"], -- Mutilate + [GetSpellInfo(14177)] = L["Assassination"], -- Cold Blood + [GetSpellInfo(51690)] = L["Combat"], -- Killing Spree + [GetSpellInfo(13877)] = L["Combat"], -- Blade Flurry + [GetSpellInfo(13750)] = L["Combat"], -- Adrenaline Rush + [GetSpellInfo(36554)] = L["Subtlety"], -- Shadowstep + [GetSpellInfo(48660)] = L["Subtlety"], -- Hemorrhage + [GetSpellInfo(51713)] = L["Subtlety"], -- Shadow Dance + -- PRIEST + [GetSpellInfo(53007)] = L["Discipline"], -- Penance + [GetSpellInfo(10060)] = L["Discipline"], -- Power Infusion + [GetSpellInfo(33206)] = L["Discipline"], -- Pain Suppression + [GetSpellInfo(34861)] = L["Holy"], -- Circle of Healing + [GetSpellInfo(15487)] = L["Shadow"], -- Silence + [GetSpellInfo(48160)] = L["Shadow"], -- Vampiric Touch + -- DEATHKNIGHT + [GetSpellInfo(55262)] = L["Blood"], -- Heart Strike + [GetSpellInfo(49203)] = L["Frost"], -- Hungering Cold + [GetSpellInfo(55268)] = L["Frost"], -- Frost Strike + [GetSpellInfo(51411)] = L["Frost"], -- Howling Blast + [GetSpellInfo(55271)] = L["Unholy"], -- Scourge Strike + -- MAGE + [GetSpellInfo(44781)] = L["Arcane"], -- Arcane Barrage + [GetSpellInfo(55360)] = L["Fire"], -- Living Bomb + [GetSpellInfo(42950)] = L["Fire"], -- Dragon's Breath + [GetSpellInfo(42945)] = L["Fire"], -- Blast Wave + [GetSpellInfo(44572)] = L["Frost"], -- Deep Freeze + -- WARLOCK + [GetSpellInfo(59164)] = L["Affliction"], -- Haunt + [GetSpellInfo(47843)] = L["Affliction"], -- Unstable Affliction + [GetSpellInfo(59672)] = L["Demonology"], -- Metamorphosis + [GetSpellInfo(47193)] = L["Demonology"], -- Demonic Empowerment + [GetSpellInfo(59172)] = L["Destruction"], -- Chaos Bolt + [GetSpellInfo(47847)] = L["Destruction"], -- Shadowfury + -- SHAMAN + [GetSpellInfo(59159)] = L["Elemental"], -- Thunderstorm + [GetSpellInfo(16166)] = L["Elemental"], -- Elemental Mastery + [GetSpellInfo(51533)] = L["Enhancement"], -- Feral Spirit + [GetSpellInfo(30823)] = L["Enhancement"], -- Shamanistic Rage + [GetSpellInfo(17364)] = L["Enhancement"], -- Stormstrike + [GetSpellInfo(61301)] = L["Restoration"], -- Riptide + [GetSpellInfo(51886)] = L["Restoration"], -- Cleanse Spirit + -- HUNTER + [GetSpellInfo(19577)] = L["Beast Mastery"], -- Intimidation + [GetSpellInfo(34490)] = L["Marksmanship"], -- Silencing Shot + [GetSpellInfo(53209)] = L["Marksmanship"], -- Chimera Shot + [GetSpellInfo(60053)] = L["Survival"], -- Explosive Shot + [GetSpellInfo(49012)] = L["Survival"], -- Wyvern Sting + -- DRUID + [GetSpellInfo(53201)] = L["Balance"], -- Starfall + [GetSpellInfo(61384)] = L["Balance"], -- Typhoon + [GetSpellInfo(48566)] = L["Feral"], -- Mangle (Cat) + [GetSpellInfo(48564)] = L["Feral"], -- Mangle (Bear) + [GetSpellInfo(18562)] = L["Restoration"], -- Swiftmend +} +function Gladdy:GetSpecSpells() + return specSpells +end + +local importantAuras = { + --- Crowd control + [GetSpellInfo(33786)] = { -- Cyclone + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 33786, + }, + [GetSpellInfo(18658)] = { -- Hibernate + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 18658, + }, + [GetSpellInfo(14309)] = { -- Freezing Trap Effect + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 14309, + }, + [GetSpellInfo(60210)] = { -- Freezing arrow effect + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 60210, + }, + [GetSpellInfo(6770)] = { -- Sap + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 6770, + }, + [GetSpellInfo(2094)] = { -- Blind + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 2094, + }, + [GetSpellInfo(5782)] = { -- Fear + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 5782, + }, + [GetSpellInfo(47860)] = { -- Death Coil Warlock + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 47860, + }, + [GetSpellInfo(6358)] = { -- Seduction + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 6358, + }, + [GetSpellInfo(5484)] = { -- Howl of Terror + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 5484, + }, + [GetSpellInfo(5246)] = { -- Intimidating Shout + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 5246, + }, + [GetSpellInfo(8122)] = { -- Psychic Scream + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 8122, + }, + [GetSpellInfo(12826)] = { -- Polymorph + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 12826, + texture = select(3, GetSpellInfo(12826)), + }, + [GetSpellInfo(51514)] = { -- Hex + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 51514, + }, + [GetSpellInfo(18647)] = { -- Banish + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 18647, + }, + [GetSpellInfo(605)] = { -- Mind Control + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 605, + }, + [GetSpellInfo(14327)] = { -- Scare Beast + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 14327, + }, + + --- Roots + -- Entangling Roots + [GetSpellInfo(26989)] = { + track = AURA_TYPE_DEBUFF, + priority = 30, + spellID = 26989, + }, + [select(1, GetSpellInfo(27010)) .. " " .. select(1, GetSpellInfo(16689))] = { + track = AURA_TYPE_DEBUFF, + priority = 30, + spellID = 27010, + altName = select(1, GetSpellInfo(27010)) .. " " .. select(1, GetSpellInfo(16689)), + }, + [GetSpellInfo(42917)] = { -- Frost Nova + track = AURA_TYPE_DEBUFF, + priority = 30, + spellID = 42917, + }, + [GetSpellInfo(33395)] = { -- Freeze (Water Elemental) + track = AURA_TYPE_DEBUFF, + priority = 30, + spellID = 33395, + }, + [GetSpellInfo(16979)] = { -- Feral Charge + track = AURA_TYPE_DEBUFF, + priority = 30, + spellID = 16979, + }, + [GetSpellInfo(23694)] = { -- Improved Hamstring + track = AURA_TYPE_DEBUFF, + priority = 30, + spellID = 23694, + }, + [GetSpellInfo(4167)] = { -- Web (Hunter Pet) + track = AURA_TYPE_DEBUFF, + priority = 30, + spellID = 4167, + }, + + --- Stuns and incapacitates + [GetSpellInfo(8983)] = { -- Bash + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 8983, + }, + [GetSpellInfo(1833)] = { -- Cheap Shot + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 1833, + }, + [GetSpellInfo(8643)] = { -- Kidney Shot + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 8643, + }, + [GetSpellInfo(1776)] = { -- Gouge + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 1776, + }, + [GetSpellInfo(44572)] = { -- Deep Freeze + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 44572, + }, + [GetSpellInfo(49012)] = { -- Wyvern Sting + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 49012, + }, + [GetSpellInfo(19503)] = { -- Scatter Shot + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 19503, + }, + [GetSpellInfo(49803)] = { -- Pounce + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 49803, + }, + [GetSpellInfo(49802)] = { -- Maim + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 49802, + }, + [GetSpellInfo(10308)] = { -- Hammer of Justice + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 10308, + }, + [GetSpellInfo(20066)] = { -- Repentance + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 20066, + }, + [GetSpellInfo(46968)] = { -- Shockwave + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 46968, + }, + [GetSpellInfo(49203)] = { -- Hungering Cold + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 49203, + }, + [GetSpellInfo(47481)] = { -- Gnaw (dk pet stun) + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 47481, + }, + [GetSpellInfo(47847)] = { -- Shadowfury Stun + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 47847, + }, + [GetSpellInfo(16922)] = { -- Imp Starfire Stun + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 16922, + }, + [GetSpellInfo(5530)] = { -- Mace Stun Effect + track = AURA_TYPE_DEBUFF, + priority = 40, + texture = select(3, GetSpellInfo(12284)), + spellID = 5530, + }, + [GetSpellInfo(20549)] = { -- War Stomp + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 20549, + }, + [GetSpellInfo(7922)] = { -- Charge Stun + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 7922, + texture = select(3, GetSpellInfo(100)) + }, + [GetSpellInfo(25274)] = { -- Intercept Stun + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 25274, + texture = select(3, GetSpellInfo(25272)) + }, + [GetSpellInfo(12809)] = { -- Concussion Blow + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 12809, + }, + [GetSpellInfo(12355)] = { -- Impact + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 12355, + }, + [GetSpellInfo(19577)] = {-- Intimidation + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 19577, + }, + [GetSpellInfo(31661)] = { -- Dragon's Breath + track = AURA_TYPE_DEBUFF, + priority = 40, + spellID = 31661, + }, + + --- Silences + [GetSpellInfo(18469)] = { -- Improved Counterspell + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 18469, + }, + [GetSpellInfo(15487)] = { -- Silence + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 15487, + }, + [GetSpellInfo(34490)] = { -- Silencing Shot + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 34490, + }, + [GetSpellInfo(18425)] = { -- Improved Kick + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 18425, + }, + [GetSpellInfo(49916)] = { -- Strangulate + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 49916, + }, + [GetSpellInfo(74347)] = { -- Silenced - Gag Order + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 74347, + }, + [GetSpellInfo(63529)] = { -- Silenced - Shield of the Templar + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 63529, + }, + ["Unstable Affliction Silence"] = { -- Unstable Affliction Silence (GetSpellInfo returns "Unstable Affliction") + track = AURA_TYPE_DEBUFF, + altName = select(1, GetSpellInfo(31117)) .. " Silence", + priority = 20, + spellID = 31117, + }, + [GetSpellInfo(24259)] = { -- Spell Lock (Felhunter) + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 24259, + }, + [GetSpellInfo(28730)] = { -- Arcane Torrent + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 28730, + }, + [GetSpellInfo(1330)] = { -- Garrote - Silence + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 1330, + }, + + --- Disarms + [GetSpellInfo(676)] = { -- Disarm + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 676, + }, + [GetSpellInfo(51722)] = { -- Dismantle + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 51722, + }, + [GetSpellInfo(53359)] = { -- Chimera Shot - Scorpid + track = AURA_TYPE_DEBUFF, + priority = 20, + spellID = 53359, + }, + + --- Buffs + [GetSpellInfo(1022)] = { -- Hand of Protection + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 1022, + }, + [GetSpellInfo(1044)] = { -- Hand of Freedom + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 1044, + }, + [GetSpellInfo(6940)] = { -- Hand of Sacrifice + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 6940, + }, + [GetSpellInfo(64205)] = { -- Divine Sacrifice + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 64205, + }, + [GetSpellInfo(53271)] = { -- Master's Call (Hunter Pet Hand of Freedom) + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 53271, + }, + [GetSpellInfo(2825)] = { -- Bloodlust + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 2825, + }, + [GetSpellInfo(32182)] = { -- Heroism + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 32182, + }, + [GetSpellInfo(33206)] = { -- Pain Suppression + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 33206, + }, + [GetSpellInfo(29166)] = { -- Innervate + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 29166, + }, + [GetSpellInfo(18708)] = { -- Fel Domination + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 18708, + }, + [GetSpellInfo(54428)] = { -- Divine Plea + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 54428, + }, + [GetSpellInfo(31821)] = { -- Aura mastery + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 31821, + }, + [GetSpellInfo(51713)] = { -- Shadow Dance + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 51713, + }, + [GetSpellInfo(7744)] = { -- Will of the Forsaken + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 7744, + }, + [GetSpellInfo(12292)] = { -- Death Wish + track = AURA_TYPE_BUFF, + priority = 15, + spellID = 12292, + }, + [GetSpellInfo(23920)] = { -- Spell Reflection + track = AURA_TYPE_BUFF, + priority = 50, + spellID = 23920, + }, + [GetSpellInfo(6346)] = {-- Fear Ward + track = AURA_TYPE_BUFF, + priority = 9, + spellID = 6346, + }, + + --- Turtling abilities + [GetSpellInfo(871)] = { -- Shield Wall + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 871, + }, + [GetSpellInfo(48707)] = { -- Anti-Magic Shell + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 48707, + }, + [GetSpellInfo(31224)] = { -- Cloak of Shadows + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 31224, + }, + [GetSpellInfo(19263)] = { -- Deterrence + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 19263, + }, + [GetSpellInfo(26669)] = { -- Evasion + track = AURA_TYPE_BUFF, + priority = 10, + spellID = 26669, + }, + + --- Immunities + [GetSpellInfo(34471)] = { -- The Beast Within + track = AURA_TYPE_BUFF, + priority = 20, + spellID = 34471, + }, + [GetSpellInfo(45438)] = { -- Ice Block + track = AURA_TYPE_BUFF, + priority = 30, + spellID = 45438, + }, + [GetSpellInfo(642)] = { -- Divine Shield + track = AURA_TYPE_BUFF, + priority = 30, + spellID = 642, + }, + + --- Alt Stuff + [GetSpellInfo(34709)] = { -- Shadowsight Buff + track = AURA_TYPE_BUFF, + duration = 15, + priority = 15, + magic = true, + spellID = 34709, + }, + [GetSpellInfo(8178)] = { -- Grounding Totem Effect + track = AURA_TYPE_BUFF, + duration = 0, + priority = 15, + spellID = 8178 + }, + [GetSpellInfo(5024)] = { -- Flee (Skull of impending Doom) -- 5024 + track = AURA_TYPE_BUFF, + priority = 15, + spellID = 5024, + altName = select(1, GetSpellInfo(5024)) .. " - " .. (select(1, GetItemInfo(4984)) or "Skull of Impending Doom"), + }, +} + +function Gladdy:GetImportantAuras() + return importantAuras +end + +local interrupts = { + [GetSpellInfo(19675)] = { duration = 4, spellID = 19675, track = AURA_TYPE_DEBUFF, texture = select(3, GetSpellInfo(19675)), priority = 15 }, -- Feral Charge Effect (Druid) + [GetSpellInfo(2139)] = { duration = 8, spellID = 2139, track = AURA_TYPE_DEBUFF, texture = select(3, GetSpellInfo(2139)), priority = 15 }, -- Counterspell (Mage) + [GetSpellInfo(1766)] = { duration = 5, spellID = 1766, track = AURA_TYPE_DEBUFF, texture = select(3, GetSpellInfo(1766)), priority = 15 }, -- Kick (Rogue) + [GetSpellInfo(6552)] = { duration = 4, spellID = 6552, track = AURA_TYPE_DEBUFF, texture = select(3, GetSpellInfo(6552)), priority = 15 }, -- Pummel (Warrior) + [GetSpellInfo(72)] = { duration = 6, spellID = 72, track = AURA_TYPE_DEBUFF, texture = select(3, GetSpellInfo(72)), priority = 15 }, -- Shield Bash (Warrior) + [GetSpellInfo(57994)] = { duration = 2, spellID = 57994, track = AURA_TYPE_DEBUFF, texture = select(3, GetSpellInfo(57994)), priority = 15 }, -- Wind Shear (Shaman) + [GetSpellInfo(19244)] = { duration = 5, spellID = 19244, track = AURA_TYPE_DEBUFF, texture = select(3, GetSpellInfo(19244)), priority = 15 }, -- Spell Lock (Warlock + [GetSpellInfo(47528)] = { duration = 5, spellID = 47528, track = AURA_TYPE_DEBUFF, texture = select(3, GetSpellInfo(47528)), priority = 15 }, -- Mind Freeze (Deathknight) +} +function Gladdy:GetInterrupts() + return interrupts +end + +local cooldownList = { + -- Spell Name Cooldown[, Spec] + -- Mage + ["MAGE"] = { + [1953] = 15, -- Blink + [42917] = 25, -- Frost Nova + [2139] = 24, -- Counterspell + [55342] = 180, -- Mirror Image + [12051] = 480, --Evocation + [45438] = { cd = 300, [L["Frost"]] = 240, }, -- Ice Block + [44572] = { cd = 30, spec = L["Frost"], }, -- Deep Freeze + [12472] = { cd = 180, spec = L["Frost"], }, -- Icy Veins + [31687] = { cd = 180, spec = L["Frost"], }, -- Summon Water Elemental + [12043] = { cd = 120, spec = L["Arcane"], }, -- Presence of Mind + [12042] = { cd = 180, spec = L["Arcane"], }, -- Arcane Power + [42950] = { cd = 20, spec = L["Fire"] }, -- Dragon's Breath + [11129] = { cd = 120, spec = L["Fire"] }, -- Combustion + [11958] = { cd = 480, spec = L["Frost"], -- Coldsnap + resetCD = { + [12472] = true, + [45438] = true, + [42917] = true, + [31687] = true, + [44572] = true, + }, + }, + }, + + -- Priest + ["PRIEST"] = { + [10890] = { cd = 27, [L["Shadow"]] = 23, }, -- Psychic Scream + [34433] = { cd = 300, [L["Shadow"]] = 180, }, -- Shadowfiend + [15487] = { cd = 45, spec = L["Shadow"], }, -- Silence + [64044] = { cd = 120, spec = L["Shadow"], }, -- Psychic Horror + [64843] = 480, -- Divine Hymn + [64901] = 360, -- Hymn of Hope + [32379] = 12, -- Shadow Word: Death + [6346] = 180, -- Fear Ward + [47585] = { cd = 75, spec = L["Shadow"], }, -- Dispersion (+ Glyph) + [10060] = { cd = 120, spec = L["Discipline"], }, -- Power Infusion + [33206] = { cd = 180, spec = L["Discipline"], }, -- Pain Suppression + }, + + -- Death Knight + ["DEATHKNIGHT"] = { + [47476] = 120, -- Strangulate + [47528] = 10, -- Mind Freeze + [48707] = 45, -- Anti-Magic Shell + [48792] = 120, -- Icebound Fortitude + [49576] = 35, -- Death Grip + [47568] = 300, -- Empower Rune Weapon + [48743] = 120, -- Death Pact + [49039] = 120, -- Lichborne + [47481] = { cd = 60, spec = L["Unholy"], }, -- Pet Gnaw + [51052] = { cd = 120, spec = L["Unholy"], }, -- Anti-Magic Zone + [46584] = { cd = 180, notSpec = L["Unholy"], }, -- Raise Dead + [49206] = { cd = 180, spec = L["Unholy"], }, -- Summon Gargoyle + [49028] = { cd = 90, spec = L["Blood"], }, -- Dancing Rune Weapon + [49203] = { cd = 60, spec = L["Frost"], }, -- Hungering Cold + }, + + -- Druid + ["DRUID"] = { + [22812] = 60, -- Barkskin + [29166] = 180, -- Innervate + [8983] = 60, -- Bash + [53312] = 60, -- Natures Grasp + [48505] = { cd = 90, spec = L["Balance"], }, -- Starfall + [50334] = { cd = 180, spec = L["Feral"], }, -- Berserk + [17116] = { cd = 120, spec = L["Restoration"], }, -- Natures Swiftness + [18562] = { cd = 15, spec = L["Restoration"], }, -- Swiftmend + [33831] = { cd = 180, spec = L["Balance"], }, -- Force of Nature + }, + + -- Shaman + ["SHAMAN"] = { + [57994] = 6, -- Wind Shear + [51514] = 45, -- Hex + [8177] = 15, -- Grounding Totem + [30823] = { cd = 60, spec = L["Enhancement"], }, -- Shamanistic Rage + [16166] = { cd = 180, spec = L["Elemental"], }, -- Elemental Mastery + [59159] = { cd = 45, spec = L["Elemental"], }, -- Thunderstorm + [16188] = { cd = 120, spec = L["Restoration"], }, -- Natures Swiftness + [51533] = { cd = 180, spec = L["Enhancement"], }, -- Feral Spirit + [16190] = { cd = 300, spec = L["Restoration"], }, -- Mana Tide Totem + }, + + -- Paladin + ["PALADIN"] = { + [10278] = 300, -- Hand of Protection + [1044] = 25, -- Hand of Freedom + [54428] = 60, -- Divine Plea + [6940] = 120, -- Hand of Sacrifice + [64205] = 120, -- Divine Sacrifice + [10308] = { cd = 60, [L["Protection"]] = 40, }, -- Hammer of Justice + [642] = { cd = 300, -- Divine Shield + sharedCD = { + cd = 30, + [31884] = true, + }, + }, + [31884] = { cd = 180, -- Avenging Wrath + sharedCD = { + cd = 30, + [642] = true, + }, + }, + [31821] = { cd = 120, spec = L["Holy"], }, -- Aura Mastery + [20066] = { cd = 60, spec = L["Retribution"], }, -- Repentance + [20216] = { cd = 120, spec = L["Holy"], }, -- Divine Favor + [31842] = { cd = 180, spec = L["Holy"], }, -- Divine Illumination + [31935] = { cd = 30, spec = L["Protection"], }, -- Avengers Shield + + }, + + -- Warlock + ["WARLOCK"] = { + [17928] = 40, -- Howl of Terror + [47860] = 120, -- Death Coil + [18708] = 180, -- Feldom + [47996] = { cd = 30, pet = true, }, -- Intercept + [48020] = 30, -- Demonic Circle: Port + [19647] = { cd = 24, pet = true, }, -- Spell Lock + [27277] = { cd = 8, pet = true, }, -- Devour Magic + [61290] = 15, -- Shadowflame + [47847] = { cd = 20, spec = L["Destruction"], }, -- Shadowfury + [17877] = { cd = 15, spec = L["Destruction"], }, -- Shadowburn + [17962] = { cd = 10, spec = L["Destruction"], }, -- Conflagrate + [59172] = { cd = 12, spec = L["Destruction"], }, -- Chaos Bolt + [47241] = { cd = 180, spec = L["Demonology"], }, -- Metamorphosis + [1122] = { cd = 600, spec = L["Demonology"], }, -- Inferno + }, + + -- Warrior + ["WARRIOR"] = { + [6552] = { cd = 10, -- Pummel + sharedCD = { + [72] = true, + }, + }, + [72] = { cd = 12, -- Shield Bash + sharedCD = { + [6552] = true, + }, + }, + [23920] = 10, -- Spell Reflection + [3411] = 30, -- Intervene + [676] = 60, -- Disarm + [5246] = 120, -- Intimidating Shout + [2565] = 60, -- Shield Block + [55694] = 180, -- Enraged Regeneration + [20230] = 300, -- Retaliation + [1719] = 300, -- Recklessness + [871] = 300, -- Shield Wall + [12292] = { cd = 180, spec = L["Fury"], }, -- Death Wish + [46924] = { cd = 90, spec = L["Arms"], }, -- Bladestorm + [46968] = { cd = 20, spec = L["Protection"], }, -- Shockwave + [12975] = { cd = 180, spec = L["Protection"], }, -- Last Stand + [12809] = { cd = 30, spec = L["Protection"], }, -- Concussion Blow + + }, + + -- Hunter + ["HUNTER"] = { + --[53548] = 28, -- Crab Prin + --[53562] = 40, -- Ravager Stun + + [19503] = 30, -- Scatter Shot + [19263] = 90, -- Deterrence + [781] = 15, -- Disengage + [5384] = 20, -- Feign Death + [3045] = 20, -- Rapid Fire + [60192] = { cd = 28, -- Freezing Arrow + sharedCD = { + [14311] = true, -- Freezing Trap + [13809] = true, -- Frost Trap + }, + }, + [14311] = { cd = 28, -- Freezing Trap + sharedCD = { + [60192] = true, -- Freezing Arrow + [13809] = true, -- Frost Trap + }, + }, + [13809] = { cd = 28, -- Frost Trap + sharedCD = { + [14311] = true, -- Freezing Trap + [60192] = true, -- Freezing Arrow + }, + }, + [34600] = { cd = 28, }, -- Snake Trap + [34490] = { cd = 20, spec = L["Marksmanship"], }, -- Silencing Shot + [19386] = { cd = 60, spec = L["Survival"], }, -- Wyvern Sting + [53271] = { cd = 60, pet = true, }, -- Masters Call + [19577] = { cd = 60, pet = true, }, -- Intimidation + [19574] = { cd = 120, pet = true, }, -- Bestial Wrath + [23989] = { cd = 180, -- Readiness + resetCD = { + [19503] = true, -- Scatter Shot + [19263] = true, -- Deterrence + [781] = true, -- Disengage + [60192] = true, -- Freezing Arrow + [14311] = true, -- Freezing Trap + [13809] = true, -- Frost Trap + [34600] = true, -- Snake Trap + [34490] = true, -- Silencing Shot + [19386] = true, -- Wyvern Sting + [53271] = true, -- Masters call + [19577] = true, -- Intimidation + }, + }, + }, + + -- Rogue + ["ROGUE"] = { + [1766] = 10, -- Kick + [8643] = 20, -- Kidney Shot + [26669] = 180, -- Evasion + [31224] = 90, -- Cloak of Shadow + [26889] = 180, -- Vanish + [2094] = 180, -- Blind + [51722] = 60, -- Dismantle + [11305] = 180, -- Sprint + [14177] = { cd = 180, spec = L["Assassination"], }, -- Cold Blood + [51713] = { cd = 60, spec = L["Subtlety"], }, -- Shadow Dance + [13750] = { cd = 180, spec = L["Combat"], }, -- Adrenaline Rush + [13877] = { cd = 120, spec = L["Combat"], }, -- Blade Flurry + [51690] = { cd = 120, spec = L["Combat"], }, -- Killing Spree + [36554] = { cd = 30, spec = L["Subtlety"], }, -- Shadowstep + [14185] = { cd = 480, spec = L["Subtlety"], -- Preparation + resetCD = { + [26669] = true, + [11305] = true, + [26889] = true, + [14177] = true, + [36554] = true, + }, + }, + }, + ["Scourge"] = { + + }, + ["BloodElf"] = { + + }, + ["Tauren"] = { + + }, + ["Orc"] = { + + }, + ["Troll"] = { + + }, + ["NightElf"] = { + + }, + ["Draenei"] = { + + }, + ["Human"] = { + + }, + ["Gnome"] = { + }, + ["Dwarf"] = { + + }, +} +function Gladdy:GetCooldownList() + return cooldownList +end + +local racials = { + ["Scourge"] = { + [7744] = true, -- Will of the Forsaken + duration = 120, + spellName = select(1, GetSpellInfo(7744)), + texture = select(3, GetSpellInfo(7744)) + }, + ["BloodElf"] = { + [28730] = true, -- Arcane Torrent + duration = 120, + spellName = select(1, GetSpellInfo(28730)), + texture = select(3, GetSpellInfo(28730)) + }, + ["Tauren"] = { + [20549] = true, -- War Stomp + duration = 120, + spellName = select(1, GetSpellInfo(20549)), + texture = select(3, GetSpellInfo(20549)) + }, + ["Orc"] = { + [20572] = true, + [33697] = true, + [33702] = true, + duration = 120, + spellName = select(1, GetSpellInfo(20572)), + texture = select(3, GetSpellInfo(20572)) + }, + ["Troll"] = { + [26297] = true, + duration = 180, + spellName = select(1, GetSpellInfo(26297)), + texture = select(3, GetSpellInfo(26297)) + }, + ["NightElf"] = { + [58984] = true, + duration = 120, + spellName = select(1, GetSpellInfo(58984)), + texture = select(3, GetSpellInfo(58984)) + }, + ["Draenei"] = { + [28880] = true, + duration = 180, + spellName = select(1, GetSpellInfo(28880)), + texture = select(3, GetSpellInfo(28880)) + }, + ["Human"] = { + [59752] = true, -- Perception + duration = 120, + spellName = select(1, GetSpellInfo(59752)), + texture = select(3, GetSpellInfo(59752)) + }, + ["Gnome"] = { + [20589] = true, -- Escape Artist + duration = 105, + spellName = select(1, GetSpellInfo(20589)), + texture = select(3, GetSpellInfo(20589)) + }, + ["Dwarf"] = { + [20594] = true, -- Stoneform + duration = 180, + spellName = select(1, GetSpellInfo(20594)), + texture = select(3, GetSpellInfo(20594)) + }, +} +function Gladdy:Racials() + return racials +end + + +--------------------- +-- TOTEM STUFF +--------------------- + +local totemData = { + -- Fire + [string_lower("Searing Totem")] = { id = 3599, texture = select(3, GetSpellInfo(3599)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Flametongue Totem")] = { id = 8227, texture = select(3, GetSpellInfo(8227)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Magma Totem")] = { id = 8190, texture = select(3, GetSpellInfo(8190)), color = { r = 0, g = 0, b = 0, a = 1 }, pulse = 2 }, + [string_lower("Fire Nova Totem")] = { id = 1535, texture = select(3, GetSpellInfo(1535)), color = { r = 0, g = 0, b = 0, a = 1 }, pulse = { cd = 4, once = true } }, + [string_lower("Totem of Wrath")] = { id = 30706, texture = select(3, GetSpellInfo(30706)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Fire Elemental Totem")] = { id = 32982, texture = select(3, GetSpellInfo(32982)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Frost Resistance Totem")] = { id = 8181, texture = select(3, GetSpellInfo(8181)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Totem of Wrath")] = { id = 30706, texture = select(3, GetSpellInfo(30706)), color = { r = 0, g = 0, b = 0, a = 1 } }, + -- Water + [string_lower("Fire Resistance Totem")] = { id = 8184, texture = select(3, GetSpellInfo(8184)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Disease Cleansing Totem")] = { id = 8170, texture = select(3, GetSpellInfo(8170)), color = { r = 0, g = 0, b = 0, a = 1 }, pulse = 5 }, + [string_lower("Healing Stream Totem")] = { id = 5394, texture = select(3, GetSpellInfo(5394)), color = { r = 0, g = 0, b = 0, a = 1 }, pulse = 2 }, + [string_lower("Mana Tide Totem")] = { id = 16190, texture = select(3, GetSpellInfo(16190)), color = { r = 0.078, g = 0.9, b = 0.16, a = 1 } }, + [string_lower("Mana Spring Totem")] = { id = 5675, texture = select(3, GetSpellInfo(5675)), color = { r = 0, g = 0, b = 0, a = 1 }, pulse = 2 }, + -- Earth + [string_lower("Earthbind Totem")] = { id = 2484, texture = select(3, GetSpellInfo(2484)), color = { r = 0.5, g = 0.5, b = 0.5, a = 1 }, pulse = 3 }, + [string_lower("Stoneclaw Totem")] = { id = 5730, texture = select(3, GetSpellInfo(5730)), color = { r = 0, g = 0, b = 0, a = 1 }, pulse = 2 }, + [string_lower("Stoneskin Totem")] = { id = 8071, texture = select(3, GetSpellInfo(8071)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Strength of Earth Totem")] = { id = 8075, texture = select(3, GetSpellInfo(8075)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Earth Elemental Totem")] = { id = 33663, texture = select(3, GetSpellInfo(33663)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Tremor Totem")] = { id = 8143, texture = select(3, GetSpellInfo(8143)), color = { r = 1, g = 0.9, b = 0.1, a = 1 }, pulse = 3 }, + -- Air + [string_lower("Grounding Totem")] = { id = 8177, texture = select(3, GetSpellInfo(8177)), color = { r = 0, g = 0.53, b = 0.92, a = 1 } }, + [string_lower("Nature Resistance Totem")] = { id = 10595, texture = select(3, GetSpellInfo(10595)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Windfury Totem")] = { id = 8512, texture = select(3, GetSpellInfo(8512)), color = { r = 0.96, g = 0, b = 0.07, a = 1 } }, + [string_lower("Sentry Totem")] = { id = 6495, texture = select(3, GetSpellInfo(6495)), color = { r = 0, g = 0, b = 0, a = 1 } }, + [string_lower("Wrath of Air Totem")] = { id = 3738, texture = select(3, GetSpellInfo(3738)), color = { r = 0, g = 0, b = 0, a = 1 } }, +} + +local totemSpellIdToPulse = { + [GetSpellInfo(totemData[string_lower("Earthbind Totem")].id)] = totemData[string_lower("Earthbind Totem")].pulse, + [2484] = totemData[string_lower("Earthbind Totem")].pulse, + [GetSpellInfo(totemData[string_lower("Tremor Totem")].id)] = totemData[string_lower("Tremor Totem")].pulse, + [8143] = totemData[string_lower("Tremor Totem")].pulse, + --[GetSpellInfo(totemData[string_lower("Poison Cleansing Totem")].id)] = totemData[string_lower("Poison Cleansing Totem")].pulse, + --[8166] = totemData[string_lower("Poison Cleansing Totem")].pulse, + [GetSpellInfo(totemData[string_lower("Disease Cleansing Totem")].id)] = totemData[string_lower("Disease Cleansing Totem")].pulse, + [8170] = totemData[string_lower("Disease Cleansing Totem")].pulse, + [GetSpellInfo(totemData[string_lower("Fire Nova Totem")].id)] = totemData[string_lower("Fire Nova Totem")].pulse, + [1535] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 1 + [8498] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 2 + [8499] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 3 + [11314] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 4 + [11315] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 5 + [25546] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 6 + [25547] = totemData[string_lower("Fire Nova Totem")].pulse, -- Rank 7 + [GetSpellInfo(totemData[string_lower("Magma Totem")].id)] = totemData[string_lower("Magma Totem")].pulse, + [8190] = totemData[string_lower("Magma Totem")].pulse, -- Rank 1 + [10585] = totemData[string_lower("Magma Totem")].pulse, -- Rank 2 + [10586] = totemData[string_lower("Magma Totem")].pulse, -- Rank 3 + [10587] = totemData[string_lower("Magma Totem")].pulse, -- Rank 4 + [25552] = totemData[string_lower("Magma Totem")].pulse, -- Rank 5 + [GetSpellInfo(totemData[string_lower("Healing Stream Totem")].id)] = totemData[string_lower("Healing Stream Totem")].pulse, + [5394] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 1 + [6375] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 2 + [6377] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 3 + [10462] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 4 + [10463] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 5 + [25567] = totemData[string_lower("Healing Stream Totem")].pulse, -- Rank 6 + [GetSpellInfo(totemData[string_lower("Mana Spring Totem")].id)] = totemData[string_lower("Mana Spring Totem")].pulse, + [5675] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 1 + [10495] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 2 + [10496] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 3 + [10497] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 4 + [25570] = totemData[string_lower("Mana Spring Totem")].pulse, -- Rank 5 + [GetSpellInfo(totemData[string_lower("Stoneclaw Totem")].id)] = totemData[string_lower("Stoneclaw Totem")].pulse, + [5730] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 1 + [6390] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 2 + [6391] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 3 + [6392] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 4 + [10427] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 5 + [10428] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 6 + [25525] = totemData[string_lower("Stoneclaw Totem")].pulse, -- Rank 7 +} + +local totemNpcIdsToTotemData = { + --fire + [2523] = totemData[string_lower("Searing Totem")], + [3902] = totemData[string_lower("Searing Totem")], + [3903] = totemData[string_lower("Searing Totem")], + [3904] = totemData[string_lower("Searing Totem")], + [7400] = totemData[string_lower("Searing Totem")], + [7402] = totemData[string_lower("Searing Totem")], + [15480] = totemData[string_lower("Searing Totem")], + [31162] = totemData[string_lower("Searing Totem")], + [31164] = totemData[string_lower("Searing Totem")], + [31165] = totemData[string_lower("Searing Totem")], + [21995] = totemData[string_lower("Searing Totem")], + [22209] = totemData[string_lower("Searing Totem")], + [22895] = totemData[string_lower("Searing Totem")], + [22896] = totemData[string_lower("Searing Totem")], + [34687] = totemData[string_lower("Searing Totem")], + [36532] = totemData[string_lower("Searing Totem")], + [43423] = totemData[string_lower("Searing Totem")], + [67380] = totemData[string_lower("Searing Totem")], + [73477] = totemData[string_lower("Searing Totem")], + [79238] = totemData[string_lower("Searing Totem")], + [22896] = totemData[string_lower("Searing Totem")], + [84519] = totemData[string_lower("Searing Totem")], + [110730] = totemData[string_lower("Searing Totem")], + [132178] = totemData[string_lower("Searing Totem")], + [9637] = totemData[string_lower("Searing Totem")], + + [5950] = totemData[string_lower("Flametongue Totem")], + [6012] = totemData[string_lower("Flametongue Totem")], + [7423] = totemData[string_lower("Flametongue Totem")], + [10557] = totemData[string_lower("Flametongue Totem")], + [15485] = totemData[string_lower("Flametongue Totem")], + [31132] = totemData[string_lower("Flametongue Totem")], + [31133] = totemData[string_lower("Flametongue Totem")], + [31158] = totemData[string_lower("Flametongue Totem")], + [42605] = totemData[string_lower("Flametongue Totem")], + + [5929] = totemData[string_lower("Magma Totem")], + [7464] = totemData[string_lower("Magma Totem")], + [7465] = totemData[string_lower("Magma Totem")], + [7466] = totemData[string_lower("Magma Totem")], + [15484] = totemData[string_lower("Magma Totem")], + [31166] = totemData[string_lower("Magma Totem")], + [31167] = totemData[string_lower("Magma Totem")], + [32887] = totemData[string_lower("Magma Totem")], + [42211] = totemData[string_lower("Magma Totem")], + [71335] = totemData[string_lower("Magma Totem")], + [71925] = totemData[string_lower("Magma Totem")], + [73085] = totemData[string_lower("Magma Totem")], + [73093] = totemData[string_lower("Magma Totem")], + [73268] = totemData[string_lower("Magma Totem")], + [88971] = totemData[string_lower("Magma Totem")], + [97369] = totemData[string_lower("Magma Totem")], + [98676] = totemData[string_lower("Magma Totem")], + + [5879] = totemData[string_lower("Fire Nova Totem")], + [6110] = totemData[string_lower("Fire Nova Totem")], + [6111] = totemData[string_lower("Fire Nova Totem")], + [7844] = totemData[string_lower("Fire Nova Totem")], + [7845] = totemData[string_lower("Fire Nova Totem")], + [14662] = totemData[string_lower("Fire Nova Totem")], + [15482] = totemData[string_lower("Fire Nova Totem")], + [15483] = totemData[string_lower("Fire Nova Totem")], + [24320] = totemData[string_lower("Fire Nova Totem")], + [32775] = totemData[string_lower("Fire Nova Totem")], + [32776] = totemData[string_lower("Fire Nova Totem")], + + [17539] = totemData[string_lower("Totem of Wrath")], + [22970] = totemData[string_lower("Totem of Wrath")], + [22971] = totemData[string_lower("Totem of Wrath")], + [30652] = totemData[string_lower("Totem of Wrath")], + [30653] = totemData[string_lower("Totem of Wrath")], + [30654] = totemData[string_lower("Totem of Wrath")], + + [15439] = totemData[string_lower("Fire Elemental Totem")], + [40830] = totemData[string_lower("Fire Elemental Totem")], + [41337] = totemData[string_lower("Fire Elemental Totem")], + [41346] = totemData[string_lower("Fire Elemental Totem")], + [72301] = totemData[string_lower("Fire Elemental Totem")], + + [5926] = totemData[string_lower("Frost Resistance Totem")], + [7412] = totemData[string_lower("Frost Resistance Totem")], + [7413] = totemData[string_lower("Frost Resistance Totem")], + [15486] = totemData[string_lower("Frost Resistance Totem")], + [31171] = totemData[string_lower("Frost Resistance Totem")], + [31172] = totemData[string_lower("Frost Resistance Totem")], + + -- Water + [5927] = totemData[string_lower("Fire Resistance Totem")], + [7424] = totemData[string_lower("Fire Resistance Totem")], + [7425] = totemData[string_lower("Fire Resistance Totem")], + [15487] = totemData[string_lower("Fire Resistance Totem")], + [31169] = totemData[string_lower("Fire Resistance Totem")], + [31170] = totemData[string_lower("Fire Resistance Totem")], + + + [5924] = totemData[string_lower("Disease Cleansing Totem")], + + [3527] = totemData[string_lower("Healing Stream Totem")], + [3906] = totemData[string_lower("Healing Stream Totem")], + [3907] = totemData[string_lower("Healing Stream Totem")], + [3908] = totemData[string_lower("Healing Stream Totem")], + [3909] = totemData[string_lower("Healing Stream Totem")], + [14664] = totemData[string_lower("Healing Stream Totem")], + [15488] = totemData[string_lower("Healing Stream Totem")], + [18235] = totemData[string_lower("Healing Stream Totem")], + [31181] = totemData[string_lower("Healing Stream Totem")], + [31182] = totemData[string_lower("Healing Stream Totem")], + [31185] = totemData[string_lower("Healing Stream Totem")], + [34686] = totemData[string_lower("Healing Stream Totem")], + [36542] = totemData[string_lower("Healing Stream Totem")], + [37810] = totemData[string_lower("Healing Stream Totem")], + [38428] = totemData[string_lower("Healing Stream Totem")], + [47077] = totemData[string_lower("Healing Stream Totem")], + [72309] = totemData[string_lower("Healing Stream Totem")], + [72457] = totemData[string_lower("Healing Stream Totem")], + [73890] = totemData[string_lower("Healing Stream Totem")], + [74433] = totemData[string_lower("Healing Stream Totem")], + [97508] = totemData[string_lower("Healing Stream Totem")], + [112567] = totemData[string_lower("Healing Stream Totem")], + [120357] = totemData[string_lower("Healing Stream Totem")], + [128539] = totemData[string_lower("Healing Stream Totem")], + [132049] = totemData[string_lower("Healing Stream Totem")], + + [10467] = totemData[string_lower("Mana Tide Totem")], + [11100] = totemData[string_lower("Mana Tide Totem")], + [11101] = totemData[string_lower("Mana Tide Totem")], + [17061] = totemData[string_lower("Mana Tide Totem")], + + [3573] = totemData[string_lower("Mana Spring Totem")], + [7414] = totemData[string_lower("Mana Spring Totem")], + [7415] = totemData[string_lower("Mana Spring Totem")], + [7416] = totemData[string_lower("Mana Spring Totem")], + [15304] = totemData[string_lower("Mana Spring Totem")], + [15489] = totemData[string_lower("Mana Spring Totem")], + [31186] = totemData[string_lower("Mana Spring Totem")], + [31189] = totemData[string_lower("Mana Spring Totem")], + [31190] = totemData[string_lower("Mana Spring Totem")], + + -- Earth + [2630] = totemData[string_lower("Earthbind Totem")], + [22486] = totemData[string_lower("Earthbind Totem")], + [40233] = totemData[string_lower("Earthbind Totem")], + [74737] = totemData[string_lower("Earthbind Totem")], + [79155] = totemData[string_lower("Earthbind Totem")], + + [3579] = totemData[string_lower("Stoneclaw Totem")], + [3911] = totemData[string_lower("Stoneclaw Totem")], + [3912] = totemData[string_lower("Stoneclaw Totem")], + [3913] = totemData[string_lower("Stoneclaw Totem")], + [7398] = totemData[string_lower("Stoneclaw Totem")], + [7399] = totemData[string_lower("Stoneclaw Totem")], + [14870] = totemData[string_lower("Stoneclaw Totem")], + [15478] = totemData[string_lower("Stoneclaw Totem")], + [31120] = totemData[string_lower("Stoneclaw Totem")], + [31121] = totemData[string_lower("Stoneclaw Totem")], + [31122] = totemData[string_lower("Stoneclaw Totem")], + [40258] = totemData[string_lower("Stoneclaw Totem")], + [102402] = totemData[string_lower("Stoneclaw Totem")], + + [5873] = totemData[string_lower("Stoneskin Totem")], + [5919] = totemData[string_lower("Stoneskin Totem")], + [5920] = totemData[string_lower("Stoneskin Totem")], + [7366] = totemData[string_lower("Stoneskin Totem")], + [7367] = totemData[string_lower("Stoneskin Totem")], + [7368] = totemData[string_lower("Stoneskin Totem")], + [14663] = totemData[string_lower("Stoneskin Totem")], + [15470] = totemData[string_lower("Stoneskin Totem")], + [15474] = totemData[string_lower("Stoneskin Totem")], + [18177] = totemData[string_lower("Stoneskin Totem")], + [21994] = totemData[string_lower("Stoneskin Totem")], + [31175] = totemData[string_lower("Stoneskin Totem")], + [31176] = totemData[string_lower("Stoneskin Totem")], + [36550] = totemData[string_lower("Stoneskin Totem")], + [40267] = totemData[string_lower("Stoneskin Totem")], + [41967] = totemData[string_lower("Stoneskin Totem")], + + [5874] = totemData[string_lower("Strength of Earth Totem")], + [5921] = totemData[string_lower("Strength of Earth Totem")], + [5922] = totemData[string_lower("Strength of Earth Totem")], + [7403] = totemData[string_lower("Strength of Earth Totem")], + [15464] = totemData[string_lower("Strength of Earth Totem")], + [15479] = totemData[string_lower("Strength of Earth Totem")], + [21992] = totemData[string_lower("Strength of Earth Totem")], + [30647] = totemData[string_lower("Strength of Earth Totem")], + [31129] = totemData[string_lower("Strength of Earth Totem")], + [40266] = totemData[string_lower("Strength of Earth Totem")], + + [15430] = totemData[string_lower("Earth Elemental Totem")], + [24649] = totemData[string_lower("Earth Elemental Totem")], + [39387] = totemData[string_lower("Earth Elemental Totem")], + [40247] = totemData[string_lower("Earth Elemental Totem")], + [72307] = totemData[string_lower("Earth Elemental Totem")], + + [5913] = totemData[string_lower("Tremor Totem")], + [41938] = totemData[string_lower("Tremor Totem")], + [41939] = totemData[string_lower("Tremor Totem")], + + -- Air + [5925] = totemData[string_lower("Grounding Totem")], + [128537] = totemData[string_lower("Grounding Totem")], + [136251] = totemData[string_lower("Grounding Totem")], + + [7467] = totemData[string_lower("Nature Resistance Totem")], + [7468] = totemData[string_lower("Nature Resistance Totem")], + [7469] = totemData[string_lower("Nature Resistance Totem")], + [15490] = totemData[string_lower("Nature Resistance Totem")], + [31173] = totemData[string_lower("Nature Resistance Totem")], + [31174] = totemData[string_lower("Nature Resistance Totem")], + + [6112] = totemData[string_lower("Windfury Totem")], + [7483] = totemData[string_lower("Windfury Totem")], + [7484] = totemData[string_lower("Windfury Totem")], + [14666] = totemData[string_lower("Windfury Totem")], + [15496] = totemData[string_lower("Windfury Totem")], + [15497] = totemData[string_lower("Windfury Totem")], + [22897] = totemData[string_lower("Windfury Totem")], + [41940] = totemData[string_lower("Windfury Totem")], + [41941] = totemData[string_lower("Windfury Totem")], + [80703] = totemData[string_lower("Windfury Totem")], + [105690] = totemData[string_lower("Windfury Totem")], + [133684] = totemData[string_lower("Windfury Totem")], + + [3968] = totemData[string_lower("Sentry Totem")], + [28938] = totemData[string_lower("Sentry Totem")], + [40187] = totemData[string_lower("Sentry Totem")], + [69505] = totemData[string_lower("Sentry Totem")], + [70413] = totemData[string_lower("Sentry Totem")], + [71145] = totemData[string_lower("Sentry Totem")], + [147410] = totemData[string_lower("Sentry Totem")], + + [15447] = totemData[string_lower("Wrath of Air Totem")], + [36556] = totemData[string_lower("Wrath of Air Totem")], +} + +function Gladdy:GetTotemData() + return totemData, totemNpcIdsToTotemData, totemSpellIdToPulse +end diff --git a/Constants_shared.lua b/Constants_shared.lua new file mode 100644 index 0000000..1c7a6b3 --- /dev/null +++ b/Constants_shared.lua @@ -0,0 +1,274 @@ +local tbl_sort, select, string_lower = table.sort, select, string.lower +local GetLocale = GetLocale + +local Gladdy = LibStub("Gladdy") +local L = Gladdy.L + +Gladdy.RACES = {"Scourge", "BloodElf", "Tauren", "Orc", "Troll", "NightElf", "Draenei", "Human", "Gnome", "Dwarf"} +tbl_sort(Gladdy.RACES) + +local RACE_ICON_TCOORDS = { + ["HUMAN_MALE"] = { 0, 0.125, 0, 0.25 }, + ["DWARF_MALE"] = { 0.125, 0.25, 0, 0.25 }, + ["GNOME_MALE"] = { 0.25, 0.375, 0, 0.25 }, + ["NIGHTELF_MALE"] = { 0.375, 0.5, 0, 0.25 }, + + ["TAUREN_MALE"] = { 0, 0.125, 0.25, 0.5 }, + ["SCOURGE_MALE"] = { 0.125, 0.25, 0.25, 0.5 }, + ["TROLL_MALE"] = { 0.25, 0.375, 0.25, 0.5 }, + ["ORC_MALE"] = { 0.375, 0.5, 0.25, 0.5 }, + + ["HUMAN_FEMALE"] = { 0, 0.125, 0.5, 0.75 }, + ["DWARF_FEMALE"] = { 0.125, 0.25, 0.5, 0.75 }, + ["GNOME_FEMALE"] = { 0.25, 0.375, 0.5, 0.75 }, + ["NIGHTELF_FEMALE"] = { 0.375, 0.5, 0.5, 0.75 }, + + ["TAUREN_FEMALE"] = { 0, 0.125, 0.75, 1.0 }, + ["SCOURGE_FEMALE"] = { 0.125, 0.25, 0.75, 1.0 }, + ["TROLL_FEMALE"] = { 0.25, 0.375, 0.75, 1.0 }, + ["ORC_FEMALE"] = { 0.375, 0.5, 0.75, 1.0 }, + + ["BLOODELF_MALE"] = { 0.5, 0.625, 0.25, 0.5 }, + ["BLOODELF_FEMALE"] = { 0.5, 0.625, 0.75, 1.0 }, + + ["DRAENEI_MALE"] = { 0.5, 0.625, 0, 0.25 }, + ["DRAENEI_FEMALE"] = { 0.5, 0.625, 0.5, 0.75 }, +} + +local arenaTimer = { + ["default"] = { + [60] = "One minute until the Arena battle begins!", + [30] = "Thirty seconds until the Arena battle begins!", + [15] = "Fifteen seconds until the Arena battle begins!", + [0] = "The Arena battle has begun!", + }, + ["esES"] = { + [60] = "¡Un minuto hasta que dé comienzo la batalla en arena!", + [30] = "¡Treinta segundos hasta que comience la batalla en arena!", + [15] = "¡Quince segundos hasta que comience la batalla en arena!", + [0] = "¡La batalla en arena ha comenzado!", + }, + ["ptBR"] = { + [60] = "Um minuto até a batalha na Arena começar!", + [30] = "Trinta segundos até a batalha na Arena começar!", + [15] = "Quinze segundos até a batalha na Arena começar!", + [0] = "A batalha na Arena começou!", + }, + ["deDE"] = { + [60] = "Noch eine Minute bis der Arenakampf beginnt!", + [30] = "Noch dreißig Sekunden bis der Arenakampf beginnt!", + [15] = "Noch fünfzehn Sekunden bis der Arenakampf beginnt!", + [0] = "Der Arenakampf hat begonnen!", + }, + ["frFR"] = { + [60] = "Le combat d'arène commence dans une minute\194\160!", + [30] = "Le combat d'arène commence dans trente secondes\194\160!", + [15] = "Le combat d'arène commence dans quinze secondes\194\160!", + [0] = "Le combat d'arène commence\194\160!", + }, + ["ruRU"] = { + [60] = "Одна минута до начала боя на арене!", + [30] = "Тридцать секунд до начала боя на арене!", + [15] = "До начала боя на арене осталось 15 секунд.", + [0] = "Бой начался!", + }, + ["itIT"] = { -- TODO + -- Beta has no itIT version available? + }, + ["koKR"] = { + [60] = "투기장 전투 시작 1분 전입니다!", + [30] = "투기장 전투 시작 30초 전입니다!", + [15] = "투기장 전투 시작 15초 전입니다!", + [0] = "투기장 전투가 시작되었습니다!", + }, + ["zhCN"] = { + [60] = "竞技场战斗将在一分钟后开始!", + [30] = "竞技场战斗将在三十秒后开始!", + [15] = "竞技场战斗将在十五秒后开始!", + [0] = "竞技场的战斗开始了!", + }, + ["zhTW"] = { + [60] = "1分鐘後競技場戰鬥開始!", + [30] = "30秒後競技場戰鬥開始!", + [15] = "15秒後競技場戰鬥開始!", + [0] = "競技場戰鬥開始了!", + }, +} +arenaTimer["esMX"] = arenaTimer["esES"] +arenaTimer["ptPT"] = arenaTimer["ptBR"] + +function Gladdy:GetArenaTimer() + if arenaTimer[GetLocale()] then + return arenaTimer[GetLocale()] + else + return arenaTimer["default"] + end +end + +Gladdy.legacy = { + castBarPos = "LEFT", + buffsCooldownPos = "TOP", + buffsBuffsCooldownPos = "BOTTOM", + classIconPos = "LEFT", + ciAnchor = "healthBar", + ciPos = "TOP", + cooldownYPos = "TOP", + cooldownXPos = "LEFT", + drCooldownPos = "RIGHT", + racialAnchor = "trinket", + racialPos = "RIGHT", + trinketPos = "RIGHT", + padding = 1, + growUp = false, +} + +Gladdy.newDefaults = { + ["bottomMargin"] = 94.99996948242188, + ["newLayout"] = true, + Pets = { + ["petYOffset"] = -81.99993896484375, + ["petXOffset"] = 181, + }, + ClassIcon = { + ["classIconXOffset"] = -74.90008544921875, + }, + Racial = { + ["racialXOffset"] = 255.9000244140625, + }, + Trinket = { + ["trinketXOffset"] = 182, + }, + ["Combat Indicator"] = { + ["ciXOffset"] = 79.99993896484375, + ["ciYOffset"] = -10.99993896484375, + }, + Cooldowns = { + ["cooldownYOffset"] = 31, + }, + ["Buffs and Debuffs"] = { + ["buffsBuffsXOffset"] = 29, + ["buffsBuffsYOffset"] = -82.99993896484375, + ["buffsXOffset"] = 29, + ["buffsYOffset"] = 62.00006103515625, + }, + Diminishings = { + ["drXOffset"] = 329.7999877929688, + ["drYOffset"] = -22.5, + }, + ["Cast Bar"] = { + ["castBarXOffset"] = -235.900146484375, + ["castBarYOffset"] = -30.5, + }, +} + +Gladdy.frameStrata = { + BACKGROUND = L["Background"] .. "(0)", + LOW = L["Low"] .. "(1)", + MEDIUM = L["Medium"] .. "(2)", + HIGH = L["High"] .. "(3)", + DIALOG = L["Dialog"] .. "(4)", + FULLSCREEN = L["Fullscreen"] .. "(5)", + FULLSCREEN_DIALOG = L["Fullscreen Dialog"] .. "(6)", + TOOLTIP = L["Tooltip"] .. "(7)", +} + +Gladdy.frameStrataSorting = { + [1] = "BACKGROUND", + [2] = "LOW", + [3] = "MEDIUM", + [4] = "HIGH", + [5] = "DIALOG", + [6] = "FULLSCREEN", + [7] = "FULLSCREEN_DIALOG", + [8] = "TOOLTIP", +} + +local auraTypeColor = {} +auraTypeColor["none"] = { r = 0.80, g = 0, b = 0, a = 1 } +auraTypeColor["magic"] = { r = 0.20, g = 0.60, b = 1.00, a = 1 } +auraTypeColor["curse"] = { r = 0.60, g = 0.00, b = 1.00, a = 1 } +auraTypeColor["disease"] = { r = 0.60, g = 0.40, b = 0, a = 1 } +auraTypeColor["poison"] = { r = 0.00, g = 0.60, b = 0, a = 1 } +auraTypeColor["immune"] = { r = 1.00, g = 0.02, b = 0.99, a = 1 } +auraTypeColor["form"] = auraTypeColor["none"] +auraTypeColor["aura"] = auraTypeColor["none"] +auraTypeColor[""] = auraTypeColor["none"] + +function Gladdy:GetAuraTypeColor() + return auraTypeColor +end + +local spellSchoolColors = {} +spellSchoolColors[1] = { r = 1, g = 1, b = 0, a = 1, type = "Physical" } --- "physical" 255, 255, 0 +spellSchoolColors[2] = { r = 1, g = 0.901, b = 0.501, a = 1, type = "Holy" } ---"holy" -- 255, 230, 128 +spellSchoolColors[4] = { r = 1, g = 0.501, b = 0, a = 1, type = "Fire" } ---"fire" -- 255, 128, 0 +spellSchoolColors[8] = { r = 0.302, g = 1, b = 0.302, a = 1, type = "Nature" } ---"nature" -- 77, 255, 77 +spellSchoolColors[16] = { r = 0.501, g = 1, b = 1, a = 1, type = "Frost" } ---"frost" -- 128, 255, 255 +spellSchoolColors[32] = { r = 0.501, g = 0.501, b = 1, a = 1, type = "Shadow" } ---"shadow" --128, 128, 255 +spellSchoolColors[64] = { r = 1, g = 0.501, b = 1, a = 1, type = "Arcane" } ---"arcane" -- 255, 128, 255 +spellSchoolColors["unknown"] = { r = 0, g = 0, b = 0, a = 1, type = "Unknown" } ---"unknown spell school" + +function Gladdy:GetSpellSchoolColors() + return spellSchoolColors +end + +--------------------- +-- TRINKET STUFF +--------------------- + +local pvpTrinkets = { -- [itemID] = cd in ms + --wotlk + [59752] = 120000, + [51377] = 120000, + [51378] = 120000, + [46083] = 120000, + [46085] = 120000, + [46081] = 120000, + [46084] = 120000, + [46082] = 120000, + [42122] = 120000, + [42123] = 120000, + --tbc + [37864] = 120000, + [37865] = 120000, + [28235] = 120000, + [30348] = 120000, + [28238] = 120000, + [30351] = 120000, + [28236] = 120000, + [30349] = 120000, + [28234] = 120000, + [28237] = 120000, + [30350] = 120000, + [28240] = 120000, + [28243] = 120000, + [30345] = 120000, + [28241] = 120000, + [30343] = 120000, + [28239] = 120000, + [30346] = 120000, + [28242] = 120000, + [30344] = 120000, + [29593] = 120000, + [29593] = 300000, + [18859] = 300000, + [18857] = 300000, + [18864] = 300000, + [18854] = 300000, + [18862] = 300000, + [18858] = 300000, + [18856] = 300000, + [18863] = 300000, + [18834] = 300000, + [18851] = 300000, + [18845] = 300000, + [18852] = 300000, + [29592] = 300000, + [18850] = 300000, + [18846] = 300000, + [18853] = 300000, +} + +function Gladdy:GetPvpTrinkets() + return pvpTrinkets +end \ No newline at end of file diff --git a/Gladdy.toc b/Gladdy_BCC.toc similarity index 94% rename from Gladdy.toc rename to Gladdy_BCC.toc index a9c4720..8a1068e 100644 --- a/Gladdy.toc +++ b/Gladdy_BCC.toc @@ -1,6 +1,6 @@ ## Interface: 20504 ## Title: Gladdy - TBC -## Version: 2.11-Release +## Version: 2.2-Beta ## Notes: The most powerful arena AddOn for WoW 2.5.4 ## Author: XiconQoo, DnB_Junkee, Knall ## X-Email: contact me on discord Knall#1751 @@ -13,7 +13,8 @@ Gladdy.lua Lang.lua Frame.lua Options.lua -Constants.lua +Constants_shared.lua +Constants_BCC.lua ImportStrings.lua Util.lua diff --git a/Gladdy_Wrath.toc b/Gladdy_Wrath.toc new file mode 100644 index 0000000..57962c5 --- /dev/null +++ b/Gladdy_Wrath.toc @@ -0,0 +1,44 @@ +## Interface: 30400 +## Title: Gladdy - WotLK +## Version: 2.2-Beta +## Notes: The most powerful arena AddOn for WoW 3.4.0 +## Author: XiconQoo, DnB_Junkee, Knall +## X-Email: contact me on discord Knall#1751 +## SavedVariables: GladdyXZ +## OptionalDeps: SharedMedia, Blizzard_CombatLog, Blizzard_ArenaUI, Blizzard_CombatText, Plater, Kui_Nameplates, NeatPlates, TidyPlates_ThreatPlates, Tukui, ElvUI + +embeds.xml + +Gladdy.lua +Lang.lua +Frame.lua +Options.lua +Constants_shared.lua +Constants_Wrath.lua +ImportStrings.lua +Util.lua + +Modules\Announcements.lua +Modules\Healthbar.lua +Modules\Powerbar.lua +Modules\Auras.lua +Modules\Castbar.lua +Modules\Classicon.lua +Modules\Clicks.lua +Modules\Diminishings.lua +Modules\Highlight.lua +Modules\TotemPlates.lua +Modules\TotemPulse.lua +Modules\Trinket.lua +Modules\Racial.lua +Modules\Cooldowns.lua +Modules\ArenaCountDown.lua +Modules\BuffsDebuffs.lua +Modules\VersionCheck.lua +Modules\XiconProfiles.lua +Modules\Pets.lua +Modules\ExportImport.lua +Modules\CombatIndicator.lua +Modules\RangeCheck.lua +Modules\ShadowsightTimer.lua +EventListener.lua diff --git a/Lang.lua b/Lang.lua index caf2d58..2d6a97f 100644 --- a/Lang.lua +++ b/Lang.lua @@ -7,6 +7,7 @@ local L = {} -- Classes L["Druid"] = C_CreatureInfo.GetClassInfo(11).className +L["Deathknight"] = C_CreatureInfo.GetClassInfo(6).className L["Hunter"] = C_CreatureInfo.GetClassInfo(3).className L["Mage"] = C_CreatureInfo.GetClassInfo(8).className L["Paladin"] = C_CreatureInfo.GetClassInfo(2).className diff --git a/Libs/LibClassAuras-1.0/ClassBuffs.lua b/Libs/LibClassAuras-1.0/ClassBuffs.lua index 48de7aa..a89b887 100644 --- a/Libs/LibClassAuras-1.0/ClassBuffs.lua +++ b/Libs/LibClassAuras-1.0/ClassBuffs.lua @@ -194,4 +194,13 @@ Buff({ 45438 }, { buffType = "immune"}, "MAGE") -- Ice Block Buff({ 6143 }, { buffType = "magic"}, "MAGE") -- Frost Ward --talents Buff({ 11426 }, { buffType = "magic"}, "MAGE") -- Ice Barrier -Buff({ 12472 }, { buffType = "magic"}, "MAGE") -- Icy Veins \ No newline at end of file +Buff({ 12472 }, { buffType = "magic"}, "MAGE") -- Icy Veins + +------------- +-- DEATHKNIGHT +------------- + +Buff({ 48707 }, { buffType = "physical"}, "DEATHKNIGHT") -- Anti-Magic Shell +Buff({ 48792 }, { buffType = "physical"}, "DEATHKNIGHT") -- Icebound Fortitude +Buff({ 49039 }, { buffType = "physical"}, "DEATHKNIGHT") -- Lichborne +Buff({ 50461 }, { buffType = "physical"}, "DEATHKNIGHT") -- Anti-Magic Zone \ No newline at end of file diff --git a/Modules/Auras.lua b/Modules/Auras.lua index bbe428a..1433d84 100644 --- a/Modules/Auras.lua +++ b/Modules/Auras.lua @@ -483,12 +483,13 @@ function Auras:Test(unit) if Gladdy.exceptionNames[spellid] then spellName = Gladdy.exceptionNames[spellid] end + local duration = math.random(2,10) if (unit == "arena2") then if (v.value.track == AURA_TYPE_BUFF) then - self:AURA_GAIN(unit,v.value.track, spellid, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) + self:AURA_GAIN(unit,v.value.track, spellid, spellName, icon, duration, GetTime() + duration) end else - self:AURA_GAIN(unit,v.value.track, spellid, spellName, icon, self.auras[spellName].duration, GetTime() + self.auras[spellName].duration) + self:AURA_GAIN(unit,v.value.track, spellid, spellName, icon, duration, GetTime() + duration) end end -- /run LibStub("Gladdy").modules["Auras"]:Test("arena1") diff --git a/Modules/Classicon.lua b/Modules/Classicon.lua index db4c792..cdf6d4b 100644 --- a/Modules/Classicon.lua +++ b/Modules/Classicon.lua @@ -22,6 +22,7 @@ local Classicon = Gladdy:NewModule("Class Icon", 81, { local classIconPath = "Interface\\Addons\\Gladdy\\Images\\Classes\\" local classIcons = { ["DRUID"] = classIconPath .. "inv_misc_monsterclaw_04", + ["DEATHKNIGHT"] = select(3, GetSpellInfo(49023)), --Might of Mograine ["HUNTER"] = classIconPath .. "inv_weapon_bow_07", ["MAGE"] = classIconPath .. "inv_staff_13", ["PALADIN"] = classIconPath .. "inv_hammer_01", @@ -39,6 +40,11 @@ local specIcons = { [L["Feral"]] = select(3, GetSpellInfo(27545)), -- Cat Form [L["Restoration"]] = select(3, GetSpellInfo(5185)), -- Healing Touch }, + ["DEATHKNIGHT"] = { + [L["Unholy"]] = select(3, GetSpellInfo(48265)), -- Unholy Presence + [L["Blood"]] = select(3, GetSpellInfo(48266)), -- Blood Presence + [L["Frost"]] = select(3, GetSpellInfo(48263)), -- Frost Presence + }, ["HUNTER"] = { [L["Beast Mastery"]] = select(3, GetSpellInfo(1515)), -- Tame Beast [L["Marksmanship"]] = select(3, GetSpellInfo(42243)), -- Volley diff --git a/Modules/Racial.lua b/Modules/Racial.lua index 335b3fe..3bba10c 100644 --- a/Modules/Racial.lua +++ b/Modules/Racial.lua @@ -32,6 +32,9 @@ function Racial:Initialize() self:RegisterMessage("JOINED_ARENA") self:RegisterMessage("ENEMY_SPOTTED") self:RegisterMessage("RACIAL_USED") + if Gladdy.expansion == "Wrath" then + self:RegisterMessage("TRINKET_USED") + end end end @@ -40,6 +43,9 @@ function Racial:UpdateFrameOnce() self:RegisterMessage("JOINED_ARENA") self:RegisterMessage("ENEMY_SPOTTED") self:RegisterMessage("RACIAL_USED") + if Gladdy.expansion == "Wrath" then + self:RegisterMessage("TRINKET_USED") + end else self:UnregisterAllMessages() end @@ -207,6 +213,25 @@ function Racial:RACIAL_USED(unit, expirationTime, spellName) Racial:Used(unit, startTime, Gladdy:Racials()[button.race].duration) end +function Racial:TRINKET_USED(unit) -- Wrath only + local racial = self.frames[unit] + local button = Gladdy.buttons[unit] + if (not racial or not button or not button.race) then + return + end + if button.race == "Scourge" then + if racial.active and racial.timeLeft >= 45 then + -- do nothing + else + racial.active = false + self:Used(unit, GetTime(), 45) + end + elseif button.race == "Human" then + racial.active = false + self:Used(unit, GetTime(), 120) + end +end + function Racial:Used(unit, startTime, duration) local racial = self.frames[unit] if (not racial) then @@ -241,8 +266,8 @@ end function Racial:Test(unit) Racial:ENEMY_SPOTTED(unit) - if (unit == "arena1" or unit == "arena3") then - Racial:Used(unit, GetTime(), Gladdy:Racials()[Gladdy.buttons[unit].race].duration) + if (unit == "arena2" or unit == "arena3") then + Gladdy:SendMessage("RACIAL_USED", unit) end end diff --git a/Modules/Trinket.lua b/Modules/Trinket.lua index fd14d10..6276f9b 100644 --- a/Modules/Trinket.lua +++ b/Modules/Trinket.lua @@ -33,12 +33,18 @@ function Trinket:Initialize() self.frames = {} if Gladdy.db.trinketEnabled then self:RegisterMessage("JOINED_ARENA") + if Gladdy.expansion == "Wrath" then + self:RegisterMessage("RACIAL_USED") + end end end function Trinket:UpdateFrameOnce() if Gladdy.db.trinketEnabled then self:RegisterMessage("JOINED_ARENA") + if Gladdy.expansion == "Wrath" then + self:RegisterMessage("RACIAL_USED") + end else self:UnregisterAllMessages() end @@ -228,6 +234,7 @@ function Trinket:ResetUnit(unit) return end + trinket.itemID = nil trinket.timeLeft = nil trinket.active = false trinket.cooldown:Clear() @@ -239,13 +246,15 @@ function Trinket:Test(unit) if (not trinket) then return end - if (unit == "arena2" or unit == "arena3") then + if (unit == "arena1" or unit == "arena2") then self:Used(unit, GetTime() * 1000, 120000) end end function Trinket:JOINED_ARENA() self:RegisterEvent("ARENA_COOLDOWNS_UPDATE") + self:RegisterEvent("ARENA_CROWD_CONTROL_SPELL_UPDATE") + self:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", "arena1", "arena2", "arena3", "arena4", "arena5") self:SetScript("OnEvent", function(self, event, ...) if self[event] then self[event](self, ...) @@ -253,19 +262,64 @@ function Trinket:JOINED_ARENA() end) end +function Trinket:ARENA_CROWD_CONTROL_SPELL_UPDATE(...) + local unitID, spellID, itemID = ... + Gladdy:Debug("INFO", "Trinket:ARENA_CROWD_CONTROL_SPELL_UPDATE", unitID, spellID, itemID) + if Gladdy.buttons[unitID] and Gladdy:GetPvpTrinkets()[itemID] then + Gladdy.buttons[unitID].trinket.itemID = itemID + if not Gladdy.db.trinketColored then + self.frames[unitID].texture:SetTexture(GetItemIcon(itemID)) + end + end +end + +function Trinket:UNIT_SPELLCAST_SUCCEEDED(...) + local unitID, castGUID, spellID = ... + if Gladdy.buttons[unitID] then + if spellID == 42292 or spellID == 59752 then + Gladdy:Debug("INFO", "Trinket:UNIT_SPELLCAST_SUCCEEDED", unitID, spellID) + self:Used(unitID, GetTime() * 1000, + Gladdy.buttons[unitID].trinket.itemID and Gladdy:GetPvpTrinkets()[Gladdy.buttons[unitID].trinket.itemID] + or 120000) + end + end +end + +function Trinket:RACIAL_USED(unit) -- Wrath only + local trinket = self.frames[unit] + if (not trinket) then + return + end + if Gladdy.buttons[unit].race == "Scourge" then + if trinket.active and trinket.timeLeft >= 44 then + -- do nothing + else + trinket.active = false + self:Used(unit, GetTime() * 1000, 45000, true) + end + elseif Gladdy.buttons[unit].race == "Human" then + trinket.active = false + self:Used(unit, GetTime() * 1000, 120000) + end +end + function Trinket:ARENA_COOLDOWNS_UPDATE() for i=1, Gladdy.curBracket do - local unit = "arena" .. i - local spellID, itemID, startTime, duration = C_PvP.GetArenaCrowdControlInfo(unit); + local unitID = "arena" .. i + local spellID, itemID, startTime, duration = C_PvP.GetArenaCrowdControlInfo(unitID) + Gladdy:Debug("INFO", "Trinket:ARENA_COOLDOWNS_UPDATE", spellID, itemID, startTime, duration) if (spellID) then + if not Gladdy.db.trinketColored and Gladdy:GetPvpTrinkets()[itemID] then + self.frames[unitID].texture:SetTexture(GetItemIcon(itemID)) + end if (startTime ~= 0 and duration ~= 0) then - self:Used(unit, startTime, duration) + self:Used(unitID, startTime, duration) end end end end -function Trinket:Used(unit, startTime, duration) +function Trinket:Used(unit, startTime, duration, passive) local trinket = self.frames[unit] if (not trinket) then return @@ -277,7 +331,9 @@ function Trinket:Used(unit, startTime, duration) if Gladdy.db.trinketColored then trinket:SetBackdropColor(Gladdy:SetColor(Gladdy.db.trinketColoredCd)) end - Gladdy:SendMessage("TRINKET_USED", unit) + if not passive then + Gladdy:SendMessage("TRINKET_USED", unit) + end end end diff --git a/Options.lua b/Options.lua index 4a6aa57..a561539 100644 --- a/Options.lua +++ b/Options.lua @@ -935,6 +935,17 @@ function Gladdy:GetAuras(auraType) end return args end + if Gladdy.expansion == "Wrath" then + spells.deathknight = { + order = 3, + type = "group", + name = LOCALIZED_CLASS_NAMES_MALE["DEATHKNIGHT"], + icon = "Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes", + iconCoords = CLASS_ICON_TCOORDS["DEATHKNIGHT"], + args = {}, + } + spells.deathknight.args = assignForClass("DEATHKNIGHT") + end spells.druid.args = assignForClass("DRUID") spells.hunter.args = assignForClass("HUNTER") spells.mage.args = assignForClass("MAGE") -- 2.39.5 From e68dea3f2258644086ced66e353dbf44ace41935 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 29 Jul 2022 07:42:36 +0200 Subject: [PATCH 181/268] Wrath make export import possible with BCC profiles and vice versa --- Modules/ExportImport.lua | 41 ++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/Modules/ExportImport.lua b/Modules/ExportImport.lua index d049d48..8ffeb46 100644 --- a/Modules/ExportImport.lua +++ b/Modules/ExportImport.lua @@ -24,6 +24,7 @@ local function table_copy(t, str) end local ExportImport = Gladdy:NewModule("Export Import", nil, { + expansion = Gladdy.expansion, }) local export = AceGUI:Create("Frame") @@ -112,6 +113,18 @@ local deletedOptions = { -- backwards compatibility padding = true, growUp = true, powerBarFontSize = true, + ["38373"] = true, -- The Beast Within (Auras) + ["34692"] = true, -- The Beast Within (Cooldowns) +} + +local expansionSpecific = { + "drCategories", + "auraListDefault", + "auraListInterrupts", + "trackedDebuffs", + "trackedBuffs", + "cooldownCooldowns", + "cooldownCooldownsOrder", } local function checkIsDeletedOption(k, str, msg, errorFound, errorMsg) @@ -162,7 +175,7 @@ function ExportImport:CheckDeserializedOptions(tbl, refTbl, str) end if errorFound then - return false, errorMsg + --return false, errorMsg end return true end @@ -227,17 +240,29 @@ function ExportImport:ApplyImport(t, table, str) if (not t.newLayout) then table.newLayout = false end + if not t.expansion then + t.expansion = "BCC" + end end for k,v in pairs(t) do - if type(v) == "table" then - if (table[k] ~= nil) then - ExportImport:ApplyImport(v, table[k], str .. "." .. k) - else - Gladdy:Debug("ERROR", "ApplyImport failed for", str .. "." .. k) + local skip = k == "expansion" + if t.expansion and t.expansion ~= table.expansion then + if Gladdy:contains(k, expansionSpecific) then + Gladdy:Debug("WARN", "ExportImport:ApplyImport", "skipped", k, "- import string expansion is", t.expansion, "- current expansion is", table.expansion) + skip = true end + end + if not skip then + if type(v) == "table" then + if (table[k] ~= nil) then + ExportImport:ApplyImport(v, table[k], str .. "." .. k) + else + Gladdy:Debug("ERROR", "ExportImport:ApplyImport", "failed for", str .. "." .. k) + end - else - table[k] = v + else + table[k] = v + end end end end -- 2.39.5 From 674eabd4899fdb4a17f66efd736b2d01ed5fccc8 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 29 Jul 2022 07:43:39 +0200 Subject: [PATCH 182/268] totempulse minor fix --- Modules/TotemPulse.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/TotemPulse.lua b/Modules/TotemPulse.lua index ff511e4..a785eb6 100644 --- a/Modules/TotemPulse.lua +++ b/Modules/TotemPulse.lua @@ -330,7 +330,7 @@ function TotemPulse:CreateCooldownFrame(style) end function TotemPulse:AddTimerFrame(nameplate, timestamp, test) - if (nameplate:IsShown() or test) and timestamp then + if (nameplate:IsShown() or test) and timestamp and timestamp.id then if not nameplate.totemTick then nameplate.totemTick = TotemPulse:CreateCooldownFrame(Gladdy.db.totemPulseTotems["totem" .. timestamp.id].style) end -- 2.39.5 From be1d4475d1a27f30f90da0cecf0eff5fbb0ab401 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 29 Jul 2022 07:44:40 +0200 Subject: [PATCH 183/268] detect spec minor fix + add deathknight to spec detection --- EventListener.lua | 32 ++++++++++++-------------------- Util.lua | 11 ++++++++++- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/EventListener.lua b/EventListener.lua index 820f181..9a2692d 100644 --- a/EventListener.lua +++ b/EventListener.lua @@ -134,8 +134,9 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() if not Gladdy.buttons[srcUnit].spec then self:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) end - if (eventType == "SPELL_CAST_SUCCESS" or eventType == "SPELL_AURA_APPLIED") then + if (eventType == "SPELL_CAST_SUCCESS" or eventType == "SPELL_AURA_APPLIED" or eventType == "SPELL_MISSED") then local unitRace = Gladdy.buttons[srcUnit].race + self:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) -- cooldown tracker if Gladdy.db.cooldown and Cooldowns.cooldownSpellIds[spellName] then local unitClass @@ -149,7 +150,6 @@ function EventListener:COMBAT_LOG_EVENT_UNFILTERED() else unitClass = Gladdy.buttons[srcUnit].race end - self:DetectSpec(srcUnit, Gladdy.specSpells[spellName]) if spellID ~= 16188 and spellID ~= 17116 then -- Nature's Swiftness CD starts when buff fades Cooldowns:CooldownUsed(srcUnit, unitClass, spellId) end @@ -314,29 +314,21 @@ function EventListener:UNIT_SPELLCAST_SUCCEEDED(unit) end end -local function notIn(spec, list) - for _,v in ipairs(list) do - if spec == v then - return false - end - end - return true -end - function EventListener:DetectSpec(unit, spec) local button = Gladdy.buttons[unit] if (not button or not spec or button.spec) then return end - if button.class == "PALADIN" and notIn(spec, {L["Holy"], L["Retribution"], L["Protection"]}) - or button.class == "SHAMAN" and notIn(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) - or button.class == "ROGUE" and notIn(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) - or button.class == "WARLOCK" and notIn(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) - or button.class == "PRIEST" and notIn(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) - or button.class == "MAGE" and notIn(spec, {L["Frost"], L["Fire"], L["Arcane"]}) - or button.class == "DRUID" and notIn(spec, {L["Restoration"], L["Feral"], L["Balance"]}) - or button.class == "HUNTER" and notIn(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) - or button.class == "WARRIOR" and notIn(spec, {L["Arms"], L["Protection"], L["Fury"]}) then + if button.class == "PALADIN" and Gladdy:contains(spec, {L["Holy"], L["Retribution"], L["Protection"]}) + or button.class == "SHAMAN" and not Gladdy:contains(spec, {L["Restoration"], L["Enhancement"], L["Elemental"]}) + or button.class == "ROGUE" and not Gladdy:contains(spec, {L["Subtlety"], L["Assassination"], L["Combat"]}) + or button.class == "WARLOCK" and not Gladdy:contains(spec, {L["Demonology"], L["Destruction"], L["Affliction"]}) + or button.class == "PRIEST" and not Gladdy:contains(spec, {L["Shadow"], L["Discipline"], L["Holy"]}) + or button.class == "MAGE" and not Gladdy:contains(spec, {L["Frost"], L["Fire"], L["Arcane"]}) + or button.class == "DRUID" and not Gladdy:contains(spec, {L["Restoration"], L["Feral"], L["Balance"]}) + or button.class == "HUNTER" and not Gladdy:contains(spec, {L["Beast Mastery"], L["Marksmanship"], L["Survival"]}) + or button.class == "WARRIOR" and not Gladdy:contains(spec, {L["Arms"], L["Protection"], L["Fury"]}) + or button.class == "DEATHKNIGHT" and not Gladdy:contains(spec, {L["Unholy"], L["Blood"], L["Frost"]}) then return end if not button.spec then diff --git a/Util.lua b/Util.lua index 947a877..204ab05 100644 --- a/Util.lua +++ b/Util.lua @@ -141,4 +141,13 @@ function Gladdy:GetTagOption(name, order, enabledOption, func, toggle) "Can be combined with OR operator like |cff1ac742[percent|status]|r. The last valid option will be used.\n"], }) end -end \ No newline at end of file +end + +function Gladdy:contains(entry, list) + for _,v in pairs(list) do + if entry == v then + return true + end + end + return false +end -- 2.39.5 From 23097951e369c5bf21988ece067d3b1327e7bb15 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 29 Jul 2022 07:44:58 +0200 Subject: [PATCH 184/268] .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 23b1f2d..deb3cb1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ BuffLib Ace-Libs Images_Raw Gladdy_old +untracked Gladdy_TW \ No newline at end of file -- 2.39.5 From f1652e2b42b448d59d37ecb30f14cb3c4d38fdf7 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Fri, 29 Jul 2022 07:45:46 +0200 Subject: [PATCH 185/268] add DRList-1.0 as lib --- Libs/DRList-1.0/DRList-1.0.lua | 400 +++++++++++++++++++ Libs/DRList-1.0/DRList-1.0.toc | 23 ++ Libs/DRList-1.0/DRList-1.0.xml | 4 + Libs/DRList-1.0/Spells.lua | 689 +++++++++++++++++++++++++++++++++ Modules/Diminishings.lua | 3 +- embeds.xml | 1 + 6 files changed, 1119 insertions(+), 1 deletion(-) create mode 100644 Libs/DRList-1.0/DRList-1.0.lua create mode 100644 Libs/DRList-1.0/DRList-1.0.toc create mode 100644 Libs/DRList-1.0/DRList-1.0.xml create mode 100644 Libs/DRList-1.0/Spells.lua diff --git a/Libs/DRList-1.0/DRList-1.0.lua b/Libs/DRList-1.0/DRList-1.0.lua new file mode 100644 index 0000000..d384400 --- /dev/null +++ b/Libs/DRList-1.0/DRList-1.0.lua @@ -0,0 +1,400 @@ +--[[ +Name: DRList-1.0 +Description: Diminishing returns categorization. Fork of outdated DRData-1.0. +Website: https://github.com/wardz/DRList-1.0/ +Documentation: https://wardz.github.io/DRList-1.0/ +Dependencies: LibStub +License: MIT +]] + +--- DRList-1.0 +-- @module DRList-1.0 +local MAJOR, MINOR = "DRList-1.0", 40 -- Don't forget to change this in Spells.lua aswell! +local Lib = assert(LibStub, MAJOR .. " requires LibStub."):NewLibrary(MAJOR, MINOR) +if not Lib then return end -- already loaded + +------------------------------------------------------------------------------- +-- *** LOCALIZATIONS ARE AUTOMATICALLY GENERATED *** +-- Please see Curseforge localization page if you'd like to help translate. +-- https://www.curseforge.com/wow/addons/drlist-1-0/localization +local L = {} +Lib.L = L +L["DISARMS"] = "Disarms" +L["DISORIENTS"] = "Disorients" +L["INCAPACITATES"] = "Incapacitates" +L["KNOCKBACKS"] = "Knockbacks" +L["ROOTS"] = "Roots" +L["SILENCES"] = "Silences" +L["STUNS"] = "Stuns" +L["TAUNTS"] = "Taunts" +L["FEARS"] = "Fears" +L["RANDOM_ROOTS"] = "Random roots" +L["RANDOM_STUNS"] = "Random stuns" +L["OPENER_STUN"] = "Opener Stuns" +L["HORROR"] = "Horrors" +L["SCATTERS"] = "Scatters" +L["SLEEPS"] = GetSpellInfo(1090) or "Sleep" +L["MIND_CONTROL"] = GetSpellInfo(605) or "Mind Control" +L["FROST_SHOCK"] = GetSpellInfo(15089) or "Frost Shock" +L["KIDNEY_SHOT"] = GetSpellInfo(408) or "Kidney Shot" +L["DEATH_COIL"] = GetSpellInfo(28412) or "Death Coil" +L["UNSTABLE_AFFLICTION"] = GetSpellInfo(31117) or "Unstable Affliction" +L["CHASTISE"] = GetSpellInfo(44041) or "Chastise" +L["COUNTERATTACK"] = GetSpellInfo(19306) or "Counterattack" +L["CYCLONE"] = GetSpellInfo(33786) or "Cyclone" +L["BANISH"] = GetSpellInfo(710) or "Banish" +L["CHARGE"] = GetSpellInfo(100) or "Charge" + +-- luacheck: push ignore 542 +local locale = GetLocale() +if locale == "deDE" then + L["FEARS"] = "Furchteffekte" + L["KNOCKBACKS"] = "Rückstoßeffekte" + L["ROOTS"] = "Bewegungsunfähigkeitseffekte" + L["SILENCES"] = "Stilleeffekte" + L["STUNS"] = "Betäubungseffekte" + L["TAUNTS"] = "Spotteffekte" +elseif locale == "frFR" then + L["FEARS"] = "Peurs" + L["KNOCKBACKS"] = "Projections" + L["ROOTS"] = "Immobilisations" + L["SILENCES"] = "Silences" + L["STUNS"] = "Etourdissements" + L["TAUNTS"] = "Provocations" +elseif locale == "itIT" then + --@localization(locale="itIT", namespace="Categories", format="lua_additive_table", handle-unlocalized="ignore")@ +elseif locale == "koKR" then + L["DISORIENTS"] = "방향 감각 상실" + L["INCAPACITATES"] = "행동 불가" + L["KNOCKBACKS"] = "밀쳐내기" + L["ROOTS"] = "이동 불가" + L["SILENCES"] = "침묵" + L["STUNS"] = "기절" +elseif locale == "ptBR" then + --@localization(locale="ptBR", namespace="Categories", format="lua_additive_table", handle-unlocalized="ignore")@ +elseif locale == "ruRU" then + L["DISARMS"] = "Разоружение" + L["DISORIENTS"] = "Дезориентация" + L["FEARS"] = "Опасения" + L["INCAPACITATES"] = "Паралич" + L["KNOCKBACKS"] = "Отбрасывание" + L["RANDOM_ROOTS"] = "Случайные корни" + L["RANDOM_STUNS"] = "Случайные оглушения" + L["ROOTS"] = "Сковывание" + L["SILENCES"] = "Немота" + L["STUNS"] = "Оглушение" + L["TAUNTS"] = "Насмешки" +elseif locale == "esES" or locale == "esMX" then + L["DISARMS"] = "Desarmar" + L["DISORIENTS"] = "Desorientar" + L["FEARS"] = "Miedos" + L["INCAPACITATES"] = "Incapacitar" + L["KNOCKBACKS"] = "Derribos" + L["RANDOM_ROOTS"] = "Raíces aleatorias" + L["RANDOM_STUNS"] = "Aturdir aleatorio" + L["ROOTS"] = "Raíces" + L["SILENCES"] = "Silencios" + L["STUNS"] = "Aturdimientos" + L["TAUNTS"] = "Provocaciones" +elseif locale == "zhCN" then + L["DISARMS"] = "缴械" + L["DISORIENTS"] = "迷惑" + L["FEARS"] = "恐惧" + L["INCAPACITATES"] = "瘫痪" + L["KNOCKBACKS"] = "击退" + L["RANDOM_ROOTS"] = "随机定身" + L["RANDOM_STUNS"] = "随机眩晕" + L["ROOTS"] = "定身" + L["SILENCES"] = "沉默" + L["STUNS"] = "昏迷" + L["TAUNTS"] = "嘲讽" +elseif locale == "zhTW" then + L["DISARMS"] = "繳械" + L["DISORIENTS"] = "迷惑" + L["FEARS"] = "恐懼" + L["INCAPACITATES"] = "癱瘓" + L["KNOCKBACKS"] = "擊退" + L["RANDOM_ROOTS"] = "隨機定身" + L["RANDOM_STUNS"] = "隨機昏迷" + L["ROOTS"] = "定身" + L["SILENCES"] = "沉默" + L["STUNS"] = "昏迷" + L["TAUNTS"] = "嘲諷" +end +-- luacheck: pop +------------------------------------------------------------------------------- + +-- Check what game version we're running +Lib.gameExpansion = ({ + [WOW_PROJECT_MAINLINE] = "retail", + [WOW_PROJECT_CLASSIC] = "classic", + [WOW_PROJECT_BURNING_CRUSADE_CLASSIC or 5] = "tbc", +})[WOW_PROJECT_ID] + +local tocVersion = select(4, GetBuildInfo()) +if tocVersion >= 30400 and tocVersion < 40000 then + Lib.gameExpansion = "wotlk" -- temporary check for wotlk build until new constant is added +end + +-- How long it takes for a DR to expire, in seconds. +Lib.resetTimes = { + retail = { + ["default"] = 18.5, -- 18 sec + 0.5 latency + ["npc"] = 23, -- Against mobs it seems to last slightly longer, depending on server load + ["knockback"] = 10, -- Knockbacks are immediately immune and only DRs for 10s + }, + + classic = { + ["default"] = 19, -- dynamic between 15 and 20s + ["npc"] = 23, + }, + + tbc = { + ["default"] = 19, -- dynamic between 15 and 20s + ["npc"] = 23, + }, + + wotlk = { + ["default"] = 19, -- dynamic between 15 and 20s + ["npc"] = 23, + }, +} + +-- List of all DR categories, english -> localized. +Lib.categoryNames = { + retail = { + ["disorient"] = L.DISORIENTS, + ["incapacitate"] = L.INCAPACITATES, + ["silence"] = L.SILENCES, + ["stun"] = L.STUNS, + ["root"] = L.ROOTS, + ["disarm"] = L.DISARMS, + ["taunt"] = L.TAUNTS, + ["knockback"] = L.KNOCKBACKS, + }, + + classic = { + ["incapacitate"] = L.INCAPACITATES, + ["stun"] = L.STUNS, -- controlled stun + ["root"] = L.ROOTS, -- controlled root + ["random_stun"] = L.RANDOM_STUNS, -- random proc stun, usually short (<3s) + ["random_root"] = L.RANDOM_ROOTS, + ["fear"] = L.FEARS, + ["mind_control"] = L.MIND_CONTROL, + ["frost_shock"] = L.FROST_SHOCK, + ["kidney_shot"] = L.KIDNEY_SHOT, + }, + + tbc = { + ["disorient"] = L.DISORIENTS, + ["incapacitate"] = L.INCAPACITATES, + ["stun"] = L.STUNS, + ["random_stun"] = L.RANDOM_STUNS, + ["random_root"] = L.RANDOM_ROOTS, + ["root"] = L.ROOTS, + ["disarm"] = L.DISARMS, + ["fear"] = L.FEARS, + ["scatter"] = L.SCATTERS, + ["mind_control"] = L.MIND_CONTROL, + ["kidney_shot"] = L.KIDNEY_SHOT, + ["death_coil"] = L.DEATH_COIL, + ["unstable_affliction"] = L.UNSTABLE_AFFLICTION, + ["chastise"] = L.CHASTISE, + ["counterattack"] = L.COUNTERATTACK, + }, + + wotlk = { -- WORK IN PROGRESS + ["incapacitate"] = L.INCAPACITATES, + ["stun"] = L.STUNS, + ["random_stun"] = L.RANDOM_STUNS, + ["random_root"] = L.RANDOM_ROOTS, + ["root"] = L.ROOTS, + ["disarm"] = L.DISARMS, + ["fear"] = L.FEARS, + ["scatter"] = L.SCATTERS, + ["silence"] = L.SILENCES, + ["horror"] = L.HORROR, + ["mind_control"] = L.MIND_CONTROL, + ["cyclone"] = L.CYCLONE, + ["banish"] = L.BANISH, + ["charge"] = L.CHARGE, + ["opener_stun"] = L.OPENER_STUN, + }, +} + +-- Categories that have DR against normal mobs. +-- Note that this is only for normal mobs on retail. Special mobs or pets have DR on all categories, +-- see UnitClassification() and UnitIsQuestBoss(). +Lib.categoriesPvE = { + retail = { + ["taunt"] = L.TAUNTS, -- Lib.categoryNames.retail.taunt + ["stun"] = L.STUNS, + ["root"] = L.ROOTS, + }, + + classic = { + ["stun"] = L.STUNS, + ["kidney_shot"] = L.KIDNEY_SHOT, + }, + + tbc = { + ["stun"] = L.STUNS, + ["random_stun"] = L.RANDOM_STUNS, + ["kidney_shot"] = L.KIDNEY_SHOT, + }, + + wotlk = { + --["taunt"] = L.TAUNTS, + ["stun"] = L.STUNS, + ["random_stun"] = L.RANDOM_STUNS, + ["opener_stun"] = L.OPENER_STUN, + }, +} + +-- Successives diminished durations +Lib.diminishedDurations = { + retail = { + -- Decreases by 50%, immune at the 4th application + ["default"] = { 0.50, 0.25 }, + -- Decreases by 35%, immune at the 5th application + ["taunt"] = { 0.65, 0.42, 0.27 }, + -- Immediately immune + ["knockback"] = {}, + }, + + classic = { + ["default"] = { 0.50, 0.25 }, + }, + + tbc = { + ["default"] = { 0.50, 0.25 }, + }, + + wotlk = { + ["default"] = { 0.50, 0.25 }, + }, +} + +------------------------------------------------------------------------------- +-- Public API +------------------------------------------------------------------------------- + +--- Get table of all spells that DRs. +-- Key is the spellID, and value is the unlocalized DR category. +-- For Classic the key is the localized spell name instead, and value +-- is a table containing both the DR category and spell ID. (Classic has no spellID payload in the combat log) +-- @see IterateSpellsByCategory +-- @treturn ?table {number=string}|table {string=table} +function Lib:GetSpells() + return Lib.spellList +end + +--- Get table of all DR categories. +-- Key is unlocalized name used for API functions, value is localized name used for UI. +-- @treturn table {string=string} +function Lib:GetCategories() + return Lib.categoryNames[Lib.gameExpansion] +end + +--- Get table of all categories that DRs in PvE only. +-- Key is unlocalized name used for API functions, value is localized name used for UI. +-- Note that this is only for normal mobs on retail. Special mobs or pets have DR on all categories, +-- see UnitClassification() and UnitIsQuestBoss(). +-- Tip: you can combine :GetPvECategories() and :IterateSpellsByCategory() to get spellIDs only for PvE aswell. +-- @treturn table {string=string} +function Lib:GetPvECategories() + return Lib.categoriesPvE[Lib.gameExpansion] +end + +--- Get constant for how long a DR lasts for a given category. +-- @tparam[opt="default"] string category Unlocalized category name, or "npc" for PvE timer. +-- @treturn number +function Lib:GetResetTime(category) + return Lib.resetTimes[Lib.gameExpansion][category or "default"] or Lib.resetTimes[Lib.gameExpansion].default +end + +--- Get unlocalized DR category by spell ID. +-- For Classic (vanilla) you should pass in the spell name instead of ID. +-- For Classic you also get an optional second return value +-- which is the hardcoded spell ID of the spell name you passed in. +-- You should use this ID to query additional info from Blizzard API if needed, as +-- spell names only works for the player if they have the spell in their current spellbook. +-- @tparam number spellID +-- @treturn[1] string|nil The category name. +-- @treturn[2] number|nil The spell ID. (Classic only) +function Lib:GetCategoryBySpellID(spellID) + if Lib.gameExpansion == "classic" then + -- special case for classic as CLEU doesn't provide spellIDs + local data = Lib.spellList[spellID] + if not data then return end + return data.category, data.spellID + end + + return Lib.spellList[spellID] +end + +--- Get localized category from unlocalized category name, case sensitive. +-- @tparam string category Unlocalized category name +-- @treturn ?string|nil The localized category name. +function Lib:GetCategoryLocalization(category) + return Lib.categoryNames[Lib.gameExpansion][category] +end + +--- Check if a category has DR against mobs. +-- Note that this is only for normal mobs on retail. Special mobs or pets have DR on all categories, +-- see UnitClassification() and UnitIsQuestBoss(). +-- @tparam string category Unlocalized category name +-- @treturn bool +function Lib:IsPvECategory(category) + return Lib.categoriesPvE[Lib.gameExpansion][category] and true or false -- make sure bool is always returned here +end + +--- Get next successive diminished duration +-- @tparam number diminished How many times the DR has been applied so far +-- @tparam[opt="default"] string category Unlocalized category name +-- @usage local reduction = DRList:GetNextDR(1) -- returns 0.50, half duration on debuff +-- @treturn number DR percentage in decimals. Returns 0 if max DR is reached or arguments are invalid. +function Lib:GetNextDR(diminished, category) + local durations = Lib.diminishedDurations[Lib.gameExpansion][category or "default"] + if not durations and Lib.categoryNames[Lib.gameExpansion][category] then + -- Redirect to default when "stun", "root" etc is passed + durations = Lib.diminishedDurations[Lib.gameExpansion]["default"] + end + + return durations and durations[diminished] or 0 +end + +do + local next = _G.next + + local function CategoryIterator(category, index) + local spellList, newCat = Lib.spellList + repeat + index, newCat = next(spellList, index) + if index then + if newCat == category or newCat.category == category then + return index, category + end + end + until not index + end + + --- Iterate through the spells of a given category. + -- @tparam string category Unlocalized category name + -- @usage for spellID in DRList:IterateSpellsByCategory("root") do print(spellID) end + -- @warning Slow function, do not use for frequent combat related stuff unless you cache results. + -- @return Iterator function + function Lib:IterateSpellsByCategory(category) + assert(Lib.categoryNames[Lib.gameExpansion][category], "invalid category") + return CategoryIterator, category + end +end + +-- keep same API as DRData-1.0 for easier transitions +Lib.GetCategoryName = Lib.GetCategoryLocalization +Lib.IsPVE = Lib.IsPvECategory +Lib.NextDR = Lib.GetNextDR +Lib.GetSpellCategory = Lib.GetCategoryBySpellID +Lib.IterateSpells = Lib.IterateSpellsByCategory +Lib.RESET_TIME = Lib.resetTimes[Lib.gameExpansion].default +Lib.pveDR = Lib.categoriesPvE diff --git a/Libs/DRList-1.0/DRList-1.0.toc b/Libs/DRList-1.0/DRList-1.0.toc new file mode 100644 index 0000000..30cf4f5 --- /dev/null +++ b/Libs/DRList-1.0/DRList-1.0.toc @@ -0,0 +1,23 @@ +## Interface: 90205 +## Interface-Classic: 11402 +## Interface-BCC: 20504 +## Interface-Wrath: 30400 +## Title: Lib: DRList-1.0 +## Version: @project-version@ +## X-Category: Library +## X-License: MIT +## X-Curse-Project-ID: 315757 +## X-Wago-ID: 9rN4BxKD + +#@no-lib-strip@ +libs\LibStub\LibStub.lua +#@end-no-lib-strip@ + +DRList-1.0.xml +#@do-not-package@ +tests\engine.lua +tests\test-retail.lua +tests\test-classic.lua +tests\test-tbc.lua +tests\test-wotlk.lua +#@end-do-not-package@ diff --git a/Libs/DRList-1.0/DRList-1.0.xml b/Libs/DRList-1.0/DRList-1.0.xml new file mode 100644 index 0000000..2ab1f09 --- /dev/null +++ b/Libs/DRList-1.0/DRList-1.0.xml @@ -0,0 +1,4 @@ + +