All pastes #386987 Raw Edit

Someone

public text v1 · immutable
·published 2007-03-09 00:40 UTC
rendered paste body
;Paladin Bot by FarmerBob (farming.bob@gmail.com)

#define ROUTINES
#define POTION1 "Lesser Healing Potion"
#define POTION2 "Healing Potion"
#define POTION3 "Minor Healing Potion"

#define DEBUGMODE TRUE

;WowScript[SelectGossipOption(1)]
;wait 20

; Emergency Situations. Potion Percent should be equal to
; or lower than Lay on Hands so that spell based (free)
; emergency gets fired first.
#define STUNHPPCT 45
#define EMERGENCYHPPCT 35
#define LAYONHANDSHPPCT 15
#define POTIONHPPCT 14

#define USEAURA "Devotion Aura"
; if healing use concentration aura... 
#define USECONCENTRATIONAURA FALSE

; If mob os below defined, attempt to finish with defined seal
#define USESEALFINISHER FALSE
#define SEALFINISHER "Seal of Righteousness"
#define MOBMAXHPPCT 15
#define MYMINMANAFORFINISHPCT 15

; Use Hammer of Justice to disrupt casting  TRUE/FALSE
#define DISRUPTCAST_HOJ TRUE

#define JUDGEMOBS TRUE
#define MYJUDGE "Seal of the Crusader"
#define MOBJUDGED "Judgement of the Crusader"
#define MYSEAL "Seal of Righteousness"

#define JUSTICERUNNERS TRUE

#define KEEPBLESSING "Blessing of Wisdom"
#define MINMANABLESS 40

#define HOLYSHOCKPULL FALSE
; if low on mana use blessing of wisdom till full mana... 
#define USEBOWISDOM TRUE
#define LOWMANABOW 50

; DOWNTIME Stuff...
; Attempt to heal rather than eat..  
#define HEALNOTEAT TRUE

; HEALING Stuff...
; Time to wait before casting another heal (in seconds)
#define TIMEBETWEENHEALS 5
#define LAYHANDSBELOW 15
; If we have multiple attackers force a shield.
#define USECONCENTRATION FALSE
#define USESHIELDBELOW 35
#define STUNHEAL TRUE
; If we need Blessing of Protection use it..
#define USEBOP TRUE
; If we need Divine Protection use it..
#define USEDP TRUE

function Pause(float delay)
{
  declare DelayTimer int local ${Math.Calc[${LavishScript.RunningTime}+(1000*${delay})]}
  while ${LavishScript.RunningTime}<${DelayTimer}
  {
    ; paused...  
    waitframe 
  }
}

function CastPaladinShield(bool ExtraAttacker, string AttackGUID)
{
  if ${Object[${AttackGUID}].Dead}
  {
    Return
  }
  echo "HoJ Cool:${Spell[Hammer of Justice].Cooldown}"
  if ${Spell[Hammer of Justice](exists)}&&STUNHEAL&&!${ExtraAttacker}&&${Me.PctHPs}>USESHIELDBELOW
  {
    if !${Spell[Hammer of Justice].Cooldown}
    {
      Target ${AttackGUID}
      Cast "Hammer of Justice"
      call GlobalCooldown
    }
  }
  if !${Me.Buff[Forbearance](exists)}&&${Me.PctHPs}<USESHIELDBELOW
  {
    if ${Spell[Blessing of Protection](exists)}
    {
      if !${Spell[Blessing of Protection].Cooldown}&&USEBOP
      {
	move backward
	wait 2
	move -stop backward
        Target ${Me.GUID}
        Cast "Blessing of Protection"
        Target ${AttackGUID}
        call EffectWait "Blessing of Protection" ${Me.GUID} 1
        call GlobalCooldown
      }
    }
  }
  elseif !${Me.Buff[Forbearance](exists)}&&${Me.PctHPs}<USESHIELDBELOW
  {
    if ${Spell[Divine Protection](exists)}
    {
      if !${Spell[Divine Protection].Cooldown}&&USEDP
      {
        Cast "Divine Protection"
        call EffectWait "Divine Protection" ${Me.GUID} 1
        call GlobalCooldown
      }
    }
  }
}

function HealPlayer(string AttackGUID)
{
  declare Aggros guidlist local
  declare GotExtraAttacker bool local FALSE

  Aggros:Search[-units,-nearest,-aggro,-alive,-range 0-10]

  if ${Aggros.Count}>1 
  {
    GotExtraAttacker:Set[TRUE]
  }
  Aggros:Clear

  ;call UpdateStats
  call GlobalCooldown
  if !${Me.Casting}&&(${Me.PctHPs}<${MinHealthPct})
  {
    echo "My Health = ${Me.PctHPs}<${MinHealthPct}"
    echo "LH Cool:${Spell[Lay on Hands].Cooldown}"
    if ${Me.PctHPs}<LAYHANDSBELOW && ${Spell[Lay on Hands](exists)}
    {
    	echo "LoH exists, and we want to use it"
      if !${Spell[Lay on Hands].Cooldown}
      {
      	echo "LoH isn't on cooldown, attempting cast"
        Target ${Me.GUID}
        Cast "Lay on Hands"
        Target ${AttackGUID}
        call GlobalCooldown
      }
      else
      {
      	echo "LoH on cooldown"
      }
    }
    else
    {
    	echo "Failed HP check or spell does not exist. HP: ${Me.PctHPs} LoH Pct: LAYHANDSBELOW LoH Exist: ${Spell[Lay on Hands](exists)}"
    call CastPaladinShield ${GotExtraAttacker} ${AttackGUID}
    }
    
    if ${Me.PctMana}<=10&&${Unit[${Me.GUID}].Level}>19&&!${Object[${AttackGUID}].Dead}
    {
      call UseBestFlashofLight
    }
    elseif !${Object[${AttackGUID}].Dead}
    {
      if ${Me.PctHPs}<30&&${Spell[Divine Favor](exists)}&&${Me.PctMana}>15
      {
        if ${Spell[Divine Favor](exists)}
        {
          if !${Spell[Divine Favor].Cooldown}
          {
            Cast "Divine Favor"
            call GlobalCooldown
          }
        }
      }
      call UseBestHolyLight
    }
  }
}

