All pastes #443980 Raw Edit

Someone

public text v1 · immutable
·published 2007-04-17 03:50 UTC
rendered paste body
/*
---------------------------------------------------------------------------
          iiDD          ttKK##WWLLLLDDDDtt..    ttWW##DDLL  ::GG####LLLL
          ffWW            LL##DD    iiKKKKff      LL##ii      ..WWKK    
          KK##ii          tt##GG      ..KK##jj    tt##..        KKGG    
        ttttKKDD;;        tt##GG        iiEEWW    tt##..        KKGG    
        DD  jj##GG        tt##GG          LL##;;  tt##..        KKGG    
      ;;LL  ..####..      tt##GG          tt##ii  tt##LLLLLLLLLLWWGG    
      DDGGLLLLWW##tt      tt##GG          LL##;;  tt##..        KKGG    
    ::GG      iiEEKK      tt##GG        iiEEWW    tt##..        KKGG    
    tttt      ..LL##..    tt##GG        ffWWGG    tt##..        KKGG    
    DD..        ;;##jj    tt##GG      tt##WW..    tt##..        KKGG    
ttDD##LL      iiGG####LLttWW##WWLLLLDDDDii..    ttWW##DDLL  ::GG####LLLL
---------------------------------------------------------------------------

; Reworked routine from "Project: Awesome Hunter Routine", which was originally created by Etox

; reworked by kras
*/

;Leave this define Intact. Its testing if this file is loaded or not.
#define ROUTINES

;Toggleable defines:			/* Commenting out a "Toggleable" define will disable the feature */


#define REVIVE_PET			/* Revive your pet in downtime?*/
#define FOOD_NAME "Tough Hunk of Bread"		/* Name of food to feed pet with */
#define MEND_LIMIT 40			/* % Hp limit for Mend Pet in combat */
#define MAX_STUCK 10 			/* How many attempts to free yourself when stuck before using heartstone and logout */
#define USE_MARK 			/* Do you want to cast hunters mark when pulling? */
#define USE_SERPENT			/* Do you want to use Serpent Sting? */
;#define PULL_FIRST			/* concussive shot pull to open? /*
;#define USE_SCORPID			/* Do you want to use Scorpid Sting? */
#define USE_ARCANE_MP 90		/* Do you want to use Arcane hots? */
;#define USE_CONCUSSIVE 20		/* Do you want to use Concussive hots on humanoids? If so at what %? */
#define USE_AIMED_SHOT			/* Do you want to pull with Aimed shot? */
#define AIMED_MP 65
;#define USE_MONGOOSE			/* Do you want to use Mongoose Bite? */
#define SWITCH_MONKEY 			/* Do you want aspect of the monkey when entering melee?(Pure melee not affected)*/
	
;Pure value defines:			/* Just change the values in the following ones */

#define ARROW_NAME "Razor Arrow"	/* Name of your arrows */
#define FEIGN_LIMIT 10			/* % Hp limit for when to feign death */
#define REVIVE_COST 188	/* The mana cost of your "Reive Pet" spell */


