• You've discovered RedGuides 📕 an EverQuest multi-boxing community 🛡️🧙🗡️. We want you to play several EQ characters at once, come join us and say hello! 👋
  • IS THIS SITE UGLY? Change the look. To dismiss this notice, click the X --->
Resource icon

Simple Farm Mob Macro (2 Viewers)

One thing I have come across rarely is that sometimes the macro gets stuck at a certain point. Probably more mesh related than anything.

Is there some way to either check if you have moved location within 60 seconds and if not then move to a known starting point?

By the way, sorry to the original poster for derailing his thread slightly!
 
I was looking for something like this and google turned up this post. I found this script to be great, my only complaint was that providing all those mob names on the command line. It's OK if you just have two or three targets, but I had 16.

So I modified this script to read an INI file that contained mobs to hunt based on the zone the script was invoked in. I have never tried to code a macro before, so I am probably not doing it the best way, but it "appears" to work.


killbot.mac
Rich (BB code):
| Update to killbot.mac v1.4 - Use INI file rather than command line arguments
| killbot.mac by Rogue601  v1.4 - work in progress
|
| This macro is meant as a tutorial for myself and possibly others.
| I tried to keep it clean and OVER comment so others know what and why
|
| The point of this macro is to pick a list of mobs you want to farm.
| It's meant to be simple and not have ignorelists or files.
|
| Please don't afk with this and get in trouble.
|
| This requires that you are running MQ2Nav and have a valid mesh.
|
| used with Autoloot this is a very effecting macro for farming tradeskill materials
| I started this to farm bear skins. I've spent more time on it then I did on bearskins. LOL
| enjoy!  

| TODO - Add nav path distance to override radius


| -------------------------------------------------------------------------------------
| Sub Main
| -------------------------------------------------------------------------------------
Sub Main


