/trunk/Stuf_Range
## Interface: 70300 |
## Interface: 80000 |
## Title: Stuf_Range |
## Author: TotalPackage |
## Notes: Displays estimate distance using LibRangeCheck-2.0. |
--[[ |
Name: LibRangeCheck-2.0 |
Revision: $Revision: 170 $ |
Revision: $Revision: 190 $ |
Author(s): mitch0 |
Website: http://www.wowace.com/projects/librangecheck-2-0/ |
Description: A range checking library based on interact distances and spell ranges |
--- LibRangeCheck-2.0 provides an easy way to check for ranges and get suitable range checking functions for specific ranges.\\ |
-- The checkers use spell and item range checks, or interact based checks for special units where those two cannot be used.\\ |
-- The lib handles the refreshing of checker lists in case talents / spells / glyphs change and in some special cases when equipment changes (for example some of the mage pvp gloves change the range of the Fire Blast spell), and also handles the caching of items used for item-based range checks.\\ |
-- The lib handles the refreshing of checker lists in case talents / spells change and in some special cases when equipment changes (for example some of the mage pvp gloves change the range of the Fire Blast spell), and also handles the caching of items used for item-based range checks.\\ |
-- A callback is provided for those interested in checker changes. |
-- @usage |
-- local rc = LibStub("LibRangeCheck-2.0") |
-- @class file |
-- @name LibRangeCheck-2.0 |
local MAJOR_VERSION = "LibRangeCheck-2.0" |
local MINOR_VERSION = tonumber(("$Revision: 170 $"):match("%d+")) + 100000 |
local MINOR_VERSION = tonumber(("$Revision: 190 $"):match("%d+")) + 100000 |
local lib, oldminor = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION) |
if not lib then |
local UpdateDelay = .5 |
local ItemRequestTimeout = 10.0 |
local FriendColor = 'ff22ff22' |
local HarmColor = 'ffff2222' |
-- interact distance based checks. ranges are based on my own measurements (thanks for all the folks who helped me with this) |
local DefaultInteractList = { |
[3] = 8, |
[2] = 9, |
-- [2] = 9, |
[4] = 28, |
} |
local InteractLists = { |
["Tauren"] = { |
[3] = 6, |
[2] = 7, |
-- [2] = 7, |
[4] = 25, |
}, |
["Scourge"] = { |
[3] = 7, |
[2] = 8, |
-- [2] = 8, |
[4] = 27, |
}, |
} |
local HarmSpells = {} |
FriendSpells["DEATHKNIGHT"] = { |
47541, -- ["Death Coil"], -- 40 |
} |
HarmSpells["DEATHKNIGHT"] = { |
47541, -- ["Death Coil"], -- 40 |
49576, -- ["Death Grip"], -- 30 |
} |
-- Items [Special thanks to Maldivia for the nice list] |
local FriendItems = { |
[5] = { |
[1] = { |
90175, -- Gin-Ji Knife Set -- doesn't seem to work for pets (always returns nil) |
}, |
[2] = { |
37727, -- Ruby Acorn |
}, |
[6] = { |
[3] = { |
42732, -- Everfrost Razor |
}, |
[4] = { |
129055, -- Shoe Shine Kit |
}, |
[5] = { |
8149, -- Voodoo Charm |
136605, -- Solendra's Compassion |
63427, -- Worgsaw |
}, |
[7] = { |
61323, -- Ruby Seeds |
}, |
[8] = { |
34368, -- Attuned Crystal Cores |
33278, -- Burning Torch |
[35] = { |
18904, -- Zorbin's Ultra-Shrinker |
}, |
[38] = { |
140786, -- Ley Spider Eggs |
}, |
[40] = { |
34471, -- Vial of the Sunwell |
}, |
[50] = { |
116139, -- Haunting Memento |
}, |
[55] = { |
74637, -- Kiryn's Poison Vial |
}, |
[60] = { |
32825, -- Soul Cannon |
37887, -- Seeds of Nature's Wrath |
[80] = { |
35278, -- Reinforced Net |
}, |
[90] = { |
133925, -- Fel Lash |
}, |
[100] = { |
41058, -- Hyldnir Harpoon |
}, |
[150] = { |
46954, -- Flaming Spears |
}, |
[200] = { |
75208, -- Rancher's Lariat |
}, |
} |
local HarmItems = { |
[5] = { |
[1] = { |
}, |
[2] = { |
37727, -- Ruby Acorn |
}, |
[6] = { |
[3] = { |
42732, -- Everfrost Razor |
}, |
[4] = { |
129055, -- Shoe Shine Kit |
}, |
[5] = { |
8149, -- Voodoo Charm |
136605, -- Solendra's Compassion |
63427, -- Worgsaw |
}, |
[7] = { |
61323, -- Ruby Seeds |
}, |
[8] = { |
34368, -- Attuned Crystal Cores |
33278, -- Burning Torch |
24269, -- Heavy Netherweave Net |
18904, -- Zorbin's Ultra-Shrinker |
}, |
[38] = { |
140786, -- Ley Spider Eggs |
}, |
[40] = { |
28767, -- The Decapitator |
}, |
[50] = { |
116139, -- Haunting Memento |
}, |
[55] = { |
74637, -- Kiryn's Poison Vial |
}, |
[60] = { |
32825, -- Soul Cannon |
37887, -- Seeds of Nature's Wrath |
[80] = { |
35278, -- Reinforced Net |
}, |
[90] = { |
133925, -- Fel Lash |
}, |
[100] = { |
33119, -- Malister's Frost Wand |
}, |
[150] = { |
46954, -- Flaming Spears |
}, |
[200] = { |
75208, -- Rancher's Lariat |
}, |
} |
-- This could've been done by checking player race as well and creating tables for those, but it's easier like this |
local GetTime = GetTime |
local HandSlotId = GetInventorySlotInfo("HandsSlot") |
local math_floor = math.floor |
local UnitIsVisible = UnitIsVisible |
-- temporary stuff |
end |
-- minRange should be nil if there's no minRange, not 0 |
local function addChecker(t, range, minRange, checker) |
local rc = { ["range"] = range, ["minRange"] = minRange, ["checker"] = checker } |
local function addChecker(t, range, minRange, checker, info) |
local rc = { ["range"] = range, ["minRange"] = minRange, ["checker"] = checker, ["info"] = info } |
for i = 1, #t do |
local v = t[i] |
if rc.range == v.range then return end |
local function createCheckerList(spellList, itemList, interactList) |
local res = {} |
if itemList then |
for range, items in pairs(itemList) do |
for i = 1, #items do |
local item = items[i] |
if GetItemInfo(item) then |
addChecker(res, range, nil, checkers_Item[item], "item:" .. item) |
break |
end |
end |
end |
end |
if spellList then |
for i = 1, #spellList do |
local sid = spellList[i] |
range = MeleeRange |
end |
if minRange then |
addChecker(res, range, minRange, checkers_SpellWithMin[spellIdx]) |
addChecker(res, range, minRange, checkers_SpellWithMin[spellIdx], "spell:" .. sid .. ":" .. tostring(name)) |
else |
addChecker(res, range, minRange, checkers_Spell[spellIdx]) |
addChecker(res, range, minRange, checkers_Spell[spellIdx], "spell:" .. sid .. ":" .. tostring(name)) |
end |
end |
end |
end |
if itemList then |
for range, items in pairs(itemList) do |
for i = 1, #items do |
local item = items[i] |
if GetItemInfo(item) then |
addChecker(res, range, nil, checkers_Item[item]) |
break |
end |
end |
end |
end |
if interactList and not next(res) then |
for index, range in pairs(interactList) do |
addChecker(res, range, nil, checkers_Interact[index]) |
addChecker(res, range, nil, checkers_Interact[index], "interact:" .. index) |
end |
end |
-- returns minRange, maxRange or nil |
local function getRange(unit, checkerList) |
local min, max = 0, nil |
for i = 1, #checkerList do |
local rc = checkerList[i] |
if not max or max > rc.range then |
if rc.minRange then |
local inRange, inMinRange = rc.checker(unit) |
if inMinRange then |
max = rc.minRange |
elseif inRange then |
min, max = rc.minRange, rc.range |
elseif min > rc.range then |
return min, max |
else |
return rc.range, max |
end |
elseif rc.checker(unit) then |
max = rc.range |
elseif min > rc.range then |
return min, max |
else |
return rc.range, max |
end |
local lo, hi = 1, #checkerList |
while lo <= hi do |
local mid = math_floor((lo + hi) / 2) |
local rc = checkerList[mid] |
if rc.checker(unit) then |
lo = mid + 1 |
else |
hi = mid - 1 |
end |
end |
return min, max |
if lo > #checkerList then |
return 0, checkerList[#checkerList].range |
elseif lo <= 1 then |
return checkerList[1].range, nil |
else |
return checkerList[lo].range, checkerList[lo - 1].range |
end |
end |
local function updateCheckers(origList, newList) |
-- << Public API |
--- The callback name that is fired when checkers are changed. |
-- @field |
-- returns the range estimate as a string |
-- deprecated, use :getRange(unit) instead and build your own strings |
-- (checkVisible is not used any more, kept for compatibility only) |
-- @param checkVisible if set to true, then a UnitIsVisible check is made, and **nil** is returned if the unit is not visible |
function lib:getRangeAsString(unit, checkVisible, showOutOfRange) |
local minRange, maxRange = self:getRange(unit) |
local minRange, maxRange = self:getRange(unit, checkVisible) |
if not minRange then return nil end |
if not maxRange then |
return showOutOfRange and minRange .. " +" or nil |
-- fall back to interact distance checks |
if playerClass == "HUNTER" or playerRace == "Tauren" then |
-- for hunters, use interact4 as it's safer |
-- for Taurens interact4 is actually closer than 25yd and interact2 is closer than 8yd, so we can't use that |
-- for Taurens interact4 is actually closer than 25yd and interact3 is closer than 8yd, so we can't use that |
minRangeCheck = checkers_Interact[4] |
else |
minRangeCheck = checkers_Interact[2] |
minRangeCheck = checkers_Interact[3] |
end |
end |
--- Get a range estimate as **minRange**, **maxRange**. |
-- @param unit the target unit to check range to. |
-- @param checkVisible if set to true, then a UnitIsVisible check is made, and **nil** is returned if the unit is not visible |
-- @return **minRange**, **maxRange** pair if a range estimate could be determined, **nil** otherwise. **maxRange** is **nil** if **unit** is further away than the highest possible range we can check. |
-- Includes checks for unit validity and friendly/enemy status. |
-- @usage |
-- local rc = LibStub("LibRangeCheck-2.0") |
-- local minRange, maxRange = rc:GetRange('target') |
function lib:GetRange(unit) |
-- local minRangeIfVisible, maxRangeIfVisible = rc:GetRange('target', true) |
function lib:GetRange(unit, checkVisible) |
if not UnitExists(unit) then |
return nil |
end |
if checkVisible and not UnitIsVisible(unit) then |
return nil |
end |
if UnitIsDeadOrGhost(unit) then |
return getRange(unit, self.miscRC) |
end |
self:scheduleInit() |
end |
function lib:GLYPH_ADDED() |
self:scheduleInit() |
end |
function lib:GLYPH_REMOVED() |
self:scheduleInit() |
end |
function lib:GLYPH_UPDATED() |
self:scheduleInit() |
end |
function lib:SPELLS_CHANGED() |
self:scheduleInit() |
end |
self.frame:Show() |
end |
-- << load-time initialization |
frame:RegisterEvent("LEARNED_SPELL_IN_TAB") |
frame:RegisterEvent("CHARACTER_POINTS_CHANGED") |
frame:RegisterEvent("PLAYER_TALENT_UPDATE") |
frame:RegisterEvent("GLYPH_ADDED") |
frame:RegisterEvent("GLYPH_REMOVED") |
frame:RegisterEvent("GLYPH_UPDATED") |
frame:RegisterEvent("SPELLS_CHANGED") |
local _, playerClass = UnitClass("player") |
if playerClass == "MAGE" or playerClass == "SHAMAN" then |