; Warrior Routines
; Originally Tenshi, Beaky_Buzzard, various others.
; Almost Entirely rewritten for xp and PVP warrior play, there's very little defensive stance use.
; The bot will charge, switch stances, intercept, use berserker rage if available when feared.
; It keeps hamstring up and maximizes dps by using overpower, mortal strike or bloodthirst when available.
; There are a number of fixes to check for targets getting out of range and whatnot missing in the originals
;Leave this define Intact. Its testing if this file is loaded or not.
#define ROUTINES
#define USE_REND 0
#define USE_HAMSTRING 0
#define USE_BLOODRAGE 0
;
; The CombatPrep function is called once you have selected a target but before you enter combat.
;
function CombatPrep()
{
;Reset flag
DoCombatPrep:Set[FALSE]
}
function Attack(string AttackGUID)
{
;debug("In Attack function")
wait 10
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 HavePulled bool local FALSE
declare StuckCheck bool local FALSE
declare StuckCheckCount int local 0
declare StuckCheckTime int local
declare Aggros guidlist local
declare MovedBackMulti bool local FALSE
if ${AttackGUID.Equal[NULL]}||${AttackGUID.Equal[NOTARGET]}
{
call UpdateHudStatus "No target to attack"
}
call UpdateHudStatus "Attacking ${Object[${AttackGUID}].Name}"
Do
{
SavX:Set[${Me.X}]
SavY:Set[${Me.Y}]
SavZ:Set[${Me.Z}]
if !${Me.Buff[Battle Stance](exists)} && !${Me.InCombat} && ${Me.Action[Battle Stance].Usable}
{
;debug("Switching to Battle Stance at start of Attack()")
Cast "Battle Stance"
debug("Battle Stance: ${Me.Buff[Battle Stance](exists)}")
waitframe
}
; Ensure we are still facing our target loc
call SmartFacePrecision ${Object[${AttackGUID}].X} ${Object[${AttackGUID}].Y}
; Check we still have a valid target
if !${Object[${AttackGUID}](exists)}
{
call UpdateHudStatus "Target lost"
TargetGUID:Set[NOTARGET]
Return
}
; Check if the target is engaged already
if ${Unit[${AttackGUID}].Tapped}
{
call UpdateHudStatus "Target already engaged"
TargetGUID:Set[NOTARGET]
Return
}
; If we dont have our chosen unit targeted and were in range target it
if !${Target.GUID.Equal[${AttackGUID}]}&&${Object[${AttackGUID}].Distance}<${TargetingRange}
{
;debug("Targeting ${Object[${AttackGUID}].Name} at distance ${Object[${AttackGUID}].Distance}")
Target ${AttackGUID}
}
; Once our target is in range turn on attack
if !${Me.Attacking}&&${Target(exists)}&&${Object[${AttackGUID}].Distance}<${TargetingRange}
{
WoWScript AttackTarget()
}
; Check we havent picked up an aggro other than the mob we have targeted.
Aggros:Search[-units,-nearest,-aggro,-alive,-range 0-10]
if !${HavePulled}&&${Aggros.Count}>0&&${Aggros[1].GUID.NotEqual[${AttackGUID}]}
{
;debug("Untargeted Unit ${Object[${Aggros[1].GUID}].Name} has aggroed exiting Attack routine")
return
}
Aggros:Clear
if ${Object[${AttackGUID}].Distance} < 24 && !${HavePulled}
{
;debug("Checking for pulling ability.")
if ${Spell[Charge](exists)} && ${Target.Distance} < 24 && ${Target.Distance} > 8 && !${Me.InCombat}
{
if !${Me.Buff[Battle Stance](exists)}
{
debug("Switching to Battle Stance to charge...")
Cast "Battle Stance"
waitframe
}
;debug("Charging ${Target} at range ${Target.Distance} - Combat State: ${Me.InCombat}")
Cast "Charge"
;debug("Deciding to heroic striket or not")
}
HavePulled:Set[TRUE]
}
; Start main attack routine
if (${PullBeforeContinue}&&${HavePulled})||!${PullBeforeContinue}
{
if ${Me.CurrentRage} > 16 && ${Me.Action[Thunder Clap].Usable} && !${Spell[Thunder Clap].Cooldown} && !${Object[${AttackGUID}].Buff[Thunder Clap](exists)}
{
echo "move me forward"
move -forward
wait 10
move -stop
Cast "Thunder Clap"
}
if ${Me.Action[Victory Rush].Usable} && !${Spell[Victory Rush].Cooldown} && ${Target.Distance} < 5
{
Casts "Victory Rush"
}
;debug("Deciding to heroic striket or not")
if ${Me.Action[Heroic Strike].Usable} && !${Spell[Heroic Strike].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 12
{
Casts "Heroic Strike"
}
Aggros:Search[-players,-units,-hostile,-nearest,-aggro,-alive,-range 0-8]
if (${Target.Class.Equal[Priest]} || ${Target.Class.Equal[Warlock]}) && !${Me.Buff[Berserker Stance](exists)}
{
Cast "Berserker Stance"
}
;debug("Deciding to heroic striket or not")
if ${Me.Action[Heroic Strike].Usable} && !${Spell[Heroic Strike].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 12
{
Casts "Heroic Strike"
}
if (${Me.Buff[Psychic Scream](exists)} || ${Me.Buff[Intimidating Shout](exists)} || ${Me.Buff[Fear](exists)} || ${Me.Buff[Howl of Terror](exists)}) && ${Me.Buff[Berserker Stance](exists)} && ${Me.Action[Berserker Rage].Usable} && !${Spell[Berserker Rage].Cooldown}
{
cast "Berserker Rage"
}
;debug("Aggro Count: ${Aggros.Count}")
if (${Me.Buff[Battle Stance](exists)} || ${Me.Buff[Berserker Stance](exists)}) && ${Target.Distance} < 5
{
;debug("Checking for execute or hamstring... line 117")
if ${Target.PctHPs} < 20 && ${Me.CurrentRage} > 15 && ${Me.Action[Execute].Usable} && !${Spell[Execute].Cooldown}
{
;debug("Executing")
Cast "Execute"
}
;debug("Decided not to execute, checking Hamstring... line 123")
if ${Me.CurrentRage} > 7 && ${Me.Action[Hamstring].Usable} && !${Spell[Hamstring].Cooldown} && USE_REND && !${Object[${AttackGUID}].Buff[Hamstring](exists)}
{
;debug("Hamstringing")
Cast "Hamstring"
}
if ${Me.Action[Bloodrage].Usable} && !${Spell[Bloodrage].Cooldown} && USE_BLOODRAGE && ${Me.Target.PctHPs}>75
{
Cast "Bloodrage"
}
if ${Me.CurrentRage} > 16 && ${Me.Action[Thunder Clap].Usable} && !${Spell[Thunder Clap].Cooldown} && !${Object[${AttackGUID}].Buff[Thunder Clap](exists)}
{
Cast "Thunder Clap"
}
;debug("Deciding to Victory Rush or not")
if ${Me.Action[Victory Rush].Usable} && !${Spell[Victory Rush].Cooldown} && ${Target.Distance} < 5
{
Casts "Victory Rush"
}
;debug("Deciding to heroic striket or not")
if ${Me.Action[Heroic Strike].Usable} && !${Spell[Heroic Strike].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 12
{
Casts "Heroic Strike"
}
}
if ${Me.Buff[Battle Stance](exists)}
{
;debug("Checking for Overpower... line 138")
if ${Me.Action[Overpower].Usable} && !${Spell[Overpower].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 5
{
;debug("Overpowering")
Cast "Overpower"
}
;debug("Deciding to heroic striket or not")
if ${Me.Action[Heroic Strike].Usable} && !${Spell[Heroic Strike].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 12
{
Casts "Heroic Strike"
}
;debug("Overpower Not ready")
}
;debug("Deciding to intercept or not...")
if ${Me.InCombat} && ${Target.Distance} < 25 && ${Target.Distance} > 7 && ${Me.CurrentRage} > 9 && !${Spell[Intercept].Cooldown}
{
;debug("Checking for Intercept... line 149")
if !${Me.Buff[ Stance](exists)}
{
;debug("Switching to Berserker Stance... line 134")
call CastSpell "Berserker Stance"
waitframe
}
;debug("Intercepting ${Target} at Distance ${Target.Distance}")
call CastSpell "Intercept"
}
;debug("Deciding to cleave or not")
if ${Aggros.Count} == 2 && !${Spell[Cleave].Cooldown} && ${Me.CurrentRage} > 19 && ${Target.Distance} < 5
{
;debug("Cleaving...")
call CastSpell "Cleave"
}
;debug("Deciding to whirlwind or not...")
if ${Aggros.Count} > 2 && !${Spell[Whirlwind].Cooldown} && ${Me.CurrentRage} > 24 && ${Target.Distance} < 5 && ${Me.Action[Whirlwind].Usable}
{
;debug("Aggros.Count > 2, going to whirlwind...")
if !${Me.Buff[Berserker Stance](exists)}
{
;debug("Casting Berserker Stance... line 153")
Cast "Berserker Stance"
}
;debug("Deciding to heroic striket or not")
if ${Me.Action[Heroic Strike].Usable} && !${Spell[Heroic Strike].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 12
{
Casts "Heroic Strike"
}
;debug("Whirlwinding...")
Cast "Whirlwind"
}
;debug("Deciding to Mortal Strike or not... line 177")
if ${Me.Action[Mortal Strike].Usable} && !${Spell[Mortal Strike].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 30
{
Cast "Mortal Strike"
}
;debug("Deciding to Bloodthirst or not")
if ${Me.Action[Bloodthirst].Usable} && !${Spell[Bloodthirst].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 30
{
Casts "Bloodthirst"
}
;debug("Deciding to heroic striket or not")
if ${Me.Action[Heroic Strike].Usable} && !${Spell[Heroic Strike].Cooldown} && ${Target.Distance} < 5 && ${Me.CurrentRage} > 12
{
Casts "Heroic Strike"
}
;debug("Deciding to Rend or not")
if !${Object[${AttackGUID}].Buff[Rend](exists)} && ${Object[${AttackGUID}].Distance} < 5 && ${Me.CurrentRage} > 10 && !${Me.Action[Rend].Cooldown} && USE_REND && ${Object[${AttackGUID}].CreatureType.NotEqual[Mechanical]} && ${Object[${AttackGUID}].CreatureType.NotEqual[Elemental]}
{
call CastSpell "Rend"
}
;debug("Thinking about defensive stance stuff...")
if ${Me.Buff[Defensive Stance](exists)}
{
if ${Me.PctHPs} < 40 && !${Spell[Concussion Blow].Cooldown} && ${Me.CurrentRage} >= 15
{
call CastSpell "Concussion Blow"
}
if ${Me.PctHPs} < 50 && !${Spell[Disarm].Cooldown} && ${Me.CurrentRage} >= 20
{
call CastSpell "Disarm"
}
if ${Me.PctHPs} < 20 && !${Spell[Shield Wall].Cooldown}
{
call CastSpell "Shield Wall"
}
}
;debug("Deciding to last stand or not...")
if ${Me.PctHPs} < 15 && !${Spell[Last Stand].Cooldown} && ${Me.Action[Last Stand].Usable}
{
Cast "Last Stand"
}
; buffs
;debug("Deciding to battle shout or not")
if !${Me.Buff[Battle Shout](exists)} && ${Me.CurrentRage}>=10 && !${Spell[Battle Shout].Cooldown} && ${Me.Action[Battle Shout].Usable}
{
call CastSpell "Battle Shout"
}
}
; Check if we wish to flee combat or not
;debug("Deciding to flee or not...")
Aggros:Search[-units,-nearest,-aggro,-alive, -range 0-${Math.Calc[${MaxRoam}/2]}]
;debug("Aggros.Count: ${Aggros.Count}")
Aggros:Clear
;If too far away run forward
if ${Target.Distance} > ${CombatMaxDist} && !${Me.Casting}
{
;debug("Too far closing")
;press and hold the forward button
wowpress -release movebackward
wowpress -hold moveforward
}
;If too close then run backward
if ${Object[${AttackGUID}].Distance}<${CombatMinDist}&&!${Me.Casting}
{
;debug("Too close backing up")
;press and hold the backward button
wowpress -release moveforward
wowpress -hold movebackward
}
;If we are close enough stop running
if (${Object[${AttackGUID}].Distance}>${CombatMinDist}&&${Object[${AttackGUID}].Distance}<${CombatMaxDist})||${Me.Casting}
{
wowpress -release moveforward
wowpress -release movebackward
StuckCheck:Set[FALSE]
}
;wait for half a second to give our pc a chance to move
wait 2
; 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&&${Object[${AttackGUID}].Distance}>${CombatMaxDist}
{
; I think i might be stuck so save off the current time
if !${StuckCheck}
{
;debug("I might be stuck")
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
{
;debug("Yep I am stuck trying to free myself")
call Obstacle
StuckCheckCount:Inc
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
{
;debug("I am no longer stuck")
StuckCheck:Set[FALSE]
StuckCheckCount:Set[0]
}
;If I am stuck too many times then quit.
if ${StuckCheckCount}>10
{
;debug("Got stuck to often")
call ExitGame
}
; Check if we have exceeded bail out timer and the mob is still at full health
if ${LavishScript.RunningTime}>${BailOut}&&${Object[${TargetGUID}].PctHPs}>99
{
GUIDBlacklist:Set[${TargetGUID},AVOID]
call UpdateHudStatus "Combat timeout reached"
TargetGUID:Set[NOTARGET]
return
}
if ${Object[${AttackGUID}](exists)} && !${Me.Dead} && ${Object[${AttackGUID}].Distance} > 100
{
if ${Target(exists)}
{
Press Esc
}
TargetGUID:Set[NOTARGET]
AttackGUID:Set[NOTARGET]
call SetAdvancePath
return
}
}
while !${Me.Dead} && ${Object[${AttackGUID}].Distance} < 100 && !${Object[${AttackGUID}].Dead}
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[-players,-units,-hostile,-nearest,-aggro,-alive,-range 0-50]
if !${Aggros.Count}
{
;debug("Resetting Downtime and CombatPrep Flags")
DoDowntime:Set[TRUE]
DoCombatPrep:Set[TRUE]
}
Aggros:Clear
}
function Downtime()
{
if ${Me.PctHPs}<${MinHealthPct}
{
call CheckDurability
while ${Me.PctHPs}<99&&!${Me.InCombat}&&!${Me.Dead}&&!${Me.Ghost}
{
if ${SitWhenRest} && !${Me.Sitting}
{
wowpress SITORSTAND
}
if ${Me.PctHPs}<55 && !${Me.Buff[Food](exists)}
{
call Eat
wait 40 ${Me.Buff[Food](exists)}
}
waitframe
}
}
;Make sure we are stood up.
if ${Me.Sitting}
{
wowpress SITORSTAND
}
; Reset downtime flag
DoDowntime:Set[FALSE]
}