Genbot v13.2.1 [Updated 07/23/2004] Defend, Guard, Protect!

Post your completed (working) macros here. Only for macros using MQ2Data syntax!

Moderator: MacroQuest Developers

A_Druid_00
Macro Maker Extraordinaire
Posts: 2378
Joined: Tue Jul 13, 2004 12:45 pm
Location: Rolling on the Lawn Farting

Post by A_Druid_00 » Fri Jul 23, 2004 10:47 am

Don't thank me, thank Cr4zyb4rd, I was just the guy who got his wheels in motion :D And he managed to find his way through pretty well after spending some time reverse engineering the code to see what was being called from where. All in all, I think you did a great job with your added comments and just the general naming of the routines; it makes it a lot easier to follow than I had expected. Genbot is a huge task, I'm even more awed now that I've took the time to read backwards through some of the tasks to see how things are triggered and called.

Vex,
I assume referring the Cast_Resist sub back to step 1 will just prevent it from running the Delete From Queue routine when it switches to a heal. That shouldn't affect the work we did in cast 6 I believe, but I wanted to make sure that was taken into account.

I'd love to see some of the functionality of cast_routines ported into GB next, if anyone wants to try screwing with it. I want to play with healing logic this weekend, or I'd screw with it myself. I have a feeling I have my work cut out for me as is.
[quote]<DigitalMocking> man, A_Druid_00 really does love those long ass if statements
<dont_know_at_all> i don't use his macro because i'm frightened of it[/quote]
[quote][12:45] <dont_know_at_all> never use a macro when you can really fuck up things with a plugin[/quote]

User avatar
Cr4zyb4rd
Plugins Czar
Posts: 1449
Joined: Tue Jul 20, 2004 11:46 am

Post by Cr4zyb4rd » Fri Jul 23, 2004 2:29 pm

I know of no method for genbot to realize which mobs are mezzed and which are not. If anyone can think of a method to recognize this, I'd love to hear it.
I'm not sure if checking the animation type is viable, as many times a mob mezzed off screen will go through its melee/casting animation once when it comes in to view. Checking if the mob is physically moving/has moved is a good indicator, but might take some overhead to code properly, and can be fooled by things like knockback-stuns. I guess the best option is the obvious...use timers and parse for mez-break messages.

I know there are some auto-mezzer/rooter bots floating around out there, but I haven't looked to see how they handle this.
I'm thrilled to see someone actually get into my Cast code and make something new work. I was afraid I got a bit to clever with my coding for anyone else to want to take the time to parse through it.
No, the code wasn't that bad...most of my problem was having only written a few 10-liner macros and some HUD changes so far, and having no clue how events worked. :smile:

iusemq2
decaying skeleton
decaying skeleton
Posts: 8
Joined: Wed Jul 14, 2004 2:19 am

Post by iusemq2 » Fri Jul 23, 2004 3:35 pm

yeah i had doheals=1 in the ini..

ty vexix i'll use the new command~

izusaga
a ghoul
a ghoul
Posts: 103
Joined: Thu Jul 01, 2004 8:02 am

Post by izusaga » Fri Jul 23, 2004 4:30 pm

I'm having the same problems as Druid with my monk, and I've concluded that it's something to do with melee range. If you tell the monk to attack with just the attack command and the mob is not within a certain range of the monk, the monk continually strafes a single step side to side until the mob is brought in range and he commences attacking.

This ONLY happens when autobehind is enabled, when it's not he attacks right away regardless of the range between himself and the mob.

Have not tried protect or guard quite yet, I'm rather comfortable with my hotkeys right now.

Also, Druid, what command do you use to make the monk FD? And does this take priority over combat and other commands? Sometimes when there are adds I'd prefer to just have him FD off agro via command from the warrior, and I never quite figured it out.

For now, anchor and autobehind=0 have replaced the buggy autobehind melee command, however. =/

frabtik
a ghoul
a ghoul
Posts: 114
Joined: Sat Feb 21, 2004 10:07 am

Post by frabtik » Fri Jul 23, 2004 4:38 pm

Starting to play with protect a bit and right off the bat I like it. Will be looking at it a bit more soon but I can definately see this as a target of target type code in addition to the way it is now. Seems when I do a /gb attack command the bot actually is doing assist of master.
Don't think it used to be this way but is a pain if you are driving him and want to attack current target and master has no target it just clears target etc. Still using last update though so maybe that comment about attack in the first post fixed this.

User avatar
OnyxSys
a ghoul
a ghoul
Posts: 133
Joined: Sun Dec 21, 2003 9:58 pm
Contact:

Post by OnyxSys » Fri Jul 23, 2004 11:42 pm

Awesome Work! Thanks for the prompt update and thanks for pointing out the retired "autoheal" command, i was unaware as the docs up are still 12.38.. any chance of a new doc coming out soon with all the new update commands?

frabtik
a ghoul
a ghoul
Posts: 114
Joined: Sat Feb 21, 2004 10:07 am

Post by frabtik » Sat Jul 24, 2004 4:25 am

Update to new version, protect does not seem to be working, will test more if I can.

mackster
a ghoul
a ghoul
Posts: 95
Joined: Mon Sep 09, 2002 3:02 pm

Post by mackster » Sat Jul 24, 2004 12:17 pm

edit: figured it out :o

edit again: guess i havent figured it out.

I am having difficulties getting the bot to assist me to nuke a target, or cast any spell on it.

Previously, I had hotkeys setup to assist the master and then snt <spellname>

That stopped working, and just recently I tried 'sn <spellname>' and this worked, but when i had to stop the bot and restart it, its now not working again with either method.

edit 3: ok here's what's happening apparently. I'm using an IRC channel to issue commands and such, the bot does not appear to be able to use assist in the irc channel. it will never find a target (this worked in last version, though).

if I /tell the bot to assist, it will acquire my target, and then i can issue my commands thru the irc channel from there on and everything works fine.
Any ideas?

crisdan
a ghoul
a ghoul
Posts: 126
Joined: Mon Mar 24, 2003 1:56 pm

Post by crisdan » Sat Jul 24, 2004 1:33 pm

Could someone quickly tell me how to get my shortcuts to work with genbot 13.2.1? I am coming from version 12.38 and evidently not updating the correct ini file. Do i have to define my shortcuts in a new way now as events only and not the old way of 12.38?

And more specific....exactly which .ini file do i update in 13.2.1 since the new genbot_shammyname.ini file has this posted at the top for shortcut info:
[Shortcuts]
default=/echo Put yer shortcuts in your .ini file!


This is how I am use to using shorctus in genbot 12.38 at the bottom of my genbot_shammy.ini:

