forked from XiconQoo/Gladdy-TBC
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
706 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<Ui> | ||
<Script file="LibSpellRange-1.0.lua"/> | ||
</Ui> |
Oops, something went wrong.