vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 SH_SMARTHEAL_VERSION= SH_SMARTHEAL.." "..SMARTHEAL_CURRENT_VERSION
2  
3 function SmartHeal:Init()
4  
5 -- Hook the UseAction function and backup original UseAction
6 SMARTHEAL_ORIG_USEACTION=UseAction;
7 UseAction = function(slot,arg1,onself) SmartHeal:UseAction(slot,arg1,onself); end;
8  
9 -- set slash command
10 SlashCmdList["SMARTHEAL"] = function(arg1) SmartHeal:SlashCmd(arg1); end;
11 SLASH_SMARTHEAL1 = "/smartheal";
12 SLASH_SMARTHEAL2 = "/smh";
13  
14 -- get realm and player name
15 SmartHeal.realmName=GetRealmName();
16 SmartHeal.playerName=UnitName("player");
17  
18  
19 --local _,_,large_version,small_version,release_version=string.find(SmartHeal_Version,"^(%d+)%.(%d+)%.?(%d*)");
20  
21 --if(not SmartHeal_Config['version'] or tonumber(SmartHeal_Config['version'])<tonumber(SMARTHEAL_CURRENT_VERSION)) then
22 -- SmartHeal_Config={}
23 --end
24  
25 SmartHeal_Config['version']=SMARTHEAL_CURRENT_VERSION
26  
27 -- set realm record in save file
28 if (not SmartHeal_Config[SmartHeal.realmName]) then
29 SmartHeal_Config[SmartHeal.realmName]={};
30 end
31  
32 -- set default settings for player if no record in save file
33 if (not SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName]) then
34 SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName]={};
35 SmartHeal.InitializeSave=1
36 end
37  
38 end
39  
40 function SmartHeal:InitMiniMapButton()
41  
42 local MinimapDefaultSettings=SmartHeal.default['minimapbutton']
43  
44 MinimapDefaultSettings.left = function() SH_OptionsFrame:Show() end
45 MinimapDefaultSettings.right = function() ScriptErrors:Hide() end
46  
47 MyMinimapButton:Create('SmartHeal',SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName]['minimapbutton'],MinimapDefaultSettings)
48  
49 end
50  
51 function SmartHeal:isActive()
52 return SmartHeal.active;
53 end
54  
55 function SmartHeal:setDefault(defaultOption)
56  
57 if(not defaultOption) then
58 for option in SmartHeal.default do
59  
60 if (type(SmartHeal.default[option])=="table") then
61  
62 local module=option
63 for option2,value in SmartHeal.default[module] do
64 SmartHeal:setConfig(option2,value,module);
65 end
66  
67 else
68 SmartHeal:setConfig(option,SmartHeal.default[option]);
69 end
70  
71 end
72 else
73 for i,option in defaultOption do
74  
75 if (type(SmartHeal.default[option])=="table") then
76  
77 local module=option
78 for option2,value in SmartHeal.default[module] do
79 SmartHeal:setConfig(option2,value,module);
80 end
81  
82 else
83 SmartHeal:setConfig(option,SmartHeal.default[option]);
84 end
85 end
86  
87 end
88  
89 end
90  
91 function SmartHeal:setConfig(option,value,module)
92  
93 if(not SmartHeal:isActive()) then return end
94  
95 if (value==nil) then value=false end
96  
97 if (module and module~="" and option and option~="") then
98  
99 if (not SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName][module]) then
100 SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName][module]={}
101 end
102  
103 SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName][module][option]=value;
104  
105  
106 else
107 if (option and option~="") then
108 SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName][option]=value;
109 end
110 end
111  
112 end
113  
114 function SmartHeal:getConfig(option,module)
115  
116 if(not SmartHeal:isActive()) then return end
117  
118 if (module) then
119  
120 local moduleConfig=SmartHeal:getConfig(module)
121 if(moduleConfig) then
122 return moduleConfig[option]
123 end
124  
125 else
126 if(SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName][option]~=nil) then
127 return SmartHeal_Config[SmartHeal.realmName][SmartHeal.playerName][option];
128 else
129 return
130 end
131 end
132 end
133  
134 function SmartHeal:SlashCmd(arg1)
135  
136 if (not SmartHeal:isActive()) then
137 SmartHeal:ErrorMsg(SH_IS_NOT_ACTIVE_CLASS)
138 return;
139 end;
140  
141 if(not SH_OptionsFrame:IsShown()) then
142 SH_OptionsFrame:Show()
143 end
144  
145 end
146  
147 function SmartHeal:doCast(spell,rank)
148  
149 if (not spell) then return; end;
150  
151 local spell_with_rank=spell;
152 SmartHeal.CastedSpell=spell;
153  
154 if (rank and rank~="") then
155 spell_with_rank=spell.."("..SH_RANK.." "..rank..")"
156 SmartHeal.CastedRank=rank;
157 end
158  
159 SmartHeal.CacheUnitId=SmartHeal:TargetUnitId()
160  
161 if (SmartHeal.selfCast==1) then SmartHeal.CacheUnitId="player" end
162  
163 CastSpellByName(spell_with_rank,SmartHeal.selfCast);
164  
165 SmartHeal.selfCast=nil
166  
167 end
168  
169 function SmartHeal:TargetUnitId()
170  
171 local targetunitId
172  
173 if (not UnitExists("target")) then
174 return
175 end
176  
177 if(UnitInRaid("target")) then
178  
179 for i=1,40 do
180 if UnitIsUnit("raid"..i,"target") then
181 targetunitId="raid"..i
182 break
183 end
184 end
185  
186 elseif(UnitInParty("target") and not UnitIsUnit("player","target")) then
187  
188 for i=1,4 do
189 if UnitIsUnit("party"..i,"target") then
190 targetunitId="party"..i
191 break
192 end
193 end
194  
195 elseif (UnitIsUnit("target","player")) then
196  
197 targetunitId="player"
198  
199 end
200  
201 return targetunitId
202  
203 end
204  
205 function SmartHeal:PlayerHasSpell(spell)
206  
207 local HasSpell=false
208 local i = 1
209 while true do
210 local sName , sRank = GetSpellName(i, BOOKTYPE_SPELL)
211 if not sName then
212 do break end
213 else
214 if (sName==spell) then
215 HasSpell=true
216 break
217 end
218 end
219  
220 i = i + 1
221 end
222  
223 return HasSpell;
224 end
225  
226 function SmartHeal:Cast(spell_fullname,ForceTarget)
227  
228  
229 local _,_,spell,rankCap=string.find(spell_fullname,"(.+)%("..SH_RANK.." (%d+)%)")
230  
231 if (not spell) then
232 spell=spell_fullname
233 end
234  
235 if (not SmartHeal:isActive()) then
236 SmartHeal:ErrorMsg(SH_IS_NOT_ACTIVE_CLASS)
237 return
238 end;
239  
240 if ( not SmartHeal:getConfig("enable") or spell=="" or not spell) then
241 return
242 end
243  
244 if (not SmartHeal.selfCast) then
245 SmartHeal.selfCast=SmartHeal:isSelfCast(spell)
246 if (IsAltKeyDown() and SmartHeal:getConfig("altselfcast")) then
247 SmartHeal.selfCast=1
248 elseif(SmartHeal.HotkeyMouseButton=="RightButton" and SmartHeal:getConfig("RClickHotKeySelfCast")) then
249 SmartHeal.selfCast=1
250 elseif (
251 --SmartHeal.selfCast==1 and not SmartHeal:getConfig("autoselfcast") or
252 ((UnitCanAttack("player","target") and ForceTarget))
253  
254 ) then
255 SmartHeal.selfCast=0
256 SmartHeal:doCast(spell,rankCap)
257 return
258 end
259 end
260  
261 local rank
262  
263 if (SmartHeal.buffList[spell]~=nil) then
264 SmartHeal.isBuff=true
265 SmartHeal.isHeal=false
266 rank=SmartHeal:buffRank(spell)
267 elseif (SmartHeal.spellList[spell]~=nil) then
268 SmartHeal.isBuff=false
269 SmartHeal.isHeal=true
270 rank=SmartHeal:healRank(spell)
271 else
272 SmartHeal:doCast(spell,rankCap)
273 end
274  
275 if (spell==SH_LESSER_GREATER_HEALS) then
276 if (rank<=3) then
277 spell=SH_LESSER_HEAL
278 elseif (rank<=7) then
279 spell=SH_HEAL
280 rank=rank-3
281 else
282 spell=SH_GREATER_HEAL
283 rank=rank-7
284 end
285 end
286  
287 if(rankCap) then
288 rank=min(rank,tonumber(rankCap))
289 end
290  
291 SmartHeal:doCast(spell,rank);
292 end
293  
294 function SmartHeal:healRank(spell)
295  
296 local SpellStats=SmartHeal.spellList[spell];
297  
298 local target="target";
299 if(SmartHeal.selfCast==1) then
300 target="player";
301 end
302  
303 local ignoreMana=false
304 if (UnitIsDead("player")) then ignoreMana=true end
305  
306 local maxrank=SmartHeal:SpellMaxRank(spell,ignoreMana)
307 if (not maxrank) then return end
308  
309 -- target max acceptable rank or optimal rank whichever is lower
310 local rank = min(SmartHeal:targetRank(target,spell),maxrank)
311  
312 if ( SpellStats.HoT==1
313 or (not UnitInParty(target) and not UnitInRaid(target) and not UnitIsUnit("player",target))
314 or (SmartHeal:ClickHeal_IsOverdrive()) -- overdrive mode ignore hp deficit
315 ) then
316  
317 if(SpellStats.HoT~=1) then
318 SmartHeal.HealedValue=SmartHeal:AdjustHealValue(spell,rank)
319 end
320  
321 return rank
322 end
323  
324 -- find the best spell rank for the health deficit
325 local hpDeficit=0;
326 local TotalHeal=0
327 local rank2=1
328 if (SpellStats.group==1) then
329 for i=1,4 do
330 hpDeficit=max(hpDeficit,UnitHealthMax("party"..i)-UnitHealth("party"..i));
331 end
332 hpDeficit=max(hpDeficit, (UnitHealthMax("player")-UnitHealth("player")) )
333 else
334 hpDeficit=UnitHealthMax(target)-UnitHealth(target);
335 end
336  
337  
338 for r=1,table.getn(SpellStats.value) do
339  
340 rank2=r
341 TotalHeal=SmartHeal:AdjustHealValue(spell,r)
342 if (TotalHeal>hpDeficit*SmartHeal:getConfig('overheal')/100) then
343 SmartHeal.HealedValue=TotalHeal
344 break
345 end
346  
347 end
348  
349 return min(rank,rank2)
350  
351 end
352  
353 function SmartHeal:isSelfCast(spell)
354  
355 if (not UnitExists("target") or not UnitIsFriend("target","player")) then
356 return 1
357 else
358 return 0
359 end
360  
361 end
362  
363 function SmartHeal:targetRank(target,spell)
364  
365 local targetRank=1;
366 local SpellStats
367  
368  
369 if (SmartHeal.isBuff) then
370 SpellStats=SmartHeal.buffList[spell];
371 elseif (SmartHeal.isHeal) then
372 SpellStats=SmartHeal.spellList[spell];
373 end
374  
375 -- find target acceptable rank
376 for i=table.getn(SpellStats.level),1,-1 do
377 if (UnitLevel(target)>=SpellStats.level[i]-10) then
378 targetRank=i;
379 break;
380  
381 end
382 end
383  
384 return targetRank
385 end
386  
387 function SmartHeal:AdjustHealValue(spell,rank)
388  
389 -- calculate bonus offsets
390 local EquipmentBonus=0
391 if (BonusScanner) then
392 EquipmentBonus=tonumber(BonusScanner:GetBonus("HEAL"))
393 end
394  
395 -- Adjust Talent
396 local talent_multiplier,talent_adder=SmartHeal:TalentAdjust(spell)
397  
398 local healvalue=(SmartHeal.spellList[spell].value[rank]*talent_multiplier)+talent_adder+(EquipmentBonus*SmartHeal:bonusAdjust(spell,rank));
399  
400 return healvalue or 0
401  
402 end
403  
404 function SmartHeal:UseAction(slot, arg2, onself)
405  
406 -- Hack to get the spell name
407 SmartHealSpellTooltip:SetAction(slot)
408 local spell = getglobal("SmartHealSpellTooltipTextLeft1"):GetText()
409 local rankTemp = getglobal("SmartHealSpellTooltipTextRight1"):GetText()
410 local _,rankCap
411 if(rankTemp) then
412 _,_,rankCap=string.find(rankTemp,"^"..SH_RANK.." (%d+)")
413 end
414  
415 SmartHeal.HotkeyMouseButton=arg1
416  
417 if ( (SmartHeal.spellList[spell]~=nil or SmartHeal.buffList[spell]~=nil)
418 and SmartHeal:getConfig("override") and SmartHeal:getConfig("enable")) then
419  
420 if (rankCap) then
421 SmartHeal:Cast(spell.."("..SH_RANK.." "..rankCap..")")
422 else
423 SmartHeal:Cast(spell)
424 end
425  
426 else
427  
428 SmartHeal.selfCast=onself
429  
430 -- Check for alt self cast
431 if (IsAltKeyDown() and SmartHeal:getConfig("altselfcast")) then
432 SmartHeal.selfCast=1
433  
434 elseif(SmartHeal.HotkeyMouseButton=="RightButton" and SmartHeal:getConfig("RClickHotKeySelfCast")) then
435  
436 SmartHeal.selfCast=1
437  
438 elseif( SmartHeal:isSelfCast(spell)==1 and SmartHeal:getConfig("autoselfcast") and
439 (SmartHeal.spellList[spell]~=nil or SmartHeal.buffList[spell]~=nil)
440  
441 ) then
442 SmartHeal.selfCast=1
443 end
444  
445 SmartHeal.CacheUnitId=SmartHeal:TargetUnitId()
446  
447 if (rankCap and SmartHeal.spellList[spell]~=nil and SmartHeal.spellList[spell].HoT~=1) then
448 SmartHeal.HealedValue=SmartHeal:AdjustHealValue(spell,tonumber(rankCap))
449 end
450  
451 -- do default button action if the spell is not listed in the healing spells list
452 SMARTHEAL_ORIG_USEACTION(slot, arg2, SmartHeal.selfCast)
453  
454 SmartHeal.selfCast=nil
455 end
456  
457  
458 end
459  
460 function SmartHeal:SpellMaxRank(spellname,ignoreMana)
461 local maxRank=1;
462 local manatooltip;
463 local spells={[1]=spellname}
464  
465 if(spellname==SH_LESSER_GREATER_HEALS) then
466 spells={[1]=SH_LESSER_HEAL, [4]=SH_HEAL, [8]=SH_GREATER_HEAL,}
467 end
468  
469  
470 for r,spell in spells do
471 local i = 1
472 while true do
473 local sName , sRank = GetSpellName(i, BOOKTYPE_SPELL)
474 if not sName then
475 do break end
476 elseif (sName==spells[r]) then
477 local _,_,rankNumber=string.find(sRank,"^"..SH_RANK.." (%d+)")
478 if (rankNumber and rankNumber~="") then
479 rankNumber=tonumber(rankNumber)
480 SmartHealSpellTooltip:SetSpell(i,BOOKTYPE_SPELL)
481 manatooltip = getglobal("SmartHealSpellTooltipTextLeft2"):GetText()
482 local _,_,mana=string.find(manatooltip,"^(%d+) "..SH_MANA);
483 if ((mana and UnitMana('player')>tonumber(mana)) or not mana or ignoreMana) then
484 maxRank=max(maxRank,rankNumber+(r-1))
485 end
486 else
487 return
488 end
489 end
490  
491 i = i + 1
492 end -- end of while loop
493 end -- end of for loop
494 return maxRank
495 end
496  
497 function SmartHeal:TalentAdjust(spell)
498  
499 local _, playerClass = UnitClass("player");
500 local rank
501 local multiplier_factor=1
502 local additional_factor=0;
503  
504 if (playerClass=="PRIEST") then
505  
506 -- Improved Renew (renew only) 5% per point
507 _, _, _, _, rank,_= GetTalentInfo(2,2);
508 if (spell==SH_RENEW) then multiplier_factor=multiplier_factor*(1+(rank*0.05)); end;
509  
510 -- Spiritual Healing (all healing) 2% per point
511 _, _, _, _, rank,_= GetTalentInfo(2,15);
512 multiplier_factor=multiplier_factor*(1+(rank*0.02));
513  
514 -- Spiritual Guidance (all healing) 5% per point, based on total spirit
515 _, _, _, _, rank,_= GetTalentInfo(2,14);
516  
517 local spirit=0;
518 if (BonusScanner) then
519 spirit=tonumber(BonusScanner:GetBonus("SPI"));
520 end
521  
522 additional_factor=additional_factor+spirit*(rank*0.05)
523  
524 elseif (playerClass=="PALADIN") then
525  
526 -- Healing Light (healing light and flash light) 4% per point
527 _, _, _, _, rank,_= GetTalentInfo(1,5);
528 if (spell==SH_HEALING_LIGHT or spell==SH_FLASH_OF_LIGHT) then multiplier_factor=multiplier_factor*(1+(rank*0.04)); end;
529  
530 elseif (playerClass=="DRUID") then
531  
532 -- Improved Rejuvenation (rejuvenation only) 5% per point
533 _, _, _, _, rank,_= GetTalentInfo(3,10);
534 if (spell==SH_REJUVENATION) then multiplier_factor=multiplier_factor*(1+(rank*0.05)); end;
535  
536 -- Gift of Nature (all healing spells) 2% per point
537 _, _, _, _, rank,_= GetTalentInfo(3,12);
538 multiplier_factor=multiplier_factor*(1+(rank*0.02));
539  
540 elseif (playerClass=="SHAMAN") then
541  
542 -- Purification 2% per point
543 _, _, _, _, rank,_= GetTalentInfo(3,10);
544 multiplier_factor=multiplier_factor*(1+(rank*0.02));
545  
546 end
547  
548 return multiplier_factor,additional_factor
549  
550 end
551  
552 function SmartHeal:bonusAdjust(spell,rank)
553  
554 local SpellStats=SmartHeal.spellList[spell];
555 local bonus=1;
556 local castTimeBonus=1;
557 local lowlevelBonus=1;
558 local HoTBonus=1;
559  
560 -- cast time discount, ActualBenefit = AdvertisedBenefit * (CastingTime / 3.5)
561 if (SpellStats.castTime[rank]<3.5 and SpellStats.value[rank]>0) then
562 castTimeBonus=SpellStats.castTime[rank]/3.5;
563 end
564  
565 -- Low level discount , EffectiveBonus = (1-((20-LevelLearnt)*0.0375))*AdvertisedBonus
566 if (SpellStats.level[rank]<20) then
567 lowlevelBonus=(1-((20-SpellStats.level[rank])*0.0375))
568 end
569  
570 -- Heal+HoT discount
571 if (SpellStats.HoTvalue~=nil) then
572 if (SpellStats.value[rank]>0 and SpellStats.HoTvalue[rank]>0) then
573 HoTBonus=SpellStats.value[rank]/(SpellStats.value[rank]+SpellStats.HoTvalue[rank])
574 end
575 end
576 bonus=bonus*castTimeBonus*lowlevelBonus*HoTBonus;
577  
578 return bonus;
579 end
580  
581 function SmartHeal:buffRank(spell)
582  
583 local BuffStats=SmartHeal.buffList[spell];
584 local targetRank=1;
585 local target="target";
586  
587 if(SmartHeal.selfCast==1) then
588 target="player";
589 end
590  
591 local maxrank=SmartHeal:SpellMaxRank(spell)
592  
593 if(not maxrank) then return end
594  
595 if (BuffStats.group==0) then -- target buff
596 targetRank=SmartHeal:targetRank(target,spell);
597  
598 elseif (BuffStats.group==1) then -- group member buff
599  
600 for i=1,4 do
601 targetRank=max(targetRank,SmartHeal:targetRank("party"..i,spell));
602 end
603  
604 targetRank=max(targetRank,SmartHeal:targetRank("player",spell));
605  
606 elseif (BuffStats.group==2) then -- paladin unit class blessings
607  
608 local _, targetClass = UnitClass(target);
609 local thisUnitClass;
610  
611 if SmartHeal:inRaid() then
612  
613 for i=1,40 do
614  
615 _, thisUnitClass = UnitClass("raid"..i);
616 if (thisUnitClass==targetClass) then
617 targetRank=max(targetRank,SmartHeal:targetRank("raid"..i,spell));
618 end
619  
620 end
621  
622 elseif SmartHeal:inParty() then
623  
624 for i=1,4 do
625  
626 _, thisUnitClass = UnitClass("party"..i);
627 if (thisUnitClass==targetClass) then
628 targetRank=max(targetRank,SmartHeal:targetRank("party"..i,spell));
629 end
630  
631 end
632 targetRank=max(targetRank,SmartHeal:targetRank("player",spell));
633  
634 end
635  
636 else
637 targetRank=SmartHeal:targetRank(target,spell); -- treat as target only buff
638 end
639  
640 -- target max acceptable rank or player max rank whichever is lower
641 return min(targetRank,maxrank);
642  
643 end
644  
645 function SmartHeal:inRaid()
646 if GetNumRaidMembers()>0 then
647 return true
648 else
649 return false
650 end
651 end
652  
653 function SmartHeal:inParty()
654 if GetNumPartyMembers()>0 then
655 return true
656 else
657 return false
658 end
659 end
660  
661 function SmartHeal:ErrorMsg(msg,r,g,b)
662 if (not r and not g and not b) then
663 r=1;g=0;b=0;
664 end
665 DEFAULT_CHAT_FRAME:AddMessage(msg,r,g,b);
666 end
667  
668 function SmartHeal:doDebug()
669  
670 SmartHeal:ErrorMsg("SmartHeal Casted: "..SmartHeal.CastedSpell.."(Rank "..SmartHeal.CastedRank..")")
671  
672 if (SMARTHEAL_HEALTABLE[SmartHeal.playerClass] ~= nil) then
673 SmartHeal_DebugMsg['talent']=SmartHeal:getAllTalent()
674 end
675  
676 end
677  
678 function SmartHeal:AlertHealer(arg1)
679  
680 if (not UnitExists("target") or not UnitIsFriend("player","target")) then
681 return
682 end
683  
684 local current_targetName=UnitName("target")
685  
686 local _,_,casterName,spell=string.find(arg1,"(.+) "..SH_BEGINS_TO_CAST.." (.+).")
687 if(not casterName or not spell) then return end
688  
689 TargetByName(casterName)
690  
691 if (UnitName("target")==casterName and UnitName("targettarget")==current_targetName) then
692  
693 local _, casterClass = UnitClass("target");
694  
695 if (UnitName("target")~= current_targetName) then
696 TargetLastTarget()
697 end
698  
699 local alert_msg=string.format(SH_ALERT_HEALER_MSG, casterName, spell, current_targetName);
700 local holdtime=UIERRORS_HOLD_TIME;
701 local casterspellList=SMARTHEAL_HEALTABLE[casterClass];
702  
703 if (casterspellList) then
704 local spellStats=casterspellList[spell];
705 if (spellStats) then
706 if (spellStats.castTime[1]) then
707 holdtime=spellStats.castTime[1]; -- take the rank 1 cast time as holdtime
708 end
709  
710 UIErrorsFrame:AddMessage(alert_msg, 0, 1.0, 0, 1.0, holdtime);
711 end
712  
713 end
714  
715 else
716  
717 if (UnitName("target")~= current_targetName) then
718 TargetLastTarget()
719 end
720 end
721  
722 end
723  
724 -- cannot stop cast onupdate after 1.10 , using warning alert instead
725 function SmartHeal:StopCasting_OnUpdate(arg1)
726  
727 --if (not SmartHeal.SpellIsCasting and not SmartHeal.SpellIsChanneling) then return end
728  
729 if (not SmartHeal.HealUnitId or not SmartHeal.DoExcessHealAlert or not SmartHeal:getConfig("excesshealalert")) then
730 return
731 end
732  
733 if (SmartHeal.SpellIsCasting) then
734 SmartHeal.timer=SmartHeal.timer-(arg1*1000)
735 end
736  
737 if(SmartHeal.timer<1000) then
738  
739 local hp_ratio=UnitHealth(SmartHeal.HealUnitId)/UnitHealthMax(SmartHeal.HealUnitId)*100
740  
741 if (hp_ratio>=SmartHeal:getConfig("excesshealalerttrigger")) then
742 UIErrorsFrame:AddMessage(SH_EXCESSIVE_HEALING_ALERT_MSG.." "..UnitName(SmartHeal.HealUnitId).."!!!", 1, 0, 1, 1.0,3);
743 end
744  
745 SmartHeal.DoExcessHealAlert=nil
746  
747 end
748  
749 end
750  
751 -- for debug purposes, use when talent tree is changed by Blizzard
752 function SmartHeal:getAllTalent()
753  
754 local _, playerClass = UnitClass("player");
755 local numTabs = GetNumTalentTabs();
756 local talent={}
757 talent[playerClass]={}
758 for t=1, numTabs do
759 local numTalents = GetNumTalents(t);
760 talent[playerClass][t]={}
761 for i=1, numTalents do
762 local nameTalent, _, _, _, currRank, maxRank= GetTalentInfo(t,i);
763 talent[playerClass][t][i]={name=nameTalent, rank=currRank,max=maxRank}
764 end
765 end
766  
767 return talent
768 end
769