Neat. I made some additional changes in the attackloop.
The if statements were cleaned up, since they were evaluating the same variables multiple times.
Added a new event OOR which sets TargetOOR to True if it occurs. This enables MeleeDistance updates, incase the mob change runspeed or move too far away along the Z axis. TargetOOR (type bool) replaces the HitFlag in previous macro, because it's a more convenient name.
Enabled NPC pet killing which wasn't possible before, because Target.Type returns pet if you target a NPC pet :)
This macro should be ready to run without any modifications. If you want to use the exptracker you need to uncomment 3 lines:
Line 22:
|#include expreport.inc
Line 79, 80:
:StickBegin
|/echo Starting Experience Tracking
|/call StartExpTrack
Code: Select all
| Startup:
| /mac stick (will use stick-pc.ini settings)
| /mac stick disarm kick taunt (will set your 3 melee actions.)
|
| To loot your own corpe:
| /echo LootMe
|
#turbo
#event RageON "#*#has become ENRAGED.#*#"
#event RageOFF "#*#is no longer enraged#*#"
#event MobGate "#*# Gates.#*#"
#event Invited "#*#To join the group, click on the 'FOLLOW' option, or 'DISBAND' to cancel#*#"
#event StunON "#*#You are stunned#*#"
#event StunON "#*#You lose control of yourself!#*#"
#event StunOFF "#*#You are unstunned#*#"
#event StunOFF "#*#You have control of yourself again.#*#"
#event LootMyCorpse "#*#LootMe#*#"
#event OOR "#*#Your target is too far away, get closer!#*#"
#event Miss "#*#You try to#*#but miss#*#"
#event Hit "#*#You#*#for#*#points of damage#*#"
|#include expreport.inc
Sub main
:setDeclares
/declare PCini outer
/declare NPCini outer
/declare MA_SB outer
/declare MobID outer
/declare CharX outer
/declare CharY outer
/declare MOBini outer
/declare MeleeAttack_1 outer
/declare MeleeAttack_2 outer
/declare MeleeAttack_3 outer
/declare MeleeDistance outer
/declare DefaultMeleeDistance outer
/declare TankToggle outer
/declare TargetOOR outer
:setGenericVars
/varset MA_SB NULL
/varset TankToggle NULL
/varset PCini stick-pc.ini
/varset NPCini stick-npc.ini
:NewCharacterCheck
/varset DefaultMeleeDistance ${Ini[${PCini},${Me.Name},DefaultMeleeDistance]}
/if (${DefaultMeleeDistance.Equal[NULL]}) /goto :NewCharacter
:setParams
/if (${Defined[Param0]}) {
/varset MeleeAttack_1 ${Param0}
} else {
/varset MeleeAttack_1 ${Ini[${PCini},${Me.Name},MeleeAttack_1]}
}
}
/if (${Defined[Param1]}) {
/varset MeleeAttack_2 ${Param1}
} else {
/varset MeleeAttack_2 ${Ini[${PCini},${Me.Name},MeleeAttack_2]}
}
}
/if (!${Defined[Param2]}) {
/varset MeleeAttack_3 ${Param2}
} else {
/varset MeleeAttack_3 ${Ini[${PCini},${Me.Name},MeleeAttack_3]}
}
}
:setINIvalues
/if (${OpenCorpse.Equal[NULL]}) /varset OpenCorpse ${Ini[${PCini},${Me.Name},OpenCorpse]}
/if (${MeleeAttack_1.Equal[NULL]}) /varset MeleeAttack_1 ${Ini[${PCini},${Me.Name},MeleeAttack_1]}
/if (${MeleeAttack_2.Equal[NULL]}) /varset MeleeAttack_2 ${Ini[${PCini},${Me.Name},MeleeAttack_2]}
/if (${MeleeAttack_3.Equal[NULL]}) /varset MeleeAttack_3 ${Ini[${PCini},${Me.Name},MeleeAttack_3]}
/varset DefaultMeleeDistance ${Ini[${PCini},${Me.Name},DefaultMeleeDistance]}
:StickBegin
|/echo Starting Experience Tracking
|/call StartExpTrack
/if (!${MeleeAttack_1.Equal[NONE]}) /echo Auto ${MeleeAttack_1} when available.
/if (!${MeleeAttack_2.Equal[NONE]}) /echo Auto ${MeleeAttack_2} when available.
/if (!${MeleeAttack_3.Equal[NONE]}) /echo Auto ${MeleeAttack_3} when available.
/goto :mainloop
:NewCharacter
/ini "${PCini}" ${Me.Name} DefaultMeleeDistance 13
/ini "${PCini}" ${Me.Name} MeleeAttack_1 NONE
/ini "${PCini}" ${Me.Name} MeleeAttack_2 NONE
/ini "${PCini}" ${Me.Name} MeleeAttack_3 NONE
/echo ${Me.Name} has been added to ${PCini}. Please re-run macro (also go edit ${PCini})
/endmacro
:mainloop
/if (${Me.Combat}) /call Attack
/doevents Invited
/doevents LootMyCorpse
/goto :mainloop
/endmacro
Sub attack
:attackCheck
/if (!${Target.Type.Equal["NPC"]}) {
/if (!${Target.Type.Equal["PET"]} && !${Target.Master.Type.Equal["NPC"]}) {
/echo Not an NPC or NPC pet!
/attack off
/return
}
}
/if (${Target.Distance}>250) {
/attack off
/echo Target too far: ${Target.Distance}
}
:attackSetup
/varset MobID ${Target.ID}
/echo ${Target.CleanName} [${Target.Level} ${Target.Class}] MaxRangeTo: ${Target.MaxRangeTo}
:attackPreFight
/call ClearReturn
/if (${Me.Pet.ID}) /pet attack
/varset MeleeDistance ${Target.MaxRangeTo}
/varset TargetOOR ${Bool[True]}
:attackMeleeLoop
/doevents RageOn
/doevents MobGate
/doevents StunON
/doevents OOR
/if (${Target.ID}!=${MobID} || ${Macro.Return.Equal["EndATK"]} || !${Me.Combat}) {
/goto :attackend
}
/if (${Target.ID}==${MobID} && !${Me.Casting.ID}) {
/if (!${Me.FeetWet}) {
/face fast nolook
} else /face fast
/if (${Target.Distance}>${MeleeDistance}) {
/keypress FORWARD HOLD
}
/if (${Target.Distance}<=${MeleeDistance}) {
/keypress FORWARD
/if (${TargetOOR}) {
/varcalc MeleeDistance ${MeleeDistance}-0.5
/delay 4
/echo DBG: MeleeDistance: [${MeleeDistance}]
/doevents Hit
/doevents Miss
}
/keypress FORWARD
}
/if (${Target.Distance}<=${Math.Calc[${MeleeDistance}-5]}) {
/keypress BACK HOLD
}
}
/if (!${Me.Casting.ID} && ${Target.Distance}<=${MeleeDistance} && ${Me.AbilityReady[${MeleeAttack_1}]}) {
/if (!${MeleeAttack_1.Equal[NONE]}) {
/doability ${MeleeAttack_1}
}
/if (!${MeleeAttack_2.Equal[NONE]}) {
/doability ${MeleeAttack_2}
}
/if (!${MeleeAttack_3.Equal[NONE]}) {
/doability ${MeleeAttack_3}
}
}
/goto :attackMeleeLoop
:attackend
/varset MobID 0
/attack off
/pet backoff
/pet hold
/keypress FORWARD
/return
Sub ClearReturn
/return NULL
Sub event_Hit
/varset TargetOOR ${Bool[NULL]}
/doevents flush OOR
/return
Sub event_Miss
/varset TargetOOR ${Bool[NULL]}
/doevents flush OOR
/return
Sub event_OOR
/varset TargetOOR ${Bool[True]}
/doevents flush Hit
/doevents flush Miss
/return
Sub event_RageOn
/if (${Target.CurrentHPs}>15) /return
/if (${Target.CurrentHPs}==0) /return
/if (${Target.ID}==${MobID}) /if (!${Me.Casting.ID}) /keypress FORWARD
/call ClearReturn
/popup MOB ENRAGE
/echo Rage On
/attack off
/pet back off
/pet hold
/call ClearReturn
:waitRage
/doevents
/if (${Target.ID}!=${MobID}) /return EndATK
/if (${Macro.Return.Equal["EndATK"]}) /return EndATK
/if (${Macro.Return.Equal["RageOFF"]}) /return
/goto :waitRage
Sub event_RageOFF
/echo Rage OFF
/popup MOB ENRAGE DONE
/attack on
/return RageOFF
Sub event_MobGate
/if (${Target.Distance}<100) /return
/echo MOB GATED!
/attack off
/return EndATK
Sub event_Invited
/delay 10
/invite
/return
Sub event_StunON
/doevents flush StunOFF
/call ClearReturn
:LoopStunOFF
/doevents StunOFF
/if (${Macro.Return.Equal["StunOFF"]}) {
/call ClearReturn
/return
}
/goto :LoopStunOFF
Sub event_StunOFF
/return StunOFF
Sub event_LootMyCorpse
/declare t int outer 0
/declare loottotal int outer
/declare lootslot int outer
/declare lootleft int outer 1
/echo "Looting My Corpse"
:corpsepull
/target mycorpse
/delay 5 ${Target.CleanName.Equal[${Me}'s corpse]}
/if (${Target.CleanName.NotEqual[${Me}'s corpse]}) {
/echo No corpse in this zone
/return
}
/delay 3s
/corpse
/delay 1s ${Target.Distance}<20
/if (${Target.Distance}>20) {
/echo Corpse is too far away
/return
}
/if (${Target.CleanName.Equal[${Me}'s corpse]}) {
/loot
}
/delay 5s ${Me.State.Equal[BIND]}
/if (${Me.State.NotEqual[BIND]}) /goto :corpsepull
/varset loottotal 0
:LootLag
/if (${loottotal}!=${Corpse.Items}) {
/varset loottotal ${Corpse.Items}
/delay 1s
/goto :LootLag
}
/if (${loottotal}<=${lootleft}) {
/echo Looting aborted. Error in number items to be left on corpse.
/notify LootWnd DoneButton leftmouseup
/return
}
/for lootslot 1 to ${loottotal}
:LootItem
/itemnotify loot${lootslot} rightmouseup
/delay 5 !${Corpse.Item[${lootslot}].ID}
/if (!${Corpse.Item[${lootslot}].ID}) {
/next lootslot
} else /goto :LootItem
/if (${Math.Calc[${Corpse.Items}-${lootleft}]}>0) /goto :LootLag
:DoneLooting
/notify LootWnd DoneButton leftmouseup
/echo Done looting.
/return