Natural Beastlord Hunter v1.1.9 (Updated 2004-07-11)

Post your completed (working) macros here. Only for macros using MQ2Data syntax!

Moderator: MacroQuest Developers

Terramantian
a ghoul
a ghoul
Posts: 120
Joined: Thu May 13, 2004 6:20 pm

Post by Terramantian » Fri Oct 01, 2004 3:36 pm

Only time I've had this happen is if there are less spells in the array than number the array was declared at. If you changed the number of spells to cast make sure to change the declaration.

Lamdadar
decaying skeleton
decaying skeleton
Posts: 6
Joined: Thu Sep 30, 2004 2:37 am

Post by Lamdadar » Thu Oct 07, 2004 1:39 am

I checked the spell array and i have the same number of spells as declared, but its still just buffs pet then stands there...

Starting Macro
Moving to pet before we start pulling
NewTarget loop (Tick:0)

Im at a loss, someone please help

User avatar
Zornecro
a ghoul
a ghoul
Posts: 82
Joined: Sun Sep 19, 2004 10:19 pm
Location: El Paso, TX

Post by Zornecro » Thu Oct 07, 2004 4:17 am

Edit the lines that say:

Code: Select all

#define DEBUG_2 "/squelch /echo"
#define DEBUG_3 "/squelch /echo"
So that they both just are set to "/echo". That gives you a lot more info. Chances are it is trying to self buff you with a spell improperly named (used forward quote instead of backward quote or misspelled), or that it is stuck waiting on something that isn't happening.
- Zornecro Mancer, Retired EQ1 Veeshan
- Unktehila, Redtigre, Twinaxe, EQ2 Crushbone

Lamdadar
decaying skeleton
decaying skeleton
Posts: 6
Joined: Thu Sep 30, 2004 2:37 am

Post by Lamdadar » Thu Oct 07, 2004 10:53 pm

Ok, so ive changed the Debug to the settings youve recommended, now it says:

Do Target
Want to target from AT2
Doing GetNewTarger method 2
IgnoreListCheck: NULL==2172 ?


Ive looked threw the mac to see if there are any names or anything that could be causing me to ignore the mobs i want to target but cant seem to find anything...

Lamdadar
decaying skeleton
decaying skeleton
Posts: 6
Joined: Thu Sep 30, 2004 2:37 am

Post by Lamdadar » Thu Oct 07, 2004 10:56 pm

correction

IgnoreListCheck: NULL==2127 ?

User avatar
Zornecro
a ghoul
a ghoul
Posts: 82
Joined: Sun Sep 19, 2004 10:19 pm
Location: El Paso, TX

Post by Zornecro » Fri Oct 08, 2004 3:32 am

Lamdadar wrote:correction

IgnoreListCheck: NULL==2127 ?
See if the "IsInArray" sub has the following statement, I may have bug fixed it on my side:

Code: Select all

		/if (${${varname}[${i}]} && ${${varname}[${i}]}==${var} ) /return 0
The other bug fix I found is in Sub ClearIgnoreList. There's a statement with /squelch in it. Bad and wrong, can just bring the macro to a halt without saying why.

Code: Select all

		/if (${Defined[IgnoreList]}) /deletevar IgnoreList
- Zornecro Mancer, Retired EQ1 Veeshan
- Unktehila, Redtigre, Twinaxe, EQ2 Crushbone

Lamdadar
decaying skeleton
decaying skeleton
Posts: 6
Joined: Thu Sep 30, 2004 2:37 am

Post by Lamdadar » Sat Oct 09, 2004 11:03 pm

Adjusted the macro again though i really dont know if i did it right so im going to include the entire mac and the msg i get. All your help has been much apreciated. Wish i knew more about this stuff...


|TODO:
|Stuckness on strafe. Stop strafing till next target
|Degree to pull. 360degrees = everyting
|Pull to homepoint - sometimes cast twice to upull the mob!
| Waiting for mobs doesnt allways work on slow mobs


| Natural Beastlord Hunter Macro c
| nbh.mac
| Author : wolf5
| Version : v1.1.9 - 2004-07-11
| Useage : /macro nbh Legionnaire
| /macro nbh target1|target2|target3|...|targetn
| Description : This macro will run your character around killing any mobs
| matching your targets.
| Then it will loot either all items or none.
| Features:
|
|- Pet allways up, and no further than a defined distance away before being
| autosummoned
|
|- Keep pet buffed (noncombat)
|
|- Keep myself buffed (noncombat)
|
|- During combat, keep myself buffed with critical spells (SoW)låæcghbnhi
|
|- Target from targetlist within a given radius (default 499) - rumor has it
| targetting above 500 gets logged by SoE ? But search for mobs outside
| this range if chosen.
|
|- Run towards target using a selfwritten /face to allow a "slack" of a given
| degree. Ie 45 degree means I wont turn 100% directly towards target
| but within 45 degrees making it look a little more natural.
|
|- Initiate attack at a given range: send in pet, slow, nuke, run to attack
|
|- Let pet tank if:
| Healthdifference in Pct between pet and myself differs more than a
| given percentage.
| If no mobs nearby.
| Only if pet is close.
|- When pet tanks:
| Nuke if mana above a given pct.
| Keep pet updated with buffs and heals.
| Keep self updated. ælæ
| When health of pet reaches same Pct as self, attack again.
|
|- Option to strafe around target to let pet attack the targets back.
|
|- Run to mob-corpse and loot if the mob was above a given level
| (to prevent looting low lvl greens)
|
|- Keep track of the items looted during the runtime of the macro.
|
|- Allways using pet as a reference on me being attacked. If pet has something
| targeted, help it.
|
|- Aquiring a new target:
| After about 6 attempts with a delay between and there is still no target,
| run back to homespot (where the script started) and sit down.
| Restless option. If nothing happens at homepoint, sooner or later we
| run to a random point nearby looking for mobs.
|
|-If my health should drops below a certain %, heal till I'm above
| (after fights or when pet tanks)
|
|-Alarm sound (/beep) if health gets below a certain level so prompt you to get
| back to the computer.
|
|-If pet health drops below a certain %, heal pet
| (after fights or when pet tanks)
|
|-If mana drops below a certain %, sit down and med till it's above.
|
|-Choice of sending in pet before or after slow.
|
|-Only nuke if we got excess mana (mana over a given %)
|
|-Obstacle avoidance. If we are stuck while running to a target, back off
| random length and turn left or right randomly. Setting the default
| "slack" degree of the /face sub to a high degree to prevent running
| into the same obstacle again, in effect letting u run in
| an arc around the obstacle.
|
|-Attack no matter what if mob is below a certain % - dont back off.
|
|-Max Range from homepoint to prevent running amokk on the map.
|
|-Option to pull to homespot all the time.
|-Option to allways run to homespot after a fight.
|
|-2 methods to select mobs. Either by distance or by mobname first.
|
|-Dont pull mobs that are closer to a NPC or PC than a defined radius
|
|--------------------------------------------------------------------------------

#include spellcast.inc
#turbo 40

|Events for counting the money we loot.
|#event Receive "#*#You receive#*#"
#event CashLoot "You receive #1#"
|#event CashLoot2 "#*#You receive #*#"

|-- The normal debug - for normal play. Enable: "/echo", Disable: "/squelch /echo"
#define DEBUG_1 "/echo"
|-- Deeper debugging - enable when trying to find bugs. Enable: "/echo", Disable: "/squelch

/echo"
#define DEBUG_2 "/echo"
|-- The Deepest debugging - will spam a lot. Enable: "/echo", Disable: "/squelch /echo"
#define DEBUG_3 "/echo"

|-- Destroys Silver if you have more than the given amount! 0=disable
#define DESTROY_GOLD_IF_ABOVE 0
|-- Destroys Silver if you have more than the given amount! 0=disable
#define DESTROY_SILVER_IF_ABOVE 500
|-- Destroys Copper if you have more than the given amount! 0=disable
#define DESTROY_COPPER_IF_ABOVE 500


|-- The degree we face towards the target, so we dont run dead on.
#define THE_SLACK_DEGREE 20
|-- The max search radius for a mob (will not use /target untill closer than SEARCH_RADIUS).
#define MAXIMUM_SEARCH_RADIUS 3000
|-- The max TARGET radius for a mob (above 500 could be bad, SoE logging?).
#define TARGET_RADIUS 499
|-- Define the Z radius on our pulls. To prevent pulling to far up or below (floors?)
#define Z_RADIUS_ON_PULLS 250
|-- How far is the max range we want to go from homespot?
#define MAX_RANGE_FROM_HOMEPOINT 3000

|-- Target method. 1-Prioritize mob sequence or 2-Prioritize distance
#define TARGET_METHOD 2

|-- The closest a another PC can be to a target
#define AVOID_PEOPLE_RADIUS 300

|-- The closest a another NPC can be to a target - Only attack single mobs?
#define AVOID_CROWDED_RADIUS 1

