Converted necrofarm.mac v.0.4.0b

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

Moderator: MacroQuest Developers

Scrime
a ghoul
a ghoul
Posts: 86
Joined: Sun Sep 21, 2003 5:48 pm
Contact:

Converted necrofarm.mac v.0.4.0b

Post by Scrime » Tue Oct 21, 2003 12:57 pm

Converted basic pet class hunter with user defined loot tables. Comments and suggestions welcome.

Code: Select all

|
|  converted necrofarm.mac - v0.4.0b 10/21/2003 by Scrime
|  Basic pet hunter script converted to new var format
|     w/ some ideas borrowed from GrimJack's hunter script.
|
|  Usage:
|   ! Have a pet up.
|   ! Put the correct spells in the spell names.
|   ! Use /call AddToMobList to add the mobs that you want to hunt.
|   ! Use /call AddToLootList to add the items that you want to loot
|   ! Use /call AddToDontLootList to add the items that you want to destroy
|       because they accidently get looted due to the wildcard nature of the loot list.
| 
|  Features:
|   + Anti-KS code.  Selects targets with no other PCs within a variable radius.
|      Also checks to make sure the target is undamaged and is not already attacking
|     someone else before engaging.
|   + Selective auto-looting.  Only keeps the items that you want it to.  Also has a
|     destroy list, in the case that you are looting all "lightstones", but still want
|     to destroy "Burned Out Lightstones" (for example)
|   + Closest mob selection.  Looks through the whole list of mobs you want to hunt
|     goes after the closest one.
|   + Debugging code.  Set DEBUG to "1==1" to show debugging code, set to "0==1" to turn
|     it off.
|   + Buff tracking.  Keeps track of buffs up on you and your pet, refreshes as nescessary.
|   + Heals your pet once it drops below 90% health.
|   + Obstruction avoidance.  Should back up and try to go around something if it gets stuck.
|
|  Known Issues/Limitations/Bugs:
|   - Does not know when to stop hunting.  $freeinv works for some people, crashes the client for
|     other people.  Until it is fixed, the script will not know when you bags are full.
|   - Does not stop to med up, stops casting spells once below 20% mana.
|   - Obstruction detection needs some tweaking, maybe an "allowance" value for being in the same spot
|     instead of waiting for the x/y locs to be the same.
|   - Some of the global variables need to be turned in to locals.
|      
|  Release Notes for v0.4.0b :
|   * NOTE: This is considered a beta release of the converted previous v0.3.0b, it still needs some more testing.  
|	  Use at you own risk, please report any problems.  Enjoy and macro responsibly.
|   * Hunt distance is now a constant (cHuntDistance) that you can set at the beginning of the script.  This
|     is the maxiumum distance away from you that the script will look for a new target.  Set to 99999 for no
|     max distance.
|   * In the anti-ks code, when looking at our targets assisted target, it will look at the name and if
|     the name contains the word "corpse" it will disregard the assist and attack anyway.
|   * In the anti-ks code, if a mob it tries to target becomes invalid because it is not full health or is
|     currently attacking someone it will not be considered the next time thru the loop.
|   * Aggro'd mob protection.  If we have a mob aggro'd on us, then the script will select that mob as our next
|     target to kill AFTER we are done with out current target before doing a normal search for a hunt target.
|   * Continuous target re-evaluation.  As long as we are moving towards our target, the script will keeping
|     looking for closer targets.  This makes it so that we wont run past newly spawned valid targets on our way
|     to our current target (which is farther away).
|   * Script now backs away from a target if it gets too close to us (too close range defined as cTooCloseRange)
|

#turbo

| used to echo debugging messages.  set to 1=1 if you want to see them, 0==1 if you dont
#define DEBUG               1==1

| distance defines, setting these alters the behavior of the script
| cAntiKSRadius is the distance from each mob that will exclude it from selecting as a
| target if there is another PC within this range.
#define cAntiKSRadius         50
| cAtkRange is how close we get to the mob before we send in the pet
#define cAtkRange            50
| cTooCloseRange is how close we let a mob we are attacking get to us before we start to
| back away
#define cTooCloseRange         30
| cHuntDistance is the maximum distance away that the script will select a new target.
#define cHuntDistance         99999

| spell names
#define SelfShieldSpell      "Major Shielding"
#define PetBuffSpell      "Intensify Death"
#define PetHealSpell      "Renew Bones"

| special events to respond to
#event PetHasteDown   "Your pet's Intensify Death spell has worn off."
#event Fizzle      "Your spell fizzles!"

| MAIN =========================================================

Sub Main
   | clear out all variables and set up new ones
   /zapvars
   /call DeclareGlobals

   | clear target, et al
   /press esc
   /press esc
   /press esc
   /press shift
   /press alt
   /press ctrl

   | never confirm looting nodrop items
   /lootn never

   | macro title
   /echo Starting NecroFarm v0.4.0a - by Scrime
   /if DEBUG /echo Debugging messages WILL be shown.
   /echo Attack range is cAtkRange.
   /echo AntiKS range is cAntiKSRadius.
   /echo TooClose range is cTooCloseRange.
   /echo Hunt range is cHuntDistance.

   | set up our hunting array
   /call AddToMobList "willowisp"
   /call AddToMobList "spider"
   /call AddToMobList "kodiak"
   /call AddToMobList "bear"
   
   | set up the loot array
   /call AddToLootList "quality"
   /call AddToLootList "lightstone"
   /call AddToLootList "silk"
   
   | set up the dont loot array
   /call AddToDontLootList "burned out lightstone"
   
:StartHunting
   /doevents
   
   /call CastSpells
   
   /if n @HaveTarget==0 /call FindAggroTarget
   /if n @HaveTarget==0 /call MoveToTarget
   /if n @HaveTarget==1 /call KillTarget
   /if n @HaveTarget==1 /call LootTarget
      
   /if n @BagsFull==1 /goto :EndMacro
   /goto :StartHunting
   
:EndMacro
   /if n @BagsFull==1 /echo NecroFarm ended: Bags are full, go sell!
/return

| SUBS =========================================================

