premium spell_routines.inc

PeteSampras

Your UI is fucking you. Stop using it.
Joined
Dec 12, 2007
Messages
3,956
Reaction score
49
Points
38
spell_routines.inc automates spell casting for you in macros and allows a bunch of additional checks and returns. the mmoloader comes with a generic version of it. This is an advanced version of it that allows a bunch more options.

In addition to handling spells/aa/items, this version handles discs, adds color coded casting messages, and now adds a robust package of options for issuing almost any command you would want to use in a macro without having to write all complicated routines yourself.

I wrote a quick macro tutorial on another thread and realized I could just incorporate the principles into spell_routines.inc to make it do a lot more if you want to, but not eat up any resources in doing so (1-20kb extra data depending on what features you use).
Version 2.8 notes:
Moved #define MySpellIni to be first line in the file for easier editing.
-Added Sub CastInitialize - this will let you pull in variables
To use just declare the 2 following variables, then /call the routine and it will search the INI:
Options= I want to use with "|" at the end and match up with type below it
OptionTypes= 1 = CastIfReady/No recast, 2=CastDuration/Yes recast, 3=CastOncePerMob
/declare Option string outer Nuke|Dot|Pet|AA|Harvest|SelfBuff|Buff|Snare|Jolt|Debuff|Command|ImHit|
/declare OptionType string outer 1|2|1|1|1|1|2|3|1|2|1|1|
Then /call CastInitialize
- Added support for Conditional statements via using \ command in INI.
Code:
[Nuke]
NukeTotal=2
NukeColor=Red
Nuke1=Blaze
Nuke2=Fire
NukeConditions1=$[COLOR=Yellow]\[/COLOR]{Target.PctHPs}<90 && $[COLOR=Yellow]\[/COLOR]{Me.PctMana}>10
NukeConditions2=$[COLOR=Yellow]\[/COLOR]{Range.Between[1,98:$[COLOR=Yellow]\[/COLOR]{Target.PctHPs}]}
Version 2.7 notes:
-Updated /itemnotify to /useitem via: /useitem ${FindItem[=item name].ItemSlot} ${FindItem[=item name].ItemSlot2}
-ImHit routine can now use normal Me.Abilities like Feign Death and Mend
Version 2.6 notes:
-Updated InvSlots for 18 May 2013 patch.
-Added /useitem for items in slot 32 or less since it is an official EQ command now.

Added custom variables:
${GoM} - Do I have a form of Gift of Mana on?
${Twincast} - Do I have twincast on?
${NoGlobalTimer} - Are any of my spells ready?
${Named} - Is my target a named spawn?
${Banestrike} - Checks if mob is known immune to Banestrike AA so you can use it as a condition. !${Banestrike} means it will try it.

Added several generic routines to perform casting, medding, assisting, an event to check if you are hit.

This is a list of the routines, what they do, and the variables you need to declare and if those variables are optional to declare or not.
You may force memorization of a spell by placing a 1 at the end of the /call.

- DefaultGem is /declared in Sub SpellRoutinesLoad, this is the gem spells will force memorize with.

Example calls:
/call CastIfReady Nuke
/call CastDuration Dot 1
/call CastCommand Command
/call CastOnPets Pets 1
/call CastIfReady SelfBuffs 1
/call CastAutoClickies
/if (${Target.ID}!=${FightID} && ${Target.ID}==${TarID} && ${Target.ID}) /call CastDPS ${Target.ID}

-Sub CastAutoClickies - Routine to autocast clicky items that have buffs on them
/call CastAutoClickies

-Sub CastModRod - Routine to auto use mod rods if you have enough HP and need enough mana.
/call CastModRod

-Sub CastDPS - Routine to determine approximately how many seconds before mob dies. Adds FightTimeRemaining variable. This can be used in a condition, example to only cast a dot if more than 25 seconds remain:
/noparse /declare DotConditions1 string outer (${FightTimeRemaining}>25)
/if (${Target.ID}!=${FightID} && ${Target.ID}==${TarID} && ${Target.ID}) /call CastDPS ${Target.ID}

-Sub CastIfReady - Routine to cast spell if ready and conditions are met with no recast considerations. Color and conditions optional. Replace "Nuke" in example with any word to create your own.
/declare NukeColor string outer Red
/declare Nuke1 string outer Impel for Blood
/noparse /declare NukeConditions1 string outer (${Me.PctHPs}<40)

-Sub CastDuration - Routine to cast spells that have duration longer than gem refresh. ie. DoTs. Color and conditions optional. Replace "Dot" in example with any word to create your own.
/declare DotColor string outer Yellow
/declare Dot1 string outer Osalur's Flashblaze
/noparse /declare DotConditions1 string outer (${Range.Between[15,${AssistAt}:${Target.PctHPs}]})
/declare DotRecast1 timer outer 12s
/declare LastDot1 int outer

-Sub CastOncePerMob - Routine to cast spells once on a mob. Color and conditions optional. Replace "Snare" in example with any word to create your own.
/declare SnareColor string outer Green
/declare LastSnare int outer
/declare Snare string outer Encroaching Darkness
/noparse /declare SnareConditions string outer (${Target.PctHPs}<25 && ${Target.Fleeing}||!${Group})

-Sub CastCommand - Routine to perform any command. Conditions optional. Replace "Command" in example with any word to create your own.
/declare Command1 string outer /pet attack
/declare Command2 string outer /stand
/noparse /declare CommandConditions1 string outer (${TarID} && ${Target.ID} && ${Me.Pet.ID} && ${Me.Pet.Following.ID}!=${TarID} && ${Target.Distance}<100)
/noparse /declare CommandConditions2 string outer (${Me.PctHPs}>70 && ${Me.Feigning})

-Sub CastOnGroup - Routine to cast spells on group. Color, recast, and conditions are optional. Replace "Heal" in example with any word to create your own. ${i} checks group member 0-5 in the routine.
/declare HealColor string outer Teal
/declare Heal1 string outer Promised Renewal
/declare HealRecast1 timer outer 20s
/noparse /declare HealConditions1 (${Group.Member[${i}].PctHPs}<80 && ${Select[${Group.Member[${i}].Class.ShortName},SHM,NEC]})

