genbot.mac Generic Bot macro for any class. V9.3 with ini

A forum for you to dump all the macros you create, allowing users to use, modify, and comment on your work.

Moderator: MacroQuest Developers

User avatar
Elric
Cheese Whore
Cheese Whore
Posts: 466
Joined: Sun Nov 23, 2003 12:31 am
Location: Tampa, Fl
Contact:

Post by Elric » Thu Jan 01, 2004 12:32 pm

I'd like to see that mac/code when you get done with it. I think it's a good idea to add that "Too powerful" fallback.
-Elric

McTisuk
orc pawn
orc pawn
Posts: 11
Joined: Thu Jan 01, 2004 6:46 am

brain dump, omg so rambling!

Post by McTisuk » Thu Jan 01, 2004 1:09 pm

Before I did the buff addition, I wrote a pseudonyms include file, ini based, that allowed you to set a list of things to replace with another thing, and saved the list, etc.

Examples were :
[spells]
sow="speed of wolf"
ds="whatever ds you want"

and so on.
I used it by psuedonym sow - it'd return either sow (if no pseud) or "speed of wolf" etc.
Had separate lists available too, so you could pseud spell sow instead.

I decided to clean it up before posting, and acidentally blanked the whole thing, so /shrug, it's not top of the list to re-write atm ;-(


Anyhow, the problem with using a lookup list to get the correct spell is the bot ISSUING the request. If your required buff list includes sow, whether you are in an indoor or outdoor zone, you request sow when you don't have it... If you aren't a druid, you can't try and cast sow to tell if it won't work.
Now I end up needing to reply saying "not outside" (ok easy), pay attention to that on the requesting bot, and decide not to ask for that buff any more until you zone...
I couldn't be bothered to do that =p ATM the buffmonitor addition just asks every so often for any buffs it's missing, it doesn't know anything about whether they are actually coming or not =p (just waits a reasonable time after the req then moves on to the next one).

I was playing with pseuds to be used for more natural-seeming chat. Worked ok. Also I thought of an advanced moving idea. Such as a Headto command. Headto ssra.
It'd then look in headto ini for ssra, and do a series of things on that list, waypoints. such as :
[ssra]
1. portg twilight
2. snme groupsoe
3. headto twilighttoscarlet
4. zone
5. headto scarlettogrey
6. zone
7. headto greytossra
8. zone

[twilighttoscarlet]
loc=whateveritis

[scarlettogrey]

in pseuds.ini
[spells]
portg="Circle of"
groupsoe="Flight of Eagles"

[zones]
ls=lavastorm
pok=knowledge

etc. maybe there's some good waypoint and path code around tho, I didn't look yet. If so, /cheer, time to build it in to genbot =p
headto my bind!
<genbot> I'm at your bind now.
/follow genbot
headto zone I died in

Anyhow, some other time. And for another time also, genbot addition to do ch rotations. Also, add in the code I have for manastone/robe, modrods, epic clickeys. I don't like those being in "personal" tho, I think they should all be core, but core to what I don't know.
Was wondering if it might be worth converting mine to have a "class" section, that could then know about things your specific class does. Maybe CH rotate would go in healer, but maybe it would be better in cleric/dru. And the shammy area would have canni routines. Druid/wiz, port routines.
Maybe the sub-sections could be split up and called from the cores atm, such as, combat calls do_sk-combat if you are sk, do_pally-combat, etc, and they live in botsk.inc, botpally.inc, etc. Shammy canni would be called in the genbot main loop, do_class-general...
maybe one for items too.
do_item-general would offer it the chance to use any items it wanted to.


WARNING !
I had a problem with genbot healing code, I hadn't set one of the spellnames for healing, and now and then the bot would try and cast it and go into a loop trying to mem it. You break out of the loop by issuing another command (heal me, for eg), and it does the double heal thing some people mentioned. So, note one to everyone : make sure your healbot has a valid spell list for healing spells.


Another Problem!

I've tracked down another problem ... Healer again. Healerbot is set to not do combat. Healerbot sits there and heals just fine. If it gets aggro, and needs to cast a heal (could be any spell tho I think) while getting hit, he often goes into a loop, trying to target the correct person to heal. This loop also can be broken by issuing a command to the bot getting it to do something, and it then tends to break out of the loop and double cast the spell it was trying to do.