function CureMe(string RecipientGUID, string SpellName)
{
  declare OldTarget GUID ${Target.GUID}

  Target ${RecipientGUID}
  Cast ${SpellName}
  call GlobalCooldown
  Target ${OldTarget}
}

function CheckDebuff(string RecipientGUID)
{
  declare Cure bool local FALSE
  declare CureSpell string local "Purify"
   
  ; If I'm already casting something then don't do anything.
  if ${Me.Casting}
  {
     return
  }
  declare DebuffCounter int local 1
  call GlobalCooldown

  if ${Spell[Cleanse](exists)}
  {
    CureSpell:Set["Cleanse"]
  }

  if ${Spell[Purify](exists)}
  {
    do
    {   
      if ${Player[${RecipientGUID}].Buff[${DebuffCounter}].Harmful}
      {
         if ${Player[${RecipientGUID}].Buff[${DebuffCounter}].DispelType.Equal[Disease]}||${Player[${RecipientGUID}].Buff[${DebuffCounter}].DispelType.Equal[Poison]}
         {
    	   call CureMe ${RecipientGUID} ${CureSpell}
      	   Cure:Set[TRUE]
         }
         if ${Player[${RecipientGUID}].Buff[${DebuffCounter}].Mechanic.Equal[rooted]}&&${Spell[Blessing of Freedom](exists)}&&!${Cure}
         {
           ; If I am rooted, I want to use BoF instead of Cleanse since Cleanse requires 6% Mana to case, BoF requires 76   
           call UpdateHudStatus "Action=${Player[${RecipientGUID}].Buff[${DebuffCounter}].Action}"
           call UpdateHudStatus "Mechanic=${Player[${RecipientGUID}].Buff[${DebuffCounter}].Mechanic}"
           if !${Spell[Blessing of Freedom].Cooldown}
           {  
    	     call CureMe ${RecipientGUID} "Blessing of Freedom"
      	     Cure:Set[TRUE]
           }
         }
         if ${Spell[Cleanse](exists)}
         {
           if ${Player[${RecipientGUID}].Buff[${DebuffCounter}].DispelType.Equal[Magic]}
           {
    	     call CureMe ${RecipientGUID} ${CureSpell}
      	     Cure:Set[TRUE]
           }
         }
       }
       DebuffCounter:Inc
     }
     while ${DebuffCounter}<57&&${Player[${RecipientGUID}].Buff[${DebuffCounter}](exists)}&&!${Cure}
   }
   return ${Cure}
} 


function DrinkPotion()
{
	if ${Item[POTION1].StackCount} && !${Item[POTION1].Cooldown}
	{
		use ${Item[POTION1].GUID}
	}
	else 
	if ${Item[POTION2].StackCount} && !${Item[POTION2].Cooldown}
	{
		use ${Item[POTION2].GUID}
	}
	else 
	if ${Item[POTION3].StackCount} && !${Item[POTION3].Cooldown}
	{
		use ${Item[POTION3].GUID}
	}
}

function RoamPrep()
{
  if ${Me.CurrentHPs}>1
  {
    while ${Me.Casting}
    {
      call Pause 1
    } 
    if ${Spell[Summon Warhorse](exists)}
    {
      if !${Me.Buff[Summon Warhorse](exists)}
      {
        wowpress -release moveforward
        wowpress -release movebackward
        call Pause 1
        Cast "Summon Warhorse"
        call EffectWait "Summon Warhorse" ${Me.GUID} 4
        call GlobalCooldown
      }
    }
  }
}

function LootPrep()
{
    if ${Me.Buff[Summon Warhorse](exists)}
    {
      WoWScript Dismount()
      call GlobalCooldown
      ;call Pause 1
    }
}

function CombatPrep()
{
    if ${Me.Buff[Summon Warhorse](exists)}
    {
      WoWScript Dismount()
      call GlobalCooldown
      ;call Pause 1
    }
	if !${Me.Buff[USEAURA](exists)}
	{
      Cast USEAURA
    }
    ; Make sure we have our Aura running.  
	;Reset flag
	DoCombatPrep:Set[FALSE]
}