-Sub CastOnPets - Routine to cast spell on pets in group. Color, Recast, and Conditions are optional. Replace "PetHeal" in example with any word to create your own. ${i} checks group member 0-5 in the routine.
/declare PetHealColor string outer Teal
/declare PetHeal1 string outer Algid Mending
/declare PetHealRecast1 timer outer 20s
/noparse /declare PetHealConditions1 (!${i} && ${Me.Pet.ID} && ${Me.Pet.PctHPs}<75)

-Sub CastOnXTarget - routine to cast spells on XTargets. Color, Recast, and Conditions are optional. Replace "XHeal" in example with any word to create your own. ${i} checks XTarget 1-10 in the routine.
/declare XHealColor string outer Teal
/declare XHeal1 string outer Promised Renewal
/declare XHealRecast1 timer outer 20s
/noparse /declare XHealConditions1 (${Spawn[${Me.XTarget[$[i}].ID}].PctHPs}<80 && ${Select[${Spawn[${Me.XTarget[${i}].ID}].Type},pc,pet,mercenary]} && ${Me.XTarget[${i}].Type.NotEqual[auto hater]})

- Sub CastTarget - Generic assist routine, must /declare a name and a % to assist at in your macro:
/declare Assist string outer name
/declare AssistAt int outer 99

-Sub Event_CastImHit - Routine for if you get hit. Must use ImHitX format. Color and conditions optional.
/declare ImHitColor string outer Pink
/declare ImHit1 string outer Improved Death Peace
/noparse /declare ImHitConditions1 string outer (${Me.PctHPs}<40)

-Sub CheckAggro - Routine to check aggro while casting any of the other sub routines. Must use JoltX format. Color and conditions optional.
/declare JoltColor string outer Teal
/declare Jolt1 string outer Death's Effigy
/noparse /declare JoltConditions1 string outer (${Me.PctAggro}>95 && ${Group})

- Sub CastMed - Generic med routine. Uses variables MedAt and MedTimer in Sub SpellRoutinesLoad
Ok great, so wtf do those routines really do for you? It means you can just #include spell_routines.inc (almost all macros already do this) and now you have access to be able to use all those features by just /calling them from your new or existing macros and all you have to do is /declare a few variables.

You are also able to use an INI by changing/using this line:
#define MySpellIni Bot_${Me.CleanName}_${Me.Class}.ini

You can differentiate what each toon uses by created INI files for them. I could create a file named Bot_PeteSamrpas_Wizard.ini and throw in
[Settings]
AnnounceSpellRoutines=TRUE
DefaultGem=gem1
MedAt=50
MedTimer=5s
..blahblah (the variables you can set are listed under Sub SpellRoutinesLoad)

If I decide I do want to use any of the new routines, I just need to /declare all the variables I want to use for each type and /call SpellRoutinesLoad

Here is an example macro for necro that uses most of the routines, note that in this case, I have an Initialize routine where I have /declared them all and a few custom variables. The rest of the macro is very tiny and just /calls the appropriate sub routine as applicable. (~225 lines of code and 11k size that functions as a full up bot using every spell/aa/clicky/pet/buffs/etc, with the vast majority being those /declares)

Code:
#turbo 80
#include spell_routines.inc

Sub Main(string assist,int amount)
/declare Assist string outer ${If[${assist.Length},${assist},${Group.MainTank}]}
/declare AssistAt int outer ${If[${amount},${amount},98]}
/call Initialize
/echo ${Macro.Name} loaded.
/echo Assisting ${Assist} at ${AssistAt}


:mainloop
/doevents
/call CastTarget
/if (${Me.CombatState.NotEqual[COMBAT]} && !${Me.Hovering}) /call Rest
/if (${CombatConditions} && !${Me.Hovering}) /call Combat
/goto :mainloop
/return

Sub Rest
/if (${TarID}&&${Target.ID}!=${TarID}) /squelch /tar id ${TarID}
/call CastIfReady SelfBuff 1
/doevents
/call CastIfReady Harvest
/doevents
/call CastIfReady Pet 1
/doevents
/call CastMed
/doevents
/call CastOnGroup Buff
/doevents
/call CastOnPets PetHeal 1
/call CastAutoClickies
/return

Sub Combat
/if (${TarID}&&${Target.ID}!=${TarID}) /squelch /tar id ${TarID}
/if (${Group}) /call CastCommand Command
/doevents
/call CastDPS ${Target.ID}
/call CastDuration Debuff
/doevents
/call CastIfReady AA
/doevents
/call CastDuration Dot 1
/doevents
/call CastIfReady Jolt
/doevents
/call CastIfReady Nuke
/doevents
/call CastOncePerMob Snare
/return

Sub Initialize
|generic stuff
/declare i int local
/call SpellRoutinesLoad
/noparse /declare CombatConditions string outer (${Target.ID}==${TarID} && ${Target.PctHPs}<=${AssistAt} && ${Target.LineOfSight} && !${Me.Feigning})
/if (${Group.GroupSize}>3) {
/noparse /declare DotsOn string outer (${Me.GemTimer[${Me.Gem[${Dot1}]}]} && ${Me.GemTimer[${Me.Gem[${Dot2}]}]} && ${Me.GemTimer[${Me.Gem[${Dot3}]}]})
}
/if (${Group.GroupSize}<4) {
/noparse /declare DotsOn string outer (${Me.GemTimer[${Me.Gem[${Dot1}]}]} && ${Me.GemTimer[${Me.Gem[${Dot2}]}]} && ${Me.GemTimer[${Me.Gem[${Dot3}]}]} && ${LastDot4}==${Target.ID} && ${LastDot5}==${Target.ID} && ${LastDot6}==${Target.ID})
}


|##Stuff I want to use over and over will be next