| COMMENT : Declare variables to save data to work with
| COMMENT : to set a variable use the /varset command example: /varset searchRadius 10000
| COMMENT : to use the variable in code  ${searchRadius}

    /if (2 > ${Macro.Params}) {
        /echo 
        /echo Usage: /mac killbot radius ini_file
        /echo
        /echo Example : /mac killbot 10000 farm.ini
        /echo Note: There is no anchor, radius is from your current location after a kill.
        /endmac
    }

    /declare debugOn                     bool     outer FALSE    
    /declare iniFilename                 string     outer ${Param1}
    /declare activeMobID                     string    outer 0
    /declare searchRadius                     int     outer ${Param0}    
    /declare searchRadiusZ                     int     outer 500  
    
    | ----------------------------------------------------------------------------
    | farmMobList - Build a mob list array
    | ----------------------------------------------------------------------------    

    | COMMENT : The INI file containing the mobs we want to hunt has been
    | COMMENT : provided. Each section in the file contains the zone shortname,
    | COMMENT : followed by a k,v pair of mobname, integer. If the integer is one, 
    | COMMENT : we want to hunt the mob. Anything else, we do not.

   
    | COMMENT : Declare some variables we will need to interpret the file. First 
    | COMMENT : determine the current zone shortname.
    
    /declare mobCount                             int     local   0
    /declare x                                    int     local   0
    /declare currentZoneName                      string  local
    /varset currentZoneName ${Zone[${Zone.ID}].ShortName}
    
    | COMMENT : Now load the entries corresponding to that zone from the INI file. 
    | COMMENT : There is no way to know ahead of time what is in there, and INI 
    | COMMENT : merely returns a string, not an array. So it is necessary to first 
    | COMMENT : parse that string and count how many mobs we need to hunt.
    
    /echo Loading ${currentZoneName} from ${iniFilename}
    /echo ${Ini[${iniFilename}]}
    /declare mobList                             string local 
    /varset mobList ${Ini[${iniFilename},${currentZoneName}]}
    /declare mobListCount                        int local 0
    /declare mobType                             string local
    /declare mobTruth                            string local
    
    | COMMENT : The total number of pipe characters in the returned string. The 
    | COMMENT : maximum number of mobs is that plus one (it is a separator).
    /varset mobListCount ${Math.Calc[${mobList.Count[|]} + 1]}
    /echo INI contained a maximum of ${mobListCount} entries in this section.
    
    | COMMENT : Iterate through that list, checking that each entry is non-NULL, 
    | COMMENT : and then check if the value is '1'. Count only entries that meet 
    | COMMENT : both criteria.
    
    /for x 1 to ${Math.Calc[${mobListCount}+1]}
        /varset mobType ${mobList.Arg[${x},|]}
        /varset mobTruth ${Ini[${iniFilename},${currentZoneName},${mobType}]}
        /if (${mobType.NotEqual[NULL]} && ${mobTruth.NotEqual[NULL]})    {    
            /if (${mobTruth.Equal[1]}) {                                
                /varcalc mobCount ${mobCount} + 1
            }
        }
    /next x
    /echo Found ${mobCount} mobs to hunt in this zone.
    
    | COMMENT: Allocate the findMobList array, sized to match the number of target 
    | COMMENT: mobs determined above. 
    /declare findMobList[${mobCount}]      string  outer
    /declare y                                    int     local   1
    
    | COMMENT: Now go back through the list, adding mobs to findMobList much as was 
    | COMMENT: done during the sizing step.
    /for x 1 to ${Math.Calc[${mobListCount}+1]}
        /varset mobType ${mobList.Arg[${x},|]}
        /varset mobTruth ${Ini[${iniFilename},${currentZoneName},${mobType}]}
        /if (${mobType.NotEqual[NULL]} && ${mobTruth.NotEqual[NULL]})    {                
            /if (${mobTruth.Equal[1]}) {                    
                /varset findMobList[${y}] ${mobType}
                /varcalc y ${y} + 1
            }
        }
    /next x        

    
    | COMMENT : if debug is on we'll display the list
        /if (!${debugOn}) {
        /echo Welcome to Killbot!, Received ${findMobList.Size} mob names to hunt.
        /for x 1 to ${findMobList.Size}
            /echo ${x}. ${findMobList[${x}]}  
        /next x
    }

    
    | ----------------------------------------------------------------------------
    | Initialize - Set some defaults and clear the xtarget list    
    | ----------------------------------------------------------------------------    
    /if (${debugOn}) /echo DEBUG: Initilizing MobList, xTar and Nav Mesh
    /xtar remove
    /nav reload
    
    
    | ----------------------------------------------------------------------------
    | Main Loop - This is where the magic happens. 
    |        1.  Agroed: If we are agroed deal with that first
    |        2. FindMob: Find the type of mob name you are looking for
    |        3.  NavMob: Navigate to the mob using MQ2Nav
    |        4. KillMob: Kill the Mob using MQ2Melee    
    | ----------------------------------------------------------------------------
        :mainloop
                    
            
         | -----------------------------------------------------------------------------------
        | 1. AGROED : If I don't have an activeMobID, but I have an Xtar that means
        |       I have been agroed.  Let's make that my active target and skip the findMob
        |------------------------------------------------------------------------------------
                /if (${activeMobID}==0 && ${Me.XTarget[1].ID}) {
                    
                    /if (${debugOn}) /echo DEBUG: Agroed: activeMobID: ${activeMobID} Xtar: ${Me.XTarget[1].ID}
                    /varset activeMobID ${Me.XTarget[1].ID}
                    
            
        | ----------------------------------------------------------------------
        | 2. FindMob : activeMobID NO then Findone or wait
        |     Here we check for an activeMobID or if we have agro in Xtarget[1]
        |    If we do NOT then we need to call FindMob
        | -------------------------------------------------------------------------
        } else /if (${activeMobID}==0 && !${Me.XTarget[1].ID}) {
                /if (${debugOn}) /echo DEBUG: gotoloopfindmob: No Active Target.
                /varset activeMobID 0
                /call FindMob
                
                
         
        
        | --------------------------------------------------------------------------------
        | 3. NavMob: If we have an activeMobID and it's located further then 30 then Navigate
        |         If we have an Xtar because of agro lets stop nav and switch
        | ---------------------------------------------------------------------------------  
        } else /if (${Spawn[id ${activeMobID}].ID} && ${Spawn[${activeMobID}].Distance} > 30) {
        
            /if (${activeMobID} == ${Me.XTarget[1].ID} || !${Me.XTarget[1].ID}) {
                /call NavMob    
            } else {
                /squelch /nav stop
                /varset activeMobID ${Me.XTarget[1].ID}    
            }
          

        | ----------------------------------------------------------
        | 4. KillMob : If everything worked we are near the activeMobID
        | ----------------------------------------------------------              
        } else {
                
                /call KillMob    

        }
            
            
           | COMMENT : the mainloop runs every 10 seconds. Change this to spead it up or slow it down.
           /doevents
           /delay 10
            
    /goto :mainloop

    :mainend
    /endmac
/return 



| -------------------------------------------------------------------------------------
| OnExit - Things it does when you type /endmac
| -------------------------------------------------------------------------------------
:OnExit
    /setchattitle MQ2
    /squelch /nav stop
    /stick off
    /end
        


