• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver
[Macro] GroundGrab.mac

Release [Macro] GroundGrab.mac 2020-05-24

No permission to download
Status
Not open for further replies.

ChatWithThisName

⚔️🛡️🗡️
Moderator
Joined
Dec 29, 2017
RedCents
23,976¢
|||||||||||||||||||||||||||||||||||||||||||||||||||
|GroundGrab.mac by Chatwiththisname
|v1.0 ~ Initial release 3/9/2018
|
|Usage: /mac GroundGrab item name I want ~~ /mac GroundGrab corn rose
| Also accepts partial name. /mac GroundGrab corn
|
|
|Purpose: Will navigate a zone and pick up any ground spawn you've
| specified. Will react to aggro (XTargets) to stop navigation
| and kill the add before resuming to it's destination.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||

Tested in misty thicket for "green leaf"
and tested in oceangreen hills for "corn rose" while reacting to adds.

Kaen01. I know you would prefer I use /nav item, no. lol.

Requirements: MQ2Nav with a mesh created for the zone you want to use it in.
~~~~~~~~~The ability to kill targets in the zone you are navigating.
 
Last edited:
Not sure if this is a loot.ini problem or this mac

works great but i ran into problem while in elddar forest

went to pick up treant branches -- it would also nav to the ancient branches and attemp to pick them up as well - they are lore

I set loot ini to destroy and i would get item destroyed message but item would still be in inventory and would get stuck on the next one.

Is there a way to ignore the ancient ones?
 
Last edited:
This works well for harvesting Brell's Bounty in Brell's Rest if you turn the radius all the way down and rebuild the mesh.
 
Not sure if this is a loot.ini problem or this mac

works great but i ran into problem while in elddar forest

went to pick up treant branches -- it would also nav to the ancient branches and attemp to pick them up as well - they are lore

I set loot ini to destroy and i would get item destroyed message but item would still be in inventory and would get stuck on the next one.

Is there a way to ignore the ancient ones?


depends on what you are typing to sort out the selection of the item. It's designed to accept partial names. Though I honestly never put in anything to cause it to accept an exact name. So if they both have the same exact name but one is ancient, then I'm afraid not.
 
1567478403546.png
This is what I am getting. Anyway to fix this? I am trying to collect glowing globes
 
Where are you getting new ones from? I just used Mesh Generator for new Mesh samething happens.
 
The mesh generator is not perfect. To get a truly GREAT map that has no bad pathing could take a person a day or more to edit to get it close. That does not include the learning curve of a day just using the mesh generator.

I had asked the same kind of question here:
https://www.redguides.com/community/threads/bushes-in-gmm-seem-to-mess-with-mq2nav.68695/

TDLR: Just pressing "Build Mesh and "Save" doesn't make a perfect map.

Some people have posted some custom meshes, if you can find them on the boards. The last one I remeber was one for GMM and even that one still gave me headaches, although it was way better the the Default build.
 
I have his Mesh files still giving me the error's
there are plenty of poorly placed collectibles in areas that are unreachable even with a perfect mesh- this could be one of those - outside of that you'll just need to "handle it"
 
Any chance you could add a check for return from Nav "Could not find path to destination" and skip those items.

Often a spawn will be inside a tree or rock and cannot be navigated to. In these cases the script gets hung trying to reach the item. You can manually move closer to the next spawn and it will kick off again until you end up with the problem spawn as the closest item again.

Thanks in advance!
 
There isn't really support for handling that to my knowledge, at least there wasn't when I created the macro. Had there been a way to manage it I certainly would have gave it a go.
 
Any chance you could add a check for return from Nav "Could not find path to destination" and skip those items.

Often a spawn will be inside a tree or rock and cannot be navigated to. In these cases the script gets hung trying to reach the item. You can manually move closer to the next spawn and it will kick off again until you end up with the problem spawn as the closest item again.

Thanks in advance!




Ok so id like to help fix some of the mesh problems with some ideas. Maybe we can add an event for the "Could not find path to destination". Once its hits that event is skips that loc and goes to another loc. maybe put in s secondary search for the next closest groundspawn. might have to add multiple searches for maybe up to 5 closest locs. also maybe have an ignore loc storage so it looks past that loc that you cant get to. all in all the mac is really nice and thank you for making it.
 
I think this is probably a mesh issue, but thought I'd ask...

In 4th Gate (as an example) if you are in front of the Barracks and the next shiny is in the Darklight Palace, it will say that it cannot find a path. If you manually run through the tunnels, once you clear the tunnel it will pick back up and run into the palace. However, even inside the palace, if often doesn't understand how to get from one section to another, but if you start running there, it eventually picks it up.

Mesh issue?
 
Would be curious to see how to code a destroy item command when you picked up something you didn't want.

Edited to not confuse peoples.
 
Last edited:
^^^^ those confusing, misdirected posts should be split out!

Side note (and relevant to this thread)...

Is there a way to have the macro /end if mq2nav can't get to a spawn loc? Right now it spams the FUCK out of the mq2 window until you end it yourself (at which point the spam can continue on by itself for another 10+ minutes) or you crash. I get that there are TLO limitations that make skipping a spawn point not viable (although, you could prolly hardcode a mac to just /nav to all the possible locations and pick up a glowing if there happens to be on there.... hrm).
 
having issues with this mac it says it found all of the items asked it to search for but i still see the groundspawns on the map and the mesh works because i can do pocketfarm mac. i run the mac and it says "all _________ were collected and waiting until more spawns any ideas on why its not going to get them

Edit I figured out the issue thank u for being an awesome day everyone
 
If your going for collectibles you would do /mac groundgrab glowing

What ever mq2 detects the item your going for on the map would be the variable you would put after the /mac groundgrab XXX
 
thanks for the help now it is scrolling super fast on the MQ2 window like it is stuck and not picking up like it was any ideas what might be wrong

Edit** i think the groundspawn is in a tree how do you get around this scenario
 
Last edited:
Unfortunatly there isnt , you can move to other side of the zone and let it repopulate and restart it.
 
I made some headway today getting this macro to skip groundspawns that can't be navigated to. Not tested thoroughly but appears to be working well.

Code:
    |||||||||||||||||||||||||||||||||||||||||||||||||||
|GroundGrab.mac by Chatwiththisname
|v1.0 ~ Initial release 3/9/2018
|
|Usage: /mac GroundGrab item name I want ~~ /mac GroundGrab corn rose
|        Also accepts partial name. /mac GroundGrab corn
|      
|
|Purpose: Will navigate a zone and pick up any ground spawn you've
|            specified. Will react to aggro (XTargets) to stop navigation
|            and kill the add before resuming to it's destination.
|
    |||||||||||||||||||||||||||||||||||||||||||||||||||