[shortcut spells]
PLBuff=Replenishment|Focus of Soul|Strength of the Diaku|Agility of the Wrulan|Endurance of the Boar|Acumen
slow=Malo|Turgur's Insects
slow1=Turgur's Insects
debuff=Malo
sow=Spirt of Wolf
bolt=Velium Strike
max=Ferine Avatar
[shortcut Items]
Sepic=spear of fate
Shaste=Scaled Avatar's Hauberk
[shortcut notarget Spells]
billy=Spirit of Bih`Li
pet=True Spirit
[shortcut notarget items]
[shortcut AA]
[shortcut noTarget AA]
[Shortcut Disc]
[shortcut noTarget Disc]

stevec
orc pawn
orc pawn
Posts: 10
Joined: Tue Jul 20, 2004 12:58 pm

Post by stevec » Sun Jul 25, 2004 6:59 am

Had my first test of MacroQuest this weekend along with GenBot and boy was it fun :)

Group were all lvl 65 (except druid who was 60)

Druid, Rogue, Shadow Knight, Rogue, Wizard, Enchanter

Probably a lot of the problems were to do with my ini files but I noticed the following:

Followmode=1 is dangerous. At one point because of an obstacle cleric caused a train because obstacle avoidance bought him in range of a mob which he aggroed. Also the bots would run off in all sorts of directions at times !

Couldnt get Chainnuke to work at all. How does this work please and how do i get the wizard to start nuking?

Couldnt get the Rogue to actually attack. She would just stand behind the mob

Buffing something like Pack Spirit will cause an endless loop if the zone doesnt support the buff. Because the buff doesnt take hold it keeps trying

I also had a few observations for improvements :)

Would be nice if Enchanters had a Mez command that would let then lockdown a mob automatically. Even give them multiple targets.

Clerics should abort a CH and patch if it becomes apparent that its not going to make it in time.

Apart from that I cant wait to get back and try out some tweaks I have been thinking about and then trying again.

Keep up the good work :)

User avatar
Cr4zyb4rd
Plugins Czar
Posts: 1449
Joined: Tue Jul 20, 2004 11:46 am

Post by Cr4zyb4rd » Sun Jul 25, 2004 10:13 am

Buffing something like Pack Spirit will cause an endless loop if the zone doesnt support the buff. Because the buff doesnt take hold it keeps trying
See a few posts up. You should be able to handle this exactly the same as casting a spell on an immune mob, just need to add the correct text to search for.
Clerics should abort a CH and patch if it becomes apparent that its not going to make it in time.
When is this, exactly? What type of patch? This is going to vary WILDLY depending on who's fighting what. The only way I can see to make this general enough would be to actually compute the mob's DPS on-the-fly and error on the side of caution (probably way too often) if no DPS data already exists.

edit: A_Druid wants me to look at ducking out of heals if somebody else lands a heal while the bot's is still casing, so we might just play around with this anyway as it's bound to use a lot of the same code.

A_Druid_00
Macro Maker Extraordinaire
Posts: 2378
Joined: Tue Jul 13, 2004 12:45 pm
Location: Rolling on the Lawn Farting

Post by A_Druid_00 » Sun Jul 25, 2004 11:31 am

Not to mention landing heals on ful HP members accounts for about 75% of my mana being wasted when I'm grouped with a cleric. I don't complain though because my patch heals save lives; but ducking out of heals would save me tons of mana for legitimate heals and debuffs.
[quote]<DigitalMocking> man, A_Druid_00 really does love those long ass if statements
<dont_know_at_all> i don't use his macro because i'm frightened of it[/quote]
[quote][12:45] <dont_know_at_all> never use a macro when you can really fuck up things with a plugin[/quote]

crisdan
a ghoul
a ghoul
Posts: 126
Joined: Mon Mar 24, 2003 1:56 pm

Post by crisdan » Sun Jul 25, 2004 6:55 pm

Would really love some feedback/help on my above bost about 4 messages back :>

bob_the_builder
a hill giant
a hill giant
Posts: 275
Joined: Tue Jul 22, 2003 1:22 pm

Post by bob_the_builder » Sun Jul 25, 2004 8:09 pm

Would really love some feedback/help on my above bost about 4 messages back :>
Read pg 2 from top to bottom, all your answers are there.

So
You have:
sow=Spirt of Wolf

Were it should be:

sow=snt Spirit of Wolf on NameS

And yes the INI file just as it states in defaut

Bob

javelinl
a lesser mummy
a lesser mummy
Posts: 70
Joined: Thu Mar 11, 2004 12:40 pm

Question on coding

Post by javelinl » Mon Jul 26, 2004 12:55 pm

I didn't see anything on the previous posts about handling automatic pet buffs, so I made a modification. However, I'm not sure about the correct syntax for AddCast to point to an ID (as opposed to a name). I cheated and used f1 f1, but I'd like to know how to do it right.

Code below. Changes in red.
Also, is it possible to highlight areas in a code box?

|botspell.inc
|Bot spell module.
|Version 13.2.1
|Date:07/21/2004
|
||**
[botspell]
version=13.2.1
**||
|

#event CastFizzle "Your spell fizzles!"
#event CastInterrupt "Your spell is interrupted."
#event CastInterrupt "Your casting has been interrupted."
#event CastNoMana "Insufficient Mana to cast this spell!"
#event CastResist "Your target resisted #*#"
#event CastTooFar "Your target is out of range, get closer!"
#event Collapse "Your gate is too unstable, and collapses."
#event Distracted "You are too distracted to cast a spell now!"
#event ImmuneSlow "Your target is immune to changes in its attack speed."
#event ImmuneRoot "Your target is immune to changes in its run speed."
#event MissedNote "You miss a note, bringing your song to a close!"
#event NoLOS "You cannot see your target."
#event NoMem "You do not seem to have that spell memorized."
#event NoOverWrite "Your spell would not have taken hold on your target."
#event NoTarget "You must first select a target for this spell!"
#event Recovered "You haven't recovered yet..."
#event Recovered "Spell recovery time not yet met."
#event RootOff "Your Immobilize spell has worn off."
#event Sitting "You must be standing to cast a spell."
#event Stunned "You can't cast spells while stunned!"
#event Stunned "You *CANNOT* cast spells, you have been silenced!"

Sub Init-Spell
/declare cmds-SPELL string outer Spell:
|For each command
|/call AddCommand "Command Section" "Command Phrase" "Called Sub"
|Command Section - where the command will be listed in response to the cmd phrase
|Command Phrase to trigger bot - End User can change to suit prefferences
|Called Sub - Routine to execute in response to Command Phrase
/call AddCommand SPELL buff Do-buff
/call AddCommand SPELL chainnuke Do-chainnuke
/call AddCommand SPELL chainstun Do-chainstun
/call AddCommand SPELL evac Do-evac
/call AddCommand SPELL loadlist Do-loadlist
/call AddCommand SPELL mana Do-mana
/call AddCommand SPELL selfbuff Do-selfbuff
/call AddCommand SPELL bufflist Do-bufflist
/call AddCommand SPELL setlompct Do-setlompct
/call AddCommand SPELL sn Do-sn
/call AddCommand SPELL snt Do-snt
/call AddCommand SPELL spellgem Do-spellgem
|/declare Vars
/declare BuffPtrList string outer
/declare BuffSelfIconList string outer
/declare CastInfo string outer
/declare CastLastResult string outer
/declare CastName string outer
/declare CastOldTargetID int outer
/declare CastQueue string outer
/declare CastStep int outer
/declare CastTarget string outer
/declare CastType string outer
/declare ChainStunNum int outer
/declare DoAgain bool outer FALSE
/declare LastSn string outer NA
/declare SpellNeedToRemem bool outer 0

|Timers
/declare CannAATimer timer outer
/declare ChainStunTime timer outer
/declare CannTimer timer outer
/declare CastTimer timer outer
/declare CTimer timer outer
/declare LomTimer timer outer
/declare ST-CheckSelfBuffs timer outer 1
/declare YaulpTimer timer outer

|Load Settings
/call LoadSetting BuffSelfList string Spell SelfBuffList "Buffs you wish to maintain on yourself separated with |"
/call LoadSetting BuffPetList string Spell PetBuffList "Buffs you wish to maintain on your pet separated with |"
/call LoadSetting BuffRetryDelay string Spell BuffRetryDelay 5m
/call LoadSetting CanniSpell string Spell CanniSpell Cannibalize
/call LoadSetting ChainNuke string Spell ChainNuke "Your Chain Nuke Spells separated with |."
/call LoadSetting ChainStun string Spell ChainStun "Your Chain Stun Spells separated with |."
/call LoadSetting DefaultSpellSet string Spell DefaultSpellSet Default
/call LoadSetting DoBuffs bool Spell DoBuffs 1
/call LoadSetting DelayBeforeSit string Spell DelayBeforeSit 3s
/call LoadSetting DoCanni bool Spell DoCanni 0
/call LoadSetting DoYaulp bool Spell DoYaulp 0
/call LoadSetting EvacSpell string Spell EvacSpell None
/call LoadSetting LomMsg string Spell LomMsg "Warning I'm running low on Mana."
/call LoadSetting RememSpells bool Spell RememSpells 0
/call LoadSetting ReportLom bool Spell ReportLom 0
/call LoadSetting SitAfterCast bool Spell SitAfterCast 0
/call LoadSetting SpellGem int Spell DefaultSpellGem 8
/call LoadSetting YaulpSpell string Spell YaulpSpell Yaulp


/if (${BuffSelfList.NotEqual[${BuffSelfList-DefaultValue}]}) {
/declare ArgNum int local 1
/for ArgNum 1 to ${Math.Calc[${BuffSelfList.Count[|]}+1]}
/varset CommandParam ${BuffSelfList.Arg[${ArgNum},|]}
/call Do-SelfBuff "${CommandParam}"
/next ArgNum
}

/if (${BuffPetList.NotEqual[${BuffPetList-DefaultValue}]}) {
/declare ArgNum1 int local 1
/for ArgNum1 1 to ${Math.Calc[${BuffPetList.Count[|]}+1]}
/varset CommandParam ${BuffPetList.Arg[${ArgNum1},|]}
/call Do-PetBuff "${CommandParam}"
/next ArgNum1
}


/return

Sub SpellMain
/call CastFromQueue
/if (${DoCanni}) /call CheckCann
/if (${DoYaulp}) /call CheckYaulp
/return

||||| Do Subs

Sub Do-buff
/declare BuffName string local
/declare BuffType string local
/if (!${Defined[Param0]}) /return
/if (${Param0.Equal[on]}) /return
/if (${Param0.Equal[off]}) {
/varset BuffListCount 0
/return
}
/declare SpellNameParam string local ${Param0}
/declare TargetName string local
/declare ParamCount int local 1
/if (${Param0.Equal[on]}) {
/varset SpellNameParam ${LastSn}
/goto :Do-BuffTargetStart
}
:Do-BuffSpellLoop
/if (${Defined[Param${ParamCount}]}) {
/if (${Param${ParamCount}.Equal[on]}) /goto :Do-BuffTargetStart
/varset SpellNameParam ${SpellNameParam} ${Param${ParamCount}}
/varcalc ParamCount ${ParamCount}+1
/goto :Do-BuffSpellLoop
}
:Do-BuffTargetStart
/varcalc ParamCount ${ParamCount}+1
/if (!${Defined[Param${ParamCount}]}) {
/varset TargetName me
} else {
/varset TargetName ${Param${ParamCount}}
/varcalc ParamCount ${ParamCount}+1
:Do-BuffTargetLoop
/if (${Defined[Param${ParamCount}]}) {
/varset TargetName ${TargetName} ${Param${ParamCount}}
/varcalc ParamCount ${ParamCount}+1
/goto :Do-BuffTargetLoop
}
/if (${TargetName.Equal[yourself]} || ${TargetName.Equal[${Me.CleanName}]}) {
/varset CommandParam ${SpellNameParam}
/call Do-SelfBuff ${CommandParam}
/return
}
}
/call AssignCastTarget "${TargetName}"
/varset TargetName ${Macro.Return}
/if (${TargetName.Equal[0]}) {
/call ChatOut 5 "I don't understand who to cast that buff on."
/return
}
/if (${DebugList.Find[spell]}) /echo Do-buff "${SpellNameParam}" "${TargetName}"
/call AddCast "${SpellNameParam}" "${TargetName}" b-0
/return


Sub BuffResult(string BuffType,string BuffCast,string BuffTarget,int Ptr)
/declare GenFor int local
/declare BuffSpell int local
/declare BuffDuration string local 0

| Find an available pointer for the buff and delete duplicates
/if (${Ptr}) {
/call ListDelbyName BuffPtrList ${Ptr} " "
/goto :gBuffPtrFound
}
/for GenFor 1 to ${Math.Calc[${BuffPtrList.Count[ ]}+2]}
/if (!${String[ ${BuffPtrList} ].Find[ ${GenFor} ]} && !${Ptr}) {
/varset Ptr ${GenFor}
}
/if (${Buff-${BuffPtrList.Arg[${GenFor}]}-Text.Equal[${BuffType};${BuffCast};${BuffTarget}]}) {
/varset Ptr ${BuffPtrList.Arg[${GenFor}]}
/call ListDelbyArg BuffPtrList ${GenFor} " "
/varset ST-BuffRefresh-${Ptr} 0
/goto :gBuffPtrFound
}
/next GenFor
:gBuffPtrFound
/if (!${Defined[Buff-${Ptr}-Text]}) /declare Buff-${Ptr}-Text string outer
/if (!${Defined[Buff-${Ptr}-RetryNum]}) /declare Buff-${Ptr}-RetryNum int outer 0

/if (${DebugList.Find[spell]}) /echo BuffPtr ${Ptr}

/if (${CastLastResult.Equal[CAST_Successful]}) {
/varset Buff-${Ptr}-RetryNum 0
/if (${Spawn[${BuffTarget}].Name.Equal[${Me.Name}]} || ${BuffTarget.Equal[0]}) {
/call CheckForBuffIcon ${BuffType} "${BuffCast}"
/if (${Macro.Return}) {
/if (!${String[|BuffSelfIconList|].Find[|${BuffType};${BuffCast}|]}) {
/call ListAppendElement BuffSelfIconList "${BuffType};${BuffCast}" |
}
/return
} else {
/call ChatOut 8 "I don't recognize the icon for ${BuffType.Arg[1,-]} ${BuffName}. Tell me 'timebuff ${BuffType.Arg[1,-]} ${BuffName}' some time when I don't have that buff active, and I'll record the buff and time how long it lasts."
}
}
/if (${String[|${TimedBuffList}].Find[|${BuffSpell};]}) {
/call ListFindStringArg TimedBuffList "|${BuffSpell};" |
/varset BuffDuration ${TimedBuffList.Arg[${Macro.Return},|].Arg[2,;]}
/if (${Spawn[${BuffTarget}].Name.Equal[${Me.Name}]} && ${Me.Buff[${TimedBuffList.Arg[${Macro.Return},|].Arg[3,;]}].ID}) {
/if (!${String[|${BuffSelfList}|].Find[|${BuffType};${BuffCast}|]}) {
/call ListAppendElement BuffSelfList "${BuffType};${BuffCast}" |
}
/return
}
}
/if (!${BuffDuration}) {
/if (${BuffType.Arg[1,-].Equal[spell]}) {
/varset BuffDuration ${Spell[${BuffCast}].Duration.TotalSeconds}s
} else /if (${BuffType.Arg[1,-].Equal[item]}) {
/varset BuffDuration ${FindItem[${BuffCast}].Spell.Duration.TotalSeconds}s
} else /if (${BuffType.Equal[alt]}) {
/varset BuffDuration ${AltAbility[${BuffCast}].ReuseTime}s
}
}
} else {
/if (${CastLastResult.Equal[CAST_NoOverWrite]} || ${CastLastResult.Equal[TARGET_NOTEXIST]}) {
/varset BuffDuration 2m
/varset Buff-${Ptr}-RetryNum 0
} else /if (${Buff-${Ptr}-RetryNum}<2) {
/varcalc Buff-${Ptr}-RetryNum ${Buff-${Ptr}-RetryNum}+1
/varset BuffDuration 15s
} else {
/varset BuffDuration 95s
/varset Buff-${Ptr}-RetryNum 0
}
}
/if (!${Defined[ST-BuffRefresh-${Ptr}]}) /declare ST-BuffRefresh-${Ptr} timer outer
/varset ST-BuffRefresh-${Ptr} ${BuffDuration}
/varcalc ST-BuffRefresh-${Ptr} ${ST-BuffRefresh-${Ptr}}-50
/if (${DebugList.Find[spell]}) /echo ST-BuffRefresh-${Ptr} ${ST-BuffRefresh-${Ptr}} BuffDuration ${BuffDuration}

/varset Buff-${Ptr}-Text ${BuffType};${BuffCast};${BuffTarget}
/call ListAppendElement BuffPtrList ${Ptr} " "
/return

Sub BuffRefresh(int Ptr)
/call AddCast "${Buff-${Ptr}-Text.Arg[1,;]};${Buff-${Ptr}-Text.Arg[2,;]}" "${Buff-${Ptr}-Text.Arg[3,;]}" b-${Ptr}
/return


Sub Do-PetBuff
/if (!${Defined[Param0]}) /return
/if (${Param0.Equal[off]}) {
/varset BuffPetList
/return
}


/if (${DebugList.Find[spell]}) /echo Do-PetBuff ${CommandParam}

/if (${Me.Pet.Distance}<90) {
/if (!${Me.PetBuff[${CommandParam}]}) {
| section I'd like to replace with the AddCast Options...
/keypress esc
/keypress F1
/keypress F1
/cast "${CommandParam}"
:wait
/delay 3
/doevents
/if (${Me.Casting.ID}) /goto :wait
| end section I'd like to replace with the AddCast Options...

}
}


/return




Sub Do-SelfBuff
/if (!${Defined[Param0]}) /return
/if (${Param0.Equal[off]}) {
/varset BuffSelfList
/return
}
/if (${DebugList.Find[spell]}) /echo Do-SelfBuff ${CommandParam}
/call RefineCast "${CommandParam}"
/if (${Macro.Return.Equal[0]}) /return
/varset CommandParam ${Macro.Return}
/if (${DebugList.Find[spell]}) /echo RefineCast Return ${Macro.Return}
/if (${CommandParam.NotEqual[0]}) {
/call CheckForBuffIcon ${Macro.Return.Arg[1,;]} "${Macro.Return.Arg[2,;]}"
/if (${DebugList.Find[spell]}) /echo CheckForBuffIcon Return ${Macro.Return}
/if (${Macro.Return}) {
/if (${String[|${BuffSelfIconList}|].Find[|${CommandParam}|]}) {
/call AddCast "${CommandParam}" "${Me.Name}" b-0
} else {
/call ListAppendElement BuffSelfIconList "${CommandParam}" |
}
} else {
/call AddCast "${CommandParam}" "${Me.Name}" b-0
}
}
/return

sub CheckSelfBuffs
/declare GenFor int local
/declare BuffType string local
/declare BuffName string local
/declare BuffSpell string local
/varset ST-CheckSelfBuffs 5s
/if (${BuffSelfIconList.Length}) {
/for GenFor 1 to ${Math.Calc[${BuffSelfIconList.Count[|]}+1]}
/varset BuffType ${BuffSelfIconList.Arg[${GenFor},|].Arg[1,;].Arg[1,-]}
/varset BuffName ${BuffSelfIconList.Arg[${GenFor},|].Arg[2,;]}
|/if (${DebugList.Find[spell]}) /echo Sub CheckSelfBuffs BuffSelfIconList ${BuffSelfIconList} BuffType ${BuffType} BuffName ${BuffName}
/call CheckForBuffIcon ${BuffType} "${BuffName}"
|/if (${DebugList.Find[spell]}) /echo CheckForBuffIcon Return ${Macro.Return}
/if (!${Macro.Return}) /call AddCast "${BuffType};${BuffName}" ${Me.Name} b-s
/next GenFor
}
/return

Sub CheckForBuffIcon(string BuffType,string BuffCast)
/declare BuffSpell string local
/if (${BuffType.Arg[1,-].Equal[spell]}) {
/varset BuffSpell ${Spell[${BuffCast}].Name}
} else /if (${BuffType.Arg[1,-].Equal[item]}) {
/varset BuffSpell ${FindItem[${BuffCast}].Spell.Name}
} else /if (${BuffType.Equal[alt]}) {
/varset BuffSpell ${AltAbility[${BuffCast}].Spell.Name}
}
/if (${String[|${TimedBuffList}].Find[|${BuffSpell};]}) {
/call ListFindStringArg TimedBuffList "|${BuffSpell};" |
/if (${Me.Buff[${TimedBuffList.Arg[${Macro.Return},|].Arg[3,;]}].ID}) {
/return 1
} else {
/return 0
}
}
/if (${Me.Buff[${BuffSpell}].ID}) /return 1
/return 0

Sub Do-bufflist
/declare GenFor int local
/call ChatOut 1 "Buffs I have on myself now:"
/for GenFor 1 to 15
/if (${Me.Buff[${GenFor}].ID}) {
/call ChatOut 1 "${Me.Buff[${GenFor}].Name} with ${Me.Buff[${GenFor}].Duration.Minutes} minutes ${Me.Buff[${GenFor}].Duration.Seconds} seconds left."
}
/next GenFor
/if (${BuffPtrList.Length}) {
/call ChatOut 1 "Buffs I am timing for myself or others:"
/for GenFor 1 to ${Math.Calc[${BuffPtrList.Count[ ]}+1]}
/call ChatOut 1 "${GenFor}. ${Buff-${GenFor}-Text.Arg[1,;]} ${Buff-${GenFor}-Text.Arg[2,;]} for ${Spawn[${Buff-${GenFor}-Text.Arg[3,;]}]} to be cast in ${Math.Calc[${ST-BuffRefresh-${GenFor}}\600].Int} minutes ${Math.Calc[${ST-BuffRefresh-${GenFor}}%600/10].Int} seconds."
/next GenFor
} else {
/call ChatOut 1 "I am keeping up no other buffs at the moment."
}
/return


Sub Do-chainnuke
/declare NukeNum int local 1
/call StandardTarget "${CommandParam}"
:ChainNukeLoop
/if (!${Target.ID}) /return
/if (${Me.Gem[${ChainNuke.Arg[${NukeNum},|]}]}) /cast "${ChainNuke.Arg[${NukeNum},|]}"
/varcalc NukeNum ${NukeNum}+1
/if (!${ChainNuke.Arg[${NukeNum},|].Length}) /varset NukeNum 1
/goto :ChainNukeLoop
/return

Sub Do-chainstun
/call StandardTarget "${CommandParam}"
/if (!${Target.ID}) /return
/varset ChainStunNum 1
/call NextStun
/return

Sub Do-evac
/if (${EvacSpell.NotEqual[None]}) /call ChatOut 5 "Moving to you and casting ${EvacSpell}!"
/varset CommandParam ${MasterName}
/call Do-moveto ${MasterName}
/call Do-anchor off
/if (${EvacSpell.NotEqual[None]}) {
/if (${DebugList.Find[spell]}) /echo Do-evac "${EvacSpell}" ${Me.Name} heal
/call AddCast "${EvacSpell}" ${Me.Name} heal
}
/return

Sub Do-loadlist(string Spellset)
/if (!${Defined[Spellset]}) /return
/memspellset ${Spellset}
/return

Sub Do-mana
/if (!${Me.Class.CanCast}) /return
/declare RoundMana int local ${Math.Calc[${Math.Calc[${Me.PctMana}/5].Int}*5].Int}
/if (${RoundMana}==100) {
/call ChatOut 2 "fm"
} else {
/call ChatOut 2 "${RoundMana}m"
}

/return

Sub Do-sn(string newSpell)
/declare snTarget string local
/call AssignCastTarget 0
/varset snTarget ${Macro.Return}
/if (!${Defined[newSpell]} && ${LastSn.Equal[NA]}) /return
/if (!${Defined[newSpell]}) /varset CommandParam "${LastSn}"
/if (${snTarget.Equal[0]}) {
/return
}
/varset LastSn ${CommandParam}
/if (${DebugList.Find[spell]}) /echo Do-sn "${CommandParam}" "${snTarget}"
/call AddCast "${CommandParam}" "${snTarget}"
/return

Sub Do-snt
/if (!${Defined[Param0]}) /return
/if (${Param0.Equal[on]} && ${LastSn.NotEqual[NA]}) /return
/declare sntCastText string local ${Param0}
/declare ParamCount int local 1
/declare sntTarget string local 0
/if (${Param0.Equal[on]}) {
/varset sntCastText ${LastSn}
/goto :Do-sntTargetStart
}

:Do-sntSpellLoop
/if (${Defined[Param${ParamCount}]}) {
/if (${Param${ParamCount}.Equal[on]}) /goto :Do-sntTargetStart
/varset sntCastText ${sntCastText} ${Param${ParamCount}}
/varcalc ParamCount ${ParamCount}+1
/goto :Do-sntSpellLoop
}
:Do-sntTargetStart
/varcalc ParamCount ${ParamCount}+1
/if (${Defined[Param${ParamCount}]}) {
/varset sntTarget ${Param${ParamCount}}
/varcalc ParamCount ${ParamCount}+1
:Do-sntTargetLoop
/if (${Defined[Param${ParamCount}]}) {
/varset sntTarget ${sntTarget} ${Param${ParamCount}}
/varcalc ParamCount ${ParamCount}+1
/goto :Do-sntTargetLoop
}
}
/if (${sntTarget.Equal[0]}) {
/if (${CombatTargetID}) {
/varset sntTarget id ${CombatTargetID}
} else /if (${Target.ID}) {
/varset sntTarget ${Target.Type} id ${Target.ID}
} else {
/varset sntTarget 0
}
} else {
/call AssignCastTarget "${sntTarget}"
/varset sntTarget ${Macro.Return}
}
/if (${DebugList.Find[spell]}) /echo Do-snt ${sntCastText} ${sntTarget}
/call AddCast "${sntCastText}" "${sntTarget}"
/varset LastSn ${sntCastText}
/return

Sub Do-spellgem
/if (!${Defined[Param0]}) {
/call ChatOut 3 "I use Gem ${SpellGem} when I need to mem new spells."
/return
}
/varset SpellGem ${Param0}
/call ChatOut 3 "I will now use Gem ${SpellGem} when I need to mem new spells."
/return




|||| Called Subs

Sub AddCast(string AddCastText,string AddCastTarget,string AddCastInfo)
/declare AddCastType string local
/if (!${Defined[AddCastTarget]}) /declare AddCastTarget string local ${Target.Name}
/if (!${Defined[AddCastInfo]}) /declare AddCastInfo string local 0
/if (!${String[ item spell alt ].Find[ ${AddCastText.Lower.Arg[1,;].Arg[1,-]} ]}) {
/if (${DebugList.Find[spell]}) /echo AddCastText ${AddCastText}
/call RefineCast "${AddCastText}"
/if (${Macro.Return.Equal[0]}) /return
/varset AddCastText ${Macro.Return}
}
/if (${AddCastText.Arg[1,;].Arg[1,-].Equal[spell]}) {
/if (${String[|pb ae|self|ae pc v2|group v1|].Find[|${Spell[${AddCastText.Arg[2,;]}].TargetType.Lower}|]}) {
/varset AddCastTarget 0
}
} else /if (${AddCastText.Arg[1,;].Arg[1,-].Equal[item]}) {
/if (${String[|pb ae|self|ae pc v2|group v1|].Find[|${FindItem[${AddCastText.Arg[2,;]}].Spell.TargetType.Lower}|]}) {
/varset AddCastTarget 0
}
}
/if (!${String[ corpse pc npc pet assist- 0 ].Find[ ${AddCastTarget.Arg[1].Lower} ]}) {
/call RefineTarget "${AddCastTarget}"
/varset AddCastTarget ${Macro.Return}
}
/if (${DebugList.Find[spell]}) /echo AddCastText ${AddCastText} AddCastTarget ${AddCastTarget} AddCastInfo ${AddCastInfo}
/if (!${CastQueue.Find[${AddCastText};${AddCastTarget};${AddCastInfo}]}) {
/if (${AddCastInfo.Equal[heal]}) {
/call ListPrependElement CastQueue "${AddCastText};${AddCastTarget};${AddCastInfo}" |
} else {
/call ListAppendElement CastQueue "${AddCastText};${AddCastTarget};${AddCastInfo}" |
}
}
/if (${DebugList.Find[spell]}) /echo CastQueue ${CastQueue}
/return

Sub CastFromQueue
/declare ArgNum int local 0
/if (!${CastStep}) {
/if (!${CastQueue.Length}) /return
/if (${CastQueue.Find[assist-]}) {
/call Assist ${MasterName}
/if (${Target.ID}) {
/call RefineTarget "${Target.Name}"
/call StringReplaceAll CastQueue assist- "${Macro.Return}"
} else {
/call ChatOut 4 "Unable to assist you to find a target to cast on."
}
}
:gNextinQueue
/varcalc ArgNum ${ArgNum}+1
/if (!${DoBuffs} && ${CastQueue.Arg[${ArgNum},|].Arg[4,;].Arg[1,-].Equal}) /goto :gNextinQueue
/if (!${CastQueue.Arg[${ArgNum},|].Length}) /return
/varset CastType ${CastQueue.Arg[${ArgNum},|].Arg[1,;]}
/varset CastName ${CastQueue.Arg[${ArgNum},|].Arg[2,;]}
/varset CastTarget ${CastQueue.Arg[${ArgNum},|].Arg[3,;]}
/varset CastInfo ${CastQueue.Arg[${ArgNum},|].Arg[4,;]}
/if (${DebugList.Find[spell]}) /echo CastType ${CastType} CastName ${CastName} CastTarget ${CastTarget}
/varset CastTimer 0
/varset CastStep 1
/varset CastOldTargetID 0
}
|/if (${DebugList.Find[spell]}) /echo CastType CastName CastStep ${CastType} ${CastName} ${CastStep}
/if (${CastQueue.Length}) /call Cast
/return

Sub Cast
/if (${String[ 1 2 3 4 5 6 7 ].Find[ ${CastStep} ]}) {
|/echo going to sub
/goto :gCast-${CastStep}
} else {
/if (${DebugList.Find[spell]}) /echo CastStep = ${CastStep} -- No corresponding goto found. Returning.
/varset CastStep 5
/return
}
| Wait for spell to pop up, stand up, and target correctly.
:gCast-1
|/if (${DebugList.Find[spell]}) /echo Cast 1 ${CastName}
/if (${CastTimer}) /return
/varset CastLastResult CHECKING_Casting
/if (${Me.Casting.ID}) /return
/varset CastLastResult CHECKING_Moving
/if (${CastType.Arg[1,-].Equal[spell]}) {
/if (${Spell[${CastName}].MyCastTime}>0.1 && ${Me.Moving} && ${Me.Class.Name.NotEqual[Bard]}) {
/varset CastStep 2
/return
}
/varset CastLastResult CHECKING_SpellMemmed
/if (!${Me.Gem[${CastName}]}) {
/varset CastStep 3
/return
}
/varset CastLastResult CHECKING_SpellUp
/if (!${Me.SpellReady[${CastName}]}) /return
} else /if (${CastType.Arg[1,-].Equal[item]}) {
/if (${FindItem[${CastName}].CastTime}>0.1 && ${Me.Moving} && ${Me.Class.Name.NotEqual[Bard]}) {
/varset CastStep 2
/return
}
}
/varset CastLastResult CHECKING_Standing
/if (!${Me.Standing}) {
/stand
}
/if (${SitAfterCast}) /varset SitTimer 1140m
/varset CastLastResult CHECKING_Target
| Not accounting for items or alt yet.
/if (${CastTarget.Equal[0]}) {
/call ChatOut 5 "Casting ${If[${CastInfo.Arg[1,-].Equal},buff ,]}${CastType.Arg[1,-]} ${CastName}."
/varset CastTarget 0
} else {
/if (!${Spawn[${CastTarget}].ID}) {
/if (${CastInfo.Arg[1,-].NotEqual} || ${CastInfo.Arg[1,-].Equal[b-0]}) {
/call ChatOut 3 "I couldn't find the target for ${CastType.Arg[1,-]} ${CastName}."
}
/varset CastStep 5
/varset CastLastResult TARGET_NOTEXIST
/return
}
/if (!${NearestSpawn[${CastTarget} radius ${MaxTargetRange}].ID}) {
/call ChatOut 3 "${NearestSpawn[${CastTarget}]} is out of range of ${CastType.Arg[1,-]} ${CastName}."
/varset CastStep 5
/varset CastLastResult TARGET_OUTOFRANGE
/return
}
/if (${Target.ID}!=${NearestSpawn[${CastTarget}].ID}) {
/varset CastOldTargetID ${Target.ID}
/squelch /target ${CastTarget}
/delay 2s ${Target.ID}==${NearestSpawn[${CastTarget}].ID}
/varset CastTimer 5
/if (${Target.ID}!=${NearestSpawn[${CastTarget}].ID}) {
/call ChatOut 3 "Wasn't able to target: ${CastTarget}"
/varset CastStep 5
/varset CastLastResult TARGET_CANNOTTARGET
/return
}
}
/call ChatOut 5 "Casting ${If[${CastInfo.Arg[1,-].Equal},buff ,]}${CastType.Arg[1,-]} ${CastName} on ${Target.CleanName}."
}

/if (${CastType.Arg[1,-].Equal[spell]}) {
/cast "${CastName}"
} else /if (${CastType.Arg[1,-].Equal[item]}) {
/cast item "${CastName}"
} else {
/alt activate ${AltAbility[${spellName}].ID}
}
}

/varset CastLastResult CAST_StillCasting
/varset CastStep 4
/varset CastTimer 0
/return
|Stop moving
:gCast-2
/if (${Me.Moving}) {
/if (!${CastTimer}) {
/call ChatOut 3 "Can't cast since I'm moving."
/keypress forward
/keypress back
/varset CastTimer 8
}
/return
}
/varcalc CastStep 1
/varset CastTimer 0
/return
| Memorize the spell
:gCast-3
/if (!${Me.Gem["${CastName}"]}) {
/if (!${CastTimer}) {
/varset SpellNeedToRemem 1
/if (${CastType.Arg[2,-].Length}) {
/memspell ${CastType.Arg[2,-]} "${CastName}"
/call ChatOut 6 "Memorizing spell: ${CastName} in slot ${CastType.Arg[2,-]}."
} else {
/memspell ${SpellGem} "${CastName}"
/call ChatOut 6 "Memorizing spell: ${CastName} in default slot ${SpellGem}."
}
/varset CastTimer 5s
}
/return
}
/varset CastStep 1
/varset CastTimer 0
/return
| Wait for spell to finish
:gCast-4
/if (${Me.Casting.ID}) {
/if (!${Me.Mount.ID} && !${Spawn[${CastTarget} radius ${MaxTargetRange}].ID} && ${CastTarget.NotEqual[0]}) {
/keypress FORWARD
/keypress BACK
/if (!${Me.Ducking}) /keypress DUCK
/delay 1
/if (${Me.Ducking}) /keypress DUCK
/varset CastStep 5
/call ChatOut 3 "Interrupted ${CastType.Arg[1,-]}: ${CastName}. Target ${NearestSpawn[${CastTarget}].CleanName} died, poofed, or came back to life!"
/varset CastLastResult SPELL_IntentionalInterruption
}
/return
}
/varcalc CastStep ${CastStep}+1
/return
| Wait for cast result
:gCast-5
/if (${CastTimer.OriginalValue}<>2) {
/varset CastTimer 2
/return
}
/if (${CastTimer}==0) {
/varset CastTimer 0
/varcalc CastStep ${CastStep}+1
}
/return
| Delete old spell as cast and update status to successful unless otherwise.
:gCast-6
/if (${CastLastResult.Equal[CAST_StillCasting]}) /varset CastLastResult CAST_Successful
/if (${CastInfo.Arg[1,-].Equal} && ${CastInfo.Arg[2,-].NotEqual[s]}) {
/call BuffResult ${CastType} "${CastName}" "${CastTarget}" ${CastInfo.Arg[2,-]}
}
/if (${CastOldTargetID}) /squelch /target id ${CastOldTargetID} radius ${MaxTargetRange}
/if (${DebugList.Find[spell]}) /echo CastLastResult ${CastLastResult}
/if (${RememSpells} && ${SpellNeedToRemem}) {
/memspellset ${DefaultSpellSet}
/call ChatOut 6 "Re-memorizing original spells."
/varcalc CastStep ${CastStep}+1
/return
}
/call ListDelbyName CastQueue "${CastType};${CastName};${CastTarget};${CastInfo}" |
/varset CastStep 0
/if (${SitAfterCast}) /varset SitTimer ${DelayBeforeSit}
/return
| Wait until spells are rememmed to continue
:gCast-7
/if (${Window[SpellBookWnd].Open}) /return
/call ChatOut 6 "Done memorizing original spells."
/varset SpellNeedToRemem 0
/if (${SitAfterCast}) /varset SitTimer ${DelayBeforeSit}
/call ListDelbyName CastQueue "${CastType};${CastName};${CastTarget};${CastInfo}" |
/varset CastStep 0
/return

Sub AssignCastTarget(string ACTarget)
/if (!${Defined[ACTarget]} || !${ACTarget.Length} || ${ACTarget.Equal[0]}) {
/if (${CastStep}==1 || ${Me.Casting.ID}) {
/return assist-
} else {
/call Assist ${MasterName}
/if (${Target.ID}) {
/return id ${Target.ID}
} else {
/call ChatOut 4 "Unable to /assist you to find a target to cast on."
/return 0
}
}
} else /if (${ACTarget.Equal[yourself]} || ${ACTarget.Equal[${Me.CleanName}]}) {
/return pc ${Me.CleanName}
} else /if (${ACTarget.Equal[me]} || ${ACTarget.Equal[${MasterName}]}) {
/return pc ${MasterName}
}
/return ${ACTarget}

Sub CheckCann
/if (!${Me.Moving}) {
/if (${Me.PctMana}<80 && ${Me.PctHPs}>=60 && ${Me.CurrentHPs}>1900 && ${CannAATimer}<=0) {
/alt activate 47
/varset CannAATimer 3m
}
/if (${Me.PctMana}<95 && ${Me.PctHPs}>=40 && ${CannTimer}<=0 && !${CastStep}) {
/if (${DebugList.Find[spell]}) /echo CheckCann "${CanniSpell}" "${Me.Name}"
/call AddCast "${CanniSpell}" ${Me.Name} buff
/varset CannTimer 4s
}
}
/return

Sub CheckMana
/if (${LomTimer}<=0) {
/if (${Me.PctMana}<${LomPct}) {
/call ChatOut 5 "${LomMsg}"
/varset LomTimer 2m
}
}
/return

Sub CheckYaulp
/if (!${Me.Moving} && ${Me.PctMana}<95 && ${YaulpTimer}<=1) {
/if (${DebugList.Find[spell]}) /echo CheckYaulp "${YaulpSpell}" "${Me.Name}"
/call AddCast "${YaulpSpell}" ${Me.Name} buff
/varset YaulpTimer 25s
}
/return

Sub NextStun
/if (!${Target.ID}) /return
:JumpStunSpell
/if (${Me.Gem[${ChainStun.Arg[${ChainStunNum},|]}]}) {
/cast "${ChainStun.Arg[${ChainStunNum},|]}"
/varset ChainStunTime 50
} else {
/varcalc ChainStunNum ${ChainStunNum}+1
/goto :JumpStunSpell
}
/varcalc ChainStunNum ${ChainStunNum}+1
/if (!${ChainStun.Arg[${ChainStunNum},|].Length}) /varset ChainStunNum 1
/return

Sub RefineCast(string RCText)
/declare RCType string local ${RCText.Arg[1]}
/declare RCName string local ${RCText.Right[-${RCType.Length}]}
/if (${String[ gem1 gem2 gem3 gem4 gem5 gem6 gem7 gem8 gem9 ].Find[ ${RCType.Lower} ]}) {
/varset RCType spell-${RCType.Right[1]}
/varset RCName ${RCName.Right[-${RCName.Arg[1].Length}]}
}
/if (${RCType.Arg[1,-].Equal[spell]}) {
/if (!${Int[${Me.Book[${RCName}]}]}) {
/call ChatOut 3 "Spell: ${RCName} not found in your book."
/return 0
}
/return ${RCType};${Spell[${RCName}]}
}
/if (${RCType.Equal[slot]}) {
/varset RCType item-${RCName.Arg[1]}
/varset RCName ${RCName.Right[-${RCName.Arg[1].Length}]}
}
/if (${RCType.Arg[1,-].Equal[item]}) {
/if (!${FindItem[${RCName}].InvSlot}) {
/call ChatOut 3 "Cannot find item: ${RCText} "
/return 0
}
/return ${RCType};${FindItem[${RCName}]}
}
/if (${RCType.Equal[alt]}) {
/if (!${AltAbility[${RCName}].ID}) {
/call ChatOut 3 "Do not understand Alt Ability: ${RCText} "
/return 0
}
/return ${RCType};${AltAbility[${RCName}]}
}
/if (!${Me.Book[${RCText}]}) {
/if (${DebugList.Find[spell]}) /echo Name |${RCText}|
/call ChatOut 3 "Spell: ${RCText} not found in your book."
/return 0
}
/return spell;${Spell[${RCText}]}

Sub RefineTarget(string RFTarget)
/if (${RFTarget.Equal[assist-]}) /return assist-
/if (${NearestSpawn[pc ${RFTarget} radius ${MaxTargetRange}].ID}) {
/varset RFTarget pc ${NearestSpawn[pc ${RFTarget}].Name}
} else {
/varset RFTarget ${NearestSpawn[${RFTarget}].Type} id ${NearestSpawn[${RFTarget}].ID}
}
/return ${RFTarget}

|||| Events
Sub Event_CastFizzle
/if (${CastStep}) {
/varset CastStep 0
/varset CastLastResult CAST_Fizzled
}
/return

Sub Event_CastInterrupt
/if (${CastStep}) {
/varset CastStep 0
/varset CastLastResult CAST_Interrupted
}
/return

Sub Event_CastNoMana
/if (${CastStep}) {
/varset CastLastResult CAST_CastNoMana
/if (${IsPally}) {
/varset CastLastResult CAST_CastNoMana
/if (${CastTimer}==0) {
/call ChatOut 5 "${MasterName} I am OOM!"
/varset CastTimer 10s
/return
}
}
/call ChatOut 5 "OOM. Medding 13 seconds and trying again. "
/if (!${Me.Sitting} && !${DoMelee}) /sit
/varset CastTimer 13s
}
/return

Sub Event_CastResist
/if (${CastStep}) {
/varset CastStep 6
/if (${CastLastResult.Equal[CAST_StillCasting]}) {
/varset CastLastResult CAST_Resisted
/call ChatOut 3 "${Target.CleanName} resisted ${CastType} ${CastName}."
}
}
/return

Sub Event_CastTooFar
/if (${CastStep}) {
/call ChatOut 3 "${NearestSpawn[${CastTarget}]} is out of range"
/varset CastStep 6
/varset CastLastResult CAST_CastTooFar
}
/return

Sub Event_Collapse
/if (${CastStep}) {
/varset CastStep 0
}
/return

Sub Event_Distracted
/if (${CastStep}) {
/call ChatOut 5 "I can't cast. I'm too distracted. "
/varset CastStep 6
/varset CastLastResult CAST_Distracted
}
/return

Sub Event_ImmuneRoot
/if (${CastStep}) {
/call ChatOut 3 "Cannot Root or Snare this Target!"
/varset CastStep 6
/varset CastLastResult CAST_ImmuneRoot
}
/return

Sub Event_ImmuneSlow
/if (${CastStep}) {
/call ChatOut 3 "Cannot Slow this Target (Immune)!"
/varset CastStep 6
/varset CastLastResult CAST_ImmuneSlow
}
/return

Sub Event_MissedNote
/if (${CastStep}) {
/varset CastStep 0
}
/return

Sub Event_NoLOS
/if (${CastStep} && ${CastStep}!=6) {
/call ChatOut 3 "I can't see my target. "
/varset CastStep 6
/varset CastLastResult CAST_NoLOS
}
/return

Sub Event_NoMem
/if (${CastStep}) {
/call ChatOut 5 "That spell is not memed. "
/varset CastStep 0
/varset CastLastResult CAST_NoMem
}
/return

Sub Event_NoOverWrite
/if (${CastStep}) {
/call ChatOut 3 "The spell won't take hold on the target."
/varset CastStep 6
/varset CastLastResult CAST_NoOverWrite
}
/return

Sub Event_NoTarget
/if (${CastStep}) {
/call ChatOut 3 "I don't know what target to cast on. "
/varset CastStep 6
/varset CastLastResult CAST_NoTarget
}
/return

Sub Event_Recovered
/varset CastStep 0
/if (${CastStep}) {
/varset CastLastResult CAST_Recovered
}
/return

Sub Event_RootOff
/call ChatOut 5 "Root has worn off. "
/return

Sub Event_Sitting
/if (${CastStep}) {
/varset CastStep 0
/varset CastLastResult CAST_NotStanding
}
/return

Sub Event_Stunned
/if (${CastStep}) {
/call ChatOut 5 "I'm STUNNED. Waiting a second to try again."
/varset CastStep 0
/varset CastTimer 1s
/varset CastLastResult CAST_Stunned
}
/return