|Nukes
/if (${Group}) {
/declare NukeColor string outer Red
/declare Nuke1 string outer Dying Grasp
/declare Nuke2 string outer Plunder Essence
/declare Nuke3 string outer Scintillate Bones
/declare Nuke4 string outer Dissolving Venin
/declare Nuke5 string outer Impel for Blood

/noparse /declare NukeConditions1 string outer (${Me.PctHPs}<40)
/noparse /declare NukeConditions2 string outer (${Me.PctHPs}<70)
/noparse /declare NukeConditions3 string outer (${DotsOn}||${Target.PctHPs}<40)
/noparse /declare NukeConditions4 string outer (${DotsOn}||${Target.PctHPs}<40)
/noparse /declare NukeConditions5 string outer (${DotsOn}||${Target.PctHPs}<40)

|Jolts
/declare JoltColor string outer Teal
/declare Jolt1 string outer Death's Effigy
/declare Jolt2 string outer Improved Death Peace

/noparse /declare JoltConditions1 string outer (${Me.PctAggro}>95 && ${Group})
/noparse /declare JoltConditions2 string outer (${Me.PctAggro}>80 && ${Group})
}
|Pet
/declare PetColor string outer Green
/declare Pet1 string outer Unearthed Assassin
/declare Pet2 string outer Sigil of the Sundered Rk. II
/declare Pet3 string outer Aegis of Kildrukaun
/noparse /declare PetConditions1 string outer (!${Me.Pet.ID} && ${Me.PctMana}>20)
/noparse /declare PetConditions2 string outer (!${Me.PetBuff[${Pet2}]} && ${Me.Pet.ID})
/noparse /declare PetConditions3 string outer (!${Me.PetBuff[${Pet3}]} && ${Me.Pet.ID})

/declare PetHealColor string outer Teal
/declare PetHeal1 string outer Algid Mending
/declare PetHealRecast1 timer outer 20s
/noparse /declare PetHealConditions1 (!${i} && ${Me.Pet.ID} && ${Me.Pet.PctHPs}==100)

|AA
/declare AAColor string outer Purple
/declare AA1 string outer Empowered Focus of Arcanum
/declare AA2 string outer Improved Twincast
/declare AA3 string outer Reluctant Benevolence
/declare AA4 string outer Fundament: Third Spire of Necromancy
/declare AA5 string outer Embrace The Decay
/declare AA6 string outer Swarm of Decay
/declare AA7 string outer Rise of Bones
/declare AA8 string outer Frenzy of the Dead
/declare AA9 string outer Silent Casting
/declare AA10 string outer Gift of Deathly Resolve
/declare AA11 string outer Funeral Pyre
/declare AA12 string outer Mercurial Torment
/declare AA13 string outer Fortify Companion
/declare AA14 string outer Companion's Blessing
/declare AA15 string outer Replenish Companion
/declare AA16 string outer Deathwhisper
/declare AA17 string outer Abstruse Soulreaper Robe
/declare AA18 string outer Blightbringer's Tunic of the Grave
/declare AA19 string outer Death Bloom
/declare AA20 string outer Hand of Death
/declare AA21 string outer Army of the Dead
/noparse /declare AAConditions2 string outer (!${Twincast})
/noparse /declare AAConditions3 string outer (${Spell[Reluctant Benevolence].Stacks})
/noparse /declare AAConditions4 string outer (${Me.Buff[Curse of Muram].ID}||${BurnMode}||${Me.Buff[Gift of Deathly Resolve].ID})
/noparse /declare AAConditions5 string outer ((${Debuffs.Poisoned}||${Debuffs.Diseased}) && !${Raid.Members})
/noparse /declare AAConditions6 string outer (${Group})
/noparse /declare AAConditions7 string outer (${Group})
/noparse /declare AAConditions8 string outer (${Me.Pet.ID} && ${Me.Pet.Distance}<50)
/noparse /declare AAConditions9 string outer (${Named})
/noparse /declare AAConditions10 string outer (!${Raid.Members} && ${Named}||${BurnMode})
/noparse /declare AAConditions11 string outer (!${SpawnCount[group brd]})
/noparse /declare AAConditions12 string outer (!${Raid.Members} && ${Named}||${BurnMode})
/noparse /declare AAConditions13 string outer (${Spawn[${Me.Pet.ID}].Distance}<100 && ${Me.Pet.PctHPs}<=70 && ${Me.Pet.ID})
/noparse /declare AAConditions14 string outer (${Spawn[${Me.Pet.ID}].Distance}<250 && ${Me.Pet.PctHPs}<=70 && ${Me.Pet.ID})
/noparse /declare AAConditions15 string outer (${Spawn[${Me.Pet.ID}].Distance}<150 && ${Me.Pet.PctHPs}<=20 && ${Me.Pet.ID})
/noparse /declare AAConditions16 string outer (${Spawn[${Me.Pet.ID}].Distance}<50 && ${Group})
/noparse /declare AAConditions19 string outer (${Me.PctHPs}>80 && ${Me.PctMana}<70)
/noparse /declare AAConditions21 string outer (${SpawnCount[corpse radius 300]} && ${Group})

|Harvest
/declare HarvestColor string outer Orange
/declare Harvest1 string outer Death Bloom
/declare Harvest2 string outer Summoned: Large Modulation Shard
/noparse /declare HarvestConditions1 string outer (${Me.PctHPs}>80 && ${Me.PctMana}<70)
/noparse /declare HarvestConditions2 string outer (!${Me.Invis} && ${Me.PctMana}<=65 && ${Me.CurrentHPs}>24000)


|SelfBuffs
/declare SelfBuffColor string outer White
/declare SelfBuff1 string outer Forsakenside
/declare SelfBuff2 string outer Shield of the Dauntless
/declare SelfBuff3 string outer Zombieskin
/declare SelfBuff4 string outer Cascade of Decay
/noparse /declare SelfBuffConditions1 string outer (${Spell[${SelfBuff1}].Stacks} && !${Me.Buff[${SelfBuff1}].ID})
/noparse /declare SelfBuffConditions2 string outer (${Spell[${SelfBuff2}].Stacks} && !${Me.Buff[${SelfBuff2}].ID})
/noparse /declare SelfBuffConditions3 string outer (!${Me.Song[Death Bloom].ID}  && !${Me.Buff[${SelfBuff3}].ID})
/noparse /declare SelfBuffConditions4 string outer (${Spell[${SelfBuff4}].Stacks} && !${Me.Buff[${SelfBuff4}].ID})

|Buffs
/declare BuffColor string outer Pink
/declare Buff1 string outer Perfected Dead Man Floating
/declare BuffRecast1 timer outer 900m
/noparse /declare BuffConditions1 string outer (${Select[${Group.Member[${i}].Class.ShortName},ENC]})

|##stuff i want to use once per mob