Sub DeclareGlobals
	/declare CurrTarget global
	/declare CurrMana global
	/declare LastPosX global
	/declare LastPosY global
	/declare OldTarget global
	
	/declare PetHasteStatus global
	
	/declare MobArraySize global
	/declare LootArraySize global
	/declare MobArrayIndex global
	/declare LootArrayIndex global
	/declare ClosestMobID global
	/declare ClosestMobDist global
	/declare HaveTarget global
	/declare ObstCount global
	/declare DontLootArraySize global
	/declare InvalidTargetID global
	
	/declare LootSlot global
	/declare BagsFull global
	/declare FizzleFlag global
	
	| array number defines, dont change
	/declare MobArray array
	/declare LootArray array
	/declare DontLootArray array
/return

Sub AddToMobList
   /if "@Param0"!="" {
      /varadd MobArraySize 1
      /varset MobArray(@MobArraySize) "@Param0"
      /if DEBUG /echo Added @Param0 to the MobArray at position $int(@MobArraySize).
   }
/return

Sub AddToLootList
   /if "@Param0"!="" {
      /varadd LootArraySize 1
      /varset LootArray(@LootArraySize) "@Param0"
      /if DEBUG /echo Added @Param0 to the LootArray at position $int(@LootArraySize).
   }
/return

Sub AddToDontLootList
   /if "@Param0"!="" {
      /varadd DontLootArraySize 1
      /varset @DontLootArray(@DontLootArraySize) "@Param0"
      /if DEBUG /echo Added @Param0 to the DontLootArray at position $int(@DontLootArraySize).
   }
/return

| ==============================================================

| FindAggroTarget
| this function targets the closest mob that is not our pet and looks to see if it has us as its
| target.  If we find a target here, then we put our pet on it and skip normally finding
| a target.
Sub FindAggroTarget
   /if DEBUG /echo Entering FindAggroTarget...
   | clear our current target
   /press esc

   | target the closest mob that is not our pet
   /target npc notid $char(pet)

   | if we have a target, then we need to see if it has a target
   /if $target()=="TRUE" {
      /if DEBUG /echo Checking closest target ($target(name), id:$target(id)) for aggro.
      /varset ClosestMobID $target(id)
      /assist
      /delay 5
      
      | if the closest mob's target is us, then select it as our target to kill.
      /if n $target(id)==$char(id) {
         /target id @ClosestMobID
         /if DEBUG /echo $target(name) ($target(id)) is aggro'd on us, selecting as next target to kill.
         /varset HaveTarget 1
         /varset ClosestMobID $target(id)
      }
   }
   /if DEBUG /echo Leaving FindAggroTarget...
/return

| ==============================================================

Sub FindTarget
   /if DEBUG /echo Entering FindTarget...

   | make sure we have nothing targeted
   /press esc
   
   | routine to find the closest, non-engaged mob from our list
   | returns nothing, but ClosestMobID will be set to the mob to engage. Keeps looking until it finds a target.
:StartFindTarget
   
   | reset the distance and ID of closest mob
   /varset ClosestMobDist cHuntDistance   
   /varset ClosestMobID 0
   /varset HaveTarget 0
   
   | go thru the list of mobs we want to hunt and find the closest one that isn't being engaged.
   /for MobArrayIndex 1 to @MobArraySize
      /target npc nopcnear cAntiKSRadius notid InvalidTargetID @MobArray(@MobArrayIndex)
      /if DEBUG {
         /if $target()=="TRUE" {
            /echo Looking for @Mobarray(@MobArrayIndex), found $target(name,clean) (id: $target(id)), Distance: $target(distance,nopredict)         
         }
      }
      
      | check to make sure we targeted something
      /if $target()=="FALSE" /goto :SkipMob
      
      | if the target is not full life, someone else is probably fighting it, skip it
      /if n $target(hp,pct)!=100 {
         /if DEBUG /echo Target is not full life, skipping.
         /varset InvalidTargetID $target(id)
         /goto :SkipMob
      }
      
      | see if this mob is closer than the last mob we checked
      /if n $target(distance,nopredict)<@ClosestMobDist {
         /if DEBUG {
            /echo $target(name) is closer than our former target, switching.
         }
         /varset ClosestMobID $target(id)
         /varset ClosestMobDist $target(distance,nopredict)
         /varset InvalidTargetID 0
         /varset HaveTarget 1
      }

:SkipMob
   /next MobArrayIndex
   
   | if we didn't find a target, start over   
   /if n @HaveTarget!=1 /goto :StartFindTarget
   
   | re-target whichever mob was closest
   /target id @ClosestMobID
   
:EndFindTarget
   /if DEBUG /echo Leaving FindTarget...
/return

| ==============================================================

Sub MoveToTarget

   /if DEBUG /echo Entering MoveToTarget...
   | moves us to the currently target, stops once we are within our cAtkRange
   
:KeepMoving
   | constantly look for a closer target
   /call FindTarget
   /call CheckForObst

   | check to make sure our target is still alive
   /if $target()=="FALSE" {
      /if DEBUG /echo Our target died before we got to it, finding a new one.
      /sendkey up up
      /varset HaveTarget 0
      /goto :EndMoveToTarget
   }   
   
   | check to make sure our target is still full life, if not someone is probably fighting it
   /if n $target(hp,pct)!=100 {
      /if DEBUG /echo Our target started losing hp before we got to it, finding a new one.
      /sendkey up up
      /varset InvalidTargetID $target(id)
      /varset HaveTarget 0
      /goto :EndMoveToTarget
   }
   
   /face
   /sendkey down up
   
   | check to see if we are close enough yet
   /if n $target(distance,nopredict)<=cAtkRange {
      /if DEBUG /echo In range of target, stop moving.
      /sendkey up up
      /goto :EndMoveToTarget
   }
   
   /goto :KeepMoving
   
:EndMoveToTarget
   /if DEBUG /echo Leaving MoveToTarget...
/return

| ==============================================================

Sub KillTarget
   /if DEBUG /echo Entering KillTarget...
   
   | check to make sure our target is still alive
   /if $target()=="FALSE" {
      /if DEBUG /echo Our target died before we attacked it, finding a new one.
      /varset InvalidTargetID 0
      /varset HaveTarget 0
      /goto :EndKillTarget
   }   
   
   | check to make sure our target is still full life, if not someone is probably fighting it
   /if n $target(hp,pct)!=100 {
      /if DEBUG /echo Our target started losing hp before we attacked it, finding a new one.
      /varset InvalidTargetID $target(id)
      /varset HaveTarget 0
      /goto :EndKillTarget
   }
   
   | make sure our target doesnt have a target, if it does then it's attacking someone, skip it
   /assist
   /delay 5
   /if DEBUG /echo Our target's ID=@ClosestMobID, assisted target's ID=$target(id)
   
   | check the assisted target's id, then check its name.  if the name contains "corpse", then
   | our original target should be considered valid.
   /if n $target(id)!=@ClosestMobID /if n $instr(corpse,$target(name))==-1 {
      /if DEBUG /echo Our target had a living target, it must've been fighting someone, skip it.
      /varset InvalidTargetID $target(id)
      /varset HaveTarget 0
      /goto :EndKillTarget
   }
   
   | send our pet in
   /pet attack

   | wait until mob is dead, if it starts to flee, follow it