Sub Main
    /if (!${Bool[${Param0}]}) {
        /echo \ayYou must provide an item to find. Usage: /mac GroundGrab item_name_to_find
        /echo \arEnding Macro.
        /end
    } else {
        /declare itemName string outer ${Param0}
    }
    /call CheckMesh
    /call Declares
    /declare i int local 1
    /while (${Bool[${Param${i}}]}) {
        /varset itemName ${itemName} ${Param${i}}
        /varcalc i ${i}+1
    }
    :getitems
    /echo \awLooking for \ay${itemName}
   
    /while (${Ground[${itemName}].ID}) {
        /call WaitNavGround "${itemName}"
    }
    /echo \awAll \ay${itemName} \awwere collected. Waiting until more spawn.
    /while (!${Ground[${itemName}].ID}) {
        /if (${Me.XTarget[1].ID}) {
            /if (${Navigation.Active}) /nav stop
            /call FarmStuff
        } else {
            /call GroupDeathChk
            /call GroupHealthChk
            /call GroupEndChk
            /call GroupManaChk
            /if (${useMerc}) /call CheckMerc
        }
        /if (${Me.Combat} && !${Me.XTarget[1].ID}) /squelch /target clear
        /delay 1s
    }
    /goto :getitems
/return

Sub WaitNavGround(GroundItemName)
    /declare i int local 1
    /if (${Debugging}) /echo \atGroundItemName: \ay${GroundItemName} \atDistance: \ay${Ground[${GroundItemName}].Distance3D}
    /while (${Ground[${GroundItemName}].Distance3D} > 15) {
        /if (${Navigation.Active}) {
            /if (${Me.XTarget[1].ID}) {
                /if (${Navigation.Active}) /nav stop
                /call FarmStuff
            } else {
                /call GroupDeathChk
                /call GroupHealthChk
                /call GroupEndChk
                /call GroupManaChk
                /if (${useMerc}) /call CheckMerc
            }
            /if (${Me.Combat} && !${Me.XTarget[1].ID}) /squelch /target clear
            /delay 10
        } else {
            /if (${Me.XTarget[1].ID}) {
                /if (${Navigation.Active}) /nav stop
                /if (${UseEQBC}) {
                    /bc ${Macro.CurLine} target xtarget ${Spawn[id ${Me.XTarget[1].ID}].Name}
                    /bcaa //target id ${Me.XTarget[1].ID}
                } else {
                    /target id ${Me.XTarget[1].ID}
                }
                /call FarmStuff
            } else {
                /call GroupDeathChk
                /call GroupHealthChk
                /call GroupEndChk
                /call GroupManaChk
                /if (${useMerc}) /call CheckMerc
            }
            /if (${Me.Combat} && !${Me.XTarget[1].ID}) /squelch /target clear

            /if (${Navigation.PathExists[loc ${Ground[${GroundItemName}].Y} ${Ground[${GroundItemName}].X} ${Ground[${GroundItemName}].Z}]}) {
                /nav loc ${Ground[${GroundItemName}].Y} ${Ground[${GroundItemName}].X} ${Ground[${GroundItemName}].Z}
            } else {
                /echo Unable to navigate to ${Ground[${GroundItemName}].DisplayName} at loc ${Ground[${GroundItemName}].Y} ${Ground[${GroundItemName}].X}. Searching for another groundspawn.

                /varset i 1
                /while (${Ground[${i}].ID}) {
                    /if (${Ground[${i}].DisplayName.Find[${GroundItemName}]}) {
                        /if (${Navigation.PathExists[loc ${Ground[${i}].Y} ${Ground[${i}].X} ${Ground[${i}].Z}]}) {
                            /nav loc ${Ground[${i}].Y} ${Ground[${i}].X} ${Ground[${i}].Z}
                            /break
                                            } else {
                            /echo Unable to navigate to ${Ground[${i}].DisplayName} at loc ${Ground[${i}].Y} ${Ground[${i}].X}. Searching for another groundspawn.
                        }
                    }
                    /varset i ${Math.Calc[${i}+1]}
                    /if (!${Ground[${i}].ID}) {
                        /echo No navigable groundspawns are available, waiting 30 seconds.
                        /delay 30s
                    }
                }
            }
        }
    }
    /if (${Navigation.Active}) /nav stop
    /invoke ${Ground[${GroundItemName}].DoTarget.ID}

    /invoke ${Ground[${GroundItemName}].Grab}
    /delay 2s ${Cursor.ID}
    /delay 5
    /autoinv
/return

Sub CheckMesh
    /if (!${Navigation.MeshLoaded}) {
        /nav reload
        /delay 1s ${Navigation.MeshLoaded}
        /if (!${Navigation.MeshLoaded}) {
            /echo "Ending Macro."
            /end
        }
    }
/return