|snare
/declare SnareColor string outer Green
/declare LastSnare int outer
/declare Snare string outer Encroaching Darkness
/noparse /declare SnareConditions string outer (${Target.PctHPs}<25 && ${Target.Fleeing}||!${Group})

|## duration stuff
|dot
/declare DotColor string outer Yellow
/declare Dot1 string outer Osalur's Flashblaze
/declare Dot2 string outer Itkari's Swift Lifedraw
/declare Dot3 string outer Bora's Swift Sickness
/if (!${Group}) /declare Dot4 string outer Pernicious Wounds
/if (!${Group}) /declare Dot5 string outer Coruscating Shadow
/if (!${Group}) /declare Dot6 string outer Ignite Thoughts
/if (!${Group}) /declare Dot7 string outer Pyre of Marnek
/if (!${Group}) /declare Dot8 string outer Termination
/noparse /declare DotConditions1 string outer (${Range.Between[15,${AssistAt}:${Target.PctHPs}]})
/noparse /declare DotConditions2 string outer (${Range.Between[15,${AssistAt}:${Target.PctHPs}]})
/noparse /declare DotConditions3 string outer (${Range.Between[15,${AssistAt}:${Target.PctHPs}]})
/noparse /declare DotConditions4 string outer (${Range.Between[75,${AssistAt}:${Target.PctHPs}]})
/noparse /declare DotConditions5 string outer (${Range.Between[75,${AssistAt}:${Target.PctHPs}]})
/noparse /declare DotConditions6 string outer (${Range.Between[25,${AssistAt}:${Target.PctHPs}]})
/noparse /declare DotConditions7 string outer (${Range.Between[25,${AssistAt}:${Target.PctHPs}]})
/noparse /declare DotConditions8 string outer (${Range.Between[25,${AssistAt}:${Target.PctHPs}]})
/declare DotRecast1 timer outer 12s
/declare DotRecast2 timer outer 12s
/declare DotRecast3 timer outer 12s
/declare DotRecast4 timer outer 120s
/declare DotRecast5 timer outer 120s
/declare DotRecast6 timer outer 48s
/declare DotRecast7 timer outer 60s
/declare DotRecast8 timer outer 48s
/for i 1 to 20
/if (${Defined[Dot${i}]}) /declare LastDot${i} int outer
/next i



/declare Debuff1 string outer Death's Malaise
/declare Debuff2 string outer Scent of Terris
/noparse /declare DebuffConditions1 string outer (${Me.GemTimer[${Me.Gem[${Nuke3}]}].Seconds}>6 && ${Target.Body.Name.Equal[Undead]} && !${SpawnCount[group shm]} && !${SpawnCount[group enc]} && !${SpawnCount[group brd]})
/declare DebuffRecast1 timer outer 90s
/declare DebuffRecast2 timer outer 600s


/for i 1 to 20
/if (${Defined[Debuff${i}]}) /declare LastDebuff${i} int outer
/next i

|##commands
/declare Command1 string outer /pet attack
/declare Command2 string outer /stand
/noparse /declare CommandConditions1 string outer (${TarID} && ${Target.ID} && ${Me.Pet.ID} && ${Me.Pet.Following.ID}!=${TarID} && ${Target.Distance}<100)
/noparse /declare CommandConditions2 string outer (${Me.PctHPs}>70 && ${Me.Feigning})