There seems to be something wierd anyhow, in the group healing check routine, it passes thru to casterheal or tankheal or whatever. It tries to pass a paramater, the targid of the person to heal. The called routines, casterheal and so on, don't have parameters, so I kept getting param0 = null ...

change

Code: Select all

Sub CasterHeal
to

Code: Select all

Sub CasterHeal(param0)
do the same for
Sub TankHeal
Sub PallyHeal
Sub Patchheal

maybe others. I thought for a while param0 was "implied" if you had no params, but I echo'd param0 on entering each and always got null .. ie, we pass in nothing, then try and heal that person.

I think these things work sometimes due to already having the person targetted, or maybe being in group with them.

Also, I mentioned before about irc not translating %T, but the fix doesn't work on irc, LOL.
All the messages I have now look like this (healer stuff again)

Code: Select all

/call ChatOut 5 @MasterName  "@PatchHealMsg $target(name)"
and I changed my ini file to NOT have %T in the message. So ini file has "heal over time on -> " and the macro works out the right name to put in it.
McTisuk ... just another macro writer~

McTisuk
orc pawn
orc pawn
Posts: 11
Joined: Thu Jan 01, 2004 6:46 am

forgot!

Post by McTisuk » Thu Jan 01, 2004 1:16 pm

I forgot to say, I like the fallback idea, and considered it, but I went for ini settings for which buffs you want instead.

I suppose, if there is fallback code, then genbot could get a buff section (what I wrote is a buff requesting section), and I could alter the buff requesting section to listen for "I can do that" responses.
If no-one responds, it would then use fallback to request the next buff instead. Could be useful, you could just have "HP buff" in the list, and the buff request code would ask for the right one based on it's level. Then, if no cleric available, it could fallback to ask for druid buff, or whatever.
McTisuk ... just another macro writer~

McTisuk
orc pawn
orc pawn
Posts: 11
Joined: Thu Jan 01, 2004 6:46 am

current buff monitoring mod to genbot & zoned fix

Post by McTisuk » Thu Jan 01, 2004 1:24 pm

To add in the buff monitoring stuff :

in botcore, change event_zoned to be the following (adds one line)

Code: Select all

Sub Event_Zoned
   /varset IsAnchored 0
   /varset ForBuffsZoned 1
   /sendkey up up
/return
and a fix for something that isn't working, change

Code: Select all

#Event Zoned "LOADING, PLEASE WAIT..."
to

Code: Select all

#Event Zoned "You have entered"
- my system at least doesn't pick up the new displayed in middle of screen zoning msg.


my modified genbot.mac

Code: Select all

|genbot.mac
|Generic bot macro for any class.
|Version 9.0
|Date:12/30/2003 1:00am
|
|
|
|
#define personal-array 0
#define botcore-array 1
#define botcombat-array 2
#define botspell-array 3
#define bothealer-array 4
#define botbuffs-array 5
#include botcore.inc
#include botspell.inc
#include botcombat.inc
#include bothealer.inc
#include botbuffs.inc
#include personal.inc
#turbo 40

Sub Main
   /zapvars
   /declare MasterCount global
   /declare ArrayCore global
   /declare ArraySpell global
   /declare ArrayComb global
   /declare ArrayHeal global
   /declare ArrayBuffs global
   /declare ArrayPers global
   /declare IniFile global
   /varset IniFile "genbot_"
   /varcat IniFile $char(name)
   /varcat IniFile ".ini"
   |Core variables
   /call SetupCoreVars
   |Spell Module Variables
   /call SetupSpellVars
   |Combat Module Variables.
   /call SetupCombatVars
   |Healer Module Variables.
   /call SetupHealerVars
   |Buffs Module Variables.
   /call SetupBuffsVars
   |Personal Module Variables.
   /call SetupPersonalVars


   /if $defined(Param0)==FALSE {
      /echo Usage: /macro generic <Master Name1> <Master Name2>...
      /endmacro
   }
   /varset MasterCount 0
   :MasterLoop
   /if $defined(Param$int(@MasterCount))==TRUE {
      /varset MName($int(@MasterCount)) @Param$int(@MasterCount)
        /varadd MasterCount 1
      /goto :MasterLoop
   }
   /varsub MasterCount 1
   /varset MasterName @MName(0)