Sub FarmStuff(string Enemy)
    /if (${Bool[${Enemy}]}) {
        /varset FarmMob ${Enemy}
        /if (${Debugging} && !${reportTarget}) {
            /echo Looking for: ${FarmMob}
            /varset reportTarget ${reportTarget.OriginalValue}
        }
    } else /if (!${reportTarget}) {
        /echo \arWe appear to have aggro.
        /varset reportTarget ${reportTarget.OriginalValue}
    }
    :findMob
    /if (${Target.Type.Equal[corpse]}) /squelch /target clear
    /if (${Window[RespawnWnd].Open}) /call GroupDeathChk
    /if (!${Me.XTarget[1].ID} || ${Window[RespawnWnd].Open}) {
        /call GroupDeathChk
        /call GroupHealthChk
        /call GroupEndChk
        /call GroupManaChk
    }
    /if (!${Spawn[id ${myTargetID}].ID} || ${Spawn[id ${myTargetID}].Type.Equal[Corpse]} && !${Me.XTarget[1].ID}) {
        /if (${Debugging}) /echo "Getting a target!"
        /varset myTargetID 0
        /call TargetShortest
        /if (${Debugging} && ${myTargetID}) /echo Target is ${Spawn[id ${myTargetID}]}
    }
    :navto
    /if (${Spawn[${myTargetID}].Distance} > 30 && !${Me.XTarget[1].ID}) {
        /call WaitNav ${myTargetID}
        /delay 10
        /goto :navto
    } else /if (!${Target.ID} && ${Target.ID} != ${myTargetID} && ${Target.ID} != ${Me.ID} && ${myTargetID} != 0 && !${Me.XTarget[1].ID}) {
        /if (${Debugging}) /echo I'm targeting ${Spawn[${myTargetID}].CleanName} ID: ${myTargetID}
        /if (${UseEQBC}) {
            /bc ${Macro.CurLine} target mytarget ${Spawn[id ${myTargetID].Name}
            /bcaa //target id ${myTargetID}
        } else {
            /target id ${myTargetID}
        }
        /delay 10
    }
    /delay 5
    /if (${Target.ID} && ${Target.Type.Equal[npc]}) {
        /if (${Navigation.Active}) /squelch /nav stop
        /stick uw loose moveback 8
        /setchattitle Killing ${Target.CleanName}
        /if (${UseEQBC}) {
            /bc ${Macro.CurLine} killthis
            /bca //killthis
        }
        /killthis
        :waitTillDead
   
        /if (${Target.ID} && ${Me.CombatState.Equal[Combat]} && ${Target.Type.Equal[npc]}) {
            /if (!${Me.Combat}) /attack
            /delay 10
            /goto :waitTillDead
        } else /if (${Target.Type.Equal[corpse]}) {
            /target clear
            /varset myTargetID 0
        }
    } else /if (${Me.XTarget[1].ID}) {
        /if (${Spawn[id ${Me.XTarget[1].ID} radius 30 zradius 50].ID} && ${Spawn[id ${Me.XTarget[1].ID} radius 30 zradius 50].LineOfSight}) {
            /if (${Navigation.Active}) /nav stop
            /if (${UseEQBC}) {
                /bc ${Macro.CurLine} target XTarget ${Spawn[id ${Me.XTarget[1].ID}].Name}
                /bcaa //target id ${Me.XTarget[1].ID}
            } else {
                /target id ${Me.XTarget[1].ID}
            }
            /setchattitle Handling add, ${Spawn[${Me.XTarget[1].ID}].CleanName}
        } else /if (${Spawn[id ${Me.XTarget[1].ID}].Distance} > 30 || !${Spawn[id ${Me.XTarget[1].ID} radius 30 zradius 50].LineOfSight}) {
            /nav id ${Me.XTarget[1].ID}
            /setchattitle Navigating to add ${Spawn[id ${Me.XTarget[1].ID}].CleanName}
            /while (${Spawn[${Me.XTarget[1].ID}].Distance} > 30) {
                /if (!${Navigation.Active}) /nav id ${Me.XTarget[1].ID}
                /delay 10
            }
        }
        /if (${UseEQBC}) {
            /bc ${Macro.CurLine} killthis
            /bca //killthis
        }
        /killthis
        /setchattitle Killing ${Target.CleanName}
        /goto :waitTillDead
    }
    /if (${UseEQBC} && !${Me.CombatState.Equal[Combat]}) {
        /bc ${Macro.CurLine} target me and stick.
        /bca //target id ${Me.ID}
        /delay 5
        /bca //stick 10 loose moveback uw
    }
/return

| --------------------------------------------------------------------------------------------
| SUB: GroupManaChk
| --------------------------------------------------------------------------------------------
Sub GroupManaChk
    /if (${Me.XTarget[1].ID}) /return
   
    /if (!${Me.Combat}) {
        /setchattitle "Group Mana Check"
        /if (${Me.PctMana} < ${MedAt} && ${Me.Class.CanCast} && !${Me.State.Equal[DEAD]}) {
            /echo \arYOU are low on mana!
            /setchattitle "Waiting on YOUR mana to reach ${MedTill}%"
            /if (!${Me.XTarget[1].ID}) {
                /while (${Me.PctMana} < ${MedTill} && !${Me.XTarget[1].ID} && !${Me.State.Equal[DEAD]}) {
                    /if (${Me.Standing} && !${Me.Casting.ID} && !${Me.Mount.ID}) /sit
                    /if (${UseEQBC}) {
                        /if (!${Defined[j]}) /declare j int local
                        /for j 1 to ${Group}
                            /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                        /next j
                    }
                    /delay 10
                }
            }
        }
        /if (${Group}) {
            /declare i int local
            /for i 1 to ${Group}
                /if ((${Group.Member[${i}].PctMana} < ${MedAt}) && ${Group.Member[${i}].Class.CanCast} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                    /echo \ar${Group.Member[${i}].Name} is low on mana!
                    /setchattitle "Waiting on ${Group.Member[${i}].Name}'s mana to reach ${MedTill}%"
                    /if (!${Me.XTarget[1].ID}) {
                        /while (${Group.Member[${i}].PctMana} < ${MedTill} && !${Me.XTarget[1].ID} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                            /if (${Me.Standing} && !${Me.Casting.ID} && !${Me.Mount.ID}) /sit
                            /if (${UseEQBC}) {
                                    /if (!${Defined[j]}) /declare j int local
                                    /for j 1 to ${Group}
                                        /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                                    /next j
                            }
                            /delay 10
                        }
                        /if (${UseEQBC}) {
                                /bc ${Macro.CurLine} stand up target me and stick
                                /bcaa //keypress w
                                /bca //target id ${Me.ID}
                                /delay 5
                                /bca //stick 10 loose moveback uw
                        }
                    }
                }
            /next i
        }
    }
/return

| --------------------------------------------------------------------------------------------
| SUB: GroupHealthChk
| --------------------------------------------------------------------------------------------
Sub GroupHealthChk
    /if (${Me.XTarget[1].ID}) /return
   
    /setchattitle "GroupHealthCheck"
    /if (!${Me.Combat}) {
        /if (${Me.PctHPs} < ${HealAt} && !${Me.State.Equal[DEAD]}) {
            /echo \arYOU are low on Health!
            /setchattitle "Waiting on YOUR health to reach ${HealTill}%"
            /if (!${Me.XTarget[1].ID}) {
                /while (${Me.PctHPs} < ${HealTill} && !${Me.XTarget[1].ID} && !${Me.State.Equal[DEAD]}) {
                    /if ((${Me.Standing}) && (!${Me.Casting.ID}) && (!${Me.Mount.ID})) /sit
                    /if (${UseEQBC}) {
                        /if (!${Defined[j]}) /declare j int local
                        /for j 1 to ${Group}
                            /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                        /next j
                    }
                    /delay 10
                }
            }
        }
        /if (${Group}) {
            /declare i int local
            /for i 1 to ${Group}
                /if (${Group.Member[${i}].ID}) {
                    /if (${Group.Member[${i}].PctHPs} < ${HealAt} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                        /echo ${Group.Member[${i}].Name} is low on Health!
                        /setchattitle "Waiting on ${Group.Member[${i}].Name} health to reach ${HealTill}%"
                        /if (!${Me.XTarget[1].ID}) {
                            /while (${Group.Member[${i}].PctHPs} < ${HealTill} && !${Me.XTarget[1].ID} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                                /if ((${Me.Standing}) && (!${Me.Casting.ID}) && (!${Me.Mount.ID})) /sit
                                /if (${UseEQBC}) {
                                    /if (!${Defined[j]}) /declare j int local
                                    /for j 0 to ${Group}
                                        /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                                    /next j
                                }
                                /delay 10
                            }
                            /if (${UseEQBC}) {
                                /bc ${Macro.CurLine} stand up target me and stick
                                /bcaa //keypress w
                                /bca //target id ${Me.ID}
                                /delay 5
                                /bca //stick 10 loose moveback uw
                            }
                        }
                    }
                }
            /next i
        }
    }
/return

| --------------------------------------------------------------------------------------------
| SUB: GroupEndChk
| --------------------------------------------------------------------------------------------
Sub GroupEndChk
    /if (${Me.XTarget[1].ID}) /return
   
    /setchattitle "GroupEnduranceCheck"
    /if (!${Me.Combat}) {
        /if (${Me.PctEndurance} < ${MedEndAt} && !${Me.State.Equal[DEAD]}) {
            /echo \arYOU are low on Endurance!
            /setchattitle "Waiting on YOUR Endurance to reach ${HealTill}%"
            /if (!${Me.XTarget[1].ID}) {
                /while (${Me.PctEndurance} < ${MedEndTill} && !${Me.XTarget[1].ID} && !${Me.State.Equal[DEAD]}) {
                    /if (${Me.Standing} && !${Me.Casting.ID} && !${Me.Mount.ID}) /sit
                    /if (${UseEQBC}) {
                        /if (!${Defined[j]}) /declare j int local
                        /for j 1 to ${Group}
                            /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                        /next j
                    }
                    /delay 10
                }
            }
        }
        /if (${Group}) {
            /declare i int local
            /for i 1 to ${Group}
                /if (${Group.Member[${i}].ID}) {
                    /if (${Group.Member[${i}].PctEndurance} < ${MedEndAt} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                        /echo \ar${Group.Member[${i}].Name} is low on Endurance!
                        /setchattitle "Waiting on ${Group.Member[${i}].Name} Endurance to reach ${HealTill}%"
                        /if (!${Me.XTarget[1].ID}) {
                            /while (${Group.Member[${i}].PctEndurance} < ${MedEndTill} && !${Me.XTarget[1].ID} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                                /if ((${Me.Standing}) && (!${Me.Casting.ID}) && (!${Me.Mount.ID})) /sit
                                /if (${UseEQBC}) {
                                    /if (!${Defined[j]}) /declare j int local
                                    /for j 0 to ${Group}
                                        /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                                    /next j
                                }
                                /delay 10
                            }
                            /if (${UseEQBC}) {
                                /bcaa //keypress w
                                /bc ${Macro.CurLine} stand up target me and stick
                                /bca //target id ${Me.ID}
                                /delay 5
                                /bca //stick 10 loose moveback uw
                            }
                        }
                    }
                }
            /next i
        }
    }
/return

| --------------------------------------------------------------------------------------------
| SUB: GroupDeathChk
| --------------------------------------------------------------------------------------------
Sub GroupDeathChk
   
    /if (${Me.State.Equal[DEAD]}) {
        /echo \arYOU~ have died! Waiting for YOU to get off your face.
        /setchattitle "You died, waiting for rez!"
        /while (${Me.STATE.Equal[DEAD]} ) {
            /delay 10
           
        }
    }
    /if (${Me.XTarget[1].ID}) /return
    /if (${Group}) {
        /declare i int local
        /for i 1 to ${Group}
            /if (${Group.Member[${i}].State.Equal[DEAD]} ) {
                /echo ${Group.Member[${i}].Name} has died. Waiting for them to get off their face.
                /setchattitle "${Group.Member[${i}].Name} has died. Waiting for Rez"
                /if (!${Me.XTarget[1].ID}) {
                    /while (${Group.Member[${i}].State.Equal[DEAD]} && !${Me.XTarget[1].ID}) {
                        /if ((${Me.Standing}) && (!${Me.Casting.ID}) && (!${Me.Mount.ID})) /sit
                        /if (${UseEQBC}) {
                            /if (!${Defined[j]}) /declare j int local
                            /for j 0 to ${Group}
                                /if (${j} != ${i}) {
                                    /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${i}].Name} //sit
                                }
                            /next j
                        }
                        /delay 10
                    }
                }
            }
        /next i
    }