| -------------------------------------------------------------------------------------
| Sub FindMob - Locate a Mob in the radius you specified
| -------------------------------------------------------------------------------------
Sub FindMob
    | COMMENT : Simple radius search. This will be replaced with a NAV search eventually
    | REMOVED : old simple one parameter search 
    | REMOVED : /varset activeMobID ${NearestSpawn[npc targetable radius ${searchRadius} zradius ${searchRadiusZ} "${farmMobList}"].ID}

    /declare closestMobID                     int    local 0
    /declare closestMobDistance                float    local 99999
    /declare checkMobID                    int    local 0
    /declare checkMobDistance                float    local 0
    /declare x                        int    local 0    
    
    | COMMENT : Lets find which of our mobs is closest and set it as the activeMobID
    | COMMENT : We set the initial value of closestMobDistance to 99999 to guarantee the first
    | COMMENT : mob checked would be chosen by default.
    | COMMENT : We run a for loop on each mob name in the list and check it against the current one.
    
    /for x 1 to ${findMobList.Size} 
        /varset checkMobID ${NearestSpawn[npc targetable radius ${searchRadius} zradius ${searchRadiusZ} "${findMobList[${x}]}"].ID}
        /varset checkMobDistance ${Spawn[${checkMobID}].Distance}
        /if (${closestMobDistance} > ${checkMobDistance} && ${checkMobID} > 0)    {
            /varset closestMobID ${checkMobID}
            /varset closestMobDistance ${checkMobDistance}
        }
    /if (${debugOn}) /echo DEBUG: FindMob:"${findMobList[${x}]}" closestMobID:${closestMobID} closestMobDistance:${closestMobDistance} checkMobID:${checkMobID} checkMobDistance:${checkMobDistance} 
        
    /next x

    | COMMENT : Only change the activeMobID if we actually found something
    | NOTE : You can do if statements in one line if there is only one command. 
    /if (${closestMobID} > 0) /varset activeMobID ${closestMobID}
    
    /if (${debugOn}) /echo DEBUG: FindMob: radius ${searchRadius} zradius ${searchRadiusZ} "${farmMobList}"
    /if (!${activeMobID}) {
        /setchattitle Scanning for Targets
        /echo FindMob: Nothing Found waiting 5 seconds. 
        /delay 50
    } 
           
/return

| -------------------------------------------------------------------------------------
| Sub NavMob - Navigate using MQ2Nav 
| -------------------------------------------------------------------------------------
Sub NavMob
    | COMMENT : Once activeMobID is set we use MQ2Nav to get there.
    /if (${debugOn}) /echo DEBUG: NavMob: Tracking "${Spawn[${activeMobID}].CleanName}" ID: ${activeMobID} Distance: ${Spawn[${activeMobID}].Distance}
    /setchattitle Tracking ${Spawn[${activeMobID}].CleanName}
    /squelch /nav id ${activeMobID}   | COMMENT: squelch removes the output of the nav spam


    
/return    

| -------------------------------------------------------------------------------------
| Sub KillMob - Target and Kill
| -------------------------------------------------------------------------------------
Sub KillMob
    
    | COMMENT : This is the kill code. It's only reachable if activeMobID is set and it's close range

    /if (${debugOn}) /echo DEBUG: Killbot: Killing a ${Spawn[${activeMobID}].CleanName} ID: ${activeMobID}
        
    /target id ${activeMobID}
    /if (${Target.ID} && ${Target.Type.Equal[NPC]}) {
        
        | COMMENT : Turn off Nav and activate MQ2Melee's /stick and /killthis
        /squelch /nav stop
        /stick 8 uw
        /setchattitle Killing ${Target.CleanName}
        /killthis
                
        :gotoloopkeepfighting
        /if (${Target.ID} && ${Me.Combat} && ${Target.Type.Equal[npc]}) {
            /delay 10
            /doevents
            /if (${debugOn}) /echo DEBUG: KillMob: Combat Loop
            /goto :gotoloopkeepfighting            
        } 

    } else { 
        /varset activeMobID 0 
    }
            
    /if (${Target.Type.Equal[corpse]}) {
        /if (${debugOn}) /echo DEBUG: KillMob: Clearing Corpse Target
        /squelch /target clear
        /varset activeMobID 0
    }
    
/return

Here's a sample INI file, in case you ever want to farm defiant in Steamfont... (4000+ kills, no robe, I suffer for my lost causes). The invocation here might look something like:

Rich (BB code):
 /mac killbot 1000 farm.ini