;
; 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)
{
   
declare SavX float ${Me.X}
declare SavY float ${Me.Y}
declare SavZ float ${Me.Z}
declare BailOut int ${Math.Calc[${LavishScript.RunningTime}+(1000*${CombatBailout})]}
declare HavePulled bool FALSE
declare StuckCheck bool FALSE
declare StuckCheckTime int
declare HaveArrows guidlist
declare Aggros guidlist
declare AggroCount int 0
declare AggroMe int 0
declare AggroPet int 0
declare AggroGUID string
declare Index int 0
if !${Script[wowbot].Variable[AttackState](exists)}
	declare AttackState string script RANGED
else
	AttackState:Set[RANGED]

if !${Script[wowbot].Variable[EvadeCount](exists)}
	declare EvadeCount int script 0

; Reset the count for evades
EvadeCount:Set[0]

; triggers
addtrigger evade "[Event:@*@:CHAT_MSG_SPELL_SELF_DAMAGE](\"Your @SPELLNAME@ was evaded by @MOB@.@*@"
;"
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}]

	; Check we still have a valid target
	if !${Unit[${AttackGUID}](exists)}
	{
		call UpdateHudStatus "Target lost"
		TargetGUID:Set[NOTARGET]
		Return
 	}
 	
 	if ${Unit[${AttackGUID}].FactionGroup.Equal[Alliance]} 
			   { 
			      ;add them to a blacklist or whatever here... 
			      call UpdateHudStatus "Target is an alliance member, don't bother attacking them" 
			      GUIDBlacklist:Set[${AttackGUID},AVOID] 
			      TargetGUID:Set[NOTARGET] 
			      Return 
	   		   } 
	
			if ${Unit[${AttackGUID}].Faction.Equal[Cenarion Circle]} 
			   { 
			      ;add them to a blacklist or whatever here... 
			      call UpdateHudStatus "Target is an alliance member, don't bother attacking them" 
			      GUIDBlacklist:Set[${AttackGUID},AVOID] 
			      TargetGUID:Set[NOTARGET] 
			      Return 
	   		   } 

       
	; Check if the target is engaged already
	if ${Unit[${AttackGUID}].Tapped}
	{
		call UpdateHudStatus "Target already engaged"
		TargetGUID:Set[NOTARGET]
		WoWScript PetFollow()
		Return         
 	}
	
	; If we dont have our chosen unit targeted and were in range target it
	if !${Target.GUID.Equal[${AttackGUID}]}&&${Unit[${AttackGUID}].Distance}<${TargetingRange}
	{
 		debug(*Routine* Current Target: ${Target.GUID} Targeting Unit: ${Unit[${AttackGUID}].Name}[${AttackGUID}])
 		Target ${AttackGUID}
 		waitframe
	}

	; Ensure we are still facing our target loc
	call SmartFace ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y}
	
	; Check if we still have ammo
	HaveArrows:Search[-exact,ARROW_NAME]

	; and go pure melee if we don't
	if (!${HaveArrows.Count} || ${Me.Equip[ranged].Durability}==0) &&${AttackState.NotEqual[PURE_MELEE]}
	{
		debug(*Routine* We are now out of ammo and wondering why the heck we choosed to bot a hunter)
		AttackState:Set[PURE_MELEE]
	}

	if ${Target.PctHPs}>99
		declare Immune-Serp bool global FALSE
		
	Event[CHAT_MSG_SPELL_SELF_DAMAGE]:AttachAtom[immunechecks]

	; check if we have pulled, if so do the attack stuff
	if ${HavePulled}
	{
		; Check if the target is engaged already
			if ${Unit[${AttackGUID}].Tapped}
			{
				call UpdateHudStatus "Target already engaged"
				TargetGUID:Set[NOTARGET]
				WoWScript PetFollow()
				Return         
 			}
		
		if !${Me.Pet.Target.GUID.Equal[${AttackGUID}]}
		{
			debug(*Routine* Asking pet to attack)
			wowscript PetAttack()
		}
		switch ${AttackState}
		{
			case RANGED
				
				call Ranged ${AttackGUID}
				if ${Return.Equal[MELEE]}
				{
					Call UpdateHudStatus "Switching to Melee"
					AttackState:Set[MELEE]
				}
				break

			case MELEE

				call Melee ${AttackGUID}
				if ${Return.Equal[RANGED]}
				{
					Call UpdateHudStatus "Switching to Ranged"
					AttackState:Set[RANGED]
				}
				break

			case PURE_MELEE

				call Melee ${AttackGUID}
				break

			default debug(*Routine* We don't have an AttackState)
 		}
	}
	; Else pull if we still have some ammo.
	else
	{
		; Check if another mob aggroed before we pull
		Aggros:Search[-units,-nopets,-nearest,-aggro,-alive,-range 0-100]

		if !${Unit[${AttackGUID}].Aggro}&&${Aggros.Count}>0
		{
			debug(*Routine* The Unit: ${Unit[${Aggros.GUID[1]}].Name}[${Unit[${Aggros.GUID[1]}]}] has aggroed us. Interupting the pulling.)
			TargetGUID:Set[NOTARGET]
			return
		}
		Aggros:Clear

		if ${HaveArrows.Count}&&!${Unit[${AttackGUID}].Aggro}
		{
			call Pull ${AttackGUID}
			if ${Return}
			{
				HavePulled:Set[TRUE]
				continue
			}
		}
		else
		{
			HavePulled:Set[TRUE]
			continue
		}
	}

	;wait for half a second to give our pc a chance to move
	wait 5

	; Stuck checks
	if ${AttackState.Equal[RANGED]}
	{

		
		; Check if the target is engaged already
			if ${Unit[${AttackGUID}].Tapped}
			{
				call UpdateHudStatus "Target already engaged"
				TargetGUID:Set[NOTARGET]
				WoWScript PetFollow()
				Return         
 	}
		
		; 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}>${RangedMaxDist}
		{
			; I think i might be stuck so save off the current time
			if !${StuckCheck}
			{
				debug(*Routine* 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(*Routine* Yep I am stuck trying to free myself)
					call Obstacle
					StuckCheckCount:Inc
					StuckCheck:Set[FALSE]
				}
			}
		}
	}
	elseif ${AttackState.Equal[MELEE]}||${AttackState.Equal[PURE_MELEE]}
	{
		;wait for half a second to give our pc a chance to move
	 	wait 5
       
      		; Check if the target is engaged already
			if ${Unit[${AttackGUID}].Tapped}
			{
				call UpdateHudStatus "Target already engaged"
				TargetGUID:Set[NOTARGET]
				WoWScript PetFollow()
				Return         
 	}
      		
      		; 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}>${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(*Routine* I am no longer stuck)
		StuckCheck:Set[FALSE]
		StuckCheckCount:Set[0]
	}

	#ifdef MAX_STUCK
	;If I have been stuck too many times then quit.
	if ${StuckCheckCount}>MAX_STUCK
	{
		debug(*Routine* Got stuck to often. Quitting the game)
		call ExitGame
	}
	#endif
		
	; Check if we have exceeded bail out timer and the mob is still at full health
	if ${LavishScript.RunningTime}>${BailOut}&&${Unit[${TargetGUID}].PctHPs}>99
	{
		GUIDBlacklist:Set[${TargetGUID},AVOID]
		call UpdateHudStatus "Combat timeout reached"
		TargetGUID:Set[NOTARGET]
		return
	}

	; Safety things

	; Check if the target is engaged already
		if ${Unit[${AttackGUID}].Tapped}
		{
			call UpdateHudStatus "Target already engaged"
			TargetGUID:Set[NOTARGET]
			WoWScript PetFollow()
			Return         
 	}
	
	; Feign Death if less than FEIGN_LIMIT % HP
	if ${Me.PctHPs}<FEIGN_LIMIT&&${Spell[Feign Death](exists)}&&!${Spell[Feign Death].Cooldown}
 	{
		move -stop
		waitframe
		call UpdateHudStatus "Feigning Death"
		call CastSpell "Feign Death" ${Me.GUID}
		wait 10
		if ${Me.Buff[Feign Death](exists)}
		{
			while ${Me.InCombat}
			{
				wait 10
			}
			; Jump once to break out of fd
			wowpress jump
			wait 10

			;Reset flags to do combat prep and downtime
			DoDowntime:Set[TRUE]
			DoCombatPrep:Set[TRUE]
			return
		}
		else
		{
			debug(*Routine* Feign Death got resisted. Time to flee!)
			RLG:Set[TRUE]
			return
		}
	}

	; Check if we should flee
	AggroMe:Set[0]
	AggroPet:Set[0]
	Index:Set[0]
	Aggros:Search[-units,-nopets,-nearest,-aggro,-alive,-range 0-40]

	; Count the aggros
	while ${Index:Inc}<=${Aggros.Count}
	{
		if ${Unit[${Aggros.GUID[${Index}]}].Target.GUID.Equal[${Me.Pet.GUID}]}
			AggroPet:Inc
		elseif ${Unit[${Aggros.GUID[${Index}]}].Target.GUID.Equal[${Me.GUID}]}
		{
			if !${AggroMe}
				AggroGUID:Set[${Aggros.GUID[1]}]
			AggroMe:Inc
		}
	}
	AggroCount:Set[${AggroPet} + ${AggroMe}]
	
	if ${Spell[Bestial Wrath](exists)} && !${Spell[Bestial Wrath].Cooldown} && ${AggroCount}>1
		{
			cast "Bestial Wrath"
		}
		
		if ${Me.Action[Rapid Fire].Usable} && ${AggroCount}>1 && !${Me.Pet.Buff[Bestial Wrath](exists)} && !${Me.Action[Bestial Wrath].Usable}
		{
			call CastSpell "Rapid Fire" ${Me.GUID}
		}
	

	if (${AggroCount}>=${Math.Calc[${PanicThreshold}+2]})||(${AggroCount}>${PanicThreshold}&&${Me.PctHPs}<40||!(${Me.Pet.Health}!=0)&&${Me.PctHPs}<40&&${Unit[${AttackGUID}].PctHPs}>30||${Me.Pet.Health}>0&&${AggroPet}&&${AggroMe}&&${Me.PctHPs}<30&&${Unit[${AttackGUID}].PctHPs}>30
	{ 
		debug(*Routine* I have ${AggroCount} Aggro mobs. Time to flee!)
		RLG:Set[TRUE]
		return
	}

	; If there is mob/mobs on us and pet only has one, order him to help out
	if ${AggroMe}&&${AggroPet}<3
	{
		while ${Unit[${AggroGUID}].Target.GUID.NotEqual[${Me.Pet.GUID}]}&&${Me.Pet.Health}!=0
		{
			if !${Target.GUID.Equal[${AggroGUID}]}
			{
				target ${AggroGUID}
				waitframe
			}
			if !${Me.Pet.Target.GUID.Equal[${AggroGUID}]}&&${Me.Pet.Health}!=0
			{
				wowscript PetAttack()
				waitframe
			}
			waitframe
		}
	}
	Aggros:Clear

	if ${QueuedCommands}
		ExecuteQueued evade
}
while !${Unit[${AttackGUID}].Dead}&&!${Me.Dead}

