All pastes #397538 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-03-16 15:42 UTC
rendered paste body
;Stealthy's Mage Routine
;Debugging/Testing Stages 0.33
;Current status: Stable, 95% bug free (the way to be!)
;Designed for use with WoWBot 15b.
;Conjuring/eating/drinking borrowed from EQJoe, can't get much better than how he has it.

;notes: work on hilly targeting, add use of scrolls (Scroll of Stamina, etc)
;notes: Totem code, add code to deal with pets (NPC warlocks, hunters)
;notes: finish combat (currently works, just not all there), finish HP test, finish a lot of things
;Working on now: AoEing/Polymorphing/add handling, not pulling an entire group.
;Up next: Running from dead target bug, fixing loot issues (if any exist), buff issue, track downtime FPS drop
;       : refixing the 0 xp/h bug which keeps resurfacing
;notes: 0xp/h bug seems to trigger on death. Left off - working on polymorph, making it not pull groups of 3+
;History: 0.33, Started conversion to pulse-style format.
;History: 0.32, Squashed a nasty bug with downtime/buffs wanting to loop eachother, did some work on aggro handling
;History: 0.31, Added water elemental code, more work on polymorphing, this time for pulls. 
;History: 0.30, Fixed the polymorph then pull sheep bug. Whole polymorphing thing still needs some debugging.
;History: 0.29, Some debugging, using managems should now work, arc missiles/other clearcast spells conflict fixed, upped detect range on getsafespot, same on pullmobs
;History: 0.28, Did a lot of work on aggro handling, much higher chance of survival now. Still does weird things.
;History: 0.27, Buffs seem fixed. Run from dead target semi fixed, can't find that dam FPS drop. Added base CC code.
;History: 0.26, Finished adding the immunechecks and damagechecks.
;History: 0.25, Fixed a couple bugs with GetSafeSpot, it now works correctly. XP/H counter fixed, manastone function added.
;History: 0.24, Fixed run to bum fuck egypt bug, fixed a minor pull issue and a few typos
;History: 0.23, Pull bug fixed. Will no longer try to spam pull until too close.
;History: 0.22, Many bugs ironed out, quite stable although incomplete. Safe to use when not around water.
;History: 0.21, somewhat works, quite buggy. Too long a list.
;Credits: EQJoe - Mage eat/drink/summon code. b7731 - Water Elemental code.