And the example file:
farm.ini
Rich (BB code):
[steamfontmts]
a_giant_diseased_rat=1
a_large_yellow_recluse=1
a_giant_yellow_recluse=1
a_minotaur_slaver=1
a_gnome_skeleton=1
a_decaying_gnome_skeleton=1
a_mountain_brownie=1
a_grikbar_shaman=1
a_grikbar_kobold=1
a_kobold_runt=1
a_kobold_scout=1
a_krag_chick=1
a_krag_elder=1
a_small_mountain_lion=1
rogue_clockwork=1
a_harpy=1
 
This has been working well for me but some zones I am trying to do my Hunter achieves would benefit from Casting Invis AA and then when at next target to /dggae /makemevisible.

When I add these:
INI:
        | COMMENT : Turn off Nav and activate MQ2Melee's /stick and /killthis
        /squelch /nav stop
        /stick 8 uw
        /cast 1
        /setchattitle Killing ${Target.CleanName}
        /call killmob
        /dgge /makemevisible
                   
        :gotoloopkeepfighting
        /if (${Target.ID} && ${Me.Combat} && ${Target.Type.Equal[npc]}) {
            /delay 10
            /doevents
            /if (${debugOn}) /echo DEBUG: KillMob: Combat Loop
            /goto :gotoloopkeepfighting           
        }

    } else {
        /varset activeMobID 0
    }
           
    /if (${Target.Type.Equal[corpse]}) {
        /if (${debugOn}) /echo DEBUG: KillMob: Clearing Corpse Target
        /squelch /target clear
        /varset activeMobID 0
        /alt act 1210
    }

I added /cast 1 to activate KOS mobs as I do not use mqmelee.

It will constantly spam /makemevisible. How can I make this fire once only? I think I may have to use MQreact and just get my other chars to /cast 1 when the main /cast 1. Though was hoping for some simple logical programming.
 
Last edited by a moderator:
Briefly skimming the code and making some assumptions based on missing info in your post...looks like you replaced
INI:
/call killthis
With
INI:
/call killmob
But it's inside the killmob sub, so it is in some kind of recursive infinite loop? Just speculation though.
 
I can only assume that /call killthis is a mqmelee command and won't work with cwtn plugins. It just spams an error. I changed it to kill mob and the spam stopped and it worked with cwtn plugin fighting.
 
I can only assume that /call killthis is a mqmelee command and won't work with cwtn plugins. It just spams an error. I changed it to kill mob and the spam stopped and it worked with cwtn plugin fighting.
Killthis is in fact an mq2melee command. With that said, the idea of killthis was to turn on melee and stick to the mob iirc. So perhaps a different sub to turn on attack and use a /stick command
 
You may consider trying MQ2Farmtest or Farm.mac, the plugin being the newest of the two. Farmtest is a plugin that should be included with VV.
I try the farmtest but don't think it has the same functionality, iirc I had to pick one mob name rather than a list.

Within killbot I could remove the killthis and kill mob as cwtn mag fires auto kill already if I get aggro from kos mob or via the /cast 1 command. So it works fine.

I just want to add in the invis and break invis so the rest of my crew activate via their cwtn plugins. It's odd it seems to fire make mevisible infinite times so for the next ten mins it scrolls through the mq window and I literally cannot invis as it breaks lol.

Surely whilst the mob is not a corpse it shouldn't cycle that part over and over?
 
I went with this in the end and made a MQ2react that turned off invis on my boxes IF they had something on xtarget1. Work fine for now, just have to disable the MQ2react before raids!

Dunno if this may help someone in future.


INI:
        | COMMENT : Turn off Nav and activate MQ2Melee's /stick and /killthis
        /squelch /nav stop
        /stick 8 uw
        /if (!${Me.Combat}) /cast 3
        /if (!${Me.Combat}) /pet attack
        /setchattitle Killing ${Target.CleanName}
        
                    
        :gotoloopkeepfighting
        /if (${Target.ID} && ${Me.Combat} && ${Target.Type.Equal[npc]}) {
            /delay 10
            /doevents
            /if (${debugOn}) /echo DEBUG: KillMob: Combat Loop
            /goto :gotoloopkeepfighting           
        }

    } else {
        /varset activeMobID 0
    }
            
    /if (${Target.Type.Equal[corpse]}) {
        /if (${debugOn}) /echo DEBUG: KillMob: Clearing Corpse Target
        /squelch /target clear
        /varset activeMobID 0
        
        :gotoloopkeepinvising
        /alt act 1210
        /if (!${Me.Invis}) {
            /delay 30
            /goto :gotoloopkeepinvising           
        }

    }
    
/return
 
Simple Farm Mob Macro

Users who are viewing this thread

Back
Top