/return

Sub TargetShortest
    /declare PullTargetID int local 0
    /declare Shortest int local 0
   
    /if (!${Me.XTarget[1].ID}) {
        |In order if I should even loop through to see how many mobs are in range I need to get a count based on my conditions
        /declare MobsInRange int local ${SpawnCount[npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"]}
        /if (${Debugging}) /echo There were ${MobsInRange} ${FarmMob} in radius of ${PullRange} and ZRad: ${ZRadius}.
        /declare i int local 0
        /declare j int local 1
        /if (${MobsInRange}) {
        |** PullList[#,1] = ID of mob, PullList[#,2] = PathLength **|
        |I created an array and made it the size of the mobcount by the 2 to store each mob's ID and the length of their nav path
            /declare PullList[${MobsInRange},2] int local 0
            |I set i equal to 1 and I iterate through each mob
            /for i 1 to ${MobsInRange}
                |just in case something dies, I don't to result in NULL during my check producing results
                /if (${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].Name.NotEqual[NULL]}) {
                    |/echo \atFound one. Maybe, lets see if it has a path.
                    |If there is a path and only if there is a path will I enter the following block statement. This is done to avoid adding mobs to the array that don't have a path.
                    /if (${Navigation.PathExists[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]} && ${Int[${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].Distance3D}]} <= ${Int[${Navigation.PathLength[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]}]}) {
                        |Now that I know this mob has a Navigation path, I need to add it to the array where ${j} is incremented only if I add a mob's ID and Path Length
                        |/echo Adding a mob to the pullList
                        /varset PullList[${j},1] ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}
                        /varset PullList[${j},2] ${Int[${Navigation.PathLength[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]}]}
                        |If this is the first mob I've added to the array, it is now my target and it has the shortest path.
                        /if (${j}==1) {
                            /varset PullTargetID ${PullList[${j},1]}
                            /varset Shortest ${PullList[${j},2]}
                        } else /if (${PullList[${j},2]} < ${Shortest}) {
                            |Otherwise if the mob I added has a PathLength shorter that the current shortest Nav Path, make it my target and set it as the shortest.
                            /varset PullTargetID ${PullList[${j},1]}
                            /varset Shortest ${PullList[${j},2]}
                        }
                        |Since I added a mob I need to increment j by 1 in the PullList Array.
                        /varcalc j ${j}+1
                    } else {
                        /if (${Debugging}) {
                            /echo \at${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].Name} was not a valid pull target.
                            /echo \ar${Navigation.PathExists[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]} && ${Int[${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].Distance3D}]} <= ${Int[${Navigation.PathLength[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]}]})
                        }
                    }
                }
            |Check the next mob in the NearestSpawn meeting my conditions loop
            /next i
            |Now that I've exited the loop, the PullTargetID variable is the one I want to navigate to and kill.
            /varset myTargetID ${PullTargetID}
            |Set the chattitle of the MQ2 window to the macro's status (Suggestion by Kaen01)
            /setchattitle Going to kill ${Spawn[id ${myTargetID}].CleanName}!
        }
    } else {
        /varset myTargetID ${Me.XTarget[1].ID}
    }
