sipetwar.mac - slightly improved pet warrior macro

Macro depository for macros written before the user variable changes that broke all of them.

Moderator: MacroQuest Developers

fryfrog
a hill giant
a hill giant
Posts: 271
Joined: Fri Jun 20, 2003 5:37 am

sipetwar.mac - slightly improved pet warrior macro

Post by fryfrog » Tue Jun 24, 2003 4:09 am

Slightly Improved Pet Warrior macro - Suggestions Welcome! (but maybe not implemented due to lazyness, never hurts to try right?)

Future Features:
- Fight behind (for when you aren't MT or something... not that that ever happens right?)
- "disc X" command to manually set off a disc

Updates:

*NEW* - Smart Kick/Bash. At start of fight, it decides weather the mob is a caster, caster and gater or plain old melee. If it is a caster or gater, it only kick/bashes when the mob tries to cast or gate. If regular melee, it should spam kick.

*FIX* - this entire time i had no idea why the "Zoning" event wasn't working AT ALL. it turned out to be that i called the sub "Event_Loading" and all the references were to #Event Zoning (duh, hello).

* added a "UseDisc" variable so you can control weather bot uses /disc evasive or /disc defensive. Default is to use evasive on 64 and below, defensive on mobs 65 and above. Tweak the levels if you want, around line 700 (search for /disc). At some point I will probably add a "disc X" so you can manually trigger a /disc if you like.
* modified the keep close to mob code to be a bit more rog and rear fighting class friendly. when the mob is moving very slow (.20, where rs3 walk speed is about .40) it will use /press to get close instead of /sendkey down. If the mob is moving faster, it uses sendkey so it can keep up easily.
* Gating and Gated detection SHOULD work. A gating mob will cause the bot to do a "/g $t trying to gate". fairly simple and shouldn't be to obvious. Could add a miss spelling or perhaps randomly choose from 1 of 5 messages to make it look more "real". If the mob gates, attack should cease so we don't go running off after mobs (3 guesses why i added this... and the first 2 don't).
* Taunt clean up. If taunt is off, the bot will not beg or disarm. Otherwise if taunt is on smart mode (recommended) or dumb mode, it will continiously taunt.
* added an "offtank" command and a taunt default. Now, even if you have taunt off (to be NOT mt on a raid maybe) but need to actually tank a mob for some reason... just "offtank <mob id>" (like attack).
* Smart Taunting! If the mob is facing us, we don't use taunt. That is how most warriors play, and it has a few advantages. As soon as the mob turns, taunt is up and used. In limited testing, agro was kept much better. It is also believe that continiously using taunt is detrimental to a warrior keeping agro. The syntax is "/tell bot taunt smart" to turn it on, "taunt dumb" to turn it off.
* Mez, Break Mez and Enrage SHOULD only be triggered if it is a mob with the same name as the one targeted. This isn't ideal, but it should help a lot more. The detect mez sucks though because there are so many different Mez lines from chanter spells.
* There were a lot of places where strings did not have " " around them, so you may have noticed a few "could not find comparison operator in 'a'" or some shit like that. I think i have made all numerical comparisons have a "n" and all string compares have " " around both the left and right part of the comparison operator.
* Evasive should be engaged for mobs that are like 59 - 63, and defensive for mobs 63+. I will add a "use disciplines" option, and probably a Min/Max level for each so it can be tweaked better. From what I have read, evasive is the prefered /disc for about 98% of mobs, especially the ones you would be killing for exp.

* Some general code tweaking and fixes, I have been doing small things here and there as i noticed them.
* Added some code to the Attack portion that checks to see if the target is kind of high and will try to use /disc evasive or /disc defensive if its high enough
* Added a few checks to see if the "target" was a merchant or a PC (we don't need him trying to attack one of those on accident).
* I found quite a few behavioral problems that could be traced down to doing a numeric comparison but forgetting the "n" in "/if n $X". I also traced down quite a few instances where i had "/if X" when it should have been "/if $X" which explained another bunch of bugs.
* Added the farm command :)

Features:
*NEW* farm command given (i think?) a single "word" the bot will continiously go after them until they are all dead!
* behaves very much like any eq pet with similar commands
* semi-intelligent watching for mezes, broken mezes, enrage and end of enrage
* guard a spot or the master (responding to creatures who attack it)
* follow the master (doesn't respond to being attacked)
* sit and stand (omg, wow how did i do that!)
* pull a creature (careful how you use it!) by running to it, tagging it and running back
* turn on and off taunting, as well as sending pet in to just taunt (eq pets can't do that!)
* report his health and hopefully his buffs (coming soon maybe?)
* joins your group when you invite it
* watches its own health and cries like a sissy if he thinks he is going to die
* will get you all the chicks
Drawbacks:
* the master needs to be IN the zone when you start the script, and if you both zone... and it zones first you will need to /tell bot reset. sometimes even if you zone first he will need a reset.
* pretty much requires that you group with it, perhaps we can fix this later
* it may not behave entirely as expected, be ready to /tell bot exit!
* not a plat macro

Code: Select all

|Summary:  allows one to control a melee charactor (specifically warrior right now) in much the
|the same way as a pet.  The commands used to control are very similar and the behavior is also.
|you probably want to find the "/varset Debug 1" line and change it to 0 so you are not spammed.

|Command Usage:
|Attack - /tell bot attack $target(id) #id of the target, so mq needs to run on Master
|Taunt - /tell bot taunt [$target(id)] OR [on] OR [off] OR [smart] OR [dumb]
|   $target(id) - bot will run to target and taunt until told to stop
|   on - bot will taunt during attack
|   off - bot will NOT taunt during attack
|   smart - uses intelligent taunting, only taunts when mob is NOT facing bot
|   dumb - switches back to taunt all the time (same as issuing "on" again)
|Sit - /tell bot sit #bot will sit down (turns revenge off)
|Stand - /tell bot stand #bot will stand up (turns revenge on)
|Goto - /tell bot goto Y X #note that it looks reversed, but just put in same order as what you see in /loc
|Follow - /tell bot follow #bot follows Master (turns revenge off)
|Guard - /tell bot guard [me] [here] OR [y] [x] (turns revenge on)
|   here - bot will guard where he is standing, retaliating against anything that attacks him
|   me - bot will follow you, retaliating against anything that attacks him
|   x y - bot will guard loc, retaliating against anything that attacks him
|Report - /tell bot report #returns pct hp cur hp/max hp and buffs
|Back - /tell bot back #bot will back off and return
|Stop - /tell bot stop #bot stops what its doing (turns revenge off)
|Exit - /tell bot exit #stops the macro (no more commands!)
|Reset - /tell bot reset #if the bot zones and the Master is not in the zone, the script loses MastID, this fixes it

|Details:
|When done attacking, the bot will return to the Master and /follow OR return to loc if guard has been defined.
|The bot should also stop attacking at enrage OR mez (or both?).  Upon un-enrage, it should start attacking again.
|Not sure what happens if mobs near by are mezed/enraged, probably confuses the script... but better than attacking
|a mezed/raged mob.  I have also added a check for being attacked, and IF the bot is in certain modes (guarding) it
|will wait 5 seconds then start attacking.

|Things YOU DO!:
|Set the "Master" to your chars name, set the "Botname" to the pets name.  Also might need to change the "Forward" 
|and "Backward" keys if you  have them set to something different.
|Also check in the Sub Main for the |# Commented variables and set as you like.

|Future Additions:
|-Possibly add looting commands (probably not though)

|Thanks:
|to codewarrior who posted his petwarrior.mac which i used as a basis for understanding
|macro quests syntax and for ideas on how to accomplish certain things.  I'm sure I have also
|taken parts from others scripts, so thanks to them as well.

|Master and Bots name
#define Master Master!
#define Botname Bot!

|Forward and Backward keys 
#define Forward up
#define Backward down

|Easier to read variables 
#define BreakLoop v0
#define TargetID v1
#define TargetName v2
#define OkToFight v3
#define X v5
#define Y v6
#define MastID v7
#define Debug v9
#define MyXLOC v10
#define MyYLOC v11
#define Retaliate v12
#define DoTaunt v13
#define CheckHealth v14
#define DefaultStance v15
#define TempVar v16
#define GuardHeading v17
#define MobShouldFace v20
#define TauntDefault v21
#define MobEnraged v22
#define UseDisc v23
#define MobGates v24
#define MobCasts v25
#define SmartKB v26
#define StopOnMezBreak v27

|Special events 
#Event Zoning "LOADING, PLEASE WAIT..." 
#Event Enrage "has become ENRAGED." 
#Event UnEnrage "is no longer enraged." 
#Event BrokeMez "has been awakened by"
#Event Invited "To join the group, click on the 'FOLLOW' option, or 'DISBAND' to cancel" 
#Event GettingHit "YOU for"
#Event MobGating "begins to cast the gate spell."
#Event MobGated "Gates."
#chat tell
#turbo

Sub Main
   
   |************************************************************************************|
   |                    Variables that are user modifiable                              |
   |************************************************************************************|
   |# Set this to 1 if you want the bot to start out vendictive
   /varset Retaliate 0
   |# Set this to 0 if you want the bot to start out NOT taunting
   /varset DoTaunt 1
   |# Set this to 0 if you dont want the bot to check its health
   /varset CheckHealth 1
   |# Set this to 1 if you want to see Debuging info
   /varset Debug 0
   |# Set this to 1 for none, 2 for follow, 3 for guard me, 4 for guard here for startup
   |# and after zoning
   /varset DefaultStance 1
   |# Set this to 0 for no taunt, 1 for dumb taunt and 2 for smart taunt
   /varset TauntDefault 2
   |# Smart Kick/Bash will try to kick/bash when a CASTER MOB tries to cast a spell OR gate.
   |# On non-casting mobs, it will just spam bash/kick like normal.
   /varset SmartKB 1
   |# If you want the bot to stop attacking when it sees mez broken, set to 1.
   /varset StopOnMezBreak 1
   |# Set to 0 to NOT use /disc, set to 1 to use. If you want to modify which /disc is 
   |# used, search the file for /disc and replace with what ever you want.  You can also 
   |# tweak the level set offs if you like.  approx line 700
   /varset UseDisc 1
   |************************************************************************************|
   
   /if n $Debug==1 /echo Starting Slightly Improved Warrior Pet script...
   /press ctrl
   /press shift
   /press alt
   |# I had to pick a number to signify that we shouldn't go back to a loc.
   |# I doubt that any zone has two elite points :)
   /varset X 31337
   /varset Y 31337
   /varset DoTaunt $TauntDefault
   /call SetMastID
   /call DoStance $DefaultStance
   
   
   |# This is where we start to loop and actually become the bot
   :MainLoop
   /doevents Zoning
   /doevents Invited
   /doevents GettingHit
   /doevents Chat
   /if $MastID==NULL /call SetMastID
   /if $target()==TRUE /if $target(type)!="NPC" /target clear
   /if $gm==TRUE /tell Master There is a GM in the Zone
   /varset BreakLoop 0
   |/delay 5
   /if n $CheckHealth==1 /if n $char(hp,pct)<=20 /tell Master OMG I am at $char(hp,pct) health... I am going to die master!
   |# Sends us back to the top to start over again
   /goto :MainLoop
/return 

|# The main handler, the Event_Chat that is called any time a /tell comes in
Sub Event_Chat 
   /if "$p1"=="Master" { 
      |# Out of group follow
      /if "$arg(1,"$p2")"=="stick" {
		 /target id MastID
         :Follow
            /call StickToTarget
            /delay 4
            /doevents
         /if BreakLoop!=1 /goto :Follow
      }
      
      |# The offtank command will tank a mob using taunt no matter what
      /if "$arg(1,"$p2")"=="Tank" {
         /if n $DoTaunt==0 {
            /varset TempVar $DoTaunt
            /varset DoTaunt $TauntDefault
         }
         /sit off
         /press Backward
         /target id $arg(2,"$p2")
         |# Some checks to make sure what we are about to attack is what we were TOLD to attack
         /if n $target(id)==$arg(2,"$p2") /if "$target(type)"!="PC" {
            /tell Master OFF TANKING: $target(level) $target(name,clean) master!
            /varset OkToFight 1
            /call Attack "$arg(2,"$p2")"
            /call AfterAttack
            /if n $TempVar>0 {
               /varset DoTaunt $TempVar
            }

         } else {
            /tell Master That is not a valid target, master!
         }
         /varset BreakLoop 1
      }

      |# The pull command, takes $target(id) and runs to it, smacks it and comes back
      /if "$arg(1,"$p2")"=="Pull" {
         /press Backward
         /target id $arg(2,"$p2")
         /if n $target(id)==$arg(2,"$p2") /if "$target(type)"!="PC" {
            /tell Master Pulling $target(name,clean) from $target(distance) away master!
            /call GotoBody $target(id)
            |# We dont to get hit on the way back and start attacking it
            /if n $Retaliate==1 {
               /varset TempVar 1
               /varset Retaliate 0
            }
            |# Run up to mob, attack, taunt, kick and run back
            /attack on
            /if n $char(ability,taunt)>0 /doability taunt
            /if n $char(ability,kick)>0 /doability kick
            /delay 1s
            /attack off
            /call AfterAttack
            |# If we had to suspend vengence... re-activate it here
            /if n $TempVar==1 /varset Retaliate 1
         }
      }
      
      |# The help command, lists what the bot can do.
      /if "$arg(1,"$p2")"=="Help" { 
         /tell Master Attack [TargetID], Pull [TargetID], Taunt [TargetID], Guard [here] or [me] or [x y], Report, Back, Stop, Sit, Stand, Follow, are my commands master! 
      } 
      
      |# This command reports hp information and IF it ever works... buffs too.
      /if "$arg(1,"$p2")"=="Report" {
         /tell Master HP: $char(hp,pct)% $char(hp,cur) / $char(hp,max)
         |/if n $Debug==1 /echo Buffs: $if(n,"$char(buff,$if(n,"$char(buff,$if(n,"$char(buff,$if(n,"$char(buff,$if(n,"$char(buff,$if(n,"$char(buff,$if(n,"$char(buff,$if(n,"$char(buff,$if(n,"$char(buff,$if(n,"$char(buff,f,1)"!="NULL",,"1 - $char(buff,1)") $if(n,"$char(buff,2)"!="NULL",,", 2 - $char(buff,2)") $if(n,"$char(buff,3)"!="NULL",," 3 - $char(buff,3)") $if(n,"$char(buff,4)"!="NULL",," 4 - $char(buff,4)") $if(n,"$char(buff,5)"!="NULL",," 5 - $char(buff,5)") $if(n,"$char(buff,6)"!="NULL",," 6 - $char(buff,6)") $if(n,"$char(buff,7)"!="NULL",," 7 - $char(buff,7)") $if(n,"$char(buff,8)"!="NULL",," 8 - $char(buff,8)") $if(n,"$char(buff,9)"!="NULL",," 9 - $char(buff,9)") $if(n,"$char(buff,10)"!="NULL",," 10 - $char(buff,10)") $if(n,"$char(buff,11)"!="NULL",," 11 - $char(buff,11)") $if(n,"$char(buff,12)"!="NULL",," 12 - $char(buff,12)") $if(n,"$char(buff,13)"!="NULL",," 13 - $char(buff,13)") $if(n,"$char(buff,14)"!="NULL",," 14 - $char(buff,14)") $if(n,"$char(buff,15)"!="NULL",," 15 - $char(buff,15)")
         /tell Master Buffs $if(n,"$char(buff,1)"!="NULL",,"1 - $char(buff,1)") $if(n,"$char(buff,2)"!="NULL",," 2 - $char(buff,2)") $if(n,"$char(buff,3)"!="NULL",," 3 - $char(buff,3)") 
         |$if(n,"$char(buff,4)"!="NULL",," 4 - $char(buff,4)") $if(n,"$char(buff,5)"!="NULL",," 5 - $char(buff,5)") $if(n,"$char(buff,6)"!="NULL",," 6 - $char(buff,6)") $if(n,"$char(buff,7)"!="NULL",," 7 - $char(buff,7)") $if(n,"$char(buff,8)"!="NULL",," 8 - $char(buff,8)") $if(n,"$char(buff,9)"!="NULL",," 9 - $char(buff,9)") $if(n,"$char(buff,10)"!="NULL",," 10 - $char(buff,10)") $if(n,"$char(buff,11)"!="NULL",," 11 - $char(buff,11)") $if(n,"$char(buff,12)"!="NULL",," 12 - $char(buff,12)") $if(n,"$char(buff,13)"!="NULL",," 13 - $char(buff,13)") $if(n,"$char(buff,14)"!="NULL",," 14 - $char(buff,14)") $if(n,"$char(buff,15)"!="NULL",," 15 - $char(buff,15)")
      }
      
      |# The attack command, uses $Target(ID)
      /if "$arg(1,"$p2")"=="Attack" {
         /sit off
         /press Backward
         /target id $arg(2,"$p2")
         |# Some checks to make sure what we are about to attack is what we were TOLD to attack
         /if n $target(id)==$arg(2,"$p2") /if "$target(type)"!="PC" {
            /tell Master Attacking: $target(level) $target(name,clean) master!
            /varset OkToFight 1
            /call Attack "$arg(2,"$p2")"
            /call AfterAttack
         } else {
           /tell Master That is not a valid target, master!
         }
         /varset BreakLoop 1
      }

      /if "$arg(1,"$p2")"=="Farm" {
         /tell Master attempting to harvest the hell out of $arg(2,"$p2"), master!
	 /varset OkToFight 1
	 /sit off
	 /press Backward
	 :KeepFarming
	 /attack off
	 /doevents
         /target npc $arg(2,"$p2")
         /delay 5
         /if n $BreakLoop!=1 /if $target()==TRUE /if $target(level)<=50 {
            /tell Master Attacking a level $target(level) $target(name) from $target(distance) away, master!
            /call Attack $target(id)
            /attack off
            /delay 5
            /if n $BreakLoop!=1 /goto :KeepFarming
         }
         /tell Master There are no more $arg(2,"$p2") to harvest the hell out of, master!
         /call AfterAttack
         /varset BreakLoop 1
      }


      |# The sit command, turns off retaliation and sits
      /if "$arg(1,"$p2")"=="Sit" {
         /if n $Retaliate==1 {
            /varset Retaliate 0
            /varset TempVar 1
         }
         /tell Master Sitting down master! 
         /press Backward
         |# Because for some reason, sony is stupid...
         /sit off 
         /sit on 
         /varset BreakLoop 1 
      }
      
      |# If retaliation was turned on, and sit was used... turns retaliation back on and stands up
      /if $arg(1,"$p2")==Stand {
         /if n $TempVar==1 /varset Retaliate 1
         /tell Master Standing up master!
         /sit off
         /varset BreakLoop 1
      }
      
      |# Takes Y and X parameters and sends bot to them
      /if "$arg(1,"$p2")"=="Goto" {
         /sit off
         /if n $arg(2,"$p2")!=NULL /if n $arg(3,"$p2")!=NULL /if $X!=31337 /if $Y!=31337 /call GotoLoc $arg(3,"$p2") $arg(2,"$p2")
         /varset BreakLoop 1
      } 
      
      |# Tells bot to follow master, turns retaliation off
      /if "$arg(1,"$p2")"=="Follow" { 
         /varset X 31337
         /varset Y 31337
         /varset Retaliate 0
         /sit off
         /target id $MastID
         /tell Master Following $target(name) master!
         /if n $Debug==1 /echo Following $target(name) from $target(distance) away.
         |# Face target and give it a moment to happen
         /face nopredict id $MastID
         /delay 8
         |# No reason to use anything fancy if we are close enough to /follow
         /if n $target(distance)>150 /call GotoBody $MastID
         /follow
         /varset BreakLoop 1
      } 
      
      |# Turns taunting on/off OR sends bot to a mob to taunt... you know, in case
      |# you are not the MT and shouldn't get agro.
      /if $arg(1,"$p2")==Taunt {
         /if "$arg(2,"$p2")"=="On" {
            /tell Master Taunting on master!
            /varset DoTaunt 1
         } else /if "$arg(2,"$p2")"=="Off" {
            /tell Master Taunting off master!
            /varset DoTaunt 0
         } else /if "$arg(2,"$p2")"=="Smart" {
            /tell Master Smart taunting activated master!
            /varset DoTaunt 2
         } else /if "$arg(2,"$p2")"=="Dumb" {
            /tell Master Smart taunting deactivated master!
            /varset DoTaunt 1
         } else {
            /target id $arg(2,"$p2") 
            /if n $target(id)==$arg(2,"$p2") {
               |# We don't want to start beating on something we are just supposed to taunt
               /varset Retaliate 0
               /tell Master Taunting $target(name,clean) until you tell me to stop master!
               /press Backward
               /call Taunt $target(id)
               /varset BreakLoop 1
            }
         }
      }

      |# Guard command takes "here" "me" or "Y" "X" locs and guards them (retaliation on)
      /if "$arg(1,"$p2")"=="Guard" {
         |# We definatly want to fight and protect ourselves in "gaurd" mode
         /varset Retaliate 1
         /varset OkToFight 1
         /if "$arg(2,"$p2")"=="Here" {
            |# Stop follow, record loc and heading
            /press Backward
            /varset X $char(x)
            /varset Y $char(y)
            /varset GuardHeading $char(heading)
            /tell Master Guarding $Y, $X facing $GuardHeading master!
         } else /if "$arg(2,"$p2")"=="Me" {
            |# Set to those elite cords and follow mastuh
            /varset X 31337
            /varset Y 31337
            /sit off
            /target id $MastID
            /if n $Debug==1 /echo Following $target(name) from $target(distance) away
            /tell Master Guarding $target(name) master!
            /face nopredict id $MastID
            /delay 8
            /if n $target(distance)>150 /call GotoBody $MastID
            /follow
         } else /if n $arg(3,"$p2")!=NULL /if n $arg(4,"$p2")!=NULL {
            |# Use provided chords and current heading to setup guard here...
            |# I hope no one uses this :)
            /varset Y $arg(3,"$p2")
            /varset X $arg(4,"$p2")
            /varset GuardHeading $char(heading)
            /tell Master Guarding $Y, $X facing $GuardHeading master!
         }
      }
      
      |# Recalls the bot immediatly to master or its guard loc
      /if "$arg(1,"$p2")"=="Back" { 
         /tell Master Coming back master!
         /attack off
         /varset Retaliate 0
         /varset OkToFight 0
         /call AfterAttack
         /varset BreakLoop 1
      }
    
      |# Attempts to stop the bot from doing what ever the hell it is doing
      /if "$arg(1,"$p2")"=="Stop" { 
         /tell Master Stopping what I am doing master!
         /attack off
         /target clear
         /press Backward
         /varset Retaliate 0
         /varset BreakLoop 1
         /varset OkToFight 0
      } 
      
      |# If all else fails, we can always exit the script
      /if "$arg(1,"$p2")"=="Exit" { 
         /tell Master Stopping it all master!
         /attack off
         /target clear
         /press Forward
         /press Backward
         /varset BreakLoop 1 
         /endmacro
      } 
      
      |# Resets the Owner's ID which is used extensively (and can be broken if pet finishes zoning before owner)
      /if "$arg(1,"$p2")"=="Reset" { 
         /call SetMastID
      } 
   } else /if "$p1"!="Master" /tell Master I have have recieved a private tell from $lasttell master! 
/return

|# This event is called by the phrase "YOU for".  We then check to see if it also contains the phrase
|# "points of damage." and just to double check we look at the OkToFight variable and then double check that
|# it was not in any "say" or "tell".  If the target is NOT an NPC, we clear our target.
|# After that, we check to make sure eq is not in combat, the target IS an NPC AND we are in retaliation mode
Sub Event_GettingHit
   /if "$p0"~~"points of damage." /if n $OkToFight==1 /if "$p0"!~"say" /if "$p0"!~"tell" {
      /if $target()==TRUE /if "$target(type)"!="NPC" /target clear
      /if $target()==TRUE /if $combat==FALSE /if $target(type)=="NPC" /if n $Retaliate==1 {
         /if n $Debug==1 /echo I am being attacked by $target(name,clean)!
         /tell Master I am being attacked by $target(name,clean), attacking in 2 seconds master!
         /delay 2s
         /press Backward
         /call Attack $target(id)
      }
   }
/return

|# Triggered by zoning, we reset our variables and get ready to do it all again.
Sub Event_Zoning 
   /if n $Debug==1 /echo Zone detected, resetting everything
   /press Forward
   /press Backward
   /attack off
   /varset X 31337
   /varset Y 31337
   /varset BreakLoop 0
   /varset TargetID 0
   /varset TargetName 0
   /varset OkToFight 1
   /varset ToldAboutGM 0
   /call SetMastID
   /call DoStance $DefaultStance
/return 

|# This should help us to keep from attacking enraged mobs (eating rage)
Sub Event_Enrage
   /if "$p0"~~"botname" /return
   /if "$p0"~~"$target(name,clean)" {
      /attack off
      /delay 5
      /varset MobEnraged 1
      /if n $Debug==1 /echo ENRAGE DETECTED, attack off!
   }
/return 

|# This should let us attack a mob AFTER it is done raging
Sub Event_UnEnrage 
   /if "$p0"~~"$target(name,clean)" {
      /if n $Debug==1 /echo ENRAGE over, attack on!
      /varset MobEnraged 0
      /attack on
      /delay 5
   }
/return 

|# This should stop us from fighting if we break mez.
Sub Event_BrokeMez
   /if "$p0"~~"Botname" {
      /attack off
      /varset OkToFight 0
      /varset BreakLoop 1
      /if n $Debug==1 /echo BROKE MEZ DETECTED, attack off!
   }
/return

|# Watching for invite message, we join.
Sub Event_Invited 
   /if n $Debug==1 /echo Invite recieved, joining group in 2 seconds
   /delay 20
   /invite
/return

Sub Event_MobCasting
   /if "$p0"~~"$target(name,clean)" {
      /if n $char(ability,slam)>0 /doability slam
      /if n $char(ability,kick)>0 /doability kick
   }
/return

Sub Event_MobGating
   /if "$p0"~~"$target(name,clean)" {
      /g %t trying to gate
      /if n $char(ability,slam)>0 /doability slam
      /if n $char(ability,kick)>0 /doability kick
   }
/return

Sub Event_MobGated
   /if "$p0"!~"say" /if "$p0"!~"group" /if "$p0"!~"out of character" /if "$p0"!~"shout" /if "$p0"!~"guild" /if "$p0"~~"$target(name,clean)" {
      /tell Master Mob Gated, stopping attack.
      /varset BreakLoop 1
      /varset OkToFight 0
   }
/return

|# This is used to take care of how we behave at script start and after zoning
Sub DoStance
   /target id $MastID
   /if n $p0==2 /if $target()==TRUE {
      /varset X 31337
      /varset Y 31337
      /varset Retaliate 0
      /sit off
      /tell Master Following $target(name) master!
      /if $Debug==1 /echo Following $target(name) from $target(distance) away.
      /face nopredict id $MastID
      /delay 5
      /if $target(distance)>=150 /call GotoBody $MastID
      /follow
      /return
   } 
   /if n $p0==3 /if $target()==TRUE {
      /varset X 31337
      /varset Y 31337
      /varset Retaliate 1
      /sit off
      /target id $MastID
      /tell Master Guarding $target(name) master!
      /if n $Debug==1 /echo Guarding $target(name) from $target(distance) away
      /face nopredict id $MastID
      /if $target(distance)>=150 /call GotoBody $MastID
      /follow
      /return
   } 
   /if n $p0==4 (
      /press Backward
      /varset X $char(x)
      /varset Y $char(y)
      /varset GuardHeading $char(heading)
      /varset Retaliate 1
      /tell Master Guarding $Y, $X facing $GuardHeading master!
      /return
   } else {
      /tell Master Just standing here master!
      /varset X 31337
      /varset Y 31337
      /varset Retaliate 0
   }
/return

|# This will reset the ID of the owner, or fail if they are not in the zone
Sub SetMastID
   /target pc Master
   /if $target()==TRUE {
      /varset MastID $target(id)
      /tell Master ID has been set to $MastID master!
      /if n $Debug==1 /echo Owner = Master , $MastID
   } else {
      /tell Master Error, ID has not be set master!
      /if n $Debug==1 /echo Owner ID NOT SET!
   }
   /delay 1 s
/return

|# Checks to see if we may have bumped into something that is stopping us
sub CheckObstacle
   |# Record our current position, wait a moment and then check if its the same
   /varset MyXLOC $char(x)
   /varset MyYLOC $char(y)
   /delay 2
   /if n $MyXLOC==$char(x) /if n $MyYLOC==$char(y) /call Obstacle
/return

|# Uses strafe and randomness to try and get around things
sub Obstacle
   /if n $Debug==1 /echo We hit an obstacle, trying to get around it.
   /sendkey up Forward
   /sendkey down Backward
   /delay 2
   /sendkey up Backward
   /sendkey down ctrl
   /if n $rand(99)>50 {
      /sendkey down right
   } else {
      /sendkey down left
   } 
   /delay 3
   /sendkey up right
   /sendkey up left
   /sendkey up ctrl
   /sendkey down Forward
/return

| Takes X Y loc and goes there
Sub GotoLoc
   /sit off
   /if n $X==31337 /return
   /if n $Y==31337 /return
   :KeepGoingLoc
   /if n $BreakLoop==1 /return
   /call CheckObstacle
   /doevents Chat
   /doevents Zoning
   /delay 0
   /if n $distance($p0,$p1)>=25 {
      /face loc $p0,$p1
      /sendkey down Forward
      /if n $BreakLoop!=1 /goto :KeepGoingLoc
   }
   /if n $distance($p0,$p1)<25 {
      /sendkey up Forward
      /return
   }
   /sendkey up Forward
/return

| Takes ID of body to goto and goes there
Sub GotoBody 
   /sit off 
   /target id $p0 
   
   :KeepGoingBody 
   /doevents Chat
   /doevents Zoning
   /delay 0 
   /if n $BreakLoop==1 /return 
   /if n $target(distance)>=25 { 
      /face nopredict fast id $target(id)
      /sendkey down Forward
   }
   /if n $target(distance)<25 { 
      /sendkey up Forward 
      /return 
   }
   /call CheckObstacle
   /if n $BreakLoop!=1 /goto :KeepGoingBody 
/return 

| Takes ID of what to taunt, goes there and taunts it until told to stop
Sub Taunt
   /target id $p0
   |# We don't want to go off and attack merchants or PCs
   /if $target(class)=="Merchant" /return
   /if $target(type)=="PC" /return
   /if $target(distance)>40 /call GotoBody $p0
   :KeepGoingTaunt
      /doevents Chat
      /doevents Zoning
      /call StickToTarget
      /if n $char(ability,taunt)>0 /doability taunt
   /if n $BreakLoop!=1 /goto :KeepGoingTaunt
/return 

|# Chooses what to do depending on guard settings and does it
Sub AfterAttack
   /if n $X==31337 /if n $Y==31337 { 
      /tell Master Returning to you master! 
      /target id $MastID
      /face nopredict id $MastID
      /delay 8
      /if $target(distance)>=150 /call GotoBody $MastID
      /follow
   } else /if n $X!=31337 /if n $Y!=31337 { 
      /tell Master Returning to $Y, $X master! 
      /call GotoLoc $Y $X
      /face heading $GuardHeading
   } 
/return

|# Fairly obvious, goes and attacks the $target(id) its given
Sub Attack
   /target id $p0
   /if "$target(class)"=="Merchant" /return
   /if "$target(type)"=="PC" /return
   /if n $target(distance)>35 /call GotoBody $p0
   
   |# Prep some variables for use
   /varset MobGates 0
   /varset MobEnraged 0
   /varset MobCasts 0

   /attack on
   /if n $StopOnMezBreak==1 /doevents BrokeMez   
   /if $OkToFight==0 {
      /attack off
      /return
   }
   
   /if n $SmartKB==1 {
   
      /if "$target(class)"=="Cleric" {
         /varset MobGates 1
         /varset MobCasts 1
      } else /if "$target(class)"=="Enchanter" {
         /varset MobGates 1
         /varset MobCasts 1
      } else /if "$target(class)"=="Necromancer" {
         /varset MobGates 1
         /varset MobCasts 1
      } else /if "$target(class)"=="Wizard" {
         /varset MobGates 1
         /varset MobCasts 1
      } else /if "$target(class)"=="Druid" {
         /varset MobGates 1
         /varset MobCasts 1
      } else /if "$target(class)"=="Shaman" {
         /varset MobGates 1
         /varset MobCasts 1
      } else /if "$target(class)"=="Magician" {
         /varset MobGates 1
         /varset MobCasts 1
      } else /if "$target(class)"=="Shadow Knight" {
         /varset MobCasts 1
      } else /if "$target(class)"=="Paladin" {
         /varset MobCasts 1
      } else /if "$target(class)"=="Ranger" {
         /varset MobCasts 1
      }
   }
   
   
   
   /if n $target(level)>61 /if n $target(level)<64 /if n $UseDisc==1 /disc evasive
   /if n $target(level)>64 /if n $UseDisc==1 /disc defensive

   :AttackLoop 
   /if n $StopOnMezBreak==1 /doevents BrokeMez
   /doevents Chat
   /doevents Zoning
   /doevents Enrage
   /doevents UnEnrage
   /doevents MobGating
   /doevents MobGated
   /doevents MobCasting
   
   | Stops attacking if mob is dead, raged, mezed or for some other reason we need to break loop 
   /if n $target(id)!=$p0 {
      |# most likely dead target
      /attack off
      /press Backward
      /return
   }
   
   /if n $OkToFight==0 {
      |# Something happened and we shouldn't fight
      /attack off
      /press Backward
      /return
   }

   /if n $BreakLoop==1 {
      |# Something happened and we need to break the loop and do something else
      /attack off
      /press Backward
      /return
   }
   
   /call StickToTarget
   
   /if n $DoTaunt>=1 {
      /if n $char(ability,disarm)>0 /doability disarm
      /if n $char(ability,begging)>0 { 
         /attack off 
         /doability Begging
         /attack on
      }
   }

   /if n $DoTaunt==2 {
      /varcalc MobShouldFace $char(heading)+180
      /varcalc MobShouldFace $MobShouldFace%360
      /if $target(heading)<=$calc($MobShouldFace+10) /if $target(heading)>=$calc($MobShouldFace-10) {
         |/doability taunt
      } else {
         /if n $char(ability,taunt)>0 /doability taunt
      }
   } else /if $DoTaunt==1 {
      /if n $char(ability,taunt)>0 /doability taunt
   }
   
   /if n $MobEnraged==0 /if n $MobGates!=1 /if n $MobCasts!=1 {
      /if n $char(ability,slam)>0 /doability slam
      /if n $char(ability,kick)>0 /doability kick
   }

   /if n $BreakLoop!=1 /goto :AttackLoop 
/return

|# Meant to be called inside a loop, it should use big changes to get close to target then
|# Use smaller changes once fairly close.
Sub StickToTarget
   /if $target()==FALSE /return
   /face fast nopredict
   /if n $target(speed)<=0.20 /if $target(distance)<20 {
      /if n $target(distance)>8 /press Forward
      /if n $target(distance)<5 /press Backward
   } else {
      /if n $target(distance)>18 /sendkey down Forward 
      /if n $target(distance)<14 /sendkey up Forward
   }
/return
Last edited by fryfrog on Sat Sep 13, 2003 3:26 am, edited 16 times in total.

fryfrog
a hill giant
a hill giant
Posts: 271
Joined: Fri Jun 20, 2003 5:37 am

Post by fryfrog » Thu Jun 26, 2003 4:26 am

can anyone tell me why the following would return "Couldn't find a comparison operator in 'and'" but work fine in an /echo?

Code: Select all

/tell Master Buffs $if("$char(buff,1)"!="NULL",,"1 - $char(buff,1)") $if("$char(buff,2)"!="NULL",," 2 - $char(buff,2)") $if("$char(buff,3)"!="NULL",," 3 - $char(buff,3)") $if("$char(buff,4)"!="NULL",," 4 - $char(buff,4)") $if("$char(buff,5)"!="NULL",," 5 - $char(buff,5)") $if("$char(buff,6)"!="NULL",," 6 - $char(buff,6)") $if("$char(buff,7)"!="NULL",," 7 - $char(buff,7)")
/tell Master Buffs $if("$char(buff,8)"!="NULL",," 8 - $char(buff,8)") $if("$char(buff,9)"!="NULL",," 9 - $char(buff,9)") $if("$char(buff,10)"!="NULL",," 10 - $char(buff,10)") $if("$char(buff,11)"!="NULL",," 11 - $char(buff,11)") $if("$char(buff,12)"!="NULL",," 12 - $char(buff,12)") $if("$char(buff,13)"!="NULL",," 13 - $char(buff,13)") $if("$char(buff,14)"!="NULL",," 14 - $char(buff,14)") $if("$char(buff,15)"!="NULL",," 15 - $char(buff,15)")

wassup
Official Guardian and Writer of TFM
Official Guardian and Writer of TFM
Posts: 1487
Joined: Sat Oct 26, 2002 5:15 pm

What is this?

Post by wassup » Thu Jun 26, 2003 11:53 am

I'm unsure of what this is supposed tobe doing. Can you explain it a little?

$if("$char(buff,3)"!="NULL",," 3 - $char(buff,3)")

alcor75
a lesser mummy
a lesser mummy
Posts: 77
Joined: Wed Jan 29, 2003 7:35 am

Post by alcor75 » Thu Jun 26, 2003 12:09 pm

Sorry can't help you with the report thing, btw i can tell you i love your script, i like the accuracy with it stick to target without running up and down and the great controll it give.
I noticced it start act a bit wilde after a wile, not attacking for ess. i hope you can tune it up a bit , i like it wery much.
If i can make a request, pls add a command to step up some but continue attack , to muve the mob Tnx )

Alcor75

User avatar
grimjack
Macro Author
Macro Author
Posts: 525
Joined: Thu Nov 07, 2002 6:51 am
Contact:

Post by grimjack » Thu Jun 26, 2003 12:18 pm

fryfrog wrote:can anyone tell me why the following would return "Couldn't find a comparison operator in 'and'" but work fine in an /echo?

Code: Select all

/tell Master Buffs $if("$char(buff,1)"!="NULL",,"1 - $char(buff,1)") $if("$char(buff,2)"!="NULL",," 2 - $char(buff,2)") $if("$char(buff,3)"!="NULL",," 3 - $char(buff,3)") $if("$char(buff,4)"!="NULL",," 4 - $char(buff,4)") $if("$char(buff,5)"!="NULL",," 5 - $char(buff,5)") $if("$char(buff,6)"!="NULL",," 6 - $char(buff,6)") $if("$char(buff,7)"!="NULL",," 7 - $char(buff,7)")
/tell Master Buffs $if("$char(buff,8)"!="NULL",," 8 - $char(buff,8)") $if("$char(buff,9)"!="NULL",," 9 - $char(buff,9)") $if("$char(buff,10)"!="NULL",," 10 - $char(buff,10)") $if("$char(buff,11)"!="NULL",," 11 - $char(buff,11)") $if("$char(buff,12)"!="NULL",," 12 - $char(buff,12)") $if("$char(buff,13)"!="NULL",," 13 - $char(buff,13)") $if("$char(buff,14)"!="NULL",," 14 - $char(buff,14)") $if("$char(buff,15)"!="NULL",," 15 - $char(buff,15)")
I don't see anything wrong that jumps out at me. Have you tried typing it in game? Another question would be is have you tried shortening it up as a test? I don't know if there are any line length limits. Another problem you will encounter here is if it did work the 2 tells would go off too fast and one would not be sent. The game requires a delay between tells.
When they come to me, they're in trouble, or they want some. I bust people out of prison, hunt down vampires, fight alien gods -- All the fun jobs people are too squeamish or too polite to do themselves.

Call me a mercenary. Call me an assassin. Call me a villain. I am all that and more.

My name's John Gaunt, but out on the streets of Cynosure, I am called...
GrimJack

User avatar
grimjack
Macro Author
Macro Author
Posts: 525
Joined: Thu Nov 07, 2002 6:51 am
Contact:

Re: What is this?

Post by grimjack » Thu Jun 26, 2003 12:37 pm

Wassup wrote:I'm unsure of what this is supposed tobe doing. Can you explain it a little?

$if("$char(buff,3)"!="NULL",," 3 - $char(buff,3)")
$if(comparison,true,false)

Basicly it does the comparison and if the statement returns true it returns the first value. If it is false it returns the second value.

For this it is checking if the name of buff 3 is not equal to NULL. If true it returns nothing. If false it returns "3 - <name of the buff>".

This brings me to a question for fryfrog.
Shouldn't it be
$if("$char(buff,3)"=="NULL",,"3 - $char(buff,3)")

example:

$if("Visions of Grandure"!="NULL",," 3 - Visions of Grandure")
$if("Visions of Grandure"!="NULL",Truestring,Falsestring)
VOG!=NULL would return as true and should print the first string which is nothing.

This would not cause the problem you where having but it could cause some things to not be printed properly. The documentation could be wrong though and false could come before true.

Thanks
GrimJack
When they come to me, they're in trouble, or they want some. I bust people out of prison, hunt down vampires, fight alien gods -- All the fun jobs people are too squeamish or too polite to do themselves.

Call me a mercenary. Call me an assassin. Call me a villain. I am all that and more.

My name's John Gaunt, but out on the streets of Cynosure, I am called...
GrimJack

User avatar
grimjack
Macro Author
Macro Author
Posts: 525
Joined: Thu Nov 07, 2002 6:51 am
Contact:

$if

Post by grimjack » Thu Jun 26, 2003 1:30 pm

It seems that $if() is broke. It always returns the false string for me.

/echo $if("blah"=="blah",true,false)
echo's false
/echo $if("fjkdls"=="blah",true,false)
echo's false also

This would not cause your problem but it would cause some wrong values to come back.

On a side note I have not fixed my $char(buff,1) yet. What does it return for you when you don't have a buff in slot 1? If it is nothing, matching it against "NULL" may not work. I woul use $strlen instead.

Example:
/tell mastername $if(n,$strlen($char(buff,1))>=0,truestr,falsestr)
If the string length for the variable $char(buff,1) is greater than or equal to 0, truestr, falsestr.

This may be causing your problem. Somtimes compairing a variable that has no value in an if clause can act goofy.

Thanks
GrimJack
When they come to me, they're in trouble, or they want some. I bust people out of prison, hunt down vampires, fight alien gods -- All the fun jobs people are too squeamish or too polite to do themselves.

Call me a mercenary. Call me an assassin. Call me a villain. I am all that and more.

My name's John Gaunt, but out on the streets of Cynosure, I am called...
GrimJack

fryfrog
a hill giant
a hill giant
Posts: 271
Joined: Fri Jun 20, 2003 5:37 am

Post by fryfrog » Thu Jun 26, 2003 7:06 pm

In this brief amount of time...

I fine tuned the $if line using /echo on a computer in eq. I originally tried it using =="NULL", but for some reason that did not work at all. I will double check. Looking at it, mine should not work!

The very weird thing is that right above it i have a /if n $debug==1 /echo (everything from above) and it DOES echo the line.

I went back and tuned it up a little using /tell (i thought echo and tell would be the same, but its not). I will paste what I ended up with when i get to work. basically, adding a "numeric" compare (n) to the check for null removed the "couldn't compare blah blah".

When i tried it from the script, it did not work but the echo still did. It just does not send the tell at all. I have some other odd problems like that elsewhere too. I have a few lines that read something like "/if $target(distance)>=150 /dosoemthing" and i have some /echo's right before and in the something it is called... for some reason, EVEN when the distance is like... 10 (right next to master) it still gets called.

does #turbo make all "/delay X X" go away?

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Post by BlueSkies » Thu Jun 26, 2003 7:32 pm

#turbo does not make the delays go away.

#turbo sets the number of macro commands that will parse in one iteration. Basically, changing this number will allow you to take processor time and give it to your macro. Too high a number, and eqgame might lock up (I haven't seen this personally, but I have seen EXTREME slowdowns in badly-written scripts, even when the #turbo is as low as 1000). Personally, I keep my turbo amounts very low, around 10-50, and I leave it off completely when debugging.
Live your dreams! Blue Skies everyone

fryfrog
a hill giant
a hill giant
Posts: 271
Joined: Fri Jun 20, 2003 5:37 am

Post by fryfrog » Thu Jun 26, 2003 10:18 pm

The staying with the mob portion is what I have really been trying to tweak. I had made it so that if it got too close, it would back up. To far away, it would move forward. Only... the keypresses last so long that one bumps into the other. When he is to close, he goes backwards but hits the "to far away" limit and goes forward... hitting the "to close" limit and it keeps repeating.

Right now, I am actually using codewarriors two line /if statement which does not include ANY backing up and it seems to work the best (thanks codewarrior) :)

How would you want backup to work? I will probably rename the current "back" to "return" and just make back move a little back and wait for the mob to come closer (or just move back for a certain amount of time). I could make it take a distance argument (optional?) so that you could possibly control how far back he moves.

fryfrog
a hill giant
a hill giant
Posts: 271
Joined: Fri Jun 20, 2003 5:37 am

Post by fryfrog » Fri Jun 27, 2003 1:42 am

I renamed the "back" command to "return" (makes more sense anyway). I added a very simple "back" command which hits the backward key for half a second then pauses for 2 seconds OR if you specify a number between 1 and 10 it pauses for that long (don't want you to accidentally stop attacking for like 8 min) :)

It is untested right now, but it was so simple i don't see why it should not work.

I was thinking of possibly going a bit more complicated, such as taking the distance to back off instead of the delay to wait. This would have the bot back up a bit and wait until the mob was X distance away to start fighting again. The distance sent in the command could be how far you want the bot to back up, since the distance the mob has to come is pretty set at about 10-18 for you to fight. I think for the mob to even move, the distance the bot moves backwards would almost HAVE to be > 20.

User avatar
grimjack
Macro Author
Macro Author
Posts: 525
Joined: Thu Nov 07, 2002 6:51 am
Contact:

Alternitave.

Post by grimjack » Fri Jun 27, 2003 1:57 am

I have not tested this since $char(buff,#) crashes me when there is no buff but it should work.

Code: Select all

/for l0 1 to 15
   /if $strlen($char(buff,$l0))>0 /varset $a(1,$l0) "$l0-$char(buff,$l0), "
   /if $strlen($char(buff,$l0))<=0 /varset $a(1,$l0) ", "
/next l0
/tell Mastername $a(1,1)$a(1,2)$a(1,3)$a(1,4)$a(1,5)$a(1,6)$a(1,7)$a(1,8)$a(1,9)$a(1,10)$a(1,11)$a(1,12)$a(1,13)$a(1,14)$a(1,15)
Thanks
GrimJack
When they come to me, they're in trouble, or they want some. I bust people out of prison, hunt down vampires, fight alien gods -- All the fun jobs people are too squeamish or too polite to do themselves.

Call me a mercenary. Call me an assassin. Call me a villain. I am all that and more.

My name's John Gaunt, but out on the streets of Cynosure, I am called...
GrimJack

fryfrog
a hill giant
a hill giant
Posts: 271
Joined: Fri Jun 20, 2003 5:37 am

Post by fryfrog » Fri Jun 27, 2003 3:34 am

i've put this in and will test it when i get home, the only change i made was for the ", " to just be "". Basically i only want it to list buffs that are up, and if i only had 1 buff up it would look like "1-Spirit of OMGHI , , , , , , , , , , , , , " with the loop you made (i think). hopefully i can store "" into the array :)

In the dev threads somewhere there is a thread about $char(buff,X) crashing people. it suggests changing EQ.h a little. there are two lines that are affected. you remove one and change the other a little.

alcor75
a lesser mummy
a lesser mummy
Posts: 77
Joined: Wed Jan 29, 2003 7:35 am

Post by alcor75 » Fri Jun 27, 2003 5:16 am

Woot , this scrip is getting better and better, tnx alot guys, i really love it.

I added this for mine lazzines


#Event AvatarFades "The Avatar Depart"
#Event AvatarProc "Your body screams with the power of an Avatar"

......
......

Sub Event_AvatarProc
/tell $Master Avater Proced... Switching back to DPS weps
/delay 0
/mouseto x y
/delay 0
/click left
/delay 0
/mouseto x y
/delay 0
/click left
/delay 0
/mouseto x y
/delay 0
/click left
/delay 0
/return

Sub Event_AvatarFade
/tell $Master Switching to Primal for Avatar Proc
/delay 0
/mouseto x y
/delay 0
/click left
/delay 0
/mouseto x y
/delay 0
/click left
/delay 0
/mouseto x y
/delay 0
/click left
/delay 0
/return

I use a custom UI that let me see my weps and the 8 inv slot so i sicply click click click and switch.
2 improve come to mine minde:
1- A On off option for the switch (maybe someone don't have a primal)
2- Time the Avatar proc (it last 6min and 30 sec) and switch it early so you newer lose avatar (loosing it make you reproc it slower since you lose alot of attack power)
3- get rid of this stupid idea.

P.S. the Avatar idea come from main forum and not from mine minde... so you know.

Alcor75

User avatar
pooz
a lesser mummy
a lesser mummy
Posts: 44
Joined: Fri Jun 27, 2003 1:01 pm

Post by pooz » Fri Jun 27, 2003 1:12 pm

If you're moving too quick during battle, try evaluating the distance you need to move and if it's small enough, turn walk on, move, then turn walk off. Walk will allow you to make smaller adjustments in distance.

Just think how wacky your pet warrior would move if he had selo's on while fighting.