#define ROUTINES
#define DEBUG
function Attack2(string AttackGUID)
{
	;These need to be set.
	;frostspec - if you're frost spec, set this to true.
	declare frostspec bool global FALSE
	;Pyropull - if you want to pull with pyroblast, set to true. Else, whatever for your spec.
	declare Pyropull bool global TRUE
	;ArcMissileTalent - if you have 5/5 Imp Arc Missiles, set this true.
	declare ArcMissileTalent bool global TRUE
	;UseFlamestrike - allow use of Flamestrike in multimob situations.
	declare UseFlamestrike bool global TRUE
	;UseBlizzard - allow use of Blizzard in multimob situations.
	declare UseBlizzard bool global FALSE
	;ElementalPull - Pull with water elemental's freeze, if you have it.
	declare ElementalPull bool global FALSE
	;UseAoEMultiMob - use AoEs at all in multimob situations.
	declare UseAoEMultiMob bool global TRUE
	
	;don't touch these, they're autoset
	;seriously ,don't touch 'em
	declare HavePulled bool global
	declare UseFrostWard bool global
	declare UseFireWard bool global
	declare Immune-Frost bool global
	declare Immune-Fire bool global
	declare Dampen bool global
	declare RangedMode bool local
	declare hastarget bool global 
	declare testx float global
	declare testy float global
	declare safex1 float global
	declare safey1 float global
	declare angle float global
	declare NoSafeSpot bool global
	declare testfail int global
	declare Adds1 guidlist global
	declare Aggros1 guidlist global
	declare Aggros2 guidlist global
	declare Mobs guidlist global
	declare Pullmobs guidlist global
	declare angle2 float global
	declare bandages string global
	declare Adds2 guidlist global
	declare CCing bool global
	declare PetSent bool global
	declare SavedTarget1 string global
	declare SavedTarget2 string global
	declare LastPulse string global

	SavedWaypointX:Set[${Me.X}]
	SavedWaypointY:Set[${Me.Y}]

	;If I'm dead, update stats and do what's needed.
	if ${Me.Dead}
	{
		#ifdef DEBUG
		call Debug "Updating Status"
		#endif
		call UpdateStats
	}
	if ${Me.Sitting}
	{
		wowpress SITORSTAND
	}
	echo "${AttackGUID} - AttackGUID"
	if ${AttackGUID[NULL]}||${AttackGUID.Equal[NOTARGET]}
	{
		call UpdateHudStatus "No Target."
		Return
	}
	;Call code to handle elites if needed.
	if ${Unit[${AttackGUID}].Classification.Equal[Elite]} 
	{
		call Elites ${AttackGUID}
	}
	;If I'm not close enough, call the code to get closer
	if ${Unit[${AttackGUID}].Distance}>${PullingRange}&&!${HavePulled}
	{
		call GetCloser ${AttackGUID}
	}
	;If I'm close enough and haven't pulled, pull. Pullchecks and how to pull will be handled
	; in the pull function.
	if ${Unit[${AttackGUID}].Distance}<${PullingRange}&&!${HavePulled}
	{
			call Pull ${AttackGUID}
	}
	;If mob's in pull range and is pulled, combat prep (downtime if needed) and nuke. If this
	;  was the last pulse, skip the combat prep because it's already done, and start the nuking.
	if (${Unit[${AttackGUID}].Distance}<${PullingRange}&&${HavePulled})||${LastPulse}==Nuke
	{
		if !${LastPulse}==Nuke
		{
			call CombatPrepChecks ${AttackGUID}
		}
		if (${CombatPrepDone} && !${NeedDowntime})||${LastPulse}==Nuke
		{
			call Nuke ${AttackGUID}
		}
		LastPulse:Clear
		if ${CombatPrepDone} && ${NeedDowntime}
		{
			LastPulse:Set[Nuke]
			DoDowntime:Set[TRUE]
			Return
		}
	}
	;If my target's dead or doesn't exist and I'm still in combat, call aggrokill - will check for aggros and respond accordingly.
	if (${Unit[${AttackGUID}].Dead}||!${Unit[${AttackGUID}](exists)}) && ${Me.InCombat}
	{
		call AggroKill
	}
	;If target's dead and I'm not in combat, see if I need downtime.
	if ${Unit[${AttackGUID}].Dead} && !${Me.InCombat}
	{
		call DowntimeCheck
	}
}
function Elites(string AttackGUID)
{
	if !${Me.InCombat} 
	{ 
		call UpdateHudStatus "Target is an elite, don't bother attacking them" 
		GUIDBlacklist:Set[${AttackGUID},AVOID] 
		TargetGUID:Set[NOTARGET] 
		Return 
	} 
	else 
	{ 
		call UpdateHudStatus "Aggrod an elite RUN after we sheep!!" 
		if !${Spell[Polymorph].Cooldown}&&${Spell[Polymorph](exists)} 
		{ 
			call CastSpell Polymorph ${AttackGUID} 
		}    
;		RLG:Set[TRUE] 
		GUIDBlacklist:Set[${AttackGUID},AVOID] 
		TargetGUID:Set[NOTARGET] 
		Return 
	} 
}
function GetCloser(string AttackGUID)
{
	if ${Unit[${AttackGUID}].Distance}>${PullingRange} && !${HavePulled}
	{
		do
		{
			move forward
		}
		while ${Unit[${AttackGUID}].Distance}>${PullingRange} && !${HavePulled} && !${HaveAggroed}
	}
}
function Pull(string AttackGUID)
{
	if !${HavePulled} && !${Unit[${AttackGUID}].Dead}
	{
		echo "x ${Unit[${AttackGUID}].X} y ${Unit[${AttackGUID}].Y}"
		SmartFace ${Unit[${AttackGUID}].X} ${Unit[${AttackGUID}].Y} 
		call CheckFacing
		move -stop 
		wait 5 
		echo "Pulling"
		;Attach atom for pullcheck
		Event[UNIT_SPELLCAST_SUCCEEDED]:AttachAtom[pullcheck]
		;Check for what spell would be best to pull with and use it.
		;If you're a frosty with an elemental, freezepull. Optional.
		do
		{	
			if ${frostspec} && ${ElementalPull} && ${Me.Pet(exists)} && !${HavePulled}
			{
				echo "Elemental pulling"
				call UpdateHudStatus "Pulling with elemental freeze"
				wowpress BONUSACTIONBUTTON5
				wait 5
				ISXWoW:ClickTerrain[${Me.Target.X}, ${Me.Target.Y}, ${Me.Target.Z}]
				PetSent:Set[TRUE]
				HavePulled:Set[TRUE]
			}
			;If you're fire and got pyro, use it.
			if !${frostspec} && ${Pyropull} && ${Spell["Pyroblast"](exists)} && !${Immune-Fire} && !${HavePulled}
			{
				echo "pyroblast pulling"
				call UpdateHudStatus "Pulling with Pyroblast"
				call CastSpell "Pyroblast" ${AttackGUID}
				HavePulled:Set[TRUE]
				echo "${HavePulled} pulled"
			}		
			;Pull with a fireball if pyro doesn't exist
			if !${frostspec} && (!${Spell["Pyroblast"](exists)}||!${Pyropull}) && !${Immune-Fire} && !${HavePulled}
			{
				echo "fireball pulling"
				call UpdateHudStatus "Pulling with Fireball"
				call CastSpell "Fireball" ${AttackGUID}
				HavePulled:Set[TRUE]
				echo "${HavePulled} pulled"
			}		
			;Frost spec? Frostbolt!
			if ${frostspec} && !${Immune-Frost} && !${HavePulled}
			{
				echo "Frostbolt pulling"
				call UpdateHudStatus "Pulling with Frostbolt"
				call CastSpell "Frostbolt" ${AttackGUID}
				HavePulled:Set[TRUE]
			}		
			;If you're a frosty and it's frost immune, you can't exactly frostbolt it...
			if ${frostspec} && ${Immune-Frost} && !${HavePulled}
			{
				echo "firebolt pulling - frost immune"
				call UpdateHudStatus "Pulling with Fireball"
				call CastSpell "Fireball" ${AttackGUID}
				HavePulled:Set[TRUE]
			}		
			;Likewise, if you're fire and it's fire immune, can't use fire.
			if !${frostspec} && ${Immune-Fire} && !${HavePulled}
			{
				echo "Frostbolt pulling - fire immune"
				call UpdateHudStatus "Pulling with Frostbolt"
				call CastSpell "Frostbolt" ${AttackGUID}
				HavePulled:Set[TRUE]
			}		
		}
		while !${HaveAggroed} && !${HavePulled}
	}
}
function Nuke(string AttackGUID)
{
	do
	{
		if (${HavePulled}&&${Unit[${AttackGUID}].Distance<=30})||${HaveAggroed}
		{
			if ${HavePulled}
			{
				PullCrowdControl:Set[TRUE]
			}
			if !${HavePulled}
			{
				AggroCrowdControl:Set[TRUE]
			}
			call CrowdControlCheck ${AttackGUID}
			;If you've got AoEs allowed (multiple mob situations), they'll do their check.
			if ${UseAoEMultimob}
			{
				call AoECheck ${AttackGUID}
			}
			;A long wand check done with our HP in mind.
			if (${Unit[${AttackGUID}].PctHPs}>=7.5&&${Me.PctHPs}>=15)||(${Unit[${AttackGUID}].Buff["Ignite"](exists)}&&${Unit[${AttackGUID}].PctHPs}<=10&&${Me.PctHPs}>=15)
			{
				echo "${Unit[${AttackGUID}].PctHPs} HP Pct, wanding."
				UpdateHudStatus "Wanding"
				call CastSpell "Shoot" ${AttackGUID}
			}
			;A scorch check, for mana efficiency.
			if (${Unit[${AttackGUID}].PctHPs}>=12.5&&${Me.PctHPs}>=15&&${Spell["Scorch"](exists))||(${Unit[${AttackGUID}].Buff["Ignite"](exists)}&&${Unit[${AttackGUID}].PctHPs}<=17.5&&${Me.PctHPs}>=20&&${Spell["Scorch"](exists))
			{
				echo "${Unit[${AttackGUID}].PctHPs} HP Pct, scorching."
				UpdateHudStatus "Casting Scorch"
				call CastSpell "Scorch" ${AttackGUID}
			}
			;Counterspell.
			if ${Unit[${AttackGUID}].Casting(exists)} && ${Spell["Counterspell"](exists)} && !${Spell["Counterspell"].Cooldown}
			{
				if ${Unit[${AttackGUID}].Distance}>30
				{
					echo "Too far to counterspell"
					do
					{
						move forward
					}
					while ${Unit[${AttackGUID}].Distance}>30
				}
				echo "Counterspelling"
				call UpdateHudStatus "Casting Counterspell"
				call CastSpell "Counterspell" ${AttackGUID}
				;It's obviously tried to cast, so flip the DampenMagic flag
				DampenMagic:Set[TRUE]
			}
			;If we have clearcast, use it well. If you're not 5/5 arc missiles, it'll be used for whatever.
			if ${Me.Buff["Clearcasting"](exists)} && ${ArcMissileTalent}
			{
				echo "Clearcasting, Arcane Missiles."
				call CastSpell "Arcane Missiles" ${AttackGUID}
			}
			;Same goes for Arc Power/Presence of Mind.
			if ${Spell["Arcane Power"](exists)} && !${Spell["Arcane Power"].Cooldown} && ${Me.PctMana}>=45
			{
				echo "Arcane Power"
				call CastSpell "Arcane Power" ${Me.GUID}
			}
			if ${Spell["Presence of Mind"](exists)} && !${Spell["Presence of Mind"].Cooldown}
			{
				echo "Presence of Mind"
				call PresenceOfMindAttackSet ${AttackGUID}
			}
			;If mob's frozen, we're going to want to icelance it... if we have Ice Lance.
			if (${Unit[${AttackGUID}].Buff["Frostbite"](exists)}||${Unit[${AttackGUID}].Buff["Frozen"](exists))&&${Spell["Ice Lance"](exists)}
			{
				echo "${AttackGUID} Frozen or Frostbite'd, Ice Lancing."
				UpdateHudStatus "Casting Ice Lance"
				call CastSpell "Ice Lance" ${AttackGUID}
			}
			;Use Fireblast if we can.
			if ${Spell["Fireblast"](exists)}&&!${Spell["Fireblast"].Cooldown}&&${Unit[${AttackGUID}].Distance}<=20
			{
				echo "${Unit[${AttackGUID}].Distance} Distance, Fireblasting."
				UpdateHudStatus "Casting Fireblast"
				call CastSpell "Fireblast" ${AttackGUID}
			}
			;Get away if the mob's close.
			if ${Unit[${AttackGUID}].Distance}<=5&&${Unit[${AttackGUID}].PctHPs}>=7.5
			{
				echo "${Unit[${AttackGUID}].Distance} Distance, Frost Nova Attack Set."
				call FrostNovaAttackSet ${AttackGUID}
				;Do our in-combat health checks.
				call HealthChecks
			}
			;Now for the rest of the nukes - Spamming fireball/frostbolt, blastwave and cone of cold if you allow.
			if ${Unit[${AttackGUID}].Distance}<=30 && !${Unit[${AttackGUID}].Dead} && ${Unit[${AttackGUID}].PctHPs}>12.5
			{
				echo "Plain 'ole nukes."
				call Nukes2 ${AttackGUID}
			}
		}
	}
	while !${Unit[${AttackGUID}].Dead} && !${Me.Dead}
}
function Nukes2(string AttackGUID}
{
	;Good 'ole Fireball and Frostbolt. It'll use whatever it needs to.
	if (!${Immune-Fire} && !${frostspec})||(${Immune-Frost} && ${frostspec})
	{
		echo "Nukes2 - Fireball"
		UpdateHudStatus "Casting Fireball"
		call CastSpell "Fireball" ${AttackGUID}
	}
	if (${Immune-Fire} && !${frostspec})||(!${Immune-Frost} && ${frostspec})
	{
		echo "Nukes2 - Frostbolt"
		UpdateHudStatus "Casting Frostbolt"
		call CastSpell "Frostbolt" ${AttackGUID}
	}
}
function PresenceOfMindAttackSet(string AttackGUID)
{
	;Use PoM and nuke something. Check for PoM's exist and cooldown was already done, not needed here.
	echo "PoMAttackSet - Presence of Mind"
	UpdateHudStatus "Casting Presence of Mind"
	call CastSpell "Presence of Mind" ${Me.GUID}
	;Now, what spell are we going to use with PoM? There are both arcfire and arcfrost mages.
	;There are also noobs that go Arcane before Fire.
	if ${Spell["Pyroblast"](exists)} && !${Immune-Fire}
	{
		echo "PoMAttackSet - Pyroblast"
		UpdateHudStatus "Casting Pyroblast"
		call CastSpell "Pyroblast" ${AttackGUID}
	}
	if (!${frostspec} && !${Immune-Fire} && !${Spell["Pyroblast"](exists)})||(${frostspec} && ${Immune-Frost})
	{
		echo "PoMAttackSet - Fireball"
		UpdateHudStatus "Casting Fireball"
		call CastSpell "Fireball" ${AttackGUID}
	}
	if (!${frostspec} && ${Immune-Fire})||(${frostspec} && !${Immune-Frost})
	{
		echo "PoMAttackSet - Frostbolt"
		UpdateHudStatus "Casting Frostbolt"
		call CastSpell "Frostbolt" ${AttackGUID}
	}
}
function FrostNovaAttackSet(string AttackGUID)
{
	if !${Immune-Frost} && ${Spell["Frost Nova"](exists)}
	{
		if !${Spell["Frost Nova"].Cooldown} && !${Immune-Frost} && ${Spell["Frost Nova"](exists)}
		{
			call GetSafeSpot ${Me.Heading.DegreesCCW}
			if !${NoSafeSpot} && !${Target.Dead}
			{
				echo "Entrapping and getting away"
				call CastSpell "Frost Nova" ${AttackGUID}
				wait 3
				call SmartFace ${safex1} ${safey1}
				wait 5
				if ${Spell["Blink"](exists)} && !${Spell["Blink"].Cooldown}
				{
					echo "Blinking"
					call CastSpell "Blink" ${Me.GUID}
				}
				face ${safex1} ${safey1}
				call moveto ${safex1} ${safey1} 2
				face ${Target.X} ${Target.Y}
			}
		}
		;Sometimes trap and get away won't work... so just get away.
		if !${Spell["Blink"].Cooldown} && ${Spell["Blink"](exists)} && (${Spell["Frost Nova"].Cooldown} || ${Immune-Frost})
		{
			call GetSafeSpot ${Me.Heading.DegreesCCW}
			if !${NoSafeSpot} && !${Target.Dead}
			{
				echo "Can't entrap, just getting away"
				call SmartFace ${safex1} ${safey1}
				wait 5
				echo "Blinking"
				call CastSpell "Blink" ${Me.GUID}
				face ${safex1} ${safey1}
				call moveto ${safex1} ${safey1} 2
				face ${Target.X} ${Target.Y}
			}
		}
		;And sometimes, you just can't get away.
		if ${Spell["Blink"].Cooldown} || ${NoSafeSpot}
		{
			if !${Spell["Frost Nova"].Cooldown} && ${Spell["Frost Nova"](exists)} && !${Immune-Frost}
			{
				echo "Can't get away, FN'ing for the hell of it"
				call UpdateHudStatus "Casting Frost Nova"
				call CastSpell "Frost Nova" ${AttackGUID}
			}
		}
	}
}
function CrowdControlCheck(string AttackGUID)
{
	echo "CrowdControlCheck"
	if ${AggroCrowdControl}
	{
		Adds1:Search[-alive,-aggro,-targetingme,-range 0-30]
		echo "AggroCrowdControl Search - ${Adds1.Count} Mobs"
		if ${Adds1.Count}>1
		{
			SavedTarget1:Set[${AttackGUID}]
			if ${Adds1[1].GUID.Equal[${AttackGUID}]}
			{
				Target ${Adds1[2]}
			}
			if !${Adds1[1].GUID.Equal[${AttackGUID}]}
			{
				Target ${Adds1[1]}
			}
			echo "CrowdControlCheck - Aggro - Polymorphing"
			UpdateHudStatus "Casting Polymorph"
			call CastSpell "Polymorph" ${Target.GUID}
			Target ${SavedTarget1}
		}
	}
	if ${PullCrowdControl}
	{
		Adds2:Search[-alive,-hostile,-origin,${Unit[${AttackGUID}].Location},-range 0-15]
		echo "PullCrowdControl Search - ${Adds2.Count} Mobs"
		if ${Adds2.Count}>2
		{
			SavedTarget2:Set[${AttackGUID}]			
			if ${Adds2[1].GUID.Equal[${AttackGUID}]}
			{
				Target ${Adds2[2]}
			}
			if !${Adds2[1].GUID.Equal[${AttackGUID}]}
			{
				Target ${Adds2[1]}
			}
			echo "CrowdControlCheck - Pull - Polymorphing"
			UpdateHudStatus "Casting Polymorph"
			call CastSpell "Polymorph" ${Target.GUID}
			Target ${SavedTarget2}
		}
	}
}
function HealthChecks()
{

}