Genbot v13.0.3 [Updated 06/15/2004] Buff Queues added!

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

Moderator: MacroQuest Developers

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Genbot v13.0.3 [Updated 06/15/2004] Buff Queues added!

Post by Vexix » Thu Jun 10, 2004 1:28 pm

*This is a production release of Genbot 13. Although I'm sure there are still some bugs, I consider this release stable enough for general use. Let me know where things are still not responding as you expect!

Current File Versions:
Genbot.mac 13.0.3
BotCore.inc 13.0.3
BotCombat.inc 13.0.3
BotSpell.inc 13.0.3
BotHealer.inc 13.0.3
BotShortCut.inc 13.0.3
Personal.inc 13.0.3
GenbotDoc.txt 12.38

Changelog 2004-06-15
Improved target change detection. As before, if your target changes state (dies, is charmed, etc) during your cast you will still duck to abort the spell, but if you just change away from your previous target, the cast will finish normally.

Changed default type for the MountItem to item instead of spell. A mount of "alt whateverthatpallymountaltis" will also work -- reported by sj_digriz

Fixed some typos -- thanks Nightshift

Changed shortcut arguments. Bug reported by sj_digriz. Previously, any shortcut that ended with on would have the argument of the shortcut when called appended to it. This hasn't worked out so well, so I've changed it to use the term "NameS" for the placeholder for the shortcut argument. Thus:

Old and busted:
fullbuff=buff aegolism on|buff Mark of Karn on|buff someotherthingy on
New hotness:
fullbuff=buff aegolism on NameS|buff Mark of Karn on NameS|buff someotherthingy on NameS|/tell NameS You are fully buffed, NameS. It's a pleasure fighting alongside you.|/wave NameS|/guild NameS is a buff leech!
All new buff code implemented. Selfbuffs for which the icon is recognized will be refreshed when the icon disappears. Unrecognized self buffs and other buffs will be refreshed 5 seconds before the max duration runs out.

sn vs. snt confusion fixed. Actually, the documentation on genbot is quite clear on how they work, so I think the confusion was all mine. They're switched back now. Thanks Mortedamour

AdvPath Follow command fixed. Unfortunately, ml2517's advpath include has an unspecified /doevents, which was causing an endless loop with my new timers for all major subs. I had to take out all of my routine timers, which was one of the ways I was trying to control the "load" genbot put on your PC. I've requested ml2517 remove the /doevents calls, since I'm not a fan of uncontrolled /doevents in .inc files.

Fixed the rememspells option. Reported by Saelinye and sj_digriz

Fixed the "heal" command. -- Reported by Saelinye.

Fixed IgninGroup to allow substrings of ignored words. For instance, "ds" was not allowed as a command in the group channel because it was the last 2 characters of "cmds".

Note: Some of the names of the .ini file settings for spells have changed for clarity, for example Remem has become RememSpells. You may want to regenerate your .ini file.

Changelog 06-11-2004
Removed an .inc line that caused errors in personal.inc

Changelog 06-10-2004
Updated the personal.inc so that it would be called from genbot.mac. Just 2 lines added.

Changelog 06-10-2004
Spell queues are now functional. Multiple spell commands can be issued without pauses in between, and genbot will remember all spells, and cast them in a first in first out order. Exceptions to this order are heals and evac spells initiated by genbot, which will be cast before any master requested spells.

Genbot automatically changes to the appropriate target immediately before casting, and changes back to your previous target immediately after casting. Genbot also recognizes target not required types of spells (pb ae, self, ae pc v2, and group v1), and does not change your target when casting them.

Before casting, genbot records the type of target (none, pc, npc, corpse, pet), and if that type changes during casting, genbot will abort the spell, assuming you're not riding a horse. This is handy if your target dies, is resurrected, is charmed, looses charm, or goes linkdead.

Items or alt abilities can be cast anywhere that a spell could be cast previously, just by prepending it with "item" or "alt" respectively, such as "buff item shrunken goblin earring" or "snt alt ae taunt". Alt abilities can called by number, or name. This functionality also works for buffs as well. Do alt buffs exist?

When requesting a spell, you can specify what spell gem to memorize to if not memorized already, such as "snt gem3 ensnare nagafen".

The major subroutines (coremain, spellmain, healmain, etc.) are now only called by timers. This ability will be developed in the future to allow you to control how often particular subs are called or if they are called at all to improve genbot performance in low frame rate environments.

Notes
I've changed the version number system so we don't end up with genbot v263.31 before it's time. The first digit represents the overall major release. Second digits represent enhancements to that release. Last digit represents bug fixes to that enhancement.

The focus of release 13 will be task queueing and performance improvement. With version 13.0.0, Spell queueing is implemented, along with handling of clickable items and alternate abilities as spells.



Known issues:

Heal messages from the .ini file don't work.
Task and spell overlap is not handled well. Requesting tasks in the middle of spells may not work.
Buffs are considered successful even if they didn't land.
Multiple genbot initiated heals can exist in the spell queue, so repeated heals may be cast on one char.
Requests to cast a spell that is already in the spell queue on the same target are ignored.
Not much testing done on alt commands, because, um, none of my chars have many alt abilities. :oops:
If using Windows XP or 2000, genbot performs much better if Performance Options are set to Background Services. http://techrepublic.com.com/5100-6313-5034438.html Programs setting can cause slow responses, especially with more than one char on a PC.

Function removals:
itemcast has been replaced with sn item <item name>, snt item <item name>, or buff item <item name>
The following commands have been replaced with the / commands:
afk <message> - Turn bot's afk on with optional <message>. USE: /tell bot /afk <message>
autoinv - Commands bot to use the /autoinv command USE: /tell bot /autoinv
camp - Commands bot to camp out. USE: /tell bot /camp
dismount - Commands bot to /dismount. USE: /tell bot /dismount
disc <discname> - Commands bot to fire the specified /disc. USE: /tell bot /disc <discname>
group <message> - Commands the bot to /gsay <message>. USE: /tell bot /g <message>
petback - Commands bot to execute it's /pet back command. USE: /tell bot /pet back
petguard - Commands bot to execute it's /pet guard command. USE: /tell bot /pet guard
random - Commands bot to /ran. USE: /tell bot /random <value>
say <message> - Commands the bot to /say <message>. USE: /tell bot /say <message>
sit - Makes bot sit USE: /tell bot /sit
stand - Makes bot stand USE: /tell bot /stand
tell <name> <message - Commands the bot to /tell <name> <message>. USE: /tell bot /tell <name> <message>


Future plans:
The ability to equip, cast, and replace items will be included.

Better buff management, including lists of outstanding buffs, the ability to remove 1 buff from the buff list, and the ability to have genbot time and name a buff icon for you.

Actions will also be incorporated into the task queue, which only contains castings stuff now.

Prioritization will be added to the task queue, so genbot can naturally decide what action to take next.

Code restructuring for increased performance.

New code for timers to determine if or how often to call subroutines.

Questions:

Can bards still cast items while moving or sitting? Moving yet, sitting no.
Can alt abilities be cast while sitting? Nope.
Do any notarget spell types besides pb ae, self, ae pc v2, and group v1 exist? None reported yet.
Why are pally spells handled as something different from every other healer? No answer.
As part of restructuring the code for better performance, I may mix the current sections, such as putting all init routines in one file. Would anyone mind this kind of reordering in return for better performance?

Ways you can help:

As you can see, I have a lot of plans for genbot, but my programming time is limited, and I kinda like to play with my own bots from time to time as well. ;) Here are some tasks that will make genbot even better, and are in search of sponsors:

Maintain the genbot doc to keep it up to date -- Latest revision done by Seagreen! Would someone like to maintain it?

Create an .ini explanation file. Lots of stuff in the .ini files that could use explanation.

Organize and sort the genbot code so it is consistent and easy to find things -- Done by sj-digriz! Thanks!

Create a scheme for organizing the genbot responses to commands throught the ChatOut subroutine. Genbots responses and response priority levels are pretty random right now, depending on who wrote 'em and their mood that day.

Create a Do-equip routine. Parameters should be either "item_name" or "slot item_name". If slot is named, then routine will attempt to equip that item in that slot, and place other item where ever the first item came from. Bonus points if you can make it handle 2HB and 2HS weapons, as well as putting items in bags into inventory slots. If a slot name isn't given, routine should find what slot the item can be equipped in, and equip it for you. An example of working code that does something similar are available here: http://macroquest2.com/phpBB2/viewtopic.php?t=7568.

Give me a PM if you're interest in any of these tasks!


Enjoy the new version, and let me know where it's not working as planned!

--Vexix

P.S. Go here for the previous version changelog: http://macroquest2.com/phpBB2/viewtopic.php?t=7393
Last edited by Vexix on Mon Jul 19, 2004 9:08 am, edited 8 times in total.

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Post by Vexix » Thu Jun 10, 2004 1:30 pm

genbot.mac

Code: Select all


|genbot.mac 
|Generic bot macro for any class. 
|Version 13.0.3 
|Date:06/15/2004
| 
||** 
[genbot] 
version=13.0.3
**|| 
| 

#include bothealer.inc 
#include botcombat.inc 
#include botspell.inc 
#include botcore.inc 
#include personal.inc 
#include botshortcut.inc 
#include advpath.inc 

Sub Main 
   /declare Commands[2,500] string outer 
   /declare Toggles[5,50] string outer 
   /declare TopCommand int outer 1 
   /declare TopToggle int outer 1 
    
   |Determine master(s) 
   |Determine if masterlist already exists - will exist if this is a reload 
   /if (!${Defined[MasterList]}) { 
      /if (!${Defined[Param0]}) { 
         /echo Usage: /macro generic <Master Name1> <Master Name2>... 
         /endmacro 
      } 
      /declare MasterList string global 
   } 
   /if (${Defined[Param0]}) { 
      |clear and rebuild master list if a list was passed 
      /varset MasterList | 
      /declare MasterCount int local 
      /for MasterCount 0 to ${Macro.Params} 
         /varset MasterList ${MasterList}${Param${MasterCount}}| 
      /next MasterCount 
   } 
    
    
    |Initialize variables in each include 
   /call Init-Core 
   /call Init-Combat 
   /call Init-Spell 
   /call Init-Healer 
   /call Init-Toggles 
   /call Init-Shortcuts 
   /call Init-Personal 
   :MainLoop 
   /doevents 
   |Fire tasks in each Include 
   /call CoreMain 
   /if (${IsHealer} || ${IsPally}) /call HealerMain 
   /call SpellMain 
   /call CombatMain  
   /call PersonalMain 
   /if (${advpath}) /call AdvPathPoll 
   /goto :MainLoop 

/return 
Last edited by Vexix on Tue Jun 15, 2004 9:28 am, edited 1 time in total.

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Post by Vexix » Thu Jun 10, 2004 1:31 pm

botcore.inc

Code: Select all

|botcore.inc
|Bot core module.
|Version 13.0.3
|Date:06/15/2004
|
||**
[botcore]
version=13.0.3
**||

#Define Debug-Core FALSE
#Define Debug-Spell FALSE

#chat chat
#chat group
#chat tell

#event Appear "You appear."
#event Appearing "You feel yourself starting to appear."
#event CorpseTooFar "You are too far away to loot that corpse."
#event ExpGained "#*#You gain#*#experience#*#"
#event FollowOff "You are no longer auto-following#*#"
#event ImDead "You have been slain by#*#"
#event IRC "<#1#> #2#"
#event LosingLev "You feel as if you are about to fall"
#event SelfEcho "[MQ2] Genbot #*#"
#event Zoned "LOADING, PLEASE WAIT..."

Sub Init-Core
   /declare cmds-CORE string outer Core:
   |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 CORE accept Do-accept
   /call AddCommand CORE anchor Do-anchor
   /call AddCommand CORE anchorradius Do-anchorradius
   /call AddCommand CORE assist Do-assist
   /call AddCommand CORE chatin Do-chatin
   /call AddCommand CORE cmds Do-cmds
   /call AddCommand CORE consent Do-consent
   /call AddCommand CORE door Do-door
   /call AddCommand CORE duck Do-duck
   /call AddCommand CORE exp Do-exp
   /call AddCommand CORE equip Do-equip
   /call AddCommand CORE face Do-face
   /call AddCommand CORE follow Do-follow
   /call AddCommand CORE FollowMode Do-FollowMode
   /call AddCommand CORE invite Do-invite
   /call AddCommand CORE lootall Do-lootall
   /call AddCommand CORE lootup Do-lootup
   /call AddCommand CORE mount Do-mount
   /call AddCommand CORE moveto Do-moveto
   /call AddCommand CORE MoveToMode Do-MoveToMode
   /call AddCommand CORE norelay Do-norelay
   /call AddCommand CORE notarget Do-notarget
   /call AddCommand CORE pause Do-pause
   /call AddCommand CORE petattack Do-petattack
   /call AddCommand CORE reject Do-reject
   /call AddCommand CORE relay Do-relay
   /call AddCommand CORE reload Do-reload
   /call AddCommand CORE reportbuffs Do-reportbuffs
   /call AddCommand CORE rmod Do-rmod
   /call AddCommand CORE rset Do-rset
   /call AddCommand CORE Rptvar Do-Rptvar
   /call AddCommand CORE run Do-run
   /call AddCommand CORE saytarget Do-saytarget
   /call AddCommand CORE Setvar Do-Setvar
   /call AddCommand CORE stay Do-stay
   /call AddCommand CORE stop Do-stop
   /call AddCommand CORE target Do-target
   /call AddCommand CORE trade Do-trade
   /call AddCommand CORE verbosity Do-verbosity
   /call AddCommand CORE yesres Do-yes
   
   |Declare Vars
   /declare advpath bool outer
   /declare Afollow int outer 0
   /declare AnchorRadius int outer 10
   /declare AnchorX int outer 0
   /declare AnchorY int outer 0
   /declare AttackOnAssist bool outer FALSE
   /declare BehindOnAssist bool outer FALSE
   /declare BreakOut bool outer FALSE
   /declare ChatIn string outer Tell
   /declare ChatInChannel string outer
   /declare CheckName bool outer FALSE
   /declare Combatstatus bool outer FALSE
   /declare CommandParam string outer
   /declare CorpseRadius int outer
   /declare CurrCommand string outer
   /declare FaceFastini int outer
   /declare FastRange int outer 14
   /declare FastMin int outer 6
   /declare FollowDistanceini int outer
   /declare FollowTarget string outer
   /declare FollowMode int outer 1
   /declare GenLastXLoc int outer 0
   /declare GenLastYLoc int outer 0
   /declare IgnGroupList string outer
   /declare IsAnchored bool outer FALSE
   /declare ListenChan string outer
   /declare ListenChat bool outer FALSE
   /declare ListenGroup bool outer FALSE
   /declare LootTooFar int outer 0
   /declare MasterName string outer ${MasterList.Arg[1,|]}
   /declare MaxTargetRange int outer
   /declare MountItem string outer
   /declare MoveToMode int outer 1
   /declare PetOnAssist bool outer FALSE
   /declare ObstacleCheck int outer 0
   /declare Relaytells bool outer TRUE
   /declare RangeMin int outer 10
   /declare RangeMax int outer 12
   /declare SilentFlagini int outer
   /declare SpeedSenseini int outer
   /declare SubCallName string outer
   /declare Supportstatus bool outer
   /declare Verbosity int outer 9

|Timers
   /declare SitTimer timer
   /declare ST-CoreMain timer outer 0
   
   /call LoadSetting AnchorRadius CORE AnchorRadius 6
   /call LoadSetting AttackOnAssist CORE AttackOnAssist 0
   /call LoadSetting BehindOnAssist CORE BehindOnAssist 0
   /call LoadSetting ChatIn CORE ChatIn Tell
   /call LoadSetting ChatInChannel CORE ChatInChannel "Channel Name"
   /call LoadSetting CheckName CORE CheckName 0
   /call LoadSetting CorpseRadius CORE MaxLootRadius 50
   /call LoadSetting FaceFastini advpath FaceFast 1
   /call LoadSetting FastMin CORE FastMin 6
   /call LoadSetting FastRange CORE FastRange 14
   /call LoadSetting FollowDistanceini advpath FollowDistance 20
   /call LoadSetting FollowMode CORE FollowMode 1
   /call LoadSetting IgnGroupList CORE IgnGroupList duck|say|tell|group|cmds|trade|run|backstab|taunt|evade|slam|bash|kick|flyingkick|disarm|traps|puller||
   /call LoadSetting ListenChan CORE ListenChan Name_of_channel
   /call LoadSetting ListenChat CORE ListenChat 1
   /call LoadSetting ListenGroup CORE ListenGroup 1
   /call LoadSetting MountItem CORE MountItem "Name of Bridle or Drum"
   /call LoadSetting MaxTargetRange CORE MaxTargetRange 250
   /call LoadSetting MoveToMode CORE MoveToMode 1
   /call LoadSetting PetOnAssist CORE PetOnAssist 0
   /call LoadSetting RangeMax CORE RangeMax 12
   /call LoadSetting RangeMin CORE RangeMin 10
   /call LoadSetting Relaytells CORE Relaytells 1
   /call LoadSetting SilentFlagini advpath SilentFlag 1
   /call LoadSetting SpeedSenseini advpath SpeedSense 15
   /call LoadSetting Verbosity CORE Verbosity 9

   /squelch /alias /gb /echo genbot

   /declare advpathv float local
   /varset advpathv ${Ini[advpath.inc,advpath,version,99999]}
   /if (${advpathv}==99999) {
      /echo Advanced pathing NOT available.
      /varset advpath 0
   } else {
      /if (${advpathv}>=1.24) {
         /varset advpath 1
         /call InitAPFVars ${FaceFastini} ${SpeedSenseini} ${FollowDistanceini}
         /varset SilentFlag ${SilentFlagini}
      } else {
         /echo Minimum advpath.inc v(1.24) required - you have v(${advpathv})
         /echo Advanced pathing found, but too old. Update it!
         /varset advpath 0
      }
   }