move -stop

; Update stats
if !${Me.Dead}
{
	call UpdateStats
}

wowpress -release movebackward
wowpress -release moveforward

;Reset flags to do combat prep and downtime
DoDowntime:Set[TRUE]
DoCombatPrep:Set[TRUE]

Return
}


function Ranged(string AttackGUID)
{
	; Check if the target is engaged already
		if ${Unit[${AttackGUID}].Tapped}
		{
			call UpdateHudStatus "Target already engaged"
			TargetGUID:Set[NOTARGET]
			WoWScript PetFollow()
			Return         
 		}
	
	
	if ${Me.Action[Intimidation].Usable} && (${Unit[${AttackGUID}].Casting(exists)} || ${Me.Target.Target.Name.Equal[${Me}]} && ${Target.PctHPs}>20 && ${Target.PctHPs}<90
		call CastSpell "Intimidation" ${Target.GUID}
	; Cast Bestial Wrath
	
	
	if !${Me.Buff[Aspect of the Hawk](exists)}
	{
		call CastOnRun "Aspect of the Hawk"
	}
          
	if !${Me.Action[Auto Shot].AutoRepeat}&&${Unit[${AttackGUID}].Distance}<${RangedMaxDist}&&${Unit[${AttackGUID}].Distance}>${RangedMinDist}
	{
		cast "Auto Shot"
	}

	; Check if we are close enough and have mana
	if ${Unit[${AttackGUID}].Distance}<${RangedMaxDist}&&${Unit[${AttackGUID}].Distance}>${RangedMinDist}&&${Me.PctMana}>10
	{
		
		
		#ifdef USE_SERPENT
		; Cast Serpent Sting
		if !${Immune-Serp} && !(${Target.CreatureType.Equal[Mechanical]} || ${Target.CreatureType.Equal[Undead]}) && ${Me.Action[Serpent Sting].Usable}&&${Unit[${AttackGUID}].PctHPs}>20&&!${Unit[${AttackGUID}].Buff[Serpent Sting](exists)}
		{
			call CastSpell "Serpent Sting" ${AttackGUID}
		}
		#endif

		#ifdef USE_SCORPID
		; Cast Scorpid Sting
		if !${Spell[Scorpid Sting].Cooldown}&&${Unit[${AttackGUID}].PctHPs}>20&&!${Unit[${AttackGUID}].Buff[Scorpid Sting](exists)}
		{
			call CastSpell "Scorpid Sting" ${AttackGUID}
		}
		#endif
		
		#ifdef USE_AIMED_SHOT
		if ${Me.Action[Aimed Shot].Usable}&&${Unit[${AttackGUID}].PctHPs}>50&&${Me.PctMana}>AIMED_MP
		{
			call CastSpell "Aimed Shot" ${AttackGUID}
		}		
		#endif
		
		#ifdef USE_ARCANE_MP
		; Cast Arcane Shot
		if !${Spell[Arcane Shot].Cooldown}&&${Unit[${AttackGUID}].PctHPs}>20&&${Me.PctMana}>USE_ARCANE_MP
		{
			call CastSpell "Arcane Shot" ${AttackGUID}
		}
		#endif

		#ifdef USE_CONCUSSIVE
		; If Target is humanoid and has Low HP. Cast Slowing Spell
		if !${Spell[Concussive Shot].Cooldown}&&${Unit[${AttackGUID}].CreatureType.Equal[Humanoid]}&&${Unit[${AttackGUID}].PctHPs}<USE_CONCUSSIVE
		{
			call CastSpell "Concussive Shot" ${AttackGUID}
		}
		#endif
	
		#ifdef MEND_LIMIT
		; Mend Pet
		if ${Me.Action[Mend Pet].Usable} && ${Me.Pet.PctHPs}<MEND_LIMIT&&${Me.Pet.Health}!=0
		{
			call MendPet
		}
		#endif
      	}

 	; If we are to close and the mob has targeted us go into melee
	if ${Unit[${AttackGUID}].Target.GUID.Equal[${Me.GUID}]}&&${Unit[${AttackGUID}].Distance}<${RangedMinDist}
	{
		debug(*Routine* *Switching to Melee* Mobs target: ${Unit[${AttackGUID}].Target.GUID} Me: ${Me.GUID} Distance: ${Unit[${AttackGUID}].Distance}<${RangedMinDist})
		return MELEE
	}
			
	; Else run backward
	if ${Unit[${AttackGUID}].Distance}<${RangedMinDist}
	{
		debug(*Routine* To close for ranged attacks. Backing)
		;press and hold the backward button
		wowpress -release moveforward
		wowpress -hold movebackward
	}     


	;If too far away run forward
	if ${Unit[${AttackGUID}].Distance}>${RangedMaxDist}
	{
		debug(*Routine* to far away for ranged attacks. Closing.)
		;press and hold the forward button
		wowpress -release movebackward
		wowpress -hold moveforward
	}

	;If we are close enough stop running
	if ${Unit[${AttackGUID}].Distance}>${RangedMinDist}&&${Unit[${AttackGUID}].Distance}<${RangedMaxDist}
	{
		wowpress -release moveforward
		wowpress -release movebackward
	}
}

function Melee(string AttackGUID)
{
	; Check if the target is engaged already
		if ${Unit[${AttackGUID}].Tapped}
		{
			call UpdateHudStatus "Target already engaged"
			TargetGUID:Set[NOTARGET]
			WoWScript PetFollow()
			Return         
 	}
	
	;initiate attack
	if !${Me.Attacking}
	{
		Call UpdateHudStatus "Attacking Target in Melee"
		WoWScript AttackTarget()
	}

	#ifdef SWITCH_MONKEY
	if !${Me.Buff[Aspect of the Monkey](exists)}
	#else
	if ${AttackState.Equal[PURE_MELEE]}&&!${Me.Buff[Aspect of the Monkey](exists)}
	#endif
	{
		call CastOnRun "Aspect of the Monkey"
	}

	#ifdef USE_MONGOOSE
	if ${Me.Action[Mongoose Bite].Usable}&&${Unit[${AttackGUID}].Distance}<${CombatMaxDist}&&${Me.PctMana}>20
	{
		call CastSpell "Mongoose Bite" ${AttackGUID}
	}
	#endif

	
		
	;Cast Disengage
	if ${Me.Action[Disengage].Usable} && ${Me.Pet(exists)}
	{
		call CastSpell "Disengage" ${AttackGUID}
	}
	
	;Cast Raptor Strike
	elseif !${Spell[Raptor Strike].Cooldown}&&${Unit[${AttackGUID}].Distance}<${CombatMaxDist}&&${Me.PctMana}>20
	{
		call CastSpell "Raptor Strike" ${AttackGUID}
	}
	
	#ifdef MEND_LIMIT
	; Mend Pet
	if ${Me.Pet.PctHPs}<MEND_LIMIT&&!${Me.Pet.Dead}
	{
		call MendPet
	}
	#endif

	; If pet has regained aggro we switch back to ranged state
	if ${Unit[${AttackGUID}].Target.GUID.Equal[${Me.Pet.GUID}]}&&${AttackState.NotEqual[PURE_MELEE]}
	{
		return RANGED
	}

	;If we are close enough stop running
	if ${Unit[${AttackGUID}].Distance}>${CombatMinDist}&&${Unit[${AttackGUID}].Distance}<${CombatMaxDist}
	{
		wowpress -release moveforward
		wowpress -release movebackward
	}

	;If too far away run forward
	if ${Unit[${AttackGUID}].Distance}>${CombatMaxDist}	
	{
		debug(*Routine* To far away for melee. Closing.)
		;press and hold the forward button
		wowpress -release movebackward
		wowpress -hold moveforward
	}

	;If too close then run backward
	if ${Unit[${AttackGUID}].Distance}<${CombatMinDist}
	{
      		debug(*Routine* To close for melee. Backing.)
       		;press and hold the backward button
       		wowpress -release moveforward
       		wowpress -hold movebackward
	}
}

function Pull(string AttackGUID)
{
	
	; Ensure we are still facing our target loc
	call SmartFace ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y}
	
	;If too far away run forward
	if ${Unit[${AttackGUID}].Distance}>${RangedMaxDist}
	{
		debug(*Routine* To far away to pull)
		;press and hold the forward button
		wowpress -release movebackward
		wowpress -hold moveforward
	}	

	; If to close run back
	if ${Unit[${AttackGUID}].Distance}<${RangedMinDist}
	{
		debug(*Routine* to close to pull)
		;press and hold the backward button
		wowpress -release moveforward
		wowpress -hold movebackward
	}     

	; Once we get close to our target then pull it
	if ${Unit[${AttackGUID}].Distance}>${RangedMinDist}&&${Unit[${AttackGUID}].Distance}<${RangedMaxDist}
	{	
		;First stop
 		move -stop
		
		; If we dont have our chosen unit targeted, target it
		if !${Target.GUID.Equal[${AttackGUID}]}
		{
 			debug(*Routine* *Pulling* Current Target: ${Target.GUID} Targeting Unit ${Unit[${AttackGUID}].Name}[${AttackGUID}])
 			Target ${AttackGUID}
 			waitframe
 			
		}

		#ifdef USE_MARK
		call UpdateHudStatus "Casting Hunter's Mark"
		call CastSpell "Hunter's Mark" ${Target.GUID}
		#endif
		
		#ifdef PULL_FIRST
		call CastSpell "Concussive Shot" ${Target.GUID}
		wait 10
		#endif
		
		; Send in pet
		wowscript PetAttack()
		waitframe

		
		
		#ifdef USE_AIMED_SHOT
		waitframe
		if ${Me.Action[Aimed Shot].Usable}
		call CastSpell "Aimed Shot"
		else		
		call CastSpell "Arcane Shot"
		wait 70 ${Me.Action[Auto Shot].AutoRepeat}&&${Math.Distance[${Me.Pet.X},${Me.Pet.Y},${Unit[${AttackGUID}].X},${Unit[${AttackGUID}].Y}]}<10
		return TRUE
		#else
		wait 10 ${Math.Distance[${Me.Pet.X},${Me.Pet.Y},${Unit[${AttackGUID}].X},${Unit[${AttackGUID}].Y}]}<10
		return TRUE
		#endif
 	}
	return FALSE
}