function Attack(string AttackGUID)
{
  
  declare SavX float local ${Me.X}
  declare SavY float local ${Me.Y}
  declare SavZ float local ${Me.Z}
  declare BailOut int local ${Math.Calc[${LavishScript.RunningTime}+(1000*${CombatBailout})]}
  declare TimeTillHeal int local ${Math.Calc[${LavishScript.RunningTime}+(1000*TIMEBETWEENHEALS)]}
  declare MobHealth int local ${Math.Calc[${LavishScript.RunningTime}+3000]}
  declare HavePulled bool local FALSE
  declare StuckCheck bool local FALSE
  declare StuckCheckTime int local
  declare Aggros guidlist local
  declare BeforeHeal int local
  declare RngPull bool FALSE
  
  declare OldHealth int local
  ;declare TAPPED bool local FALSE
  
  if ${AttackGUID.Equal[NULL]}||${AttackGUID.Equal[NOTARGET]}
  {
	  call UpdateHudStatus "No target has been found."
  }
  
  call UpdateHudStatus "Attacking ${Object[${AttackGUID}].Name}"
  
  call CombatPrep
  
  Do
  {
    SavX:Set[${Me.X}]
    SavY:Set[${Me.Y}]
    SavZ:Set[${Me.Z}]

    ; Check we still have a valid target
    if !${Unit[${AttackGUID}](exists)}
    {
   	  call UpdateHudStatus "Target has been lost."
	  TargetGUID:Set[NOTARGET]
	  Return
    }
  
    ; Check if the target is engaged already
	if ${Unit[${AttackGUID}].Tapped}
	{
  	  call UpdateHudStatus "Target has already been found."
	  TargetGUID:Set[NOTARGET]
  	  Return		
  	} 
  
	; If we dont have our chosen unit targeted and were in range target it
	if !${Target.GUID.Equal[${AttackGUID}]}&&${Unit[${AttackGUID}].Distance}<${TargetingRange}
	{
  	  #ifdef DEBUG
  	  call Debug "Targeting Unit ${Unit[${AttackGUID}].Distance}[${AttackGUID}]"
  	  #endif
  	  Target ${AttackGUID}
  	  wait 10
  	  call FaceTarget ${AttackGUID}
  	}

    ; List here things you don't want the bot to attack..
    if ${Unit[${TargetGUID}].Name.Equal[Gann Stonespire]}||${Unit[${TargetGUID}].Name.Equal[Greater Barrens Kodo]}||${Unit[${TargetGUID}].Name.Equal[Barrens Kodo]}||${Unit[${TargetGUID}].Name.Equal[Wooly Kodo]}
	{
      call UpdateHudStatus "We don't like ${Unit[${AttackGUID}].Name}, lets avoid it.."
      GUIDBlacklist:Set[${TargetGUID},AVOID]
	  TargetGUID:Set[NOTARGET]
	  DoDowntime:Set[TRUE]
	  DoCombatPrep:Set[TRUE]
	  Return
    }
  	
  	if !${Me.Attacking}&&${Target(exists)}&&${Unit[${AttackGUID}].Distance}<${TargetingRange}
  	{
  	  WoWScript AttackTarget()
  	  OldHealth:Set[100]
  	}

    if !${RngPull}&&HOLYSHOCKPULL
    {
      call UpdateHudStatus "Let's do this from range..."
      call ShockPull ${AttackGUID}
      RngPull:Set[TRUE]
    }
  
	; Check we havent picked up aggro
;	Aggros:Search[-units, -nearest, -alive, -exact, Eye of Naxxramas, -range, 1-30]
;	if ${Aggros.Count}>0
;	{
;      AttackGUID:Set[Aggros[1].GUID]
;      call FaceTarget ${AttackGUID}
;    }
;    Aggros:Clear

	if ${LavishScript.RunningTime}>${BailOut}&&${Object[${AttackGUID}].PctHPs}>99
	{    
	  GUIDBlacklist:Set[${AttackGUID},AVOID]
	  call UpdateHudStatus "Combat timeout reached"
	  AttackGUID:Set[NOTARGET]
	  DoDowntime:Set[TRUE]
	  DoCombatPrep:Set[TRUE]
	  Return
	}    
  	    
  	Aggros:Search[-units,-nearest,-aggro,-alive,-range 0-10]
  	if !${HavePulled}&&${Aggros.Count}>0&&${Aggros[1].GUID.NotEqual[${AttackGUID}]}
  	{
  	  #ifdef DEBUG
  	  call Debug "${Unit[${Aggros[1].GUID}].Name} has aggroed exiting Attack routine"
  	  #endif
  	  Return
  	}
  	Aggros:Clear
  	HavePulled:Set[TRUE]
  	
  	if (${PullBeforeContinue}&&${HavePulled})||!${PullBeforeContinue}
  	{
  	  ;If we are close enough stop running
  	  if ${Unit[${AttackGUID}].Distance}>${CombatMinDist}&&${Unit[${AttackGUID}].Distance}<${CombatMaxDist}
  	  {
  		wowpress -release moveforward
  		wowpress -release movebackward
  		StuckCheck:Set[FALSE]
  		call Pause 0.3
   	  }
      call FaceTarget ${AttackGUID}  	
    }
  
    ;call FindWeakestMob ${AttackGUID}
    ;AttackGUID:Set[${Return}]
	  	
    call ApproachTarget ${AttackGUID}	

    ;If we are close enough stop running
    call FaceTarget ${AttackGUID}
    call CheckDebuff ${Me.GUID}
    call ManaTap ${AttackGUID}  
    call DoBlessings
    call DoJudgements ${AttackGUID}
    call DoSeal ${AttackGUID}

	;Exorcism 
	if ${Unit[${AttackGUID}].Buff["Judgement of the Crusader"](exists)}&&${Me.PctMana}>35 && !${Unit[${AttackGUID}].Dead}&&!${Spell[Exorcism].Cooldown} && ${Target.CreatureType.Equal[Undead]} || ${Unit[${AttackGUID}].Buff["Judgement of the Crusader"](exists)} && ${Me.PctMana}>35 && !${Unit[${AttackGUID}].Dead}&&!${Spell[Exorcism].Cooldown} && ${Target.CreatureType.Equal[Demon]} 
	{
      call FaceTarget ${AttackGUID}
      wowpress -release moveforward
	  wowpress -release movebackward
	  call CastSpell "Exorcism"
    }
  
	call ExecuteThis ${AttackGUID}
    call UseConcecration ${AttackGUID}
    
    if ${LavishScript.RunningTime}>${TimeTillHeal}&&${Me.PctHPs}<${MinHealthPct}
	{
       BeforeHeal:Set[${Me.PctHPs}]
       call HealPlayer ${AttackGUID}
       TimeTillNextHeal:Set[${Math.Calc[${LavishScript.RunningTime}+(1000*TIMEBETWEENHEALS)]}]
  	}
    call DisruptCast ${AttackGUID}  	
  	
  	; Check if we wish to flee combat or not
  	Aggros:Search[-units,-nearest,-aggro,-alive, -range 0-${Math.Calc[${MaxRoam}/2]}]
  	;call UpdateHudStatus "I have ${Aggros.Count} mobs on me."
  		
if ${Target.PctHPs}==100 && ${Me.InCombat} && ${Target.Distance}<20
{
	face -heading ${Math.Calc[${Me.Heading}+180]}
	move -stop
	wait 10
	wowpress JUMP
	face -heading ${Math.Calc[${Me.Heading}+180]}
}
  	if (${Aggros.Count}>=${Math.Calc[${PanicThreshold}*2]})||(${Aggros.Count}>${PanicThreshold}&&(${Me.PctHPs}<40||((${Me.PctHPs}<30&&${Me.PctMana}<10)&&${Unit[AttackGUID].PctHPs}>30))
  	{
  	  call Debug "I have ${Aggros.Count} mobs on me.  Run."
  	  RLG:Set[TRUE]
  	  return
	}
  	
	call StandUp
  	
  	; Check to make sure we have moved if not then try and avoid the
  	; obstacle thats in our path
  	if ${Math.Distance[${Me.X},${Me.Y},${Me.Z},${SavX},${SavY},${SavZ}]}<1&&${Unit[${AttackGUID}].Distance}>${Math.Calc[${CombatMaxDist}-1]}
  	{
  	  ; I think i might be stuck so save off the current time
  	  if !${StuckCheck}
  	  {
  		#ifdef DEBUG
  		call Debug "We might be stuck..."
  		#endif
  		StuckCheck:Set[TRUE]
  		StuckCheckTime:Set[${LavishScript.RunningTime}]
  	  }
  	  else
  	  {
  		; If I am still stuck after 8 seconds then try and avoid the obstacle.
  		if ${Math.Calc[${LavishScript.RunningTime}-${StuckCheckTime}]}>8000
  		{
  		  #ifdef DEBUG
  		  call Debug "Let's try to get unstuck..."
  		  #endif
  		  call Obstacle
  		  StuckCheck:Set[FALSE]
  		}
  	  }
  	
      ; If I have moved away from my saved spot reset my stuck toggle
  	  if ${StuckCheck}&&${Math.Distance[${Me.X},${Me.Y},${Me.Z},${SavX},${SavY},${SavZ}]}>3
  	  {
  	 	#ifdef DEBUG
  		call Debug "We are no longer stuck."
  		#endif
  		StuckCheck:Set[FALSE]
  	  }	
  
	  ; Check if we have exceeded bail out timer
	  if ${LavishScript.RunningTime}>${BailOut}
	  {
  		GUIDBlacklist:Set[${TargetGUID},AVOID]
  		call UpdateHudStatus "Combat timeout reached"
  		TargetGUID:Set[NOTARGET]
  		return
  	  }
  	}
  }
  while !${Unit[${AttackGUID}].Dead}&&!${Me.Dead}

  ; Update stats
  if !${Me.Dead}
  {
	  call UpdateStats
  }
  wowpress -release movebackward
  wowpress -release moveforward
  ;Reset flags to do combat prep and downtime if we are not still aggroed
  Aggros:Search[-units,-nearest,-aggro,-alive,-range 0-50]
  if !${Aggros.Count}
  {
	call Debug "Resetting Downtime and CombatPrep Flags"
	DoDowntime:Set[TRUE]
	DoCombatPrep:Set[TRUE]
  }
  Aggros:Clear
}

function PrintMsg(string msg)
{
  if DEBUGMODE
  {
    call UpdateHudStatus ${msg}
  }
}

function UseBestHolyLight()
{
  declare SpellRank int 0
  declare OldTarget string local
  
  call StandUp
  call GetHolyLightRank
  SpellRank:Set[${Return}]
  
  call GlobalCooldown

  call UpdateHudStatus "call Holy Light ${Me.GUID} ${SpellRank}"
  ;call CastSpellByRank "Holy Light" ${SpellRank} ${Me.GUID}
  if ${SpellRank} > 0 
  {
    if ${Spell[Concentration Aura](exists)}&&USECONCENTRATION&&!${Me.Buff[Concentration Aura](exists)}&&${Me.InCombat}
    {
      echo "Focus....  I need to focus..."
      Cast "Concentration Aura"
      wait 1
      call GlobalCooldown
    }
   
    OldTarget:Set[${Target.GUID}]
    Target ${Me.GUID}
    Cast "Holy Light" ${SpellRank}
    ;call bCastSpell "Holy Light" ${SpellRank} ${Me.GUID} ${Me.GUID}
    Target ${OldTarget}
    while ${Me.Casting}
    {
      call Pause 0.2
    }
    call GlobalCooldown
	if !${Me.Buff[USEAURA](exists)}&&!${Me.Casting}&&${Me.InCombat}
	{
      Cast USEAURA
      call GlobalCooldown
    }
  }
}

function UseBestFlashofLight()
{
  declare SpellRank int 0
  call StandUp
  call GetFlashofLight
  SpellRank:Set[${Return}]
  
  call GlobalCooldown
  if ${SpellRank} > 0 
  {
    call bCastSpell "Flash of Light" ${SpellRank} ${Me.GUID} ${Me.GUID}
    call GlobalCooldown
    waitframe 
  }
}


function StandUp()
{
  if ${Me.Sitting}
  {
    wowpress SITORSTAND
  }
}

function SitDown()
{
  if !${Me.Sitting}
  {
   wowpress SITORSTAND
  }
}

function DrinkCheck()
{
  if !${Me.Buff[Drink](exists)}
  {
    call UpdateHudStatus "Man I need some milk..  Makes the body stronger"
    wowpress ACTIONBUTTON11
    wait 40 ${Me.Buff[Drink](exists)}
  }
}

function FoodCheck()
{
  if !${Me.Buff[Food](exists)}
  {
    wowpress ACTIONBUTTON12
    wait 40 ${Me.Buff[Food](exists)}
  }
}

function FoodDrinkCheck()
{
  if !${Me.Buff[Food](exists)}
  {
    wowpress ACTIONBUTTON12
    wait 40 ${Me.Buff[Food](exists)}
  }
  if !${Me.Buff[Food](exists)}
  {
    wowpress ACTIONBUTTON11
    wait 40 ${Me.Buff[Drink](exists)}
  }
}


function Downtime()
{
  call CheckDebuff ${Me.GUID}
  
  ;call UpdateHudStatus "Downtime()" 
  ;call UpdateHudStatus "${Me.PctHPs}<${MinHealthPct}||${Me.PctMana}<${MinManaPct}"
  if ${Me.PctHPs}<${MinHealthPct}||${Me.PctMana}<${MinManaPct}&&HEALNOTEAT
  {
    while ${Me.PctHPs}<95&&!${Me.InCombat}&&!${Me.Dead}&&!${Me.Ghost}
    {
      if ${Me.PctMana}>5&&!${Me.Buff[Drink](exists)}
      {
        call StandUp
        call UseBestHolyLight
      }
      if ${Me.PctMana}<=20
      {
        if ${Me.PctHPs}<85&&!${Me.Buff[Food](exists)}
        {
          call FoodCheck
        }
        call DrinkCheck
      }
      call UpdateStats
    }
    if ${Me.PctHPs}<${MinHealthPct}||${Me.PctMana}<${MinManaPct}
    {
      while (${Me.PctMana}<95||${Me.PctHPs}<95)&&!${Me.InCombat}&&!${Me.Dead}&&!${Me.Ghost}
      {
        if ${Me.PctMana}<95&&${Me.PctHPs}<95
        {
  	      call FoodDrinkCheck
        }
        if (${Me.PctHPs}<95)
        {
   	      call FoodCheck
        }
  
        if (${Me.PctMana}<95)
        {
   	      call DrinkCheck
        }
      }
    }
  }
  call StandUp
  call DoBlessings
  call CheckDurability

  DoDowntime:Set[FALSE]
}

function GetFlashofLight()
{
  declare HealsFor[11] int
  declare ManaFor[11] int
  declare SpellRank int 0
  declare GotSpell bool FALSE
  declare cntr int 1
  declare HPDown int ${Math.Calc[${Me.MaxHealth}-${Me.Health}]}
  
  ;call UpdateHudStatus "HP Stats:${Me.MaxHealth}-${Me.Health}=${HPDown}"
  
  if ${Me.PctHPs}>98
  {
    Return ${SpellRank}
  }
  ; RANK : Heal Avg
  HealsFor[1]:Set[65]
  HealsFor[2]:Set[102]
  HealsFor[3]:Set[153]
  HealsFor[4]:Set[215]
  HealsFor[5]:Set[285]
  HealsFor[6]:Set[370]
  HealsFor[7]:Set[490]
  ManaFor[1]:Set[35]
  ManaFor[2]:Set[50]
  ManaFor[3]:Set[70]
  ManaFor[4]:Set[90]
  ManaFor[5]:Set[115]
  ManaFor[6]:Set[140]
  ManaFor[7]:Set[180]

  do 
  {
    if !${Spell[Flash of Light,${cntr}](exists)}
    {
      GotSpell:Set[TRUE]
      break
    }
    else 
    {
      if ${HPDown}>${HealsFor[${cntr}]}&&${Me.CurrentMana}>=${ManaFor[${cntr}]}
      {
        SpellRank:Set[${cntr}]
      }
    }
    cntr:Inc
  }
  while !${GotSpell}&&${cntr}<12

  Return ${SpellRank}
}

; This is set for Pallie heals, but could easily be adapted to other classes with healing
function GetHolyLightRank()
{
  declare HealsFor[11] int
  declare ManaFor[11] int
  declare SpellRank int 0
  declare GotSpell bool FALSE
  declare cntr int 1
  declare HPDown int ${Math.Calc[${Me.MaxHealth}-${Me.Health}]}
  
  ;call UpdateHudStatus "HP Stats:${Me.MaxHealth}-${Me.Health}=${HPDown}"
  
  if ${Me.PctHPs}>98
  {
    Return ${SpellRank}
  }
  ; RANK : Heal Avg
  HealsFor[1]:Set[50]
  HealsFor[2]:Set[90]
  HealsFor[3]:Set[167]
  HealsFor[4]:Set[330]
  HealsFor[5]:Set[525]
  HealsFor[6]:Set[740]
  HealsFor[7]:Set[1000]
  HealsFor[8]:Set[1320]
  HealsFor[9]:Set[1695]
  HealsFor[10]:Set[1850]
  HealsFor[11]:Set[2330]
  ; RANK : Heal Avg
  ManaFor[1]:Set[35]
  ManaFor[2]:Set[60]
  ManaFor[3]:Set[110]
  ManaFor[4]:Set[190]
  ManaFor[5]:Set[275]
  ManaFor[6]:Set[365]
  ManaFor[7]:Set[465]
  ManaFor[8]:Set[580]
  ManaFor[9]:Set[660]
  ManaFor[10]:Set[710]
  ManaFor[11]:Set[840]

  do 
  {
    if !${Spell[Holy Light,${cntr}](exists)}
    {
      GotSpell:Set[TRUE]
      break
    }
    else 
    {
      if ${HPDown}>${HealsFor[${cntr}]}&&${Me.CurrentMana}>=${ManaFor[${cntr}]}
      {
        SpellRank:Set[${cntr}]
      }
    }
    cntr:Inc
  }
  while !${GotSpell}&&${cntr}<12

  Return ${SpellRank}
}

function FaceTarget(string AttackGUID)
{
  Face ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y} 
  call CheckFacing
}

function ExecuteThis(string AttackGUID)
{
  if !${Me.InCombat}
  {
    Return
  }

  call GlobalCooldown
  call FaceTarget ${AttackGUID}
  if ${Spell[Hammer of Wrath](exists)}&&${Unit[${AttackGUID}].PctHPs}<20&&!${Unit[${AttackGUID}].Dead}
  {
    if !${Spell[Hammer of Wrath].Cooldown}
    {
      call CastSpell "Hammer of Wrath" ${AttackGUID}
      call GlobalCooldown
    }
  }
  if ${Spell[Judgement](exists)}&&${Me.PctMana}>=MYMINMANAFORFINISHPCT&&${Spell[SEALFINISHER](exists)}&&USESEALFINISHER&&!${Unit[${AttackGUID}].Dead}
  {
    if ${Unit[${AttackGUID}].PctHPs}<MOBMAXHPPCT&&!${Spell[Judgement].Cooldown}
    {
      if !${Me.Buff[SEALFINISHER](exists)}&&!${Unit[${AttackGUID}].Dead}
      {
        Cast SEALFINISHER
        call GlobalCooldown
      }
      Cast "Judgement"
      call GlobalCooldown
    }
  }
}

function FindWeakestMob(string AttackGUID)
{
  declare Aggros guidlist local
  declare curlevel int ${Unit[${AttackGUID}].Level}
  declare Counter int 1
  ; Multiple Enemies, if we have consecration, use it.

  Aggros:Search[-units,-nearest,-aggro,-alive,-range 0-8]
  
  if ${Aggros.Count}<2
  {
    Return ${AttackGUID}
  }
  do
  {
    if !${Unit[${Aggros[${Counter}].GUID}].Level}<${curlevel}
    {
      AttackGUID:Set[Aggros[${Counter}].GUID]
    }
    Counter:Inc
  }
  while ${Counter}<=${Aggros.Count}
  Aggros:Clear
  call FaceTarget ${AttackGUID}
  Return ${AttackGUID}
}