|##ImHit event
/declare ImHit1 string outer Death's Effigy
/declare ImHit2 string outer Embalmer's Carapace
/declare ImHit3 string outer Harmshield
/declare ImHit4 string outer Improved Death Peace
/noparse /declare ImHitConditions1 string outer (${Me.PctHPs}<40)
/noparse /declare ImHitConditions2 string outer (${Me.PctHPs}<40 && ${Me.Standing})
/noparse /declare ImHitConditions3 string outer (${Me.PctHPs}<40 && !${Me.Buff[Embalmer's Carapace].ID})
/noparse /declare ImHitConditions4 string outer (${Me.PctHPs}<40 && ${Me.Standing})
/return
But say I just wanted to add a nuke and dot to my basic assist macro. Also, I want to automatically use all my self clickies and click any mod rods I have. I would add (using the guide above):
Code:
#include spell_routines.inc

Sub Main
/call SpellRoutinesLoad
/declare Nuke1 string outer Fire Rk. II
/noparse /declare NukeConditions1 (${Me.PctMana}>70 && ${Target.PctHPs}<95)
/declare Dot1 string outer Disease Cloud
/noparse /declare DotConditions1 string outer (${Target.PctHPs}>20)
/declare LastDot1 int outer
/declare DotRecast1 timer outer 90s
:loop
...
/call CastAutoClickies
/call CastIfReady Nuke
/call CastDuration Dot 1
/call CastModRod
..
/return
and tada, now it casts Fire Rk. II if its already memorized, and Disease Cloud whether it is memmed or not in your basic assist macro. It will also auto use any clicky buff items or mod rods you have as needed.


****NOTE:

If there are other common tasks that can be included in this, or if there is a more efficient way/something is wrong, please let me know. I have tested what I can for many hours, but I don't have access to the right classes to test a few of the things.

MMOLoader will overwrite your spell_routines.inc if the box is checked to download INIs. If you want to always use this, you have to uncheck that box.
 

Attachments

  • Spell_routines.inc
    65.8 KB · Views: 42
Last edited:
Version 2.7 notes:
-Updated /itemnotify to /useitem via: /useitem ${FindItem[=item name].ItemSlot} ${FindItem[=item name].ItemSlot2}
-ImHit routine can now use normal Me.Abilities like Feign Death and Mend

Fry updated the compile to correct the FindItem TLO issue and we can now /useitem things in bags. Version 2.7 requires latest compile so items can click correctly.
 
I updated spell_routines.inc to be able to use Conditions from an INI without having to rely on /noparse. What this means is you could now simplify your macro creation and just update your spells in an INI or use a premade INI such as bot.mac and create an ultra lite version of any macro.

I had a problem during initial testing in that the macro was too fast. String.Replace seems to move slower than the macro and would cause errors. I've since created a loop process to avoid it, but I have only done limited testing. If someone else wants to give it a shot, thatd be awesome. To make use of conditions in an INI, you need to put "\" between "$" and "{" on any of your conditions.

Example INI entry:
Code:
[Nuke]
NukeTotal=2
NukeColor=Red
Nuke1=Blaze
Nuke2=Fire
NukeConditions1=$[COLOR=Yellow]\[/COLOR]{Target.PctHPs}<90 && $[COLOR=Yellow]\[/COLOR]{Me.PctMana}>10
NukeConditions2=$[COLOR=Yellow]\[/COLOR]{Range.Between[1,98:$[COLOR=Yellow]\[/COLOR]{Target.PctHPs}]}
Then your /declare info could be:

Code:
#define MyIni Bot_${Me.Name}_${Me.Class}.ini

/declare i int local
/declare NukeColor string outer ${Ini[MyIni,Nuke,NukeColor]}
/for i 1 to ${Ini[MyIni,Nuke,NukeTotal]}
/declare Nuke${i} string outer ${Ini[MyIni,Nuke,Nuke${i}]}
/declare NukeConditions${i} string outer ${Ini[MyIni,Nuke,NukeConditions${i}]}
/next i
Essentially you can make a very streamlined macro and use an INI for easy upgrading later. But I want a little testing before I post it as the official version. Post here or come to IRC or email me if there are any issues. If all goes well, I may create bot v3.0 on this principle so that it gets sped up. Thanks.

EDIT: /noparse /declare string outer blahblah still works same as before. This just lets you do it either way.
 
Last edited:
Decided to just write a full blown version since it is easy for me and probably more difficult for others. This pulls most pre-existing sections from Bot.mac ini. There are a few you would have to create or modify slightly to get the correct format.

Code:
#turbo 80
#define MyIni [COLOR=Lime]Bot_${Me.CleanName}_${Me.Class}.ini[/COLOR]
#include spell_routines.inc

Sub Main(string assist,int amount)
/declare Assist string outer ${If[${assist.Length},${assist},${Group.MainTank}]}
/declare AssistAt int outer ${If[${amount},${amount},98]}
/call Initialize
/echo ${Macro.Name} loaded.
/echo Assisting ${Assist} at ${AssistAt}


:mainloop
/doevents
/call CastTarget
/if (${Me.CombatState.NotEqual[COMBAT]} && !${Me.Hovering}) /call Rest
/if (${CombatConditions} && !${Me.Hovering}) /call Combat
/goto :mainloop
/return

Sub Rest
/if (${TarID}&&${Target.ID}!=${TarID}) /squelch /tar id ${TarID}
/call CastIfReady SelfBuff 1
/doevents
/call CastIfReady Harvest
/doevents
/call CastIfReady Pet 1
/doevents
/call CastMed
/doevents
/call CastOnGroup Buff
/doevents
/call CastOnPets PetHeal 1
/call CastAutoClickies
/return

Sub Combat
/if (${TarID}&&${Target.ID}!=${TarID}) /squelch /tar id ${TarID}
/if (${Group}) /call CastCommand Command
/doevents
/call CastDPS ${Target.ID}
/call CastDuration Debuff
/doevents
/call CastIfReady AA
/doevents
/call CastDuration Dot 1
/doevents
/call CastIfReady Jolt
/doevents
/call CastIfReady Nuke
/doevents
/call CastOncePerMob Snare
/return

Sub Initialize
/declare i int local
/declare x int local
/call SpellRoutinesLoad
/noparse /declare CombatConditions string outer (${Target.ID}==${TarID} && ${Target.PctHPs}<=${AssistAt} && ${Target.LineOfSight} && !${Me.Feigning})

|options I want to use with "|" at the end and match up with type below it
|OptionTypes 1 = CastIfReady/No recast, 2=CastDuration/Yes recast, 3=CastOncePerMob
[COLOR=Yellow]/declare Option string outer Nuke|Dot|Pet|AA|Harvest|SelfBuff|Buff|Snare|Jolt|Debuff|Command|ImHit|
/declare OptionType string outer 1|2|1|1|1|1|2|3|1|2|1|1|[/COLOR]


/for x 1 to ${Option.Count[|]}
/declare ${Option.Arg[${x},|]}Total int outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Total]}
/if (${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color].Length}) /declare ${Option.Arg[${x},|]}Color string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color]}
/if (${OptionType.Arg[${x},|]}==3) /goto :option3
/if (!${${Option.Arg[${x},|]}Total}) /goto :skipx
    /for i 1 to ${${Option.Arg[${x},|]}Total}
        /declare ${Option.Arg[${x},|]}${i} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}SpellName${i}]}
        /declare ${Option.Arg[${x},|]}Conditions${i} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Conditions${i},123456]}
        /if (${${Option.Arg[${x},|]}Conditions${i}.Equal[123456]}) /deletevar ${Option.Arg[${x},|]}Conditions${i}
        /if (${OptionType.Arg[${x},|]}==2) /declare ${Option.Arg[${x},|]}Recast${i} timer outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Recast${i}]}
        /if (${OptionType.Arg[${x},|]}==2) /declare Last${Option.Arg[${x},|]}${i} timer outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Recast${i}]}
        /goto :skipi
        :option3
        /declare ${OptionType.Arg[${x},|]}Color string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color]}
        /declare ${OptionType.Arg[${x},|]} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}]}
        /declare ${OptionType.Arg[${x},|]}Conditions string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Conditions,123456]}
        /if (${${Option.Arg[${x},|]}Conditions.Equal[123456]}) /deletevar ${Option.Arg[${x},|]}Conditions    
        /declare Last${OptionType.Arg[${x},|]} int outer
        :skipi
    /next i
:skipx
/next x
/return
Other than your INI, the highlighted yellow is all you would need to change to fit your toon for the Sub Initialize portion. Taking a closer look at it:
Code:
|options I want to use with "|" at the end and match up with type below it
|OptionTypes 1 = CastIfReady/No recast, 2=CastDuration/Yes recast, 3=CastOncePerMob
[COLOR=Yellow]/declare Option string outer Nuke|Dot|Pet|AA|Harvest|SelfBuff|Buff|Snare|Jolt|Debuff|Command|ImHit|
/declare OptionType string outer 1|2|1|1|1|1|2|3|1|2|1|1|[/COLOR]
I put in the name of the section as the Option, then a corresponding number as the type as the OptionType, then add "|" after each one and move to the next. The first 3 of that sequence would pull from bot.mac:
Code:
[Nuke]
NukeTotal=4
NukeColor=Red
NukeSpellName1=Fire
NukeConditions1=$\{Range.Between[1,95:$\{Target.PctHPs}]}
NukeSpellName2=Blaze
NukeConditions2=$\{Range.Between[1,95:$\{Target.PctHPs}]}
NukeSpellName3=Char
NukeConditions3=$\{Range.Between[1,95:$\{Target.PctHPs}]}
NukeSpellName4=Smolder
NukeConditions4=$\{Range.Between[1,95:$\{Target.PctHPs}]}