|||This is where the commands the bot can take is set up
   /call CoreCommands
   /call SpellCommands
   /call CombatCommands
   /call HealerCommands
   /call BuffsCommands
   /call PersonalCommands
      :MainLoop
   /doevents
   |||Sub from bothealer.inc
   /call CheckGrpHealth
   ||| Sub From bothealer.inc
   /call PalGrpHealChk
   ||| Sub From bothealer.inc
   /call PalHealChk
   |||Sub from botbuffs.inc
   /call CheckBuffs
   |||Sub from botcombat.inc
      /if n @Combatstatus==0 {
      /if n $DoTraps==1 /call TrapFinder
   }
   /if n @DoArchery!=1 {
      /if n @Combatstatus==1 /call RangeSub
   }
   /if n @Combatstatus==1 /call MeleeAbility
   /if n @Combatstatus!=1 {
      /if n @Supportstatus!=1 {
         /if n @IsAnchored==0 {
            /if n @Afollow==1 {
               /target @FollowTarget
               /call Do-moveto foo @FollowTarget
            }
         }
      }
      /if n @IsAnchored==1 {
         /if n $distance(@AnchorX,@AnchorY)>@AnchorRadius {
            /call MoveToAnchor
         } else /if n @SitAfterCast==1 {
            /if $char(state)==STAND /sit
         }
      }
   }
   /if $combat==TRUE {
      /if $target()==TRUE {
         /if "$target(name,clean)"!="$char(name)" {
            /if n @AutoEngage==1 /varset Combatstatus 1
         }
      }
   }
   /call PersonalMain

   /doevents
   /varset CmdArrayNum 0
   /goto :MainLoop
/return
and botbuffs.inc

Code: Select all

|botbuffs.inc
|Bot buff checking module.
|Version 1
|Date:1/1/2004
|
|
|
|Requires botspell.inc

Sub BuffsCommands
   /varset Commands(5,0) CheckBuffs
   /varset ArrayBuffs 0
/return

Sub TellCmds-buffs
   /declare counter local
   /declare cmds local
   /varset cmds ""
   /for counter 0 to @ArrayBuffs
      /varcat cmds "@Commands(5,@counter), "
   /next counter
   /call ChatOut 2 @MasterName "@cmds."
/return


Sub SetupBuffsVars
   /declare CmdList-buffs global
   /declare generalbuffs array
   /declare combatbuffs array
   /declare askoncebuff global
   /declare ForBuffsZoned global
   /varset ForBuffsZoned 1


   /for tempvar 1 to 10 {
     /varset generalbuffs(@tempvar) "$ini(@IniFile,"Buffs",generalbuffs@tempvar)"
      /if "@generalbuffs(@tempvar)"=="NOTFOUND" {
	      /ini "@IniFile" "Buffs" "generalbuffs@tempvar" "none"
              /varset generalbuffs(@tempvar) "none"
      }
    }
    /next tempvar

   /for tempvar 1 to 10 {
     /varset combatbuffs(@tempvar) "$ini(@IniFile,"Buffs",combatbuffs@tempvar)"
      /if "@combatbuffs(@tempvar)"=="NOTFOUND" {
	      /ini "@IniFile" "Buffs" "combatbuffs@tempvar" "none"
              /varset combatbuffs(@tempvar) "none"
      }
   }
   /next tempvar

   /varset askoncebuff "$ini(@IniFile,"Buffs",askoncebuff)"
      /if "@askoncebuff"=="NOTFOUND" {
	      /ini "@IniFile" "Buffs" "askoncebuff" "none"
              /varset askoncebuff "none"
      }
   }
/return

Sub checkcombatbuffs
/declare count local
  /for count 1 to 10
    /if "@combatbuffs(@count)"!="none" /call checkabuff "@combatbuffs(@count)"
  /next count
/return

Sub checkgeneralbuffs
/declare count local
  /for count 1 to 10
    /if "@generalbuffs(@count)"!="none" /call checkabuff "@generalbuffs(@count)"
  /next count
/return

Sub checkaskoncebuff
    /if n ForBuffsZoned==1 {
	/varset ForBuffsZoned 0
        /if "@askoncebuff"!="none" {
	    /call checkabuff "@askoncebuff"
	}
    }

/return

Sub checkabuff(listtocheck)


