Need help please with my Beastlord bot macro

Need some help with that macro you're working on or aren't quite sure how to get your macro to do something? Ask here!

Moderator: MacroQuest Developers

3boxer
orc pawn
orc pawn
Posts: 15
Joined: Fri Dec 12, 2003 11:12 am

Need help please with my Beastlord bot macro

Post by 3boxer » Sun Jan 04, 2004 8:26 pm

Hi folks. I'm having a little trouble with my beastlord macro (thanks to all who helped contribute code which comprises the macro btw). Here's the problem. I can get him to do most commands just fine. I can have him sit, stand, follow, etc and no problems. I can even tell him "attack" and he attacks fine.

However, AFTER I have him do the "attack" command, the macro won't accept any more commands. The macro doesn't end, it just won't do anything else. After issuing the original attack command after starting the macro, the beastlord attacks as he should. Once the mob dies however, the macro does a /call Main and then tells me the error "Variable name already defined". It looks like it's obviously trying to RE-declare the variables. After it gives this variable error, the macro appears to keep running (I don't get the "macro has ended" message), but then I can't issue any more commands - he just ignores them - even the /sit, /stand, etc ones.

Would someone mind taking a look and telling me what you think might fix it? I've worked with it a while and can't figure it out.

Thanks!

Code: Select all

|usage /mac beastlord "mastername" 
| 
|This macro is for a simple Beastlord bot. 
|It will follow simple commands as listed below. 

#include Spellcast.inc 
#chat tell 

#Event enraged "has become enraged" 
#Event toofar "Your target is too far away, get closer!" 

Sub Main 

/declare slowSpell local
/declare Master global 
/varset Master @Param0
/varset slowSpell "Drowsy"    

   :mainloop 
   /doevents 
   /goto :mainloop 
/return 

Sub Event_Chat 
  /if "@Param1"!="@Master" /return 
  /if "@Param2"~~"sit" /sit 
  /if "@Param2"~~"stand" /stand 
  /if "@Param2"~~"follow" /call Do-Follow 
  /if "@Param2"~~"assist" /call Do-Assist 
  /if "@Param2"~~"slow" /call Do-Slow 
  /if "@Param2"~~"attack" /call Do-Attack 
  /if "@Param2"~~"petattack" /call PetAttack 
  /if "@Param2"~~"petback" /call PetBack 
/return

Sub Do-Attack 
   /assist @Master  
   /delay 1s 
   /tell @Master Attacking %t 
   /pet attack 
   /call Combat 
/return 

Sub Combat 
   /attack on 
   :fight 
   /face fast 
   /doevents 
   /delay 0 
   /if "$target()"=="False" { 
     /sendkey up up 
     /call Main 
   } 
   /goto :fight 
/return 

Sub Do-Follow 
   /press esc 
   /press esc 
   /stand 
   /attack off 
   /target @Master
   /t @Master Following you 
      :followLoop 
      /if n $target(distance)>20 /sendkey down up 
      /if n $target(distance)<20 /sendkey up up 
      /face fast 
   /doevents 
   /delay 0 
   /if "$target()"=="TRUE" /goto :followLoop 
/return 

Sub Event_toofar 
    /sendkey down up 
      :farLoop 
      /if n $target(distance)<30 /sendkey up up 
      /face fast 
   /doevents 
   /delay 0 
   /if "$target()"=="TRUE" { 
     /if n $target(distance)>40 /goto :farLoop 
     /call Combat 
   } 
/return 

Sub Event_enraged 
  /attack off 
  /pet back off  
  /press esc 
  /t @Master RAGE!! 
  /delay 0 
/return 

Sub Do-Slow 
   /sit off 
   /assist @Master 
   /delay 1 
   /call Cast "@slowSpell" 
/return 

Sub PetBack 
   /t @Master Pulling Pet Back 
   /pet back off 
/return

Sub Do-Assist
   /assist Kruggan
/return

Goofmester1
a hill giant
a hill giant
Posts: 241
Joined: Thu Nov 06, 2003 4:26 am

Post by Goofmester1 » Sun Jan 04, 2004 9:06 pm

Try changing this

Code: Select all

/if "$target()"=="False" { 
     /sendkey up up 
     /call Main 
   } 
to this

Code: Select all

/if "$target()"=="False" { 
     /sendkey up up 
     /goto :mainloop 
   } 

3boxer
orc pawn
orc pawn
Posts: 15
Joined: Fri Dec 12, 2003 11:12 am

Post by 3boxer » Sun Jan 04, 2004 9:12 pm

Unfortunately when I changed that, it gives the following error:

Ending macro: Couldn't find label :mainloop

I'm guessing because you can't hop outside a subroutine like that?

Hrm still need to figure out what's wrong..

Any ideas?

3boxer
orc pawn
orc pawn
Posts: 15
Joined: Fri Dec 12, 2003 11:12 am

Post by 3boxer » Sun Jan 04, 2004 9:20 pm

Hmm I think I may have figure it out by just putting a /return in there instead of a /goto Main as shown below. Initial testing looks good.

Code: Select all

Sub Combat 
   /attack on 
   :fight 
   /face fast 
   /doevents 
   /delay 0 
   /if "$target()"=="False" { 
     /sendkey up up 
     [b]/return[/b]
   } 
   /goto :fight 
/return

User avatar
Bad Karma
a snow griffon
a snow griffon
Posts: 346
Joined: Sat Nov 22, 2003 9:34 pm
Contact:

Post by Bad Karma » Sun Jan 04, 2004 9:25 pm

First, what happens if you /endmac after getting "Variables already defined"? Does it tell you "the current macro has ended", or "cannot end a macro when one isn't running"? If I remember correctly from my own experiences with this, it should abort the macro. If not, this is what I believe might be happening. I'm doing this in my head right now at work, so I can't do any testing...it's just a theory at this point, but might help.

Code: Select all

Sub Combat
   /attack on
   :fight
   /face fast
   /doevents
   /delay 0
   /if "$target()"=="False" {
     /sendkey up up
     /call Main
   }
   /goto :fight
/return
Here's what I'm seeing it do, correct me if I'm wrong...

The mac goes from: Main --> Chat --> Attack --> Combat
While in the :fight loop, there is a /call back to Main if you loose your target for any reason (ie: mob dies).
So, now you're back in Main, but never really finished Combat. The next /return that you encounter, then, would normally send you back to Main, but you never really finished doing Combat.
Therefore, the next /return that you encounter comes from your Chat events, which sends you back to Combat, rather than Main, like it is supposed to.
Once it gets back to Combat, it executes the next command, which is /goto :fight, where it again encounters the /call Main because there is no target.
The result is an endless loop between these events. What happens if you target something? It should resume fighting, if I'm tracking this right in my head.


On a side note, I notice on a couple of your movement routines you do a /face fast AFTER doing your move forward/check distance. Wouldn't it be more accurate to /face first, then /sendkey? Might save you a step or two in overshooting your target and running around in circles. Just a thought, anyway.

User avatar
Bad Karma
a snow griffon
a snow griffon
Posts: 346
Joined: Sat Nov 22, 2003 9:34 pm
Contact:

Post by Bad Karma » Sun Jan 04, 2004 9:26 pm

LOL...looks like you saw what I was while I wrote my message. I think the fix you posted will work.

3boxer
orc pawn
orc pawn
Posts: 15
Joined: Fri Dec 12, 2003 11:12 am

Post by 3boxer » Sun Jan 04, 2004 9:33 pm

Hehe thanks Bad Karma :) Aye it appears to be working. Thanks for the tip on /face fast - I'm tweaking it now with your suggestions. One problem I'm noticing while I'm testing this (in Paineel newbie garden) is that whenever I send the attack order to my bot, he often looks at the ground when attacking a mob (such as a bat, rat, etc). What this ends up causing is the "You cannot see your target" deal.