:MainCombatLoop
   /call CastSpells
:FollowMob
   | check to see if the mob is getting away from us, if so follow
   /if n $target(distance,nopredict)>cAtkRange {
      /if DEBUG /echo Target moved away from us, following.
      /face
      /sendkey down up
   } else {
      /face
      /sendkey up up
   }
   
   | check to see if the mob is getting too close to us, if so back off
   /if n $target(distance,nopredict)<cTooCloseRange {
      /if DEBUG /echo Target getting too close to us, backing away.
      /face
      /sendkey down down
   } else {
      /face
      /sendkey up down
   }
   
   | if we lose our target while attacking it, then the mob died.
   /if $target()=="FALSE" /goto :EndKillTarget
   /goto :MainCombatLoop

:EndKillTarget
   | make sure our pet follows us
   /pet follow
   | make sure we stop moving
   /sendkey up up
   /sendkey up down
   
   /if DEBUG /echo Leaving KillTarget...
/return

| ==============================================================

Sub LootTarget
:StartLootTarget
   /if DEBUG /echo Entering LootTarget...
   
   | target the corpse of the mob we just killed
   /target id @ClosestMobID
   
   | move up to it
   /face
:CheckCorpseDistance
   /call CheckForObst
   /if n $target(distance)>15 {
      /face
      /sendkey down up
      /goto :CheckCorpseDistance
   } else {
      /sendkey up up
   }

   | open the loot window
   /loot
   /delay 2s
   
   | check each slot (0-7) to see if its something we want to keep
   /for LootSlot 0 to 7
      /click left corpse @LootSlot
      /delay 1s

      | if there is nothing on the cursor, then we are out of loots, stop the loop
      /if "$cursor()"=="NULL" /goto :EndLootTarget
      
      /if DEBUG /echo Checking loot slot #@LootSlot: $cursor(name)

      | check whats on our cursor against the list of things we DONT want to keep
      /for LootArrayIndex 1 to @DontLootArraySize
         /if "$cursor(name)"=="@DontLootArray(@LootArrayIndex)" {
            /if DEBUG /echo $cursor(name) matches @DontLootArray(@LootArrayIndex), destroying.
               /click left destroy
               /delay 1s
             /goto :NextLoot
         }
      /next LootArrayIndex

      | check whats on our cursor against the list of things we want to keep
      /for LootArrayIndex 1 to @LootArraySize
         /if "$cursor(name)"~~"@LootArray(@LootArrayIndex)" {
            /if DEBUG /echo $cursor(name) matches @LootArray(@LootArrayIndex), keeping.
               /click left auto
               /delay 1s
             /goto :NextLoot
         }
      /next LootArrayIndex
      
      | if we make it to here, it means that the loot didnt match anything in our list
      | so, we destroy the object.
      /if DEBUG /echo $cursor(name) doesn't match anything in our list, destroying.
      /click left destroy
      /delay 1s
      
:NextLoot
   /next LootSlot

:EndLootTarget
   /press esc
   /varset HaveTarget 0
   
   | if our bags are full, its time to stop hunting and go sell.  For now, end the macro.
   | /if n $freeinv(space)==0 /varset BagsFull 1
   | /if DEBUG /echo Inventory space remaining: $freeinv(space) slots.
   
   /if DEBUG /echo Leaving LootTarget...
/return


| ==============================================================

Sub CastSpells
   /if DEBUG /echo Entering CastSpells...
:StartSpells

   | see if we have mana to spare
   /if n $char(mana,pct)<20 /goto :SkipSpells
   
   | decide which spell to cast
   /if   n $char(buff,"SelfShieldSpell")==0 {
      /if DEBUG /echo Trying to cast "SelfShieldSpell".
      /call NoFizzleCast "SelfShieldSpell"
      /if DEBUG /echo Delay time is: $int($calc($spell("SelfShieldSpell",casttime)*10+5))
      /delay $int($calc($spell("SelfShieldSpell",casttime)*10+5))
      /goto :StartSpells
   }
   
   | check to see if we have a pet up
   /if n $char(pet)!=0 {

      | check to see if we need to heal our pet.
      /if n $spawn($char(pet),hp,pct)<50 {
         /if DEBUG /echo Trying to cast "PetHealSpell".      
         /target id $char(pet)
         /call NoFizzleCast "PetHealSpell"
         /if DEBUG /echo Delay time is: $int($calc($spell("PetHealSpell",casttime)*10+5))
         /delay $int($calc($spell("PetHealSpell",casttime)*10+5))
         /goto :StartSpells
      }

      | check to see if we need to buff our pet
      /if n @PetHasteStatus==0 {
         /if DEBUG /echo Trying to cast "PetBuffSpell".
         /target id $char(pet)
         /call NoFizzleCast "PetBuffSpell"
         /if DEBUG /echo Delay time is: $int($calc($spell("PetBuffSpell",casttime)*10+5))
         /delay $int($calc($spell("PetBuffSpell",casttime)*10+5))
         /varset PetHasteStatus 1
         /goto :StartSpells
      }
   }
:SkipSpells   
   /target id @ClosestMobID
   /if DEBUG /echo Leaving CastSpells...
/return

| ==============================================================

Sub NoFizzleCast
   | make sure we dont get passed a null spell name
   /if "@Param0"!="" {
:NoFizzleCastStart
      /varset FizzleFlag 0
      | check to make sure we have mana to cast this spell
      /if n $char(mana,cur)<$spell("@Param0",mana) /goto :NoFizzleCastEnd
      
      /cast "@Param0"
      /doevents Fizzle
      
      | if we fizzled, try to cast again
      /if n @FizzleFlag==1 /goto :NoFizzleCastStart
   }