|buffs that are fading soon

   /if $char(buff,$char(buff,"@listtocheck"),duration)<=1 {
     /if $char(book,"@listtocheck")==NULL {
       /Call ChatOut 9 @MasterName "My @listtocheck fades in $char(buff,$char(buff,"@listtocheck"),durationsecs)"
       /Call ChatOut 5 @MasterName "snme @listtocheck"
       /delay 50
       /return
       }
      /call spellsub "@listtocheck"
     /return
     }
    }


| buffs we are just outright missing atm

   /if $char(buff,"@listtocheck")==0 {
     /if $char(book,"@listtocheck")==NULL {
       /Call ChatOut 5 @MasterName "snme @listtocheck"
       :WaitForBuff
        /delay 5s
        /if $char(buff,"@listtocheck")==0  /goto :WaitForBuff
        /return
       }
|        we cast this one ourselves
      /declare buffsoldtarg local
      /varset buffsoldtarg $target(id)
      /target myself
      /call spellsub "@listtocheck"
      /target $spawn(@buffsoldtarg,name)
     /return
     }

/return


Sub CheckBuffs
 /Call checkgeneralbuffs
 /if $combat==TRUE /Call CheckCombatBuffs
 /if n ForBuffsZoned==1 /call Checkaskoncebuffs
/return

think that's all of the changes you need to make.
Last edited by McTisuk on Thu Jan 01, 2004 1:37 pm, edited 1 time in total.
McTisuk ... just another macro writer~

McTisuk
orc pawn
orc pawn
Posts: 11
Joined: Thu Jan 01, 2004 6:46 am

Generic skillup include file

Post by McTisuk » Thu Jan 01, 2004 1:30 pm

This you would include in genbot.mac, for example, at the top of the file where the other includes are, add
#include botskillup.inc

can use in any macro tho.

It gives you notification when any skill increases, you can alter that to do what you want tho. Will eventually want to add a spelltrainer to genbot.
Train Divination max
;-)

anyhow, usable in any macro, without needing to worry!

Checked and working for all hybrid-available skills, but I haven't checked the rest for validity.


EDIT ! took out the code sample here, because it's SO long, not directly related to genbot, and it's current functionality is provided much easier as seen below -)
To see the original code, look here
http://macroquest2.com/phpBB2/viewtopic ... 3358#33358
and the responses / discussion :-)
Last edited by McTisuk on Thu Jan 01, 2004 10:53 pm, edited 1 time in total.
McTisuk ... just another macro writer~

ml2517
a grimling bloodguard
a grimling bloodguard
Posts: 1216
Joined: Wed Nov 12, 2003 1:12 am

Post by ml2517 » Thu Jan 01, 2004 2:30 pm

All of that mess can probably be summed up like this:

Code: Select all

#Event SkillUp "You have become better at" 

Sub Event_SkillUp(SkillUpText) 
/declare ParseSkillLevel local 
/declare ParseSkill local 
/declare PositionStart local 
/declare PositionEnd local 
/varset PositionStart $calc($instr("! (","@SkillUpText")+3) 
/varset PositionEnd $instr(")","@SkillUpText") 
/varset ParseSkillLevel $mid(@PositionStart,$calc(@PositionEnd-@PositionStart),"@SkillUpText") 
/varset PositionStart $instr("You have become better at ","@SkillUpText") 
/varset PositionEnd $instr("! (","@SkillUpText") 
/varset ParseSkill $mid(@PositionStart,$calc(@PositionEnd-@PositionStart),"@SkillUpText")
/call ChatOut 5 "@MasterName" "@ParseSkill increased - @ParseSkillLevel ..." 
/if n @ParseSkillLevel==$calc($calc($char(level)*5)+5) { 
    /call ChatOut 5 "@MasterName" "@ParseSkill maxed for level - @ParseSkillLevel ... woo!" 
    /if n @ParseSkillLevel==235 { 
        /call ChatOut 5 "@MasterName" "@ParseSkill maxed forever! - 235 is max!" 
    } 
} 
/return 

McTisuk
orc pawn
orc pawn
Posts: 11
Joined: Thu Jan 01, 2004 6:46 am

Post by McTisuk » Thu Jan 01, 2004 3:51 pm

Thanks -)
I think I had some good and bad reasons for doing it that way, partly clarity.
I replied with questions in the other thread tho -) this poor thread spammed to hell with my junk already ;-(
McTisuk ... just another macro writer~

Zacaria
orc pawn
orc pawn
Posts: 19
Joined: Wed Dec 03, 2003 5:47 pm

Post by Zacaria » Thu Jan 01, 2004 4:01 pm

i love how people can take something you work hard on and clarify it and then you go "damn i knew i should have done it like that " :) good stuff