function UseConcecration(string AttackGUID)
{
  declare Aggros guidlist local

  if !${Me.InCombat} 
  {
    Return
  }
  call GlobalCooldown
  ; Multiple Enemies, if we have consecration, use it.
  Aggros:Search[-units,-nearest,-aggro,-alive,-range 0-8]
  if ${Aggros.Count}>1&&${Spell[Consecration](exists)}
  {
    if !${Spell[Consecration].Cooldown}
    {
      call CastSpell "Cast Consecration"
      call GlobalCooldown
    }
  }
  Aggros:Clear
}

function DisruptCast(string AttackGUID)
{
  ; If the target is casting, and we can kick, give it a good boot to stop spell casting:
  if !${Me.InCombat} 
  {
    Return
  }
  call GlobalCooldown
  if ${Target.Casting.ID(exists)}
  {
     if ${Me.Buff[Mana Tap](exists)}&&!${Spell[Arcane Torrent].Cooldown} 
     {
       Cast "Arcane Torrent"
       call GlobalCooldown
     }
     elseif DISRUPTCAST_HOJ&&${Spell[Hammer of Justice](exists)}
     {
       if !${Spell["Hammer of Justice"].Cooldown}
       {
         call CastSpell "Hammer of Justice" ${AttackGUID}
         call GlobalCooldown
       }
     }
   } 
}