:NoFizzleCastEnd
/return

| ==============================================================

Sub CheckForObst
   /if n $char(x)==@LastPosX /if n $char(y)==@LastPosY {
      /varadd ObstCount 1
   } else {
      /varset ObstCount 0
   }
   
   /varset LastPosX $char(x)
   /varset LastPosY $char(y)
   
   /if n @ObstCount>3 {
      /call GoAroundObst
   }
/return

| ==============================================================

Sub GoAroundObst
   /if DEBUG /echo Entering GoAroundObst...
   | back up some
   /sendkey up up
   /sendkey down down
   /delay 1s
   /sendkey up down
   
   | go left or right a bit, randomly
   /if n $rand(2)==1 {
      /sendkey down left
      /delay 5
      /sendkey up left
   } else {
      /sendkey down right
      /delay 5
      /sendkey up right
   }
   
   | move forward a bit
   /sendkey down up
   /delay 1s
   /sendkey up up
   
   /if DEBUG /echo Leaving GoAroundObst...   
/return

| EVENTS =======================================================

Sub Event_PetHasteDown
   /varset PetHasteStatus 0
/return

Sub Event_Fizzle
   /varset FizzleFlag 1
/return 

Stogar
a lesser mummy
a lesser mummy
Posts: 58
Joined: Mon Oct 13, 2003 12:02 pm

Post by Stogar » Tue Oct 21, 2003 9:52 pm

I tried this out with a necro I've had parked for a bit. Only changed the pet buff, self buff, and pet heal spell names.

Ran it and got this:
Starting NecroFarm v0.4.0a - by Scrime
Debugging messages WILL be shown.
Attack range is 50.
AntiKS range is 50.
TooClose range is 30.
Hunt range is 99999.
Added willowisp to the MobArray at position 1.
Added spider to the MobArray at position 2.
Added kodiak to the MobArray at position 3.
Added bear to the MobArray at position 4.
Added quality to the LootArray at position 1.
Added lightstone to the LootArray at position 2.
Added silk to the LootArray at position 3.
Ending macro: Bad variable in /var function.
necrofarm.mac@189 (AddToDontLootList): /varset @DontLootArray(@DontLootArraySize) "@Param0"
necrofarm.mac@119 (Main): /call AddToDontLootList "burned out lightstone"
Cleared the following: Timers Vars Arrays
The current macro has ended.
This was the original line:

Code: Select all

/varset @DontLootArray(@DontLootArraySize) "@Param0" 
I changed to:

Code: Select all

/varset DontLootArray(@DontLootArraySize) "@Param0" 
Looks like a typo but took my rookie debugging skills 20 minutes to get it :)

Scrime
a ghoul
a ghoul
Posts: 86
Joined: Sun Sep 21, 2003 5:48 pm
Contact:

Post by Scrime » Wed Oct 22, 2003 8:21 am

You're right. I had converted it at work and haven't tested it yet.

Nice catch.

Stogar
a lesser mummy
a lesser mummy
Posts: 58
Joined: Mon Oct 13, 2003 12:02 pm

Post by Stogar » Wed Oct 22, 2003 9:40 am

Just used it last night, it's pretty solid. Buffing works at the beginning but can't confirm if it's happening when the pet worn off message pops. Loot code works like a charm.

The target aquisition is awesome. The only problem I have with it is the spam. I typically run my macroing on a second accout/machine and am not afk so I do like to see channel messages (ooc, shout,etc).

I turned off debugging and I know I can turn off other messages just gotta click that search button and find it again. The other side effect of the targeting is when you run out of targets, ie you have cleared the zone, the no target spam brought my EQ client to it's knees. It took me 5 minutes to type /endmacro.


Again this is just one hell of a macro, thanks.

--edit--
I think the /filter command is what i am looking for.

Tuffy
a lesser mummy
a lesser mummy
Posts: 33
Joined: Thu Oct 02, 2003 9:20 am

Thank you

Post by Tuffy » Wed Oct 22, 2003 11:14 am

Thank you again for updating this macro. I tried my best to get this sucker to work and by looking at what you did I was not far off. But I was off none the less.

Thanks,

DyvimTvar

Possible feature imporvements

Post by DyvimTvar » Wed Oct 22, 2003 12:54 pm

Great macro,

I was thinking of adding mob health checking and spells to cast at certain health percentages. For example have it cast darkness on the mob at 80% health, lifetap dot at 60% health, and dd at 40% health.

I think I can add that, I'll be trying later today, what I'm not sure I can do is have the health levels and spells variable. If someone smarter than me wants to take a crack at it that'd be great. I'll post mine when it works, but it may take a while. ;)

Dyvim Tvar

Scrime
a ghoul
a ghoul
Posts: 86
Joined: Sun Sep 21, 2003 5:48 pm
Contact:

Post by Scrime » Wed Oct 22, 2003 1:21 pm

I had considered doing something like that as well, but I designed it as a farm bot more than an xp bot. It was intended to stay up and running as long as possible, so that you would get maximum farmage with it.

I actually have another very simple necrobot macro that I use for my wifes necro when she needs to go mess with the kids or make my dinner (hehe). I tell it to assist me and it sends its pet in, buffs itself and its pet, heals its pet when needed, casts lifetap/dots/nuke depending on mana/mob hp levels.

As I said, this particular macro is designed just for farming things that are easy and tedious to kill, like spiders for silks, bears for pelts, willowisps for lightstones, etc. However, you are more than welcome to modify it for your needs.

If anyone wants to see my very basic necrobot, let me know and I'll clean it up and post it here.

Raevynhart
decaying skeleton
decaying skeleton
Posts: 3
Joined: Sat Oct 18, 2003 6:14 am

Necrobot

Post by Raevynhart » Wed Oct 22, 2003 1:40 pm

Greeetings.

I would love to see an example of your necrobot.

Thanks,
Raevynhart

DyvimTvar
orc pawn
orc pawn
Posts: 16
Joined: Wed Oct 22, 2003 1:21 pm

I'd like to see it as well

Post by DyvimTvar » Wed Oct 22, 2003 1:59 pm

Subject says it all, I'd love to see the macro, the more macro's I see, the more I learn. ;)
DyvimTvar

tac8357
orc pawn
orc pawn
Posts: 25
Joined: Fri Oct 17, 2003 5:18 pm
Contact:

question

Post by tac8357 » Thu Oct 23, 2003 12:41 pm