|-- Also loot items?
#define LOOT_ITEMS True
|-- Loot all items?
#define LOOT_ALL_ITEMS False
|-- Destroy the remaining items -not in use atm
#define LOOT_ABOVE_LEVEL 1
|-- Keep loot record - Will display how much you have looted + items
#define LOOT_KEEP_RECORD True

|-- No matter other settings. If the value of the item is above this, GET IT! (Value is in

copper)
|-- Not nodrop
#define LOOT_NORMAL_ITEMS_IF_VALUE_IS_ABOVE 10000
|-- No matter other settings. If the value of the item is above this and stackable, GET IT!

(Value is in copper)
|-- Not lore, not nodrop
#define LOOT_STACKABLE_ITEMS_IF_VALUE_IS_ABOVE 1000

|#define LOOT_DESTROY False
|-- What lvl should the mob be before we bother looting it


|-- At what range do we slow/send in pet?
#define INITIALIZE_ATTACK_RANGE 150
|-- If we dont get any target for a while at homepoint, run somewhere else
#define ARE_WE_RESTLESS True
|-- How far do we want to run?
#define RESTLESS_RANGE 500
|-- We dont want to stay back when the mob is fleeing, now do we :-)
#define FORCE_ATTACK_WHEN_MOB_BELOW 30
|-- Do we want to stay on opposite side than the pet on the mob
#define STRAFE_TO_BACK True
|-- If the PCT of your pet and yourself differs from this number, let pet tank
#define LET_PET_TANK_IF_DIFFERENCE 8
|-- If there are more than 1 mob within this radius, just tank on
#define IGNORE_PETTANK_IF_MOBS_RADIUS 100

|-- Allways return to homepoint | can be li'l buggy?
#define RETURN_TO_HOMEPOINT True

|-- Should we allways pull to the same spot?
#define PULL_TO_HOMEPOINT True
|-- What spell should we use to pull ?
#define PULL_TO_HOME_SPELL_NAME "Sha's Advantage"
|-- What spellgem slot should we use?
#define PULL_TO_HOME_SPELL_GEM 2
|-- Should I tell pet to back off while running back. False for those who have /pet hold
#define PULL_TO_HOME_PETBACKOFF True

|-- If we dont have a pet, should we allways summon one?
#define ALLWAYS_HAVE_PET True
|-- What pet do we want?
#define PET_SPELL "Spirit of Khurenz"
|-- Favorite gem spot for the pet (1-8)
#define PET_GEM 1
|-- How far off should the pet be before we summon it?
#define MAX_PET_RANGE_BEFORE_SUMMON 500


|-- Should we slow when pulling?
#define DO_SLOW_ON_PULL True
|-- Should we send in pet before or after we slow?
#define SEND_PET_BEFORE_SLOW False
|-- Only slow mobs above a certain level
#define SLOW_ABOVE_LEVEL 25
|-- What slow spell
#define SLOW_SPELL "Sha's Advantage"
|-- Favorite gem spot for the slow (1-8)
#define SLOW_GEM 6

|-- Should we nuke when we pull?
#define DO_NUKE_ON_PULL False
|-- Prevent nuking when mana below % to not waste mana
#define NUKE_ABOVE_MANA_PCT 50
|-- Prevent nuking low lvls, they arent worth it
#define NUKE_ABOVE_LEVEL 30
|-- Name of nuke spell
#define NUKE_SPELL "Blizzard Blast"
|-- Favorite gem spot for the nuke (1-8)
#define NUKE_GEM 8

|-- How low on health should I be before I heal myself (noncombat)
#define HEAL_BELOW_PCT 50
|-- Name of healing spell
#define HEAL_SPELL "Greater Healing"
|-- Favorite gem spot for the heal (1-8)
#define HEAL_GEM 5
|-- If your health gets below this lvl start /beep'ing
#define ALARM_HEALTH_BELOW_PCT 40

|-- How low on health should the pet be before we heal it (noncombat)
#define HEAL_PET_BELOW_PCT 50
|-- Name of pet healing spell
#define HEAL_PET_SPELL "Sha's Restoration"
|-- Favorite gem spot for the petheal (1-8)
#define HEAL_PET_GEM 7

|-- What is the minimum mana I should have, sit down and med if below
#define MIN_MANA_BEFORE_MEDITATE 50



|----------------------------------------------------------------------------
|SUB: Main - Declarations and Initialization
|----------------------------------------------------------------------------
Sub Main
|Log to output file "/spew on" or turn it off "/spew off" (MacroQuest\logs\DebugSpew.log)
/spew on

|Buffs to be kept up on self (max 15) - "Buff" or "Buff|GemSlot"
/declare MyBuffs[2] string outer
/varset MyBuffs[1] "Spiritual Purity|3"
/varset MyBuffs[2] "Alacrity|4"

|Critical buffs to be kept up on self (max 15) - cast during fight
/declare CritBuffs[1] string outer
/varset CritBuffs[1] "Spiritual Purity|3"


|Buffs to be kept up on petf (max 15) - "Buff" or "Buff|GemSlot"
/declare PetBuffs[2] string outer
/varset PetBuffs[1] "Spirit of the Storm|2"
/varset PetBuffs[2] "Sha's Ferocity|1"


|Loot items we want to loot
/declare LootList[6] string outer
/varset LootList[1] "Fine Steel Short"
/varset LootList[2] "Fine Steel Long"
/varset LootList[3] "Fine Steel Rapier"
/varset LootList[4] "Fine Steel Scimitar"
/varset LootList[5] "silk"
/varset LootList[6] "venom"

DEBUG_1 Starting macro

|Group of locked target data
/declare TargetLevel int outer |Level of Target
/declare TargetName string outer |Name of Target
/declare TargetID int outer |ID of Target

|Data to detect if we are stuck
/declare oldposx float outer
/declare oldposy float outer
/varcalc oldposx ${Me.X} +100
/varcalc oldposy ${Me.Y} +100

|A counter for the Move subs
/declare keypressercnt1 int outer 0
/declare keypressercnt2 int outer 0
/declare keypressercnt3 int outer 0
/declare keypressercnt4 int outer 0
/declare keypressercnt5 int outer 0
/declare keypressercnt6 int outer 0

|Variable to prevent stuckfix after casting a spell
/declare JustCastedSpell bool outer


|/declare tmp string outer |Just a tmp string
|/declare tmp2 string outer |Just a tmp string
/declare lootcnt int outer 0 |Loot counter

/declare homeX float outer ${Me.X} |Our homepoint
/declare homeY float outer ${Me.Y} |Our homepoint
/declare homeZ float outer ${Me.Z} |Our homepoint
/declare rndX float outer ${Me.X} |Rnd
/declare rndY float outer ${Me.Y} |Rnd

DEBUG_2 Homepoint: ${Me.X} ${Me.Y}

/declare leftdown bool outer |Are we turning left
/declare rightdown bool outer |Are we turning right
/declare strafeleftdown bool outer |Are we turning left
/declare straferightdown bool outer |Are we turning right
/declare forwarddown bool outer |Are we moving forward
/declare backdown bool outer |Are we moving backwards

/declare stickontarget bool outer |Bool to prevent us from leaving
/declare stickontarget_2 bool outer |Bool to prevent us from leaving (pull_to_home)

/declare initiatedattack bool outer |Bool to only initiate once

/declare theslack int outer THE_SLACK_DEGREE |the global slack on FaceTarget

/declare waitcounter int outer 0 |How many times shall we get no target found before we

do something (run/wait/gohome)

/declare tickcnt int outer 0 |Tickcounter. 1 delay = 1 tick
/declare aqtargcnt int outer 0 |Aquiretarget ticker
/declare ignoreclearcnt int outer 0 |IgnoreList clearing counter


|Getting targets - Made it for the String.Arg not working - works now tho, but I keep the

code
/declare numbtargs int outer
/if (!${Defined[Param0]}) {
DEBUG_1 No targets chosen! Exiting.
/endmacro
}

|Make "targets" array (global) with list over the mobs we want
/call SplitString targets "${Param0}" "|"
/declare i int local
/for i 1 to ${targets.Size}
DEBUG_2 Target defined (${i}): "${targets[${i}]}"
/next i

