;Paladin Bot by FarmerBob (farming.bob@gmail.com)
#define ROUTINES
#define POTION1 "Superior Healing Potion"
#define POTION2 "Healing Potion"
#define POTION3 "Minor Healing Potion"
#define DEBUGMODE TRUE
#define RUNONSTART 10
;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 36
#define EMERGENCYHPPCT 40
#define LAYONHANDSHPPCT 20
#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 TRUE
#define SEALFINISHER "Seal of Righteousness"
#define MOBMAXHPPCT 20
#define MYMINMANAFORFINISHPCT 40
; 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 40
; 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 20
#define STUNHEAL TRUE
; If we need Divine Shield 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)
{
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[Divine Shield](exists)}
{
if !${Spell[Divine Shield].Cooldown}&&USEBOP
{
; face -heading ${Math.Calc[${Me.Heading}+180]}
; move forward
; wait 10
; move -stop
; face -heading ${Math.Calc[${Me.Heading}+180]}
; move -stop
Target ${Me.GUID}
Cast "Divine Shield"
Target ${AttackGUID}
call EffectWait "Divine Shield" ${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}<EMERGENCYHPPCT
{
;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}<40&&${Spell[Divine Favor](exists)}
{
if ${Spell[Divine Favor](exists)}
{
if !${Spell[Divine Favor].Cooldown}
{
Cast "Divine Favor"
call GlobalCooldown
}
}
}
move -stop
use ${Item[Vengeance of the Illidari].GUID}
call GlobalCooldown
call UseBestHolyLight
}
}
}
function CureMe(string RecipientGUID, string SpellName)
{
declare OldTarget GUID ${Target.GUID}
if ${Spell[${SpellName}](exists)}
{
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 Aggros1 guidlist global
declare OldHealth int local
;declare TAPPED bool local FALSE
;blacklist
if ${Unit[${AttackGUID}].Name.Equal[Swamp Gas]}
{
GUIDBlacklist:Set[${AttackGUID},AVOID]
TargetGUID:Set[NOTARGET]
return
}
if ${AttackGUID.Equal[NULL]}||${AttackGUID.Equal[NOTARGET]}
{
call UpdateHudStatus "No target has been found."
}
call UpdateHudStatus "Attacking ${Object[${AttackGUID}].Name}"
call CombatPrep
call DoBlessings
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.. blacklist
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]
Aggros1:Clear
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]
Aggros1:Clear
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}
if !${Me.Equip[mainhand].Durability} == NULL || !${Me.Equip[mainhand].Durability} == 0 && !${Me.Attacking}
{
call CastSpell "Attack" ${AttackGUID}
}
echo "Aggros1 count ${Aggros1.Count}"
if ${Aggros1.Count}>1
{
echo "Sword and board for extra attacker"
Aggros1:Search[-units,-targetingme,-range 0-20]
Item[Shatterstone Pick]:RightClick
Item[Landslide Buckler]:RightClick
}
call CheckDebuff ${Me.GUID}
call ManaTap ${AttackGUID}
call DoBlessings
call DoJudgements ${AttackGUID}
call DoSeal ${AttackGUID}
call ApproachTarget ${AttackGUID}
if !${Me.Equip[mainhand].Durability} == NULL || !${Me.Equip[mainhand].Durability} == 0 && !${Me.Attacking}
{
call CastSpell "Attack" ${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 backward
call CastSpell "Exorcism"
}
call ExecuteThis ${AttackGUID}
call UseConcecration ${AttackGUID}
if ${LavishScript.RunningTime}>${TimeTillHeal}&& ${Me.PctHPs} < EMERGENCYHPPCT
{
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."
#ifdef RUNONSTART
if ${Target.PctHPs}>95 && ${Me.InCombat} && ${Target.Distance}<20 && !${Target.Casting.ID(exists)} || ${Target.Distance} < 1
{
;face -heading ${Math.Calc[${Me.Heading}+180]}
wowpress -hold movebackward
wait RUNONSTART
wowpress -release movebackward
call FaceTarget ${AttackGUID}
;face -heading ${Math.Calc[${Me.Heading}+180]}
}
#endif
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]
Aggros1:Clear
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"
call Drink
wait 40 ${Me.Buff[Drink](exists)}
}
}
function FoodCheck()
{
if !${Me.Buff[Food](exists)}
{
call Eat
wait 40 ${Me.Buff[Food](exists)}
}
}
function FoodDrinkCheck()
{
if !${Me.Buff[Food](exists)}
{
call Eat
wait 40 ${Me.Buff[Food](exists)}
}
if !${Me.Buff[Food](exists)}
{
call Drink
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
Aggros1:Clear
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[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 ${Spell[Arcane Torrent](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)} && !${Me.InCombat}
{
Cast "Blessing of Wisdom"
call GlobalCooldown
}
else
if ${Spell[KEEPBLESSING](exists)}&&!${Me.Buff[KEEPBLESSING](exists)}&&${Me.PctMana}>${MinManaPct} && !${Me.InCombat}
{
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
}
}