function ManaTap(string AttackGUID)
{
  if !${Me.InCombat} 
  {
    Return
  }
  call GlobalCooldown
  if ${Unit[${AttackGUID}].PctMana}>0&&${Spell[Mana Tap](exists)}
  {
    ;call UpdateHudStatus "MT ST: ${Me.Buff[Mana Tap].Duration}:${Me.Buff[Mana Tap].Application} "
    ;call UpdateHudStatus "CORRECT: ${Me.Race}  Target Has Mana :${Unit[${AttackGUID}].PctMana:${TapManaBuff}:${Spell[Mana Tap].Cooldown}"
    if !${Spell[Mana Tap].Cooldown}&&${Me.Buff[Mana Tap].Application}<3||!${Spell[Mana Tap].Cooldown}&&${Me.Buff[Mana Tap].Duration}<=60
    {
      call UpdateHudStatus "Casting Mana Tap"
      Cast "Mana Tap"
      call GlobalCooldown
    }
    if ${Me.PctMana}<=70&&!${Spell[Arcane Torrent].Cooldown}&&${Me.Buff[Mana Tap](exists)}
    {
      Cast "Arcane Torrent"
      call GlobalCooldown
    }
  }
}

function ApproachTarget(string AttackGUID)
{
  ;If too far away run forward
  declare TargetDistance int local ${Math.Distance[${Me.X},${Me.Y},${Me.Z},${Target.X},${Target.Y},${Target.Z}]}
  declare MaxDistance int local ${Math.Calc[${CombatMaxDist}-1]}
  
  if ${Me.Buff[Summon Warhorse](exists)}
  {
    echo "Need to dismount"
    WoWScript Dismount()
    call GlobalCooldown
      ;call Pause 1
  }
  if !${Target.GUID.Equal[${AttackGUID}]}&&${Unit[${AttackGUID}].Distance}<${TargetingRange}
  {
	Target ${AttackGUID}
  	wait 10
  	call FaceTarget ${AttackGUID}
  }

  while ${TargetDistance}>${MaxDistance}&&!${Me.Casting}&&!${Object[${AttackGUID}].Dead}&&!${Unit[${AttackGUID}].Tapped}&&!${Me.Dead}
  {
    ; determine if mob is moving towards or away...
    call SmartFacePrecision ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y}
    TargetDistance:Set[${Math.Distance[${Me.X},${Me.Y},${Me.Z},${Unit[${AttackGUID}].X},${Unit[${AttackGUID}].Y},${Unit[${AttackGUID}].Z}]}]
    ;echo "My Distace = ${TargetDistance}"
    if ${TargetDistance}<${LastDistance}||${TargetDistance}>${MaxDistance}
    {
      ; We are moving towards the critter....
      LastDistance:Set[${TargetDistance}]
 	  wowpress -hold moveforward
    }
	if (${TargetDistance}>${CombatMinDist}&&${TargetDistance}<${MaxDistance})
	{
		TargetDistance:Set[${Math.Distance[${Me.X},${Me.Y},${Me.Z},${Unit[${AttackGUID}].X},${Unit[${AttackGUID}].Y},${Unit[${AttackGUID}].Z}]}]
        call SmartFacePrecision ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y}
		wowpress -release moveforward
		wowpress -release movebackward
	}
  }    
  wowpress -release moveforward
  wowpress -release movebackward
  call SmartFacePrecision ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y}
}