How hard would it be to convert it for use for a Shaman and his pet?

Stogar
a lesser mummy
a lesser mummy
Posts: 58
Joined: Mon Oct 13, 2003 12:02 pm

Post by Stogar » Thu Oct 23, 2003 1:49 pm

I was working on a Shaman or even generic pet farm version. A quick and dirty way to change it would be to change this:

Code: Select all

| spell names 
#define SelfShieldSpell      "Major Shielding" 
#define PetBuffSpell      "Intensify Death" 
#define PetHealSpell      "Renew Bones" 

| special events to respond to 
#event PetHasteDown   "Your pet's Intensify Death spell has worn off." 

to something like this(changed in bold):

Code: Select all

| spell names 
#define SelfShieldSpell      [b]"Harnessing of Spirit" [/b]
#define PetBuffSpell      [b]"Alacrity"[/b] 
#define PetHealSpell      [b]"Superior Healing"[/b] 

| special events to respond to 
#event PetHasteDown   "Your pet's [b]Alacrity[/b] spell has worn off." 
#event Fizzle      "Your spell fizzles!" 
You'd need to define more petbuffs if you want to add others. Changing these spells though should give it the same functionality as the original necro version.

Mixy
a lesser mummy
a lesser mummy
Posts: 46
Joined: Tue Jul 09, 2002 5:00 pm

Post by Mixy » Fri Oct 24, 2003 3:51 pm

Here's a modification of the above macro. I tried to add GM protection, meditiaion, and pet recast.

Please be advised that this is untested, and my first macro attempt... so please point out any problems so that i can try to learn from them.
All of the things i added were taken from other macros. I take no credit for the work.
-Mixy

Code: Select all

|  Attemped to add GM protection and Med up code.
|  Also added a pet recast in case he dies and you live
|  -Mixy
| 
|  converted necrofarm.mac - v0.4.0b 10/21/2003 by Scrime 
|  Basic pet hunter script converted to new var format 
|     w/ some ideas borrowed from GrimJack's hunter script. 
| 
|  Usage: 
|   ! Have a pet up. 
|   ! Put the correct spells in the spell names. 
|   ! Use /call AddToMobList to add the mobs that you want to hunt. 
|   ! Use /call AddToLootList to add the items that you want to loot 
|   ! Use /call AddToDontLootList to add the items that you want to destroy 
|       because they accidently get looted due to the wildcard nature of the loot list. 
| 
|  Features: 
|   + Anti-KS code.  Selects targets with no other PCs within a variable radius. 
|      Also checks to make sure the target is undamaged and is not already attacking 
|     someone else before engaging. 
|   + Selective auto-looting.  Only keeps the items that you want it to.  Also has a 
|     destroy list, in the case that you are looting all "lightstones", but still want 
|     to destroy "Burned Out Lightstones" (for example) 
|   + Closest mob selection.  Looks through the whole list of mobs you want to hunt 
|     goes after the closest one. 
|   + Debugging code.  Set DEBUG to "1==1" to show debugging code, set to "0==1" to turn 
|     it off. 
|   + Buff tracking.  Keeps track of buffs up on you and your pet, refreshes as nescessary. 
|   + Heals your pet once it drops below 90% health. 
|   + Obstruction avoidance.  Should back up and try to go around something if it gets stuck. 
| 
|  Known Issues/Limitations/Bugs: 
|   - Does not know when to stop hunting.  $freeinv works for some people, crashes the client for 
|     other people.  Until it is fixed, the script will not know when you bags are full. 
|   - Does not stop to med up, stops casting spells once below 20% mana. 
|   - Obstruction detection needs some tweaking, maybe an "allowance" value for being in the same spot 
|     instead of waiting for the x/y locs to be the same. 
|   - Some of the global variables need to be turned in to locals. 
|      
|  Release Notes for v0.4.0b : 
|   * NOTE: This is considered a beta release of the converted previous v0.3.0b, it still needs some more testing.  
|     Use at you own risk, please report any problems.  Enjoy and macro responsibly. 
|   * Hunt distance is now a constant (cHuntDistance) that you can set at the beginning of the script.  This 
|     is the maxiumum distance away from you that the script will look for a new target.  Set to 99999 for no 
|     max distance. 
|   * In the anti-ks code, when looking at our targets assisted target, it will look at the name and if 
|     the name contains the word "corpse" it will disregard the assist and attack anyway. 
|   * In the anti-ks code, if a mob it tries to target becomes invalid because it is not full health or is 
|     currently attacking someone it will not be considered the next time thru the loop. 
|   * Aggro'd mob protection.  If we have a mob aggro'd on us, then the script will select that mob as our next 
|     target to kill AFTER we are done with out current target before doing a normal search for a hunt target. 
|   * Continuous target re-evaluation.  As long as we are moving towards our target, the script will keeping 
|     looking for closer targets.  This makes it so that we wont run past newly spawned valid targets on our way 
|     to our current target (which is farther away). 
|   * Script now backs away from a target if it gets too close to us (too close range defined as cTooCloseRange) 
| 

#turbo 

| used to echo debugging messages.  set to 1=1 if you want to see them, 0==1 if you dont 
#define DEBUG               1==1 

| distance defines, setting these alters the behavior of the script 
| cAntiKSRadius is the distance from each mob that will exclude it from selecting as a 
| target if there is another PC within this range. 
#define cAntiKSRadius         50 
| cAtkRange is how close we get to the mob before we send in the pet 
#define cAtkRange            50 
| cTooCloseRange is how close we let a mob we are attacking get to us before we start to 
| back away 
#define cTooCloseRange         30 
| cHuntDistance is the maximum distance away that the script will select a new target. 
#define cHuntDistance         99999 

| spell names 
#define SelfShieldSpell      "Major Shielding" 
#define PetBuffSpell      "Intensify Death" 
#define PetHealSpell      "Renew Bones"
#define constPetSpell               "Summon Dead"

| special events to respond to 
#event PetHasteDown   "Your pet's Intensify Death spell has worn off." 
#event Fizzle      "Your spell fizzles!" 

| MAIN ========================================================= 