[Dot]
DotTotal=3
DotColor=Yellow
DotSpellName1=Disease
DotConditions1=$\{Range.Between[25,95:$\{Target.PctHPs}]}
DotRecast1=90s
DotSpellName2=Plague
DotConditions2=$\{Range.Between[25,95:$\{Target.PctHPs}]}
DotRecast2=30s
DotSpellName3=Bubonic Tonic
DotConditions3=$\{Range.Between[15,95:$\{Target.PctHPs}]}
DotRecast3=12s

[Pet]
PetColor=Blue
PetTotal=2
PetSpellName1=Summon Undead
PetConditions1=!$\{Me.Pet.ID}
PetSpellName2=Haste
PetSpellConditions2=!$\{Me.PetBuff[Haste].ID} && $\{Me.Pet.ID}
You would have to add NameColor=blah to each section, and some CastOncePerMob stuff like snare would need to be added. But otherwise it is pretty straight forward additions.
 
Last edited:
all sounds great

trying to fig out what this all does (new)
Spell_routines.inc is used by many macro to cast spells or use abilities. This version does all that, adds discs and abilities and rank checks and a few other things. It also adds a set of routines to let you handle a bunch of different spell types without having to create the routines yourself. When you get down to the crux of it, there are only so many different ways to use a spell/skill and this breaks all those out in to easy to reference routines.

The premade casting routines along with the ability to easily generate variables means you can make fast and customized macros with minimal effort. And you can tailor them to use preexisting INIs if desired. So for example, you could make a bot lite version using this so your dps runs much faster. Then maybe use the full blown version on a healer/mezzer/tank. Ultimately it takes what was hours long process and a ton of testing and condenses it down into minutes to make your own macro.

I made a few video macro tutorials, but I havent finished them yet. It covers 3 of the 4 basics so far, but doesnt talk about loops or flow control. You can check them out at:
https://www.youtube.com/playlist?list=PL916d8FRO0rmj5l6pyq0Y_9mPtftO3tes
I got tired of tabbing to the wrong screen and having to redo the videos so i just stopped and havent touched it since then. I eventually intend to finish that up and get into some more complex ones, then hopefully get around to creating homework projects that people can make something (supposing there was interest in that). Finding motivation to complete them is hard and my AC is broken so its so hot in here and I want to die a little as opposed to make videos.
 
Last edited:
Can anyone take a look at the following macro and ini and tell me what I am doing wrong please? I'm using the latest test version of spell_routines.inc.

When I start it will cast the defined buffs over and over.

It will also cast the spells defined in the harvest section even if the character is at 100 mana.

It's like it is ignoring the conditions defined in the ini, but I don't have the know how to work out what I am doing wrong.

I haven't got to the stage of using anything in the Sub combat section of the macro yet.

Thanks.

100wiz.mac
Code:
#turbo 80
#define MyIni Bot_${Me.CleanName}_${Me.Class}.ini
#include spell_routines.inc

Sub Main(string assist,int amount)
/declare Assist string outer ${If[${assist.Length},${assist},${Group.MainTank}]}
/declare AssistAt int outer ${If[${amount},${amount},98]}
/call Initialize
/echo ${Macro.Name} loaded.
/echo Assisting ${Assist} at ${AssistAt}


:mainloop
/doevents
/call CastTarget
/if (${Me.CombatState.NotEqual[COMBAT]} && !${Me.Hovering}) /call Rest
/if (${CombatConditions} && !${Me.Hovering}) /call Combat
/goto :mainloop
/return

Sub Rest
/if (${TarID}&&${Target.ID}!=${TarID}) /squelch /tar id ${TarID}
/call CastIfReady SelfBuff 1
/doevents
/call CastIfReady Harvest
/doevents
/call CastMed
/doevents
/call CastAutoClickies
/return

Sub Combat
/if (${TarID}&&${Target.ID}!=${TarID}) /squelch /tar id ${TarID}
/if (${Group}) /call CastCommand Command
/doevents
/call CastDPS ${Target.ID}
/call CastOncePerMob Freeze
/doevents
/call CastIfReady AA
/doevents
/call CastIfReady Jolt 1
/doevents
/call CastIfReady Nuke 1
/return

Sub Initialize
/declare i int local
/declare x int local
/call SpellRoutinesLoad
/noparse /declare CombatConditions string outer (${Target.ID}==${TarID} && ${Target.PctHPs}<=${AssistAt} && ${Target.LineOfSight} && !${Me.Feigning})

|options I want to use with "|" at the end and match up with type below it
|OptionTypes 1 = CastIfReady/No recast, 2=CastDuration/Yes recast, 3=CastOncePerMob
/declare Option string outer Nuke|Jolt|AA|Harvest|SelfBuff|Command|ImHit|Freeze|
/declare OptionType string outer 1|1|1|1|2|1|1|3|