ml2517
a grimling bloodguard
a grimling bloodguard
Posts: 1216
Joined: Wed Nov 12, 2003 1:12 am

Post by ml2517 » Thu Jan 01, 2004 6:09 pm

Hehe.. I actually worked on the skillup routine a bit more and its very flexible now. See this post.

http://macroquest2.com/phpBB2/viewtopic ... 3358#33358

User avatar
lasher
a lesser mummy
a lesser mummy
Posts: 71
Joined: Thu Dec 18, 2003 4:09 pm

Re: brain dump, omg so rambling!

Post by lasher » Thu Jan 01, 2004 6:21 pm

McTisuk wrote: There seems to be something wierd anyhow, in the group healing check routine, it passes thru to casterheal or tankheal or whatever. It tries to pass a paramater, the targid of the person to heal. The called routines, casterheal and so on, don't have parameters, so I kept getting param0 = null ...

change

Code: Select all

Sub CasterHeal
to

Code: Select all

Sub CasterHeal(param0)
do the same for
Sub TankHeal
Sub PallyHeal
Sub Patchheal

maybe others. I thought for a while param0 was "implied" if you had no params, but I echo'd param0 on entering each and always got null .. ie, we pass in nothing, then try and heal that person.
param0 is implied. those changes aren't needed unless I'm mistaken

edit: I just asked and confirmed that it was implied.

User avatar
lasher
a lesser mummy
a lesser mummy
Posts: 71
Joined: Thu Dec 18, 2003 4:09 pm

Post by lasher » Thu Jan 01, 2004 6:33 pm