/return

Sub AddCommand(string CmdSect,string CmdPhrase,string CmdRoutine)
   /varset Commands[1,${TopCommand}] ${CmdPhrase}
   /varset Commands[2,${TopCommand}] ${CmdRoutine}
   /varcalc TopCommand ${TopCommand}+1
   /varset cmds-${CmdSect} ${cmds-${CmdSect}} ${CmdPhrase}
/return

Sub LoadSetting(string VarName,string SectionName,string KeyName,string DefaultValue)
   /if (!${Defined[LoadFrom]}) {
      /declare LoadFrom string outer ini
   }
   /if (${LoadFrom.Equal[ini]}) {
      /declare IniValue string local
      /if (!${Defined[IniFile]}) {
         |setup ini File Reference
         /declare IniFile string outer genbot_${Me.CleanName}.ini
      }
      /varset IniValue ${Ini[${IniFile},${SectionName},${KeyName},NOTFOUND]}
      /if (${IniValue.Equal[NOTFOUND]}) {
         /ini ${IniFile} "${SectionName}" "${KeyName}" "${DefaultValue}"
         /varset ${VarName}  ${DefaultValue}
      } else {
         /varset ${VarName}  ${IniValue}
      }
   }

/return

Sub CoreMain
   /varset ST-CoreMain 0
   /if (${Combatstatus}) /return
   /if ((!${Supportstatus})&&(!${IsAnchored})) {
      /if (${Afollow}) {
         /varset CommandParam ${FollowTarget}
         /call Do-moveto
      }
   }
   /if (${IsAnchored}) {
      /if (${Math.Distance[${AnchorY},${AnchorX}]}>${AnchorRadius}) {
         /call MoveToAnchor
      } else {
         /if ((${SitAfterCast})&&(${Me.Standing}&&!${SitTimer})) /varset SitTimer ${DelayBeforeSit}
      }
   }
/return

||||||||||||Do-subs

Sub Do-accept
   /target clear
   /invite
/return

Sub Do-reject
   /target clear
   /disband
/return

Sub Do-anchor
   /if (!${IsAnchored}) {
      /varset IsAnchored 1
      /varset AnchorX ${Me.X}
      /varset AnchorY ${Me.Y}
      /varset Afollow 0
      /varset FollowTarget NULL
      /if (${advpath} && ${FollowFlag}) /call StopFunction
      /keypress LEFT
      /keypress RIGHT
      /call ChatOut 5 ${MasterName} "Created anchor at Loc: ${AnchorY},${AnchorX}."
      /return
   }
   /if (${IsAnchored}) {
     /varset IsAnchored 0
     /call ChatOut 5 ${MasterName} "Removed Anchor."
   }
/return

Sub Do-anchorradius(int NewRadius)
   /if (!${Defined[NewRadius]}) {
      /call ChatOut 3 ${MasterName} "My anchor radius is ${AnchorRadius}."
   }
   /if (${NewRadius}<3) /return
   /varset AnchorRadius ${NewRadius}
   /call ChatOut 3 ${MasterName} "My new anchor radius is ${AnchorRadius}."
/return

Sub Do-assist(string AssistName)
   /varset Supportstatus 1
   /if (!${Defined[AssistName]}) {
      /call Assist "${MasterName}"
   } else /if (${AssistName.Equal[me]}) {
      /call Assist "${MasterName}"
   } else /if (${AssistName.Equal[yourself]}) {
      /return
   } else /if (${AssistName.Equal[${Me.CleanName}]}) {
      /return
   } else {
      /call Assist "${CommandParam}"
   }
   /if (!${Target.ID}) {
      /call ChatOut 5 ${MasterName} "I failed to get a target."
   } else {
      /call ChatOut 5 ${MasterName} "My target is now ${Target.CleanName}."
      /if (${AttackOnAssist}) /varset Combatstatus 1
      /if (${BehindOnAssist}) /call do-getbehind
      /if (${PetOnAssist}) {
         /if (${Me.Sitting}) /Stand
         /call Delay 5
         /pet attack
         /call Delay 5
         /if (${SitAfterCast} && ${Me.Standing}) /varset SitTimer ${DelayBeforeSit}
      }
   }
   /call ExecCommand assistcall
/return

Sub Do-chatin
   /if (!${Defined[Param0]}) {
      /call ChatOut 1 ${MasterName} "My chat goes to ${ChatIn}."
      /return
   }
   /varset ChatIn ${Param0}
   /call ChatOut 1 ${MasterName} "My chat goes to ${ChatIn}."
/return

Sub Do-cmds
   /declare CommandTypes string local Core|Spell|Combat|Healer|Personal|Toggles|Shortcuts|
   /if (${Defined[Param0]} && ${CommandTypes.Find[${Param0}]}) {
      /call ChatOut 2 ${MasterName} "${cmds-${Param0.Upper}}"
      /return
  } else {
      /call ChatOut 3 ${MasterName} "Must specify one of ${CommandTypes}"
  }
/return

Sub Do-consent(string TargetName)
   /if (!${Defined[TargetName]}) {
      /call Assist "${MasterName}"
      /varset CommandParam ${Target.CleanName}
      /consent ${Target.CleanName}
   } else /if (${TargetName.Equal[me]}) {
      /call ChatOut 3 ${MasterName} "I'm giving you consent."
      /consent ${MasterName}
      /varset CommandParam ${MasterName}
      /return
   } else /if (${TargetName.Equal[yourself]}) {
      /return
   } else /if (${TargetName.Equal[${Me.CleanName}]}) {
      /return
   } else {
      /consent ${CommandParam}
   }
   /call ChatOut 3 ${MasterName} "I gave consent to ${CommandParam}"
/return

Sub Do-Door
   /doort
   /face door
   /keypress u
/return

Sub Do-duck
   /keypress DUCK
   /varset SpellFail 1
   /varset CTimer 0
/return

Sub Do-exp
   /call ChatOut 5 ${MasterName} "I am at ${Me.PctExp} percent exp.
/return

Sub Do-equip
      /if (${Macro.Params}>1) {
         /for counter 1 to ${Math.Calc[${Macro.Params}-1]}
            /varset CommandText ${CommandText} ${Param${counter}}
         /next counter
         /if {Debug-Core} /echo Do-equip CommandText ${CommandText}
      }
      /declare SlotName string local ${CommandText.Arg[${Math.Calc[${CommandText.Count[ ]}+1]}]}
      /if (${InvSlot[SlotName]} && ${InvSlot[SlotName]}<22) {
         /varset slotName ${SlotName} 
         /varset CommandText ${CommandText.Right[-${CommandText.Arg[${Math.Calc[${CommandText.Count[ ]}+1]}].Length}]}
      
      /if ( !${FindItem[${spellName}].InvSlot} ) { 
         /echo Cannot find item: ${spellName} 
         /return CAST_UNKNOWNSPELL 
      }      
      /if ( ${FindItem[${spellName}].InvSlot}>30 ) { 
         /varset swapItemBack true 
         /if ( ${FindItem[${spellName}].WornSlot[1]} ) { 
            /varset slotName ${FindItem[${spellName}].WornSlot[1]} 
         } else { 
            /varset slotName pack8 
         } 
         /varset slotID ${InvSlot[${slotName}].ID} 
         /varset oldSlotID ${FindItem[${spellName}].InvSlot.ID} 
         /autoinventory 
         /if ( ${InvSlot[${oldSlotID}].Pack} ) { 
      :open_pack 
            /nomodkey /itemnotify ${InvSlot[${oldSlotID}].Pack} rightmouseup 
            /if ( !${Window[${InvSlot[${oldSlotID}].Pack.Name}].Open} ) /goto :open_pack 
         } 
      :pick_up_item 
         /if ( ${InvSlot[${oldSlotID}].Pack} && !${Window[${InvSlot[${oldSlotID}].Pack.Name}].Open} ) /nomodkey /itemnotify ${InvSlot[${oldSlotID}].Pack} rightmouseup 
         /nomodkey /itemnotify ${InvSlot[${oldSlotID}]} leftmouseup 
         /if ( !${Cursor.Name.Equal[${spellName}]} ) /goto :pick_up_item 
      :exchange_items 
         /nomodkey /itemnotify ${slotID} leftmouseup 
         /if ( !${Me.Inventory[${slotID}].Name.Equal[${spellName}]} ) /goto :exchange_items 
      } 

/return

Sub Do-face
   /call StandardTarget "${CommandParam}"
   /call ChatOut 5 ${MasterName} "Facing ${Target.CleanName}."
   /if (${Me.Sitting}) /Stand
   /call Delay 5
   /face
/return

Sub Do-follow
   /if (${Me.Sitting}) /Stand
   /varset IsAnchored 0
   /if (!${Defined[Param0]}) {
         /varset FollowTarget ${MasterName}
   } else /if (${CommandParam.Equal[me]}) {
         /varset FollowTarget ${MasterName}
   } else /if (${CommandParam.Equal[yourself]}) {
         /return
   } else /if (${CommandParam.Equal[${Me.CleanName}]}) {
         /return
   } else {
         /varset FollowTarget ${CommandParam}
   }
   /call Target "${FollowTarget}"
   /if (${FollowMode}==1) {
      /varset Afollow 1
   }
   /if (${FollowMode}==2) {
      /call FollowFunction "${Target.CleanName}"
   }
   /if (${FollowMode}==3) {
      /follow
   }
   /if (${Target.ID}) {
      /call ChatOut 5 ${MasterName} "I am now following ${Target.CleanName}."
   } else {
      /call ChatOut 5 ${MasterName} "Unable to follow ${FollowTarget}."
      /call StopFunction
      /varset FollowTarget NULL
   }
/return

Sub Do-FollowMode
   /if (!${Defined[Param0]}) /return
   /varset FollowMode ${Param0}
/return

Sub Do-invite(string TargetName)
   /if (!${Defined[Param0]}) {
      /call Assist "${MasterName}"
   } else /if (${TargetName.Equal[me]}) {
      /call Target "pc ${MasterName}"
   } else /if (${TargetName.Equal[yourself]}) {
      /return
   } else /if (${TargetName.Equal[${Me.CleanName}]}) {
      /return
   } else {
      /call Target "pc ${CommandParam}"
   }
   /call ChatOut 3 ${MasterName} "Inviting ${Target.CleanName}."
   /invite
/return

Sub Do-lootall
   /declare DeadCount int local
   /declare CorpseList string local
   /declare si int local
   /if (${Me.Combat}) {
      /call ChatOut 5 ${MasterName} "I'm busy fighting right now.  Ask me to loot again later!"
      /return
   }
   /varset DeadCount ${SpawnCount[corpse radius ${CorpseRadius}]}
   /if (!${DeadCount}) {
      /call ChatOut 5 ${MasterName} "No corpses within range to loot."
      /return
   }
   /vardata CorpseList String[ ]
   /for si 1 to ${DeadCount}
      /varset CorpseList ${CorpseList} ${NearestSpawn[${si},corpse radius ${CorpseRadius}].ID}
   /next si
   /for si 1 to ${DeadCount}
      /call Target "id ${CorpseList.Arg[${si}]}
      /if (${Target.Type.Equal[corpse]}) /call Loot
   /next si
/return

Sub Do-lootup
   /if (!${Defined[Param0]}) {
      /call Assist "${MasterName}"
   } else {
      /call Target "${CommandParam}"
   }
   /call Loot
/return

Sub Do-mount
   /if (${Me.Sitting}) /stand
   /if (!${String[ item alt spell slot ].Find[ ${MountItem} ]}) /varset MountItem item ${MountItem}
   /call AddCast "${MountItem}" "0" buff
   /call ChatOut 5 ${MasterName} "Summoning my mount."
/return

Sub Do-moveto(string TargetName)
   /if (${Me.Sitting}) /stand
   /varset ObstacleCheck 0
   /varset GenLastXLoc ${Me.X}
   /varset GenLastYLoc ${Me.Y}
   /if (!${Defined[TargetName]}) {
      /call Assist "${MasterName}"
      /varset CommandParam ${Target.CleanName}
   } else /if (${TargetName.Equal[me]}) {
      /call Target "${MasterName}"
      /varset CommandParam ${Target.CleanName}
   } else /if (${TargetName.Equal[yourself]}) {
      /return
   } else /if (${TargetName.Equal[${Me.CleanName}]}) {
      /return
   } else {
      /call Target "${CommandParam}"
   }
   /if (!${Target.ID}) /return
   /doevents chat
   /if (${MoveToMode}==1) {
      |/if (${Supportstatus}) /return
      /call RangeSub
   }
   /if (${MoveToMode}==2) {
      /call GotoFunction "${Target.Y}" "${Target.X}" "${Target.Z}"
   }
/return

Sub Do-MoveToMode
   /if (!${Defined[Param0]}) /return
   /varset MoveToMode ${Param0}
/return

Sub Do-notarget
   /target clear
/return

Sub Do-pause
      /if (${advpath}) {
         /if (!${PauseFlag}) {
            /call ChatOut 5 ${MasterName} "Pausing."
         } else {
            /call ChatOut 5 ${MasterName} "Unpausing."
         }
         /call PauseFunction
      }
/return

Sub Do-petattack
   /call Assist "${MasterName}"
   /if (!${Target.ID}) /call ChatOut 5 ${MasterName} "I failed to get a target."
   /pet attack
/return

Sub Do-relay
   /varset Relaytells 1
/return

Sub Do-norelay
   /varset Relaytells 0
/return

Sub Do-reload
   /call ChatOut 5 ${MasterName} "Reload initiated."
   /mac genbot
/return

Sub Do-reportbuffs
   /if (${Defined[Param0]}) {
      /declare myBuffs string local Buffs:
      /declare counter int local
      /for counter 0 to 15
          /if (${Me.Buff[${counter}].ID}) /varset myBuffs ${myBuffs} "${Me.Buff[${counter}]}"
      /next counter
      /call ChatOut 1 ${MasterName} "${myBuffs}"
   } else {
      /if (${Param0.Equal[queue]}) {
         /declare counter int local
         /for counter 1 to ${BuffListCount}
            /call ChatOut 1 ${MasterName} "Buff ${BuffList[${counter},2]} needs to be refreshed on ${BuffList[${counter},1]} in {BuffListTimes[${counter},1]} seconds."
         /next counter
      }
   }
/return

Sub Do-rmod(int RangeMod)
   /if (!${Defined[RangeMod]}) {
   /varcalc RangeMin ${RangeMin}+${RangeMod}
   /varcalc RangeMax ${RangeMax}+${RangeMod}
   /varcalc FastRange ${FastRange}+${RangeMod}
   /varcalc FastMin ${FastMin}+${RangeMod}
   /call ChatOut 3 ${MasterName} "New Ranges: FastMin=${FastMin} RangeMin=${RangeMin} RangeMax=${RangeMax} FastRange=${FastRange}"
/return

Sub Do-rset(int NewFastMin,int NewRangeMin,int NewRangeMax,int NewFastRange)
   /if (!${Defined[NewFastMin]}) /return
   /if (!${Defined[NewRangeMin]}) /return
   /if (!${Defined[NewRangeMax]}) /return
   /if (!${Defined[NewFastRange]}) /return
   /if (${NewFastMin}>${NewRangeMin}) /return
   /if (${NewRangeMin}>${NewRangeMax}) /return
   /if (${NewRangeMax}>${NewFastRange}) /return
   /varset FastMin ${NewFastMin}
   /varset RangeMin ${NewRangeMin}
   /varset RangeMax ${NewRangeMax}
   /varset FastRange ${NewFastRange}
   /call ChatOut 3 ${MasterName} "New Ranges: FastMin=${FastMin} RangeMin=${RangeMin} RangeMax=${RangeMax} FastRange=${FastRange}"
/return

Sub Do-Rptvar
   /if (!${Defined[Param0]}) /return
   /call ChatOut 5 ${MasterName} "${Param0} is equal to ${${Param0}}"
/return

Sub Do-run
   /keypress ctrl+r
/return

Sub Do-saytarget
   /call ChatOut 5 ${MasterName} "my target is ${Target.CleanName}."
/return

Sub Do-Setvar
   /if (!${Defined[Param0]}) /return
   /declare VarLen int local
   /declare ValueLen int local
   /declare VarName string Local
   /varset VarName ${CommandParam.Arg[1]}
   /varset VarLen ${CommandParam.Length}
   /varset ValueLen ${CommandParam.Length}
   /varcalc ValueLen ${ValueLen}-${VarLen}
   /varset ${VarName} ${CommandParam.Right[${ValueLen}]}
   /call ChatOut 5 ${MasterName} "${Param0} is now equal to ${${Param0}}"
/return

Sub Do-stay
   /varset Afollow 0
   /varset FollowTarget NULL
   /if ((${advpath})&&(${FollowFlag})) /call StopFunction
   /keypress LEFT
   /keypress RIGHT
/return

Sub Do-stop
   /dismount
   /varset Supportstatus 0
   /varset BreakOut 1
   /varset LootTooFar 1
   /varset SpellFail 1
   /varset Afollow 0
   /if ((${advpath})&&(${FollowFlag})) /call StopFunction
   /varset FollowTarget NULL
   /call ChatOut 5 ${MasterName} "Stopping."
   /keypress LEFT
   /keypress RIGHT
   /keypress DUCK
   /keypress DUCK
   /target clear
   /keypress right
/return

Sub Do-target
   /varset Supportstatus 1
   /call StandardTarget "${CommandParam}"
   /call ChatOut 5 ${MasterName} "My target is now ${Target.CleanName}."
/return

Sub Do-trade
   /call ChatOut 5 ${MasterName} "Clicking trade."
   /notify TradeWnd TRDW_Trade_Button LeftMouseUp
   /call Delay 3
/return

Sub Do-verbosity(int NewVerbosity)
   /if (!${Defined[NewVerbosity]}) {
      /call ChatOut 1 ${MasterName} "My Verbosity is set to ${Verbosity}."
      /return
   }
   /varset Verbosity ${NewVerbosity}
   /call ChatOut 1 ${MasterName} "My Verbosity is set to ${Verbosity}."
/return

Sub Do-yes
   /call ChatOut 5 ${MasterName} "Clicking yes for res."
   /notify ConfirmationDialogBox Yes_Button leftmouseup
   /call Delay 3
/return


|||||||||||| Called subs

Sub Assist(string sAssistName)
   /squelch /target clear
   /if (Debug-Core) /echo /assist ${sAssistName}
   /assist ${sAssistName}
   /delay 3s ${Target.ID}
   /if (!${Target.ID}) /echo Unable to /assist you.
/return

Sub ChatOut(int ChatPriority,string ChatTarget,string ChatText)
   /if (${ChatPriority}>${Verbosity}) /return
   /if (${ChatTarget.Equal[GROUP]}) {
      /gsay ${ChatText}
      /return
   }
   /if (${ChatTarget.Equal[${Me.CleanName}]}) {
      /echo ${ChatText}
      /return
   }
   /if (${ChatIn.Equal[tell]}) {
      /tell ${ChatTarget} ${ChatText}
   } else /if (${ChatIn.Equal[Group]}) {
      /gsay ${ChatText}
   } else /if (${ChatIn.Equal[Raid]}) {
      /rsay ${ChatText}
   } else /if (${ChatIn.Equal[Say]}) {
      /say ${ChatText}
   } else /if (${ChatIn.Equal[Channel]}) {
      /chat #${ChatInChannel} ${ChatText}
   } else /if (${ChatIn.Equal[IRC]}) {
      /irc ${ChatText}
   }
/return

Sub Detectobst
   /if (${Math.Distance[${GenLastYLoc},${GenLastXLoc},${Me.Z}:${Me.Y},${Me.X},${Me.Z}]}<1) /call Hitobst 5
   /varset GenLastXLoc ${Me.X}
   /varset GenLastYLoc ${Me.Y}
/return

Sub ExecCommand(string CommandText)
   /declare counter int local

   /if (${Macro.Params}>1) {
      /for counter 1 to ${Math.Calc[${Macro.Params}-1]}
         /varset CommandText ${CommandText} ${Param${counter}}
      /next counter
   }
   /if (${CommandText.Left[1].Equal[/]}) {
      /docommand ${CommandText}
      /return
   }
   /varset CurrCommand ${CommandText.Arg[1]}
   /if (${CommandText.Arg[2].Length}) {
      /varset CommandParam ${CommandText.Right[-${CurrCommand.Length}]}
   } else {
      /varset CommandParam
   }
   /if (${Defined[cmds-SHORTCUTS]}) {
      /if (${String[ ${cmds-SHORTCUTS.Lower} ].Find[ ${CurrCommand.Lower} ]}) {
         /call ShortCut "${CommandText}"
         /return
      }
   }

   /if (${Defined[cmds-ROUTINES]}) {
      /if (${String[ ${cmds-ROUTINES.Lower} ].Find[ ${CurrCommand.Lower} ]}) {
         /call Routine "${CommandText}"
         /return
      }
   }
   /for counter 1 to ${TopCommand}
      /if (${CurrCommand.Equal[${Commands[1,${counter}]}]}) {
         /call ${Commands[2,${counter}]} ${CommandParam}
         /return
      }
   /next counter

   /if (${Defined[Toggles]}) {
      /for counter 1 to ${TopToggle}
         /if (${CurrCommand.Equal[${Toggles[1,${counter}]}]}) {
            /call SetToggle ${counter} ${CommandParam}
            /return
         }
      /next counter
   }
/return

Sub Fastback
   /varset ObstacleCheck 0
   /varset GenLastXLoc ${Me.X}
   /varset GenLastYLoc ${Me.Y}
   :fastbackloop
      /doevents chat
      /if (!${Target.ID}) {
         /varset Combatstatus 0
         /Keypress BACK
         /if (${Me.Combat}) /attack off
         /return
      }
      /if (${Me.Sitting}) /stand
      /face fast
      /if (${Target.Distance}<${FastMin}) /Keypress BACK hold
      /if (${Target.Distance}>=${FastMin}) {
            /Keypress BACK
            /return
         }
   /if (${ObstacleCheck}>=8) {
      /if ((${GenLastXLoc}==${Me.X})&&(${GenLastYLoc}==${Me.Y})) {
         /if (${Math.Rand[100]}>50) {
            /Keypress STRAFE_LEFT hold
            /delay 1
            /Keypress STRAFE_LEFT
            /return
         } else {
            /Keypress STRAFE_RIGHT hold
            /delay 1
            /Keypress STRAFE_RIGHT
            /return
         }
      }
      /varset GenLastXLoc ${Me.X}
      /varset GenLastYLoc ${Me.Y}
   }
   /varcalc ObstacleCheck ${ObstacleCheck}+1
   /goto :fastbackloop
/return

|Fastmove
|Called by Rangesub for when mob is more than /keypress distance away.
|Usage: /call Fastmove
Sub Fastmove
   /varset ObstacleCheck 0
   /varset GenLastXLoc ${Me.X}
   /varset GenLastYLoc ${Me.Y}
   :fastmoveloop
   |/doevents chat   Took out since it was stuffing up evacs?
   /if (!${Target.ID}) {
      /varset Combatstatus 0
      /keypress FORWARD
      /if (${Me.Combat}) /attack off
      /return
   }
   /if (${Me.Sitting}) /stand
   /face fast
   /if (${Target.Distance}>${FastRange}) /keypress FORWARD hold
   /if (${Target.Distance}<=${FastRange}) {
      /keypress FORWARD
      /return
   }
   /if (${ObstacleCheck}>=60) {
      /call Detectobst
      /varset ObstacleCheck 0
   }
   /if (${Target.Distance}>=${FastRange}) /varcalc ObstacleCheck ${ObstacleCheck}+1
   /goto :fastmoveloop
/return

Sub Hitobst(int HoldTime)
   /keypress FORWARD
   /keypress BACK hold
   /if (${Math.Rand[100]}>50) {
      /call Delay 2s
      /keypress BACK
      /keypress RIGHT hold
      /call Delay ${HoldTime}
      /keypress RIGHT
      /keypress FORWARD hold
      /call Delay 2s
      /keypress FORWARD

   } else {
      /call Delay 2s
      /keypress BACK
      /keypress LEFT hold
      /call Delay ${HoldTime}
      /keypress LEFT
      /keypress FORWARD hold
      /call Delay 2s
      /keypress FORWARD
   }
   /keypress LEFT
   /keypress RIGHT
/return

sub Loot
   /declare counter int local
   /declare LootSlot int local 1
   /if (${Me.Combat}) /return
   /if (!${Target.ID}) /target corpse radius 100
   /if (${Target.State.NotEqual[DEAD]}) /return
   /call Rangesub
   /face
   /varset LootTooFar 0
   /lootn never
   /loot
   /varset counter 0
   :CoreWaitLoot
      /call Delay 5
      /doevents chat
      /varcalc counter ${counter}+1
      /if (${BreakOut}) /goto :donelooting
      /if (${counter}>12) /goto :donelooting
   /if (!${Corpse.Items}) /goto :CoreWaitLoot
   /delay 2s
   /call ChatOut 5 ${MasterName} "Looting ${Target.CleanName}."
   :lootloop
      /if (${LootTooFar}) /goto :donelooting
      /if (!${Corpse.Items}) /goto :donelooting
      /doevents chat
      /itemnotify loot${LootSlot} rightmouseup
      /call Delay 1s
      /varcalc LootSlot ${LootSlot}+1
      /doevents chat
      /if (${Cursor.ID}) /goto :donelooting
      /if (${BreakOut}) /goto :donelooting
   /goto :lootloop
   :donelooting
   /lootn always
   /notify LootWnd DoneButton leftmouseup
/return

Sub MoveToAnchor
   /varset GenLastXLoc ${Me.X}
   /varset GenLastYLoc ${Me.Y}
   /varset ObstacleCheck 0
   :AnchorMoveLoop
      /if (!${IsAnchored}) {
         /keypress BACK
         /return
      }
      /doevents chat
      /if (${Combatstatus}) {
         /keypress down
         /return
      }
      /if (${Me.Sitting}) /stand
      /face nolook loc ${AnchorY},${AnchorX}
      /if (${Math.Distance[${AnchorY},${AnchorX}]}>${AnchorRadius}) /keypress FORWARD hold
      /if (${Math.Distance[${AnchorY},${AnchorX}]}<=${AnchorRadius}) {
         /keypress FORWARD
         /face away nolook loc ${AnchorY},${AnchorX}
         /keypress Home
         /return
      }
      /if (${ObstacleCheck}>=3) {
         /call Detectobst
         /varset ObstacleCheck 0
      }
      /varcalc ObstacleCheck ${ObstacleCheck}+1
   /goto :AnchorMoveLoop
/return


|RangeSub
|Used to keep bot in combat range.
|Usage /call Rangesub
|Vars Used: RangeMax, RangeMin, FastRange, FastMin
Sub Rangesub
   /if (!${Target.ID} || ${Target.ID}==${Me.ID}) /return
   /if (${Target.CleanName.Equal[${Me.CleanName}]}) /return
   /if (${Me.Sitting}) /stand
   /face fast
   /if (${Target.Distance}>=${FastRange}) /call Fastmove
   /if (${Target.Distance}<=${FastMin}) /call FastBack
   /if (${Target.Distance}>${RangeMax}) /keypress FORWARD
   /if (${Target.Distance}<${RangeMin}) /keypress BACK
/return

Sub StandardTarget(string TargetName)
   /if (!${Defined[TargetName]}) {
      /return
   } else /if (!${TargetName.Length}) {
      /call Assist "${MasterName}"
   } else /if (${TargetName.Equal[me]}) {
      /call Target "pc ${MasterName}"
   } else /if (${TargetName.Equal[yourself]}) {
      /call Target myself
   } else /if (${TargetName.Equal[${Me.CleanName}]}) {
      /call Target myself
   } else {
      /call Target "${TargetName}"
   }
/return

Sub Target(string sTargetName)
   /squelch /target clear
   /target ${sTargetName} radius ${MaxTargetRange}
   /delay 3s ${Target.ID}
   /if (!${Target.ID}) /echo Unable to locate target ${sTargetName} .
/return

Sub ListDelbyArg(string sList,int sArg,string sDiv)
   /if (!${Defined[sDiv]}) /varset sDiv |
   /declare sright int local
   /declare sleft int local
   /declare splaceholder string local
   /varset ${sList} ${sDiv}${${sList}}${sDiv}${sDiv}
   /varset splaceholder ${String[${${sList}}].Arg[${sArg},${sDiv}]}
   /varcalc sleft  ${${sList}.Find[${sDiv}${splaceholder}${sDiv}]}
   /varcalc sright ${sleft}+${String[${splaceholder}${sDiv}].Length}
   /varset ${sList} ${${sList}.Left[${sleft}]}${${sList}.Right[-${sright}]}
   /varset ${sList} ${${sList}.Left[-2].Right[-1]}
   /if (Debug-Core) /echo List ${${sList}} deleted arg ${sArg}
/return

Sub ListReplacebyArg(string sList,string sElement,string sArg,string sDiv)
   /if (!${Defined[sDiv]}) /varset sDiv |
   /varset ${sList} ${sDiv}${${sList}}${sDiv}${sDiv}
   /declare sright int local
   /declare sleft int local
   /declare splaceholder string local
   /varset splaceholder ${String[${${sList}}].Arg[${sArg},${sDiv}]}
   /varcalc sleft  ${${sList}.Find[${sDiv}${splaceholder}${sDiv}]}
   /varcalc sright ${sleft}+${String[${splaceholder}${sDiv}].Length}
   /varset ${sList} ${${sList}.Left[${sleft}]}${sElement}${sDiv}${${sList}.Right[-${sright}]}
   /varset ${sList} ${${sList}.Left[-2].Right[-1]}
   /if (Debug-Core) /echo List ${${sList}} sElement ${sElement} repladed arg ${sArg}
/return

Sub StringReplaceAll(string sList,string oldElement,string newElement)
   /declare GenFor int local
   /declare sright int local
   /declare sleft int local
   /for GenFor 1 to ${${sList}.Length}
      /if (${${sList}.Find[${oldElement}]}) {
         /varset ${sList} |${${sList}}||
         /varcalc sleft  ${${sList}.Find[${oldElement}]}-1
         /varcalc sright ${sleft}+${String[${oldElement}].Length}
         /varset ${sList} ${${sList}.Left[${sleft}]}${newElement}${${sList}.Right[-${sright}]}
         /varset ${sList} ${${sList}.Left[-2].Right[-1]}
      } else {
         /if (Debug-Core) /echo List ${${sList}} oldElement ${oldElement} replaced newElement ${newElement}
         /return
      }
   /next GenFor
   /echo Error in StringReplaceAll
/return

Sub ListDelbyName(string sList,string sName,string sDiv)
   /if (Debug-Core) /echo List ${${sList}}  TO Delete: ${sName}
   /if (!${Defined[sDiv]}) /varset sDiv |
   /varset ${sList} ${sDiv}${${sList}}${sDiv}${sDiv}
   /declare sright int local
   /declare sleft int local
   /varcalc sleft  ${String[${sDiv}${${sList}}${sDiv}].Find[${sDiv}${sName}${sDiv}]}-1
   /varcalc sright ${sleft}+${String[${sName}${sDiv}].Length}
   /varset ${sList} ${${sList}.Left[${sleft}]}${${sList}.Right[-${sright}]}
   /varset ${sList} ${${sList}.Left[-2].Right[-1]}
   /if (Debug-Core) /echo List ${${sList}}  Deleted: ${sName}
/return

Sub ListAppendElement(string sList,string sElement,string sDiv)
   /if (!${Defined[sDiv]}) /varset sDiv |
   /if (${${sList}.Length}) {
      /varset ${sList} ${${sList}}${sDiv}${sElement}
   } else {
      /varset ${sList} ${sElement}
   }
   /if (Debug-Core) /echo List ${${sList}}  Added: ${sElement}
/return


Sub ListPrependElement(string sList,string sElement,string sDiv)
   /if (!${Defined[sDiv]}) /varset sDiv |
   /if (${${sList}.Length}) {
      /varset ${sList} ${sElement}${sDiv}${${sList}}
   } else {
      /varset ${sList} ${sElement}
   }
   /if (Debug-Core) /echo List ${${sList}}  Added: ${sElement}
/return

Sub ListFindStringArg(string sList,string sString,string sDiv)
   /if (!${Defined[sDiv]}) /varset sDiv |
   /declare sReturn int local
   /varcalc sReturn ${${sList}.Left[${${sList}.Find[${sString}]}].Count[${sDiv}]}+1
   /if (Debug-Core) /echo List ${${sList}}  Arg: ${sReturn}
/return ${sReturn}


|||||||||||| Events

Sub Event_Appear
   /call ChatOut 3 ${MasterName} "I'm no longer invis."
/return

Sub Event_Appearing
   /call ChatOut 3 ${MasterName} "I'm starting to appear."
/return

Sub Event_Chat(string ChatType,string ChatSender,string ChatText)
   /if (!${ChatType.Equal[GROUP]} && !${ChatType.Equal[${ListenChan}]}&& !${ChatType.Equal[TELL]}) {
      /return
   }
   /if (${ChatType.Equal[GROUP]} && !${ListenGroup}) /return
   /if (${ChatType.Equal[${ListenChan}]} && !${ListenChat}) /return
   /if (${ChatType.Equal[${ListenChan}]} || ${ChatType.Equal[GROUP]}) {
      /if (${CheckName} && ${ChatText.Arg[1].NotEqual[${Me.CleanName}]}) /return
      /if (${CheckName}) {
         /declare NameLength int local ${Me.CleanName.Length}
         /varcalc NameLength ${NameLength}+1
         /varset ChatText ${ChatText.Right[-${NameLength}]}
      } else {
         /if (${String[|${IgnGroupList}|].Find[|${ChatText.Arg[1]}|]}) /return
      }
   }
   /if (${MasterList.Find[|${ChatSender}|]}) {
      /varset MasterName ${ChatSender}
      /call ExecCommand "${ChatText}"
      /return
   }
   /if (${Relaytells} && ${ChatType.Equal[TELL]}) /call ChatOut 1 ${MasterName} "${ChatSender} told me: ${ChatText}"
/return

Sub Event_CorpseTooFar
   /call ChatOut 5 ${MasterName} "I'm not close enough to loot ${Target.CleanName}."
   /varset LootTooFar 1
/return

Sub Event_ExpGained
   /call ExecCommand EventExpGained
/return

Sub Event_FollowOff
   /target clear
   /call ChatOut 5 ${MasterName} "Auto follow Off."
/return

Sub Event_ImDead
   /call ExecCommand EventDead
/return

Sub Event_IRC(string IRCText,string IRCSender)
      /if (${MasterList.Find[|${IRCSender}|]}) {
      /declare NameLength int local ${IRCSender.Length}
         /varcalc NameLength ${NameLength}+2
         /varset IRCText ${IRCText.Right[-${NameLength}]}
    /call ExecCommand "${IRCText}"
      /return
   }
/return

Sub Event_LosingLev
   /call ChatOut 3 ${MasterName} "I'm losing Levitate"
/return

Sub Event_SelfEcho(string EchoText)
   /varset MasterName ${Me.CleanName}
   /varset EchoText ${EchoText.Right[-13]}
   /call ExecCommand "${EchoText}"
/return

Sub Event_timer(string TimerName,string OldValue)
   /if (${TimerName.Arg[1,-].Equal[ST]}) {
      /if (Debug-Core) /echo ${Me.Name} Calling subroutine ${TimerName.Right[-3]}
      /vardata SubCallName TimerName.Right[-3]
      /if (${SubCallName.Find[-]}) /call StringReplaceAll SubCallName "-" " "
      /if (Debug-Core) /echo ${Me.Name} Calling subroutine ${SubCallName}
      /call ${SubCallName}
   }
   /if (${TimerName.Equal[SitTimer]}) {
      /if (${Me.Standing}) /sit
   }
   /if (${TimerName.Equal[ChainStunTime]}) {
      /call NextStun
   }
/return

Sub Event_Zoned
   /varset IsAnchored 0
   /keypress FORWARD
   /call ExecCommand EventZoned
/return
Last edited by Vexix on Tue Jun 15, 2004 9:29 am, edited 1 time in total.

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Post by Vexix » Thu Jun 10, 2004 1:32 pm

botcombat.inc

Code: Select all

|botcombat.inc
|Bot combat module.
|Version 13.0.3
|Date:06/15/2004
|
||**
[botcombat]
version=13.0.3
**||

#event ArcheryTooFar "Your target is too far away, get closer"
#event AttackedMiss "#*#YOU, but #*#"
#event Bash "You Bash #*#"
#event DisarmTrap "You have disarmed #*#"
#event Enraged "#*#has become ENRAGED."
#event FoundFloorTrap "You sense a trap in this direction."
#event FoundBoxTrap "You are certain that #*#"
#event GettingHit "#*#YOU for #*#"
#event Hit "You Hit #*#"
#event Offrage "#*#is no longer enraged."
#event Pierce "You pierce #*#"
#event Slash "You slash #*#"

Sub Init-Combat
   /declare cmds-COMBAT string outer Combat:
   |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 COMBAT attack Do-attack
   /call AddCommand COMBAT behind Do-behind
   /call AddCommand COMBAT disc Do-disc
   /call AddCommand COMBAT getbehind Do-getbehind
   /call AddCommand COMBAT hide Do-hide
   /call AddCommand COMBAT noattack Do-noattack
   /call AddCommand COMBAT shield Do-shield
   /call AddCommand COMBAT sneak Do-sneak
   |Declare Variables
   /declare Aggressive bool outer FALSE
   /declare AutoBehind bool outer FALSE
   /declare AutoEngage bool outer FALSE
   /declare DoArchery bool outer FALSE
   /declare DoBackstab bool outer FALSE
   /declare DoBash bool outer FALSE
   /declare DoDisarm bool outer FALSE
   /declare DoEvade bool outer FALSE
   /declare DoFlyingKick bool outer FALSE
   /declare DoFrenzy bool outer FALSE
   /declare DoKick bool outer FALSE
   /declare DoIncite bool outer FALSE
   /declare DoSlam bool outer FALSE
   /declare DoTaunt bool outer FALSE
   /declare DoTraps bool outer FALSE
   /declare EnrageVar bool outer FALSE
   /declare InCiteTimer timer outer
   /declare IsPuller bool outer FALSE
   
   /declare ST-CombatMain timer outer 0

   /call LoadSetting Aggressive Combat BeAggressive 0
   /call LoadSetting AutoBehind Combat AutoBehind 0
   /call LoadSetting AutoEngage Combat AutoEngage 0
   /call LoadSetting DoArchery Combat DoArchery 0
   /call LoadSetting DoBackstab Combat DoBackstab 0
   /call LoadSetting DoBash Combat DoBash 0
   /call LoadSetting DoDisarm Combat DoDisarm 0
   /call LoadSetting DoEvade Combat DoEvade 0
   /call LoadSetting DoFrenzy Combat DoFrenzy 0
   /call LoadSetting DoFlyingKick Combat DoFlyingKick 0
   /call LoadSetting DoIncite Combat DoIncite 0
   /call LoadSetting DoKick Combat DoKick 0
   /call LoadSetting DoSlam Combat DoSlam 0
   /call LoadSetting DoTaunt Combat DoTaunt 0
   /call LoadSetting DoTraps Combat DoTraps 0
/return

Sub CombatMain
   /varset ST-CombatMain 0
   /call Combatcheck
   /if ( !${Combatstatus} && ${DoTraps} ) /call TrapFinder
   /if ( !${DoArchery} && ${Combatstatus} ) /call RangeSub
   /if (${Combatstatus}) /call MeleeAbility
   /if (${Me.Combat} && ${Target.ID} && !${Target.CleanName.Equal[${Me.CleanName}]} && ${AutoEngage}) {
      /varset Combatstatus 1
   }
/return

||||| Do Subs

Sub Do-attack
   /varset Supportstatus 1
   /varset Combatstatus 1
   /if (${Me.Sitting}) /stand
   /call StandardTarget "${CommandParam}"
   /if (${Me.Name.Equal[${Target.CleanName}]}) {
      /varset Combatstatus 0
      /return
   }
   /call ChatOut 5 ${MasterName} "Attacking ${Target.CleanName}."
   /if (!${DoArchery}) /attack on
/return

Sub Do-behind
   /if (!${Target.ID}) {
      /call Assist "${MasterName}"
      }
   :behind
   /if (!${Target.ID}) /return
   /doevents
   /call RangeSub
  | ----- Clockwise Rotate Check -----
   /if (!${Target.ID}) /return
   /if (${Target.Heading.Degrees}>=180 && ${Math.Calc[${Target.Heading.Degrees}-180]}<=${Me.Heading.Degrees} && ${Me.Heading.Degrees}<${Math.Calc[${Target.Heading.Degrees}-22.5]}) /call bsclock
   /if (!${Target.ID}) /return
   /if (${Target.Heading.Degrees}>=180 && ${Me.Heading.Degrees}<=180 && ${Math.Calc[${Me.Heading.Degrees}-22.5]}>${Math.Calc[${Target.Heading.Degrees}-360]}) /call bscounter
   /if (!${Target.ID}) /return
   /if (${Target.Heading.Degrees}<=180 && ${Me.Heading.Degrees}<${Math.Calc[${Target.Heading.Degrees}-22.5]}) /call bsclock
  | ----- Counter Clockwise Rotate Check -----
   /if (!${Target.ID}) /return
   /if (${Me.Heading.Degrees}>=180 && ${Math.Calc[${Me.Heading.Degrees}-180]}<=${Target.Heading.Degrees} && ${Me.Heading.Degrees}>${Math.Calc[${Target.Heading.Degrees}+22.5]}) /call bscounter
   /if (!${Target.ID}) /return
   /if (${Me.Heading.Degrees}>=180 && ${Target.Heading.Degrees}<=180 && ${Math.Calc[${Me.Heading.Degrees}-157.5]}<${Math.Calc[${Target.Heading.Degrees}+180]}) /call bsclock
   /if (!${Target.ID}) /return
   /if (${Me.Heading.Degrees}<=180 && ${Target.Heading.Degrees}<=180 && ${Me.Heading.Degrees}>${Math.Calc[${Target.Heading.Degrees}+25]}) /call bscounter
   /if (!${Target.ID}) /return
   /if (${Math.Abs[${Math.Calc[${Target.Heading.Degrees}-${Me.Heading.Degrees}]}]}>30) /goto :behind
/return

Sub Do-disc
   /if (!${Defined[Param0]}) /return
     /disc ${Param0}
/return

Sub Do-getbehind
   /varset ObstacleCheck 0
   /varset GenLastXLoc ${Me.Y}
   /varset GenLastYLoc ${Me.X}
   /if (!${Target.ID}) {
      /call Assist "${MasterName}"
   }
   /if (${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}<3) /goto :noneed
   /if (!${Target.ID}) /return
   /keypress FORWARD hold
   :gobehindloop
   /if (${Me.State.NotEqual[STAND]}) /stand
   /if (!${Target.ID}) {
      /keypress FORWARD
      /return
   }
   /if (${ObstacleCheck}>=60) {
      /if (${GenLastXLoc}==${Me.Y} && ${GenLastYLoc}==${Me.X}) {
         /keypress FORWARD
         /return
      }
      /varset GenLastXLoc ${Me.Y}
      /varset GenLastYLoc ${Me.X}
      /varset ObstacleCheck 0
   }
   /varcalc ObstacleCheck ${ObstacleCheck}+1
   /doevents
   /face nolook fast loc ${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}
   /if (${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}>1) /goto :gobehindloop
   /keypress FORWARD
   /face fast
:noneed
/keypress FORWARD
/return

Sub Do-hide
   /doability Hide
   /call Delay 2s
   /if (${Me.AbilityReady[Hide]}) {
      /call ChatOut 5 ${MasterName} "I'm not hiding"
   } else {
      /call ChatOut 5 ${MasterName} "I am hiding."
   }
/return

Sub Do-noattack
   /attack off
   /varset Combatstatus 0
   /varset Supportstatus 0
/return

Sub Do-shield
   /if ( !${Defined[Param0]} || ${Param0.Equal[me]}) {
      /shield ${MasterName}
   } else {
      /shield ${CommandParam}
   }
/return

Sub Do-sneak
   /doability Sneak
   /call Delay 2s
   /if (${Me.AbilityReady[Sneak]}) {
      /call ChatOut 5 ${MasterName} "I'm not sneaking atm"
   } else {
      /call ChatOut 5 ${MasterName} "I'm sneaking"
   }
/return

||||| Called Subs

Sub bsclock
   /if (!${Target.ID}) /return
   /if (${Me.Sitting}) {
      /stand
      /delay 3
   }
   /keypress strafe_left hold
   :MoreClock
   /if (${DoBackstab} && ${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}<15) {
      /face fast
      /doability "Backstab"
   }
   /if (!${Target.ID}) {
      /keypress strafe_left
      /return
   }
   /if (${Target.Distance}>20) {
      /keypress strafe_left
      /call RangeSub
      /return
   }
   /if (${Target.Distance}<4) {
      /keypress strafe_left
      /call RangeSub
      /return
   }
   /face fast
   /if (${Target.Heading.Degrees}>=180 && ${Math.Calc[${Target.Heading.Degrees}-180]}<=${Me.Heading.Degrees} && ${Me.Heading.Degrees}<${Math.Calc[${Target.Heading.Degrees}-22.5]}) /goto :MoreClock
   /if (${Target.Heading.Degrees}<=180 && ${Me.Heading.Degrees}<${Math.Calc[${Target.Heading.Degrees}-22.5]}) /goto :MoreClock
   /if (${Target.Heading.Degrees}>=180 && ${Me.Heading.Degrees}<=180 && ${Math.Calc[${Me.Heading.Degrees}-22.5]}>${Math.Calc[${Target.Heading.Degrees}-360]}) /goto :MoreClock
   /keypress strafe_left
   /face fast
/return

Sub bscounter
   /if (!${Target.ID}) /return
   /if (${Me.Sitting}) {
      /stand
      /delay 3
   }
   /keypress strafe_right hold
   :MoreCounter
   /if (${DoBackstab} && ${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}<15) {
      /face fast
      /doability "Backstab"
   }
   /if (!${Target.ID}) {
      /keypress strafe_right
      /return
   }
   /if (${Target.Distance}>20) {
      /keypress strafe_right
      /call RangeSub
      /return
   }
   /if (${Target.Distance}<4) {
      /keypress strafe_right
      /call RangeSub
      /return
   }
   /face fast
   /if (${Me.Heading.Degrees}>=180 && ${Math.Calc[${Me.Heading.Degrees}-180]}<=${Target.Heading.Degrees} && ${Me.Heading.Degrees}>${Math.Calc[${Target.Heading.Degrees}+22.5]}) /goto :MoreCounter
   /if (${Me.Heading.Degrees}<=180 && ${Target.Heading.Degrees}<=180 && ${Me.Heading.Degrees}>${Math.Calc[${Target.Heading.Degrees}+25]}) /goto :MoreCounter
   /if (${Me.Heading.Degrees}>=180 && ${Target.Heading.Degrees}<=180 && ${Math.Calc[${Me.Heading.Degrees}-157.5]}<${Math.Calc[${Target.Heading.Degrees}+180]}) /goto :MoreCounter
   /keypress strafe_right
   /face fast
/return

Sub CheckAggressive(string AggroText)
   /if (${Window[InventoryWindow].Open}) /return
   /call CheckPuller
   /if (!${Aggressive}) /return
   /if (!${AggroText.Find[say]} && !${AggroText.Find[group]} && !${AggroText.Find[out of character]} && !${AggroText.Find[shout]} && !${AggroText.Find[guild]} && ${Target.ID}) {
      /if (${Target.Type.NotEqual[NPC]}) {
         /target clear
         /call Delay 2s
      }
      /if ( !${Me.Combat} && ${Target.Type.Equal[NPC]} && ${Aggressive}) {
         /call ChatOut 5 ${MasterName} "I am being attacked by ${Target.CleanName}."
         /call Delay 2
         /varset Combatstatus 1
         /attack on
      }
   }
/return

Sub CheckPuller
   /declare AggTemp bool local
   /if (!${IsPuller}) /return
   /if (${Math.Distance[${AnchorX},${AnchorY}]}<=${AnchorRadius}) /return
   /declare mobface local
   /varset mobface ${Math.Calc[(${Me.Heading.Degrees}+180)]}
   /varcalc mobface ${mobface}%360
   /if (${Target.Heading.Degrees}<=${Math.Calc[${mobface}+10]} && ${Target.Heading.Degrees}>=${Math.Calc[${mobface}-10]}) {
      /attack off
      /varset Combatstatus 0
      /varset AggTemp ${Aggressive}
      /varset Aggressive 0
      /call MoveToAnchor
      /varset Aggressive ${AggTemp}
    }
/return

|Combatcheck
|Used to check if attack is on and should not be.
|Usage /call Combatcheck.
Sub Combatcheck
   /if (${EnrageVar}) {
      /if (${Target.ID}) {
         /return
      } else {
         /varset EnrageVar 0
         /varset Combatstatus 0
         /attack off
         /return
      }
   }
   /if (${Supportstatus}) {
      /if (!${Target.ID}) {
         /call Delay 5
         /if (!${Target.ID}) {
            /varset Supportstatus 0
         }
      }
   }

   /if (${Combatstatus}) {
      /if (!${Target.ID}) {
         /call Delay 5
         /if (!${Target.ID}) {
            /varset Combatstatus 0
            /varset Supportstatus 0
            /attack off
            /return
         }
      }
      /if (${Me.Casting.ID}) /return
      /if (${EnrageVar}) /return
      /if ( !${DoArchery} && !${Me.Combat} ) /attack on
      /if (${AutoBehind} && ${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}>6) /call Do-behind
   }
/return

|MeleeAbility
|Used to do melee abilities if vars are set to.
|Usage /call MeleeAbility
Sub MeleeAbility
   /if (${Me.Casting.ID} || !${Me.Standing} || !${Target.ID}) /return
   /if (${Me.AltTimerReady}) {
      /if (${DoSlam}) {
         /face fast
         /doability "Slam"
      }
      /if (${DoBash}) {
         /face fast
         /doability "Bash"
      }
      /if (${DoBackstab} && ${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}<15) {
         /face fast
         /doability "Backstab"
      }
      /if (${DoFrenzy}) {
         /face fast
         /doability "Frenzy"
      }
      /if (${DoKick}) {
         /face fast
         /doability "Kick"
      }
   }
   /if (${DoEvade} && ${Me.AbilityReady[Hide]}) {
      /attack off
      /delay 1
      /doability "Hide"
      /attack on
   }
   /if (${DoTaunt} && ${Me.AbilityReady[Taunt]}) {
      /doability "Taunt"
   }
   /if (${DoFlyingKick} && ${Me.AbilityReady[Flying Kick]}) {
      /face fast
      /doability "Flying Kick"
   }
   /if (${DoDisarm} && ${Me.AbilityReady[Disarm]}) {
      /face fast
      /doability "Disarm"
   }
   /if (${DoArchery}) {
      /face fast
      /range
   }
   /if (${DoIncite} && ${InCiteTimer}<=0) {
      /face fast
      /disc incite
      /varset InCiteTimer 30s
   }
/return

||||| Events


Sub Event_ArcheryTooFar
/return

Sub Event_AttackedMiss
   /if (${SitAfterCast}) /varset SitTimer ${DelayBeforeSit}
   /call CheckAggressive "${Param0}"
   /call ExecCommand EventAttacked
/return

Sub Event_Bash
   /call CheckPuller
/return

Sub Event_DisarmTrap
   /call Delay 2s
   /call ChatOut 5 ${MasterName} "Trap disarmed."
/return

Sub Event_Enraged
   /if (${Target.ID}) {
      /if (${Combatstatus}) {
         /varset EnrageVar 1
         /attack off
      }
      /varset EnrageVar 1
   }
/return

Sub Event_FoundBoxTrap
   /if (${Me.AbilityReady[Disarm Traps]}) {
      /call ChatOut 5 ${MasterName} "Trying to disarm a ${Target.CleanName} trap."
      /doability "Disarm Traps"
      /return
   }
/return

Sub Event_FoundFloorTrap
   /if (${Me.AbilityReady[Disarm Traps]}) {
      /call ChatOut 5 ${MasterName} "Trying to disarm a floor trap."
      /doability "Disarm Traps"
      /return
   }
/return

Sub Event_GettingHit
   /if (${SitAfterCast}) /varset SitTimer ${DelayBeforeSit}
   /call CheckAggressive "${Param0}"
   /call ExecCommand EventAttacked
/return

Sub Event_Hit
   /call CheckPuller
/return

Sub Event_Offrage
   /if (${Target.ID}) {
      /if (${Combatstatus}) {
         /varset EnrageVar 0
         /attack

      }
      /varset EnrageVar 0
   }
/return

Sub Event_Pierce
   /call CheckPuller
/return

Sub Event_Slash
   /call CheckPuller
/return

|TrapFinder
|Used to auto sence traps when DoTraps is set to 1
|Usage /call TrapFinder
Sub TrapFinder
   /if (${DoTraps} && ${Me.AbilityReady[Sense Traps]}) /doability "Sense Traps"
   /doevents
/return
Last edited by Vexix on Tue Jun 15, 2004 9:31 am, edited 1 time in total.

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Post by Vexix » Thu Jun 10, 2004 1:34 pm

botspell.inc

Code: Select all



|botspell.inc
|Bot spell module.
|Version 13.0.3
|Date:06/15/2004
|
||**
[botspell]
version=13.0.3
**||
|

#Define Debug-Spell FALSE

#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 BuffRetryDelay string outer
   /declare BuffSelfIconList string outer
   /declare BuffSelfList string outer
   /declare CannAATimer timer outer
   /declare CanniSpell string outer
   /declare CannTimer timer 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 CastTimer timer outer
   /declare CastType string outer
   /declare ChainNuke string outer
   /declare ChainStun string outer
   /declare ChainStunNum int outer
   /declare ChainStunTime timer outer
   /declare CTimer timer outer
   /declare DefaultSpellSet string outer
   /declare DelayBeforeSit string outer 3s
   /declare DoAgain bool outer FALSE
   /declare DoCanni bool outer FALSE
   /declare DoYaulp bool outer FALSE
   /declare EvacSpell string outer
   /declare LastSn string outer NA
   /declare LomMsg string outer
   /declare LomTimer timer outer
   /declare Remem bool outer FALSE
   /declare ReportLom bool outer FALSE
   /declare SitAfterCast bool outer FALSE
   /declare SitTimer timer outer
   /declare SpellFail bool outer FALSE
   /declare SpellGem int outer
   /declare SpellSlot int outer
   /declare StartCast bool outer FALSE
   /declare YaulpSpell string outer
   /declare YaulpTimer timer outer
   /declare ST-SpellMain timer outer 0
   /declare ST-CheckSelfBuffs timer outer 1

   /call LoadSetting BuffSelfList Spell SelfBuffList "Buffs you wish to maintain on yourself separated with |"
   /call LoadSetting BuffRetryDelay Spell BuffRetryDelay 5m
   /call LoadSetting CanniSpell Spell CanniSpell Canniblize
   /call LoadSetting ChainNuke Spell ChainNuke "Your Chain Nuke Spells separated with |."
   /call LoadSetting ChainStun Spell ChainStun "Your Chain Stun Spells separated with |."
   /call LoadSetting DefaultSpellSet Spell DefaultSpellSet Default
   /call LoadSetting DelayBeforeSit Spell DelayBeforeSit 3s
   /call LoadSetting DoCanni Spell DoCanni 0
   /call LoadSetting DoYaulp Spell DoYaulp 0
   /call LoadSetting EvacSpell Spell EvacSpell NONE
   /call LoadSetting LomMsg Spell LomMsg "Warning I'm running low on Mana."
   /call LoadSetting Remem Spell RememSpells 0
   /call LoadSetting ReportLom Spell ReportLom 0
   /call LoadSetting SitAfterCast Spell SitAfterCast 0
   /call LoadSetting SpellGem Spell DefaultSpellGem 8
   /call LoadSetting YaulpSpell Spell YaulpSpell yaulp


   /if (${BuffSelfList.NotEqual[Buffs you wish to maintain on yourself separated with |]}) {
      /declare ArgNum int local 1
      /for ArgNum 1 to ${Math.Calc[${BuffSelfList.Count[|]}+1]}
         /call RefineCast "${BuffSelfList.Arg[${ArgNum},|]}"
         /varset CommandParam ${Macro.Return}
         /if (Debug-Spell) /echo RefineCast Return ${Macro.Return}
         /if (${CommandParam.NotEqual[0]}) {
            /call CheckForBuffIcon ${Macro.Return.Arg[1,;]} "${Macro.Return.Arg[2,;]}"
            /if (Debug-Spell) /echo CheckForBuffIcon Return ${Macro.Return}
            /if (${Macro.Return}) {
               /call ListAppendElement BuffSelfIconList "${CommandParam}" |
            } else {
               /call AddCast "${CommandParam}" "${Me.Name}" b-0
            }
         }
      /next ArgNum
   }
/return

Sub SpellMain
   /varset ST-SpellMain 0
   /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}]}) {
         /call Do-SelfBuff "${CommandParam}"
         /return
      }
   }
   /call AssignCastTarget "${TargetName}"
   /varset TargetName ${Macro.Return}
   /if (${TargetName.Equal[0]}) {
      /call ChatOut 5 ${MasterName} "I don't understand who to cast that buff on."
      /return
   }
   /if (Debug-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}) /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}]}.Equal[${BuffType};${BuffCast};${BuffTarget}]}) {
         /varset Ptr ${BuffPtrList.Arg[${GenFor}]}
         /call ListDelbyArg BuffPtrList ${GenFor} |
         /varset ST-BuffRefresh-${Ptr} 0
         /goto :gBuffPtrFound
      }
   /next GenFor
   :gBuffPtrFound
   /if (Debug-Spell) /echo BuffPtr ${Ptr}
   
   /if (${CastLastResult.Equal[CAST_Successful]}) {
      /if (${Spawn[${BuffTarget}].Name.Equal[${Me.Name}]} || ${BuffTarget.Equal[0]}) {
         /call CheckForBuffIcon ${BuffType} "${BuffName}"
         /if (${Macro.Return}) {
            /if (!${String[|BuffSelfIconList|].Find[|${BuffType};${BuffCast}|]}) {
               /call ListAppendElement BuffSelfIconList "${BuffType};${BuffCast}" |
            }
            /return
         } else {
         |/call ChatOut 8 ${MasterName} "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 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 {
      /varset BuffDuration ${BuffRetryDelay}
   }
   /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 (Debug-Spell) /echo ST-BuffRefresh-${Ptr} ${ST-BuffRefresh-${Ptr}} BuffDuration ${BuffDuration}
   
   /if (!${Defined[Buff-${Ptr}]}) /declare Buff-${Ptr} string outer
   /varset Buff-${Ptr} ${BuffType};${BuffCast};${BuffTarget}
   /call ListAppendElement BuffPtrList ${Ptr} " "
/return

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

Sub Do-SelfBuff
   /if (!${Defined[Param0]}) /return
   /if (${Param0.Equal[off]}) {
      /varset BuffSelfList 
      /return
   }
   /if (Debug-Spell) /echo Do-SelfBuff ${CommandParam}
   /call RefineCast "${CommandParam}"
   /if (${Macro.Return.Equal[0]}) /return
   /varset CommandParam ${Macro.Return}
   /if (!${String[|${BuffSelfList}|].Find[|${CommandParam}|]}) {
      /call ListAppendElement BuffSelfList "${CommandParam}" |
   }
/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 (Debug-Spell) /echo Sub CheckSelfBuffs BuffSelfIconList ${BuffSelfIconList} BuffType ${BuffType} BuffName ${BuffName}
         /call CheckForBuffIcon ${BuffType} "${BuffName}"
         |/if (Debug-Spell) /echo CheckForBuffIcon Return ${Macro.Return}
         /if (!${Macro.Return}) /call AddCast "${BuffType};${BuffName}" ${Me.Name} buff
      /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 ${MasterName} "Buffs I have on myself now:"
   /for GenFor 1 to 15
      /if (${Me.Buff[${GenFor}].ID}) {
         /call ChatOut 1 ${MasterName} "${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 ${MasterName} "Buffs I am timing for myself or others:"
      /for GenFor 1 to ${Math.Calc[${BuffPtrList.Count[ ]}+1]}
         /call ChatOut 1 ${MasterName} "${GenFor}. ${Buff-${GenFor}.Arg[1,;]} ${Buff-${GenFor}.Arg[2,;]} for ${Spawn[${Buff-${GenFor}.Arg[3,;]}]} to be cast in ${Math.Calc[${ST-BuffRefresh-${GenFor}}\600]} minutes ${Math.Calc[${ST-BuffRefresh-${GenFor}}%600]} seconds."
      /next GenFor
   } else {
      /call ChatOut 1 ${MasterName} "I am keeping up no other buffs at the moment."
   }
/return


Sub Do-chainnuke
   /declare NukeNum int local 1
   /call StandardTarget "${CommandParam}"
   :ChainNukeLoop
      /if (${BreakOut}) /return
      /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 ${MasterName} "Moving to you and casting ${EvacSpell}!"
   /varset CommandParam ${MasterName}
   /call Do-moveto ${MasterName}
   /call Delay 2s
   /if (${EvacSpell.NotEqual[None]}) {
      /if (Debug-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 ${MasterName} "fm"
   } else {
     /call ChatOut 2 ${MasterName} "${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 (Debug-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 (!${Target.ID}) {
         /varset sntTarget 0
      } else /if (${Target.Type.Equal[PC]}) {
         /varset sntTarget PC ${Target.CleanName}
      } else {
         /varset sntTarget ${Target.Type} id ${Target.ID}
      }
   } else {
      /call AssignCastTarget "${sntTarget}"
      /varset sntTarget "${Macro.Return}"
   }
   /if (Debug-Spell) /echo Do-snt ${sntCastText} ${sntTarget}
   /call AddCast "${sntCastText}" "${sntTarget}"
   /varset LastSn ${sntCastText}
/return

Sub Do-spellgem
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "I Gem ${SpellGem} when I need to mem new spells."
      /return
   }
   /varset SpellGem ${Param0}
   /call ChatOut 3 ${MasterName} "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 (Debug-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 (Debug-Spell) /echo AddCastText;AddCastTarget ${AddCastText};${AddCastTarget};${AddCastInfo}
   /if (!${CastQueue.Find[${AddCastText};${AddCastTarget}]}) {
      /if (!${Defined[AddCastCategory]} || ${AddCastCategory.NotEqual[heal]}) {
         /call ListAppendElement CastQueue "${AddCastText};${AddCastTarget};${AddCastInfo}" |
      } else {
         /call ListPrependElement CastQueue "${AddCastText};${AddCastTarget};${AddCastInfo}" |
      }
   }
   /if (Debug-Spell) /echo CastQueue ${CastQueue}
/return

Sub CastFromQueue
   /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 ${MasterName} "Unable to assist you to find a target to cast on."
         }
      }
      /varset CastType ${CastQueue.Arg[1,;]}
      /varset CastName ${CastQueue.Arg[2,;]}
      /varset CastTarget ${CastQueue.Arg[3,;]}
      /varset CastInfo ${CastQueue.Arg[1,|].Arg[4,;]}
      /if (Debug-Spell) /echo CastType ${CastType} CastName ${CastName} CastTarget ${CastTarget}
      /varset CastTimer 0
      /varset CastStep 1
      /varset CastOldTargetID 0
   }
   |/if (Debug-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 (Debug-Spell) /echo CastStep = ${CastStep} -- No corresponding goto found.  Returning.
      /varstep CastStep 5
      /return
   }
   | Wait for spell to pop up, stand up, and target correctly.
:gCast-1
   |/if (Debug-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 3 ${MasterName} "Casting ${CastType.Arg[1,-]} ${CastName}."
      /varset CastTarget 0
   } else {
      /if (!${Spawn[${CastTarget}].ID}) {
         /call ChatOut 3 ${MasterName} "I couldn't find the target: ${CastTarget}"
         /varset CastStep 5
         /varset CastLastResult TARGET_NOTEXIST
         /return
      }
      /if (!${NearestSpawn[${CastTarget} radius ${MaxTargetRange}].ID}) {
         /call ChatOut 3 ${MasterName} "Target: ${CastTarget}  is out of range."
         /varset CastStep 5
         /varset CastLastResult TARGET_OUTOFRANGE
         /return
      }
      /if (${Target.ID}!=${NearestSpawn[${CastTarget}].ID}) {
         /varset CastOldTargetID ${Target.ID}
         /target ${CastTarget}
         /delay 2s ${Target.ID}==${NearestSpawn[${CastTarget}].ID}
         /varset CastTimer 5
         /if (${Target.ID}!=${NearestSpawn[${CastTarget}].ID}) {
            /call ChatOut 3 ${MasterName} "Wasn't able to target: ${CastTarget}"
            /varset CastStep 5
            /varset CastLastResult TARGET_CANNOTTARGET
            /return 
         }
      }
      /call ChatOut 3 ${MasterName} "Casting ${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 ${MasterName} "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}) {
         /if (${CastType.Arg[2,-].Length}) { 
            /memspell ${CastType.Arg[2,-]} "${CastName}" 
            /call ChatOut 3 ${MasterName} "Memorizing spell: ${CastName} in slot ${CastType.Arg[2,-]}."
         } else {
            /memspell ${SpellGem} "${CastName}" 
            /call ChatOut 3 ${MasterName} "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 6 ${MasterName} "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[b]}) /call BuffResult ${CastType} "${CastName}" "${CastTarget}" ${CastInfo.Arg[2,-]}
   /if (${CastOldTargetID}) /target id ${CastOldTargetID} radius ${MaxTargetRange}
   /if (Debug-Spell) /echo CastLastResult ${CastLastResult}
   /if (${Remem}) {
      /memspellset ${DefaultSpellSet}
      /call ChatOut 6 ${MasterName} "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 ${MasterName} "Done memorizing original spells."
   /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 ${MasterName} "Unable to /assist you to find a target to cast on."
            /return 0
         }
      }
   } else /if (${ACTarget.Equal[yourself]} || ${ACTarget.Equal[${Me.CleanName}]}) {
      /return ${Me.Name}
   } else /if (${ACTarget.Equal[me]}) {
      /return ${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 (Debug-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 ${MasterName} "${LomMsg}"
         /varset LomTimer 2m
      }
   }
/return

Sub CheckYaulp
   /if (!${Me.Moving} && ${Me.PctMana}<95 && ${YaulpTimer}<=1) {
      /if (Debug-Spell) /echo CheckYaulp "${YaulpSpell}" "${Me.Name}"
      /call AddCast "${YaulpSpell}" ${Me.Name} buff
      /varset YaulpTimer 25s
   }
/return

Sub NextStun
   /if (${BreakOut}) /return
   /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 ${MasterName} "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 ${MasterName} "Cannot find item: ${RCText} "
         /return 0
      }
      /return ${RCType};${FindItem[${RCName}]}
   }
   /if (${RCType.Equal[alt]}) {
      /if (!${AltAbility[${RCName}].ID}) { 
         /call ChatOut 3 ${MasterName} "Do not understand Alt Ability: ${RCText} "
         /return 0
      }
      /return ${RCType};${AltAbility[${RCName}]}
   }
   /if (!${Me.Book[${RCText}]}) {
      /if (Debug-Spell) /echo Name |${RCText}|
      /call ChatOut 3 ${MasterName} "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[${RFTarget}].Type.Equal[PC]}) {
      /varset RFTarget pc ${NearestSpawn[${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 CastStep 5
         /varset CastLastResult CAST_CastNoMana
         /if (${CastTimer}==0) {
            /call ChatOut 5 "${MasterName} I am OOM!"
            /varset CastTimer 100
            /return
         }
      }
      /call ChatOut 5 ${MasterName} "OOM. Medding 13 seconds and trying again. "
      /varset CastStep 0
      /if (!${Me.Standing} && !${Combatstatus}) /sit
      /varset CastTimer 130
   }
/return

Sub Event_CastResist
   /if (${CastStep}) {
      /varset CastStep 5
      /if (${CastLastResult.Equal[CAST_StillCasting]}) {
         /varset CastLastResult CAST_Resisted
         /call ChatOut 3 ${MasterName} "${Target.CleanName} Resisted."
      }
   }
/return

Sub Event_CastTooFar
   /if (${CastStep}) {
      /call ChatOut 3 ${MasterName} "Too far away. "
      /varset CastStep 5
      /varset CastLastResult CAST_CastTooFar
   }
/return

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

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

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

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

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

Sub Event_NoLOS
   /if (${CastStep}) {
      /call ChatOut 10 ${MasterName} "I can't see my target. "
      /varset CastStep 5
      /varset CastLastResult CAST_NoLOS
   }
/return

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

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

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

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

Sub Event_RootOff
   /call ChatOut 5 ${MasterName} "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 ${MasterName} "I'm STUNNED. Waiting a second to try again."
      /varset CastStep 0
      /varset CastTimer 1s
      /varset CastLastResult CAST_Stunned
   }
/return
Last edited by Vexix on Tue Jun 15, 2004 9:32 am, edited 2 times in total.

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Post by Vexix » Thu Jun 10, 2004 1:35 pm

bothealer.inc

Code: Select all

|bothealer.inc
|Bot healer module.
|Version 13.0.3
|Date:06/15/2004
|
||**
[bothealer]
version=13.0.3
**||

Sub Init-Healer
   /declare cmds-HEALER string outer Healer:

   |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 HEALER heal Do-heal
   /call AddCommand HEALER resetwatch Do-resetwatch
   /call AddCommand HEALER setcasterheal Do-setcasterheal
   /call AddCommand HEALER setcasterhealpct Do-setcasterhealpct
   /call AddCommand HEALER setdefaultheal Do-setdefaultheal
   /call AddCommand HEALER setpatchheal Do-setpatchheal
   /call AddCommand HEALER setpetheal Do-setpetheal
   /call AddCommand HEALER setpethealpct Do-setpethealpct
   /call AddCommand HEALER settankheal Do-settankheal
   /call AddCommand HEALER settankhealpct Do-settankhealpct
   /call AddCommand HEALER watchtarget Do-watchtarget

   |declare Vars
   /declare CasterList string outer
   /declare CasterPctHeal int outer 81
   /declare CasterSpell string outer
   /declare CastMsgTimer1 timer outer
   /declare CastMsgTimer2 timer outer
   /declare DefaultHealSpell string outer
   /declare HealCasterMsg string outer
   /declare HealPetMsg string outer
   /declare HealPets bool outer FALSE
   /declare HealTankMsg string outer
   /declare HealTargets[21] int outer 0
   /declare IsHealer bool outer FALSE
   /declare IsPally bool outer FALSE
   /declare LowHealthCheck int outer 0
   /declare PalGrpPct int outer 81
   /declare PalHealGrpMsg string outer
   /declare PalHealMsg string outer
   /declare PalHealPct int outer 81
   /declare PallyGroupSpell string outer
   /declare PatchHealer bool outer TRUE
   /declare PallyHealSpell string outer
   /declare PatchHealMsg string outer
   /declare PatchSpell string outer
   /declare PetPctHeal int outer 81
   /declare PetSpell string outer
   /declare ReportAutoHeal bool outer TRUE
   /declare TankList string outer
   /declare TankPctHeal int outer 51
   /declare TankSpell string outer
   /declare WatchTargetCount int outer 0
   /declare WatchTargetIDs[15] int outer 0
   /declare WatchTargets[15] string outer
   /declare WatchWaitCount int outer 0

   /declare ST-HealerMain timer outer 0

   /call LoadSetting CasterSpell Healer CasterSpell "Name of heal spell autoheal uses on Non Tanks"
   /call LoadSetting CasterPctHeal Healer CasterPctHeal 70
   /call LoadSetting DefaultHealSpell Healer DefaultHealSpell "Name of Default Heal Spell"
   /call LoadSetting HealCasterMsg Healer HealCasterMsg "Healing %t"
   /call LoadSetting HealPetMsg Healer HealPetMsg "Healing %t"
   /call LoadSetting HealPets Healer HealPets 0
   /call LoadSetting HealTankMsg Healer HealTankMsg "Big Heal on %t"
   /call LoadSetting IsHealer Healer IsHealer 0
   /call LoadSetting IsPally Healer IsPally 0
   /call LoadSetting PalGrpPct Healer PalGrpPct 81
   /call LoadSetting PalHealPct Healer PalHealPct 81
   /call LoadSetting PallyGroupSpell Healer PallyGroupSpell "Name of Pally Group Heal Spell"
   /call LoadSetting PallyHealSpell Healer PallyHealSpell "Name of Pally Heal Spell"
   /call LoadSetting PalHealMsg Healer PalHealMsg "Healing %t"
   /call LoadSetting PatchHealer Healer PatchHealer 1
   /call LoadSetting PatchHealMsg Healer PatchHealMsg "Patch Healing %t"
   /call LoadSetting PatchSpell Healer PatchSpell "Name of Patch Heal Spell"
   /call LoadSetting PetPctHeal Healer PetPctHeal 51
   /call LoadSetting PetSpell Healer PetSpell "Name of Pet Heal Spell"
   /call LoadSetting ReportAutoHeal Healer ReportAutoHeal 1
   /call LoadSetting TankSpell Healer TankSpell "Name of heal spell autoheal uses on Tanks"
   /call LoadSetting TankPctHeal Healer TankPctHeal 51

   /varset TankList ${Ini[${IniFile},Healer,TankList,NotFound]}
   /varset CasterList ${Ini[${IniFile},Healer,CasterList,NotFound]}
   /if (${TankList.Equal[NotFound]} && ${CasterList.Equal[NotFound]}) {
      /ini ${IniFile} Healer TankList "Warrior|Shadow Knight|Paladin|Monk|Beastlord|Ranger|Shaman|Berserker"
      /ini ${IniFile} Healer CasterList "Necromancer|Wizard|Enchanter|Magician|Rogue|Druid|Cleric|Bard"
      /varset TankList Warrior|Shadow Knight|Paladin|Monk|Beastlord|Ranger|Shaman|Berserker
      /varset CasterList Necromancer|Wizard|Enchanter|Magician|Rogue|Druid|Cleric|Bard
   }
/return

Sub HealerMain
   /varset ST-HealerMain 0
   /call CheckGrpHealth
   /call PalGrpHealChk
   /call PalHealChk
/return

||||| Do Subs
Sub Do-setcasterheal
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "I heal non tanks with ${CasterSpell}."
      /return
   }
   /varset CasterSpell ${CommandParam}
   /call ChatOut 3 ${MasterName} "I'll start using ${CasterSpell} on non tanks."
/return

Sub Do-setcasterhealpct
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "I heal non tanks at ${CasterPctHeal} %."
      /return
   }
   /varset CasterPctHeal ${Param0}
   /call ChatOut 3 ${MasterName} "I heal non tanks at ${CasterPctHeal} %."
/return

Sub Do-setdefaultheal
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "I usualy heal with ${DefaultHealSpell}."
      /return
   }
   /varset DefaultHealSpell ${CommandParam}
   /call ChatOut 3 ${MasterName} "I'll start using ${DefaultHealSpell}."
/return

Sub Do-heal
   /declare HealTarget string local ${Macro.Return}
   /if (!${NearestSpawn[${CommandParam}].ID} || ${Target.Type.Equal[NPC]} || ${CommandParam.Equal[me]}) {
      /varset HealTarget pc ${MasterName}
   } else /if (${CommandParam.Equal[yourself]}) {
      /varset HealTarget ${Me.Name}
   } else {
      /varset HealTarget id ${Target.ID}
   }
   /call ChatOut 3 ${MasterName} "Casting ${DefaultHealSpell} on ${NearestSpawn[${HealTarget}]}."
   /call AddCast "${DefaultHealSpell}" "${HealTarget}" heal
/return

Sub Do-setpatchheal
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "I use ${PatchSpell} for patch heals."
      /return
   }
   /varset PatchSpell ${CommandParam}
   /call ChatOut 3 ${MasterName} "I'll use ${PatchSpell} for patch heals now."
/return

Sub Do-setpetheal
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "My pet heal is ${PetSpell}."
      /return
   }
   /varset PetSpell ${CommandParam}
   /call ChatOut 3 ${MasterName} "I'll use ${PetSpell} to heal pets."
/return

Sub Do-setpethealpct
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "I heal pets at ${PetPctHeal} %."
      /return
   }
   /varset PetPctHeal ${Param0}
   /call ChatOut 3 ${MasterName} "I heal pets at ${PetPctHeal} %."
/return

Sub Do-settankheal
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "My tank heal is ${TankSpell}"
      /return
   }
   /varset TankSpell ${CommandParam}
   /call ChatOut 3 ${MasterName} "I'll use ${TankSpell} to heal tanks."
/return

Sub Do-settankhealpct
   /if (!${Defined[Param0]}) {
      /call ChatOut 3 ${MasterName} "I heal tanks at ${TankPctHeal} %."
      /return
   }
   /varset TankPctHeal ${Param0}
   /call ChatOut 3 ${MasterName} "I heal tanks at ${TankPctHeal} %."
/return

Sub Do-watchtarget
   /if (${String[${Param0}].Equal[off]}) {
      /varset WatchTargetCount 0
      /return
   }
   /target clear
   /call delay 5
   /call StandardTarget "${CommandParam}"
   /call Delay 25
   /if (${Target.ID}) {
      /varcalc WatchTargetCount ${WatchTargetCount}+1
      /varset WatchTargets[${WatchTargetCount}] ${Target.CleanName}
      /varset WatchTargetIDs[${WatchTargetCount}] ${Target.ID}
      /call ChatOut 3 ${MasterName} "Now watching the health of ${Target.CleanName}."
   } else {
      /call ChatOut 3 ${MasterName} "Who did you want me to watch?"
   }
/return

||||| Called Subs

Sub CastHeal(int TarID,string HealSpell,string castMsg)
   /if (${Me.Moving}) /return
   /if (!${CastMsgTimer1}) {
      |/if (${ReportAutoHeal}) /g ${castMsg}
      /varset CastMsgTimer1 50
   }
   /call AddCast "${HealSpell}" "id ${TarID}" "heal"
   /if (${SitAfterCast}) /varset SitTimer ${DelayBeforeSit}
/return

Sub CheckGrpHealth
   /declare HealCount int local 0
   /declare BadIDs int local 0
   /declare SaveCombatStat int local 0
   /declare SaveCombatID int local 0
   /declare QuickID int local 0
   /declare tempvar int local 0
   /if (!${IsHealer}) /return
   /if (${IsPally}) /return
   /if (${Combatstatus}) {
      /varset SaveCombatStat 1
      /varset SaveCombatID ${Target.ID}
   }
   /varset HealCount ${Group}
   /for tempvar 1 to ${Group}
      /varset HealTargets[${tempvar}] ${Group[${tempvar}].ID}
   /next tempvar
   /varcalc HealCount ${HealCount}+1
   /varset HealTargets[${HealCount}] ${Me.ID}
   /if (${WatchWaitCount}>10 && ${WatchTargetCount}>0) {
      /for tempvar 1 to ${WatchTargetCount}
         /varcalc HealCount ${HealCount}+1
         /varset HealTargets[${HealCount}] ${WatchTargetIDs[${tempvar}]}
      /next tempvar
      /varset WatchWaitCount 0
   }
   /varcalc WatchWaitCount ${WatchWaitCount}+1
   /for tempvar 1 to ${HealCount}
      /if (${tempvar}>${Group} && ${Target.ID}!=${HealTargets[${tempvar}]} && ${HealTargets[${tempvar}]}!=${Me.ID}) {
         /if (${Combatstatus}==1) /attack off
         /target id ${HealTargets[${tempvar}]}
         /delay 5
         /if (${Target.ID}!=${HealTargets[${tempvar}]}) {
            /varcalc BadIDs ${BadIDs}+1
         }
      }
      /varset QuickID ${HealTargets[${tempvar}]}
      /if (${Spawn[${QuickID}].PctHPs}<${TankPctHeal} && ${Spawn[${QuickID}].State.NotEqual[DEAD]}) {
         /if (${TankList.Find[${Spawn[${QuickID}].Class}]}) {
            /if (${Spawn[${QuickID}].PctHPs}<${Math.Calc[${TankPctHeal}/2]} && ${PatchHealer}) /call PatchHeal ${QuickID}
            /if (${Me.Combat}) /attack off
            /call CastHeal ${QuickID} "${TankSpell}" "${HealTankMsg}"
         }
      }
      /if (${BreakOut}) /return
      /if ((${Spawn[${QuickID}].PctHPs}<${CasterPctHeal})&&(${Spawn[${QuickID}].State.NotEqual[DEAD]})) {
         /if (${CasterList.Find[${Spawn[${QuickID}].Class}]}) {
            /if ((${Spawn[${QuickID}].PctHPs}<${Math.Calc[${CasterPctHeal}/2]})&&(${PatchHealer})) /call PatchHeal ${QuickID}
            /if (${Me.Combat}) /attack off
            /call CastHeal ${QuickID} "${CasterSpell}" "${HealCasterMsg}"
         }
      }
      /if (${BreakOut}) /return
      /if (${HealPets} && ${Spawn[${QuickID}].Class.PetClass} && ${Spawn[${QuickID}].Pet.ID}) {
         /if (${Spawn[${QuickID}].Pet.PctHPs}<${PetPctHeal}) {
            /if (${Me.Combat}) /attack off
            /call CastHeal ${Spawn[${QuickID}].Pet.ID} "${PetSpell}" "${HealPetMsg}"
         }
      }
   /next tempvar
   /if (${SaveCombatStat}) {
      /if (${Target.ID}!=${SaveCombatID}) /target ID ${SaveCombatID}
      /if (${Target.ID} && ${Target.Type.Equal[NPC]}) {
         /if (${Me.Sitting}) /stand
         /attack on
         /varset Combatstatus 1
      }
   }
   /if (${BadIDs}>0) /call ResetWatchTargets
/return

Sub PalHealChk
    /declare tempvar int local 0
   /if (!${IsPally}) /return
   /if (!${IsHealer}) /return
   /for tempvar 0 to ${Group}
      /if ((${Group[${tempvar}].PctHPs}<${PalHealPct})&&(${Group[${tempvar}].State.NotEqual[DEAD]})) /call PallyHeal ${Group[${tempvar}].ID}
   /next tempvar
/return

Sub PalGroupheal
   /if (${Me.Sitting}) /stand
   /if (${ReportAutoHeal}) /g ${PalHealGrpMsg}
   /call AddCast "${PallyGroupSpell}" 0 heal
/return

Sub PalGrpHealChk
   /declare tempvar int local 1
   /if (!${IsPally}) /return
   /if (!${IsHealer}) /return
   /if (${Me.PctHPs}>${PalHealPct}) {
      /varset LowHealthCheck 0
   } else {
      /varset LowHealthCheck 1
   }
   /for tempvar 1 to ${Group}
      /if ((${Group[${tempvar}].PctHPs}<${PalHealPct})&&(${Group[${tempvar}].State.NotEqual[DEAD]})) /varcalc LowHealthCheck ${LowHealthCheck}+1
      /if (${LowHealthCheck}>=3) {
         /call PalGroupheal
         /return
      }
   /next tempvar
/return

Sub PallyHeal(int TarID)
   /if (${Combatstatus}) /return
   /if (${TarID}==${Me.ID}) /target myself
   /if (${TarID}!=${Me.ID}) /target id ${TarID}
   /if (${Me.Sitting}) /stand
   /if (!${Combatstatus}) /g ${PalHealMsg}
   /call AddCast "${PallyHealSpell}" 0 heal
/return

Sub Patchheal(int TarID)
   /if (${Me.Moving}) /return
   /if (${TarID}==${Me.ID})  /target myself
   /if (${TarID}!=${Me.ID} && ${Target.ID}!=${TarID}) /target id ${TarID}
   /call Delay 1
   /if (${Me.Sitting}) /stand
   /if (${CastMsgTimer1}<=0) {
      /if (${ReportAutoHeal}) /g ${PatchHealMsg}
      /varset CastMsgTimer1 50
   }
   /if (${Me.Gem[${PatchSpell}]}) /cast "${PatchSpell}"
   /if (${SitAfterCast}) /varset SitTimer ${DelayBeforeSit}
/return

Sub ResetWatchTargets
   /declare counter int local
   /for counter 1 to ${WatchTargetCount}
      /target PC ${WatchTargets[${counter}]}
      /call Delay 25
      /if (${Target.CleanName.Equal[${WatchTargets[${counter}]}]}) {
            /varset WatchTargetIDs[${counter}] ${Target.ID}
      } else {
            /call ChatOut 5 ${MasterName} "I failed to find ${WatchTargets[${counter}]} in the zone."
      }
   /next counter
/return
Last edited by Vexix on Tue Jun 15, 2004 9:33 am, edited 1 time in total.

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Post by Vexix » Thu Jun 10, 2004 1:36 pm

botshortcut.inc

Code: Select all

|botshortcut.inc
|Module for linking Custom Commands to Character spells and items
|Includes Variable Toggling function as well
|Version 13.0.3
|Date:06/15/2004
|
||**
[shortcuts]
version=13.0.3
**||

Sub Init-Toggles
   /declare cmds-TOGGLES string outer Toggles:
   |For each Variable that has a TRUE/FALSE State
   |Each Command can be toggled by 1/0, TRUE/FALSE, On/Off, Yes/No
   |/call AddToggle Command PhraseOff PhraseOn Variable Type
   |Command to force Toggle - End User change change to suit prefferences
   |PhraseOff returned by the bot when value is FALSE
   |PhraseOn returned by the bot when value is TRUE
   |Variable to be changed by the command
   | Type TRUE Command will return Variable State when no Param Present
   | Type FALSE Command Will Toggle Variable State when no Param Present
   /call AddToggle aftercastsit "I will no longer sit after casting." "I will now sit after casting." SitAfterCast FALSE
   /call AddToggle aona "I will Not Attack when Assisting." "I will Attack when Assisting." AttackOnAssist TRUE
   /call AddToggle archery "Archery is set to off." "Archery is set to on." DoArchery TRUE
   /call AddToggle autobehind "I won't position myself behind the mob." "I will position myself behind the mob." AutoBehind FALSE
   /call AddToggle autoengage "I will not engage when attack is on." "I will engage when attack is on." AutoEngage TRUE
   /call AddToggle autoheal "Let me know when people need heals." "I'll watch for heals." IsHealer TRUE
   /call AddToggle autohealpets "I will not heal the pets." "I will heal the pets." HealPets TRUE
   /call AddToggle bash "Auto Bash is now off." "Auto Bash is now on." DoBash FALSE
   /call AddToggle backstab "Auto Backstab is now off." "Auto Backstab is now on." DoBackstab FALSE
   /call AddToggle beagg "Aggressive is set to off. " "Aggressive is set to on." Aggressive TRUE
   /call AddToggle bona "I won't move behind on assist." "I will move behind on assist." BehindOnAssist TRUE
   /call AddToggle canni "I won't eat myself for mana." "I will eat myself for mana." DoCanni TRUE
   /call AddToggle Checkname "I will respond to all commands." "I will only respond to commands that are addressed to me." CheckName TRUE
   /call AddToggle disarm "Auto Disarm is now off." "Auto Disarm is now on." DoDisarm FALSE
   /call AddToggle evade "Auto Evade is now off." "Auto Evade is now on." DoEvade FALSE
   /call AddToggle flyingkick "Auto FlyingKick is now off." "Auto FlyingKick is now on." DoFlyingKick FALSE
   /call AddToggle frenzy "Auto Frenzy is now off." "Auto Frenzy is now on." DoFrenzy FALSE
   /call AddToggle incite "I won't use the incite discipline when in combat." "I will use the incite discipline when in combat." DoIncite FALSE
   /call AddToggle kick "Auto Kick is now off." "Auto Kick is now on." DoKick FALSE
   /call AddToggle ListenChat "I will ignore Chat" "I will listen in Chat." ListenChat TRUE
   /call AddToggle listengroup "I will ignore Group Chat." "I will listen in Group Chat." ListenGroup TRUE
   /call AddToggle patchheal "I'm not a patch Healer." "I'm a patch Healer." PatchHealer TRUE
   /call AddToggle petona "I won't send pet in on assist." "I will send pet in on assist." PetOnAssist TRUE
   /call AddToggle puller "I'm not the puller." "I'm the puller." IsPuller TRUE
   /call AddToggle Remem "I won't remem my spellset after casting." "I will remem my spellset after casting." Remem TRUE
   /call AddToggle reportlom "I won't tell you when I'm low on Mana." "I'll let you know when I'm low on Mana." reportlom FALSE
   /call AddToggle slam "Auto Slam is now off." "Auto Slam is now on." DoSlam FALSE
   /call AddToggle taunt "Auto Taunt is now off." "Auto Taunt is now on." DoTaunt FALSE
   /call AddToggle traps "I will not detect for traps." "I will detect for traps." DoTraps FALSE
   /call AddToggle yaulp "I won't Yaulp for mana." "I will Yaulp for mana." DoYaulp TRUE

   /call AddCommand CORE shortcuts Do-shortcutsinfo

/return

Sub Init-Shortcuts
   /declare cmds-SHORTCUTS string outer Shortcuts:
   /declare Shortcutlist string local
   /declare ArgNum int local 0
   /declare Short string local 0
   /declare ParamS string outer


   /varset ArgNum 1
   /varset Shortcutlist ${Ini[${IniFile},Shortcuts,-1,Undefined]}
   /if (!${Shortcutlist.Find[Undefined]}) {
      :shortcuts
      /if (${Shortcutlist.Arg[${ArgNum},|].Length}) {
         /varset Short ${Shortcutlist.Arg[${ArgNum},|].Lower}
         |add Command
         /varset cmds-SHORTCUTS ${cmds-SHORTCUTS} ${Short}
         /if (!${Defined[ShortCuts-${Short}-Text]}) /declare ShortCuts-${Short}-Text string outer
         /varset ShortCuts-${Short}-Text ${Ini[${IniFile},Shortcuts,${Short},NA]}
         /varcalc ArgNum ${ArgNum}+1
         /goto :shortcuts
      }
   } else {
      /ini ${IniFile} Shortcuts default "/echo Put yer shortcuts in your .ini file!"
   }
/return

||||| Do Subs
Sub Do-shortcutsinfo
   /if (${Defined[Param0]}) {
      /if (${String[ ${cmds-SHORTCUTS.Lower} ].Find[ ${Param0.Lower} ]}) {
         /call ChatOut 3 ${MasterName} "Shortcut ${Param0} does: ${ShortCuts-${Param0}-Text}"
      } else {
         /call ChatOut 3 ${MasterName} "I don't know the shortcut ${Param0}."
      }
   } else {
      /call ChatOut 3 ${MasterName} "${cmds-SHORTCUTS}"
      /call ChatOut 3 ${MasterName} "Type: shortcuts name_of_shortcut for more information on any particular shortcut.
   }
/return


||||| Called Subs

Sub AddToggle(string commandText,string OffText,string OnText,string VarName,bool ToggleType)
   /varcalc TopToggle ${TopToggle}+1
   /varset Toggles[1,${TopToggle}] ${commandText}
   /varset Toggles[2,${TopToggle}] ${OffText}
   /varset Toggles[3,${TopToggle}] ${OnText}
   /varset Toggles[4,${TopToggle}] ${VarName}
   /varset Toggles[5,${TopToggle}] ${ToggleType}
   /varset cmds-TOGGLES ${cmds-TOGGLES} ${commandText}
/return

Sub SetToggle(int ToggleNum,string newValue)
   /if (!${Defined[newValue]} && ${Toggles[5,${ToggleNum}]}) {
      /if (${${Toggles[4,${ToggleNum}]}}) {
         /call ChatOut 9 ${MasterName} "${Toggles[3,${ToggleNum}]}"
      } else {
         /Call ChatOut 9 ${MasterName} "${Toggles[2,${ToggleNum}]}"
      }
      /return
   }
   /if ( !${Defined[newValue]} && !${Toggles[5,${ToggleNum}]}) {
      /declare newValue Local
      /if (${${Toggles[4,${ToggleNum}]}}) {
         /varset newValue 0
      } else {
         /varset newValue 1
      }
   }
   /if (${newValue.Equal[True]} || ${newValue.Equal[On]} || ${newValue.Equal[1]} || ${newValue.Equal[yes]}) {
      /varset ${Toggles[4,${ToggleNum}]} 1
   } else {
      /varset ${Toggles[4,${ToggleNum}]} 0
   }

   /if (${${Toggles[4,${ToggleNum}]}}) {
      /call ChatOut 9 ${MasterName} "${Toggles[3,${ToggleNum}]}"
   } else {
      /Call ChatOut 9 ${MasterName} "${Toggles[2,${ToggleNum}]}"
   }
/return

Sub ShortCut(string ShortCutCommand)
   /declare Name string local
   /declare ParseText string local
   /declare si int local

   /varset Name ${ShortCutCommand.Arg[1].Lower}
   /varset ParseText ${ShortCuts-${Name}-Text}
   /if (${ParseText.Find[NameS]} && ${ShortCutCommand.Arg[2].Length}) {
      /vardata CommandParam ParseText
      /call StringReplaceAll CommandParam NameS ${ShortCutCommand.Arg[2]}
      /vardata ParseText CommandParam
   }
   /for si 1 to ${Math.Calc[${ParseText.Count[|]}+1]}
      /call ExecCommand "${ParseText.Arg[${si},|]}"
   /next si
/return
Last edited by Vexix on Tue Jun 15, 2004 9:34 am, edited 1 time in total.

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Post by Vexix » Thu Jun 10, 2004 1:38 pm

personal.inc

Code: Select all


|personal.inc 
|Personal commands module example. 
|Version 13.0.3
|Date:06/15/2004
| 
||** 
[personal] 
version=13.0.3
**|| 
|Define your personal Events Here 
|#Event EExample "Explain it to me again" 

Sub Init-Personal 
   /declare cmds-PERSONAL string outer Personal: 

  /declare ST-PersonalMain timer outer 0
    
   |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 
   |Called Sub - Routine to execute in response to Command Phrase 
   |/call AddCommand PERSONAL command subroutine 
   |Command Phrase to trigger bot - End User can change to suit prefferences 
   |For each Variable that has a TRUE/FALSE State 
   |Each Command can be toggled by 1/0, TRUE/FALSE, On/Off, Yes/No 
   |/call AddToggle Command "PhraseOff" "PhraseOn" Variable Type 
   |Command to force Toggle - End User change change to suit prefferences 
   |PhraseOff returned by the bot when value is FALSE 
   |PhraseOn returned by the bot when value is TRUE 
   |Variable to be changed by the command 
   | Type TRUE Command will return Variable State when no Param Present 
   | Type FALSE Command Will Toggle Variable State when no Param Present 
   |/call AddToggle PerToggle "I will not do it anymore" "I will do it now" MyToggle TRUE 
   |Declare you variables here and Set their Defaults 
   |/declare PersonalValue string outer 
   |/Declare AnotherValue int outer default 
   |INI Values 
   |/call LoadSetting PersonalVar Personal Personalkey Default 
/return 

|Things that you want to happen every loop through the macro go in this sub. 
Sub PersonalMain 
   /varset ST-PersonalMain 0

   |/Call MyExampleSub 
   |/if (${AnotherValue}) /call ConditionalExample 
    
/return 

|Add your own Event and and other subroutines here 

|Sub Event_EExample 
|   Some Event Code 
|/return 

|Sub MyExampleSub 
| Some Code activate every loop of the code 
|/return 

|Sub CommandFunction 
|   Some Code that will run every time CommandName is activated 
|/return 

|sub ConditionalExample 
|   Some Code that will run everytime "AnotherValue" is true 
|/return 
Last edited by Vexix on Tue Jun 15, 2004 9:36 am, edited 4 times in total.

Vexix
Genbot Janitor
Posts: 245
Joined: Sat Apr 17, 2004 10:10 am

Post by Vexix » Thu Jun 10, 2004 1:39 pm

genbotdoc.txt
|GenbotDoc.txt
|Manual for the Generic bot macro
|Version 12.38
|Date:06/04/2004
|
||**
[genbotDoc]
version=12.38
**||
|

Welcome to Genbot, probably the easiest way to multibox characters in Everquest.

To start genbot type /macro genbot <mastername> with <mastername> being the name of the character that will be in control of the bot.

By default your bot will respond to any command the master character /tells him.
By changing the values of listengroup, listenchat (in genbot_botname.ini), or by sending the toggle commands listenGroup, listenChat
you can start the Bot listening for commands sent either in group or in a chat channel.
The bot will still only respond to characters on it's list of masters but will do it in these other channels.

Additionally if you have the IRC plugin properly set up on your system the bot can listen in an IRC channel for commands.

By default the Bot will respond to it's Master in Tells. By changing the INI value ChatIn or by sending the command ChatIn,
the bot can respond in tells, group, channel or IRC. (IRC requires functional IRC Plugin)

The first time you run Genbot on a character the macro will create a default INI file. (genbot_botname.ini)
You probably want to start the macro and /endmacro it the first time so that you check/modify the INI settings.

BOT COMMANDS FROM THE BOT WINDOW:
/gb - Send commands to yourself. EXAMPLE /gb sit

MASTER TO BOT COMMANDS:
/tell bot command <parameter> <parameter> ...
* IF checkname is false, you can use group and chat commands like this;
/1 command <parameter> <parameter> ...
/g command <parameter> <parameter> ...
* IF checkname is true, then use group and chat commands like this;
/1 bot command <parameter> <parameter> ...
/g bot command <parameter> <parameter> ...

MISC:
shortcuts <shortcutname> - Display what <shortcutname> does, default will list all your shortcuts.

lootup <Me|Yourself|TargetName|clear> Commands bot to loot.
- <clear> bot loots masters target
- <CorpseName> bot loots CorpseName
lootall - Commands bot to attempt to loot all corpses around it.

setvar - Sets a var to new setting
rptvar - Commands bot to reply with the current value of a variable

target <Me|Yourself|TargetName|clear> - Causes the bot to change it's target;
- <Me> targets master
- <Yourself> bot targets itself
- <TargetName> name of target
- <clear> clears your current target
notarget - Commands bot to clear it's target.
face - Commands bot to face it's current target.
assist - Commands bot to assist the master, how the bot acts when assisting is controlled by toggles.

accept - Command bot to accept the current group invite.
invite - Command bot to invite it's current target to group.
reject - Command bot to reject the current group invite.

consent <playername> - Commands bot to give consent to <playername>, default will consent it's master.
reload - Commands bot to re-init the macro
trade - Commands bot to hit the trade button in a trade window.
yesres - Commands bot to hit yes on a ressurection confirm box.

MOVEMENT:
anchor - Causes the bot to remember it's current location and return there between fights.
anchorradius <distance> - Tells bot to stop moving when it is within <distance> of its anchor point.
door - Causes the bot to attempt to open the closest door.
duck - Commands the bot to duck.

follow <blank|name> - Command bot to follow the master or his designated target;
- <blank> - if master has no target, tells the bot to follow you.
- <blank> - if master has a target, tells the bot to follow master's target.
- <name> - tells the bot to follow name, name can be your name,pcname or npcname.
- EXAMPLE /tell bot follow
followmode <1|2|3> - Sets how the bot follows;
- <1> (Combat mode) is facing you constantly and attempting to move directly towards you.
- <2> (AdvPathFollow) is plotting the path of it's target, and then following that path
- <3> (Eq's /follow) is the native /follow command used by EQ (group members only?)
- EXAMPLE /tell bot followmode 2
stay - Commands bot to stop following
pause - Pauses the advanced follow command

moveto <Me|Loc|TargetName> - commands the bot to move to a point, then stop;
- <Me> moves bot to you
- <225,-300> moves bot to the location 225 , -300
- <%T> moves bot to your target
- EXAMPLE. /tell bot moveto Me
movetomode <1|2> - Sets how the bot movesto;
- <1> (normal) Genbot Anchor type
- <2> (AdvPathGoto)
- EXAMPLE. /tell bot movetomode 1

mount - Commands bot to get on it's mount (defined in genbot_botname.ini)
stop - Forces the bot to stop, will duck, dismount and stop moving.


COMMUNICATION:
checkname - if set to true, bot will only respond to commands in group or chat if the command is preceeded with <botname>
exp - Commands bot to reply with it's current exp percent
norelay - Stops bot from sending received tells to it's master
relay - Starts bot sending received tells to it's master
saytarget - The bot will tell you what it's currently Targeting.
reportbuffs - Commands bot to tell it's master a list of currently active buffs.
cmds - Asks bot to return a list of available commands
verbosity - Changes what level chat the bot actually sends to it's master.
chatin <channelname> - Changes what channel the bot will use for replying to it's master.


COMBAT:
attack - Commands bot to start attacking
noattack - Commands bot to Stop attacking

behind - Commands bot to move behind it's current target
getbehind - Commands bot to move behind the specified target

petattack - Assist's master for target and then issues the bot /pet attack command.

hide - Commands bot to use it's Hide ability
rmod <distance> - Changes relative distances in combat
rset <distance> - Changes the range settings used in combat
shield - Commands bot to /shield it's master
sneak - Commands bot to use it's sneak ability


CASTING:
buff <spell> - Commands bot to cast <spell> on it's master
buff <spell> on <target> - Commands bot to cast buff <spell> ON <target>, bot will automatically refresh it.
chainnuke - Commands bot to start chaining nukes on <target>
chainstun - Commands bot to start chaining stuns on <target>
evac - Commands bot to move to it's master and cast it's evac spell, if defined in the .ini file.
heal - Commands bot to heal <target>
itemcast <itemname> - Commands bot to trigger the specified item.
loadlist <listname> - Commands bot to load a spell list
mana - Commands bot to reply with it's current mana

sn <spell|item> - Commands bot to cast the specified spell on master's target.
<spell> - will cast <spell> on master's target.
<item> - will right click item on master's target.
snt <spell|item> on <target> - Commands bot to cast <spell|item> ON <target>,if "on <target>" is not specified, it will cast on bot's target
<spell> - snt brell's stalwart shield on PlayerName
<item> - snt Regent Symbol of Innoruuk on NPCName

spellgem <number> - This sets the spell gem used when bot is required to memorize a new spell. (1 to 8)
setlompct <percent> - Sets the mana percent at which the bot will report low mana

settankheal <spell> - Sets the spell used to heal tanks, if no <spell> is specified then the current spell is reported.
setcasterheal <spell> - Sets the spell used to heal casters, if no <spell> is specified then the current spell is reported.
setpetheal <spell> - Sets the spell used to heal pets, if no <spell> is specified then the current spell is reported.
setdefaultheal <spell> - Sets the spell used for the heal command, if no <spell> is specified then the current spell is reported.
setpatchheal <spell> - Sets the spell used to patch heal, if no <spell> is specified then the current spell is reported.

setcasterhealpct <percent> - Sets the HP % at which caster's will be healed, if <percent> is not specified, the current % is reported.
settankhealpct <percent> - Sets the HP % at which tank's will be healed, if <percent> is not specified, the current % is reported.
setpethealpct <percent> - Sets the HP % at which pet's will be healed, if <percent> is not specified, the current % is reported.

watchtarget - Commands bot to monitor the hit points of <target>. Needs to have autoheal on for target to be healed.
resetwatch - Commands bot to reaquire the ID's of it's targets, good to execute after zoning


TOGGLES: COMMAND - DESCRIPTION - DEFAULT
Most toggles can have there default starting value set in your genbot_botname.ini file
One example,when we are telling the bot to bash during combat, is the line: DoBash=1

listengroup - Toggles bot listening for commands in group chat - OFF
listenchat - Toggles bot listening for commands in the Chat Channel - OFF

aona - Toggles bot attacking targets on assist - OFF
bona - Toggles bot attacking from behind on assist - OFF
petona - Toggles bot doing /pet attack on assist - OFF
beagg - Toggles bot automatically fighting back when attacked - OFF
puller - Controls if the bot will return to it's anchor point when attacked - OFF
autoengage - Controls if the bot will close and engage when in combat - OFF
autobehind - Controls if the bot will automatically attempt to fight behind all targets during combat - OFF

backstab - Toggles bot using backstab while fighting - OFF
bash - Toggles bot using Bash during fighting - OFF
disarm - Toggles bot using disarm while fighting - OFF
evade - Toggles bot using Hide during fighting - OFF
flyingkick - Toggles bot using flyingkick while fighting - OFF
frenzy - Toggles bot using frenzy while fighting - OFF
incite - Toggles bot using incite while fighting - OFF
kick - Toggles bot using kick while fighting - OFF
slam - Toggles bot using Slam during fighting - OFF
taunt - Toggles bot using taunt while fighting - OFF

archery - Toggles bot using archery while fighting - OFF
run - Toggles run setting on bot
traps - Toggles bot trying to find and disarm traps - OFF

aftercastsit - Controls if the bot will sit after casting spells - OFF
autoheal - Controls if the bot will automatically use heals on group and watch targets - OFF
autohealpets - Controls if the bot will automatically use heals on pets - OFF
patchheal - Controls if the bot will automatically patch heal targets below half their heal percent - OFF
reportlom - Controls if the bot will automatically report when it's low on mana - OFF
yaulp - Toggles if bot will use yaulp (Yaulp spell is defined in genbot_botname.ini) when low on mana - OFF
canni - Toggles if bot will cannibalize when low on mana - OFF


OBSOLETE COMMANDS
These commands will be removed, all of them can be replaced by the native command support now built into genbot.

"Implemented /commands natively into genbot.
Any command to the bot which begins with a / will be executed by the bot.
For example, "/wave" or "/yell" or "/target id 1234" or "/call MySubroutine" are all valid bot commands." - Vexix

afk <message> - Turn bot's afk on with optional <message>. USE: /tell bot /afk <message>
autoinv - Commands bot to use the /autoinv command USE: /tell bot /autoinv
camp - Commands bot to camp out. USE: /tell bot /camp
dismount - Commands bot to /dismount. USE: /tell bot /dismount
disc <discname> - Commands bot to fire the specified /disc. USE: /tell bot /disc <discname>
group <message> - Commands the bot to /gsay <message>. USE: /tell bot /g <message>
petback - Commands bot to execute it's /pet back command. USE: /tell bot /pet back
petguard - Commands bot to execute it's /pet guard command. USE: /tell bot /pet guard
random - Commands bot to /ran. USE: /tell bot /random <value>
say <message> - Commands the bot to /say <message>. USE: /tell bot /say <message>
sit - Makes bot sit USE: /tell bot /sit
stand - Makes bot stand USE: /tell bot /stand
tell <name> <message - Commands the bot to /tell <name> <message>. USE: /tell bot /tell <name> <message>



SHORTCUTS - Vexix
Genbot also includes shortcuts, which can run any everquest, macroquest, or genbot command.
For instance, the following would be a valid Genbot .ini section:

[Shortcuts]
eyepatch=itemcast Eyepatch of Plunder
nukeit=sn Lure of Fire
sowon=buff spirit of wolf on
uberaa=/alt activate 33
takemehome=/echo play:PoKtoNexxus 1 f nopp z;NexxustoBazaar 10 cr nopp z;BazaartoShadHav 1 cf nopp noz

Shortcuts give an easy way to abbreviate long commands, like interzone advpaths, and also have some really cool possibilities for controlling parties.
For instance, you could have your leader say nukeit in groupsay, and each of the PCs in the party could respond with an appropriate nuke as defined
in their .ini file. The wizzy Lures it, the enchanter smacks it with his DD+stun, the druid casts wildfire, and the warrior, um, slams it!

Similarly, if you called evacuate, with the .ini's set up right, the druid could cast his evac, the cleric might automatically heal the druid
to make sure he survives, and the warrior could hit AE taunt to pull aggro from the druid. Fun, fun!

To show what shortcuts you have defined in your .ini file while running the macro, I added the shortcuts command.
Type "shortcuts" for a list of available shortcuts, and type "shortcuts name_of_shortcut" to see what that particular shortcut does.

Shortcuts can be used to do some very cool stuff. For instance, shortcuts can also call other shortcuts.
If the above "mark" shortcut had the " on" removed to allow it to cast on the current target instead of expecting you to provide one, then:

Mark=snt Mark of the righteous|snt Mark of kings|/target clear

Then you could make another shortcut:

markparty=/target clear|/keypress F1|markon|/keypress F2|markon|/keypress F3|markon|/keypress F4|markon|/keypress F5|markon|/keypress F6|markon

Which would buff your entire party for you. If you didn't have 6 people in your party, it would still try to target them and cast,
but it would immediately get an error and time out, so no real loss.

Likewise this could be done for items, but in order to do so, a /delay command to account for the casting time would need to be included,
since the /itemcast command doesn't wait for a response. To shrink your entire party use:

shrink=/itemcast "cobalt bracer"|/delay 8s|/target clear
shrinkparty=/target clear|/keypress F1|shrink|/keypress F2|shrink|/keypress F3|shrink|/keypress F4|shrink|/keypress F5|shrink|/keypress F6|shrink

Unfortunately, this shortcut would still wait after trying to all 6 party members, even if you only had 2.

NOTE: You can use DataVar expressions in shortcuts, but be warned they will be evaluated by the first MQ2 char they hit.
In otherwards, if you are running MQ2, and give your bot the command /say My name is ${Me.Name}, the bot will say,
My name is MasterName, since the datavar is evaluated by the master MQ2. If you're not running MQ2, and give the same command,
the bot will say, "My name is Bot."

CAUTIONS:
With great power, comes great responsibility.
Since shortcuts can call other shortcuts, it's possible to create shortcuts which would endlessly loop.
I don't recommend that.

Shortcuts take full control of your bot during execution.
It would be easy to make a long cleric buff shortcut chain which would cast every buff on every member of your party,
but remember that until your buff chain finished, your cleric bot will do no healing or moving.
I hope nothing spawns or wanders into your party!


Genbot Credits and History:

Version 0-8.8 Genbot created and developed by Grimjack
Version 8.8-? Lasher took over the code.
Version ?-12.34 Lord Giddeon maintained the code. Fez_Ajer did some trouble-shooting and code fixes.
Version 12.35 - Current Vexix Updated the code and introduced generalized shortcuts.

sj_digriz
a lesser mummy
a lesser mummy
Posts: 40
Joined: Wed Jun 02, 2004 9:10 am
Contact:

Post by sj_digriz » Thu Jun 10, 2004 4:00 pm

I had to go back to 12.38... Wish I was better at getting dumps of errors for you. But here's what I got before switching back. Hope this helps.

performance is WAY improved FYI$$$

#1: mount says "I don't have that spell"

#2: selfbufflist cycles endlessly stopping other stuff from happening. I'm wondering if this is really the culprit in the crash.

#3: Crashes to desktop after running for about 10 minutes every time.

#4: Shortcuts can't find spells if they are already loaded in a slot other than the autoload gem, then crashes. ie...I made a shortcut to slow

slow=snt Forlorn Deeds

Forlorn Deeds is in gem2. The screen goes all wonky then crashes if I type the word slow. But, if i specifically do /2 snt Forlorn Deeds then it works.

Hmm...was some other stuff I can't remember now. I'll get back to you later. I'll do more testing when I have the time to properly document/log the results.

Thanks for all your work.
SJ

Nightshift
a lesser mummy
a lesser mummy
Posts: 54
Joined: Mon Oct 13, 2003 8:52 am

Just some typos

Post by Nightshift » Thu Jun 10, 2004 4:11 pm

Haven't ran the code yet, just reading though it right now.



botspell.inc


Line 113:

Code: Select all

/call LoadSetting SelfBuffList Spell SelfBuffList "Buffs you wish to maintain o[color=red]f[/color] yourself separated with |"
Change the f to an n.

Line 608:

Code: Select all

/if (${SelfBuffList.Equal[Buffs you wish to maintain o[color=red]f[/color] yourself separated with |]} || !${SelfBuffList.Length}) /return
Change the f to an n.


Line: 473

Code: Select all

/call ChatOut 3 ${MasterName} "[color=red]Cast[/color] cast since I'm moving."
Change Cast to Can't


All I see with a quick glance, will test it later.

NightShift

venidar
orc pawn
orc pawn
Posts: 12
Joined: Fri May 14, 2004 3:24 pm

Post by venidar » Thu Jun 10, 2004 5:02 pm

Questions:

Can bards still cast items while moving or sitting?
Can alt abilities be cast while sitting?
Do any notarget spell types besides b ae, self, ae pc v2, and group v1 exist?
Why are pally spells handled as something different from every other healer?
As part of restructuring the code for better performance, I may mix the current sections, such as putting all init routines in one file. Would anyone mind this kind of reordering in return for better performance?
Bards can cast while moving/sitting. edit: clicking items did stand the bard for me though

Alt abilities didn't get changed to auto stand, at least the ones I've used (exodus, divine arb) require you to stand before you can cast them.

It would be nice to see the heal stuff merged together so that clerics could also do group heals, and paladins could make use of their single target heals..they look mutually exclusive in the code atm.

User avatar
Fuergrissa
a grimling bloodguard
a grimling bloodguard
Posts: 607
Joined: Mon Dec 08, 2003 3:46 pm
Location: UK

Post by Fuergrissa » Fri Jun 11, 2004 2:20 am

very good job Vexix, Thank you for your improvements and mods.
[quote]"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning."[/quote]

Roentgen
orc pawn
orc pawn
Posts: 15
Joined: Fri Nov 28, 2003 9:15 pm

Post by Roentgen » Fri Jun 11, 2004 3:24 pm

thank you for all the hard work. I have used genbot for quite some time but mostly just grouped commands together on hotkeys from the master. I would like to fine tune and start using short cuts like you described above and have a quick question.


I would like to automate control of adds. I use both a bard and an enchanter and would love to assign the bard (or second choice chanter) to "deal" with adds and keep em mezzed.


Thoughts?

MrSmallie
a hill giant
a hill giant
Posts: 167
Joined: Fri Oct 11, 2002 11:18 am

Post by MrSmallie » Fri Jun 11, 2004 3:35 pm

I have a simple question. Is Genbot setup to allow for autattack based on radius? I just started messing around with it, and I go pull something, run back to where my warrior is, and do a /tell attack, and he goes at it. It would be nice to not need the /tell and just have him go at it when the mob gets in range. Make sense?
Me
[img]http://home.comcast.net/~mrsmallie/ches.JPG[/img]