function DoBlessings()
{
  call GlobalCooldown
  if ${Me.PctMana}<LOWMANABOW&&USEBOWISDOM&&!${Me.Buff["Blessing of Wisdom"](exists)}&&${Spell["Blessing of Wisdom"](exists)}
  {
    Cast "Blessing of Wisdom"
    call GlobalCooldown
  }
  else 
  if ${Spell[KEEPBLESSING](exists)}&&!${Me.Buff[KEEPBLESSING](exists)}&&${Me.PctMana}>${MinManaPct}
  {
    Cast KEEPBLESSING
    call GlobalCooldown
  }
  if ${Spell["Righteous Fury"](exists)}
  {
    if !${Me.Buff["Righteous Fury"](exists)}
    {
      Cast "Righteous Fury"
      call GlobalCooldown
    }
  }
}

function DoSeal(string AttackGUID)
{
  ;call UpdateHudStatus "DoSeal() ${Spell[MYSEAL](exists)} : ${Unit[${AttackGUID}].Buff[MOBJUDGED](exists)}"
  call GlobalCooldown
  if ${Spell[MYSEAL](exists)}&&${Unit[${AttackGUID}].Buff[MOBJUDGED](exists)}
  {
	;call UpdateHudStatus "We Need a Seal to fight with"
    ;call UpdateHudStatus "DoSeal() ${Me.PctMana} :  ${Unit[${AttackGUID}].Dead} : ${Me.Buff[MYSEAL](exists)} : ${Unit[${AttackGUID}].PctHPs}"
	if ${Me.PctMana}>15&&!${Unit[${AttackGUID}].Dead}&&!${Me.Buff[MYSEAL](exists)}&&${Unit[${AttackGUID}].PctHPs}>18 
	{
      ; call UpdateHudStatus "Casting MYSEAL" 
      Cast MYSEAL ${Me.GUID}
      call EffectWait MYSEAL ${Me.GUID} 4
      call GlobalCooldown
	}
  }
}

function GlobalCooldown()
{
  while ${Me.GlobalCooldown}
  {
    ; echo "Me.GlobalCooldown = ${Me.GlobalCooldown}"
  }
}

function EffectWait(string EffectName, string AttackGUID, int waitfor)
{
  declare DelayTimer int local ${Math.Calc[${LavishScript.RunningTime}+(1000*${waitfor})]}

  while !${Unit[${AttackGUID}].Buff[${EffectName}](exists)}&&${LavishScript.RunningTime}<${DelayTimer}
  {
    ; "echo waiting for buff ${EffectName}"
  }
}

function DoJudgements(string AttackGUID)
{
  call GlobalCooldown
  if !${Me.InCombat} 
  {
    Return
  }
  if JUDGEMOBS&&${Spell[MYJUDGE](exists)}&&${Spell["Judgement"](exists)}&&${Unit[${AttackGUID}].PctHPs}>18&&!${Unit[${AttackGUID}].Dead}
  {
    if ${Me.PctMana}>25&&!${Me.Buff[MYJUDGE](exists)}&&!${Unit[${AttackGUID}].Buff[MOBJUDGED](exists)}&&${Me.Action[MYJUDGE].Usable}
    {
      call FaceTarget ${AttackGUID}
      Target ${Me.GUID}
      call UpdateHudStatus "Casting My JudgeSeal"
      Cast MYJUDGE
      Target ${AttackGUID}
      call EffectWait MYJUDGE ${Me.GUID} 2
      call GlobalCooldown
      
    }
    if ${Me.PctMana}>20&&!${Spell[Judgement].Cooldown}&&${Me.Buff[MYJUDGE](exists)}&&!${Unit[${AttackGUID}].Buff[MOBJUDGED](exists)}&&${Unit[${AttackGUID}].Distance}<5
    {
      call FaceTarget ${AttackGUID}
      if ${Me.Action["Judgement"].Usable}
      {
        call UpdateHudStatus "Casting Judgement"
        Cast "Judgement"
        call GlobalCooldown
        call EffectWait MOBJUDGED ${AttackGUID} 2
      }
    }
  }
}

function ShockPull(string AttackGUID)
{
  if ${Spell[Holy Shock](exists)}
  {
    if !${Me.InCombat}&&!${Me.Dead}&&!${Me.Ghost}
    {
      ; Move into ranged combat range
      call UpdateHudStatus "MobRNG:${Unit[${AttackGUID}].Distance}  PRNG:${PullingRange}"
      if ${Unit[${AttackGUID}].Distance}>${PullingRange}
	  {
        call SmartFacePrecision ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y}
        move forward
        do
        {
          call SmartFacePrecision ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y}
          move forward
          WaitFrame
        }
        while ${Unit[${AttackGUID}].Distance}>${PullingRange}
        move -stop forward
        ;wait for half a second to give our pc a chance to move
        wait 5
      }
      ;If we are close enough for ranged, stop running and fire
      if ${Unit[${AttackGUID}].Distance}<=20
      {
        wowpress -release moveforward
        wowpress -release movebackward
        waitframe
        call CastSpell "Holy Shock" ${AttackGUID}
      }
    }
  }
}