|Any secondary targets? (in conjunction with TARGET_METHOD = 2
|Will only go for those if there are none of the primary targets.
/if (${Defined[Param1]}) {
/call SplitString targets2 "${Param1}" "|"
/for i 1 to ${targets2.Size}
DEBUG_2 Secondary Target defined (${i}): "${targets2[${i}]}"
/next i
}


/call MainSub
DEBUG_1 Exited normally!
/return


|----------------------------------------------------------------------------
|SUB: MainSub - The main sub
|----------------------------------------------------------------------------
Sub MainSub

/declare cnt1 int local 0

/if (${Bool[PULL_TO_HOMEPOINT]}) {
/if ( ${Me.Pet.ID} ) /pet guard
}

/if (${Bool[PULL_TO_HOMEPOINT]} && ${Me.Pet.ID}) {
|Allways run to pet before getting new target
DEBUG_1 Moving to pet before we start pulling
/target id ${Me.Pet.ID}
/call RunToSpotTarget
/varset homeX ${Me.X}
/varset homeY ${Me.Y}
}


|The main loop. After an attack we go here to aquire a new target
:NewTarget
/varset stickontarget False
/varset stickontarget_2 False
/varset initiatedattack False
DEBUG_1 NewTarget loop (Tick: ${tickcnt})

/call ClearIgnoreList
/call StopAllMovement "MainSub"

/if (${Bool[PULL_TO_HOMEPOINT]} && ${Me.Pet.ID}) {
|Allways run to pet before getting new target
/target id ${Me.Pet.ID}
/call RunToSpotTarget
|/varset homeX ${Me.X}
|/varset homeY ${Me.Y}
}

/call FaceTarget

:Repeater
DEBUG_2 NewTarget loop2
/call ClearTarget "repeater1"
/call StopAttack

|/call SetTarget

/if ( ${Target.Type.Equal[NPC]} ) {
/call ClearTarget "repeater2"
}

|Assist pet to see if he is busy
/call AssistPet "mainsub"

/if ( ${Target.Type.Equal["Corpse"]} || !${Target.ID} ) {
/call ClearTarget "repeater3"
} else {
/call SetTarget "mainsub"
}

/if ( ${Target.ID}==${Me.Pet.ID} ) {
/call ClearTarget "mainsub1"
}

/if ( ${Spawn[${TargetID}].Type.Equal["NPC"]} ) {
DEBUG_1 Assisting pet: ${Spawn[${TargetID}].CleanName}
/varset waitcounter 0
/varset stickontarget True
|Allready in action, so dont initiate stuff
/varset initiatedattack True
DEBUG_1 PetTarget Locked! ${Spawn[${TargetID}].CleanName}
/call StandUp
/goto :MainAttackLoop
}

/call ClearTarget "mainsub2"

|:FirstTime
/squelch /if ( ${Target.ID} ) /target clear
/call DowntimeWork
/if ( ${Macro.Return}==0 ) {
DEBUG_2 Return to top after DowntimeWork
/goto :NewTarget
}
/call AquireTarget

/if ( ${Macro.Return}==0 ) {
DEBUG_1 No targets found. Waiting.
/call StopAllMovement "MS1"
/call SitDown
/goto :Repeater
} else {
DEBUG_1 Target Name: ${Spawn[${TargetID}].CleanName}, Lvl:${Spawn[${TargetID}].Level},

Class: ${Spawn[${TargetID}].Class}
}


|The main attack loop - Here all the attacking will take place
:MainAttackLoop

|Have we lost our target?
/if ( ${TargetID}==0 ) {
/goto :NewTarget
}

|Warn if I am low on health
/if ( ${Me.PctHPs}<ALARM_HEALTH_BELOW_PCT ) {
/if ( ${Math.Rand[20]} < 3 ) /beep
/popup "ALARM ALARM. HEALTH IS LOW!!!"
}

|Paranoia. Any GM's in zone? abort macro!
/call CheckGM

|If we get attacked while running to our target, we just got ourselves a new one instead
/if ( ${Spawn[${TargetID}].Distance} > TARGET_RADIUS ) {
|If we get attack on the way, assist pet every 4 sec
/varcalc cnt1 ${cnt1}+1
/if ( ${cnt1} > 40 ) {
/call AssistPet "mainattackloop"
/if ( ${Target.ID} && ${Target.Type.Equal[NPC]}) {
/call ClearTarget "MAL"
/call SetTarget "mainattack"
/goto :NewTarget
}
/varset cnt1 0
}
}


|If we have not targeted our locked target and within target range, target
/if ( !${Target.ID} && ${Spawn[${TargetID}].Distance} < TARGET_RADIUS ) {
DEBUG_1 Targetting the mob: ${Spawn[${TargetID}].CleanName} (${TargetID}) Distance:

${Spawn[${TargetID}].Distance}
/call TargetMainTarget
|/target id ${TargetID}
}
|}

/varset waitcounter 0

|If i got no main target is gone
/if (!${Spawn[${TargetID}].ID} || ${Spawn[${TargetID}].Type.Equal[CORPSE]} ) {
DEBUG_1 Ending fight, No Target
/call StopAllMovement "MS2"
/call DoTheLooting ${TargetID}
DEBUG_2 Looting Done
/goto :NewTarget
}

|If target is a corpse
/if ( ${Spawn[${TargetID}].Type.Equal[CORPSE]} ) {
DEBUG_1 Ending fight, Target is a Corpse
/call StopAllMovement "MS3"
/call DoTheLooting ${TargetID}
/call StopAllMovement "MainSub"
/call Delay 10
/call Delay ${Math.Rand[20]}
/goto :NewTarget
}


/call MainAttack ${TargetID}
|/if ( ${Macro.Return}==0 && !${Spawn[${TargetID}].ID} ) /goto :NewTarget
/if ( ${Macro.Return}==0 ) {
DEBUG_2 MainAttack Return: ${Macro.Return}
/goto :NewTarget
}

|Remove pet from target if it is. just in case
|/call UntargetPet

|/call TargetMainTarget
/goto :MainAttackLoop

:EndMacro
/endmacro
/return


|----------------------------------------------------------------------------
|SUB: UntargetPet - If pet is targeted, untarget it.
|----------------------------------------------------------------------------
Sub UntargetPet
/if ( ${Me.Pet.ID} ) {
/if ( ${Target.Name.Equal[${Me.Pet.Name}]} ) {
/squelch /if ( ${Target.ID} ) /target clear
|/call ClearTarget "untargetpet"
}
}
/return


|----------------------------------------------------------------------------
|SUB: CheckToAbortAttack - Sees if we have to abort our attack
|----------------------------------------------------------------------------
Sub CheckToAbortAttack(int targID)
DEBUG_1 >Checking if we should abort...

|To prevent circle running on this intensive part
/call MoveLeftStop
/call MoveRightStop

|/target id ${targID}
/call TargetMainTarget
/call Delay 1

|If target has a speed above 100 assume its running (someone has it)
| Wont work very well if snared
/if ( ${Spawn[${targID}].Speed}>150 ) {
DEBUG_1 Ending fight, Target running (aggroed on someone else)
/pet back
/call AddToNoList IgnoreList ${targID}
|/call ClearTarget
/return 0
}

|Check if mob is heading in a direction of a close by PC
/call DetectNPCtowardsPC ${targID}
/if (${Macro.Return}==0) {
DEBUG_1 NPC seems to be heading for someone else! Aborting.
/pet back
/call AddToNoList IgnoreList ${targID}
|/call ClearTarget
/return 0
}

|Check if anyone is closer than me
/call AnyoneCloser ${targID}
/if (${Macro.Return}==0) {
DEBUG_1 Someone is closer than me! Aborting. ${Spawn[${targID}].CleanName} (${targID})
/pet back
/call AddToNoList IgnoreList ${targID}
|/call ClearTarget
/return 0
}

|If this target is below 100% and I targeted it manually it is probably just snatched