#ifdef MEND_LIMIT
function MendPet()
{
	declare SavX float local ${Me.X}
	declare SavY float local ${Me.Y}
	declare SavZ float local ${Me.Z}
	declare StuckCheck bool local FALSE
	declare StuckCheckTime int local

	while ${Me.Pet.Health}!=0
	{
		; Ensure we are still facing our target loc
		call SmartFace ${Me.Pet.X} ${Me.Pet.Y}

		; Else run backward
		if ${Me.Pet.Distance}<${CombatMinDist}
		{
			debug(*Routine* To close for mending. Backing.) 
			;press and hold the backward button
			wowpress -release moveforward
			wowpress -hold movebackward
		}     


		;If too far away run forward
		if ${Me.Pet.Distance}>20
		{
			debug(*Routine* To far away for mending. Closing.)
			;press and hold the forward button
			wowpress -release movebackward
			wowpress -hold moveforward
		}

		;If we are close enough stop running and mend pet
		if ${Me.Pet.Distance}>${CombatMinDist}&&${Me.Pet.Distance}<20
		{
			wowpress -release moveforward
			wowpress -release movebackward
			waitframe
			call CastSpell "Mend Pet" ${Me.Pet.GUID}
			break
		}

		;wait for half a second to give our pc a chance to move
		wait 5

		; 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&&${Me.Pet.Distance}>${RangedMaxDist}
		{
			; I think i might be stuck so call back pet
			wowscript PetPassiveMode()
			wait 50 ${Me.Pet.Distance}<20
		}
	}
}
#endif