leetenc01 wrote:was wondering, since im a fairly big newb to MQ heh, where in this would i need to edit to make my bot cast an item for his spell. Like if my wiz bot had epic and i wanted buff1 to be click staff of the four. Just putting buff one as the item name didnt work :(
look in personal.inc more specifically at the do-bp sub.

User avatar
lasher
a lesser mummy
a lesser mummy
Posts: 71
Joined: Thu Dec 18, 2003 4:09 pm

Post by lasher » Thu Jan 01, 2004 6:57 pm

Flea wrote:Also getting a problem, or bug not sure, but when i Tell shaman, 'debuff' shaman then debuffs mob, however he then casts all spells on buff list on the mob.
Not happening in my version. Are you using any hacks, or did you change something?

McTisuk
orc pawn
orc pawn
Posts: 11
Joined: Thu Jan 01, 2004 6:46 am

Re: brain dump, omg so rambling!

Post by McTisuk » Thu Jan 01, 2004 10:43 pm

param0 is implied. those changes aren't needed unless I'm mistaken

edit: I just asked and confirmed that it was implied.
I figured, since the code worked sometimes, that they were implied - it works sometimes for me.
I was having a problem in those routines tho, under very specific circumstances. To nail it down, I was /echoing stuff everywhere and seeing where it ended up sticking. It turned out that it was in the spellcasting loop, called by those routines, because there was no target set properly. So, I began to look at where the target came from .. it came from higher up and got passed in, etc.

Eventually I was in a situation where I was echoing out the params being called in to those routines, then right inside the routines echoing what THEY saw the params as .. and getting nulls inside the routines.
eg, /echo @param0 or whatever it was about to use. Adding the (param0) fixed this, suddenly the echo that had been saying null changed to having the correct target.


Anyhow, up there I described the exact way to replicate the problem ... be a healer, not assist (combat code doing nothing). Have reason to then heal yourself or a watch target, but you MUST then get hit in this attempt., WHILE you are trying to do the heal, but after the heal section has begun.
Bingo, loop stuck trying to get the right target, processing locked until an event (such as a tell cmd request) causes it to bounce out of the loop.
At this point, it does the initial event processing, RE-attempts it's heal it was trying to do but couldn't due to targetting error being hit (usually works now because hits don't interrupt quite the same by chance), then does the asked for cmd, and then back to it's main parse loop unless anything else has been queued.

I DID play with the code in those sections to try and fix this, so other small changes I made might have been the real fix, but in testing, I would see /echo results like this:
/echo calling try-to-heal MyCharName
/echo just inside try-to-heal NULL

until I added the (param0) wherapon my output became
/echo calling try-to-heal MyCharName
/echo just inside try-to-heal MyCharName

The root of the problem I was trying to tie down tho is to do with the targetting of a spawn (pc whatever) you want to heal. REAL easy to simulate "getting hit in combat at the wrong moment" - Target no-one, healer on combat off, nuke or dmg yourself until you are below the caster heal % you've set, then run the macro. It processes a few times, then decides you need a heal. When it targets you, just entering the attempt loop, press escape to clear target. This is what the mob would do if it hit you (except it'd set target to IT. Either way it's the wrong target). Bot can't heal - fair enough, BUT it gets loop stuck, NOT exits gracefully, carries on processing, and comes back on next pulse for another attempt, maybe not getting hit that time.

All those healXXXtype routines that scan the lists of tank/caster, etc, have this problem, and you can kinda see it was an issue due to the target setting code in them. What needs to happen is to trace down the exact point it gets into a loop. When I did this, it was in the actual spellcast routine, due to not having a target set correctly. It jams in the casting routine itself and never leaves.
Maybe the solution is to fix the spellcasting routine to gracefully return more reliably, but the problem is actually that some point before the call to cast, the target switched, and the check target code doesn't manage to switch it back before it calls the attempt.

Just due to other problems I had, my spellcasting code actually records the target ID on entry, does it's other processing, and SETS IT AGAIN if target is not the same, just before it actually presses cast(and then waits).
I was seeing nulls passed into the spellcast routine, but on entry to it's calling healcastertype routine, target had value set correctly.

If my attempted fix doesn't resolve the problem, at least these descriptions should allow other folks to see the /cause/ of the "bot stops, then later casts the same spell twice, but hey, 2 heals is better than none!" messages people have been leaving for a while -)

While I'm talking about it, is there any way (not log-spewing) to do realtime stack listing or variable watching for MQ2? For debugging this kind of thing, it would be a huge help. Maybe a plugin idea? Add watch(variablename), to show current value all the time updated somewhere (like hps do), and then current callstack (with paramaters) would rock =p

I see another problem sometimes with genbot, same heal/combat setup - the bot sometimes gets switched on to attack mode when it gets hit, and of course I don't want it to (melee) attack. It also stops processing other reqs I think, but does respond to cmds and breaks out of it's loop.. But to track that down will be the same kind of issue as this one, lots of painful /echo debug spam spewing till you follow it down, then catch the "odd" call to the wrong place.
McTisuk ... just another macro writer~

Flea
a lesser mummy
a lesser mummy
Posts: 55
Joined: Fri Dec 26, 2003 4:56 am

Post by Flea » Thu Jan 01, 2004 11:35 pm

lasher wrote:
Flea wrote:Also getting a problem, or bug not sure, but when i Tell shaman, 'debuff' shaman then debuffs mob, however he then casts all spells on buff list on the mob.
Not happening in my version. Are you using any hacks, or did you change something?
Using original coding.

McTisuk
orc pawn
orc pawn
Posts: 11
Joined: Thu Jan 01, 2004 6:46 am

Re: Heya

Post by McTisuk » Thu Jan 01, 2004 11:39 pm

w00tz0r wrote: In botcore.inc

Sub MoveToAnchor

<snipped>

Is there a way to make the script cause the bot when returning to face in a little bit random direction? Or place a random pause between killing the mob and returning?
Basically just to make it appear more humanlike.
untested, not running eq atm, but here's my suggested change to implement the delay, not including your altered faces :

Code: Select all

Sub MoveToAnchor
[color=darkred]/declare donedelay local
   /varset donedelay 0[/color]
   /varset MyXLoc $char(x)
   /varset MyYLoc $char(y)
   /varset countdown 0
   :AnchorMoveLoop
   /if @IsAnchored==0 {
      /sendkey up up
      /return
   }
   /doevents
   /if n @Combatstatus==1 {
      /sendkey up up
      /return
   }
[color=darkred]  /if n @donedelay==0 {
| alter 50 to be suitable "longest"delay before bot moves.
   /delay $rand(50)
  /varset donedelay 1
  }[/color]
   /if "$char(state)"=="SIT" /stand

This should make it do a random delay( max of 50) before it begins the move home, ANY time it tries to move to anchor point. I am guessing it's this that "drives" the bot home once it's out of combat.
McTisuk ... just another macro writer~