vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[---------------------------------------------------------------------------------
2 This is a table of ranks, which rank of which buff spell has a required level
3 ----------------------------------------------------------------------------------]]
4  
5 local L = AceLibrary:GetInstance("AceLocale-2.0"):new("Clique")
6  
7 local buff_lookup = {
8 -- Buff lookups
9 [L"BUFF_PWF"] = {1,12,24,36,48,60},
10 [L"BUFF_PWS"] = {6,12,18,24,30,36,42,48,54,60},
11 [L"BUFF_SP"] = {30,42,56},
12 [L"BUFF_DS"] = {30,40,50,60},
13 [L"BUFF_RENEW"] = {8,14,20,26,32,38,44,50,56,60},
14 [L"BUFF_MOTW"] = {1,10,20,30,40,50,60},
15 [L"BUFF_THORNS"] = {6,14,24,34,44,54},
16 [L"BUFF_REJUVENATION"] = {4,10,16,22,28,34,40,46,52,58,60},
17 [L"BUFF_REGROWTH"] = {12,18,24,30,36,42,48,54,60},
18 [L"BUFF_AI"] = {1,14,28,42,56},
19 [L"BUFF_DM"] = {12,24,34,48,60},
20 [L"BUFF_AM"] = {18,30,42,54},
21 [L"BUFF_BOM"] = {4,12,22,32,42,52,60},
22 [L"BUFF_BOP"] = {10,24,38},
23 [L"BUFF_BOW"] = {14,24,34,44,54,60},
24 [L"BUFF_BOS"] = {20,30,40,50,60},
25 [L"BUFF_BOL"] = {40,50,60},
26 [L"BUFF_BOSFC"] = {46,54},
27 }
28  
29 local cure_lookup = {
30 -- Cure lookups
31 [L"CURE_CURE_DISEASE"] = {"Disease"},
32 [L"CURE_ABOLISH_DISEASE"] = {"Disease"},
33 [L"CURE_PURIFY"] = {"Disease", "Poison"},
34 [L"CURE_CLEANSE"] = {"Disease", "Poison", "Magic"},
35 [L"CURE_DISPEL_MAGIC"] = {"Magic"},
36 [L"CURE_CURE_POISON"] = {"Poison"},
37 [L"CURE_ABOLISH_POISON"] = {"Poison"},
38 [L"CURE_REMOVE_LESSER_CURSE"] = {"Curse"},
39 [L"CURE_REMOVE_CURSE"] = {"Curse"},
40 ["Disease"] = {
41 L"CURE_ABOLISH_DISEASE",
42 L"CURE_CURE_DISEASE",
43 L"CURE_CLEANSE",
44 L"CURE_PURIFY",
45 },
46 ["Poison"] = {
47 L"CURE_ABOLISH_POISON",
48 L"CURE_CURE_POISON",
49 L"CURE_CLEANSE",
50 L"CURE_PURIFY",
51 },
52 ["Magic"] = {
53 L"CURE_DISPEL_MAGIC",
54 L"CURE_CLEANSE",
55 },
56 ["Curse"] = {
57 L"CURE_REMOVE_LESSER_CURSE",
58 L"CURE_REMOVE_CURSE",
59 },
60 }
61  
62 local dual_lookup = {
63 -- Any spell that can be cast on friendly or hostile units
64 [L"DUAL_HOLY_SHOCK"] = true,
65 [L"DUAL_MIND_VISION"] = true,
66 [L"CURE_DISPEL_MAGIC"] = true,
67 }
68  
69 --[[---------------------------------------------------------------------------------
70 Register all of our utility functions
71 ----------------------------------------------------------------------------------]]
72  
73 function Clique:RegUtilFuncs()
74 self:RegisterCustomFunction("Clique:CastSpell(\"spell\")", "Clique:CastSpell(\"spell\")", "Casts a spell on Clique.unit without changing targets")
75 self:RegisterCustomFunction("Clique:IsBuffActive(\"buff\")", "Clique:IsBuffActive(\"buff\")", "Checks whether a buff or debuff is active on Clique.unit")
76 self:RegisterCustomFunction("Clique:UnitMenu()", "Clique:UnitMenu()", "Pops up the unit menu for Clique.unit")
77 self:RegisterCustomFunction("Clique:CureAny()", "Clique:CureAny()", "Attempts to cure any ailments on Clique.unit")
78 self:RegisterCustomFunction("Clique:NewSpell(\"spell\", \"buff\")", "Clique:NewSpell(\"spell\", \"buff\")", "Casts a spell if a given buff is NOT on a target")
79 self:RegisterCustomFunction("Clique:TargetUnit()", "Clique:TargetUnit()", "Targets the unit you clicked on.")
80 self:RegisterCustomFunction("Clique:AssistUnit()", "Clique:AssistUnit()", "Assists the unit you clicked on.")
81 end
82  
83 --[[---------------------------------------------------------------------------------
84 Scans the spellbook to determine which buffs/cures we know
85 ----------------------------------------------------------------------------------]]
86  
87 function Clique:ScanSpellbook()
88 self:LevelDebug(2, "Clique:ScanSpellbok()")
89  
90 local tabs = GetNumSpellTabs()
91 local name,texture,start,offset = GetSpellTabInfo(tabs)
92 local numspells = start + offset
93  
94 self.spellbook = self:ClearTable(self.spellbook)
95 self.spellbook.buffs = buff_lookup
96  
97 -- ace:print("Scanning " .. tabs .. " tabs for spells.")
98 for i=1,numspells do
99 local name,rank = GetSpellName(i, BOOKTYPE_SPELL)
100 -- ace:print("** Scanning spell id: " .. i .. " found " .. name .. ".")
101 local _,_,numrank = string.find(rank, L"RANK" .. " (%d+)")
102 numrank = tonumber(numrank)
103  
104 if buff_lookup[name] or cure_lookup[name] then
105 if numrank then
106 self.spellbook[name] = numrank
107 else
108 self.spellbook[name] = true
109 end
110 end
111  
112 if dual_lookup[name] and numrank then
113 local spell = string.format("%s(%s %d)", name, L"RANK", numrank)
114 dual_lookup[spell] = true
115 end
116 end
117 end
118  
119 function Clique:IsDualSpell(spell)
120 return dual_lookup[spell]
121 end
122  
123 --[[---------------------------------------------------------------------------------
124 IsBuffActive() - Simple enough
125 ----------------------------------------------------------------------------------]]
126  
127 function Clique:IsBuffActive(spell, unit)
128 if not unit then unit = Clique.unit end
129 if not UnitExists(unit) then return end
130  
131 if string.find(spell, "Interface\\Icons\\") then
132 for i=1,32 do
133 local texture = UnitBuff(unit, i)
134 if texture == spell then return true end
135 end
136  
137 for i=1,16 do
138 local texture = UnitDebuff(unit, i)
139 if texture == spell then return true end
140 end
141  
142 return false
143 end
144  
145  
146 if not self.tooltip then
147 local tt = CreateFrame("GameTooltip", "CliqueTooltip", nil, "GameTooltipTemplate")
148 tt:SetOwner(tt, "ANCHOR_NONE")
149 tt.name = CliqueTooltipTextLeft1
150 self.tooltip = tt
151 end
152  
153 -- Check buffs
154 for i=1,32 do
155 if not UnitBuff(unit, i) then return nil end
156  
157 self.tooltip:ClearLines()
158 self.tooltip:SetUnitBuff(unit, i)
159 if string.find(self.tooltip.name:GetText(), spell) then
160 return i
161 end
162 end
163  
164 -- Check debuffs
165 for i=1,32 do
166 if not UnitDebuff(unit, i) then return nil end
167  
168 self.tooltip:ClearLines()
169 self.tooltip:SetUnitDebuff(unit, i)
170 if string.find(self.tooltip.name:GetText(), spell) then
171 return i
172 end
173 end
174 return false
175 end
176  
177 function Clique:IsBuff(name)
178 return buff_lookup[name]
179 end
180  
181 function Clique:BuffTest(name, rank, unit)
182 if not self:IsBuff(name) then return end
183  
184 local level = UnitLevel(unit)
185 return (buff_lookup[name][rank] - 10) <= level
186 end
187  
188 --[[---------------------------------------------------------------------------------
189 Handles the "smart buff" casting, determining which rank of a specified
190 spell to cast on the given unit (based on level restrictions)
191 ----------------------------------------------------------------------------------]]
192  
193 function Clique:BestRank(name, unit)
194 -- If we don't know the spell
195 if not unit then unit = Clique.unit end
196 if not self.spellbook[name] or not buff_lookup[name] or not UnitExists(unit) then return end
197  
198 local level = UnitLevel(unit)
199 local maxrank = self.spellbook[name]
200 local castrank = nil
201  
202 -- Make sure we don't go beyond the rank we currently know
203  
204 for i=1,maxrank do
205 if self:BuffTest(name, i, unit) then
206 castrank = i
207 end
208 end
209  
210 if castrank then
211 self:LevelDebug(3, "Trying to cast: %s(%s %d)", name, L"RANK", castrank)
212 Clique:CastSpell(string.format("%s(%s %d)", name, L"RANK", castrank), unit)
213 return castrank
214 end
215 return true
216 end
217  
218 --[[---------------------------------------------------------------------------------
219 This is a small unitID cache on unit names which returns the friendly unitID
220 of a specified unit. This helps to convert raid2targettarget into the more
221 friendly (and usable) raid14 allowing us to click-cast without changing
222 targets.
223 ----------------------------------------------------------------------------------]]
224  
225 local unitCache = {}
226 local RAID_IDS = {}
227 local PARTY_IDS = {}
228 for i=1,MAX_RAID_MEMBERS do RAID_IDS[i] = "raid"..i end
229 for i=1,MAX_PARTY_MEMBERS do PARTY_IDS[i] = "party"..i end
230  
231 function Clique:GetFriendlyUnit(unit)
232 local name = UnitName(unit)
233 local cache = unitCache[name]
234  
235 --ace:print("Unit: " .. unit .. " Cache: " .. tostring(cache))
236  
237 if cache then
238 if UnitName(cache) == name then
239 return cache
240 end
241 end
242  
243 local unitID = nil
244 local num = GetNumRaidMembers()
245  
246 local tbl
247 if not UnitIsUnit("player", unit) then
248 if num > 0 then
249 tbl = RAID_IDS
250 else
251 num = GetNumPartyMembers()
252 tbl = PARTY_IDS
253 end
254  
255 for i=1,num do
256 local u = tbl[i]
257 if UnitIsUnit(u, unit) then
258 unitID = u
259 break
260 end
261 end
262 else
263 unitID = "player"
264 end
265  
266 unitCache[name] = unitID
267  
268 --ace:print("UnitID: " .. (tostring(unitID or unit)))
269  
270 return unitID
271 end
272  
273 --[[---------------------------------------------------------------------------------
274 Simple table re-use function. Prevents memory churn
275 ----------------------------------------------------------------------------------]]
276  
277 function Clique:ClearTable(tbl)
278 if not tbl then tbl = {} end
279 for k in pairs(tbl) do tbl[k] = nil end
280 table.setn(tbl, 0)
281 return tbl
282 end
283  
284 --[[---------------------------------------------------------------------------------
285 Sets the tooltip OnEnter
286 ----------------------------------------------------------------------------------]]
287  
288 function Clique:SetTooltip(frame, text)
289 local func = function()
290 GameTooltip:SetOwner(frame, "ANCHOR_TOPLEFT")
291 GameTooltip:SetText(text)
292 GameTooltip:Show()
293 end
294  
295 frame:SetScript("OnEnter", func)
296 frame:SetScript("OnLeave", function() GameTooltip:Hide() end)
297 end
298  
299 --[[---------------------------------------------------------------------------------
300 Pops up the user menu
301 ----------------------------------------------------------------------------------]]
302  
303 function Clique:UnitMenu(unit)
304 local type,x = nil,nil
305 unit = unit or Clique.unit
306  
307 if unit == "player" then
308 type = PlayerFrameDropDown
309 elseif unit == "target" then
310 type = TargetFrameDropDown
311 elseif unit == "pet" then
312 type = PetFrameDropDown
313 elseif string.find(unit, "party") then
314 _,_,x = string.find(unit, "(%d+)")
315 type = getglobal("PartyMemberFrame"..x.."DropDown")
316 elseif string.find(unit, "raid") then
317 _,_,x = string.find(unit, "(%d+)")
318 type = FriendsDropDown
319 this.unit = unit
320 this.name = UnitName(unit)
321 this.id = this:GetID()
322 FriendsDropDown.displayMode = "MENU"
323 FriendsDropDown.initialize = RaidFrameDropDown_Initialize
324 end
325  
326 if x then this:SetID(x) end
327  
328 if type then
329 type.unit = unit
330 type.name = UnitName(unit)
331 ToggleDropDownMenu(1, nil, type,"cursor")
332 return true
333 end
334 return true
335 end
336  
337 --[[---------------------------------------------------------------------------------
338 Dispels the unit of any ailments you can cure
339 ----------------------------------------------------------------------------------]]
340  
341 function Clique:CureAny(unit)
342 unit = unit or Clique.unit
343 local ailments = Clique:ClearTable(self.work)
344  
345 for i=1,16 do
346 local texture,stack,type = UnitDebuff(unit, i)
347 if not texture then break end
348 if type then
349 ailments[type] = true
350 end
351 end
352 if next(ailments) then
353 self:Debug("Checking ailments")
354 for type in pairs(ailments) do
355 self:Debug("Checking for type: " .. type)
356 for i,cure in pairs(cure_lookup[type]) do
357 self:Debug("Checking spell: " .. cure)
358 if self.spellbook[cure] then
359 self:Debug(cure)
360 Clique:CastSpell(cure, unit)
361 return cure
362 end
363 end
364 end
365 end
366 return true
367 end
368  
369 function Clique:NewSpell(spell, buff)
370 if not Clique:IsBuffActive(buff or spell) then
371 if Clique:IsBuff(spell) then
372 Clique:BestRank(spell)
373 else
374 Clique:CastSpell(spell)
375 end
376 end
377 return true
378 end
379  
380 function Clique:TargetUnit(unit)
381 if not unit then unit = Clique.unit end
382 TargetUnit(unit)
383 return true
384 end
385  
386 function Clique:AssistUnit(unit)
387 if not unit then unit = Clique.unit end
388 AssistUnit(unit)
389 return true
390 end