function evade(string Line, string Spellname, string Mob)
{
	call UpdateHudStatus "Your ${Spellname} was evaded by ${Mob}"
	EvadeCount:Inc
	debug(EvadeCount: ${EvadeCount})
}

function Downtime(int repeat=0)
{
	if ${Item[-inventory,Scroll of](exists)}
	{
		Item:[Scroll of]:Use
	}
	
	#ifdef REVIVE_PET
	; Revive pet if dead, else call him
	if !(${Me.Pet.Health}!=0)
	{
		move -stop
		call UpdateHudStatus "Trying to call pet"
		call CastSpell "Call Pet" ${Me.GUID}
		wait 20 !${Me.GlobalCooldown}
		if !(${Me.Pet.Health}!=0)
		{
			if ${Me.CurrentMana}>REVIVE_COST
			{
				wait 15
				call UpdateHudStatus "Pet seems to be dead, lets rez him"
				CastSpell "Revive Pet"
				wait 20 ${Me.Casting}
				while ${Me.Casting}
				{
					waitframe
				}
				wait 10
				call UpdateHudStatus "Mending Pet"
				CastSpell "Mend Pet"
				wait 20 ${Me.Casting}
				while ${Me.Casting}
				{
					waitframe
				}
				wait 10
			}
			else
			{
				repeat:Inc
			}
		}
		wait 10
	}
	#endif

	#ifdef FOOD_NAME
	if ${Me.Pet.PctHappiness}<70&&${Me.Pet.Health}!=0
	/* &&${Item[FOOD_NAME](exists)}*/
	{
		/*cast "feed pet"
		wait 20 ${WoWScript[SpellIsTargeting()]}
		waitframe
		Item[-exact,FOOD_NAME]:Use
		wait 1
		wowscript SpellStopTargeting()
		*/
		type f
		wait 10
	}
	#endif

	if (${Me.PctHPs}<${MinHealthPct}||${Me.PctMana}<${MinManaPct}||${repeat}==1)&&!${Me.Dead}&&!${Me.Ghost}
	{
		if ${SitWhenRest}&&!${Me.Sitting}
		{
			wowpress SITORSTAND
		}

		if ${Me.PctHPs}<80 && !${Me.Buff[Food](exists)}
		{
			call Eat
			wait 40 ${Me.Buff[Food](exists)}
		}
		
		if ${Me.PctMana}<80 && !${Me.Buff[Drink](exists)}
		{
			call Drink
			wait 40 ${Me.Buff[Drink](exists)}
		}

		while (${Me.PctHPs}<90||${Me.PctMana}<90)&&!${Me.InCombat}&&!${Me.Dead}&&!${Me.Ghost}
		{
			waitframe
		}
	}

	call check_for_lootable_containers
	
	;Make sure we are stood up.
	if ${Me.Sitting}
	{
		wowpress SITORSTAND
	}

	; Check if we need to repair
	call CheckDurability

	; Reset downtime flag
	DoDowntime:Set[FALSE]

	; Do we need to repeat downtime?
	if ${repeat}==1
		call Downtime ${repeat:Inc}
}