Sub Main 
   | clear out all variables and set up new ones 
   /zapvars 
   /call DeclareGlobals
   /varset MedTime 3m
   /varset DummyTime 11m 
   /varset DummyMsg "afk, bio really quick" 
   | clear target, et al 
   /press esc 
   /press esc 
   /press esc 
   /press shift 
   /press alt 
   /press ctrl 

   | never confirm looting nodrop items 
   /lootn never 

   | macro title 
   /echo Starting NecroFarm v0.4.0a - by Scrime 
   /if DEBUG /echo Debugging messages WILL be shown. 
   /echo Attack range is cAtkRange. 
   /echo AntiKS range is cAntiKSRadius. 
   /echo TooClose range is cTooCloseRange. 
   /echo Hunt range is cHuntDistance. 

   | set up our hunting array 
   /call AddToMobList "willowisp" 
   /call AddToMobList "spider" 
   /call AddToMobList "kodiak" 
   /call AddToMobList "bear" 
    
   | set up the loot array 
   /call AddToLootList "quality" 
   /call AddToLootList "lightstone" 
   /call AddToLootList "silk" 
    
   | set up the dont loot array 
   /call AddToDontLootList "burned out lightstone" 
    
:StartHunting 
   /doevents 
    
   /call CastSpells 
    
   /if n @HaveTarget==0 /call FindAggroTarget 
   /if n @HaveTarget==0 /call MoveToTarget 
   /if n @HaveTarget==1 /call KillTarget 
   /if n @HaveTarget==1 /call LootTarget 
      
   /if n @BagsFull==1 /goto :EndMacro 
   /goto :StartHunting 
    
:EndMacro 
   /if n @BagsFull==1 /echo NecroFarm ended: Bags are full, go sell! 
/return 

| SUBS ========================================================= 

Sub DeclareGlobals 
   /declare CurrTarget global 
   /declare CurrMana global 
   /declare LastPosX global 
   /declare LastPosY global 
   /declare OldTarget global 
    
   /declare PetHasteStatus global 
    
   /declare MobArraySize global 
   /declare LootArraySize global 
   /declare MobArrayIndex global 
   /declare LootArrayIndex global 
   /declare ClosestMobID global 
   /declare ClosestMobDist global 
   /declare HaveTarget global 
   /declare ObstCount global 
   /declare DontLootArraySize global 
   /declare InvalidTargetID global 
    
   /declare LootSlot global 
   /declare BagsFull global 
   /declare FizzleFlag global 
   
   /declare DummyTime global 
   /declare DummyMsg global 
   
   | array number defines, dont change 
   /declare MobArray array 
   /declare LootArray array 
   /declare DontLootArray array 
/return 

Sub AddToMobList 
   /if "@Param0"!="" { 
      /varadd MobArraySize 1 
      /varset MobArray(@MobArraySize) "@Param0" 
      /if DEBUG /echo Added @Param0 to the MobArray at position $int(@MobArraySize). 
   } 
/return 

Sub AddToLootList 
   /if "@Param0"!="" { 
      /varadd LootArraySize 1 
      /varset LootArray(@LootArraySize) "@Param0" 
      /if DEBUG /echo Added @Param0 to the LootArray at position $int(@LootArraySize). 
   } 
/return 

Sub AddToDontLootList 
   /if "@Param0"!="" { 
      /varadd DontLootArraySize 1 
      /varset DontLootArray(@DontLootArraySize) "@Param0" 
      /if DEBUG /echo Added @Param0 to the DontLootArray at position $int(@DontLootArraySize). 
   } 
/return 

| ============================================================== 

| FindAggroTarget 
| this function targets the closest mob that is not our pet and looks to see if it has us as its 
| target.  If we find a target here, then we put our pet on it and skip normally finding 
| a target. 
Sub FindAggroTarget 
   /if DEBUG /echo Entering FindAggroTarget... 
   /if $gm==TRUE /call DummyMode 
   | clear our current target 
   /press esc 

   | target the closest mob that is not our pet 
   /target npc notid $char(pet) 

   | if we have a target, then we need to see if it has a target 
   /if $target()=="TRUE" { 
      /if DEBUG /echo Checking closest target ($target(name), id:$target(id)) for aggro. 
      /varset ClosestMobID $target(id) 
      /assist 
      /delay 5 
      
      | if the closest mob's target is us, then select it as our target to kill. 
      /if n $target(id)==$char(id) { 
         /target id @ClosestMobID 
         /if DEBUG /echo $target(name) ($target(id)) is aggro'd on us, selecting as next target to kill. 
         /varset HaveTarget 1 
         /varset ClosestMobID $target(id) 
      } 
   } 
   /if DEBUG /echo Leaving FindAggroTarget... 
/return 

| ============================================================== 

Sub DummyMode 
   /echo GM IN ZONE!  Pausing the script (@DummyTime)! 
   /afk @DummyMsg 
    /who all enchanter
    /delay @DummyTime 
    /afk off 
   /stand 
/return 

Sub FindTarget 
   /if DEBUG /echo Entering FindTarget... 

   | make sure we have nothing targeted 
   /press esc 
    
   | routine to find the closest, non-engaged mob from our list 
   | returns nothing, but ClosestMobID will be set to the mob to engage. Keeps looking until it finds a target. 
:StartFindTarget 
    
   | reset the distance and ID of closest mob 
   /varset ClosestMobDist cHuntDistance    
   /varset ClosestMobID 0 
   /varset HaveTarget 0 
    
   | go thru the list of mobs we want to hunt and find the closest one that isn't being engaged. 
   /for MobArrayIndex 1 to @MobArraySize 
      /target npc nopcnear cAntiKSRadius notid InvalidTargetID @MobArray(@MobArrayIndex) 
      /if DEBUG { 
         /if $target()=="TRUE" { 
            /echo Looking for @Mobarray(@MobArrayIndex), found $target(name,clean) (id: $target(id)), Distance: $target(distance,nopredict)          
         } 
      } 
      
      | check to make sure we targeted something 
      /if $target()=="FALSE" /goto :SkipMob 
      
      | if the target is not full life, someone else is probably fighting it, skip it 
      /if n $target(hp,pct)!=100 { 
         /if DEBUG /echo Target is not full life, skipping. 
         /varset InvalidTargetID $target(id) 
         /goto :SkipMob 
      } 
      
      | see if this mob is closer than the last mob we checked 
      /if n $target(distance,nopredict)<@ClosestMobDist { 
         /if DEBUG { 
            /echo $target(name) is closer than our former target, switching. 
         } 
         /varset ClosestMobID $target(id) 
         /varset ClosestMobDist $target(distance,nopredict) 
         /varset InvalidTargetID 0 
         /varset HaveTarget 1 
      } 