/for x 1 to ${Option.Count[|]}
/declare ${Option.Arg[${x},|]}Total int outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Total]}
/if (${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color].Length}) /declare ${Option.Arg[${x},|]}Color string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color]}
/if (${OptionType.Arg[${x},|]}==3) /goto :option3
/if (!${${Option.Arg[${x},|]}Total}) /goto :skipx
    /for i 1 to ${${Option.Arg[${x},|]}Total}
        /declare ${Option.Arg[${x},|]}${i} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}SpellName${i}]}
        /declare ${Option.Arg[${x},|]}Conditions${i} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Conditions${i},123456]}
        /if (${${Option.Arg[${x},|]}Conditions${i}.Equal[123456]}) /deletevar ${Option.Arg[${x},|]}Conditions${i}
        /if (${OptionType.Arg[${x},|]}==2) /declare ${Option.Arg[${x},|]}Recast${i} timer outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Recast${i}]}
        /if (${OptionType.Arg[${x},|]}==2) /declare Last${Option.Arg[${x},|]}${i} timer outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Recast${i}]}
        /goto :skipi
        :option3
        /declare ${OptionType.Arg[${x},|]}Color string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color]}
        /declare ${OptionType.Arg[${x},|]} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}]}
        /declare ${OptionType.Arg[${x},|]}Conditions string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Conditions,123456]}
        /if (${${Option.Arg[${x},|]}Conditions.Equal[123456]}) /deletevar ${Option.Arg[${x},|]}Conditions    
        /declare Last${OptionType.Arg[${x},|]} int outer
        :skipi
    /next i
:skipx
/next x
/return

Bot_CHARNAME_wizard.ini
Code:
[Settings]
DismountToInterrupt=FALSE
AnnounceSpellRoutines=FALSE
HaveVOA=TRUE
AnnounceSpellRoutinesChannel=cechob
DefaultGem=12
MedAt=40
MedTimer=10s
[Nuke]
NukeTotal=8
NukeColor=Red
NukeSpellName1=Claw of the Flamewing
NukeSpellName2=Ethereal Weave
NukeSpellName3=Ethereal Hoarfrost
NukeSpellName4=Ethereal Incandescence
NukeSpellName5=Ethereal Salvo
NukeSpellName6=Force of Will
NukeSpellName7=Force of Flame
NukeSpellName8=Force of Ice
NukeConditions1=!$\{Twincast}
NukeConditions2=$\{Twincast}||$\{Me.Song[Elemental Flames].ID}||$\{GoM}
NukeConditions3=
NukeConditions4=
NukeConditions5=
NukeConditions6=!$\{NoGlobalTimer}
NukeConditions7=!$\{NoGlobalTimer}
NukeConditions8=!$\{NoGlobalTimer}
[Jolt]
JoltTotal=5
JoltColor=Teal
JoltSpellName1=A Hole in Space
JoltSpellName2=Concussive Intuition
JoltSpellName3=Arcane Whisper
JoltSpellName4=Mind Crash
JoltSpellName5=Concussive Salvo
JoltConditions1=$\{Named} && $\{Me.PctAggro}>85
JoltConditions2=$\{Me.PctHPs}<70||$\{Me.PctAggro}>90
JoltConditions3=$\{Me.PctAggro}>70
JoltConditions4=$\{Named} && !$\{Me.Song[Silent Casting].ID}
JoltConditions5=$\{Named} && $\{Me.PctAggro}>95
[AA]
AATotal=11
AAColor=Purple
AASpellName1=Empowered Focus of Arcanum
AA2SpellName=Improved Twincast
AASpellName3=Twincast Rk. III
AASpellName4=Prolonged Destruction
AASpellName5=Lower Element
AASpellName6=Twilight Robe of the Frozen Flame
AASpellName7=Fury of Ro
AASpellName8=Fundament: Second Spire of Arcanum
AASpellName9=Silent Casting
AASpellName10=Fury of Kerafyrm
AASpellName11=Forceful Rejuvenation
AAConditions1=$\{Named}
AAConditions2=$\{Named} && !$\{Twincast}
AAConditions3=!$\{Twincast} && $\{Target.PctHPs}>70
AAConditions4=$\{Named}
AAConditions5=$\{Named}
AAConditions9=$\{Named}
AAConditions11=!$\{Cast.Ready[Bucolic Harvest Rk. II]} && $\{Me.PctMana}<30
[Harvest]
HarvestTotal=3
HarvestColor=Orange
HarvestSpellName1=Bucolic Harvest
HarvestSpellName2=Harvest of Druzzil
HarvestSpellName3=Summoned: Large Modulation Shard
HarvestConditions1=!$\{Me.Invis} && $\{Me.PctMana}<=65
HarvestConditions2=!$\{Me.Invis} && $\{Me.PctMana}<=64
HarvestConditions3=!$\{Me.Invis} && $\{Me.PctMana}<=70 && ${Me.CurrentHPs}>24000
[SelfBuff]
SelfBuffTotal=5
SelfBuffColor=White
SelfBuffSpellName1=Armor of the Stonescale Rk. II
SelfBuffSpellName2=Improved Familiar
SelfBuffSpellName3=Shield of the Dauntless Rk. II
SelfBuffSpellName4=Perfected Levitation
SelfBuffSpellName5=Pyromancy
SelfBuffConditions1=$\{Spell[${SelfBuff1}].Stacks} && !$\{Me.Buff[${SelfBuff1}].ID}
SelfBuffConditions2=$\{Spell[${SelfBuff2}].Stacks} && !$\{Me.Buff[${SelfBuff2}].ID}
SelfBuffConditions3=$\{Spell[${SelfBuff3}].Stacks} && !$\{Me.Buff[${SelfBuff3}].ID}
SelfBuffConditions4=$\{Spell[${SelfBuff4}].Stacks} && !$\{Me.Buff[${SelfBuff4}].ID}
SelfBuffConditions5=$\{Spell[${SelfBuff5}].Stacks} && !$\{Me.Buff[${SelfBuff5}].ID}
[Freeze]
FreezeTotal=1
FreezeColor=Blue
FreezeSpellName1=Skullfreeze Rk. II
FreezeConditions1=
 
oh, put () around the conditions. That should clear it up. Sorry, i didnt show what you would have to do for multiple variables or if you used ||.

So like:
NukeConditions2=($\{Twincast}||$\{Me.Song[Elemental Flames].ID}||$\{GoM})

Edit:
Also you may need to change:
SelfBuffConditions1=$\{Spell[${SelfBuff1}].Stacks} && !$\{Me.Buff[${SelfBuff1}].ID}
to be:
SelfBuffConditions1=($\{Spell[$\{SelfBuff1}].Stacks} && !$\{Me.Buff[$\{SelfBuff1}].ID})

The way .Replace works, it could randomly cause a crash if not. I dont know why it does it because it makes no sense.

Shortcut route:
ctrl+h
replace $\ with $
replace $ with $\

entire ini is fixed. (and you can convert back and forth from using the full macro with ease)
 