;call bCastSpell "Holy Light" 0 ${Me.GUID} "player"
;----------------------------------------------------------------------------------
;| Function Name: WoWUnitToGUID
;| Returns: string UNIT_Found.GUID
;| Description: Used to get a lavish GUID from a given WoW UnitID
;|
;----------------------------------------------------------------------------------
function:string WoWUnitToGUID(string UNIT_ID)
{
    ;call Debug "WoWUnitToGUID: UNIT_ID=${UNIT_ID}"
    declare UNIT_Name           string      local
    declare UNIT_GUID           string      local
    declare UNIT_Found          guidlist    local
    
    ;Before we search for the unit in the guid list make sure the UNIT_ID is not null
    if ${UNIT_ID.Equal[NULL]}
        return "NULL"
    
    ; Convert our wow unit into a GUID that lavish script can use
    UNIT_Name:Set[${WoWScript["UnitName(\"${UNIT_ID}\")"]}]
    ;call Debug "WoWUnitToGUID: UNIT_Name=${UNIT_Name}"
    if ${UNIT_Name.Equal[NULL]}
        return "NULL"

    ;call Debug "WoWUnitToGUID: Searching for ${UNIT_Name}"    
    UNIT_Found:Search[${UNIT_Name}]
    ;call Debug "WoWUnitToGUID: UNIT_Found.Count=${UNIT_Found.Count}"
    if ${UNIT_Found.Count}==0
    {
        ;call Debug "WoWUnitToGUID: Couldnt find ${UNIT_ID}:${UNIT_Name}"
        return "NULL"
    }
    else
    {
        ;We cant check the name of non unit or non player types
        if ${UNIT_Found.Object[1].Type.Equal[Unit]} || ${UNIT_Found.Object[1].Type.Equal[Player]}
        {
            ;We need to check if the GUID has a name because I was matching GUIDs to Skin of Shadow wtf bug?
            if ${UNIT_Found.Object[1].Name.Equal[NULL]} || !${UNIT_Found.Object[1].Name.Equal[${UNIT_Name}]}
            {
                ;call Debug "WoWUnitToGUID: The guid we matched doesnt have the same name as the wow unit id"
                return "NULL"
            }
            else
            {
                ;call Debug "WoWUnitToGUID: found ${UNIT_Found.GUID[1]} WOW_UnitID=${UNIT_ID} name=${UNIT_Name}"
                return ${UNIT_Found.GUID[1]}
            }
        }
        else
        {
            return "NULL"
        }
        
    }
}

function bCastSpell(string strSpellName, int intSpellRank, string strSpellTargetGUID, string strSpellTargetWOWID)
{
    call Debug "bCastSpell: SpellName=${strSpellName} intSpellRank=${intSpellRank} strSpellTarget=${strSpellTargetGUID}:${Object[${strSpellTargetGUID}].Name} strSpellTargetWOWID=${strSpellTargetWOWID}:${WoWScript[UnitName(\"${strSpellTargetWOWID}\")]}"
    echo "bCastSpell: SpellName=${strSpellName} intSpellRank=${intSpellRank} strSpellTarget=${strSpellTargetGUID} strSpellTargetWOWID=${strSpellTargetWOWID}:${WoWScript[UnitName(\"${strSpellTargetWOWID}\")]}"
    declare OriginalTargetGUID string local ${Target.GUID}
    declare UNIT_GUID string local NULL
    declare intCastRank int local ${intSpellRank}
    declare intNumOfForms int local 0
    declare strPreviousPowerType string local
    declare bSwitchedForm bool local FLASE
    
    ;First we need to know if the strSpellTarget is a GUID or a WOWUnitID either way we need the GUID
    if !${strSpellTargetGUID.Equal[NULL]}
    {
        if ${Object[${strSpellTargetGUID}](exists)}
        {
            UNIT_GUID:Set[${strSpellTargetGUID}]
        }
    }
    else
    {
        ;Its a wow id so convert it to a GUID
        call WoWUnitToGUID ${strSpellTargetWOWID}
        UNIT_GUID:Set[${Return}]
    }

    ;Make sure we have a GUID before continuing
    if ${UNIT_GUID.Equal[NULL]}
    {
        call UpdateHudStatus "bCastSpell: SpellTargetGUID=NULL returning"
        return TRUE
    }

    if !${Spell[${strSpellName}](exists)}
    {
        call UpdateHudStatus "bCastSpell:You do not have the spell ${strSpellName}"
        return TRUE
    }
    else
    {
        ;We know the spell exists now but does the rank exist?
        if ${intCastRank} > 0 && !${Spell["${strSpellName}",${intCastRank}](exists)}
        {
            call UpdateHudStatus "bCastSpell:You do not have the spell ${${strSpellObject}.SpellName} Rank ${${strSpellObject}.CastingRank}"
            intCastRank:Set[0]
        }
    }

    if ${intCastRank} > 0
    {
        if ${Spell[${strSpellName},${intCastRank}].Mana} > ${Me.Current${Me.Power}}
        {
            call UpdateHudStatus "bCastSpell:You do not have enough ${Me.Power} to cast ${strSpellName} Rank ${intCastRank}"
            return TRUE
        }
    }
    else
    {
        if ${Spell[${strSpellName}].Mana} > ${Me.Current${Me.Power}}
        {
            call UpdateHudStatus "bCastSpell:You do not have enough ${Me.Power} to cast ${strSpellName} highest rank"
            return TRUE
        }
    }
    
    ;If we are casting or the spell is on cooldown then stop casting and let the next pulse try again
    if ${Spell["${strSpellName}"].Cooldown} > 0 || ${Me.Casting} || ${Me.GlobalCooldown} > 0
    {
        wowscript SpellStopCasting()
        return TRUE
    }
    
    call UpdateHudStatus "bCastSpell: Past first spell cancel for SpellName=${strSpellName} intSpellRank=${intSpellRank} strSpellTarget=${strSpellTargetGUID} strSpellTargetWOWID=${strSpellTargetWOWID}"        
    if ${intCastRank} > 0
    {
        call UpdateHudStatus "bCastSpell: Casting ${strSpellName} ${intCastRank}"
        Cast "${strSpellName}" ${intCastRank}
    }
    else
    {
        call UpdateHudStatus "bCastSpell: Casting ${strSpellName} no rank so highest level"
        Cast "${strSpellName}"
    }
    wait 7

    ;Wait for us to finish Casting 
    while ${Me.Casting}
    {
        waitframe
    }
}