:SkipMob 
   /next MobArrayIndex 
    
   | if we didn't find a target, start over    
   /if n @HaveTarget!=1 /goto :StartFindTarget 
    
   | re-target whichever mob was closest 
   /target id @ClosestMobID 
    
:EndFindTarget 
   /if DEBUG /echo Leaving FindTarget... 
/return 

| ============================================================== 

Sub MoveToTarget 

   /if DEBUG /echo Entering MoveToTarget... 
   | moves us to the currently target, stops once we are within our cAtkRange 
    
:KeepMoving 
   | constantly look for a closer target 
   /call FindTarget 
   /call CheckForObst 

   | check to make sure our target is still alive 
   /if $target()=="FALSE" { 
      /if DEBUG /echo Our target died before we got to it, finding a new one. 
      /sendkey up up 
      /varset HaveTarget 0 
      /goto :EndMoveToTarget 
   }    
    
   | check to make sure our target is still full life, if not someone is probably fighting it 
   /if n $target(hp,pct)!=100 { 
      /if DEBUG /echo Our target started losing hp before we got to it, finding a new one. 
      /sendkey up up 
      /varset InvalidTargetID $target(id) 
      /varset HaveTarget 0 
      /goto :EndMoveToTarget 
   } 
    
   /face 
   /sendkey down up 
    
   | check to see if we are close enough yet 
   /if n $target(distance,nopredict)<=cAtkRange { 
      /if DEBUG /echo In range of target, stop moving. 
      /sendkey up up 
      /goto :EndMoveToTarget 
   } 
    
   /goto :KeepMoving 
    
:EndMoveToTarget 
   /if DEBUG /echo Leaving MoveToTarget... 
/return 

| ============================================================== 

Sub KillTarget 
   /if DEBUG /echo Entering KillTarget... 
    
   | check to make sure our target is still alive 
   /if $target()=="FALSE" { 
      /if DEBUG /echo Our target died before we attacked it, finding a new one. 
      /varset InvalidTargetID 0 
      /varset HaveTarget 0 
      /goto :EndKillTarget 
   }    
    
   | check to make sure our target is still full life, if not someone is probably fighting it 
   /if n $target(hp,pct)!=100 { 
      /if DEBUG /echo Our target started losing hp before we attacked it, finding a new one. 
      /varset InvalidTargetID $target(id) 
      /varset HaveTarget 0 
      /goto :EndKillTarget 
   } 
    
   | make sure our target doesnt have a target, if it does then it's attacking someone, skip it 
   /assist 
   /delay 5 
   /if DEBUG /echo Our target's ID=@ClosestMobID, assisted target's ID=$target(id) 
    
   | check the assisted target's id, then check its name.  if the name contains "corpse", then 
   | our original target should be considered valid. 
   /if n $target(id)!=@ClosestMobID /if n $instr(corpse,$target(name))==-1 { 
      /if DEBUG /echo Our target had a living target, it must've been fighting someone, skip it. 
      /varset InvalidTargetID $target(id) 
      /varset HaveTarget 0 
      /goto :EndKillTarget 
   } 
    
   | send our pet in 
   /pet attack 

   | wait until mob is dead, if it starts to flee, follow it 
:MainCombatLoop 
   /call CastSpells 
:FollowMob 
   | check to see if the mob is getting away from us, if so follow 
   /if n $target(distance,nopredict)>cAtkRange { 
      /if DEBUG /echo Target moved away from us, following. 
      /face 
      /sendkey down up 
   } else { 
      /face 
      /sendkey up up 
   } 
    
   | check to see if the mob is getting too close to us, if so back off 
   /if n $target(distance,nopredict)<cTooCloseRange { 
      /if DEBUG /echo Target getting too close to us, backing away. 
      /face 
      /sendkey down down 
   } else { 
      /face 
      /sendkey up down 
   } 
    
   | if we lose our target while attacking it, then the mob died. 
   /if $target()=="FALSE" /goto :EndKillTarget 
   /goto :MainCombatLoop 

:EndKillTarget 
   | make sure our pet follows us 
   /pet follow 
   | make sure we stop moving 
   /sendkey up up 
   /sendkey up down 
    
   /if DEBUG /echo Leaving KillTarget... 
/return 

| ============================================================== 

Sub LootTarget 
:StartLootTarget 
   /if DEBUG /echo Entering LootTarget... 
    
   | target the corpse of the mob we just killed 
   /target id @ClosestMobID 
    
   | move up to it 
   /face 
:CheckCorpseDistance 
   /call CheckForObst 
   /if n $target(distance)>15 { 
      /face 
      /sendkey down up 
      /goto :CheckCorpseDistance 
   } else { 
      /sendkey up up 
   } 

   | open the loot window 
   /loot 
   /delay 2s 
    
   | check each slot (0-7) to see if its something we want to keep 
   /for LootSlot 0 to 7 
      /click left corpse @LootSlot 
      /delay 1s 

      | if there is nothing on the cursor, then we are out of loots, stop the loop 
      /if "$cursor()"=="NULL" /goto :EndLootTarget 
      
      /if DEBUG /echo Checking loot slot #@LootSlot: $cursor(name) 

      | check whats on our cursor against the list of things we DONT want to keep 
      /for LootArrayIndex 1 to @DontLootArraySize 
         /if "$cursor(name)"=="@DontLootArray(@LootArrayIndex)" { 
            /if DEBUG /echo $cursor(name) matches @DontLootArray(@LootArrayIndex), destroying. 
               /click left destroy 
               /delay 1s 
             /goto :NextLoot 
         } 
      /next LootArrayIndex 

      | check whats on our cursor against the list of things we want to keep 
      /for LootArrayIndex 1 to @LootArraySize 
         /if "$cursor(name)"~~"@LootArray(@LootArrayIndex)" { 
            /if DEBUG /echo $cursor(name) matches @LootArray(@LootArrayIndex), keeping. 
               /click left auto 
               /delay 1s 
             /goto :NextLoot 
         } 
      /next LootArrayIndex 
      
      | if we make it to here, it means that the loot didnt match anything in our list 
      | so, we destroy the object. 
      /if DEBUG /echo $cursor(name) doesn't match anything in our list, destroying. 
      /click left destroy 
      /delay 1s 
      