Not really sure what to do about that yet. If the answer hits you, I'm appreciative in advance!

User avatar
Bad Karma
a snow griffon
a snow griffon
Posts: 346
Joined: Sat Nov 22, 2003 9:34 pm
Contact:

Post by Bad Karma » Sun Jan 04, 2004 9:52 pm

That's because the /face command uses the mob height (size), not the Z-axis. If the mob is 1' tall, but flying 6' in the air, you're going to look at the ground.

Quick fix for this might be to use /face 0, which will center your view (as if hitting NUM_5). (I think I read an option of /face nolook[b/] somewhere, too.) I hope I remembered this correctly. Sucks doing this from work...I can't reference any of my macros. lol

3boxer
orc pawn
orc pawn
Posts: 15
Joined: Fri Dec 12, 2003 11:12 am

Post by 3boxer » Sun Jan 04, 2004 10:03 pm

Thanks bud - ill give it a try :)

3boxer
orc pawn
orc pawn
Posts: 15
Joined: Fri Dec 12, 2003 11:12 am

Post by 3boxer » Sun Jan 04, 2004 10:44 pm

Ok I'm relentless tonight so I'll bug you some more hehe. I've been searching around, but haven't been able to find an example of this.

Any thoughts on how to add an event that would fire in the event that the Beastlord's health dropped below 80%? I was initially thinking it would need to go inside of the Main subroutine to constantly monitor the BST's health and loop over and over. In the event it drops below 80%, it could shoot a tell to the "master" and warn him that he's taking damage. However, I'm now wondering if it would need to be an Event instead (not sure what to check for other than something like "hits you for X points of damage") so that it could fire regardless of whether the bot was currently inside of it's Attack routine, Follow routine, or wherever.

