From a83c1ad0c22445985a72d288c00ecaec91a14e39 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 15 Jun 2021 09:05:07 +0200 Subject: [PATCH 01/40] castbar enable/disable --- Modules/Castbar.lua | 104 ++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/Modules/Castbar.lua b/Modules/Castbar.lua index 824c187..9066c13 100644 --- a/Modules/Castbar.lua +++ b/Modules/Castbar.lua @@ -19,6 +19,7 @@ local Gladdy = LibStub("Gladdy") local L = Gladdy.L local AceGUIWidgetLSMlists = AceGUIWidgetLSMlists local Castbar = Gladdy:NewModule("Cast Bar", 70, { + castBarEnabled = true, castBarHeight = 20, castBarWidth = 160, castBarIconSize = 22, @@ -439,42 +440,41 @@ end --------------------------- function Castbar:JOINED_ARENA() - for i=1, Gladdy.curBracket do - local unit = "arena" .. i - local castBar = self.frames[unit] - castBar:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED") - castBar:RegisterEvent("UNIT_SPELLCAST_DELAYED") - castBar:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START") - castBar:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE") - castBar:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP") - castBar:RegisterUnitEvent("UNIT_SPELLCAST_START", unit) - castBar:RegisterUnitEvent("UNIT_SPELLCAST_STOP", unit) - castBar:RegisterUnitEvent("UNIT_SPELLCAST_FAILED", unit) - castBar:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", unit) - castBar:SetScript("OnEvent", Castbar.OnEvent) - castBar:SetScript("OnUpdate", Castbar.OnUpdate) - castBar.fadeOut = nil - self:CAST_STOP(unit) - --Castbar.OnEvent(castBar, "PLAYER_ENTERING_WORLD") + if Gladdy.db.castBarEnabled then + for i=1, Gladdy.curBracket do + local unit = "arena" .. i + local castBar = self.frames[unit] + castBar:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED") + castBar:RegisterEvent("UNIT_SPELLCAST_DELAYED") + castBar:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START") + castBar:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE") + castBar:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP") + castBar:RegisterUnitEvent("UNIT_SPELLCAST_START", unit) + castBar:RegisterUnitEvent("UNIT_SPELLCAST_STOP", unit) + castBar:RegisterUnitEvent("UNIT_SPELLCAST_FAILED", unit) + castBar:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", unit) + castBar:SetScript("OnEvent", Castbar.OnEvent) + castBar:SetScript("OnUpdate", Castbar.OnUpdate) + castBar.fadeOut = nil + self:CAST_STOP(unit) + --Castbar.OnEvent(castBar, "PLAYER_ENTERING_WORLD") + end end end function Castbar:ResetUnit(unit) local castBar = self.frames[unit] - castBar:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED") - castBar:UnregisterEvent("UNIT_SPELLCAST_DELAYED") - castBar:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_START") - castBar:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE") - castBar:UnregisterEvent("UNIT_SPELLCAST_CHANNEL_STOP") - castBar:UnregisterEvent("UNIT_SPELLCAST_START") - castBar:UnregisterEvent("UNIT_SPELLCAST_STOP") - castBar:UnregisterEvent("UNIT_SPELLCAST_FAILED") + castBar:UnregisterAllEvents() castBar:SetScript("OnEvent", nil) castBar:SetScript("OnUpdate", nil) castBar.fadeOut = nil self:CAST_STOP(unit) end +function Castbar:Reset() + self.test = nil +end + --------------------------- -- TEST @@ -482,25 +482,30 @@ end --------------------------- function Castbar:Test(unit) - local spell, _, icon, value, maxValue, event, endTime, startTime + self.test = true + if Gladdy.db.castBarEnabled then + local spell, _, icon, value, maxValue, event, endTime, startTime - if (unit == "arena2") then - spell, _, icon = GetSpellInfo(27072) - value, maxValue, event = 0, 40, "cast" - elseif (unit == "arena1") then - spell, _, icon = GetSpellInfo(27220) - endTime = GetTime() * 1000 + 60*1000 - startTime = GetTime() * 1000 - value = (endTime / 1000) - GetTime() - maxValue = (endTime - startTime) / 1000 - event = "channel" - elseif (unit == "arena3") then - spell, _, icon = GetSpellInfo(20770) - value, maxValue, event = 0, 60, "cast" - end + if (unit == "arena2") then + spell, _, icon = GetSpellInfo(27072) + value, maxValue, event = 0, 40, "cast" + elseif (unit == "arena1") then + spell, _, icon = GetSpellInfo(27220) + endTime = GetTime() * 1000 + 60*1000 + startTime = GetTime() * 1000 + value = (endTime / 1000) - GetTime() + maxValue = (endTime - startTime) / 1000 + event = "channel" + elseif (unit == "arena3") then + spell, _, icon = GetSpellInfo(20770) + value, maxValue, event = 0, 60, "cast" + end - if (spell) then - self:CAST_START(unit, spell, icon, value, maxValue, event) + if (spell) then + self:CAST_START(unit, spell, icon, value, maxValue, event) + end + else + self:CAST_STOP(unit) end end @@ -541,11 +546,17 @@ function Castbar:GetOptions() name = L["Cast Bar"], order = 2, }, + castBarEnabled = option({ + type = "toggle", + name = L["Enabled"], + desc = L["If test is running, type \"/gladdy test\" again"], + order = 3, + }), group = { type = "group", childGroups = "tree", name = L["Frame"], - order = 3, + order = 4, args = { barFrame = { type = "group", @@ -565,6 +576,7 @@ function Castbar:GetOptions() min = 0, max = 50, step = 1, + width = "full", }), castBarWidth = option({ type = "range", @@ -574,6 +586,7 @@ function Castbar:GetOptions() min = 0, max = 300, step = 1, + width = "full", }), headerTexture = { type = "header", @@ -614,6 +627,7 @@ function Castbar:GetOptions() min = 0.5, max = Gladdy.db.castBarHeight/2, step = 0.5, + width = "full", }), castBarBorderStyle = option({ type = "select", @@ -647,6 +661,7 @@ function Castbar:GetOptions() min = 0, max = 100, step = 1, + width = "full", }), headerBorder = { type = "header", @@ -723,6 +738,7 @@ function Castbar:GetOptions() order = 4, min = 1, max = 20, + width = "full", }), headerFormat = { type = "header", @@ -781,6 +797,7 @@ function Castbar:GetOptions() min = -400, max = 400, step = 0.1, + width = "full", }), castBarYOffset = option({ type = "range", @@ -789,6 +806,7 @@ function Castbar:GetOptions() min = -400, max = 400, step = 0.1, + width = "full", }), } }, From 7b0bf921c45408799e6207e19d680257ee5cb5e5 Mon Sep 17 00:00:00 2001 From: Sumsebrum Date: Tue, 15 Jun 2021 09:05:20 +0200 Subject: [PATCH 02/40] Range Check added --- Gladdy.toc | 2 + Libs/LibSpellRange-1.0/LibSpellRange-1.0.lua | 232 +++++++++++ Libs/LibSpellRange-1.0/README.md | 61 +++ Libs/LibSpellRange-1.0/lib.xml | 3 + Modules/RangeCheck.lua | 407 +++++++++++++++++++ embeds.xml | 1 + 6 files changed, 706 insertions(+) create mode 100644 Libs/LibSpellRange-1.0/LibSpellRange-1.0.lua create mode 100644 Libs/LibSpellRange-1.0/README.md create mode 100644 Libs/LibSpellRange-1.0/lib.xml create mode 100644 Modules/RangeCheck.lua diff --git a/Gladdy.toc b/Gladdy.toc index 21b3a2d..5c43168 100644 --- a/Gladdy.toc +++ b/Gladdy.toc @@ -35,4 +35,6 @@ Modules\XiconProfiles.lua Modules\Pets.lua Modules\ExportImport.lua Modules\CombatIndicator.lua +Modules\RangeCheck.lua +Modules\ShadowsightTimer.lua EventListener.lua diff --git a/Libs/LibSpellRange-1.0/LibSpellRange-1.0.lua b/Libs/LibSpellRange-1.0/LibSpellRange-1.0.lua new file mode 100644 index 0000000..56f7b72 --- /dev/null +++ b/Libs/LibSpellRange-1.0/LibSpellRange-1.0.lua @@ -0,0 +1,232 @@ +--- = Background = +-- Blizzard's IsSpellInRange API has always been very limited - you either must have the name of the spell, or its spell book ID. Checking directly by spellID is simply not possible. +-- Now, in Mists of Pandaria, Blizzard changed the way that many talents and specialization spells work - instead of giving you a new spell when leaned, they replace existing spells. These replacement spells do not work with Blizzard's IsSpellInRange function whatsoever; this limitation is what prompted the creation of this lib. +-- = Usage = +-- **LibSpellRange-1.0** exposes an enhanced version of IsSpellInRange that: +-- * Allows ranged checking based on both spell name and spellID. +-- * Works correctly with replacement spells that will not work using Blizzard's IsSpellInRange method alone. +-- +-- @class file +-- @name LibSpellRange-1.0.lua + +local major = "SpellRange-1.0" +local minor = 15 + +assert(LibStub, format("%s requires LibStub.", major)) + +local Lib = LibStub:NewLibrary(major, minor) +if not Lib then return end + +local tonumber = _G.tonumber +local strlower = _G.strlower +local wipe = _G.wipe +local type = _G.type + +local GetSpellTabInfo = _G.GetSpellTabInfo +local GetNumSpellTabs = _G.GetNumSpellTabs +local GetSpellBookItemInfo = _G.GetSpellBookItemInfo +local GetSpellBookItemName = _G.GetSpellBookItemName +local GetSpellLink = _G.GetSpellLink +local GetSpellInfo = _G.GetSpellInfo + +local IsSpellInRange = _G.IsSpellInRange +local SpellHasRange = _G.SpellHasRange + +-- isNumber is basically a tonumber cache for maximum efficiency +Lib.isNumber = Lib.isNumber or setmetatable({}, { + __mode = "kv", + __index = function(t, i) + local o = tonumber(i) or false + t[i] = o + return o +end}) +local isNumber = Lib.isNumber + +-- strlower cache for maximum efficiency +Lib.strlowerCache = Lib.strlowerCache or setmetatable( +{}, { + __index = function(t, i) + if not i then return end + local o + if type(i) == "number" then + o = i + else + o = strlower(i) + end + t[i] = o + return o + end, +}) local strlowerCache = Lib.strlowerCache + +-- Matches lowercase player spell names to their spellBookID +Lib.spellsByName_spell = Lib.spellsByName_spell or {} +local spellsByName_spell = Lib.spellsByName_spell + +-- Matches player spellIDs to their spellBookID +Lib.spellsByID_spell = Lib.spellsByID_spell or {} +local spellsByID_spell = Lib.spellsByID_spell + +-- Matches lowercase pet spell names to their spellBookID +Lib.spellsByName_pet = Lib.spellsByName_pet or {} +local spellsByName_pet = Lib.spellsByName_pet + +-- Matches pet spellIDs to their spellBookID +Lib.spellsByID_pet = Lib.spellsByID_pet or {} +local spellsByID_pet = Lib.spellsByID_pet + +-- Updates spellsByName and spellsByID +local function UpdateBook(bookType) + local max = 0 + for i = 1, GetNumSpellTabs() do + local _, _, offs, numspells, _, specId = GetSpellTabInfo(i) + if specId == 0 then + max = offs + numspells + end + end + + local spellsByName = Lib["spellsByName_" .. bookType] + local spellsByID = Lib["spellsByID_" .. bookType] + + wipe(spellsByName) + wipe(spellsByID) + + for spellBookID = 1, max do + local type, baseSpellID = GetSpellBookItemInfo(spellBookID, bookType) + + if type == "SPELL" or type == "PETACTION" then + local currentSpellName = GetSpellBookItemName(spellBookID, bookType) + local link = GetSpellLink(currentSpellName) + local currentSpellID = tonumber(link and link:gsub("|", "||"):match("spell:(%d+)")) + + -- For each entry we add to a table, + -- only add it if there isn't anything there already. + -- This prevents weird passives from overwriting real, legit spells. + -- For example, in WoW 7.3.5 the ret paladin mastery + -- was coming back with a base spell named "Judgement", + -- which was overwriting the real "Judgement". + -- Passives usually come last in the spellbook, + -- so this should work just fine as a workaround. + -- This issue with "Judgement" is gone in BFA because the mastery changed. + + if currentSpellName and not spellsByName[strlower(currentSpellName)] then + spellsByName[strlower(currentSpellName)] = spellBookID + end + if currentSpellID and not spellsByID[currentSpellID] then + spellsByID[currentSpellID] = spellBookID + end + + if type == "SPELL" then + -- PETACTION (pet abilities) don't return a spellID for baseSpellID, + -- so base spells only work for proper player spells. + local baseSpellName = GetSpellInfo(baseSpellID) + if baseSpellName and not spellsByName[strlower(baseSpellName)] then + spellsByName[strlower(baseSpellName)] = spellBookID + end + if baseSpellID and not spellsByID[baseSpellID] then + spellsByID[baseSpellID] = spellBookID + end + end + end + end +end + +-- Handles updating spellsByName and spellsByID +if not Lib.updaterFrame then + Lib.updaterFrame = CreateFrame("Frame") +end +Lib.updaterFrame:UnregisterAllEvents() +Lib.updaterFrame:RegisterEvent("SPELLS_CHANGED") + +local function UpdateSpells() + UpdateBook("spell") + UpdateBook("pet") +end + +Lib.updaterFrame:SetScript("OnEvent", UpdateSpells) +UpdateSpells() + +--- Improved spell range checking function. +-- @name SpellRange.IsSpellInRange +-- @paramsig spell, unit +-- @param spell Name or spellID of a spell that you wish to check the range of. The spell must be a spell that you have in your spellbook or your pet's spellbook. +-- @param unit UnitID of the spell that you wish to check the range on. +-- @return Exact same returns as http://wowprogramming.com/docs/api/IsSpellInRange +-- @usage +-- -- Check spell range by spell name on unit "target" +-- local SpellRange = LibStub("SpellRange-1.0") +-- local inRange = SpellRange.IsSpellInRange("Stormstrike", "target") +-- +-- -- Check spell range by spellID on unit "mouseover" +-- local SpellRange = LibStub("SpellRange-1.0") +-- local inRange = SpellRange.IsSpellInRange(17364, "mouseover") +function Lib.IsSpellInRange(spellInput, unit) + if isNumber[spellInput] then + local spell = spellsByID_spell[spellInput] + if spell then + return IsSpellInRange(spell, "spell", unit) + else + local spell = spellsByID_pet[spellInput] + if spell then + return IsSpellInRange(spell, "pet", unit) + end + end + else + local spellInput = strlowerCache[spellInput] + + local spell = spellsByName_spell[spellInput] + if spell then + return IsSpellInRange(spell, "spell", unit) + else + local spell = spellsByName_pet[spellInput] + if spell then + return IsSpellInRange(spell, "pet", unit) + end + end + + return IsSpellInRange(spellInput, unit) + end + +end + + +--- Improved SpellHasRange. +-- @name SpellRange.SpellHasRange +-- @paramsig spell +-- @param spell Name or spellID of a spell that you wish to check for a range. The spell must be a spell that you have in your spellbook or your pet's spellbook. +-- @return Exact same returns as http://wowprogramming.com/docs/api/SpellHasRange +-- @usage +-- -- Check if a spell has a range by spell name +-- local SpellRange = LibStub("SpellRange-1.0") +-- local hasRange = SpellRange.SpellHasRange("Stormstrike") +-- +-- -- Check if a spell has a range by spellID +-- local SpellRange = LibStub("SpellRange-1.0") +-- local hasRange = SpellRange.SpellHasRange(17364) +function Lib.SpellHasRange(spellInput) + if isNumber[spellInput] then + local spell = spellsByID_spell[spellInput] + if spell then + return SpellHasRange(spell, "spell") + else + local spell = spellsByID_pet[spellInput] + if spell then + return SpellHasRange(spell, "pet") + end + end + else + local spellInput = strlowerCache[spellInput] + + local spell = spellsByName_spell[spellInput] + if spell then + return SpellHasRange(spell, "spell") + else + local spell = spellsByName_pet[spellInput] + if spell then + return SpellHasRange(spell, "pet") + end + end + + return SpellHasRange(spellInput) + end + +end diff --git a/Libs/LibSpellRange-1.0/README.md b/Libs/LibSpellRange-1.0/README.md new file mode 100644 index 0000000..992f4ed --- /dev/null +++ b/Libs/LibSpellRange-1.0/README.md @@ -0,0 +1,61 @@ +# LibSpellRange-1.0 + +## Background + +Blizzard's `IsSpellInRange` API has always been very limited - you either must have the name of the spell, +or its spell book ID. Checking directly by spellID is simply not possible. +Now, since Mists of Pandaria, Blizzard changed the way that many talents and specialization spells work - +instead of giving you a new spell when leaned, they replace existing spells. These replacement spells do +not work with Blizzard's IsSpellInRange function whatsoever; this limitation is what prompted the creation of this lib. + +## Usage + +**LibSpellRange-1.0** exposes an enhanced version of IsSpellInRange that: + +* Allows ranged checking based on both spell name and spellID. +* Works correctly with replacement spells that will not work using Blizzard's IsSpellInRange method alone. + +### `SpellRange.IsSpellInRange(spell, unit)` - Improved `IsSpellInRange` + +#### Parameters + +- `spell` - Name or spellID of a spell that you wish to check the range of. The spell must be a spell that you have in your spellbook or your pet's spellbook. +- `unit` - UnitID of the spell that you wish to check the range on. + +#### Return value + +Exact same returns as [the built-in `IsSpellInRange`](http://wowprogramming.com/docs/api/IsSpellInRange.html) + +#### Usage + +``` lua +-- Check spell range by spell name on unit "target" +local SpellRange = LibStub("SpellRange-1.0") +local inRange = SpellRange.IsSpellInRange("Stormstrike", "target") + +-- Check spell range by spellID on unit "mouseover" +local SpellRange = LibStub("SpellRange-1.0") +local inRange = SpellRange.IsSpellInRange(17364, "mouseover") +``` + +### `SpellRange.SpellHasRange(spell)` - Improved `SpellHasRange` + +#### Parameters + +- `spell` - Name or spellID of a spell that you wish to check for a range. The spell must be a spell that you have in your spellbook or your pet's spellbook. + +#### Return value + +Exact same returns as [the built-in `SpellHasRange`](http://wowprogramming.com/docs/api/SpellHasRange.html) + +#### Usage + +``` lua +-- Check if a spell has a range by spell name +local SpellRange = LibStub("SpellRange-1.0") +local hasRange = SpellRange.SpellHasRange("Stormstrike") + +-- Check if a spell has a range by spellID +local SpellRange = LibStub("SpellRange-1.0") +local hasRange = SpellRange.SpellHasRange(17364) +``` diff --git a/Libs/LibSpellRange-1.0/lib.xml b/Libs/LibSpellRange-1.0/lib.xml new file mode 100644 index 0000000..1214c3c --- /dev/null +++ b/Libs/LibSpellRange-1.0/lib.xml @@ -0,0 +1,3 @@ + +