function check_for_lootable_containers() 
{ 
   while ${Item["Small Barnacled Clam"].Slot(exists)} && ${Item["Small Barnacled Clam"].Bag.Number(exists)} 
      { 
         call lootContainer "Small Barnacled Clam" 
   } 
   
   while ${Item["Big-mouth Clam"].Slot(exists)} && ${Item["Big-mouth Clam"].Bag.Number(exists)} 
   { 
      call lootContainer "Big-mouth Clam" 
   } 
   while ${Item["Thick-shelled Clam"].Slot(exists)} && ${Item["Thick-shelled Clam"].Bag.Number(exists)} 
      { 
         call lootContainer "Thick-shelled Clam" 
   } 
   while ${Item["Bloated Catfish"].Slot(exists)} && ${Item["Bloated Catfish"].Bag.Number(exists)} 
   { 
      call lootContainer "Bloated Catfish" 
   } 
   while ${Item["Bloated Mud Snapper"].Slot(exists)} && ${Item["Bloated Mud Snapper"].Bag.Number(exists)} 
   { 
      call lootContainer "Bloated Mud Snapper" 
   } 
   while ${Item["Bloated Redgill"].Slot(exists)} && ${Item["Bloated Redgill"].Bag.Number(exists)} 
   { 
      call lootContainer "Bloated Redgill" 
   } 
   while ${Item["Bloated Salmon"].Slot(exists)} && ${Item["Bloated Salmon"].Bag.Number(exists)} 
   { 
      call lootContainer "Bloated Salmon" 
   } 
   while ${Item["Bloated Smallfish"].Slot(exists)} && ${Item["Bloated Smallfish"].Bag.Number(exists)} 
   { 
      call lootContainer "Bloated Smallfish" 
   } 
   while ${Item["Bloated Trout"].Slot(exists)} && ${Item["Bloated Trout"].Bag.Number(exists)} 
   { 
      call lootContainer "Bloated Trout" 
   } 
   while ${Item["Dented Crate"].Slot(exists)} && ${Item["Dented Crate"].Bag.Number(exists)} 
   { 
      call lootContainer "Dented Crate" 
   } 
   while ${Item["Heavy Crate"].Slot(exists)} && ${Item["Heavy Crate"].Bag.Number(exists)} 
   { 
      call lootContainer "Heavy Crate" 
   } 
   while ${Item["Message in a Bottle"].Slot(exists)} && ${Item["Message in a Bottle"].Bag.Number(exists)} 
   { 
      call lootContainer "Message in a Bottle" 
   } 
   while ${Item["Sealed Crate"].Slot(exists)} && ${Item["Sealed Crate"].Bag.Number(exists)} 
   { 
      call lootContainer "Sealed Crate" 
   } 
   while ${Item["Small Chest"].Slot(exists)} && ${Item["Small Chest"].Bag.Number(exists)} 
   { 
      call lootContainer "Heavy Crate" 
   } 
   while ${Item["Waterlogged Crate"].Slot(exists)} && ${Item["Waterlogged Crate"].Bag.Number(exists)} 
   { 
      call lootContainer "Waterlogged Crate" 
   } 
   while ${Item["Battered Chest"].Slot(exists)} && ${Item["Battered Chest"].Bag.Number(exists)} 
   { 
      call lootContainer "Battered Chest" 
   } 
   while ${Item["Large Battered Chest"].Slot(exists)} && ${Item["Large Battered Chest"].Bag.Number(exists)} 
   { 
      call lootContainer "Large Battered Chest" 
   } 
}


function lootContainer(string itemName) 
{ 
   if !${Me.Casting} 
   { 
      Item["${itemName}"]:Use 
      wait 10 ${LootWindow(exists)} 

      lootall 
      wait 15 !${LootWindow(exists)} 
   } 
   else 
   { 
      wait 10 
   } 
}

atom(script) immunechecks(string eventid , text, Message)
{
	if ${Message.Find["Serpent Sting"]}&&${Message.Find["failed"]}&&${Message.Find["immune"]}
	{
		declare Immune-Serp bool global TRUE
	}
	
	if ${Message.Find["afflicted by Serpent Sting"]}||${Message.Find["damage from your Serpent Sting"]}
	{
		declare Immune-Serp bool global FALSE
	}
}