Last edited:
Buffs and harvest are working great now, thank you.

oh, put () around the conditions. That should clear it up. Sorry, i didnt show what you would have to do for multiple variables or if you used ||.

So like:
NukeConditions2=($\{Twincast}||$\{Me.Song[Elemental Flames].ID}||$\{GoM})

Edit:
Also you may need to change:
SelfBuffConditions1=$\{Spell[${SelfBuff1}].Stacks} && !$\{Me.Buff[${SelfBuff1}].ID}
to be:
SelfBuffConditions1=$\{Spell[$\{SelfBuff1}].Stacks} && !$\{Me.Buff[$\{SelfBuff1}].ID}

The way .Replace works, it could randomly cause a crash if not. I dont know why it does it because it makes no sense.

Shortcut route:
ctrl+h
replace $\ with $
replace $ with $\

entire ini is fixed. (and you can convert back and forth from using the full macro with ease)
 
Good deal.

I've added a few new TLO members that will get put out whenever latest compile is updated. You will be able to tidy up the INIs some. Accessing TLO/Members is a little faster than using custom variables, so I recommend switching to them once they go live.

- ${Me.Twincast} will return TRUE/FALSE if you have a version of Twincast on
- ${Me.GoM} will return 65-100 for highest level spell you can cast for free if you have GoM on, if no GoM on, it will be 0
- ${Target.Named} will work exactly like ${Named}

Ill try to poke around to see if i can make one for seeing if there is global cooldown or not. I had done a quick search for it once and couldnt find a real setting for it.
 
Last edited:
Updated spell_routines.inc to v2.8
New compile is up, it has a slew of new spell related variables and spell slot updates.

Me.Twincast
Me.GoM
Me.FirstBook
Me.LastBook

Target.Named

Spell.TargetType was updated to have all options

Item.Collectible

.Item.Procs - combat procs
.Item.Focus - focus effect or sympathetic procs
.Item.Worn - worn effect, like haste

lots of spell slots effects were updated. Auras were particularly annoying, so if you see any spell info that are wrong, let me know. This will eventually get changed in spell_routines.inc

Also, added a MakeIni.mac that will auto generate a complete Ini for you that will work with the examples mentioned above. You can find that macro on:
http://www.mmobugs.com/forums/everq...user-generated-macros-intermediate-level.html
 
Error when using this mac.

I'm getting "Subroutine SpellRoutinesLoad wasn't found" any clue what may be happening?



Code:
#turbo 80
#define MyIni Bot_${Me.CleanName}_${Me.Class}.ini
#include spell_routines.inc

Sub Main(string assist,int amount)
/declare Assist string outer ${If[${assist.Length},${assist},${Group.MainTank}]}
/declare AssistAt int outer ${If[${amount},${amount},98]}
/call Initialize
/echo ${Macro.Name} loaded.
/echo Assisting ${Assist} at ${AssistAt}


:mainloop
/doevents
/call CastTarget
/if (${Me.CombatState.NotEqual[COMBAT]} && !${Me.Hovering}) /call Rest
/if (${CombatConditions} && !${Me.Hovering}) /call Combat
/goto :mainloop
/return

Sub Rest
/if (${TarID}&&${Target.ID}!=${TarID}) /squelch /tar id ${TarID}
/call CastIfReady SelfBuff 1
/doevents
/call CastIfReady Harvest
/doevents
/call CastMed
/doevents
/call CastAutoClickies
/return

Sub Combat
/if (${TarID}&&${Target.ID}!=${TarID}) /squelch /tar id ${TarID}
/if (${Group}) /call CastCommand Command
/doevents
/call CastDPS ${Target.ID}
/call CastOncePerMob Freeze
/doevents
/call CastIfReady AA
/doevents
/call CastIfReady Jolt 1
/doevents
/call CastIfReady Nuke 1
/return

Sub Initialize
/declare i int local
/declare x int local
/call SpellRoutinesLoad
/noparse /declare CombatConditions string outer (${Target.ID}==${TarID} && ${Target.PctHPs}<=${AssistAt} && ${Target.LineOfSight} && !${Me.Feigning})

|options I want to use with "|" at the end and match up with type below it
|OptionTypes 1 = CastIfReady/No recast, 2=CastDuration/Yes recast, 3=CastOncePerMob
/declare Option string outer Nuke|Jolt|AA|Harvest|SelfBuff|Command|ImHit|Freeze|
/declare OptionType string outer 1|1|1|1|2|1|1|3|


/for x 1 to ${Option.Count[|]}
/declare ${Option.Arg[${x},|]}Total int outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Total]}
/if (${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color].Length}) /declare ${Option.Arg[${x},|]}Color string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color]}
/if (${OptionType.Arg[${x},|]}==3) /goto :option3
/if (!${${Option.Arg[${x},|]}Total}) /goto :skipx
    /for i 1 to ${${Option.Arg[${x},|]}Total}
        /declare ${Option.Arg[${x},|]}${i} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}SpellName${i}]}
        /declare ${Option.Arg[${x},|]}Conditions${i} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Conditions${i},123456]}
        /if (${${Option.Arg[${x},|]}Conditions${i}.Equal[123456]}) /deletevar ${Option.Arg[${x},|]}Conditions${i}
        /if (${OptionType.Arg[${x},|]}==2) /declare ${Option.Arg[${x},|]}Recast${i} timer outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Recast${i}]}
        /if (${OptionType.Arg[${x},|]}==2) /declare Last${Option.Arg[${x},|]}${i} timer outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Recast${i}]}
        /goto :skipi
        :option3
        /declare ${OptionType.Arg[${x},|]}Color string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Color]}
        /declare ${OptionType.Arg[${x},|]} string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}]}
        /declare ${OptionType.Arg[${x},|]}Conditions string outer ${Ini[MyIni,${Option.Arg[${x},|]},${Option.Arg[${x},|]}Conditions,123456]}
        /if (${${Option.Arg[${x},|]}Conditions.Equal[123456]}) /deletevar ${Option.Arg[${x},|]}Conditions    
        /declare Last${OptionType.Arg[${x},|]} int outer
        :skipi
    /next i
:skipx
/next x
/return
 
I think something edited my spellroutine.inc file so redownloaded and seems to be working fine.