/return

Sub CheckMerc
    /if (${Mercenary.State.Equal[DEAD]}) {
        /echo Your mercenary has died. Waiting to be able to revive them.
        :waitForMerc
        /if (${Group} && ${Window[MMGW_ManageWnd].Child[MMGW_SuspendButton].Tooltip.Equal[Revive your current mercenary.]} && ${Window[MMGW_ManageWnd].Child[MMGW_SuspendButton].Enabled}) /notify MMGW_ManageWnd MMGW_SuspendButton leftmouseup
        /if (${Mercenary.State.Equal[DEAD]} && !${Me.XTarget[1].ID}) /goto :waitForMerc
    }
/return

Sub Declares(int Param0, string Param1)
    /declare FarmMob string outer ${Param1}
    /declare PullRange int outer ${Param0}
    /declare ZRadius int outer 50
    /declare Debugging bool outer FALSE
    /declare HealAt int outer 70
    /declare HealTill int outer 100
    /declare MedEndAt int outer 3
    /declare MedEndTill int outer 20
    /declare MedAt int outer 30
    /declare MedTill int outer 100
    /declare UseEQBC bool outer FALSE
    /declare Targets string outer
    /declare myTargetID int outer 0
    /declare reportTarget timer outer 5s
    /declare useMerc bool outer FALSE
        /declare WaypointCount int outer ${Math.Calc[(${Ini[..\MQ2Nav.ini,${Zone.ShortName}].Length}-${Ini[..\MQ2Nav.ini,${Zone.ShortName}].Replace[GroundGrab,].Length})/10]}
    /declare wpCounter int outer 0
/return
 
Last edited by a moderator:
I made some headway today getting this macro to skip groundspawns that can't be navigated to. Not tested thoroughly but appears to be working well.

Code:
    |||||||||||||||||||||||||||||||||||||||||||||||||||
|GroundGrab.mac by Chatwiththisname
|v1.0 ~ Initial release 3/9/2018
|
|Usage: /mac GroundGrab item name I want ~~ /mac GroundGrab corn rose
|        Also accepts partial name. /mac GroundGrab corn
|     
|
|Purpose: Will navigate a zone and pick up any ground spawn you've
|            specified. Will react to aggro (XTargets) to stop navigation
|            and kill the add before resuming to it's destination.
|
    |||||||||||||||||||||||||||||||||||||||||||||||||||
Sub Main
    /if (!${Bool[${Param0}]}) {
        /echo \ayYou must provide an item to find. Usage: /mac GroundGrab item_name_to_find
        /echo \arEnding Macro.
        /end
    } else {
        /declare itemName string outer ${Param0}
    }
    /call CheckMesh
    /call Declares
    /declare i int local 1
    /while (${Bool[${Param${i}}]}) {
        /varset itemName ${itemName} ${Param${i}}
        /varcalc i ${i}+1
    }
    :getitems
    /echo \awLooking for \ay${itemName}
  
    /while (${Ground[${itemName}].ID}) {
        /call WaitNavGround "${itemName}"
    }
    /echo \awAll \ay${itemName} \awwere collected. Waiting until more spawn.
    /while (!${Ground[${itemName}].ID}) {
        /if (${Me.XTarget[1].ID}) {
            /if (${Navigation.Active}) /nav stop
            /call FarmStuff
        } else {
            /call GroupDeathChk
            /call GroupHealthChk
            /call GroupEndChk
            /call GroupManaChk
            /if (${useMerc}) /call CheckMerc
        }
        /if (${Me.Combat} && !${Me.XTarget[1].ID}) /squelch /target clear
        /delay 1s
    }
    /goto :getitems
/return

Sub WaitNavGround(GroundItemName)
    /declare i int local 1
    /if (${Debugging}) /echo \atGroundItemName: \ay${GroundItemName} \atDistance: \ay${Ground[${GroundItemName}].Distance3D}
    /while (${Ground[${GroundItemName}].Distance3D} > 15) {
        /if (${Navigation.Active}) {
            /if (${Me.XTarget[1].ID}) {
                /if (${Navigation.Active}) /nav stop
                /call FarmStuff
            } else {
                /call GroupDeathChk
                /call GroupHealthChk
                /call GroupEndChk
                /call GroupManaChk
                /if (${useMerc}) /call CheckMerc
            }
            /if (${Me.Combat} && !${Me.XTarget[1].ID}) /squelch /target clear
            /delay 10
        } else {
            /if (${Me.XTarget[1].ID}) {
                /if (${Navigation.Active}) /nav stop
                /if (${UseEQBC}) {
                    /bc ${Macro.CurLine} target xtarget ${Spawn[id ${Me.XTarget[1].ID}].Name}
                    /bcaa //target id ${Me.XTarget[1].ID}
                } else {
                    /target id ${Me.XTarget[1].ID}
                }
                /call FarmStuff
            } else {
                /call GroupDeathChk
                /call GroupHealthChk
                /call GroupEndChk
                /call GroupManaChk
                /if (${useMerc}) /call CheckMerc
            }
            /if (${Me.Combat} && !${Me.XTarget[1].ID}) /squelch /target clear

            /if (${Navigation.PathExists[loc ${Ground[${GroundItemName}].Y} ${Ground[${GroundItemName}].X} ${Ground[${GroundItemName}].Z}]}) {
                /nav loc ${Ground[${GroundItemName}].Y} ${Ground[${GroundItemName}].X} ${Ground[${GroundItemName}].Z}
            } else {
                /echo Unable to navigate to ${Ground[${GroundItemName}].DisplayName} at loc ${Ground[${GroundItemName}].Y} ${Ground[${GroundItemName}].X}. Searching for another groundspawn.

                /varset i 1
                /while (${Ground[${i}].ID}) {
                    /if (${Ground[${i}].DisplayName.Find[${GroundItemName}]}) {
                        /if (${Navigation.PathExists[loc ${Ground[${i}].Y} ${Ground[${i}].X} ${Ground[${i}].Z}]}) {
                            /nav loc ${Ground[${i}].Y} ${Ground[${i}].X} ${Ground[${i}].Z}
                            /break
                                            } else {
                            /echo Unable to navigate to ${Ground[${i}].DisplayName} at loc ${Ground[${i}].Y} ${Ground[${i}].X}. Searching for another groundspawn.
                        }
                    }
                    /varset i ${Math.Calc[${i}+1]}
                    /if (!${Ground[${i}].ID}) {
                        /echo No navigable groundspawns are available, waiting 30 seconds.
                        /delay 30s
                    }
                }
            }
        }
    }
    /if (${Navigation.Active}) /nav stop
    /invoke ${Ground[${GroundItemName}].DoTarget.ID}

    /invoke ${Ground[${GroundItemName}].Grab}
    /delay 2s ${Cursor.ID}
    /delay 5
    /autoinv
/return

Sub CheckMesh
    /if (!${Navigation.MeshLoaded}) {
        /nav reload
        /delay 1s ${Navigation.MeshLoaded}
        /if (!${Navigation.MeshLoaded}) {
            /echo "Ending Macro."
            /end
        }
    }
/return

Sub FarmStuff(string Enemy)
    /if (${Bool[${Enemy}]}) {
        /varset FarmMob ${Enemy}
        /if (${Debugging} && !${reportTarget}) {
            /echo Looking for: ${FarmMob}
            /varset reportTarget ${reportTarget.OriginalValue}
        }
    } else /if (!${reportTarget}) {
        /echo \arWe appear to have aggro.
        /varset reportTarget ${reportTarget.OriginalValue}
    }
    :findMob
    /if (${Target.Type.Equal[corpse]}) /squelch /target clear
    /if (${Window[RespawnWnd].Open}) /call GroupDeathChk
    /if (!${Me.XTarget[1].ID} || ${Window[RespawnWnd].Open}) {
        /call GroupDeathChk
        /call GroupHealthChk
        /call GroupEndChk
        /call GroupManaChk
    }
    /if (!${Spawn[id ${myTargetID}].ID} || ${Spawn[id ${myTargetID}].Type.Equal[Corpse]} && !${Me.XTarget[1].ID}) {
        /if (${Debugging}) /echo "Getting a target!"
        /varset myTargetID 0
        /call TargetShortest
        /if (${Debugging} && ${myTargetID}) /echo Target is ${Spawn[id ${myTargetID}]}
    }
    :navto
    /if (${Spawn[${myTargetID}].Distance} > 30 && !${Me.XTarget[1].ID}) {
        /call WaitNav ${myTargetID}
        /delay 10
        /goto :navto
    } else /if (!${Target.ID} && ${Target.ID} != ${myTargetID} && ${Target.ID} != ${Me.ID} && ${myTargetID} != 0 && !${Me.XTarget[1].ID}) {
        /if (${Debugging}) /echo I'm targeting ${Spawn[${myTargetID}].CleanName} ID: ${myTargetID}
        /if (${UseEQBC}) {
            /bc ${Macro.CurLine} target mytarget ${Spawn[id ${myTargetID].Name}
            /bcaa //target id ${myTargetID}
        } else {
            /target id ${myTargetID}
        }
        /delay 10
    }
    /delay 5
    /if (${Target.ID} && ${Target.Type.Equal[npc]}) {
        /if (${Navigation.Active}) /squelch /nav stop
        /stick uw loose moveback 8
        /setchattitle Killing ${Target.CleanName}
        /if (${UseEQBC}) {
            /bc ${Macro.CurLine} killthis
            /bca //killthis
        }
        /killthis
        :waitTillDead
  
        /if (${Target.ID} && ${Me.CombatState.Equal[Combat]} && ${Target.Type.Equal[npc]}) {
            /if (!${Me.Combat}) /attack
            /delay 10
            /goto :waitTillDead
        } else /if (${Target.Type.Equal[corpse]}) {
            /target clear
            /varset myTargetID 0
        }
    } else /if (${Me.XTarget[1].ID}) {
        /if (${Spawn[id ${Me.XTarget[1].ID} radius 30 zradius 50].ID} && ${Spawn[id ${Me.XTarget[1].ID} radius 30 zradius 50].LineOfSight}) {
            /if (${Navigation.Active}) /nav stop
            /if (${UseEQBC}) {
                /bc ${Macro.CurLine} target XTarget ${Spawn[id ${Me.XTarget[1].ID}].Name}
                /bcaa //target id ${Me.XTarget[1].ID}
            } else {
                /target id ${Me.XTarget[1].ID}
            }
            /setchattitle Handling add, ${Spawn[${Me.XTarget[1].ID}].CleanName}
        } else /if (${Spawn[id ${Me.XTarget[1].ID}].Distance} > 30 || !${Spawn[id ${Me.XTarget[1].ID} radius 30 zradius 50].LineOfSight}) {
            /nav id ${Me.XTarget[1].ID}
            /setchattitle Navigating to add ${Spawn[id ${Me.XTarget[1].ID}].CleanName}
            /while (${Spawn[${Me.XTarget[1].ID}].Distance} > 30) {
                /if (!${Navigation.Active}) /nav id ${Me.XTarget[1].ID}
                /delay 10
            }
        }
        /if (${UseEQBC}) {
            /bc ${Macro.CurLine} killthis
            /bca //killthis
        }
        /killthis
        /setchattitle Killing ${Target.CleanName}
        /goto :waitTillDead
    }
    /if (${UseEQBC} && !${Me.CombatState.Equal[Combat]}) {
        /bc ${Macro.CurLine} target me and stick.
        /bca //target id ${Me.ID}
        /delay 5
        /bca //stick 10 loose moveback uw
    }
/return

| --------------------------------------------------------------------------------------------
| SUB: GroupManaChk
| --------------------------------------------------------------------------------------------
Sub GroupManaChk
    /if (${Me.XTarget[1].ID}) /return
  
    /if (!${Me.Combat}) {
        /setchattitle "Group Mana Check"
        /if (${Me.PctMana} < ${MedAt} && ${Me.Class.CanCast} && !${Me.State.Equal[DEAD]}) {
            /echo \arYOU are low on mana!
            /setchattitle "Waiting on YOUR mana to reach ${MedTill}%"
            /if (!${Me.XTarget[1].ID}) {
                /while (${Me.PctMana} < ${MedTill} && !${Me.XTarget[1].ID} && !${Me.State.Equal[DEAD]}) {
                    /if (${Me.Standing} && !${Me.Casting.ID} && !${Me.Mount.ID}) /sit
                    /if (${UseEQBC}) {
                        /if (!${Defined[j]}) /declare j int local
                        /for j 1 to ${Group}
                            /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                        /next j
                    }
                    /delay 10
                }
            }
        }
        /if (${Group}) {
            /declare i int local
            /for i 1 to ${Group}
                /if ((${Group.Member[${i}].PctMana} < ${MedAt}) && ${Group.Member[${i}].Class.CanCast} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                    /echo \ar${Group.Member[${i}].Name} is low on mana!
                    /setchattitle "Waiting on ${Group.Member[${i}].Name}'s mana to reach ${MedTill}%"
                    /if (!${Me.XTarget[1].ID}) {
                        /while (${Group.Member[${i}].PctMana} < ${MedTill} && !${Me.XTarget[1].ID} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                            /if (${Me.Standing} && !${Me.Casting.ID} && !${Me.Mount.ID}) /sit
                            /if (${UseEQBC}) {
                                    /if (!${Defined[j]}) /declare j int local
                                    /for j 1 to ${Group}
                                        /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                                    /next j
                            }
                            /delay 10
                        }
                        /if (${UseEQBC}) {
                                /bc ${Macro.CurLine} stand up target me and stick
                                /bcaa //keypress w
                                /bca //target id ${Me.ID}
                                /delay 5
                                /bca //stick 10 loose moveback uw
                        }
                    }
                }
            /next i
        }
    }
/return

| --------------------------------------------------------------------------------------------
| SUB: GroupHealthChk
| --------------------------------------------------------------------------------------------
Sub GroupHealthChk
    /if (${Me.XTarget[1].ID}) /return
  
    /setchattitle "GroupHealthCheck"
    /if (!${Me.Combat}) {
        /if (${Me.PctHPs} < ${HealAt} && !${Me.State.Equal[DEAD]}) {
            /echo \arYOU are low on Health!
            /setchattitle "Waiting on YOUR health to reach ${HealTill}%"
            /if (!${Me.XTarget[1].ID}) {
                /while (${Me.PctHPs} < ${HealTill} && !${Me.XTarget[1].ID} && !${Me.State.Equal[DEAD]}) {
                    /if ((${Me.Standing}) && (!${Me.Casting.ID}) && (!${Me.Mount.ID})) /sit
                    /if (${UseEQBC}) {
                        /if (!${Defined[j]}) /declare j int local
                        /for j 1 to ${Group}
                            /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                        /next j
                    }
                    /delay 10
                }
            }
        }
        /if (${Group}) {
            /declare i int local
            /for i 1 to ${Group}
                /if (${Group.Member[${i}].ID}) {
                    /if (${Group.Member[${i}].PctHPs} < ${HealAt} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                        /echo ${Group.Member[${i}].Name} is low on Health!
                        /setchattitle "Waiting on ${Group.Member[${i}].Name} health to reach ${HealTill}%"
                        /if (!${Me.XTarget[1].ID}) {
                            /while (${Group.Member[${i}].PctHPs} < ${HealTill} && !${Me.XTarget[1].ID} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                                /if ((${Me.Standing}) && (!${Me.Casting.ID}) && (!${Me.Mount.ID})) /sit
                                /if (${UseEQBC}) {
                                    /if (!${Defined[j]}) /declare j int local
                                    /for j 0 to ${Group}
                                        /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                                    /next j
                                }
                                /delay 10
                            }
                            /if (${UseEQBC}) {
                                /bc ${Macro.CurLine} stand up target me and stick
                                /bcaa //keypress w
                                /bca //target id ${Me.ID}
                                /delay 5
                                /bca //stick 10 loose moveback uw
                            }
                        }
                    }
                }
            /next i
        }
    }
/return

| --------------------------------------------------------------------------------------------
| SUB: GroupEndChk
| --------------------------------------------------------------------------------------------
Sub GroupEndChk
    /if (${Me.XTarget[1].ID}) /return
  
    /setchattitle "GroupEnduranceCheck"
    /if (!${Me.Combat}) {
        /if (${Me.PctEndurance} < ${MedEndAt} && !${Me.State.Equal[DEAD]}) {
            /echo \arYOU are low on Endurance!
            /setchattitle "Waiting on YOUR Endurance to reach ${HealTill}%"
            /if (!${Me.XTarget[1].ID}) {
                /while (${Me.PctEndurance} < ${MedEndTill} && !${Me.XTarget[1].ID} && !${Me.State.Equal[DEAD]}) {
                    /if (${Me.Standing} && !${Me.Casting.ID} && !${Me.Mount.ID}) /sit
                    /if (${UseEQBC}) {
                        /if (!${Defined[j]}) /declare j int local
                        /for j 1 to ${Group}
                            /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                        /next j
                    }
                    /delay 10
                }
            }
        }
        /if (${Group}) {
            /declare i int local
            /for i 1 to ${Group}
                /if (${Group.Member[${i}].ID}) {
                    /if (${Group.Member[${i}].PctEndurance} < ${MedEndAt} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                        /echo \ar${Group.Member[${i}].Name} is low on Endurance!
                        /setchattitle "Waiting on ${Group.Member[${i}].Name} Endurance to reach ${HealTill}%"
                        /if (!${Me.XTarget[1].ID}) {
                            /while (${Group.Member[${i}].PctEndurance} < ${MedEndTill} && !${Me.XTarget[1].ID} && !${Group.Member[${i}].State.Equal[DEAD]}) {
                                /if ((${Me.Standing}) && (!${Me.Casting.ID}) && (!${Me.Mount.ID})) /sit
                                /if (${UseEQBC}) {
                                    /if (!${Defined[j]}) /declare j int local
                                    /for j 0 to ${Group}
                                        /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${j}].Name} //sit
                                    /next j
                                }
                                /delay 10
                            }
                            /if (${UseEQBC}) {
                                /bcaa //keypress w
                                /bc ${Macro.CurLine} stand up target me and stick
                                /bca //target id ${Me.ID}
                                /delay 5
                                /bca //stick 10 loose moveback uw
                            }
                        }
                    }
                }
            /next i
        }
    }
/return

| --------------------------------------------------------------------------------------------
| SUB: GroupDeathChk
| --------------------------------------------------------------------------------------------
Sub GroupDeathChk
  
    /if (${Me.State.Equal[DEAD]}) {
        /echo \arYOU~ have died! Waiting for YOU to get off your face.
        /setchattitle "You died, waiting for rez!"
        /while (${Me.STATE.Equal[DEAD]} ) {
            /delay 10
          
        }
    }
    /if (${Me.XTarget[1].ID}) /return
    /if (${Group}) {
        /declare i int local
        /for i 1 to ${Group}
            /if (${Group.Member[${i}].State.Equal[DEAD]} ) {
                /echo ${Group.Member[${i}].Name} has died. Waiting for them to get off their face.
                /setchattitle "${Group.Member[${i}].Name} has died. Waiting for Rez"
                /if (!${Me.XTarget[1].ID}) {
                    /while (${Group.Member[${i}].State.Equal[DEAD]} && !${Me.XTarget[1].ID}) {
                        /if ((${Me.Standing}) && (!${Me.Casting.ID}) && (!${Me.Mount.ID})) /sit
                        /if (${UseEQBC}) {
                            /if (!${Defined[j]}) /declare j int local
                            /for j 0 to ${Group}
                                /if (${j} != ${i}) {
                                    /if (${Group.Member[${j}].State.Equal[Stand]} && !${Group.Member[${j}].Type.Equal[Mercenary]}) /bct ${Group.Member[${i}].Name} //sit
                                }
                            /next j
                        }
                        /delay 10
                    }
                }
            }
        /next i
    }
/return

Sub TargetShortest
    /declare PullTargetID int local 0
    /declare Shortest int local 0
  
    /if (!${Me.XTarget[1].ID}) {
        |In order if I should even loop through to see how many mobs are in range I need to get a count based on my conditions
        /declare MobsInRange int local ${SpawnCount[npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"]}
        /if (${Debugging}) /echo There were ${MobsInRange} ${FarmMob} in radius of ${PullRange} and ZRad: ${ZRadius}.
        /declare i int local 0
        /declare j int local 1
        /if (${MobsInRange}) {
        |** PullList[#,1] = ID of mob, PullList[#,2] = PathLength **|
        |I created an array and made it the size of the mobcount by the 2 to store each mob's ID and the length of their nav path
            /declare PullList[${MobsInRange},2] int local 0
            |I set i equal to 1 and I iterate through each mob
            /for i 1 to ${MobsInRange}
                |just in case something dies, I don't to result in NULL during my check producing results
                /if (${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].Name.NotEqual[NULL]}) {
                    |/echo \atFound one. Maybe, lets see if it has a path.
                    |If there is a path and only if there is a path will I enter the following block statement. This is done to avoid adding mobs to the array that don't have a path.
                    /if (${Navigation.PathExists[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]} && ${Int[${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].Distance3D}]} <= ${Int[${Navigation.PathLength[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]}]}) {
                        |Now that I know this mob has a Navigation path, I need to add it to the array where ${j} is incremented only if I add a mob's ID and Path Length
                        |/echo Adding a mob to the pullList
                        /varset PullList[${j},1] ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}
                        /varset PullList[${j},2] ${Int[${Navigation.PathLength[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]}]}
                        |If this is the first mob I've added to the array, it is now my target and it has the shortest path.
                        /if (${j}==1) {
                            /varset PullTargetID ${PullList[${j},1]}
                            /varset Shortest ${PullList[${j},2]}
                        } else /if (${PullList[${j},2]} < ${Shortest}) {
                            |Otherwise if the mob I added has a PathLength shorter that the current shortest Nav Path, make it my target and set it as the shortest.
                            /varset PullTargetID ${PullList[${j},1]}
                            /varset Shortest ${PullList[${j},2]}
                        }
                        |Since I added a mob I need to increment j by 1 in the PullList Array.
                        /varcalc j ${j}+1
                    } else {
                        /if (${Debugging}) {
                            /echo \at${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].Name} was not a valid pull target.
                            /echo \ar${Navigation.PathExists[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]} && ${Int[${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].Distance3D}]} <= ${Int[${Navigation.PathLength[id ${NearestSpawn[${i},npc noalert 1 targetable radius ${PullRange} zradius ${ZRadius} "${FarmMob}"].ID}]}]})
                        }
                    }
                }
            |Check the next mob in the NearestSpawn meeting my conditions loop
            /next i
            |Now that I've exited the loop, the PullTargetID variable is the one I want to navigate to and kill.
            /varset myTargetID ${PullTargetID}
            |Set the chattitle of the MQ2 window to the macro's status (Suggestion by Kaen01)
            /setchattitle Going to kill ${Spawn[id ${myTargetID}].CleanName}!
        }
    } else {
        /varset myTargetID ${Me.XTarget[1].ID}
    }
/return

Sub CheckMerc
    /if (${Mercenary.State.Equal[DEAD]}) {
        /echo Your mercenary has died. Waiting to be able to revive them.
        :waitForMerc
        /if (${Group} && ${Window[MMGW_ManageWnd].Child[MMGW_SuspendButton].Tooltip.Equal[Revive your current mercenary.]} && ${Window[MMGW_ManageWnd].Child[MMGW_SuspendButton].Enabled}) /notify MMGW_ManageWnd MMGW_SuspendButton leftmouseup
        /if (${Mercenary.State.Equal[DEAD]} && !${Me.XTarget[1].ID}) /goto :waitForMerc
    }
/return

Sub Declares(int Param0, string Param1)
    /declare FarmMob string outer ${Param1}
    /declare PullRange int outer ${Param0}
    /declare ZRadius int outer 50
    /declare Debugging bool outer FALSE
    /declare HealAt int outer 70
    /declare HealTill int outer 100
    /declare MedEndAt int outer 3
    /declare MedEndTill int outer 20
    /declare MedAt int outer 30
    /declare MedTill int outer 100
    /declare UseEQBC bool outer FALSE
    /declare Targets string outer
    /declare myTargetID int outer 0
    /declare reportTarget timer outer 5s
    /declare useMerc bool outer FALSE
        /declare WaypointCount int outer ${Math.Calc[(${Ini[..\MQ2Nav.ini,${Zone.ShortName}].Length}-${Ini[..\MQ2Nav.ini,${Zone.ShortName}].Replace[GroundGrab,].Length})/10]}
    /declare wpCounter int outer 0
/return
EXCELLENT, After trying to fix the maps and with this update works perfect. Thanks.
 
Ran this code in The Great Divide without problems using a custom map.
Great job !
 
@ChatWithThisName Would you like to update or can we put @jfreelov as maintainer?
 
What about skipping one that you get a lore message? The only issue in elddar forest or something is the branches have the same name between the lore ones and then on-lore ones.
 
overall this is working great. only request, can we make a command or option to turn off agro / melee. I run a monk and would like to be able to auto run to collects and FD with big trains in see invis zones.
 
Release [Macro] GroundGrab.mac
Status
Not open for further replies.

Users who are viewing this thread

Back
Top
Cart