11/06/03 Updated necrofarm.mac v.0.4.1

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

Moderator: MacroQuest Developers

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

11/06/03 Updated necrofarm.mac v.0.4.1

Post by Stogar » Fri Nov 07, 2003 8:42 pm

All credit for this script goes to Scrime. I fixed a problem with moving to target by using search and replace.
-Scrime if you have a new version I'll whack this post, thanks for the macro.

Code: Select all

|  Fixed necrofarm.mac - v0.4.1  11/06/03 
|   - removed most "nopredict" from distance calcs in /face
|   - added "/face loc $target(y), $target(x)" in MoveToTarget Sub
|   - only oddity I can see is that character looks up just before attacking mob
|   - All credit goes to Scrime for this awesome script - Stogar
|
|  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        1500

| spell names 
#define SelfShieldSpell      "Greater Shielding" 
#define PetBuffSpell      "Augment Death" 
#define PetHealSpell      "Mend Bones" 

| special events to respond to 
#event PetHasteDown   "Your pet's Augment 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" 
         
   | set up the loot array 
   /call AddToLootList "silk" 
   /call AddToLootList "lightstone"
    
   | 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)          
         } 
      } 
      
      | 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)<@ClosestMobDist { 
         /if DEBUG { 
            /echo $target(name) is closer than our former target, switching. 
         } 
         /varset ClosestMobID $target(id) 
         /varset ClosestMobDist $target(distance) 
         /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 loc $target(y), $target(x) 
   /sendkey down up 
    
   | check to see if we are close enough yet 
   /if n $target(distance)<=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)>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)<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 

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

Also Works great for Shamans

Post by tac8357 » Sat Nov 08, 2003 12:23 pm

With some minor spell changes you can use this macro for any class that have pets....... Works great

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

Post by DekeFentle » Sun Nov 09, 2003 11:30 am

I agree wonderful macro! However I'm concerned about the amount of feed back into the chat window generated by pressing ESC so often and the amount to trageting that this does. (I read here somewhere that everytime you target someting EQ can see that server side)

Isn't there some way to use $searchspawn to find and move to the mob and only target it once you get there? I have asked this in a couple of other places and still now feed back.
Revelation 6:8

Sephin

Suggestion

Post by Sephin » Sun Nov 09, 2003 12:17 pm

Hey I was wondering if we could do this beastlord style. I also was wondering if you could make it kill seafuries. This would solve the full bag loot because you can set the only gems on loot, they are stackable right? If not dismiss this, but still a beastlord one would be nice. Im no programmer, but I might try messing around with it switching spell names and stuff.

Also are mounts 6 hour buffs like lucy says? If so can you add in the script for the person to summon a horse and mount it once it wears off. I havent looked over the whole thing, but it looks nice.

User avatar
Seagreen500
crash test
Posts: 47
Joined: Mon Nov 10, 2003 1:04 am

/look 0

Post by Seagreen500 » Mon Nov 10, 2003 7:17 pm

I found that when I got close to a mob, and used /face it would look up also.
Multiple /face's equal looking ever higher.
I /face once then
/look 0

thus setting my view position to straight ahead.

This looks like a great script and I am hoping to mod it to my Enc's needs tonight ;)

Thanks

jon5137
orc pawn
orc pawn
Posts: 12
Joined: Mon Nov 17, 2003 2:09 pm

Post by jon5137 » Mon Nov 17, 2003 7:31 pm

Quick question, how do I had more buffs to the list? I want it to load up 3 or 4 buffs on myself and pet. Also is there a way to make it so I slow mob then am ready to heal pet. AS it is right now the bot just stands there waiting to heal pet. Seems there should be a way to add in maybe a combat or offensive spell option or a melee option as I am a bst. Any tips would help :)

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

Post by Stogar » Thu Nov 20, 2003 12:35 pm

I'll have to try that /look 0, maybe in the combat loop.


As far as other buffs, heals, slows, etc.... I'd check Scrime's other necro script posted in this forum. This script is a farming script really I've never needed to heal or slow mobs, but then again I am farming spiderlings. If my pet needs healing after a fight with one of those, I need to play another class.

If you farming something moderately tough then maybe just do a quick and dirty /cast X, with X being the spell gem for slow. As far as healing goes you'd be best using his other necro script or hacking pet heal code from another one.