- 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:
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)
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):
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.
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:
Version 2.7 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.6 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
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.-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
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
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
****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
Last edited: