Genbot v13.3.7 [Updated 04/19/05]

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

Moderator: MacroQuest Developers

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Genbot v13.3.7 [Updated 04/19/05]

Post by ascii38 » Tue Aug 24, 2004 10:09 pm

Current File Versions:
Genbot.mac 13.3.6
BotCommon.inc 13.3.0
BotMain.inc 13.3.6
BotCore.inc 13.3.7
BotCombat.inc 13.3.3
BotSpell.inc 13.3.7
BotHealer.inc 13.3.6
GenbotDoc.txt 13.3.0

advpath.inc 1.31
advpath2.inc 1.31
Advpath files can be found here: http://macroquest2.com/phpBB2/viewtopic.php?t=8655
Advpath.inc needs ${Group} syntax fixed in Sub TargetMob .

NOTE: I'm publishing what I've got. It's worked for me for the limited amount of playtime I've had lately (to much time at the hospital). Other than a couple of stupid mistakes I fixed today, I haven't tested after the October 11, 2005 patch. The code is even more of a mess than normal and there are some work in process bits in here that aren't used. I got a couple of requests to post what I have, so here goes...

Changelog 2005-10-17

- Fixed for ${String} removal (which, IMHO, makes the code even worse)
- Changed Canni and Yaulp functionality to no longer memorize the spell if it is not already memorized.
- Added "CanniHealOverTime" ini file directive for spell to heal self after cannibalizing down to 70% health.
- Other stuff that I didn't write down.

Changelog 2005-04-19

- Fixed BotHealer.inc for change in ${Group} syntax

Changelog 2004-08-29

- Added two missing parentheses to auto /pet backoff.

- command-resetwatch was missing.

Changelog 2004-08-24

- Auto "/pet backoff" on enrage and gate (me). NOTE: Does not reengage pets in offrage. (me)

- IRC Messages set mastername to master that sent message (me).

- IRC "say" messages will accept botname as first arg with checkname off just as EQ Chat messages do (me).

- IRC "msg" handled like a direct tell (Gus)

- Handle Other language Tells & cross-server tells (dman)

- Don't relay pet tells (me)

- Enrage/Offrage events + handlers (frabtik)

- Assist assisting who it's told to assist rather than always assisting master (frabtik)

- Added /return for stopheal code. Still mostly untested.

See http://macroquest2.com/phpBB2/viewtopic.php?t=8623 for 13.3.0 - 13.3.2 changelog

Known issues:

reload command don't work.
Pets of NPCs are tricky to code for. Some commands such as guard will ignore them.
Heal messages from the .ini file don't work.
Multiple genbot initiated heals can exist in the spell queue, so repeated heals may be cast on one char.
If you have your hands full and try to memorize a spell, genbot will loop.
If using Windows XP or 2000, genbot performs much better if Performance Options are set to Background Services. Programs setting can cause slow responses, especially with more than one char on a PC.

Future plans (Vexix):

Next major release will be a rework of bothealer.inc.

I'm also planning to work a bit on advpath to see if I can stop it from doing the cha-cha in laggy environments.

For other future plans, see the poll: http://macroquest2.com/phpBB2/viewtopic.php?t=8191

Immediate future plans (me, until Vexix returns):

Integrate IRC with the rest of the chat code. Gus, I didn't include that code in this version because I like the "/i say joebot stun" pseudo-checkname function, so I left it in.

Put in Frabtik's taunt/incite code. "Sub CheckIsLookingAt" will have to be used it Health of Target's Target leadership AA is not available.

{Probably obsoleted by bandolier} Clean up and include my do-equip code. The code hits the highpoints that Vexix wanted but needs some cleaning up.

Ways you can help:

Bug reports!

Maintain the genbot doc to keep it up to date. Mistole sent Vexix an updated doc file, including the INI, which Vexix was updating for the new version. Fire it my way if the delay in Vexix's return gets to unbearable.

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.

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

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

Go here for more of the changelog on the previous (13.2) version:
http://macroquest2.com/phpBB2/viewtopic.php?t=8383
Last edited by ascii38 on Mon Oct 17, 2005 4:48 pm, edited 5 times in total.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:10 pm

genbot.mac

Code: Select all

|genbot.mac
|Personal commands module example.
|Version 13.3.6
|Date:06/08/2005
|
||**
[individual]
version=13.3.6
**||

|   Use this file to add in character or task specific routines or commands
|   That will not apply to all of your characters.  Use botcommon.inc for
|   your own routines and commands that you want all of your bots to be able
|   to use.

|   Since this mac calls all of the other .inc files, feel free to change the
|   name to botname1.mac or time.mac or tradeskill.mac or whatever according
|   to how you customize it.


| Change "bot_" below to specify a different .ini file.
| Useful if you want to make separate files for different activities for the
| same character.

#define INI_FILE_PREFIX bot_

#include botmain.inc

|Define your personal Events Here
|#Event EExample "Explain it to me again"

Sub Init-Individual
 
   |/call AddCommands Command_Phrase1 <Command_Phrase2> <Command_Phrase3> . . .
   | Command_Phrase - what the master will type to invoke the command
   | Put in as many command phrases as you like on the same line.
   |  The subroutine called will be Command-Command_Phrase1, etc.
   | example: /call AddCommands sit stand moveto
   | with subroutines called Command-sit, Command-stand, and Command-moveto
   
   |/call AddToggle Command ToggleDefaultValue|noini return|toggle "PhraseOff" "PhraseOn" <callsub>
   |
   | example: /call AddToggle sitaftercast off return "I will no longer sit after casting." "I will now sit after casting." callsub
   |
   | Command switch a Toggle - End User change change to suit prefferences
   |   The actual name of the toggle variable will be ${Toggle-ToggleName}.
   |   In our example, this would be ${Toggle-sitaftercast}
   | ToggleDefaultValue should be whatever you want the default value to be.
   |   This value will be entered into the ini file, under the Command name.
   |   If noini is used, then no .ini entry will be created, and the default
   |     will be set to FALSE.
   | return will return the toggle setting when no param is given
   | toggle will toggle the toggle setting when no param is given
   | PhraseOff returned by the bot when value is FALSE
   | PhraseOn returned by the bot when value is TRUE
   | callsub - optional - if entered, SetToggle will call ToggleCommand subroutine
   |   (ex. Sub Toggle-sitaftercast) after setting the toggle and before outputting
   |   the result
   
   |/declare PersonalValue string outer
   |/declare AnotherValue int outer default
   
   |INI Values
   |/call LoadSetting PersonalVar VarType Personalkey "Default Value"
   | Declares and initializes variable PersonalVar by reading from the .ini key
   |  called PersonalKey
   | If no PersonalKey entry in .ini file, or entry is blank, "Default Value"
   |  is entered in .ini file.
   | Valid VarTypes are string, int, bool, and event.
   
/return

|Things that you want to happen every loop through the macro go in this sub.
Sub IndividualMain

   |/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 ascii38 on Mon Oct 17, 2005 4:49 pm, edited 1 time in total.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:10 pm

botcommon.inc

Code: Select all

|botcommon.inc
|Common commands module example.
|Version 13.3.0
|Date:08/05/2004
|
||**
[common]
version=13.3.0
**||

|   Use this file for your own routines and commands that you want all of
|   your bots to be able to use.

|   Use the base genbot.mac to add in character or task specific routines
|   or commands that will not apply to all of your characters.

|Define your personal Events Here
|#Event EExample "Explain it to me again"

Sub Init-Common

   |/call AddCommands Command_Phrase1 <Command_Phrase2> <Command_Phrase3> . . .
   | Command_Phrase - what the master will type to invoke the command
   | Put in as many command phrases as you like on the same line.
   |  The subroutine called will be Command-Command_Phrase1, etc.
   | example: /call AddCommands sit stand moveto
   | with subroutines called Command-sit, Command-stand, and Command-moveto
   
   |/call AddToggle Command ToggleDefaultValue|noini return|toggle "PhraseOff" "PhraseOn" <callsub>
   |
   | example: /call AddToggle sitaftercast off return "I will no longer sit after casting." "I will now sit after casting." callsub
   |
   | Command switch a Toggle - End User change change to suit prefferences
   |   The actual name of the toggle variable will be ${Toggle-ToggleName}.
   |   In our example, this would be ${Toggle-sitaftercast}
   | ToggleDefaultValue should be whatever you want the default value to be.
   |   This value will be entered into the ini file, under the Command name.
   |   If noini is used, then no .ini entry will be created, and the default
   |     will be set to FALSE.
   | return will return the toggle setting when no param is given
   | toggle will toggle the toggle setting when no param is given
   | PhraseOff returned by the bot when value is FALSE
   | PhraseOn returned by the bot when value is TRUE
   | callsub - optional - if entered, SetToggle will call ToggleCommand subroutine
   |   (ex. Sub Toggle-sitaftercast) after setting the toggle and before outputting
   |   the result
   
   |/declare PersonalValue string outer
   |/declare AnotherValue int outer default
   
   |INI Values
   |/call LoadSetting PersonalVar VarType Personalkey "Default Value"
   | Declares and initializes variable PersonalVar by reading from the .ini key
   |  called PersonalKey
   | If no PersonalKey entry in .ini file, or entry is blank, "Default Value"
   |  is entered in .ini file.
   | Valid VarTypes are string, int, bool, and event.
   
/return

|Things that you want to happen every loop through the macro go in this sub.
Sub CommonMain

   |/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 ascii38 on Mon Oct 17, 2005 4:49 pm, edited 1 time in total.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:11 pm

botmain.inc

Code: Select all

|botmain.inc
|Generic bot macro for any class.
|Version 13.3.6
|Date:08/06/2005
|
||**
[genbot]
version=13.3.6
**||
|

|-------------------------------------------------------------------------
|Includes
|-------------------------------------------------------------------------
#include bothealer.inc
#include botcombat.inc
#include botspell.inc
#include botcore.inc
#include botcommon.inc
#include advpath.inc

|-------------------------------------------------------------------------
|SUB: Main Program Sub
|-------------------------------------------------------------------------

Sub Main
   /declare GenFor int local
   /declare SectionName string outer
   |----------------------------------------------------------------------
   |Initialize MasterList (characters that can control this bot)
   |Checks to see if list already exists in case a reload is done
   |----------------------------------------------------------------------
   /if (!${Defined[MasterList]}) {
      /if (!${Defined[Param0]}) {
         /echo Usage: /macro generic <Master Name1> <Master Name2>...
         /endmacro
      }
      /declare MasterList string outer
   }
   |----------------------------------------------------------------------
   |clear and rebuild master list if a list is passed
   |----------------------------------------------------------------------
   /if (${Defined[Param0]}) {
      /for GenFor 0 to (${Macro.Params}-1)
         /call ListAppendElement MasterList ${Param${GenFor}.Lower} " "
      /next GenFor
   }
   |----------------------------------------------------------------------
   |Call the Initialize Sub of each include file
   |----------------------------------------------------------------------
   /declare SectionsList string outer Core Combat Spell Healer Shortcuts Common Individual
   /for GenFor 1 to ${Math.Calc[${SectionsList.Count[ ]}+1]}
      /declare cmds-${SectionsList.Arg[${GenFor}]} string outer
   /next GenFor
   
   /for GenFor 1 to ${Math.Calc[${SectionsList.Count[ ]}+1]}
      /varset SectionName ${SectionsList.Arg[${GenFor}]}
      /if (${DebugList.Find[main]}) /echo Calling Init-${SectionName}.
      /call Init-${SectionName}
   /next GenFor
   | Setting SectionName to blank let's SetToggle routine know it can talk again.
   /varset SectionName
   |----------------------------------------------------------------------
   |Main program loop performs subs for each include file
   |----------------------------------------------------------------------
   :MainLoop
   /doevents
   /if (${Toggle-doheal}) /call HealerMain
   /if (${CombatTargetID}) /call CombatMain 
   /call CoreMain
   /call SpellMain
   /call CommonMain
   /call IndividualMain
   /goto :MainLoop

/return


|-------------------------------------------------------------------------
| SHORTCUT SUBROUTINES
|-------------------------------------------------------------------------

   |----------------------------------------------------------------------
   | Init-Shortcuts: to load in shortcuts from the .ini file
   |----------------------------------------------------------------------

Sub Init-Shortcuts
   /declare Shortcutlist string local
   /declare ArgNum int local 0
   /declare Short string local 0
   /declare ParamS string outer
   
   /varset ArgNum 1
   /if (!${Defined[IniFile]}) /declare IniFile string outer genbot_${Me.CleanName}.ini
   /varset Shortcutlist ${Ini[${IniFile},SHORTCUTS,-1,Undefined]}
   /if (${Shortcutlist.NotEqual[Undefined||]}) {
      :shortcuts
      /if (${Shortcutlist.Arg[${ArgNum},|].Length}) {
         /varset Short ${Shortcutlist.Arg[${ArgNum},|].Lower}
         /call LoadSetting ${Short} shortcut ${Short} None
         /varcalc ArgNum ${ArgNum}+1
         /goto :shortcuts
      }
   } else {
      /ini ${IniFile} SHORTCUTS default "/echo Put yer shortcuts in your .ini file!"
   }
/return

   |----------------------------------------------------------------------
   | Command-shortcuts: to list available shortcuts
   |----------------------------------------------------------------------


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

   |----------------------------------------------------------------------
   | Init-Shortcuts: execute a shortcut
   |----------------------------------------------------------------------

Sub ShortCut(string ShortCutCommand)
   /declare Name string local
   /declare ParseText string local
   /declare GenFor 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.Right[${Math.Calc[-${ShortCutCommand.Arg[1].Length}-1]}]}"
      /vardata ParseText CommandParam
   }
   /for GenFor 1 to ${Math.Calc[${ParseText.Count[|]}+1]}
      /call ExecCommand "${ParseText.Arg[${GenFor},|]}"
   /next GenFor
/return


|-------------------------------------------------------------------------
| INITIALIZATION CONTROL SUBROUTINES
|-------------------------------------------------------------------------

   |----------------------------------------------------------------------
   | AddCommands: add a command
   |----------------------------------------------------------------------

Sub AddCommands
   /declare GenFor int local
   /declare GenStr string local |${cmds-${SectionName}}|
   /for GenFor 0 to ${Math.Calc[${Macro.Params}-1]}
      /if (!${GenStr.Find[|${Param${GenFor}}|]}) {
         /call ListAppendElement cmds-${SectionName} ${Param${GenFor}} "|"
      }
   /next GenFor
/return

   |----------------------------------------------------------------------
   | AddToggle: add a toggle command and load initial setting from .ini
   |----------------------------------------------------------------------

Sub AddToggle(string Name,string TogDefault,string TogType,string OffText,string OnText,string CallSub)
   /declare Setting string local
   /if (!${Defined[Toggle-${Name}]}) {
      /declare Toggle-${Name} bool outer
      /declare Toggle-${Name}-OffText string outer
      /declare Toggle-${Name}-OnText string outer
      /declare Toggle-${Name}-ToggleType string outer
      /declare Toggle-${Name}-CallSub bool outer
   }
   /varset Toggle-${Name}-OffText ${OffText}
   /varset Toggle-${Name}-OnText ${OnText}
   /varset Toggle-${Name}-ToggleType ${TogType}
   /if (${CallSub.Lower.Equal[callsub]}) {
      /varset Toggle-${Name}-CallSub TRUE
   } else {
      /varset Toggle-${Name}-CallSub FALSE
   }
   /if (${TogDefault.Equal[noini]}) {
      /varset Toggle-${Name} FALSE
   } else {
      /call LoadSetting ${Name} toggle ${Name} ${TogDefault}
   }
   /call ListAppendElement cmds-${SectionName} ${Name} "|"
/return

   |----------------------------------------------------------------------
   | SetToggle: set the value of the .ini and repeat current setting
   |----------------------------------------------------------------------

Sub SetToggle(string Name,string newValue)
   /declare TrueString string local
   /declare FalseString string local
   /declare OutputString string local
   
   | If no argument and Toggle is a toggle type, toggle it.
   /if (!${Defined[newValue]}) {
      /if (${Toggle-${Name}-ToggleType.Equal[toggle]}) {
         /if (${${Toggle-${Name}}) {
            /declare newValue string local 0
         } else {
            /declare newValue string local 1
         }
      } else {
         /declare newValue string local ${${Toggle-${Name}}
      }
     
   | If it has an argument, set according to argument, and clear newValue.
   } else {
      /varset newValue ${newValue.Lower}
      /varset TrueString true on 1 yes
      /varset FalseString false off 0 no
      /if (${TrueString.Find[${newValue}]}) {
         /varset Toggle-${Name} 1
         /varset newValue
      } else /if (${FalseString.Find[${newValue}]}) {
         /varset Toggle-${Name} 0
         /varset newValue
      }
   }
   
   | Call the extended function sub if indicated.
   /if (${Toggle-${Name}-CallSub}) {
      /call Toggle-${Name} ${newValue}
   }
   
   | If we're still initializing, don't output the setting.
   /if (${SectionName.Length}) /return
   
   | Find the appropriate response string for new toggle setting.
   | Using CommandParam for the output string just cuz I'm too lazy
   | to declare another outer string.
   /if (${Toggle-${Name}}) {
      /varset CommandParam ${Toggle-${Name}-OnText}
   } else {
      /varset CommandParam ${Toggle-${Name}-OffText}
   }
   
   | Replace any @'s with $'s for runtime values.
   /if (${CommandParam.Count[@]}) {
      /call CollapseParams CommandParam
      /varset CommandParam ${Macro.Return}
   }
   
   | Say what you've come to say.
   /call ChatOut 6 "${CommandParam}"
/return

   |----------------------------------------------------------------------
   | LoadSetting: load a variable value from the .ini file
   |----------------------------------------------------------------------

Sub LoadSetting(string VarName,string VarType,string KeyName,string DefaultValue)
   /declare RealSection string local ${SectionName.Upper}
   /if (${VarType.Equal[shortcut]} || ${VarType.Equal[event]}) {
      /varset RealSection ${VarType.Upper}S
   }
   
   | Initialize the .ini file.
   /if (!${Defined[IniFile]}) {
      /declare IniFile string outer INI_FILE_PREFIX${Me.CleanName}.ini
   }
   
   | Read value from .ini file
   /declare IniValue string local ${Ini[${IniFile},${RealSection},${KeyName},NOTFOUND]}
   | If no .ini value, use the DefaultValue
   /if (${IniValue.Equal[NOTFOUND]}) {
         /ini ${IniFile} "${RealSection}" "${KeyName}" "${DefaultValue}"
         /varset IniValue ${DefaultValue}
   }
   
   | If it's a string, set the varname-DefaultValue variable
   /if (${VarType.Equal[string]}) {
      /if (!${Defined[${VarName}-DefaultValue]}) {
         /declare ${VarName}-DefaultValue ${VarType} outer
      }
      /vardata ${VarName}-DefaultValue DefaultValue

   |If it's a shortcut, then set the shortcut var and add to the list of shortcuts
   } else /if (${VarType.Equal[shortcut]} || ${VarType.Equal[event]}) {
      /if (!${IniValue.Lower.Equal[none]}) {
         /if (!${Defined[ShortCuts-${VarName.Lower}-Text]}) {
            /declare ShortCuts-${VarName.Lower}-Text string outer
         }
         /varset ShortCuts-${VarName.Lower}-Text ${IniValue}
         /call ListAppendElement cmds-Shortcuts ${VarName.Lower} "|"
      }
      /return

   | If it's a toggle, then use SetToggle sub to give the value.
   } else /if (${VarType.Equal[toggle]}) {
      /call SetToggle ${VarName.Lower} ${IniValue}
      /return
   }
   
   | Must be not a shortcut nor a toggle, since not /returned yet.
   /if (!${Defined[${VarName}]}) {
      /declare ${VarName} ${VarType} outer
   }
   /varset ${VarName} ${IniValue}
/return

   |----------------------------------------------------------------------
   | CollapseParams: replace @'s with $'s to evaluate datavars at runtime
   |----------------------------------------------------------------------

Sub CollapseParams(string Parms)
   /declare GenFor int local
   /declare stemp string local
   /declare sint int local
   
   |/echo Parms ${Parms} ${${Parms}}
   
   /varset sint ${${Parms}.Count[@]}
   |/if (Debug) /echo name ${Name} schar @ sint ${sint}
   /if (${sint}) {
      /varset stemp ${${Parms}.Arg[${Math.Calc[${sint}+1]},@]}
      |/if (Debug) /echo stemp ${stemp}
      /for GenFor ${sint} downto 1
         |/if (Debug) /echo In for loop
         /if (${${Parms}.Arg[${GenFor},@].Length}) {
            /varset stemp ${${Parms}.Arg[${GenFor},@]}$${stemp}
         } else {
            /varset stemp $${stemp}
         }
      /next GenFor
   } else {
      /varset stemp ${${Parms}}
   }
   |/echo new result ${stemp}
/return ${stemp}
Last edited by ascii38 on Mon Oct 17, 2005 4:50 pm, edited 1 time in total.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:11 pm

botcore.inc

Code: Select all

|botcore.inc
|Bot core module.
|Version 13.3.7
|Date:10/17/2005
|
||**
[botcore]
version=13.3.7
**||

#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 EscKey       "You no longer have a target."
#event ExpGained    "#*#You gain#*#experience#*#"
#event FollowOff    "You are no longer auto-following#*#"
#event ImDead       "You have been slain by#*#"
#event Invite       "#1# invites you to join a group."
#event IRCSAY       "<#1#> #2#"
#event IRCMSG       "<#1#/#*#> #2#"
#event LosingLev    "You feel as if you are about to fall"
#event SelfEcho     "[MQ2] Genbot #*#"
#event Zoned        "LOADING, PLEASE WAIT..."
#Event AltTell      "#1# told you, '#2#"
#Event AltTell      "#1# tells you,#*#, '#2#"

Sub Init-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 AddCommands accept afk autoinv anchor anchorradius assist
   /call AddCommands autoinv camp chatin cmds consent dismount door duck
   /call AddCommands exp equip face follow followmode group invite
   /call AddCommands lootall lootup mount moveto movetomode notarget
   /call AddCommands pause petattack petback petguard random reject
   /call AddCommands reload rmod rptvar run say saytarget setvar shortcuts sit stand
   /call AddCommands stay stop tell target trade verbosity yesres

|Declare Vars
   /declare advpath bool outer
   /declare Afollow int outer 0
   /declare AnchorLoc string outer 0
   /declare BreakOut bool outer FALSE
   /declare CombatTargetID int outer 0
   /declare CommandParam string outer
   /declare CorpseList string outer
   /declare CurrCommand string outer
   /declare FollowTarget string outer
   /declare IsAnchored bool outer FALSE
   /declare LootTooFar int outer 0
   /declare MasterName string outer ${MasterList.Arg[1, ]}
   /declare MoveToDest string outer
   /declare MoveToRange string outer 0

   /declare ObstacleCheck int outer 0
   /declare SubCallName string outer
   /declare TalkToSelf bool outer

|Timers
   /declare SitTimer timer outer 0
   /declare ChatOutTimer timer outer 0
   /declare CheckObstacleTimer timer outer 0

   /call LoadSetting AnchorRadius int AnchorRadius 6
   /call LoadSetting ChatIn string ChatIn Tell
   /call LoadSetting ChatInChannel string ChatInChannel "Channel Name"
   /call AddToggle checkname off return "I will respond to all commands." "I will only respond to commands that are addressed to me."
   /call LoadSetting CorpseRadius int MaxLootRadius 50
   /call LoadSetting followmode int followmode 1
   /call LoadSetting IgnGroupList string IgnGroupList duck|say|tell|group|cmds|trade|run|backstab|taunt|evade|slam|bash|kick|flyingkick|disarm|traps|puller||
   /call LoadSetting ListenChan string ListenChan Name_of_channel
   /call AddToggle listenchat on return "I will ignore Chat" "I will listen in Chat."
   /call AddToggle listengroup on return "I will ignore Group Chat." "I will listen in Group Chat."
   /call LoadSetting MountItem string MountItem "Name of Bridle or Drum"
   /call LoadSetting MaxTargetRange int MaxTargetRange 250
   /call LoadSetting movetomode int movetomode 1
   /call AddToggle relaytells on return "I will not relay tells to my master." "I will relay tells to my master."
   /call AddToggle trap off return "I will not detect for traps." "I will detect for traps."
   /call LoadSetting Verbosity int Verbosity 9
   /call LoadSetting DebugList string DebugList "None"

   /varset SectionName advpath

   /call LoadSetting FaceFastini int FaceFast 1
   /call LoadSetting SilentFlagini int SilentFlag 1
   /call LoadSetting SpeedSenseini int SpeedSense 15
   /call LoadSetting FollowDistanceini int FollowDistance 20

   /call LoadSetting EventExpGained event EventExpGained "None"
   /call LoadSetting EventImDead event EventImDead "None"
   /call LoadSetting EventLoosingLevitate event EventLoosingLevitate "/botsay I'm loosing Levitate."
   /call LoadSetting EventLoosingInvis event EventLoosingInvis "/botsay I'm loosing invis."
   /call LoadSetting EventLostInvis event EventLostInvis "/botsay I'm no longer invis."
   /call LoadSetting EventZoned event EventZoned "None"

   /assist off

   /squelch /alias /gb /echo genbot
   /squelch /alias /botsay /call ChatOut 1
   /squelch /alias /then /multiline ; /varset DidThenClause 1 ; /call ExecCommand
   
   /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 CoreMain
   |Check Protect
   /if (${Toggle-protect}) {
      /declare MobID int local ${Spawn[pc ${MasterName}].NearestSpawn[npc radius ${MeleeRadius} zradius 10].ID}
      /if (!${MobID}) {
         /varset MobID ${Spawn[pc ${MasterName}].NearestSpawn[pet radius ${MeleeRadius} zradius 10].ID
         /if (!${Spawn[id ${MobID}].Master.Type.Equal[npc]}) /varset MobID 0
      }
      /if (${MobID} && ${CombatTargetID}!=${MobID}) {
         /call CheckIsLookingAt ${MobID} ${Spawn[${MasterName}].ID}
         /if (${Macro.Return}) {
            /call CheckNeverKill ${MobID}
            /if (${Macro.Return}) {
               /call Target "id ${MobID}"
               /varset CombatTargetID ${MobID}
               /call ExecCommand EventProtect ${Spawn[id ${CombatTargetID}].CleanName}
            }
         }
      }
   }
   /if (${MoveToDest.Length}) /call MoveTo
   /if (${Me.Combat} && (${Target.Type.Equal[NPC]} || ${Target.Master.Type.Equal[npc]}) && ${Toggle-autoengage} && ${Target.Distance}<${MeleeMaxRadius}) {
      /varset CombatTargetID ${Target.ID}
   } else /if (${CombatTargetID}) {
      /return
   } else /if (${Me.Combat}) /attack off
   /if (${Toggle-trap} && ${Me.AbilityReady[Sense Traps]}) /doability "Sense Traps"
   /if (${IsAnchored}) {
      /if (${Math.Distance[${AnchorLoc}]}>${AnchorRadius}) {
         /if (!${MoveToDest.Length} && !${CombatTargetID}) /call MoveTo "${AnchorLoc}"
      } else {
         /if (${Toggle-sitaftercast} && ${Me.Standing} && !${SitTimer}) /varset SitTimer ${DelayBeforeSit}
         |Check Guard
         /if (${Toggle-guard} && ${Spawn[npc radius ${GuardRadius}].ID}) {
            /call CheckNeverKill ${NearestSpawn[npc radius ${GuardRadius}].ID}
            /if (${Macro.Return}) {
               /call Target "id ${NearestSpawn[npc radius ${GuardRadius}].ID}"
               /varset CombatTargetID ${NearestSpawn[npc radius ${GuardRadius}].ID}
               /call ExecCommand EventGuard ${NearestSpawn[npc radius ${GuardRadius}].CleanName}
            }
         }
      }
      /return
   }
   /if (${Toggle-guard}) /call ExecCommand guard off
   /if (${advpath}) /call AdvPathPoll
   /if (${Afollow} && !${NearestSpawn[${FollowTarget} radius FollowDistanceini].ID}) {
      /call MoveTo "${FollowTarget}"
   }
/return

||||||||||||Command-subs

Sub Command-accept
   /squelch /target clear
   /invite
/return

Sub Command-reject
   /squelch /target clear
   /disband
/return

Sub Command-afk
   /if (!${Defined[Param0]}) {
      /afk
   } else {
      /afk ${CommandParam}
   }
   /call ChatOut 3 "Going afk."
/return

Sub Command-anchor
   /if (!${IsAnchored}) {
      /varset IsAnchored 1
      /varset AnchorLoc ${Me.Y},${Me.X}
      /varset Afollow 0
      /varset FollowTarget NULL
      /if (${advpath} && ${FollowFlag}) /call StopFunction
      /keypress left
      /keypress right
      /call ChatOut 5 "Created anchor at Loc: ${AnchorLoc}."
      /return
   }
   /if (${IsAnchored}) {
     /varset IsAnchored 0
     /call ChatOut 5 "Removed Anchor."
   }
/return

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

Sub Command-assist(string AssistName)
   /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 "I failed to get a target."
   } else {
      /call ChatOut 5 "My target is now ${Target.CleanName}."
      /varset CombatTargetID ${Target.ID}
      /if (${Toggle-petona}) {
         /if (${Me.Sitting}) /Stand
         /call Delay 5
         /pet attack
         /call Delay 5
         /if (${Toggle-sitaftercast} && ${Me.Standing}) /varset SitTimer ${DelayBeforeSit}
      }
   }
   /call ExecCommand assistcall
/return

Sub Command-autoinv
   /autoinventory
/return

Sub Command-camp
   /dismount
   /varset Afollow 0
   /if ((${advpath})&&(${FollowFlag})) /call StopFunction
   /varset FollowTarget NULL
   /keypress left
   /keypress right
   /call ChatOut 3 "Camping out."
   /if (${Me.Standing}) /Sit
   /camp desktop
/return

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

Sub Command-cmds
  /if (${Defined[Param0]} && ${SectionsList.Find[${Param0}]}) {
      /call ChatOut 2 "${cmds-${Param0.Left[1].Upper}${Param0.Right[-1].Lower}}"
      /return
  } else {
      /call ChatOut 3 "Must specify one of ${SectionsList}"
  }
/return

Sub Command-consent(string TargetName)
   /if (!${Defined[TargetName]}) {
      /call Assist "${MasterName}"
      /varset CommandParam ${Target.CleanName}
      /consent ${Target.CleanName}
   } else /if (${TargetName.Equal[me]}) {
      /call ChatOut 3 "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 "I gave consent to ${CommandParam}"
/return

Sub Command-dismount
   /dismount
   /call ChatOut 5 "I got off my mount."
/return

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

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

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

Sub Command-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 Command-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 Command-face
   /call StandardTarget "${CommandParam}"
   /call ChatOut 5 "Facing ${Target.CleanName}."
   /if (${Me.Sitting}) /Stand
   /call Delay 5
   /face
/return

Sub Command-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}
   }
   /if (${Spawn[${FollowTarget}].ID}) {
      /call ChatOut 5 "I am now following ${Spawn[${FollowTarget}].CleanName}."
   } else {
      /call ChatOut 5 "Unable to follow ${FollowTarget}."
      /call StopFunction
      /varset Afollow 0
      /return
   }
   /if (${followmode}==1) {
      /varset Afollow 1
   }
   /if (${followmode}==2) {
      /call FollowFunction "${Spawn[${FollowTarget}].CleanName}"
   }
   /if (${followmode}==3) {
      /follow
   }
/return

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

Sub Command-group
   /if (!${Defined[Param0]}) {
      /return
   } else {
      /g ${CommandParam}
   }
/return

Sub Command-invite(string TargetName)
   /if (!${Defined[TargetName]}) {
      /call Assist "${MasterName}"
	  /if (${Target.Type.Upper.Equal[PC]}) {
	     /varset TargetName ${Target.Name}
      } else {
	     /call ChatOut 3 "Cannot Invite ${Target.CleanName}."
		 /return
      }
   } else /if (${TargetName.Lower.Equal[me]}) {
      /varset TargetName ${MasterName}
   } else /if (${TargetName.Lower.Equal[yourself]}) {
      /return
   } else /if (${TargetName.Equal[${Me.CleanName}]}) {
      /return
   } 
   /call ChatOut 3 "Inviting ${TargetName}."
   /invite ${TargetName}
/return

Sub Command-lootall
   /declare DeadCount int local
   /declare si int local
   /varset CorpseList
   /if (${Me.Combat}) {
      /call ChatOut 5 "I'm busy fighting right now.  Ask me to loot again later!"
      /return
   }
   /varset DeadCount ${SpawnCount[corpse radius ${CorpseRadius}]}
   /if (!${DeadCount}) {
      /call ChatOut 5 "No corpses within range to loot."
      /return
   }
   /for si 1 to ${DeadCount}
      /call ListAppendElement 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 Command-lootup
   /if (${Me.Combat}) {
      /call ChatOut 6 "I'm busy fighting right now.  Ask me to loot again later!"
      /return
   }
   /if (${Defined[Param0]}) {
      /call Target "corpse ${CommandParam}"
   }
   /call Loot
/return

Sub Command-mount
   /declare GenString local string
   /varset GenString " item alt spell slot "
   /if (${Me.Sitting}) /stand
   /if (!${GenString.Find[ ${MountItem.Arg[1].Arg[1,-]} ]}) /varset MountItem item ${MountItem}
   /call AddCast "${MountItem}" "0" buff
   /call ChatOut 5 "Summoning my mount."
/return

Sub Command-moveto
   /if (!${CommandParam.Find[,]}) {
      /if (${movetomode}==1) {
         /call MoveTo "${CommandParam}"
      }
      /if (${movetomode}==2) {
         /call GotoFunction "${CommandParam.Arg[1,]}" "${CommandParam.Arg[2,]}"
      }
      /return
   }
   /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]} || ${TargetName.Equal[${Me.CleanName}]}) {
      /return
   } else {
      /if (${Spawn[${CommandParam}].ID}) /call ChatOut 3 "Destination for moveto not recognized.  Try a pc or npc name, or a loc in the form: y,x, such as -100,300"
      /return
   }
   /if (${movetomode}==1) {
      /call MoveTo "${CommandParam}"
   }
   /if (${movetomode}==2) {
      /call GotoFunction "${Spawn[${CommandParam}].Y}" "${Spawn[${CommandParam}].X}" "${Spawn[${CommandParam}].Z}"
   }
/return

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

Sub Command-notarget
   /squelch /target clear
/return

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

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

Sub Command-petback
   /pet back off
/return

Sub Command-petguard
   /pet guard here
/return

Sub Command-random
   /if (!${Defined[Param0]}) /return
   /if (!${Defined[Param1]}) {
      /random ${Param0}
   } else {
      /random ${Param0} ${Param1}
   }
/return

Sub Command-reload
   /call ChatOut 5 "Reload initiated."
   /mac genbot
/return

Sub Command-rmod(int RangeMod)
   /if (!${Defined[RangeMod]}) /return
   /varcalc MeleeRange ${MeleeRange}+${RangeMod}
   /call ChatOut 3 "New melee range is ${MeleeRange}"
/return

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

Sub Command-run
   /keypress ctrl+r
/return

Sub Command-say
   /if (!${Defined[Param0]}) {
      /return
   } else {
      /say ${CommandParam}
   }
/return

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

Sub Command-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 "${Param0} is now equal to ${${Param0}}"
/return

Sub Command-sit
   /varset Afollow 0
   /varset FollowTarget NULL
   /if ((${advpath})&&(${FollowFlag})) /call StopFunction
   /if (${Me.Standing}) /sit
/return

Sub Command-stand
   /if (${Me.Sitting}) /Stand
/return

Sub Command-stay
   /varset Afollow 0
   /varset MoveToDest
   /varset FollowTarget NULL
   /if ((${advpath})&&(${FollowFlag})) /call StopFunction
   /keypress DOWN
   /keypress left
   /keypress right
/return

Sub Command-stop
   /if (${Me.Mount.ID}) /dismount
   /varset CombatTargetID 0
   /varset LootTooFar 1
   /varset Afollow 0
   /varset MoveToDest
   /varset CastQueue
   /if (${advpath}) /call StopFunction
   /varset FollowTarget NULL
   /call ChatOut 5 "Stopping."
   /keypress left
   /keypress right
   /keypress DUCK
   /keypress DUCK
   /keypress forward
   /keypress back
   /squelch /target clear
   /keypress right
/return

Sub Command-target
   /call StandardTarget "${CommandParam}"
   /call ChatOut 5 "My target is now ${Target.CleanName}."
/return

Sub Command-tell
   /if (!${Defined[Param0]}) {
      /return
   } else {
      /tell ${CommandParam}
   }
/return

Sub Command-trade
   /call ChatOut 5 "Clicking trade."
   /notify TradeWnd TRDW_Trade_Button LeftMouseUp
   /call Delay 3
/return

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

Sub Command-yesres
   /call ChatOut 5 "Clicking yes for res."
   /notify ConfirmationDialogBox Yes_Button leftmouseup
   /call Delay 3
/return


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

Sub Assist(string sAssistName)
   /squelch /target clear
   /if (${DebugList.Find[core]}) /echo /assist ${sAssistName}
   /assist ${sAssistName}
   /delay 2s ${Target.ID}
   /if (!${Target.ID}) /call ChatOut 3 "Unable to /assist ${sAssistName}."
/return

Sub ChatOut(int ChatPriority,string ChatText)
   /declare GenFor int local

   /if (${ChatPriority}>${Verbosity}) /return
   /if (${Macro.Params}>2) {
      /for GenFor 2 to ${Math.Calc[${Macro.Params}-1]}
         /varset ChatText ${ChatText} ${Param${GenFor}}
      /next GenFor
   }
   /if (${MasterName.Equal[GROUP]}) {
      /gsay ${ChatText}
      /return
   }
   /if (${TalkToSelf}) {
      /echo ${ChatText}
      /return
   }
   /if (${ChatIn.Equal[tell]}) {
      /if (${ChatOutTimer}) /delay ${ChatOutTimer}
      /varset ChatOutTimer 20
      /tell ${MasterName} ${ChatText}
   } else /if (${ChatIn.Equal[Group]}) {
      /gsay ${ChatText}
   } else /if (${ChatIn.Equal[Raid]}) {
      /rsay ${ChatText}
   } else /if (${ChatIn.Equal[Say]}) {
      /if (${ChatOutTimer}) /delay ${ChatOutTimer}
      /varset ChatOutTimer 20
      /say ${ChatText}
   } else /if (${ChatIn.Equal[Channel]}) {
      /if (${ChatOutTimer}) /delay ${ChatOutTimer}
      /varset ChatOutTimer 20
      /chat #${ChatInChannel} ${ChatText}
   } else /if (${ChatIn.Equal[IRC]}) {
      /i say ${ChatText}
   }
/return

Sub ExecCommand(string CommandText)
   /declare GenFor int local
   /declare GenStr string local
   /declare DidThenClause bool local 0
   /declare ElseClause string local

   /if (${Macro.Params}>1) {
      /for GenFor 1 to ${Math.Calc[${Macro.Params}-1]}
         /varset CommandText ${CommandText} ${Param${GenFor}}
      /next GenFor
   }
   /if (${CommandText.Left[3].Lower.Equal[/if]}) {
      /if (${CommandText.Find[/else]}) {
         /varset ElseClause ${CommandText.Right[-${Math.Calc[${CommandText.Find[/else ]}+5]}]}
         /varset CommandText ${CommandText.Left[${Math.Calc[${CommandText.Find[/else ]}-1]}]}
         /docommand ${CommandText}
         /if (!${DidThenClause}) {
            /call ExecCommand "${ElseClause}"
         }
      } else {
         /docommand ${CommandText}
      }
      /return
   }
   /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-Routines]}) {
   /varset GenStr |${cmds-Routines.Lower}|
      /if (${GenStr.Find[ ${CurrCommand.Lower}|]}) {
         /echo doing routines ${CommandText}
         /call Routine "${CommandText}"
         /return
      }
   }

   /if (${Defined[cmds-Shortcuts]}) {
      /varset GenStr |${cmds-Shortcuts.Lower}|
      /if (${GenStr.Find[|${CurrCommand.Lower}|]}) {
         /echo doing ShortCut ${CommandText}
         /call ShortCut "${CommandText}"
         /return
      }
   }

   /if (${Defined[Toggle-${CurrCommand.Lower}]}) {
         /echo doing Toggle ${CurrCommand} ${CommandParam}
      /call SetToggle ${CurrCommand.Lower} ${CommandParam}
      /return
   }

   /for GenFor 1 to ${Math.Calc[${SectionsList.Count[ ]}+1]}
      /if (${SectionsList.Arg[${GenFor}].NotEqual[Shortcuts]} && ${SectionsList.Arg[${GenFor}].NotEqual[Shortcuts]}) {
         /varset GenStr |${cmds-${SectionsList.Arg[${GenFor}]}}|
		 /if (${GenStr.Find[|${CurrCommand}|]}) {
            /echo doing Command ${CurrCommand} ${CommandParam}
            /call Command-${CurrCommand} ${CommandParam}
            /return
         }
      }
   /next GenFor

/return

sub Loot
   /declare GenFor int local
   /declare LootSlot int local 1
   /if (${Me.Combat}) /return
   /if (!${Target.ID}) /squelch /target corpse radius ${CorpseRadius}
   /if (${Target.Type.NotEqual[corpse]}) /return
   :MoveToCorpse
   /call MoveTo "${Target.Y},${Target.X}"
   /if (${Spawn[${MoveToDest}].Type.Equal[corpse]}) /goto :MoveToCorpse
   /squelch /face
   /varset LootTooFar 0
   /lootn never
   /loot
   /varset GenFor 0
   :CoreWaitLoot
      /call Delay 5
      /doevents chat
      /varcalc GenFor ${GenFor}+1
      /if (${GenFor}>12) /goto :donelooting
   /if (!${Corpse.Items}) /goto :CoreWaitLoot
   /delay 2s
   /call ChatOut 5 "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
      /if (${LootSlot}>31) /varset LootSlot 1
      /doevents chat
      /if (${Cursor.ID}) /autoinv
   /goto :lootloop
   :donelooting
   /lootn always
   /notify LootWnd DoneButton leftmouseup
   /delay 2s ${Me.Standing}
/return

Sub MoveTo
   /if (${Defined[Param0]}) {
      /varset MoveToDest ${Param0}
      /if (${MoveToDest.Equal[me]}) /varset MoveToDest ${Spawn[pc ${MasterName}].ID}
      /if (${Defined[Param1]}) {
         /varset MoveToRange ${Param1}
      } else {
         /varset MoveToRange ${AnchorRadius}
      }
   }
   /if (${CastStep}) /return
   /if (!${Me.Standing}) /stand
   /declare MoveDist int local
   /declare DistGoal int local
   /declare CheckObstacle int local 0
   /varset LastLoc ${Me.Y},${Me.X}
   :MoveLoop
      /if (${MoveToDest.Find[,]}) {
         /face nolook loc ${MoveToDest}
         /varset DistGoal ${AnchorRadius}
         /varcalc MoveDist ${Math.Distance[${MoveToDest}]}
      } else /if (!${Spawn[${MoveToDest}].ID} || ${Spawn[${MoveToDest}].ID}==${Me.ID} || ${MoveToDest.Find[Null]}) {
         /varset MoveToDest
         /return
      } else {
         /squelch /face fast id ${Spawn[${MoveToDest}].ID}
         /varset DistGoal ${MeleeRange}
         /varcalc MoveDist ${Math.Distance[${Spawn[${MoveToDest}].Y},${Spawn[${MoveToDest}].X}]}
      }
      /if (${MoveDist}>${DistGoal}) {
         /keypress forward hold
      } else {
         /if (${MoveToDest.Equal[${CombatTargetID}]} && ${MoveDist}<${MeleeRange}-5) {
            /keypress back hold
            /delay 5 (${Math.Distance[${Spawn[${MoveToDest}].Y},${Spawn[${MoveToDest}].X}]}>${MeleeRange}-2)
            /keypress back
         }
         /keypress forward
         /if (${MoveToDest.Equal[${AnchorLoc}]}) {
            /face nolook away loc ${AnchorLoc}
            /keypress Home
         }
         /varset MoveToDest
         /return
      }
      |/if (!${CheckObstacle.OriginalValue}) /varset CheckObstacle 3
      /varcalc CheckObstacle ${CheckObstacle}+1
      /if (${CheckObstacle}>5) {
         /varset CheckObstacle 0
         /if (${Math.Distance[${LastLoc}:${Me.Y},${Me.X}]}<0.1) {
            /call Hitobst 5
            /return
         }
         /if (${MoveDist}-${Math.Distance[${LastLoc}:${Me.Y},${Me.X}]}>${DistGoal}+100) {
            /return
         }
         /varset LastLoc ${Me.Y},${Me.X}
      }
   /goto :MoveLoop
/return

Sub Hitobst(int HoldTime)
   /if (!${Me.Speed}) {
      /keypress forward
      /return
   }
   /keypress forward
   /keypress back hold
   /delay 2s
   /keypress back
   /if (${Math.Rand[2]}) {
      /keypress right hold
      /delay ${HoldTime}
      /keypress right
   } else {
      /keypress left hold
      /delay ${HoldTime}
      /keypress left
   }
   /keypress forward hold
   /delay 2s
   /keypress forward
   /keypress left
   /keypress right
/return

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

Sub Target(string sTargetName)

   | Check if intended target already targetted.
   /if (${Target.ID} && ${Spawn[${sTargetName}].ID}==${Target.ID} && (!${Spawn[pc ${sTargetName}].ID} || ${Target.Type.Equal[pc]})) /return
   /squelch /target clear
   /if (${Spawn[pc ${sTargetName} radius ${MaxTargetRange}].ID}) {
      /squelch /target pc ${sTargetName} radius ${MaxTargetRange}
   } else {
      /squelch /target ${sTargetName} radius ${MaxTargetRange}
   }
   /delay 2s ${Target.ID}
   /if (!${Target.ID}) /echo Unable to locate target ${sTargetName}.
/return

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

Sub ListReplacebyArg(string sList,string sElement,string sArg,string sDiv)
   /if (!${Defined[sDiv]}) /declare sDiv string local |
   /varset ${sList} ${sDiv}${${sList}}${sDiv}${sDiv}
   /declare sright int local
   /declare sleft int local
   /declare splaceholder string local ${${sList}}
   /varset splaceholder ${splaceholder.Arg[${sArg},${sDiv}]}
   /varcalc sleft  ${${sList}.Find[${sDiv}${splaceholder}${sDiv}]}
   /varset splaceholder ${splaceholder}${sDiv}
   /varcalc sright ${sleft}+${splaceholder.Length}
   /varset ${sList} ${${sList}.Left[${sleft}]}${sElement}${sDiv}${${sList}.Right[-${sright}]}
   /varset ${sList} ${${sList}.Left[-2].Right[-1]}
   /if (${DebugList.Find[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}+${oldElement.Length}
         /varset ${sList} ${${sList}.Left[${sleft}]}${newElement}${${sList}.Right[-${sright}]}
         /varset ${sList} ${${sList}.Left[-2].Right[-1]}
      } else {
         /if (${DebugList.Find[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 (${DebugList.Find[core]}) /echo List ${${sList}}  TO Delete: ${sName}
   /if (!${Defined[sDiv]}) /declare sDiv string local |
   /varset ${sList} ${sDiv}${${sList}}${sDiv}${sDiv}
   /declare sright int local
   /declare sleft int local
   /declare splaceholder string local ${sDiv}${${sList}}${sDiv}
   /varcalc sleft  ${splaceholder.Find[${sDiv}${sName}${sDiv}]}-1
   /varset splaceholder ${sName}${sDiv}
   /varcalc sright ${sleft}+${splaceholder.Length}
   /varset ${sList} ${${sList}.Left[${sleft}]}${${sList}.Right[-${sright}]}
   /varset ${sList} ${${sList}.Left[-2].Right[-1]}
   /if (${DebugList.Find[core]}) /echo List ${${sList}}  Deleted: ${sName}
/return

Sub ListAppendElement(string sList,string sElement,string sDiv)
   /if (!${Defined[sDiv]}) /declare sDiv string local |
   /if (${${sList}.Length}) {
      /varset ${sList} ${${sList}}${sDiv}${sElement}
   } else {
      /varset ${sList} ${sElement}
   }
   /if (${DebugList.Find[core]}) /echo List ${${sList}}  Added: ${sElement}
/return


Sub ListPrependElement(string sList,string sElement,string sDiv)
   /if (!${Defined[sDiv]}) /declare sDiv string local |
   /if (${${sList}.Length}) {
      /varset ${sList} ${sElement}${sDiv}${${sList}}
   } else {
      /varset ${sList} ${sElement}
   }
   /if (${DebugList.Find[core]}) /echo List ${${sList}}  Added: ${sElement}
/return

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


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

Sub Event_Appear
   /call ExecCommand EventLostInvis
/return

Sub Event_Appearing
   /call ExecCommand EventLoosingInvis

/return

Sub Event_Chat(string ChatType,string ChatSender,string ChatText)
   /declare GenString string local
   /varset ChatType ${ChatType.Lower}
   /if (!${ChatType.Equal[group]} && !${ChatType.Equal[${listenchan}]}&& !${ChatType.Equal[tell]}) {
      /return
   }
   /if (${ChatType.Equal[group]} && !${Toggle-listengroup}) /return
   /if (${ChatType.Equal[${listenchan}]} && !${Toggle-listenchat}) /return
   /if (${ChatType.Equal[${listenchan}]} || ${ChatType.Equal[group]}) {
      /if (${ChatText.Arg[1].Equal[${Me.CleanName}]}) {
         /declare NameLength int local ${Me.CleanName.Length}
         /varcalc NameLength ${NameLength}+1
         /varset ChatText ${ChatText.Right[-${NameLength}]}
      } else {
         /if (${Toggle-checkname}) /return
         /varset GenString |${IgnGroupList}|
         /if (${GenString.Find[|${ChatText.Arg[1]}|]}) /return
      }
   }
   /if (${MasterList.Lower.Find[${ChatSender.Lower}]}) {
      /varset MasterName ${ChatSender}
      /varset TalkToSelf 0
      /call ExecCommand "${ChatText}"
      /return
   }
   /if (${Toggle-relaytells} && ${ChatType.Equal[TELL]}) {
      /if (${Spawn[npc ${ChatSender} radius 100].ID} || ${Spawn[${ChatSender}].Master.ID}==${Me.ID}) /return
      /call ChatOut 1 "${ChatSender} told me: ${ChatText}"
   }
/return

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

Sub Event_EscKey
   /call Command-stop
/return

Sub Event_ExpGained
   /call ExecCommand EventExpGained
/return

Sub Event_FollowOff
   /squelch /target clear
   /call ChatOut 5 "Auto follow Off."
/return

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

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

Sub Event_ImDead
   /call ExecCommand EventImDead
/return

Sub Event_Invite
   /if (${MasterList.Lower.Find[${Param1.Lower}]}) {
      /call Command-accept
   } else {
      /call ChatOut 6 "${Param1} has invited me to join his group."
      /call ChatOut 9 "Let me know if I should 'accept' or 'reject' his invitation."
   }
/return

Sub Event_IRCSAY(string IRCText,string IRCSender)
   /if (${MasterList.Find[${IRCSender.Lower}]}) {
      /declare NameLength int local ${IRCSender.Length}
      /varcalc NameLength ${NameLength}+2
      /varset IRCText ${IRCText.Right[-${NameLength}]}
      /if (${IRCText.Arg[1].Equal[${Me.CleanName}]}) {
         /varset NameLength ${Me.CleanName.Length}
         /varcalc NameLength ${NameLength}+1
         /varset IRCText ${IRCText.Right[-${NameLength}]}
      }
      /varset MasterName ${IRCSender}
      /call ExecCommand "${IRCText}"
      /return
   }
/return

Sub Event_IRCMSG(string IRCText,string IRCSender,string Command)
   /if (${MasterList.Lower.Find[ ${IRCSender.Lower} ]}) {
      /varset MasterName ${IRCSender}
      /call ExecCommand "${Command}"
   }
/return

Sub Event_LosingLev
   /call ExecCommand EventLoosingLevitate
/return

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

Sub Event_timer(string TimerName,string OldValue)
   /if (${TimerName.Arg[1,-].Equal[ST]}) {
      /if (${DebugList.Find[core]}) /echo ${Me.Name} Calling subroutine ${TimerName.Right[-3]}
      /vardata SubCallName TimerName.Right[-3]
      /if (${SubCallName.Find[-]}) /call StringReplaceAll SubCallName "-" " "
      |/if (${DebugList.Find[core]}) /echo ${Me.Name} Calling subroutine ${SubCallName}
      /call ${SubCallName}
   }
   /if (${TimerName.Equal[SitTimer]}) {
      /if (${Me.Standing} && !${CastStep} && !${Me.Speed}) {
         /sit
      } else {
         /varset SitTimer 2s
      }
   }
   /if (${TimerName.Equal[ChainStunTime]}) {
      /call NextStun
   }
/return

Sub Event_Zoned
   /varset IsAnchored 0
   /keypress forward
   /call ExecCommand EventZoned
/return

Sub Event_AltTell(string line, string sender, string text)
   /call Event_Chat TELL "${sender}" "${text.Left[-1]}"
/return
Last edited by ascii38 on Mon Oct 17, 2005 4:51 pm, edited 1 time in total.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:12 pm

botcombat.inc

Code: Select all

|botcombat.inc
|Bot combat module.
|Version 13.3.3
|Date:08/24/2004
|
||**
[botcombat]
version=13.3.3
**||

#event Attacking       "You pierce #*#"
#event Attacking       "You slash #*#"
#event Attacking       "You Hit #*#"
#event Attacking       "You Bash #*#"
#event ArcheryTooFar   "Your target is too far away, get closer"
#event DisarmTrap      "You have disarmed #*#"
#event Enraged         "#*#|${Spawn[id ${CombatTargetID}].CleanName.Right[${Math.Calc[${Spawn[id ${CombatTargetID}].CleanName.Length}-1]}]}| has become ENRAGED#*#"
#event FoundFloorTrap  "You sense a trap in this direction."
#event FoundBoxTrap    "You are certain that #*#"
#event UnderAttack     "#1#YOU for #*#"
#event UnderAttack     "#1#to#*#YOU, but #*#"
#event MobGate         "#*#|${Spawn[${CombatTargetID}].CleanName}| Gates.#*#"
#event Offrage         "#*#|${Spawn[id ${CombatTargetID}].CleanName.Right[${Math.Calc[${Spawn[id ${CombatTargetID}].CleanName.Length}-1]}]}| is no longer enraged#*#"


Sub Init-Combat

   /call AddCommands attack behind disc getbehind hide noattack shield sneak

|Declare Variables
   /declare EnrageVar bool outer FALSE

|Timers
   /declare TauntDiscTimer timer outer

|Load settings

   /call AddToggle archery    off   return "Archery is set to off." "Archery is set to on."
   /call AddToggle autobehind off   return "I won't position myself behind the mob." "I will position myself behind the mob."
   /call AddToggle autoengage on    return "I will not engage when attack is on." "I will engage when attack is on."
   /call AddToggle bash       off    return "Auto Bash is now off." "Auto Bash is now on."
   /call AddToggle backstab   off    return "Auto Backstab is now off." "Auto Backstab is now on."
   /call AddToggle disarm     off    return "Auto Disarm is now off." "Auto Disarm is now on."
   /call AddToggle evade      off    return "Auto Evade is now off." "Auto Evade is now on."
   /call AddToggle flyingkick off    return "Auto FlyingKick is now off." "Auto FlyingKick is now on."
   /call AddToggle frenzy     off    return "Auto Frenzy is now off." "Auto Frenzy is now on."
   /call AddToggle kick       off    return "Auto Kick is now off." "Auto Kick is now on."
   /call AddToggle slam       off    return "Auto Slam is now off." "Auto Slam is now on."
   /call AddToggle taunt      off    return "Auto Taunt is now off." "Auto Taunt is now on."
   /call AddToggle puller     noini return "I'm not the puller." "I'm the puller."
   /call AddToggle petona off return "I won't send pet in on assist." "I will send pet in on assist."
   /call AddToggle tauntdisc     off    return "I won't use the @{WarTauntDisc} discipline when in combat." "I will use the @{WarTauntDisc} discipline when in combat."
   /call LoadSetting WarTauntDisc string WarTauntDisc incite
   /call AddToggle guard     noini    return "I will not defend this area from intruders." "I will defend this area from intruders." callsub
   /call LoadSetting GuardRadius int GuardRadius 50
   /call AddToggle defend     off   return "I will not defend myself if atttacked." "I will defend myself if atttacked."
   /call AddToggle protect   off    return "I will not protect @{MasterName}." "I will protect @{MasterName} ."
   /call LoadSetting ProtectList string ProtectList ${MasterList}
   /call LoadSetting NeverKill string NeverKill "things you never want to attack separated by |"
   /call LoadSetting MeleeRadius int ProtectOrDefendCheckRadius 50
   /call AddToggle melee     off    return "I will not close to do melee when in combat." "I will close and do melee when in combat."
   /call LoadSetting MeleeRange int MeleeRange 12
   /call LoadSetting MeleeMaxRadius int MeleeMaxRadius 100

| Shortcuts   
   /call LoadSetting EventDefend event EventDefend "/botsay I've been attacked by NameS!  Attacking right back!"
   /call LoadSetting EventGuard event EventGuard "/botsay Intruder alert!  Attacking the trespassing NameS!"
   /call LoadSetting EventAttacked event EventAttacked "None"
   /call LoadSetting EventProtect event EventProtect "/botsay How dare NameS attack my master?!  I must punish this insolence!"

/return

Sub CombatMain
   /call Combatcheck
   /if (!${CombatTargetID}) /return
   /if (${Toggle-melee}) {
      /if (!${Me.Combat} && ${Target.Distance}<${Spawn[${CombatTargetID}].MaxRangeTo}) /attack on
      /if (!${MoveTo.Length}) /call MoveTo ${CombatTargetID} ${MeleeRange}
      /call MeleeAbility
   }
   /if (${Toggle-archery}) {
      /squelch /face fast
      /range
   }
/return

||||Do Subs
Sub Command-attack
   /call StandardTarget "${CommandParam}"
   /if (!${Target.Type.Equal[NPC]} && !${Target.Master.Type.Equal[NPC]}) {
      /varset CombatTargetID 0
      /return
   }
   /varset CombatTargetID ${Target.ID}
   /if (!${Me.Standing}) /stand
   /call ChatOut 5 "Attacking ${Target.CleanName}."
/return

Sub Command-behind
   /if (!${Target.ID}) {
      /call Assist "${MasterName}"
      }
   :behind
   /if (!${Target.ID}) /return
   /call MoveTo ${CombatTargetID}
  | ----- 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 Command-disc
   /if (!${Defined[Param0]}) /return
     /disc ${Param0}
/return

Sub Command-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
   /squelch /face fast
:noneed
/keypress FORWARD
/return

Sub Toggle-guard
   /if (${CommandParam.Equal[${Int[${CommandParam}]}]}) {
      /varset DoGuard 1
      /varset GuardRadius ${CommandParam}
   }
   /if (${DoGuard}) {
      /if (!${IsAnchored}) /call ExecCommand anchor
   }
/return

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

|Sub ProtectToggle
|   /if (${CommandParam.Equal[none]}) {
|      /varset DoGuard 1
|      /varset GuardRadius ${CommandParam}
|   }
|   /if (${DoGuard}) {
|      /if (!${IsAnchored}) /call Command-anchor
|   }
|/return

Sub Command-noattack
   /varset CombatTargetID 0
/return

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

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

||||| Called Subs

Sub bsclock
   /if (!${Target.ID}) /return
   /if (!${Me.Standing}) {
      /stand
      /delay 3
   }
   /keypress strafe_left hold
   :MoreClock
   /if (${Toggle-backstab} && ${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}<15) {
      /squelch /face fast
      /doability "Backstab"
   }
   /if (!${Target.ID}) {
      /keypress strafe_left
      /return
   }
   /if (${Target.Distance}>20) {
      /keypress strafe_left
      /call MoveTo ${CombatTargetID}
      /return
   }
   /if (${Target.Distance}<4) {
      /keypress strafe_left
      /call MoveTo ${CombatTargetID}
      /return
   }
   /squelch /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
   /squelch /face fast
/return

Sub bscounter
   /if (!${Target.ID}) /return
   /if (!${Me.Standing}) {
      /stand
      /delay 3
   }
   /keypress strafe_right hold
   :MoreCounter
   /if (${Toggle-backstab} && ${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}<15) {
      /squelch /face fast
      /doability "Backstab"
   }
   /if (!${Target.ID}) {
      /keypress strafe_right
      /return
   }
   /if (${Target.Distance}>20) {
      /keypress strafe_right
      /call MoveTo ${CombatTargetID}
      /return
   }
   /if (${Target.Distance}<4) {
      /keypress strafe_right
      /call MoveTo ${CombatTargetID}
      /return
   }
   /squelch /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
   /squelch /face fast
/return

Sub CheckPuller
   /declare AggTemp bool local
   /if (!${Toggle-puller}) /return
   /if (${Math.Distance[${AnchorLoc}]}<=${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]}) {
      /varset CombatTargetID 0
      /varset AggTemp ${Toggle-defend}
      /varset Toggle-defend 0
      /call MoveTo "${AnchorLoc}"
      /varset Toggle-defend ${AggTemp}
    }
/return

|Combatcheck
|Used to check if attack is on and should not be.
|Usage /call Combatcheck.
Sub Combatcheck
   /call CheckNeverKill
   /if (!${Spawn[id ${CombatTargetID}].Type.Equal[npc]} && !${Spawn[id ${CombatTargetID}].Master.Type.Equal[npc]}) {
      /varset CombatTargetID 0
      /attack off
      /return
   }
   /if (${Spawn[id ${CombatTargetID}].Distance}>${MeleeMaxRadius}) {
      /call ChatOut 5 "Combat Target is out of range!"
      /varset CombatTargetID 0
      /attack off
      /return
   }
   /if (${CastStep}) /return
   /if (${Target.ID}!=${CombatTargetID}) /call Target "id ${CombatTargetID}"
   /if (${EnrageVar}) /return
   /if (${Toggle-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 Command-behind
/return

Sub CheckNeverKill(int CheckID)
   /declare GenFor int local
   /if (!${Defined[CheckID]}) /declare CheckID int local ${CombatTargetID}
   /if (${NeverKill.Equal[${NeverKill-DefaultValue}]}) /return 1
   /for GenFor 1 to ${Math.Calc[${NeverKill.Count[|]}+1]}
      /if (${Spawn[${CheckID}].CleanName.Find[${NeverKill.Arg[${GenFor},|]}]}) {
         /if (${CombatTargetID}==${CheckID}) /varset CombatTargetID 0
         /return 0
      }
   /next GenFor
/return 1

| IsAggroed
| Used for checking if an NPC is attacking.someone.  Default PC is master
|Usage /call CheckIsLookingAt "id of mob to check" "id of PC to check"
Sub CheckIsLookingAt(int MobID,int PCID)
   /declare MobHeading int local 0
   /declare HeadingToPC int local
   /declare DeltaX local float
   /declare DeltaY local float
   /declare HeadingDelta local float
   /if (!${Defined[PCID]}) /varset PCID ${Spawn[${MasterName}].ID}
   /if (${Spawn[id ${MobID}].ID}) {
      /varcalc MobHeading ${Spawn[id ${MobID}].Heading.Degrees}
      /varcalc DeltaX ${Spawn[id ${PCID}].X}-${Spawn[id ${MobID}].X}
      /varcalc DeltaY ${Spawn[id ${PCID}].Y}-${Spawn[id ${MobID}].Y}
      /if (${DeltaX}>0) {
         /varcalc HeadingToPC ${Math.Atan[${DeltaY}/${DeltaX}]}+270
      } else /if (${DeltaX}<0) {
         /varcalc HeadingToPC ${Math.Atan[${DeltaY}/${DeltaX}]}+90
      } else {
         /if (${DeltaY}>0) {
            /varcalc HeadingToPC 90
         } else {
            /varcalc HeadingToPC 270
         }
      }
      /varcalc HeadingDelta ${Math.Abs[${HeadingToPC}-${MobHeading}]}
      |/echo DeltaY ${DeltaY} DeltaX ${DeltaX}  Atan ${Math.Atan[${DeltaY}/${DeltaX}]}
      /echo Mob ${Spawn[id ${MobID}].Name} MobHeading ${MobHeading} HeadingToPC ${HeadingToPC} HeadingDelta ${HeadingDelta}
      /if (${HeadingDelta}<4 || ${HeadingDelta}>356) {
         /return 1
      }
   }
/return 0


|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 (${Toggle-slam}) {
         /squelch /face fast
         /doability "Slam"
      }
      /if (${Toggle-bash}) {
         /squelch /face fast
         /doability "Bash"
      }
      /if (${Toggle-backstab} && ${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.Degrees}]}*10]},${Math.Calc[${Target.X}+${Math.Sin[${Target.Heading.Degrees}]}*10]}]}<15) {
         /squelch /face fast
         /doability "Backstab"
      }
      /if (${Toggle-frenzy}) {
         /squelch /face fast
         /doability "Frenzy"
      }
      /if (${Toggle-kick}) {
         /squelch /face fast
         /doability "Kick"
      }
   }
   /if (${Toggle-evade} && ${Me.AbilityReady[Hide]}) {
      /attack off
      /delay 1
      /doability "Hide"
      /attack on
   }
   /if (${Toggle-taunt} && ${Me.AbilityReady[Taunt]}) {
      /doability "Taunt"
   }
   /if (${Toggle-flyingkick} && ${Me.AbilityReady[Flying Kick]}) {
      /squelch /face fast
      /doability "Flying Kick"
   }
   /if (${Toggle-disarm} && ${Me.AbilityReady[Disarm]}) {
      /squelch /face fast
      /doability "Disarm"
   }
   /if (${Toggle-tauntdisc} && !${TauntDiscTimer}) {
      /squelch /face fast
      /disc ${WarTauntDisc}
      /varset TauntDiscTimer 30s
   }
/return

||||| Events


Sub Event_ArcheryTooFar
/return

Sub Event_Attacking
   /call CheckPuller
/return

Sub Event_DisarmTrap
   /call Delay 2s
   /call ChatOut 5 "Trap disarmed."
/return

Sub Event_Enraged
   /if (${Target.ID}) {
      /if (${CombatTargetID}) /varset EnrageVar ${Target.ID}
      /attack off
      /varset CombatTargetID 0
      /if (${Toggle-petona}) /pet backoff
   }
/return 

Sub Event_MobGate
   /if (${CombatTargetID}) {
      /varset CombatTargetID 0
      /if (${Toggle-petona}) /pet backoff
   }
/return

Sub Event_Offrage
   /if (${Target.ID}) {
      /if (${EnrageVar}) {
         /varset CombatTargetID ${EnrageVar}
         /varset EnrageVar 0
      }
      /varset EnrageVar 0
   }
/return 

Sub Event_UnderAttack(string Line,string Attacker)
   /if (${Attacker.Find[say]} || ${Attacker.Find[group]} || ${Attacker.Find[out of character]} || ${Attacker.Find[shout]} || ${Attacker.Find[guild]} || ${Attacker.Find[MQ2]} || ${Attacker.Find[ healed ]}) /return
   /call CheckPuller
   /declare MobName string local ${Attacker.Left[${Math.Calc[-${Attacker.Arg[${Math.Calc[${Attacker.Count[ ]}]}].Length}-1]}]}
   /if (!${CombatTargetID} && ${Toggle-defend} && ${NearestSpawn[${MobName}].Distance}<${MeleeRadius}) {
      /call CheckNeverKill ${NearestSpawn[MobName].ID}
      /if (${Macro.Return}) {
         /call Target "${MobName}"
         /if (${Target.Type.Equal[NPC]} || ${Target.Master.Type.Equal[npc]}) {
            /varset CombatTargetID ${Target.ID}
            /call ExecCommand EventDefend ${Target.CleanName}
         }
      }
   } else {
      /call ExecCommand EventAttacked ${MobName}
      /if (${SitAfterCast}) /varset SitTimer ${DelayBeforeSit}
   }
/return
Last edited by ascii38 on Mon Oct 17, 2005 4:52 pm, edited 2 times in total.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:13 pm

botspell.inc

Code: Select all

|botspell.inc
|Bot spell module.
|Version 13.3.7
|Date:10/17/2005
|
||**
[botspell]
version=13.3.6
**||

#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!"
#event WornOff "Your #1# spell has worn off of #2#."

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 AddCommands buff chainnuke chainstun evac loadlist
   /call AddCommands mana selfbuff bufflist setlompct sn snt spellgem
|/declare Vars
   /declare BuffPtrList string outer
   /declare BuffSelfIconList string outer
   /declare CastInfo string outer
   /declare CastLastResult string outer
   /declare CastName string outer
   /declare CastOldTargetID int outer
   /declare CastQueue string outer
   /declare CastStep int outer
   /declare CastTarget string outer
   /declare CastType string outer
   /declare ChainStunNum int outer
   /declare DoAgain bool outer FALSE
   /declare LastSn string outer NA
   /declare SpellNeedToRemem bool outer 0

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

|Load Settings
   /call LoadSetting BuffSelfList string SelfBuffList "Buffs you wish to maintain on yourself separated with |"
   /call AddToggle sitaftercast on return "I will no longer sit after casting." "I will now sit after casting."
   /call LoadSetting DelayBeforeSit string DelayBeforeSit 3s
   /call AddToggle canni off return "I won't eat myself for mana." "I will eat myself for mana."
   /call LoadSetting CanniSpell string CanniSpell Cannibalize
   /call LoadSetting CanniLimit string CanniUntilPctHPsLessThan 40
   /call LoadSetting CanniHoT string CanniHealOverTime Quiescence
   /call LoadSetting ChainNuke string ChainNuke "Your Chain Nuke Spells separated with |."
   /call LoadSetting ChainStun string ChainStun "Your Chain Stun Spells separated with |."
   /call LoadSetting DefaultSpellSet string DefaultSpellSet Default
   /call AddToggle dobuff on return "I won't cast buffs until commanded." "I will cast buffs."
   /call LoadSetting EvacSpell string EvacSpell "Enter the name of your Evac spell here."
   /call LoadSetting LomMsg string LomMsg "Warning I'm running low on Mana."
   /call AddToggle reportlom off return "I won't tell you when I'm low on Mana." "I'll let you know when I'm low on Mana."
   /call AddToggle remem off return "I won't remem my spellset after casting." "I will remem my spellset after casting."
   /call LoadSetting SpellGem int DefaultSpellGem 8
   /call AddToggle yaulp off return "I won't Yaulp for mana." "I will Yaulp for mana."
   /call LoadSetting YaulpSpell string YaulpSpell Yaulp


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

Sub SpellMain
   /call CastFromQueue
   /if (${Toggle-canni}) /call CheckCann
   /if (${Toggle-yaulp}) /call CheckYaulp
/return

||||| Do Subs

Sub Command-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 :Command-BuffTargetStart
   }
   :Command-BuffSpellLoop
      /if (${Defined[Param${ParamCount}]}) {
         /if (${Param${ParamCount}.Equal[on]}) /goto :Command-BuffTargetStart
         /varset SpellNameParam ${SpellNameParam} ${Param${ParamCount}}
         /varcalc ParamCount ${ParamCount}+1
         /goto :Command-BuffSpellLoop
      }
   :Command-BuffTargetStart
   /varcalc ParamCount ${ParamCount}+1
   /if (!${Defined[Param${ParamCount}]}) {
      /varset TargetName me
   } else {
      /varset TargetName ${Param${ParamCount}}
      /varcalc ParamCount ${ParamCount}+1
      :Command-BuffTargetLoop
         /if (${Defined[Param${ParamCount}]}) {
            /varset TargetName ${TargetName} ${Param${ParamCount}}
            /varcalc ParamCount ${ParamCount}+1
            /goto :Command-BuffTargetLoop
         }
      /if (${TargetName.Equal[yourself]} || ${TargetName.Equal[${Me.CleanName}]}) {
         /varset CommandParam ${SpellNameParam}
         /call Command-SelfBuff ${CommandParam}
         /return
      }
   }
   /call AssignCastTarget "${TargetName}"
   /varset TargetName ${Macro.Return}
   /if (${TargetName.Equal[0]}) {
      /call ChatOut 5 "I don't understand who to cast that buff on."
      /return
   }
   /if (${DebugList.Find[spell]}) /echo Command-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 GenStr string local
   /declare BuffSpell int local
   /declare BuffDuration string local 0
   | Find an available pointer for the buff and delete duplicates
   /if (${Ptr}) {
      /call ListDelbyName BuffPtrList ${Ptr} " "
      /goto :gBuffPtrFound
   }
   /for GenFor 1 to ${Math.Calc[${BuffPtrList.Count[ ]}+2]}
      /if (!${BuffPtrList.Find[ ${GenFor} ]} && !${Ptr}) {
         /varset Ptr ${GenFor}
      }
      /if (${Buff-${BuffPtrList.Arg[${GenFor}]}-Text.Equal[${BuffType};${BuffCast};${BuffTarget}]}) {
         /varset Ptr ${BuffPtrList.Arg[${GenFor}]}
         /call ListDelbyArg BuffPtrList ${GenFor} " "
         /varset ST-BuffRefresh-${Ptr} 0
         /goto :gBuffPtrFound
      }
   /next GenFor
   :gBuffPtrFound
   /if (!${Defined[Buff-${Ptr}-Text]}) /declare Buff-${Ptr}-Text string outer
   /if (!${Defined[Buff-${Ptr}-RetryNum]}) /declare Buff-${Ptr}-RetryNum int outer 0

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

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

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

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

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

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

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

Sub Command-chainnuke
   /if (${ChainNuke.Equal[${ChainNuke-DefaultValue}]}) /return
   /declare NukeNum int local 1
   /call StandardTarget "${CommandParam}"
   /call ChatOut 5 "Chain nuking ${Target.CleanName}."
   /stand
   :ChainNukeLoop
      /if (!${Target.ID}) {
         /call ChatOut 5 "Chain nuking complete."
         /if (${Toggle-sitaftercast}) {
            /stopcast
            /varset SitTimer ${DelayBeforeSit}
         }
         /return
      }
      /if (${Me.SpellReady[${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 Command-chainstun
   /if (${ChainStun.Equal[${ChainStun-DefaultValue}]}) /return
   /call StandardTarget "${CommandParam}"
   /if (!${Target.ID}) /return
   /varset ChainStunNum 1
   /call NextStun
/return

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

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

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

/return

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

Sub Command-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 :Command-sntTargetStart
   }

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

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




|||| Called Subs

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

Sub CastFromQueue
   /if (${Merchant.Open} || ${Window[BigBankWnd]}) /return
   /declare ArgNum int local 0
   /if (!${CastStep}) {
      /if (!${CastQueue.Length}) /return
      /if (${CastQueue.Find[assist-]}) {
         /call Assist ${MasterName}
         /if (${Target.ID}) {
            /call RefineTarget "${Target.Name}"
            /call StringReplaceAll CastQueue assist- "${Macro.Return}"
         } else {
            /call ChatOut 4 "Unable to assist you to find a target to cast on."
         }
      }
      :gNextinQueue
      /varcalc ArgNum ${ArgNum}+1
      /if (!${Toggle-dobuff} && ${CastQueue.Arg[${ArgNum},|].Arg[4,;].Arg[1,-].Equal[b]}) /goto :gNextinQueue
      /if (!${CastQueue.Arg[${ArgNum},|].Length}) /return
      /varset CastType ${CastQueue.Arg[${ArgNum},|].Arg[1,;]}
      /varset CastName ${CastQueue.Arg[${ArgNum},|].Arg[2,;]}
      /varset CastTarget ${CastQueue.Arg[${ArgNum},|].Arg[3,;]}
      /varset CastInfo ${CastQueue.Arg[${ArgNum},|].Arg[4,;]}
      /if (${DebugList.Find[spell]}) /echo CastType ${CastType} CastName ${CastName} CastTarget ${CastTarget}
      /varset CastTimer 0
      /varset CastStep 1
      /varset CastOldTargetID 0
   } else /if (${Toggle-stopforheals} && ${CastQueue.Arg[1,|].Arg[4,;].Left[1].Equal[h]} && !${CastInfo.Left[1].Equal[h]}) {
      /if (${Me.Casting.ID}) /stopcast
      /varset CastStep 0
      /call ChatOut 3 "Interrupted ${CastType.Arg[1,-]}: ${CastName}.  I need to heal somebody instead!"
      /varset CastLastResult SPELL_IntentionalInterruption
      /return
   }

   |/if (${DebugList.Find[spell]}) /echo CastType CastName CastStep ${CastType} ${CastName} ${CastStep}
   /if (${CastQueue.Length}) /call Cast
   /return

Sub Cast
   /declare GenStr string local 1 2 3 4 5 6 7
   /if (${GenStr.Find[${CastStep}]}) {
	  /goto :gCast-${CastStep}
   } else {
      /if (${DebugList.Find[spell]}) /echo CastStep = ${CastStep} -- No corresponding goto found.  Returning.
      /varset CastStep 5
      /return
   }
   | Wait for spell to pop up, stand up, and target correctly.
:gCast-1
   |/if (${DebugList.Find[spell]}) /echo Cast 1 ${CastName}
   /if (${CastTimer}) /return
   /varset CastLastResult CHECKING_Casting
   /if (${Me.Casting.ID}) /return

   | Check the target conditions if a target required.
   /if (!${CastTarget.Equal[0]}) {
      /if (!${Spawn[${CastTarget}].ID}) {
         /if (${CastInfo.Arg[1,-].NotEqual[b]} || ${CastInfo.Arg[1,-].Equal[b-0]}) {
            /call ChatOut 3 "I couldn't find the target for ${CastType.Arg[1,-]} ${CastName}."
         }
         /varset CastStep 5
         /varset CastLastResult TARGET_NOTEXIST
         /return
      }
      /if (!${NearestSpawn[${CastTarget} radius ${MaxTargetRange}].ID}) {
         /call ChatOut 3 "${NearestSpawn[${CastTarget}]} is out of range of ${CastType.Arg[1,-]} ${CastName}."
         /varset CastStep 5
         /varset CastLastResult TARGET_OUTOFRANGE
         /return
      }
      /if (${Target.ID}!=${NearestSpawn[${CastTarget}].ID}) {
         /varset CastOldTargetID ${Target.ID}
         /squelch /target ${CastTarget}
         /delay 2s ${Target.ID}==${NearestSpawn[${CastTarget}].ID}
         /varset CastTimer 5
         /if (${Target.ID}!=${NearestSpawn[${CastTarget}].ID}) {
            /call ChatOut 3 "Wasn't able to target: ${CastTarget}"
            /varset CastStep 5
            /varset CastLastResult TARGET_CANNOTTARGET
            /return
         }
      }
   }

   /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 (${Toggle-sitaftercast}) /varset SitTimer 1140m
   /varset CastLastResult CHECKING_Target
   | Not accounting for items or alt yet.

   | Announce the casting.
   /if (${CastTarget.Equal[0]}) {
      /call ChatOut 5 "Casting ${If[${CastInfo.Arg[1,-].Equal[b]},buff ,]}${CastType.Arg[1,-]} ${CastName}."
   } else {
      /call ChatOut 5 "Casting ${If[${CastInfo.Arg[1,-].Equal[b]},buff ,]}${CastType.Arg[1,-]} ${CastName} on ${Target.CleanName}."
   }

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

   /varset CastLastResult CAST_StillCasting
   /varset CastStep 4
   /varset CastTimer 0
   /return
   |Stop moving
:gCast-2
   /if (${Me.Moving}) {
      /if (!${CastTimer}) {
         /call ChatOut 3 "Can't cast since I'm moving."
         /keypress forward
         /keypress back
         /varset CastTimer 8
      }
      /return
   }
   /varcalc CastStep 1
   /varset CastTimer 0
   /return
   | Memorize the spell
:gCast-3
   /if (!${Me.Gem["${CastName}"]}) {
      /if (!${CastTimer}) {
         /varset SpellNeedToRemem 1
         /if (${CastType.Arg[2,-].Length}) {
            /memspell ${CastType.Arg[2,-]} "${CastName}"
            /call ChatOut 6 "Memorizing spell: ${CastName} in slot ${CastType.Arg[2,-]}."
         } else {
            /memspell ${SpellGem} "${CastName}"
            /call ChatOut 6 "Memorizing spell: ${CastName} in default slot ${SpellGem}."
         }
         /varset CastTimer 5s
      }
      /return
   }
   /varset CastStep 1
   /varset CastTimer 0
   /return
   | Wait for spell to finish
:gCast-4
   /if (${Me.Casting.ID}) {
      /if (!${Me.Mount.ID} && !${Spawn[${CastTarget} radius ${MaxTargetRange}].ID} && ${CastTarget.NotEqual[0]}) {
         /stopcast
         /varset CastStep 6
         /call ChatOut 3 "Interrupted ${CastType.Arg[1,-]}: ${CastName}.  Target ${NearestSpawn[${CastTarget}].CleanName} died, poofed, or came back to life!"
         /varset CastLastResult SPELL_IntentionalInterruption
         /return
      }
      /if (${Toggle-stopifhealed} && ${CastInfo.Left[1].Equal[heal]} && ${CastTarget.NotEqual[0]}) {


         /if (${Spawn[${CastTarget}].Type.Equal[pet]}) {
            /if (${Spawn[${CastTarget}].PctHPs}>${PetPctHeal}+5) {
               /varset CastStep 6
            }
         } else /if (${TankList.Find[${Spawn[${CastTarget}].Class}]}) {
            /if (${Spawn[${CastTarget}].PctHPs}>${TankPctHeal}+5) {
               /varset CastStep 6
            }
         } else /if (${CasterList.Find[${Spawn[${CastTarget}].Class}]}) {
            /if (${Spawn[${CastTarget}].PctHPs}>${CasterPctHeal}+5) {
               /varset CastStep 6
            }
         }
         /if (${CastStep}==6) {
            /stopcast
            /call ChatOut 3 "Interrupted ${CastType.Arg[1,-]}: ${CastName}.  ${NearestSpawn[${CastTarget}].CleanName} was healed while I was casting!"
            /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]} && ${CastInfo.Arg[2,-].NotEqual[s]}) {
      /call BuffResult ${CastType} "${CastName}" "${CastTarget}" ${CastInfo.Arg[2,-]}
   }
   /if (${CastOldTargetID}) /squelch /target id ${CastOldTargetID} radius ${MaxTargetRange}
   /if (${DebugList.Find[spell]}) /echo CastLastResult ${CastLastResult}
   /if (${Toggle-remem} && ${SpellNeedToRemem}) {
      /memspellset ${DefaultSpellSet}
      /call ChatOut 6 "Re-memorizing original spells."
      /varcalc CastStep ${CastStep}+1
      /return
   }
   /call ListDelbyName CastQueue "${CastType};${CastName};${CastTarget};${CastInfo}" |
   /varset CastStep 0
   /if (${Toggle-sitaftercast}) /varset SitTimer ${DelayBeforeSit}
   /return
   | Wait until spells are rememmed to continue
:gCast-7
   /if (${Window[SpellBookWnd].Open}) /return
   /call ChatOut 6 "Done memorizing original spells."
   /varset SpellNeedToRemem 0
   /if (${Toggle-sitaftercast}) /varset SitTimer ${DelayBeforeSit}
   /call ListDelbyName CastQueue "${CastType};${CastName};${CastTarget};${CastInfo}" |
   /varset CastStep 0
/return

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

Sub CheckCann
   /if (!${Me.Moving}) {
      /if (${Me.CurrentMana}<${Me.MaxMana}-1066 && ${Me.CurrentHPs}>${Me.MaxHPs}\5+1924 && ${Me.AltAbilityReady[Cannibalization]} && ${CannTimer}<=0) {
         /alt activate 47
		 /varset CannTimer 5
      }
      /if (${Me.PctHPs}<70 && !${Me.Buff[${CanniHoT}].ID} && ${Me.Book[${CanniHoT}]}) {
         /if (${DebugList.Find[spell]}) /echo CheckCann "${CanniHoT}" "${Me.Name}"
         /call AddCast "${CanniHoT}" ${Me.Name} buff
		 /varset CannTimer 1
         /return
      }
      /if (${Me.PctMana}<95 && ${Me.PctHPs}>=${CanniLimit} && ${Me.SpellReady["${CanniSpell}"]} && ${CannTimer}<=0 && !${CastQueue.Length}) {
         /call AddCast "${CanniSpell}" ${Me.Name} buff
         /varset CannTimer 1
      }
   }
/return

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

Sub CheckYaulp
   /if (!${Me.Moving}) {
      /if ((${Me.PctMana}<95 || ${CombatTargetID}) && !${Me.Buff["${YaulpSpell}"].ID} && ${Me.SpellReady["${YaulpSpell}"]}) {
         /if (${DebugList.Find[spell]}) /echo CheckYaulp "${YaulpSpell}" "${Me.Name}"
         /call AddCast "${YaulpSpell}" ${Me.Name} buff
      }
   }
/return

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

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

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

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

Sub Event_CastInterrupt
   /if (${CastStep} && !${CastLastResult.Equal[SPELL_IntentionalInterruption]}) {
      /varset CastStep 0
      /varset CastLastResult CAST_Interrupted
   }
/return

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sub Event_WornOff(string WornOffText, string WornOffSpell, string WornOffTarget)
   
/return
Last edited by ascii38 on Mon Sep 24, 2007 6:45 pm, edited 2 times in total.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:13 pm

bothealer.inc

Code: Select all

|bothealer.inc
|Bot healer module.
|Version 13.3.6
|Date:08/06/2005
|
||**
[bothealer]
version=13.3.6
**||

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

|declare Vars
   /declare CasterList string outer
   /declare HealTargets[21] int outer 0
   /declare LowHealthCheck int outer 0
   /declare TankList string outer
   /declare WatchTargetCount int outer 0
   /declare WatchTargetIDs[15] int outer 0
   /declare WatchTargets[15] string outer
   /declare WatchWaitCount int outer 0

|Timers
   /declare CastMsgTimer1 timer outer
   /declare CastMsgTimer2 timer outer

|Load Settings
   /call AddToggle doheal on return "I will not heal anyone unless commanded." "I will watch and cast heal spells as necessary."
   /call LoadSetting CasterSpell string CasterSpell "Name of heal spell autoheal uses on Non Tanks"
   /call LoadSetting CasterPctHeal int CasterPctHeal 70
   /call LoadSetting DefaultHealSpell string DefaultHealSpell "Name of Default Heal Spell"
   /call LoadSetting HealCasterMsg string HealCasterMsg "Healing %t"
   /call LoadSetting HealPetMsg string HealPetMsg "Healing %t"
   /call AddToggle healpets off return "I will not heal the pets." "I will heal the pets."
   /call LoadSetting HealTankMsg string HealTankMsg "Big Heal on %t"
   /call LoadSetting IsPally bool IsPally 0
   /call LoadSetting PalGrpPct int PalGrpPct 81
   /call LoadSetting PalHealPct int PalHealPct 81
   /call LoadSetting PallyGroupSpell string PallyGroupSpell "Name of Pally Group Heal Spell"
   /call LoadSetting PallyHealSpell string PallyHealSpell "Name of Pally Heal Spell"
   /call LoadSetting PalHealMsg string PalHealMsg "Healing %t"
   /call AddToggle patchheal on return "I'm not a patch Healer." "I'm a patch Healer."
   /call LoadSetting PatchHealMsg string PatchHealMsg "Patch Healing %t"
   /call LoadSetting PatchSpell string PatchSpell "Name of Patch Heal Spell"
   /call LoadSetting PetPctHeal int PetPctHeal 51
   /call LoadSetting PetSpell string PetSpell "Name of Pet Heal Spell"
   /call LoadSetting ReportAutoHeal bool ReportAutoHeal 1
   /call LoadSetting TankSpell string TankSpell "Name of heal spell autoheal uses on Tanks"
   /call LoadSetting TankPctHeal int TankPctHeal 51
   /call AddToggle stopifhealed on return "I will not interrupt heal spells even if target is healed by someone else." "I will interrupt heal spells if target is already above the heal %."
   /call AddToggle stopforheals off return "I will not interrupt other spells for heal spells." "I will interrupt other spells for heal spells."



   /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
   /call CheckGrpHealth
   /call PalGrpHealChk
   /call PalHealChk
/return

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

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

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

Sub Command-heal
   /if (${DefaultHealSpell.Equal[${DefaultHealSpell-DefaultValue}]}) /return
   /call AssignCastTarget "${CommandParam}"
   /declare HealTarget string local ${Macro.Return}
   |/call ChatOut 3 "Casting ${DefaultHealSpell} on ${NearestSpawn[${HealTarget}]}."
   /call AddCast "${DefaultHealSpell}" "${HealTarget}" h-com
/return

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

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

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

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

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

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

||||| Called Subs

Sub CastHeal(int TarID,string HealSpell,string castMsg)
   /if (!${CastMsgTimer1}) {
      |/if (${ReportAutoHeal}) /g ${castMsg}
      /varset CastMsgTimer1 50
   }
   /call AddCast "${HealSpell}" "id ${TarID}" "heal"
/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 (!${Toggle-doheal}) /return
   /if (${IsPally}) /return
   /varset HealCount ${Group}
   /for tempvar 1 to ${Group}
      /varset HealTargets[${tempvar}] ${Group.Member[${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}) {
         /squelch /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]} && ${Toggle-patchhealer}) /call PatchHeal ${QuickID}
            /call CastHeal ${QuickID} "${TankSpell}" "${HealTankMsg}"
         }
      }
      /if ((${Spawn[${QuickID}].PctHPs}<${CasterPctHeal})&&(${Spawn[${QuickID}].State.NotEqual[DEAD]})) {
         /if (${CasterList.Find[${Spawn[${QuickID}].Class}]}) {
            /if ((${Spawn[${QuickID}].PctHPs}<${Math.Calc[${CasterPctHeal}/2]})&&(${Toggle-patchhealer})) /call PatchHeal ${QuickID}
            /call CastHeal ${QuickID} "${CasterSpell}" "${HealCasterMsg}"
         }
      }
      /if (${Toggle-healpets} && ${Spawn[${QuickID}].Class.PetClass} && ${Spawn[${QuickID}].Pet.ID}) {
         /if (${Spawn[${QuickID}].Pet.PctHPs}<${PetPctHeal}) {
            /call CastHeal ${Spawn[${QuickID}].Pet.ID} "${PetSpell}" "${HealPetMsg}"
         }
      }
   /next tempvar
   /if (${CombatTargetID}) /call Target "id ${CombatTargetID}"
   /if (${BadIDs}>0) /call ResetWatchTargets
/return

Sub PalHealChk
    /declare tempvar int local 0
   /if (!${IsPally}) /return
   /if (!${Toggle-doheal}) /return
   /for tempvar 0 to ${Group}
      /if ((${Group.Member[${tempvar}].PctHPs}<${PalHealPct})&&(${Group.Member[${tempvar}].State.NotEqual[DEAD]})) /call PallyHeal ${Group.Member[${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 (!${Toggle-doheal}) /return
   /if (${Me.PctHPs}>${PalHealPct}) {
      /varset LowHealthCheck 0
   } else {
      /varset LowHealthCheck 1
   }
   /for tempvar 1 to ${Group}
      /if ((${Group.Member[${tempvar}].PctHPs}<${PalHealPct})&&(${Group.Member[${tempvar}].State.NotEqual[DEAD]})) /varcalc LowHealthCheck ${LowHealthCheck}+1
      /if (${LowHealthCheck}>=3) {
         /call PalGroupheal
         /return
      }
   /next tempvar
/return

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

Sub Patchheal(int TarID)
   /if (${CastMsgTimer1}<=0) {
      |/if (${ReportAutoHeal}) /g ${PatchHealMsg}
      /varset CastMsgTimer1 50
   }
   /if (${Me.Gem[${PatchSpell}]}) /call AddCast "${PatchSpell}" "id ${TarID}" "heal"
/return

Sub ResetWatchTargets
   /declare counter int local
   /for counter 1 to ${WatchTargetCount}
      /squelch /target PC ${WatchTargets[${counter}]}
      /call Delay 25
      /if (${Target.CleanName.Equal[${WatchTargets[${counter}]}]}) {
            /varset WatchTargetIDs[${counter}] ${Target.ID}
      } else {
            /call ChatOut 5 "I failed to find ${WatchTargets[${counter}]} in the zone."
      }
   /next counter
/return
Last edited by ascii38 on Tue Oct 25, 2005 12:55 am, edited 4 times in total.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:14 pm

botdoc.txt

Code: Select all

BotDoc.txt
Manual for the Generic bot macro and .ini that accomanies it.
Version 13.3.0
Date:08/05/2004
 
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.  You can also do /macro genbot <mastername1> <mastername2> <mastername3>. . . if you want multiple characters to be able to command the bot.

The first time you run genbot, a file will be created in your /macros directory, called bot_BotName.ini.  This is called your .ini file, and can be used to give the initial preferences for many of your bots actions.  We recommend you /endmacro after you start genbot the first time, and immediately edit this file as appropriate.  For instance, if the char is a healer, change "doheals=off" to "doheals=on" under "[Healer]".

By default your bot will act on to any command the master character /tells him.
By changing the values of "listengroup", "listenchat" in your .ini file or by sending the toggle commands "listengroup", "listenchat" you can set the bot to listen for commands sent in group or chat channel as well.  Of course, even in these other channels, the bot will still only respond to characters on its list of masters.

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)

Quick notation note: "command a|b|c" means you can enter a or b or c as a parameter for "command", but you must enter one of them.  "command <a>" means that you can enter "command" with or without "a" depending on what you want the bot to do.  "command <a|b>" means you can use "command" with a or b or nothing.

Also, none of the genbot commands use quotation marks, although sometimes I use them as above to distinguish between text and the actual commands you will use.

Capitals are also never required in macros.  Capitals used below mean you need to replace that word with the appropriate object.  For example, "loot CorpseName" means you should replace "CorpseName" with the actual name of the corpse you want the bot to loot.

TOGGLES - Toggles can be turned on with "on" or "true" or "yes" or "1".  They can be turned off with "off" or "false" or "no" or "0".  If no parameter is given, the toggle with either flip, or return it's current toggle depending on the type of toggle.

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

MASTER TO BOT COMMANDS:

You can command your bot using tells, like this:
   /tell BotName command <parameter> <parameter> ...

If checkname is set to off in your .ini, then use group and chat commands like this;
   /1 command <parameter> <parameter> ...
   /g command <parameter> <parameter> ...

If checkname is set to on in your .ini file, your bot will only respond to group and chat commands like this;
   /1 BotName command <parameter> <parameter> ...
   /g BotName command <parameter> <parameter> ...

You can also use "/g BotName command. . ." format even if checkname is set to off.  This is useful if you are commanding multiple bots, and only want one of them to follow your command.

You can also command the bot to use any normal EQ or MQ2 command that starts with a slash character.  For instance, to tell your bot to "/wave", just do "/tell BotName /wave".

---------------------------------------------------------------
[GENERAL COMMANDS AND FUNCTIONS]

reload - Not currently working.>  Commands bot to re-init the macro once you have mad changes to the .ini

setvar - Sets a var to new setting

rptvar - Commands bot to reply with the current value of a variable
  These two command are only for advanced users.

---------------------------------------------------------------
[CHARACTER COMMANDS]

autoinv - Commands bot to use the /autoinv command

camp - Commands bot to camp out.

dismount - Commands bot to /dismount.

disc DiscName - Commands bot to fire the specified /disc.

lootup <TargetName> Commands bot to loot a corpse.
  CorpseName bot loots CorpseName
  no parameter   bot loots nearest corpse

lootall - Commands bot to attempt to loot all corpses around it.  Maximum distance is defined as CorpseRadius in the .ini file.

target <me|yourself|TargetName> - Causes the bot to change it's target;
  me - targets master
  yourself - bot targets itself
  TargetName - name of target
  no parameter - 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.  Currently the same as attack.

accept - Command bot to accept the current group invite.

invite <PlayerName> - Command bot to invite it's current target to group.
  PlayerName - Command bot to invite PlayerName to group. 
  no parameter - Command bot to invite master's target to group.   

reject - Command bot to reject the current group invite.

consent <me|TargetName>
  me|no parameter - Commands bot to give consent to it's master.
  TargetName - Commands bot to give consent to TargetName.

trade - Commands bot to hit the trade button in a trade window.

yesres - Commands bot to hit yes on a ressurection confirm box.

random Number - Commands bot to /ran Number.

sit - Makes bot sit

stand - Makes bot stand



---------------------------------------------------------------
[COMMUNICATION]

afk <message> - Turn bot's afk on with optional <message>.

listengroup - Toggles bot listening for commands in group chat. . Default Value: OFF

checkname - Toggle.  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.

listenchat - Toggles bot listening for commands in the Chat Channel defined by the "chatin" command or in the .ini file. Default Value: OFF

chatin ChannelName - Changes what channel the bot will use for replying to it's master.  Example: "myprivateline"

group Message - Commands the bot to /gsay Message.

say Message - Commands the bot to /say Message.

tell Name Message - Commands the bot to /tell Name Message.


---------------------------------------------------------------
[MOVEMENT]
 
anchor - Causes the bot to remember it's current location and return there between fights.

anchorradius <distance> - Tells bot the distance within which to stop moving when it is anchored.

door - Causes the bot to attempt to open the closest door.

duck - Commands the bot to duck.

follow <Name> - Command bot to follow the master or his designated target;
  Name - tells the bot to follow name, name can be your name,pcname or npcname.
  no parameter - if master has no target, tells the bot to follow the master.
 
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

getbehind - Commands bot to move behind the specified target

moveto me|Loc|Name - commands the bot to move to a point, then stop;
  me - moves bot to you
  225,-300 - moves bot to the location 225 , -300
  Name - moves bot to Name
  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

run - Toggles run setting on bot

traps - Toggles bot trying to find and disarm traps. Default Value: OFF

mount - Commands bot to get on it's mount (defined in bot_BotName.ini)

stop - Forces the bot to stop, will duck, dismount and stop moving.

---------------------------------------------------------------
[COMBAT]

petona - Toggles bot doing /pet attack on assist. Default Value: OFF

defend - Toggles bot automatically fighting back when attacked. Default Value: OFF

protect - Toggles bot to protect the master or not.  Only detects by checking if mob is facing master, so can misfire.  Not to be used if not in a combat area.

guard - Toggles the bot to anchor itself and protect the nearby area from NPCs.  Guard radius is set in the .ini file.

puller - Controls if the bot will return to it's anchor point when attacked. Default Value: OFF

autoengage - Controls if the bot will close and engage when in combat. Default Value: OFF

autobehind - Controls if the bot will automatically attempt to fight behind all targets during combat. Default Value: OFF

backstab - Toggles bot using backstab while fighting. Default Value: OFF

bash - Toggles bot using Bash during fighting. Default Value: OFF

disarm - Toggles bot using disarm while fighting. Default Value: OFF

evade - Toggles bot using Hide during fighting. Default Value: OFF

flyingkick - Toggles bot using flyingkick while fighting. Default Value: OFF

frenzy - Toggles bot using frenzy while fighting. Default Value: OFF

tauntdisc - Toggles bot using warrior taunt discipline while fighting. Which discipline is used is defined in the .ini file under COMBAT in WarTauntDisc.  Default Value: OFF

kick - Toggles bot using kick while fighting. Default Value: OFF

slam - Toggles bot using Slam during fighting. Default Value: OFF

taunt - Toggles bot using taunt while fighting. Default Value: OFF

archery - Toggles bot using archery while fighting. Default Value: OFF

attack - Commands bot to start attacking

noattack - Commands bot to Stop attacking

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

petback - Commands bot to execute it's /pet back command.

petguard - Commands bot to execute it's /pet guard 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]

reportlom - Controls if the bot will automatically report when it's low on mana. Default Value: OFF

yaulp - Toggles if bot will use yaulp (Yaulp spell is defined in genbot_BotName.ini) when low on mana. Default Value: OFF

canni - Toggles if bot will cannibalize when low on mana. Default Value: OFF

aftercastsit - Controls if the bot will sit after casting spells. Default Value: OFF

buff <Spell> <on Target> - Commands bot to cast buff Spell on Target, bot will automatically refresh it.
buff <Spell> - Commands bot to cast Spell on it's master

bufflist - Lists all buffs currently on bot and all buffs they are keeping up on other chars.

chainnuke Target- Commands bot to start chaining nukes on Target

chainstun Target - 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.

loadlist <listname> - Commands bot to load a spell list

mana - Commands bot to reply with it's current mana

sn <spell|gemNumber|item|alt> CastName - Commands bot to cast the specified spell or item or alt ability on master's target.
  spell|no parameter - will cast CastName on master's target.
  gemNumber - If spell is not already memorized, memorizes it to slot Number before casting.
  item - will right click item CastName on master's target.
  alt - will use alt ability CastName on master's target.
  EXAMPLE: sn item Nature Walkers Scimitar on a large snake

snt <spell|gemNumber|item|alt> CastName <on Target> - Commands bot to cast <spell|item> ON Target,if "on Target" is not
specified, it will cast on bot's target
  spell|no parameter - will cast CastName on Target.
  gemNumber - If spell is not already memorized, memorizes it to slot Number before casting.
  item - will right click item CastName on Target.
  alt - will use alt ability CastName on Target.

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

---------------------------------------------------------------
[HEALING]

autoheal - Controls if the bot will automatically use heals on group and watch targets. Default Value: OFF

autohealpets - Controls if the bot will automatically use heals on pets. Default Value: OFF

patchheal - Controls if the bot will automatically patch heal targets below half their heal percent. Default Value: OFF

heal <me|yourself|TargetName> - Commands bot to heal TargetName.  If not specified, heals master's target.

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


---------------------------------------------------------------
SHORTCUTS

Genbot also includes shortcuts, which can run any everquest, macroquest, or genbot command.  Shortcuts must be defined in your .ini file.

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

For instance, the following would be a valid Genbot .ini section:

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

To execute any of the above shortcuts, just command the word to the left of the equal sign.  For instance, "/tell BotName nukeit" would cause the bot to cast Lure of Fire on your target.

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.

To shrink your entire party using a Cobalt Bracer do:

shrink=/snt item cobalt bracer
shrinkparty=/keypress F1|shrink|/keypress F2|shrink|/keypress F3|shrink|/keypress F4|shrink|/keypress F5|shrink|/keypress F6|shrink

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."

---------------------------------------------------------------
CAUTION

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 - Vexix Updated the code and introduced generalized shortcuts.
Version 13.0-1.x - Vexix redid spell routines to be more flexible and include items and alt abilities.
Version 13.2.x - Vexix added the defend, protect, and guard commands, as well as events.
Version 13.3.x - Vexix changed base code to allow individual genbot macros and simplified the code.

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Tue Aug 24, 2004 10:15 pm

Space left intentionally blank.

Neolesh
a hill giant
a hill giant
Posts: 231
Joined: Mon Aug 23, 2004 11:15 am

Post by Neolesh » Wed Aug 25, 2004 9:48 pm

Subroutine Command-resetwatch wasn't found
botcore.inc@780
botcore.inc@1060
botmain.inc@66

This happened executing the resetwatch command which I assumed would reset my watch list :)

Neolesh
a hill giant
a hill giant
Posts: 231
Joined: Mon Aug 23, 2004 11:15 am

Post by Neolesh » Wed Aug 25, 2004 9:52 pm

I also was trying to figure out how to turn off reporting the autoheal. I changed the value in the ini

ReportAutoHeal=1
to
ReportAutoHeal=0
ReportAutoHeal=off
and
ReportAutoHeal=no

and none worked?

ascii38
a grimling bloodguard
a grimling bloodguard
Posts: 506
Joined: Sat Jul 17, 2004 8:06 pm

Post by ascii38 » Thu Aug 26, 2004 12:54 am

This is probably not the best way to fix the resetwatch thing, but it should do the job. Add the following to bothealer.inc somwhere (I put it at line 180, under Sub Command-watchtarget in my local copy)

Code: Select all

Sub Command-resetwatch
   /call ResetWatchTargets
/return
For the autoheal message, are you a Paladin? The report autoheal functionality seems to be commented out in CastHeal and PatchHeal but not in PalGroupHeal. If you are a paladin, try removing or commenting out line 255 of bothealer.inc which reads /if (${ReportAutoHeal}) /g ${PalHealGrpMsg}. If you aren't a Paladin, then I don't have an answer right now :smile:

Neolesh
a hill giant
a hill giant
Posts: 231
Joined: Mon Aug 23, 2004 11:15 am

Post by Neolesh » Thu Aug 26, 2004 1:37 am

I am a Ranger and thanks for the fix on resetwatch =)

Neolesh
a hill giant
a hill giant
Posts: 231
Joined: Mon Aug 23, 2004 11:15 am

Post by Neolesh » Thu Aug 26, 2004 3:02 am

The reporting I'm refering to isn't in /g it's in tell to me.. by bot keeps telling me over and over "Casting spell Complete Healing on #####"

So that's what I'm trying to turn off.