Any ideas on best practice?

Thanks.

User avatar
Bad Karma
a snow griffon
a snow griffon
Posts: 346
Joined: Sat Nov 22, 2003 9:34 pm
Contact:

Post by Bad Karma » Mon Jan 05, 2004 12:04 am

See if this works smoother in your Combat sub:

Code: Select all

Sub Combat
   /attack on
   :fight
   /face fast
   /doevents
   /delay 0
   [b]/if $target(state)==DEAD /return[/b]
   /goto :fight
/return
I'm working on the other question you had. I'm at work right now, and it's been a little busy since lunch.[/b]

User avatar
Bad Karma
a snow griffon
a snow griffon
Posts: 346
Joined: Sat Nov 22, 2003 9:34 pm
Contact:

Post by Bad Karma » Mon Jan 05, 2004 12:20 am

That's probally going to depend on what you are going to do with it if/when he does take damage or get attacked.

If all you want it to do is inform you that you are being attacked, you can trap the event like this:

Code: Select all

#Event UnderAttack "hits YOU for"

Sub Do-UnderAttack
   /t @Master HELP!  HELP!  I'm being oppressed!
/return
That will check during your main loop, and your Combat sub, as it's currently written. You will then be spammed throught the course of your battle.

If all you want to do is determine wether or not you have dropped below 80% health, you could do this:

Code: Select all

   /if n $char(hp,pct)<=80 {
   ...insert whatever you want it to do here...
   }
You could use this to trigger a heal spell, send a tell to @Master, or run like a bish. You can also include a check to see if you are currently attacking so it does nothing if in combat (where you would normally expect to take damage), or wait until you reach a different percent of health before doing something.

I was going to include an example of checking health && attack status, and a few other things, but it's a little busy here still. That should be enough to get you started, though.

Oh yeah...you would insert that code anywhere in your mac that you want to check on this, depending on what you want to do with it. If you put it in your Main loop, you will want to set it up to call to a sub that further checks certain states of your character. /if attacking... /if whatever... so that if you are already in combat, it will heal, or request a heal, if you are just moving, it might send a tell for help, if you are weaving baskets, it could eat a sandwich....you get the idea. =)

User avatar
Bad Karma
a snow griffon
a snow griffon
Posts: 346
Joined: Sat Nov 22, 2003 9:34 pm
Contact:

Post by Bad Karma » Mon Jan 05, 2004 2:32 am

Bad Karma wrote:

Code: Select all

   /if $target(state)==DEAD /return
I thought about this on my way home, and don't think this will work for what you want it to do, because when the mob dies, you will loose your target, anyway. Since you don't have a target verifier in your mac (to make sure you're still on the right target, or even on a target at all), there is nothing for it to check the status of.

Since you will automatically stop attacking when the mob dies, a better check might be to see if your current character state is Attack.

Code: Select all

/if n $combat!=TRUE /return
This can also be combined with the Check HP% posted above to determine if you need to start attacking if you get jumped...

3boxer
orc pawn
orc pawn
Posts: 15
Joined: Fri Dec 12, 2003 11:12 am

Post by 3boxer » Mon Jan 05, 2004 12:28 pm

Wow - can I hire you? =) Thanks for your help on all this. I understand and appreciate it. I think my goal is simply to msg my main character (the SK) and let him know - "HELP! I'm dying back here!", letting me know so that I don't pull another mob and can run back and help him out. Ideally - one would just think I could just notice when my BST's health is going down in the group window - but I've played long enough to realize that it's easy to overlook sometimes, leaving me wondering, um - why is my BST dead? I think the attack state method will work great.

Thanks bud!

User avatar
Bad Karma
a snow griffon
a snow griffon
Posts: 346
Joined: Sat Nov 22, 2003 9:34 pm
Contact:

Post by Bad Karma » Mon Jan 05, 2004 8:50 pm

There's a gorup window? lol
I never look at that thing. I'm always too damn buys in /tellhell or running the guild or allaince. What you're doing has merit. I have similar code I use....but rarely /mac in group, unless it's just a canni mac running in the background to keep my mana up. I'm working on a mac that will automate a lot of the redundant processes I'm doing manually in groups, to free me up for other crap people seem to think I'm the only one that can handle.

Take a look at GenBot. Seriously. A lot of what you want to do is already in there, and it's a great place to learn. Yeah, it's huge, but after you spend a bit of time looking it over, you'll understand it pretty simply. There are other smaller and more specialized macs out there, also. All excellent sources for writing your own.

If you still want to hire me after all that....$$$