vanilla-wow-addons – Rev 1
?pathlinks?
--[[---------------------------------------------------------------------------------
This is a table of ranks, which rank of which buff spell has a required level
----------------------------------------------------------------------------------]]
local L = AceLibrary:GetInstance("AceLocale-2.0"):new("Clique")
local buff_lookup = {
-- Buff lookups
[L"BUFF_PWF"] = {1,12,24,36,48,60},
[L"BUFF_PWS"] = {6,12,18,24,30,36,42,48,54,60},
[L"BUFF_SP"] = {30,42,56},
[L"BUFF_DS"] = {30,40,50,60},
[L"BUFF_RENEW"] = {8,14,20,26,32,38,44,50,56,60},
[L"BUFF_MOTW"] = {1,10,20,30,40,50,60},
[L"BUFF_THORNS"] = {6,14,24,34,44,54},
[L"BUFF_REJUVENATION"] = {4,10,16,22,28,34,40,46,52,58,60},
[L"BUFF_REGROWTH"] = {12,18,24,30,36,42,48,54,60},
[L"BUFF_AI"] = {1,14,28,42,56},
[L"BUFF_DM"] = {12,24,34,48,60},
[L"BUFF_AM"] = {18,30,42,54},
[L"BUFF_BOM"] = {4,12,22,32,42,52,60},
[L"BUFF_BOP"] = {10,24,38},
[L"BUFF_BOW"] = {14,24,34,44,54,60},
[L"BUFF_BOS"] = {20,30,40,50,60},
[L"BUFF_BOL"] = {40,50,60},
[L"BUFF_BOSFC"] = {46,54},
}
local cure_lookup = {
-- Cure lookups
[L"CURE_CURE_DISEASE"] = {"Disease"},
[L"CURE_ABOLISH_DISEASE"] = {"Disease"},
[L"CURE_PURIFY"] = {"Disease", "Poison"},
[L"CURE_CLEANSE"] = {"Disease", "Poison", "Magic"},
[L"CURE_DISPEL_MAGIC"] = {"Magic"},
[L"CURE_CURE_POISON"] = {"Poison"},
[L"CURE_ABOLISH_POISON"] = {"Poison"},
[L"CURE_REMOVE_LESSER_CURSE"] = {"Curse"},
[L"CURE_REMOVE_CURSE"] = {"Curse"},
["Disease"] = {
L"CURE_ABOLISH_DISEASE",
L"CURE_CURE_DISEASE",
L"CURE_CLEANSE",
L"CURE_PURIFY",
},
["Poison"] = {
L"CURE_ABOLISH_POISON",
L"CURE_CURE_POISON",
L"CURE_CLEANSE",
L"CURE_PURIFY",
},
["Magic"] = {
L"CURE_DISPEL_MAGIC",
L"CURE_CLEANSE",
},
["Curse"] = {
L"CURE_REMOVE_LESSER_CURSE",
L"CURE_REMOVE_CURSE",
},
}
local dual_lookup = {
-- Any spell that can be cast on friendly or hostile units
[L"DUAL_HOLY_SHOCK"] = true,
[L"DUAL_MIND_VISION"] = true,
[L"CURE_DISPEL_MAGIC"] = true,
}
--[[---------------------------------------------------------------------------------
Register all of our utility functions
----------------------------------------------------------------------------------]]
function Clique:RegUtilFuncs()
self:RegisterCustomFunction("Clique:CastSpell(\"spell\")", "Clique:CastSpell(\"spell\")", "Casts a spell on Clique.unit without changing targets")
self:RegisterCustomFunction("Clique:IsBuffActive(\"buff\")", "Clique:IsBuffActive(\"buff\")", "Checks whether a buff or debuff is active on Clique.unit")
self:RegisterCustomFunction("Clique:UnitMenu()", "Clique:UnitMenu()", "Pops up the unit menu for Clique.unit")
self:RegisterCustomFunction("Clique:CureAny()", "Clique:CureAny()", "Attempts to cure any ailments on Clique.unit")
self:RegisterCustomFunction("Clique:NewSpell(\"spell\", \"buff\")", "Clique:NewSpell(\"spell\", \"buff\")", "Casts a spell if a given buff is NOT on a target")
self:RegisterCustomFunction("Clique:TargetUnit()", "Clique:TargetUnit()", "Targets the unit you clicked on.")
self:RegisterCustomFunction("Clique:AssistUnit()", "Clique:AssistUnit()", "Assists the unit you clicked on.")
end
--[[---------------------------------------------------------------------------------
Scans the spellbook to determine which buffs/cures we know
----------------------------------------------------------------------------------]]
function Clique:ScanSpellbook()
self:LevelDebug(2, "Clique:ScanSpellbok()")
local tabs = GetNumSpellTabs()
local name,texture,start,offset = GetSpellTabInfo(tabs)
local numspells = start + offset
self.spellbook = self:ClearTable(self.spellbook)
self.spellbook.buffs = buff_lookup
-- ace:print("Scanning " .. tabs .. " tabs for spells.")
for i=1,numspells do
local name,rank = GetSpellName(i, BOOKTYPE_SPELL)
-- ace:print("** Scanning spell id: " .. i .. " found " .. name .. ".")
local _,_,numrank = string.find(rank, L"RANK" .. " (%d+)")
numrank = tonumber(numrank)
if buff_lookup[name] or cure_lookup[name] then
if numrank then
self.spellbook[name] = numrank
else
self.spellbook[name] = true
end
end
if dual_lookup[name] and numrank then
local spell = string.format("%s(%s %d)", name, L"RANK", numrank)
dual_lookup[spell] = true
end
end
end
function Clique:IsDualSpell(spell)
return dual_lookup[spell]
end
--[[---------------------------------------------------------------------------------
IsBuffActive() - Simple enough
----------------------------------------------------------------------------------]]
function Clique:IsBuffActive(spell, unit)
if not unit then unit = Clique.unit end
if not UnitExists(unit) then return end
if string.find(spell, "Interface\\Icons\\") then
for i=1,32 do
local texture = UnitBuff(unit, i)
if texture == spell then return true end
end
for i=1,16 do
local texture = UnitDebuff(unit, i)
if texture == spell then return true end
end
return false
end
if not self.tooltip then
local tt = CreateFrame("GameTooltip", "CliqueTooltip", nil, "GameTooltipTemplate")
tt:SetOwner(tt, "ANCHOR_NONE")
tt.name = CliqueTooltipTextLeft1
self.tooltip = tt
end
-- Check buffs
for i=1,32 do
if not UnitBuff(unit, i) then return nil end
self.tooltip:ClearLines()
self.tooltip:SetUnitBuff(unit, i)
if string.find(self.tooltip.name:GetText(), spell) then
return i
end
end
-- Check debuffs
for i=1,32 do
if not UnitDebuff(unit, i) then return nil end
self.tooltip:ClearLines()
self.tooltip:SetUnitDebuff(unit, i)
if string.find(self.tooltip.name:GetText(), spell) then
return i
end
end
return false
end
function Clique:IsBuff(name)
return buff_lookup[name]
end
function Clique:BuffTest(name, rank, unit)
if not self:IsBuff(name) then return end
local level = UnitLevel(unit)
return (buff_lookup[name][rank] - 10) <= level
end
--[[---------------------------------------------------------------------------------
Handles the "smart buff" casting, determining which rank of a specified
spell to cast on the given unit (based on level restrictions)
----------------------------------------------------------------------------------]]
function Clique:BestRank(name, unit)
-- If we don't know the spell
if not unit then unit = Clique.unit end
if not self.spellbook[name] or not buff_lookup[name] or not UnitExists(unit) then return end
local level = UnitLevel(unit)
local maxrank = self.spellbook[name]
local castrank = nil
-- Make sure we don't go beyond the rank we currently know
for i=1,maxrank do
if self:BuffTest(name, i, unit) then
castrank = i
end
end
if castrank then
self:LevelDebug(3, "Trying to cast: %s(%s %d)", name, L"RANK", castrank)
Clique:CastSpell(string.format("%s(%s %d)", name, L"RANK", castrank), unit)
return castrank
end
return true
end
--[[---------------------------------------------------------------------------------
This is a small unitID cache on unit names which returns the friendly unitID
of a specified unit. This helps to convert raid2targettarget into the more
friendly (and usable) raid14 allowing us to click-cast without changing
targets.
----------------------------------------------------------------------------------]]
local unitCache = {}
local RAID_IDS = {}
local PARTY_IDS = {}
for i=1,MAX_RAID_MEMBERS do RAID_IDS[i] = "raid"..i end
for i=1,MAX_PARTY_MEMBERS do PARTY_IDS[i] = "party"..i end
function Clique:GetFriendlyUnit(unit)
local name = UnitName(unit)
local cache = unitCache[name]
--ace:print("Unit: " .. unit .. " Cache: " .. tostring(cache))
if cache then
if UnitName(cache) == name then
return cache
end
end
local unitID = nil
local num = GetNumRaidMembers()
local tbl
if not UnitIsUnit("player", unit) then
if num > 0 then
tbl = RAID_IDS
else
num = GetNumPartyMembers()
tbl = PARTY_IDS
end
for i=1,num do
local u = tbl[i]
if UnitIsUnit(u, unit) then
unitID = u
break
end
end
else
unitID = "player"
end
unitCache[name] = unitID
--ace:print("UnitID: " .. (tostring(unitID or unit)))
return unitID
end
--[[---------------------------------------------------------------------------------
Simple table re-use function. Prevents memory churn
----------------------------------------------------------------------------------]]
function Clique:ClearTable(tbl)
if not tbl then tbl = {} end
for k in pairs(tbl) do tbl[k] = nil end
table.setn(tbl, 0)
return tbl
end
--[[---------------------------------------------------------------------------------
Sets the tooltip OnEnter
----------------------------------------------------------------------------------]]
function Clique:SetTooltip(frame, text)
local func = function()
GameTooltip:SetOwner(frame, "ANCHOR_TOPLEFT")
GameTooltip:SetText(text)
GameTooltip:Show()
end
frame:SetScript("OnEnter", func)
frame:SetScript("OnLeave", function() GameTooltip:Hide() end)
end
--[[---------------------------------------------------------------------------------
Pops up the user menu
----------------------------------------------------------------------------------]]
function Clique:UnitMenu(unit)
local type,x = nil,nil
unit = unit or Clique.unit
if unit == "player" then
type = PlayerFrameDropDown
elseif unit == "target" then
type = TargetFrameDropDown
elseif unit == "pet" then
type = PetFrameDropDown
elseif string.find(unit, "party") then
_,_,x = string.find(unit, "(%d+)")
type = getglobal("PartyMemberFrame"..x.."DropDown")
elseif string.find(unit, "raid") then
_,_,x = string.find(unit, "(%d+)")
type = FriendsDropDown
this.unit = unit
this.name = UnitName(unit)
this.id = this:GetID()
FriendsDropDown.displayMode = "MENU"
FriendsDropDown.initialize = RaidFrameDropDown_Initialize
end
if x then this:SetID(x) end
if type then
type.unit = unit
type.name = UnitName(unit)
ToggleDropDownMenu(1, nil, type,"cursor")
return true
end
return true
end
--[[---------------------------------------------------------------------------------
Dispels the unit of any ailments you can cure
----------------------------------------------------------------------------------]]
function Clique:CureAny(unit)
unit = unit or Clique.unit
local ailments = Clique:ClearTable(self.work)
for i=1,16 do
local texture,stack,type = UnitDebuff(unit, i)
if not texture then break end
if type then
ailments[type] = true
end
end
if next(ailments) then
self:Debug("Checking ailments")
for type in pairs(ailments) do
self:Debug("Checking for type: " .. type)
for i,cure in pairs(cure_lookup[type]) do
self:Debug("Checking spell: " .. cure)
if self.spellbook[cure] then
self:Debug(cure)
Clique:CastSpell(cure, unit)
return cure
end
end
end
end
return true
end
function Clique:NewSpell(spell, buff)
if not Clique:IsBuffActive(buff or spell) then
if Clique:IsBuff(spell) then
Clique:BestRank(spell)
else
Clique:CastSpell(spell)
end
end
return true
end
function Clique:TargetUnit(unit)
if not unit then unit = Clique.unit end
TargetUnit(unit)
return true
end
function Clique:AssistUnit(unit)
if not unit then unit = Clique.unit end
AssistUnit(unit)
return true
end
Generated by GNU Enscript 1.6.5.90.