before me
|/if ( ${Target.ID}==${Spawn[${TargetID}].ID} && !${stickontarget} ) {
/if ( !${stickontarget} ) {
/if ( ${Spawn[${targID}].PctHPs}<100 ) {
DEBUG_1 Ending fight, Target(${Spawn[${TargetID}].PctHPs}%) < 100%
/pet back
|/call ClearTarget "checkabort"
/return 0
}
}

|Checking to see if the area is to mob-crowdy
/if ( AVOID_CROWDED_RADIUS>0 ) {
|Is there any other mob very close by the target?
/call AnyNPCCloserTo ${targID} AVOID_CROWDED_RADIUS
/if ( ${Macro.Return}==0 ) {
DEBUG_1 To crowdy at Target: ${Spawn[${targID}].CleanName} (${targID}) (

${Spawn[${targID}].Distance} )
/return 0
}
}

/return 1

|----------------------------------------------------------------------------
|SUB: MainAttack - Handles the fighting
|----------------------------------------------------------------------------
Sub MainAttack(int targID)
/declare timeoutcnt1 int local 0

|Any VERY IMPORTANT buffs worn off? ie SoW for fleeing - dont do it to often
/if ( ${Math.Rand[50]}<=2 ) /call MaintainCriticalSelfBuffs

|Check to see if its time to check for new target, as we are moving in. (approx every 2

second + processing time)
/if ( !${initiatedattack} ) {
/declare tt int local
/varcalc tt ${tickcnt} / 20

/declare oID int local
/varset oID ${TargetID}
/if ( ${tt}>${aqtargcnt} ) {
|To prevent doing circles on heavy targetsearching
/call MoveLeftStop
/call MoveRightStop
DEBUG_1 >Checking if any target is closer than the current:

${Spawn[${TargetID}].CleanName} (${TargetID}) ${Spawn[${TargetID}].Distance}...
/varset aqtargcnt ${tt}
/call TargetIt
/if (${oID}<>${TargetID}) {
/if ( ${TargetID}==0 ) {
DEBUG_1 Target Lost
/return 0
}
DEBUG_1 Target switched to: ${Spawn[${TargetID}].CleanName}, Lvl:

${Spawn[${TargetID}].Level}, Class: ${Spawn[${TargetID}].Class}
}
}
}

|PULLING TO HOMEPOINT ATTACKING
/if (${Bool[PULL_TO_HOMEPOINT]}) {
/if ( ${Spawn[${targID}].Distance}<INITIALIZE_ATTACK_RANGE && !${initiatedattack})

{
/call CheckToAbortAttack ${targID}
/if ( ${Macro.Return}==0 ) /return 0


|Start pulling, and run home
/target id ${targID}
/declare TargetDist int local
/declare i int local

|Face homewards before starting to pull
/face nolook loc ${homeY},${homeX}

:TryAgain
|Return if no active target
/if (!${Target.ID} && !${Target.Type.Equal[NPC]}) /return 1

|Check the distance...
/if ( ${Spell["PULL_TO_HOME_SPELL_NAME"].Range}<${Target.Distance}) /return

1

|Start to pull
DEBUG_1 Casting pullspell ("PULL_TO_HOME_SPELL_NAME") (${Target.ID})
/call Cast "PULL_TO_HOME_SPELL_NAME" gemPULL_TO_HOME_SPELL_GEM
/varcalc tickcnt ${tickcnt} +

${Math.Calc[${Spell["PULL_TO_HOME_SPELL_NAME"].MyCastTime}*10]}
/call Delay 1

|Checking to see if target is heading my way. Or we have failed the pull.
/call NPCtowardsME ${targID}

|If the mob is outside attackrange+buffer and it is not headed in out

direction, presume pull to have failed. Try again
/if ( ${Macro.Return}==1 &&

${Target.Distance}>${Math.Calc[${Target.MaxRange}+50]} ) /goto :TryAgain

/varset JustCastedSpell true
/varset initiatedattack true
/varset stickontarget true

|/face fast nolook loc ${homeY},${homeX}
/varset keypressercnt1 100

/call MoveForward
:PetBackOff
DEBUG_3 Distance to mob: ${Spawn[${TargetID}].Distance}

/for i 0 to 10
DEBUG_3 Stepping homewards
/call StepToSpot ${homeX} ${homeY} 20
/if ( ${Macro.Return}==0 ) /goto :donelooping
/call Delay 1
/next i

|Dont outrun the mob!
:WaitForMob
/if ( ${Spawn[${TargetID}].Distance}>200 ) {
DEBUG_2 Waiting for the Mob. Distance: ${Spawn[${TargetID}].Distance} > 300
/call StopAllMovement "AquireTarget0"
/varset keypressercnt1 100
|/target clear
|/call Delay 1
|/target id ${TargetID}
/call Delay 2
/varcalc timeoutcnt1 ${timeoutcnt1}+1
/if (${timeoutcnt1}>50) {
DEBUG_1 Timeout waiting for mob!
/call ClearTarget
/return 1
}
/goto :WaitForMob
}
/call MoveForward

/if (${Bool[PULL_TO_HOME_PETBACKOFF]}) /pet back

/goto :PetBackOff
:donelooping

DEBUG_2 we are home. turn around
/call StopAllMovement "AquireTarget1"
/if ( ${Target.ID} ) /face nolook
/varset waitcounter 0
/return 1

/goto :PetBackOff
}


|NORMAL ATTACKING
} else {
|Initialize the attack - send pet, slow, nuke - Only initiate once per mob
/if ( ${Spawn[${targID}].Distance}<INITIALIZE_ATTACK_RANGE && !${initiatedattack})

{
/call CheckToAbortAttack ${targID}
/if ( ${Macro.Return}==0 ) /return 0


DEBUG_1 ** INITIATING ATTACK: ${Target.CleanName}
/varset initiatedattack True


|Send in pet before slow?
/if (${Bool[SEND_PET_BEFORE_SLOW]}) {
DEBUG_2 Asking pet to attack ${Target.CleanName} (${Target.Name})!
/pet attack
DEBUG_3 Pet attacking ${Target.CleanName}!
}

|Do the Slowing
/if (${Bool[DO_SLOW_ON_PULL]}) {
/if ( ${Target.Level}>SLOW_ABOVE_LEVEL) {
/if ( ${Target.Type.Equal[NPC]} ) {
DEBUG_1 Casting slow!
/call Cast "SLOW_SPELL" gemSLOW_GEM
/varcalc tickcnt ${tickcnt} +

${Math.Calc[${Spell["SLOW_SPELL"].MyCastTime}*10]}
/varset JustCastedSpell true
|To prevent stuckdetecting
/call MoveForward "MainAttack 00"
/call Delay 10
}
}
}


/if (!${Bool[SEND_PET_BEFORE_SLOW]}) {
/if ( ${Target.PctHPs}<100 ) {
|Someone else grabbed it before I got the chance to charge (maybe

during slow)
/pet back
/call Delay 1
/pet back
/call Delay 1
DEBUG_1 Ending fight, Not Attacking + Target ${Target.PctHPs}% < 100%

before Slow went in
/call AddToNoList IgnoreList ${targID}
/call ClearTarget "attackloop1"
/return 0
}
}

|If we havent allready sent the pet, now is the time
/if (!${Bool[SEND_PET_BEFORE_SLOW]}) {
/pet attack
DEBUG_2 Pet attacking ${Target.CleanName}!
}

|Do a nuke before attacking?
/call DoTheNuke

/varset stickontarget True
DEBUG_1 Target Locked! ${Target.CleanName}
}
}



|If we are not attacking and the health of the mob is below 100% asume someone else has it.

back off!
/if ( ${Spawn[${TargetID}].Distance}>200) {
|/if ( ${Target.ID}==${Spawn[${targID}].ID} && !${stickontarget} ) {
/if ( !${stickontarget} ) {
/if (!${Me.Combat} && ${Spawn[${TargetID}].PctHPs}<100) {
/call AddToNoList IgnoreList ${targID}
/pet back
DEBUG_1 Ending fight, Not Attacking + Target(${Spawn[${TargetID}].PctHPs}%) <

100%
/call ClearTarget "attackloop2"
/return 0
}
}
}

|Either attack or move towards target
/declare TargDist float local
|/varset TargDist ${Math.Calc[ ${Target.DistancePredict} - (${Target.MaxRangeTo}/2) ]}
|/varset TargDist ${Math.Calc[ ${Spawn[${targID}].DistancePredict} -

(${Spawn[${targID}].MaxRangeTo}/2) ]}
/varset TargDist ${Math.Calc[ ${Spawn[${targID}].Distance} -

(${Spawn[${targID}].MaxRangeTo}/2) ]}
|/varset TargDist ${Math.Calc[ ${Spawn[${targID}].Distance} -

(${Spawn[${targID}].MaxRangeTo}) ]}

|When we are doing the meleeing!
|DEBUG_3 Distance to target: ${TargDist}
/if ( ${TargDist} < 0 ) {

|Target our target if are fighting it and its not targeted yet
/if ( !${Target.ID} ) /call TargetMainTarget

/call MoveForwardStop "MainAttack"
/call StartAttack
/if ( ${Me.AbilityReady["kick"]} ) /doability "kick"

|Should we back off? - not target is moving/fleeing
/if ( ${Target.PctHPs}>FORCE_ATTACK_WHEN_MOB_BELOW && ${Spawn[${targID}].Speed}==0 ) {
DEBUG_3 BACK OFF FOR PET ${Target.ID} - ${Spawn[${targID}].ID} - ${targID}
/call BackoffForPet ${Target.ID}
|Target the main target and continue
/call TargetMainTarget
/call StandUp
}

|Keep face towards mob
/call FaceTarget

|Strafe around to back of mob (opposite of pet)?
/if (${Bool[STRAFE_TO_BACK]} && ${Target.Speed}==0 && ${Me.Pet.Distance}<100 ) {
/declare mydeg float local
/declare petdeg float local
/declare targdeg float local
/varcalc mydeg ${Heading[${Target.Y},${Target.X}].DegreesCCW}
/varset petdeg ${Me.Pet.Heading.DegreesCCW}

/if ( ${petdeg<180} ) {
/varcalc targdeg ${petdeg} + 180
} else {
/varcalc targdeg ${petdeg} - 180
}

/if ( ${targdeg} > 360 ) /varcalc targdeg ${targdeg} - 360
/if ( ${targdeg} < 0 ) /varcalc targdeg ${targdeg} + 360

/call StepStrafeToAngleTarget ${targdeg}
}
|/return 1
} else {

|If we are allways pulling home. Only run when getting target
/if (${Bool[PULL_TO_HOMEPOINT]}) {
/if ( !${initiatedattack}) {
/call StepToSpot ${Spawn[${targID}].X} ${Spawn[${targID}].Y}

${Math.Calc[${Spawn[${targID}].MaxRangeTo}/2]}
} else {
|Head towards the mob when its very close. Or we are allready in

combat (backoffrompet)
/if ( ${TargDist} < 20 || ${stickontarget_2}) {
|/pet attack
|DEBUG_3 /if ( ${TargDist} < 50 || ${stickontarget})
/call StepToSpot ${Spawn[${targID}].X} ${Spawn[${targID}].Y}

${Math.Calc[${Spawn[${targID}].MaxRangeTo}/2]}
/varset stickontarget_2 True
} else {
|/varset stickontarget True
}

|If pet is engaging, get it to back off
/if (${Bool[PULL_TO_HOME_PETBACKOFF]}) {
/if ( !${Me.Combat} && ${Me.Pet.Speed}>0 ) {
/pet back
/call Delay 3
}
}

/if (${Defined[timeoutcounter1]}) {
/varcalc timeoutcounter1 ${timeoutcounter1} + 1
} else {
/declare timeoutcounter1 int outer 0
}

/if ( ${Me.Combat} ) {
/varset timeoutcounter1 0
}
/if ( ${timeoutcounter1}>400 ) {
/varset timeoutcounter1 0
|/if ( ${Target.Distance}<500 ) {
| DEBUG_1 Seems the mob is not coming. Going to get it

again!
|
| /varset initiatedattack false
|} else {
DEBUG_1 Seems the mob is not coming. Scrapping it...
/return 0
|}
}

}

|Checking for timeout
/if (${Defined[justcastspellcounter]}) {
/varcalc justcastspellcounter ${justcastspellcounter} + 1
} else {
/declare justcastspellcounter int outer 0
}


} else {
|Non PULL_TO_HOMEPOINT code
/call StepToSpot ${Spawn[${targID}].X} ${Spawn[${targID}].Y}

${Math.Calc[${Spawn[${targID}].MaxRangeTo}/2]}
}
}

/return 1




|----------------------------------------------------------------------------
|SUB: MainAttack - Handles the fighting
|----------------------------------------------------------------------------
Sub DowntimeWork
/call StopAllMovement "DowntimeWork"

| Make sure critical spells are up
/call MaintainCriticalSelfBuffs
/if ( ${Macro.Return}==0 ) /return 0
DEBUG_2 1. Critical Buffs Checked

| Check if we are low on mana or health. Heal or sit down if low
/call CheckMana
/if ( ${Macro.Return}==0 ) /return 0
DEBUG_2 2. Mana Checked

/call HealMyself
/if ( ${Macro.Return}==0 ) /return 0
DEBUG_2 3. Health Checked

| Make sure pet is up + all its buffs are on it
/call HealPet
/if ( ${Macro.Return}==0 ) /return 0
DEBUG_2 4. Pet Health Checked

/call MaintainPetBuffs
/if ( ${Macro.Return}==0 ) /return 0
DEBUG_2 5. Pet Buffs Checked

| Make sure all buffs on self are up
/call MaintainSelfBuffs
/if ( ${Macro.Return}==0 ) /return 0
DEBUG_2 6. Buffs Checked

/return 1



|----------------------------------------------------------------------------
|SUB: AquireTarget - Finding a target
|----------------------------------------------------------------------------
Sub AquireTarget
/declare TargetDist float local |Distance to Target
/declare tmpint int local
/declare rand int local |random var

/varset TargetDist ${Math.Distance[${homeY},${homeX},0:${Me.Y},${Me.X},0]}
/if ( ${TargetDist}>40 ) /varcalc waitcounter ${waitcounter}+1


|/if ( !${Target.ID} ) {
/if ( !${Spawn[${TargetID}].ID} ) {
/call ClearTarget "aquiretarget"
DEBUG_3 Do target

|Target distance to run home if we are outside max range
/varset TargetDist ${Math.Distance[${homeY},${homeX},0:${Me.Y},${Me.X},0]}
/if ( ${TargetDist}>MAX_RANGE_FROM_HOMEPOINT || ${waitcounter}>3) {
DEBUG_1 Running home.
|Run to homespot
:Retarget0
/for rand 0 to 10
/call StepToSpot ${homeX} ${homeY} 40
/call Delay 1
/next rand
|/call MoveForwardStop

/varset TargetDist ${Math.Distance[${homeY},${homeX},0:${Me.Y},${Me.X},0]}

|If we are inside the maxrange border/2, search for a mob
/if ( ${TargetDist}<${Math.Calc[MAX_RANGE_FROM_HOMEPOINT/2]} ) {
/call TargetIt AT1
/if ( ${Spawn[${TargetID}].ID} ) /return 1
} else {
|If we get attack on the way, assist pet
/call AssistPet "aquiretarget"
/if ( ${Target.ID} && ${Target.Type.Equal[NPC]}) {
/return 0
}

}

|We are home
/if ( ${TargetDist}<40 ) {
/call StopAllMovement "AquireTarget1"
/varset waitcounter 0
/return 0
}

/goto :Retarget0
|/if ( !${Spawn[${TargetID}].ID} ) /goto :Retarget0
}

/call TargetIt AT2
/if ( ${Spawn[${TargetID}].ID} ) /return 1


|Calculating distance home
/varset TargetDist ${Math.Distance[${homeY},${homeX},0:${Me.Y},${Me.X},0]}

|Should we allways return to homepoint after a fight?
/if ( ${Bool[RETURN_TO_HOMEPOINT]} ) {
/if ( ${TargetDist}>40 ) {
DEBUG_1 Running home again
/call RunToSpot ${homeX} ${homeY} 40
/varset waitcounter 0
/return 0
}
}

/if ( ${Bool[ARE_WE_RESTLESS]} ) {
/if ( ${TargetDist}<40 ) {
/varcalc waitcounter ${waitcounter}-1
/if ( ${waitcounter}<-5 ) {

DEBUG_1 We are restless. Running a bit. ${rndX}, ${rndY}
:Retarget1
/for tmpint 0 to 10
/call StepToSpot ${rndX} ${rndY} 40
/call Delay 1
/next tmpint

/call TargetIt AT3
/if ( ${Spawn[${TargetID}].ID} ) /return 1

/varset TargetDist ${Math.Distance[${rndY},${rndX},0:${Me.Y},${Me.X},0]}
/if ( ${TargetDist}<40 ) {
/call StopAllMovement "AquireTarget2"
/varset waitcounter 0
/if ( ${Math.Rand[10]} < 5 ) {
/varset rndX ${Math.Calc[ ${Me.X} + ${Math.Rand[RESTLESS_RANGE]} *

2 ]}
} else {
/varset rndX ${Math.Calc[ ${Me.X} - ${Math.Rand[RESTLESS_RANGE]} *

2 ]}
}
/if ( ${Math.Rand[10]} < 5 ) {
/varset rndY ${Math.Calc[ ${Me.Y} + ${Math.Rand[RESTLESS_RANGE]} *

2 ]}
} else {
/varset rndY ${Math.Calc[ ${Me.Y} - ${Math.Rand[RESTLESS_RANGE]} *

2 ]}
}
/return 0
}

|/if ( !${Target.ID} ) /goto :Retarget1
|/if ( !${Spawn[${TargetID}].ID} )
/goto :Retarget1

}
}
}


/if ( ${waitcounter}==1 ) /call SitDown

/call StopAllMovement "MainSub"
/call Delay 40
/return 0

}



/if ( ${TargetID}<=0 ) /return 0
|DEBUG_3 Target: ${TargetID} - ${Spawn[${TargetID}].CleanName} ${Spawn[${TargetID}].Level}

${Spawn[${TargetID}].Class} (${Spawn[${TargetID}].Name})
/return 1


|----------------------------------------------------------------------------
|SUB: DoTheNuke - Nuke target
|----------------------------------------------------------------------------
Sub DoTheNuke
/if (${Bool[DO_NUKE_ON_PULL]}) {
/if ( ${Me.PctMana}>NUKE_ABOVE_MANA_PCT) {
/if ( ${Target.Level}>SLOW_ABOVE_LEVEL && ${Target.Type.Equal[NPC]}) {
/call Cast "NUKE_SPELL" gem1
/varcalc tickcnt ${tickcnt} +

${Math.Calc[${Spell["NUKE_SPELL"].MyCastTime}*10]}
/varset JustCastedSpell true
}
}
}
/return

|----------------------------------------------------------------------------
|SUB: BackoffFromMob - Backing off outside the mob range
|----------------------------------------------------------------------------
Sub BackoffFromMob(int targID)
/declare TargDist float local
|Move off the double range
/varcalc TargDist ${Spawn[${targID}].Distance} - (${Spawn[${targID}].MaxRange}*1.3)

|DEBUG_3 backoff mob
|DEBUG_3 backoff/moveback ${TargDist} should be less than 0
/if ( ${TargDist}<0) /call MoveBack "BackoffFromMob"

|Move back out of range
:BackOff1
/varcalc TargDist ${Spawn[${targID}].Distance} - (${Spawn[${targID}].MaxRange}*1.3)
|DEBUG_3 BackOff1 ${TargDist} --- ${Spawn[${targID}].Distance}
/if ( !${Target.ID} ) /return

|If we are not out of range (times 2)
/if ( ${TargDist}<0) {
|DEBUG_3 BackOff: ${TargDist} --- ${Spawn[${targID}].Distance}

(${Spawn[${targID}].MaxRange}*1.3)
/call Delay 1
/call FaceTarget
/goto :BackOff1
}
|DEBUG_3 stop attack
/call StopAttack
/call StopAllMovement "BackoffFromMob"
|DEBUG_3 backoff mob done
/return

|----------------------------------------------------------------------------
|SUB: BackoffForPet - Backing off when its the pets turn to tank
|----------------------------------------------------------------------------
Sub BackoffForPet(int targID)
/if ( ${Math.Calc[ ${Me.Pet.PctHPs} - ${Me.PctHPs} ]} > LET_PET_TANK_IF_DIFFERENCE ) {
/declare cnt int local

|/declare themobname string local
|/varset themobname ${Target.Name}

|What to do while idle - This will be main loop til we help pet again
:Repeat1

|We cant back off if pet is out of range
/if ( ${Me.Pet.Distance}>150 ) {
|DEBUG_3 Pet out of range
/call StartAttack
/return
}
|If there is more than 1 mob within range, dont back off
/call AnyExtraMobsNearby IGNORE_PETTANK_IF_MOBS_RADIUS
/if ( ${Macro.Return}>1 ) {
DEBUG_2 Cannot back off. ${Macro.Return} mobs close (including our target).
/call MoveLeftStop
/call MoveRightStop
/call StartAttack
/return
}
|DEBUG_3 Number of mobs close by is: ${Macro.Return}

/call BackoffFromMob ${targID}

/varcalc cnt ${cnt}+1

|/varset mymobID ${Target.ID}
/if ( ${cnt}==1 ) /squelch /if ( ${Target.ID} ) /target clear
|/if ( ${cnt}==1 ) /call ClearTarget "backoffforpet"

|Check once per second if something is happening
/if ( ${cnt}>5 ) {
|If spawn is moving, attack again!
|DEBUG_3 Pet range ${Me.Pet.Distance}
/if ( ${Spawn[${targID}].Speed}>10 ) {
DEBUG_1 Target moving or fleeing. Attacking.
/call StartAttack
/return
}

|DEBUG_3 Letting pet tank some!
/call SitDown
DEBUG_1 Main target(${Spawn[${targID}].CleanName}) at ${Spawn[${targID}].PctHPs}%
|/if ( !${Target.ID} ) /return
|/target ${themobname}]}

/if ( !${Spawn[${targID}].ID} ) {
DEBUG_1 Returning because pet has killed the target!
/return
}
/if ( ${Spawn[${targID}].PctHPs}<FORCE_ATTACK_WHEN_MOB_BELOW ) {
DEBUG_1 Mob is so low I can maul him dead now!
/call StartAttack
/return
}

/call Delay 3
/call AssistPet "backoffforpet"

|Pet on wrong target? put it on the right one
/if ( ${Target.ID}!=${targID} ) {
/call TargetMainTarget
/call Delay 1
/pet back
/call Delay 1
/pet attack
}

|Nuke some?
/call DoTheNuke

|Maintain my important buffs
/call MaintainCriticalSelfBuffs

|Maintain pet buffs
/call MaintainPetBuffs

|Heal myself if needed
/call HealMyself

|Will wait until the pet reaches same % of health as self
/varset cnt 0
}

/call Delay 1

|If pet still has more HPs than me just loop
/if ( ${Me.Pet.PctHPs} > ${Me.PctHPs} ) /goto :Repeat1

DEBUG_1 Pet health equal to mine! Back to action!
/call StartAttack
}
/return

|----------------------------------------------------------------------------
|SUB: AnyExtraMobsNearby - Checks if there is a second mob within radius
|----------------------------------------------------------------------------
Sub AnyExtraMobsNearby(int radius)
/declare i int local
/declare c int local 0
/for i 1 to 5
/if ( ${NearestSpawn[${i}].Distance} < ${radius} &&

${NearestSpawn[${i}].Type.Equal[NPC]}) {
|DEBUG_3 ${i} - ${NearestSpawn[${i}].CleanName} ${NearestSpawn[${i}].Distance}
/varcalc c ${c}+1
/call Delay 2
}
/next i
/if ( ${c}>0 ) /return ${c}
/return 0

|----------------------------------------------------------------------------
|SUB: StartAttack
|----------------------------------------------------------------------------
Sub StartAttack
/if ( !${Me.Combat} ) /attack on
/varset theslack THE_SLACK_DEGREE
/return


|----------------------------------------------------------------------------
|SUB: StopAttack
|----------------------------------------------------------------------------
Sub StopAttack
/if ( ${Me.Combat} ) /attack off
/return


|----------------------------------------------------------------------------
|SUB: AssistPet - Target pet, assist it and wait for a target
|----------------------------------------------------------------------------
Sub AssistPet
DEBUG_3 AssistPet called from ${Param0}
/declare cnt int local
/if ( !${Target.ID} ) {
/if ( ${Me.Pet.ID} ) {
/target ${Me.Pet.CleanName}
:GetTarget1
/if ( !${Me.Pet.CleanName.Equal[${Target.CleanName}]} ) {
/call Delay 1
/goto :GetTarget1
|DEBUG_3 waiting for pet: ${Target.CleanName}
}
/assist
:GetTarget2
/if ( ${Me.Pet.CleanName.Equal[${Target.CleanName}]} ) {
/varcalc cnt ${cnt}+1
/call Delay 1
/if ( ${cnt}>10 ) {
/squelch /if ( ${Target.ID} ) /target clear
|/call ClearTarget "assistpet"
/return
|DEBUG_3 waiting for target: ${Target.CleanName}
}
/goto :GetTarget2
}
|DEBUG_3 Pet is targetting: ${Target.CleanName}
}
}
/return


|----------------------------------------------------------------------------
|SUB: SummonPet - Summon pet if farther away than the defined range
|----------------------------------------------------------------------------
Sub SummonPet(bool force)
/if ( MAX_PET_RANGE_BEFORE_SUMMON>0 || ${force}) {
/if ( ${Me.Pet.Distance}>MAX_PET_RANGE_BEFORE_SUMMON || ${force}) {
DEBUG_1 Summoning pet. Its range is ${Me.Pet.Distance}
/call Cast "Summon Companion" gem7
/varcalc tickcnt ${tickcnt} + ${Math.Calc[${Spell["Summon

Companion"].MyCastTime}*10]}
/varset JustCastedSpell true
/call Delay 10

/if (${Bool[PULL_TO_HOMEPOINT]}) {
/if ( ${Me.Pet.ID} ) /pet guard
}

/return 0
}
}
/return 1


|----------------------------------------------------------------------------
|SUB: HealPet - Heal pet if needed
|----------------------------------------------------------------------------
Sub HealPet
|Heal pet?
/if ( ${Me.Pet.PctHPs}<HEAL_PET_BELOW_PCT ) {
/if ( ${Me.Pet.ID} ) {
/target ${Me.Pet.CleanName}
/call Cast "HEAL_PET_SPELL" gemHEAL_PET_GEM
/varcalc tickcnt ${tickcnt} +

${Math.Calc[${Spell["HEAL_PET_SPELL"].MyCastTime}*10]}
/varset JustCastedSpell true
/if ( !${Me.Sitting} ) /sit
/return 0
}
}
/return 1


|----------------------------------------------------------------------------
|SUB: HealMyself
|----------------------------------------------------------------------------
Sub HealMyself
|Heal?
/if ( ${Me.PctHPs}<HEAL_BELOW_PCT ) {
/call StopAllMovement "HealMyself"
/if ( !${Target.Name.Equal[${Me.Name}]} ) /target ${Me.Name}
/call Cast "HEAL_SPELL" gemHEAL_GEM
/varcalc tickcnt ${tickcnt} + ${Math.Calc[${Spell["HEAL_SPELL"].MyCastTime}*10]}
/varset JustCastedSpell true
/if ( !${Me.Sitting} ) /sit
/squelch /if ( ${Target.ID} ) /target clear
|/call ClearTarget "healmyself"
/call Delay 1
/return 0
}
/return 1


|----------------------------------------------------------------------------
|SUB: CheckMana
|----------------------------------------------------------------------------
Sub CheckMana
/if ( ${Me.PctHPs}<HEAL_BELOW_PCT && ${Me.PctMana}<50 ) {
/call Delay 10
/if ( !${Me.Sitting} ) /sit
/return 0
}

|Meditate?
/if ( ${Me.PctMana}<MIN_MANA_BEFORE_MEDITATE ) {
DEBUG_1 Mana below MIN_MANA_BEFORE_MEDITATE%. Meditating.
/if ( !${Me.Sitting} ) /sit
/declare i int local
/squelch /if ( ${Target.ID} ) /target clear
|/call ClearTarget "checkmana"
/for i 1 to 10
/call Delay 10
/if ( ${Target.ID} ) /return 1
/next i
/if ( ${Me.PctMana}<MIN_MANA_BEFORE_MEDITATE ) {
/return 0
}
DEBUG_2 Mana OK now.
}
/return 1


|----------------------------------------------------------------------------
|SUB: MaintainPetBuffs - Heal pet and keep its buffs up
|----------------------------------------------------------------------------
Sub MaintainPetBuffs
|If we have pet
/if ( ${Bool[ALLWAYS_HAVE_PET]} ) {
/if ( !${Me.Pet.ID} ) {
DEBUG_1 Creating new pet
/call Cast "PET_SPELL" gemPET_GEM
/varcalc tickcnt ${tickcnt} + ${Math.Calc[${Spell["PET_SPELL"].MyCastTime}*10]}
/varset JustCastedSpell true
/if (${Bool[PULL_TO_HOMEPOINT]}) {
/if ( ${Me.Pet.ID} ) /pet guard
}
/return 0
}

/call SummonPet

|KeepUpBuffsOnPet
/declare iCount int local
/declare t string local
/for iCount 1 to ${PetBuffs.Size}
/call SplitString tmp_tmp ${PetBuffs[${iCount}]} "|"
/varset t ${Me.PetBuff[${tmp_tmp[1]}]}
/if ( ${t.Equal[NULL]} ) {
/if ( !${Target.ID}!=${Me.Pet.ID} ) {
/target ${Me.Pet.Name}
}

|If we are to far away to buff pet - run to it
/if (${Spell["${tmp_tmp[1]}"].Range}<${Me.Pet.Distance}) {
|Echo pet to far away to buff. Summoning it, or running to it
/if ( ${Me.Pet.Distance}>200 ) {
/call SummonPet true
} else {
/call RunToSpotTarget
}
/pet follow
}

|Cast with gemselection or default
/if ( ${tmp_tmp.Size}>1 ) {
DEBUG_2 Trying to cast "${tmp_tmp[1]}"
/call Cast "${tmp_tmp[1]}" gem${tmp_tmp[2]}
/varset JustCastedSpell true
} else {
DEBUG_2 Trying to cast "${tmp_tmp[1]}"
/call Cast "${tmp_tmp[1]}"
/varset JustCastedSpell true
}
/varcalc tickcnt ${tickcnt} +

${Math.Calc[${Spell["${tmp_tmp[1]}"].MyCastTime}*10]}
|/delay 5
|Return to top - so we dont keep buffing if being attacked
/return 0
}
/next iCount

/return 1


|----------------------------------------------------------------------------
|SUB: MaintainSelfBuffs - Keep buffs up
|----------------------------------------------------------------------------
Sub MaintainSelfBuffs
|KeepUpBuffsOnMe
/declare iCount int local
/declare t string local
/for iCount 1 to ${MyBuffs.Size}
/call SplitString tmp_tmp ${MyBuffs[${iCount}]} "|"
/varset t ${Me.Buff[${tmp_tmp[1]}]}
/if ( ${t.Equal[NULL]} ) {
/if ( !${Target.ID}!=${Me.ID} ) {
/target ${Me.Name}
}
|Cast with gemselection or default
/if ( ${tmp_tmp.Size}>1 ) {
DEBUG_2 Trying to cast "${tmp_tmp[1]}"
/call Cast "${tmp_tmp[1]}" gem${tmp_tmp[2]}
/varset JustCastedSpell true
} else {
DEBUG_2 Trying to cast "${tmp_tmp[1]}"
/call Cast "${tmp_tmp[1]}"
/varset JustCastedSpell true
}
/varcalc tickcnt ${tickcnt} + ${Math.Calc[${Spell["${tmp_tmp[1]}"].MyCastTime}*10]}
|Return to top - so we dont keep buffing if being attacked
/return 0
}
/next iCount

/return 1


|----------------------------------------------------------------------------
|SUB: MaintainCriticalSelfBuffs - Keep buffs up, even during fight - SOW!
|----------------------------------------------------------------------------
Sub MaintainCriticalSelfBuffs
|KeepUpCriticalBuffsOnMe
/declare iCount int local
/declare t string local
/for iCount 1 to ${CritBuffs.Size}
/call SplitString tmp_tmp ${CritBuffs[${iCount}]} "|"
/varset t ${Me.Buff[${tmp_tmp[1]}]}
/if ( ${t.Equal[NULL]} ) {
DEBUG_3 Infinity loop? Echoing debug data...
DEBUG_3 ${t},${tmp_tmp[1]},${Me.Buff[${tmp_tmp[1]}]}
/if ( !${Target.ID}!=${Me.ID} ) {
/target ${Me.Name}
}
|Cast with gemselection or default
/if ( ${tmp_tmp.Size}>1 ) {
|DEBUG_3 Cast "${tmp_tmp[1]}" gem${tmp_tmp[2]}
/call Cast "${tmp_tmp[1]}" gem${tmp_tmp[2]}
/varset JustCastedSpell true
} else {
|DEBUG_3 Cast "${tmp_tmp[1]}"
/call Cast "${tmp_tmp[1]}"
/varset JustCastedSpell true
}
/varcalc tickcnt ${tickcnt} + ${Math.Calc[${Spell["${tmp_tmp[1]}"].MyCastTime}*10]}
|/delay 5
|Return to top - so we dont keep buffing if being attacked
/return 0
}
/next iCount
/return 1


|----------------------------------------------------------------------------
|SUB: FaceTarget - Corpse or NPC
|----------------------------------------------------------------------------
Sub FaceTarget
/if ( !${Target.ID} || ${Target.Type.Equal[PC]} || ${Target.Type.Equal[Pet]} ) {
DEBUG_3 Stopping facing
/call StopAllMovement "FaceTarget"
/return
}
|DEBUG_3 Face ON
/call FacePosition ${Target.X} ${Target.Y}
/return ${Macro.Return}


|----------------------------------------------------------------------------
|SUB: FacePosition
|----------------------------------------------------------------------------
Sub FacePosition(float X, float Y)
|Face towards target - At a 'slack' degrees slack - more natural
/call WhatDirection ${X} ${Y} ${theslack}
/if ( ${Macro.Return}==0 ) {
/call MoveLeft "FacePosition"
}
/if ( ${Macro.Return}==1 ) {
/call MoveRight "FacePosition"
}
/if ( ${Macro.Return}==-1 ) {
/call MoveLeftStop "FacePosition"
/call MoveRightStop "FacePosition"
/return 0
}

/return 1


|----------------------------------------------------------------------------
|SUB: WhatDirection is the target? 0=left, 1=right, -1=dead on (with slack)
|----------------------------------------------------------------------------
Sub WhatDirection(float X, float Y, int slack)
/if (!${Defined[slack]}) /declare slack int local

/declare currdeg int local
/varset currdeg ${Me.Heading.DegreesCCW}

/declare targdeg string local
/varset targdeg ${Heading[${Y},${X}].DegreesCCW}

/if ( ${currdeg}<${targdeg} ) {
/if ( ${Math.Abs[${currdeg}-${targdeg}]} > ${slack} ) {
/if (${Math.Calc[${targdeg}-${currdeg}]} < 180 ) {
/return 0
} else {
/return 1
}
} else {
/return -1
}
} else {
/if ( ${Math.Abs[${targdeg}-${currdeg}]} > ${slack} ) {
/if (${Math.Calc[${currdeg}-${targdeg}]} < 180 ) {
/return 1
} else {
/return 0
}
} else {
/return -1
}
}
/return -1


|----------------------------------------------------------------------------
|SUB: StuckFixTarget
|----------------------------------------------------------------------------
Sub StuckFixTarget
/declare targpct int local
/if ( ${Target.ID} ) {
/if ( ${Target.PctHPs}==100 ) { |To prevent stuckfix during combat
/call StuckFix
/return ${Macro.Return}
}
}
/return

|----------------------------------------------------------------------------
|SUB: StuckFix
|----------------------------------------------------------------------------
Sub StuckFix
/if ( ${forwarddown} ) {
/declare moved float local
/declare rnd int local

|Trying to get out of a spot where we are stuck
/varset moved ${Math.Distance[${oldposy},${oldposx},0:${Me.Y},${Me.X},0]}
|Storing the old position, for next check

|DEBUG_3 ${oldposy},${oldposx} - ${Me.Y},${Me.X} - ${JustCastedSpell}

/varset oldposx ${Me.X}
/varset oldposy ${Me.Y}

/varset rnd ${Math.Rand[1500]}

|Fixes the detection of stuckiness after casting a spell
/if ( ${JustCastedSpell} ) {
/if (${Defined[justcastspellcounter]}) {
/varcalc justcastspellcounter ${justcastspellcounter} + 1
} else {
/declare justcastspellcounter int outer 0
}

/if ( ${justcastspellcounter}>10 ) {
/varset JustCastedSpell false
/varset justcastspellcounter 0
}

/return 1
}

/if ( ${moved}<50 ) {
/if ( ${rnd}<250 ) {
/if ( ${moved}<0.10 ) {
/call MoveForwardStop "StuckFix"
DEBUG_1 Moving around obstacle
/call MoveBack "StuckFix"
/delay ${Math.Rand[15]}
/call MoveRight "StuckFix"
/delay ${Math.Rand[15]}
/call MoveBackStop "StuckFix"
/call MoveRightStop "StuckFix"
/varset theslack 95
/delay ${Math.Rand[15]}
DEBUG_2 Moving forward after obst
/delay 5
/call MoveForward "StuckFix"
/return 0
}
} else /if ( ${rnd}<500 ) {
/if ( ${moved}==0 ) {
/call MoveForwardStop "StuckFix"
DEBUG_1 Moving around obstacle
/call MoveBack "StuckFix"
/delay ${Math.Rand[15]}
/call MoveLeft "StuckFix"
/delay ${Math.Rand[15]}
/call MoveBackStop "StuckFix"
/call MoveLeftStop "StuckFix"
/varset theslack 95
/delay ${Math.Rand[15]}
DEBUG_2 Moving forward after obst
/delay 5
/call MoveForward "StuckFix"
/return 0
}
} else {
|There is a chance to do nothing.
}
}
}
/return 1


|----------------------------------------------------------------------------
|SUB: RunToSpotTarget - Runs to target. Returns when we are at target
|----------------------------------------------------------------------------
Sub RunToSpotTarget
/declare tmp string local
/varset tmp ${Target}
/if ( ${tmp.Equal["NULL"]} ) /return
/call RunToSpot ${Target.X} ${Target.Y} ${Math.Calc[${Target.MaxRangeTo}/2]}
/return


|----------------------------------------------------------------------------
|SUB: RunToSpot - Runs to spot. Returns when we are at spot
|----------------------------------------------------------------------------
Sub RunToSpot(float X, float Y, float howclose)
:RunLoop
/call StepToSpot ${X} ${Y} ${howclose}
/if ( ${Macro.Return}==0 ) /return 1
/goto :RunLoop
/return 1


|----------------------------------------------------------------------------
|SUB: StepToSpot - Runs towards spot. Returns immediately
|----------------------------------------------------------------------------
Sub StepToSpot(float X, float Y, float howclose)
|Immediately stop if me or my pet is targeted
/if ( ${Target.ID}==${Me.ID} || ${Target.ID}==${Me.Pet.ID}) {
DEBUG_3 Am i targeted.
/call StopAllMovement "StepToSpot"
/call StopAttack
/squelch /if ( ${Target.ID} ) /target clear
|/call ClearTarget "steptospot"
/return 1
}

|If slack has been set up to a high number adjust it to come back down to
| the defined number over time
/if ( ${theslack} > THE_SLACK_DEGREE ) {
DEBUG_3 Adjust slack
/varcalc theslack ${theslack}-2
}

/declare TargDist float local |Distance to Target
/varset TargDist ${Math.Distance[${Y},${X},0:${Me.Y},${Me.X},0]}

/if ( ${TargDist}<${howclose} ) {
DEBUG_3 targdist<${howclose} - ${TargDist}<${howclose}
/call StopAllMovement "StepToSpot"
/return 0
}

/call FacePosition ${X} ${Y}

/if ( ${TargDist}>100 ) {
DEBUG_3 targdist>100 - ${TargDist}>100
|Move forward if range is above 100
/call MoveForward "StepToSpot"
} else {
DEBUG_3 targdist<100 - ${TargDist}<100
|Move forward only if we are faced towards the mob
| to prevent a large arc towards the close mob
/if ( ${Macro.Return}==0 ) {
/call MoveForward "StepToSpot"
}
}

/call Delay 1
|Debugging purpose. To prevent to run veeeery long
/if ( ${TargDist} > MAXIMUM_SEARCH_RADIUS ) DEBUG_3 Distance to spot ${X},${Y} =

${TargDist} - slack: ${theslack}

/call StuckFix
/if ( ${Macro.Return}==0 ) {
DEBUG_2 StuckFixed
|/return 0
}

|Checking if we are stuck
/return 1


|----------------------------------------------------------------------------
|SUB: StepToTarget
|----------------------------------------------------------------------------
Sub StepToTarget(float X, float Y)
/call StepToSpot ${Target.X} ${Target.Y} ${Math.Calc[${Target.MaxRangeTo}/2]}
/return


|----------------------------------------------------------------------------
|SUB: DoTheLooting
|----------------------------------------------------------------------------
Sub DoTheLooting(int targID)
DEBUG_1 Going to loot
DEBUG_2 DoTheLooting Target: ${TargetLevel} ${TargetName}'s corpse, ID:${TargetID}
/call StopAllMovement
/if (${TargetLevel}>LOOT_ABOVE_LEVEL) {
|/call TargetMainTarget
/call Delay 3
DEBUG_2 Running to the corpse
/call RunToSpot ${Spawn[${targID}].X} ${Spawn[${targID}].Y}

${Math.Calc[${Spawn[${targID}].MaxRangeTo}/2]}
DEBUG_2 Running done
/if ( ${Spawn[${targID}].Type.Equal["Corpse"]} ) {
/varcalc lootcnt ${lootcnt}+1
DEBUG_1 Looting corpse #${lootcnt}
/call LootMob
/varset theslack THE_SLACK_DEGREE
|/call MoveForward
/doevents
} else {
DEBUG_1 Can't loot a non-corpse!
}
} else {
DEBUG_1 This one is to low lvl. I wont loot it!
/squelch /if ( ${Target.ID} ) /target clear
|/call Clear

Lamdadar
decaying skeleton
decaying skeleton
Posts: 6
Joined: Thu Sep 30, 2004 2:37 am

Post by Lamdadar » Sat Oct 09, 2004 11:06 pm

Guess it would help if i actually posted the errors


Do Target
Want to target from AT2
Doing GetNewTarger method 2
IgnoreListCheck: NULL==1046 ?

inorpo
a lesser mummy
a lesser mummy
Posts: 31
Joined: Sat Nov 29, 2003 1:44 pm

Post by inorpo » Sat Oct 16, 2004 2:03 pm

Is there still a working copy of this somewhere? I can't get any of the links to work.

Mattr35
a lesser mummy
a lesser mummy
Posts: 43
Joined: Wed Dec 29, 2004 12:27 am

Trouble looting

Post by Mattr35 » Wed Dec 29, 2004 12:30 am

Using this in an are like S Ro it works great. I went to the AC camp in OoT and the only problem I had was with the cyclops.

When low on health they run up hill. When the mob dies I'm too far away to loot the corpse. After 2 tries it forgets the corpse and moves too look for the next target.

How can I get my charac to move closer to the corpse (Z axis is causing the prob), up hill?

Matt

Mattr35
a lesser mummy
a lesser mummy
Posts: 43
Joined: Wed Dec 29, 2004 12:27 am

Post by Mattr35 » Wed Dec 29, 2004 5:23 pm

How could I get it to automatically cast my Tunic of Khati Sha? I'd rather have this up for haste than Frenzy.

Matt

User avatar
aChallenged1
a grimling bloodguard
a grimling bloodguard
Posts: 1804
Joined: Mon Jun 28, 2004 10:12 pm

Post by aChallenged1 » Thu Dec 30, 2004 6:35 am

http://macroquest2.com/phpBB2/viewtopic.php?t=7238

make sure to read the thread and make any changes needed.
change it from a mac to an INC according to instructions.
It's an old bit of code so it got screwed up back in June by a change to how certain characters are presented so you will need to change all instances of the following...

Code: Select all

<
to

Code: Select all

<

Code: Select all

>
to

Code: Select all

>
do it in notepad and use the ctrl +h to replace all of each one at a time.
Then you can add it into this macro and modify it to do what you need. I haven't looked, but it would seem like an event trigger and sub.

Good luck!
Fuck writing MQ2 macros. Go with IS scripts; IS Rules!

desnts
RTFM, then ask again
Posts: 58
Joined: Wed Apr 30, 2003 4:40 pm

Post by desnts » Sat Jan 15, 2005 10:09 am

Is there still a working copy of this somewhere? I can't get any of the links to work.
me either was wondering that myself. im useing version 1.2 was wanting to upgrade hehe.

User avatar
aChallenged1
a grimling bloodguard
a grimling bloodguard
Posts: 1804
Joined: Mon Jun 28, 2004 10:12 pm

Post by aChallenged1 » Sat Jan 15, 2005 10:28 am

What about it doesn't work?

It's possible that changes to MQ2 since it was released have broken it.

At least it seems that the html code for > and < have been fixed.
Fuck writing MQ2 macros. Go with IS scripts; IS Rules!

kawaru23
orc pawn
orc pawn
Posts: 21
Joined: Thu Feb 19, 2004 9:33 am

Post by kawaru23 » Sun Jan 23, 2005 2:21 pm

To have it cast the tunic you'll probably want to use swap.mac. Don't put it in the list of buffs, but you'll make a functions something like:

Code: Select all

Sub CheckHaste
/declare t string local
	/varset t ${Me.Buff["Celerity"]}
	/if ( ${t.Equal[NULL]} ) {
		/call Parser "ClickChest@"
	}
/return
And then follow the instructions in swap.mac to add a function in the swap.ini file for ClickChest. Oh, and you'll want to have an include line at the top to bring in swap.mac.[/code]