:NextLoot 
   /next LootSlot 

:EndLootTarget 
   /press esc 
   /varset HaveTarget 0 
    
   | if our bags are full, its time to stop hunting and go sell.  For now, end the macro. 
   | /if n $freeinv(space)==0 /varset BagsFull 1 
   | /if DEBUG /echo Inventory space remaining: $freeinv(space) slots. 
    
   /if DEBUG /echo Leaving LootTarget... 
/return 


| ============================================================== 

Sub CastSpells 
   /if DEBUG /echo Entering CastSpells... 
:StartSpells 

   | see if we have mana to spare 
   /if n $char(mana,pct)<20 /call MedUp
    
   | decide which spell to cast 
   /if   n $char(buff,"SelfShieldSpell")==0 { 
      /if DEBUG /echo Trying to cast "SelfShieldSpell". 
      /call NoFizzleCast "SelfShieldSpell" 
      /if DEBUG /echo Delay time is: $int($calc($spell("SelfShieldSpell",casttime)*10+5)) 
      /delay $int($calc($spell("SelfShieldSpell",casttime)*10+5)) 
      /goto :StartSpells 
   } 
         
   | check to see if we have a pet up and cast one if we dont
   /if n $char(pet)==0 {
       /if DEBUG /echo Trying to cast "constPetSpell".
       /call NoFizzleCast "constPetSpell"
       /if DEBUG /echo Delay time is: $int($calc($spell("constPetSpell",casttime)*10+5)) 
       /delay $int($calc($spell("constPetSpell",casttime)*10+5)) 
       /goto :StartSpells 
      }
   /if n $char(pet)!=0 { 

      | check to see if we need to heal our pet. 
      /if n $spawn($char(pet),hp,pct)<50 { 
         /if DEBUG /echo Trying to cast "PetHealSpell".      
         /target id $char(pet) 
         /call NoFizzleCast "PetHealSpell" 
         /if DEBUG /echo Delay time is: $int($calc($spell("PetHealSpell",casttime)*10+5)) 
         /delay $int($calc($spell("PetHealSpell",casttime)*10+5)) 
         /goto :StartSpells 
      } 

      | check to see if we need to buff our pet 
      /if n @PetHasteStatus==0 { 
         /if DEBUG /echo Trying to cast "PetBuffSpell". 
         /target id $char(pet) 
         /call NoFizzleCast "PetBuffSpell" 
         /if DEBUG /echo Delay time is: $int($calc($spell("PetBuffSpell",casttime)*10+5)) 
         /delay $int($calc($spell("PetBuffSpell",casttime)*10+5)) 
         /varset PetHasteStatus 1 
         /goto :StartSpells 
      } 
   } 
   /target id @ClosestMobID 
   /if DEBUG /echo Leaving CastSpells... 
/return 

| ============================================================== 

Sub NoFizzleCast 
   | make sure we dont get passed a null spell name 
   /if "@Param0"!="" { 
:NoFizzleCastStart 
      /varset FizzleFlag 0
      /if "$char(state)"!="STAND" /stand
      | check to make sure we have mana to cast this spell 
      /if n $char(mana,cur)<$spell("@Param0",mana) /call MedUp
      
      /cast "@Param0" 
      /doevents Fizzle 
      
      | if we fizzled, try to cast again 
      /if n @FizzleFlag==1 /goto :NoFizzleCastStart 
   } 
/return 

| ============================================================== 

Sub MedUp
 :MedStart
     /if "$char(state)"=="STAND" /sit
     /delay @MedTime
     /if n $char(mana,cur)<70 /goto :MedStart
     /if "$char(state)"!="STAND" /stand
/return

| ============================================================== 

Sub CheckForObst 
   /if n $char(x)==@LastPosX /if n $char(y)==@LastPosY { 
      /varadd ObstCount 1 
   } else { 
      /varset ObstCount 0 
   } 
    
   /varset LastPosX $char(x) 
   /varset LastPosY $char(y) 
    
   /if n @ObstCount>3 { 
      /call GoAroundObst 
   } 
/return 

| ============================================================== 

Sub GoAroundObst 
   /if DEBUG /echo Entering GoAroundObst... 
   | back up some 
   /sendkey up up 
   /sendkey down down 
   /delay 1s 
   /sendkey up down 
    
   | go left or right a bit, randomly 
   /if n $rand(2)==1 { 
      /sendkey down left 
      /delay 5 
      /sendkey up left 
   } else { 
      /sendkey down right 
      /delay 5 
      /sendkey up right 
   } 
    
   | move forward a bit 
   /sendkey down up 
   /delay 1s 
   /sendkey up up 
    
   /if DEBUG /echo Leaving GoAroundObst...    
/return 

| EVENTS ======================================================= 

Sub Event_PetHasteDown 
   /varset PetHasteStatus 0 
/return 

Sub Event_Fizzle 
   /varset FizzleFlag 1 
/return 
Please take a look and tell me what you think.
Safe macroing
Last edited by Mixy on Thu Oct 30, 2003 8:14 am, edited 1 time in total.

DekeFentle
a lesser mummy
a lesser mummy
Posts: 48
Joined: Wed Oct 22, 2003 1:41 pm

Post by DekeFentle » Mon Oct 27, 2003 12:12 pm

I’ve been using the first one and started having problems when I put “large areonide(sp)” in the target array. I started targeting large pirana! Needless to say this is a bad thing :shock:

Code: Select all

/for MobArrayIndex 1 to @MobArraySize 
/target npc nopcnear cAntiKSRadius notid InvalidTargetID @MobArray(@MobArrayIndex)
I change the above to

Code: Select all

/for MobArrayIndex 1 to @MobArraySize 
/target npc nopcnear cAntiKSRadius notid InvalidTargetID “@MobArray(@MobArrayIndex)”
Just added quotes around @MobArray(@MobArrayIndex) I now get the spiders I expect instead of drowning.

I’ll check your new one out tonight once I update. I can't wait to get output to a new window!
Revelation 6:8

Guest

Problem with new MQ

Post by Guest » Wed Oct 29, 2003 8:01 pm

Was using this wonderful macro just today with an older version of MQ. Updated, new compile everything. Now when i run the macro it targets fine but it says that the mob is two close even though its far as hell away. Any ideas? did not change any variables from the old version to the new version. Just thinks that I am right on the mob when in fact I am not.