vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | |
2 | --[[ BestBuff 1.7 |
||
3 | |||
4 | Casts the best rank possible of various buffs on caster's target, |
||
5 | irregardless of caster or target level. |
||
6 | |||
7 | Configuration: /bestbuff |
||
8 | It will bring up a window to set options and define buffs. |
||
9 | Generally you will only need to do this once or very seldom. |
||
10 | |||
11 | There are now two ways to use BestBuff: |
||
12 | |||
13 | Old way: /script BestBuff(buff_name) |
||
14 | ie: /script BestBuff("Power Word: Fortitude") |
||
15 | |||
16 | New way: Go into /bestbuff config panel and check Enabled. |
||
17 | Any buff defined there on your action bars will automatically BestBuff. |
||
18 | |||
19 | This means if you have macros dedicated to casting BestBuff you can get |
||
20 | rid of them. Drag the spell from your spellbook to a hotkey and use it |
||
21 | there. |
||
22 | |||
23 | Self cast and spam which were previously turned on/off in the BestBuff() |
||
24 | function are now defined in the BestBuff settings. By default, buffs |
||
25 | have no notification and do not self cast. |
||
26 | |||
27 | To add/change/remove buffs, use the /bestbuff config panel. For more |
||
28 | permanent changes (in case you frequently lose SavedVariables.lua), |
||
29 | instructions are in the BestBuff_Defaults.lua. |
||
30 | |||
31 | To restore settings to default, use /bestbuff reset. |
||
32 | |||
33 | -- Gello |
||
34 | |||
35 | 3/29/06 - 1.10 tooltip changes |
||
36 | 7/24/05 - changed highest rank to highest rank user knows |
||
37 | 4/11/05 - removed BestBuff from UISpecialFrames |
||
38 | 4/1/05 - added UI config window, ability to auto-BestBuff from action bar, |
||
39 | saved buffs to SavedVariables.lua so users don't have to re-edit |
||
40 | for every update. |
||
41 | 3/22/05 - updated toc to 1300 |
||
42 | 3/18/05 - fixed a small bug causing excess spam |
||
43 | 3/17/05 - added switch to kill self cast, some cleanup and comments |
||
44 | 2/8/05 - initial release |
||
45 | |||
46 | ]] |
||
47 | |||
48 | BestBuff_Original_UseAction = nil; -- for hooking UseAction |
||
49 | |||
50 | --[[ Variables saved to SavedVariables.lua ]] |
||
51 | |||
52 | BB = {}; |
||
53 | BB.Buffs = {}; |
||
54 | BB.Enabled = 1; |
||
55 | BB.Population = 0; |
||
56 | BB.Selected = 0; |
||
57 | |||
58 | --[[ Original BestBuff() left mostly unchanged ]] |
||
59 | --[[ no squelch or self cast disable flags, they're in config options now ]] |
||
60 | |||
61 | function BestBuff(intended_buff) |
||
62 | |||
63 | local best_rank = 1; |
||
64 | local target_rank = 1; |
||
65 | local cast_rank = 1; |
||
66 | local which_buff = 0; |
||
67 | local x = 1; |
||
68 | local text = nil; |
||
69 | |||
70 | which_buff = nil; |
||
71 | |||
72 | -- intended_buff is the string passed to us by user, see if this is in the buffnames list |
||
73 | for x=1, table.getn(BB.Buffs), 1 do |
||
74 | if (BB.Buffs[x].Name == intended_buff) then |
||
75 | which_buff = x; |
||
76 | end |
||
77 | end |
||
78 | |||
79 | -- if it is in the list... |
||
80 | if which_buff then |
||
81 | |||
82 | -- see which is the player's best castable rank due to player's level |
||
83 | for x=1, table.getn(BB.Buffs[which_buff].Levels), 1 do |
||
84 | if (UnitLevel("player")>=tonumber(BB.Buffs[which_buff].Levels[x])) then |
||
85 | best_rank = x; |
||
86 | end |
||
87 | end |
||
88 | |||
89 | -- see which is the target's best rank due to target's level |
||
90 | if (UnitLevel("target")>0) then |
||
91 | for x=1, table.getn(BB.Buffs[which_buff].Levels), 1 do |
||
92 | if (UnitLevel("target")>=(tonumber(BB.Buffs[which_buff].Levels[x])-10)) then |
||
93 | target_rank = x; |
||
94 | end |
||
95 | end |
||
96 | else |
||
97 | target_rank = best_rank |
||
98 | end |
||
99 | |||
100 | -- if the target's best rank is greater than the caster's best rank, |
||
101 | -- (ie, target is much higher level) then the actual rank will be |
||
102 | -- the caster's best rank. |
||
103 | if best_rank < target_rank then |
||
104 | cast_rank = best_rank; |
||
105 | else |
||
106 | -- otherwise, choose the best rank for the target. |
||
107 | cast_rank = target_rank; |
||
108 | end |
||
109 | |||
110 | -- attempt the spell |
||
111 | BestBuff_CastSpellByName(intended_buff,"Rank "..cast_rank); |
||
112 | |||
113 | -- if spam is on and we have a friendly target, spam away |
||
114 | if BB.Buffs[which_buff].Notify==1 and UnitExists("target") then |
||
115 | text = "Casting "..intended_buff.."(Rank "..cast_rank..") on "..UnitName("target").."."; |
||
116 | end |
||
117 | |||
118 | -- If the spell didn't actually cast, and selfcasting not disabled, self cast it |
||
119 | if BB.Buffs[which_buff].SelfCast==1 and SpellIsTargeting() then |
||
120 | cast_rank = best_rank; |
||
121 | SpellTargetUnit("player"); |
||
122 | if BB.Buffs[which_buff].Notify==1 then |
||
123 | text = "Casting "..intended_buff.."(Rank "..cast_rank..") on yourself."; |
||
124 | end |
||
125 | end |
||
126 | |||
127 | else |
||
128 | -- if we're here it means the user asked for a buff not in the buffnames list |
||
129 | text = "Unable to cast "..intended_buff.."."; |
||
130 | end |
||
131 | |||
132 | -- if we gained a message to spam at some point, spam it |
||
133 | if text and DEFAULT_CHAT_FRAME then |
||
134 | DEFAULT_CHAT_FRAME:AddMessage(text); |
||
135 | end |
||
136 | |||
137 | end |
||
138 | |||
139 | |||
140 | --[[ BestBuff callback functions ]] |
||
141 | |||
142 | |||
143 | function BestBuff_OnLoad() |
||
144 | BestBuff_Original_UseAction = UseAction; |
||
145 | UseAction = BestBuff_New_UseAction; |
||
146 | this:RegisterEvent("VARIABLES_LOADED"); |
||
147 | end |
||
148 | |||
149 | function BestBuff_OnEvent() |
||
150 | |||
151 | if event=="VARIABLES_LOADED" then |
||
152 | BestBuffFrame:Hide(); |
||
153 | if BB.Population<1 then |
||
154 | BestBuff_PopulateBuffs() |
||
155 | end |
||
156 | if BB.Enabled then |
||
157 | BestBuffEnableCheckButton:SetChecked(1); |
||
158 | else |
||
159 | BestBuffEnableCheckButton:SetChecked(0); |
||
160 | end |
||
161 | SlashCmdList["BestBuffCOMMAND"] = BestBuff_SlashHandler; |
||
162 | SLASH_BestBuffCOMMAND1 = "/bestbuff"; |
||
163 | end |
||
164 | |||
165 | end |
||
166 | |||
167 | function BestBuff_SlashHandler(arg1) |
||
168 | |||
169 | if string.find(arg1,"reset") then |
||
170 | BestBuff_PopulateBuffs(); |
||
171 | end |
||
172 | |||
173 | BestBuff_Startup(); |
||
174 | BestBuff_ClearEntry(); |
||
175 | end |
||
176 | |||
177 | |||
178 | function BestBuff_New_UseAction(slot,arg2,onself) |
||
179 | |||
180 | local intended_buff; |
||
181 | local which_buff = nil; |
||
182 | local i; |
||
183 | |||
184 | if not BB.Enabled then |
||
185 | BestBuff_Original_UseAction(slot,arg2,onself); |
||
186 | else |
||
187 | BestBuffTooltip:SetOwner(UIParent,"ANCHOR_NONE") |
||
188 | BestBuffTooltip:SetAction(slot); |
||
189 | intended_buff = getglobal("BestBuffTooltipTextLeft1"):GetText(); |
||
190 | |||
191 | for i=1,table.getn(BB.Buffs) do |
||
192 | if BB.Buffs[i].Name == intended_buff then |
||
193 | which_buff = intended_buff; |
||
194 | end |
||
195 | end |
||
196 | |||
197 | if which_buff then |
||
198 | BestBuff(intended_buff); |
||
199 | else |
||
200 | BestBuff_Original_UseAction(slot,arg2,onself); |
||
201 | end |
||
202 | end |
||
203 | end |
||
204 | |||
205 | |||
206 | --[[ Helper functions ]] |
||
207 | |||
208 | -- CastSpellByName() won't work from within UseAction, use CastSpell instead |
||
209 | function BestBuff_CastSpellByName(spell_name,spell_rank) --intended_buff,"Rank "..cast_rank); |
||
210 | |||
211 | local id; |
||
212 | local i = 1; |
||
213 | local done = nil; |
||
214 | local name; |
||
215 | local rank; |
||
216 | local id = nil; |
||
217 | local intended_rank; |
||
218 | |||
219 | _,_,intended_rank = string.find(spell_rank,"(%d+)") |
||
220 | |||
221 | while not done do |
||
222 | name,rank = GetSpellName(i,BOOKTYPE_SPELL); |
||
223 | if not name then |
||
224 | done = true; |
||
225 | else |
||
226 | if name==spell_name then |
||
227 | _,_,rank = string.find(rank,"(%d+)") |
||
228 | if tonumber(rank)<=tonumber(intended_rank) then |
||
229 | id = i; |
||
230 | end |
||
231 | end |
||
232 | end |
||
233 | i = i+1; |
||
234 | end |
||
235 | |||
236 | if id then |
||
237 | CastSpell(id,BOOKTYPE_SPELL); |
||
238 | end |
||
239 | end |
||
240 | |||
241 | |||
242 | |||
243 | -- restore or initialize Buff to defaults |
||
244 | function BestBuff_PopulateBuffs() |
||
245 | |||
246 | BestBuffEnableCheckButton:SetChecked(0); |
||
247 | BB = {}; |
||
248 | BB.Buffs = {}; |
||
249 | BB.Enabled = false; |
||
250 | BB.Selected = 0; |
||
251 | BB.Population = 1; |
||
252 | foreach(BBDefaultBuffs,BestBuff_AddDefaultBuffs); |
||
253 | BestBuff_SortBuffs(); |
||
254 | end |
||
255 | function BestBuff_AddDefaultBuffs(arg1) |
||
256 | |||
257 | local i; |
||
258 | |||
259 | if arg1 then |
||
260 | BB.Buffs[BB.Population] = {}; |
||
261 | BB.Buffs[BB.Population].Name = arg1; |
||
262 | BB.Buffs[BB.Population].Notify = BBDefault_Notify; |
||
263 | BB.Buffs[BB.Population].SelfCast = BBDefault_SelfCast; |
||
264 | BB.Buffs[BB.Population].Levels = {}; |
||
265 | for i=1,table.getn(BBDefaultBuffs[arg1]) do |
||
266 | BB.Buffs[BB.Population].Levels[i] = BBDefaultBuffs[arg1][i]; |
||
267 | end |
||
268 | end |
||
269 | BB.Population = BB.Population + 1; |
||
270 | end |
||
271 | |||
272 | -- always sort buffs alphabetically by .Name |
||
273 | function BestBuff_SortBuffs() |
||
274 | |||
275 | local temp_buff = {}; |
||
276 | local changed = true; |
||
277 | |||
278 | if BB.Population>2 then |
||
279 | while changed do |
||
280 | changed = false; |
||
281 | for i=1,BB.Population-2 do |
||
282 | if BB.Buffs[i].Name > BB.Buffs[i+1].Name then |
||
283 | temp_buff = BB.Buffs[i]; |
||
284 | BB.Buffs[i] = BB.Buffs[i+1]; |
||
285 | BB.Buffs[i+1] = temp_buff; |
||
286 | changed = true; |
||
287 | end |
||
288 | end |
||
289 | end |
||
290 | end |
||
291 | end |
||
292 | |||
293 | |||
294 | function BestBuff_Debug() |
||
295 | |||
296 | local i; |
||
297 | local j; |
||
298 | local text; |
||
299 | |||
300 | DEFAULT_CHAT_FRAME:AddMessage("Population: "..BB.Population); |
||
301 | for i=1,table.getn(BB.Buffs) do |
||
302 | text = "Buff #"..i..": "..BB.Buffs[i].Name..": "; |
||
303 | for j=1,table.getn(BB.Buffs[i].Levels) do |
||
304 | text = text .. BB.Buffs[i].Levels[j] .. " "; |
||
305 | end |
||
306 | DEFAULT_CHAT_FRAME:AddMessage(text); |
||
307 | end |
||
308 | end |
||
309 | |||
310 | -- reset the lower "edit" area of the window |
||
311 | function BestBuff_ClearEntry() |
||
312 | |||
313 | BestBuffEditBox_OnEscapePressed(); |
||
314 | BestBuff_SortBuffs() |
||
315 | BB.Selected = 0; |
||
316 | BestBuffEditNameBox:SetText(""); |
||
317 | BestBuffEditLevelsBox:SetText(""); |
||
318 | BestBuffNotifyCheckButton:SetChecked(0); |
||
319 | BestBuffSelfCastCheckButton:SetChecked(0); |
||
320 | BestBuffList_Update(); |
||
321 | end |
||
322 | |||
323 | -- returns a string as levels separated by spaces |
||
324 | function BestBuff_LevelString(arg1) |
||
325 | |||
326 | local text = ""; |
||
327 | |||
328 | if BB.Buffs[arg1].Levels then |
||
329 | for i=1,table.getn(BB.Buffs[arg1].Levels) do |
||
330 | if i>1 then |
||
331 | text = text .. " "; |
||
332 | end |
||
333 | text = text .. BB.Buffs[arg1].Levels[i]; |
||
334 | end |
||
335 | end |
||
336 | |||
337 | return text; |
||
338 | end |
||
339 | |||
340 | function BestBuff_Startup() |
||
341 | BestBuffFrame:StopMovingOrSizing(); |
||
342 | BestBuffFrame:Show(); |
||
343 | end |
||
344 | |||
345 | |||
346 | --[[ Dialog control functions ]] |
||
347 | |||
348 | function BestBuff_OnMouseDown(arg1) |
||
349 | if arg1=="LeftButton" then |
||
350 | BestBuffFrame:StartMoving(); |
||
351 | end |
||
352 | end |
||
353 | |||
354 | function BestBuff_OnMouseUp(arg1) |
||
355 | if arg1=="LeftButton" then |
||
356 | BestBuffFrame:StopMovingOrSizing(); |
||
357 | end |
||
358 | end |
||
359 | |||
360 | function BestBuffCloseButton_OnClick() |
||
361 | |||
362 | BestBuff_ClearEntry(); |
||
363 | BestBuffFrame:Hide(); |
||
364 | end |
||
365 | |||
366 | function BestBuffNameButton_OnClick(arg1) |
||
367 | |||
368 | local index; |
||
369 | local item; |
||
370 | |||
371 | BestBuffEditBox_OnEscapePressed(); |
||
372 | |||
373 | index = arg1 + FauxScrollFrame_GetOffset(BestBuffScrollFrame) |
||
374 | |||
375 | if index==BB.Selected then |
||
376 | index = BB.Population; |
||
377 | BB.Selected = 0; |
||
378 | end |
||
379 | |||
380 | if index < BB.Population then |
||
381 | BB.Selected = index; |
||
382 | BestBuffEditNameBox:SetText(BB.Buffs[index].Name); |
||
383 | BestBuffEditLevelsBox:SetText(BestBuff_LevelString(index)); |
||
384 | BestBuffNotifyCheckButton:SetChecked(BB.Buffs[index].Notify); |
||
385 | BestBuffSelfCastCheckButton:SetChecked(BB.Buffs[index].SelfCast); |
||
386 | BestBuffList_Update(); |
||
387 | else |
||
388 | BestBuff_ClearEntry(); |
||
389 | end |
||
390 | end |
||
391 | |||
392 | function BestBuffEnableCheckButton_OnClick() |
||
393 | |||
394 | if BestBuffEnableCheckButton:GetChecked()==1 then |
||
395 | BB.Enabled = true; |
||
396 | else |
||
397 | BB.Enabled = false; |
||
398 | end |
||
399 | end |
||
400 | |||
401 | function BestBuffSelfCastCheckButton_OnClick() |
||
402 | |||
403 | if BB.Selected>0 then |
||
404 | BB.Buffs[BB.Selected].SelfCast = BestBuffSelfCastCheckButton:GetChecked(); |
||
405 | end |
||
406 | end |
||
407 | |||
408 | function BestBuffNotifyCheckButton_OnClick() |
||
409 | |||
410 | if BB.Selected>0 then |
||
411 | BB.Buffs[BB.Selected].Notify = BestBuffNotifyCheckButton:GetChecked(); |
||
412 | end |
||
413 | end |
||
414 | |||
415 | function BestBuffAddButton_OnClick() |
||
416 | |||
417 | local i; |
||
418 | local j; |
||
419 | local text; |
||
420 | local err_msg = ""; |
||
421 | |||
422 | text = BestBuffEditNameBox:GetText(); |
||
423 | |||
424 | for i=1,BB.Population-1 do |
||
425 | if text=="" or BB.Buffs[i].Name==text then |
||
426 | err_msg = "Can't add this buff.\nNew buffs must have a unique name."; |
||
427 | end |
||
428 | end |
||
429 | |||
430 | if err_msg~="" then |
||
431 | message(err_msg); |
||
432 | else |
||
433 | |||
434 | BB.Buffs[BB.Population] = {}; |
||
435 | BB.Buffs[BB.Population].Name = BestBuffEditNameBox:GetText(); |
||
436 | |||
437 | text = BestBuffEditLevelsBox:GetText(); |
||
438 | -- populate .Levels with numbers in text |
||
439 | BB.Buffs[BB.Population].Levels = {}; |
||
440 | j = 1; |
||
441 | for i in string.gfind(text,"(%d+)") do |
||
442 | BB.Buffs[BB.Population].Levels[j] = i; |
||
443 | j = j+1; |
||
444 | end |
||
445 | if j==1 then |
||
446 | BB.Buffs[BB.Population].Levels[1] = 1; |
||
447 | end |
||
448 | |||
449 | BB.Buffs[BB.Population].Notify = BestBuffNotifyCheckButton:GetChecked(); |
||
450 | |||
451 | BB.Buffs[BB.Population].SelfCast = BestBuffSelfCastCheckButton:GetChecked(); |
||
452 | |||
453 | table.setn(BB.Buffs,BB.Population); |
||
454 | BB.Population = BB.Population + 1; |
||
455 | |||
456 | BestBuff_ClearEntry(); |
||
457 | |||
458 | end |
||
459 | end |
||
460 | |||
461 | function BestBuffChangeButton_OnClick() |
||
462 | |||
463 | local item; |
||
464 | local i; |
||
465 | local j; |
||
466 | local text; |
||
467 | |||
468 | if BB.Selected>0 then |
||
469 | BB.Buffs[BB.Selected].Name = BestBuffEditNameBox:GetText(); |
||
470 | text = BestBuffEditLevelsBox:GetText(); |
||
471 | -- populate .Levels with numbers in text |
||
472 | BB.Buffs[BB.Selected].Levels = {}; |
||
473 | j = 1; |
||
474 | for i in string.gfind(text,"(%d+)") do |
||
475 | BB.Buffs[BB.Selected].Levels[j] = i; |
||
476 | j = j+1; |
||
477 | end |
||
478 | if j==1 then |
||
479 | BB.Buffs[BB.Selected].Levels[1] = 1; |
||
480 | end |
||
481 | BB.Buffs[BB.Selected].Notify = BestBuffNotifyCheckButton:GetChecked(); |
||
482 | BB.Buffs[BB.Selected].SelfCast = BestBuffSelfCastCheckButton:GetChecked(); |
||
483 | BestBuff_ClearEntry(); |
||
484 | end |
||
485 | end |
||
486 | |||
487 | function BestBuffDeleteButton_OnClick() |
||
488 | |||
489 | if BB.Selected>0 then |
||
490 | table.remove(BB.Buffs,BB.Selected); |
||
491 | BB.Population = BB.Population - 1; |
||
492 | BB.Selected = 0; |
||
493 | BestBuff_ClearEntry(); |
||
494 | end |
||
495 | end |
||
496 | |||
497 | function BestBuffEditBox_OnEscapePressed() |
||
498 | |||
499 | BestBuffEditNameBox:ClearFocus(); |
||
500 | BestBuffEditLevelsBox:ClearFocus(); |
||
501 | |||
502 | if BB.Selected>0 then |
||
503 | BestBuffEditNameBox:SetText(BB.Buffs[BB.Selected].Name); |
||
504 | BestBuffEditLevelsBox:SetText(BestBuff_LevelString(BB.Selected)); |
||
505 | end |
||
506 | end |
||
507 | |||
508 | function BestBuffList_Update() |
||
509 | |||
510 | local index; |
||
511 | local i; |
||
512 | local itemText; |
||
513 | local itemButton; |
||
514 | |||
515 | FauxScrollFrame_Update(BestBuffScrollFrame, BB.Population-1, 8, 8); |
||
516 | |||
517 | for i=1,8 do |
||
518 | index = i + FauxScrollFrame_GetOffset(BestBuffScrollFrame); |
||
519 | itemButton = getglobal("BestBuffName"..i); |
||
520 | itemText = getglobal("BestBuffName"..i.."_Text"); |
||
521 | if (index<BB.Population) then |
||
522 | itemText:SetText(BB.Buffs[index].Name); |
||
523 | itemText:Show(); |
||
524 | if index==BB.Selected then |
||
525 | itemButton:LockHighlight(); |
||
526 | else |
||
527 | itemButton:UnlockHighlight(); |
||
528 | end |
||
529 | else |
||
530 | itemText:Hide(); |
||
531 | itemButton:UnlockHighlight(); |
||
532 | end |
||
533 | end |
||
534 | end |
||
535 | |||
536 | |||
537 | --[[ BestBuff Tooltip/OnEnter functions ]] |
||
538 | |||
539 | function BestBuff_Tooltip(arg1,arg2) |
||
540 | |||
541 | GameTooltip_SetDefaultAnchor(GameTooltip,this); |
||
542 | GameTooltip:SetText(arg1); |
||
543 | GameTooltip:AddLine(arg2, .75, .75, .75, 1); |
||
544 | GameTooltip:Show(); |
||
545 | end |
||
546 | |||
547 | function BestBuffEnableCheckButton_OnEnter() |
||
548 | BestBuff_Tooltip("Enable Auto BestBuff","Checking this will allow BestBuff to alter the ranks of buffs cast directly from an action bar. This will not affect the /script BestBuff() macro command at all.\n\nThe buffs below will still be used for /script BestBuff()."); |
||
549 | end |
||
550 | |||
551 | function BestBuffSelfCastCheckButton_OnEnter() |
||
552 | BestBuff_Tooltip("Self cast this buff","Checking this will cause this buff to cast on you if it cannot cast on the current target."); |
||
553 | end |
||
554 | |||
555 | function BestBuffNotifyCheckButton_OnEnter() |
||
556 | BestBuff_Tooltip("Notify on casting this buff","Checking this will send a notification of the spell, rank and target to your main chat window when you cast this buff."); |
||
557 | end |
||
558 | |||
559 | function BestBuffAddButton_OnEnter() |
||
560 | BestBuff_Tooltip("Add this buff","Click here to add this buff to the potential buffs list."); |
||
561 | end |
||
562 | |||
563 | function BestBuffChangeButton_OnEnter() |
||
564 | BestBuff_Tooltip("Change this buff", "Click here to change the selected buff to the values entered above."); |
||
565 | end |
||
566 | |||
567 | function BestBuffDeleteButton_OnEnter() |
||
568 | BestBuff_Tooltip("Delete this buff", "Click here to delete the selected buff from the potential buffs list."); |
||
569 | end |
||
570 | |||
571 | function BestBuffEditNameBox_OnEnter() |
||
572 | BestBuff_Tooltip("Buff name", "This field is the exact cast-sensitive name of the buff as used by WoW. ie, Power Word: Fortitude"); |
||
573 | end |
||
574 | |||
575 | function BestBuffEditLevelsBox_OnEnter() |
||
576 | BestBuff_Tooltip("Buff levels", "This field is a list of the levels each rank of a buff is learned, separated by spaces. Each number corresponds to a rank.\n\nie, 1 12 24 means:\n(Rank 1) is learned at level 1\n(Rank 2) is learned at level 12\n(Rank 3) is learned at level 24"); |
||
577 | end |
||
578 | |||
579 | function HighestRank(spellname) |
||
580 | |||
581 | local rank = 0; |
||
582 | local foundspell,foundrank=""; |
||
583 | local i=1; |
||
584 | |||
585 | while foundspell do |
||
586 | foundspell, foundrank = GetSpellName(i,BOOKTYPE_SPELL); |
||
587 | i = i + 1; |
||
588 | _,_,foundrank=string.find(tostring(foundrank),"Rank (%d+)"); |
||
589 | foundrank = tonumber(foundrank); |
||
590 | if foundspell==spellname and foundrank and foundrank>rank then |
||
591 | rank = foundrank; |
||
592 | end |
||
593 | end |
||
594 | |||
595 | return rank; |
||
596 | end |