Documentation is posted here: http://www.sharemation.com/jerle69/eq/RHDocs.html
Jerele, if you take offense to my modifications, and or the link for the documentation to yruo original post, please let me know, and i will voluntarily remove this post. I was super impressed with yuor code, and sinply wanted to share my modifications with other monks, that may be in the same boat i am. This is simply me modifying a great thing, and in no way am i trying to take any credit for the code or work put into it.
I decided to convert this macro, simply because any of the other MONK ddesigned macro's didnt really suit my needs, or i feel was stable enough and had enough options etc etc.... I foudn this macro a while ago, and fell in love with it almost immediately (big time props Jerle).. and i actually used it for a while, unedited.
After a few changes here, a few changes there, a cut and past of snippets here and there, over time it evolved into this... not ALOT changed to it, but enough to make it in my eyes, a new monk macro.
The changes are simple.... for the most part, all the "backstab" code was changed to "fling Kick" code. I also added Celestial Fists code that i outright stole from, i think "monk.mac". That snippet clicks yoru fists for yuo automaticly, when there are no other blocking buffs (i added in OOW buffs that block it as well, or at least ones i am aware of).
My next "project" will be to add an autofd to it, for auto aggro avoidance... but dont expect that anytime soon, im an old old ODL time coder, back from basic days, so .. all be it i enjoy tinkering around with code, its still pretty difficult for me to try to code somethign from scratch, however i enjoy trying so expect it, just dont expect it soon. =)
Anywyas, heres the code.... only thing changed was rh.mac to mh.mac (rh.ini and all associated code etc etc is still named rh.ini)
*** CODE IS LISTED IN TWO POSTS - Board appearently cant hold the whole code in one post - ***
mh.mac
Code: Select all
|---------------------------------------------------------------------------------
|
| Monk Helper (MH) Macro
| by G&D (10/28/04)
| MODIFIED VERSION OF:
| Rogue Helper (RH) Macro
| - v6.0 by Jerle (10/26/04)
|
| ALL CREDIT of this macro goes to its proper Author, Jerle, I simply modified
| it slightly to work in the same respects for a monk. Adding Epic 1.0 Checks,
| changing backstabs to flying kicks, etc etc. All the rogue implementations (i.e.
| autotrap, autoevade, etc etc.) are still in the code, i might decide to remove them
| for performance issues, however on my machine i have no problems with
| performance and this macro.
| --My next project for converting RH to MH will be aggro avoidance - AutoFD
| --- G&D
|
| Documentation for MH is now separated from the macro proper. Please look for
| RHDocs.txt for syntax and use, or RHChangeLog.txt for the implementation
| change log.
|
|---------------------------------------------------------------------------------
|
| RH Syntax:
|
| Usage: /mac mh
|
| Default settings can be changed by their respective controlling /command
|
| Type /rhhelp for help or /status to see current settings!
|
|---------------------------------------------------------------------------------
#Chat tell
#Event StrikeVic "#*#Seeking a Victim#*#"
#Event AttackOn "#*#Auto attack is on#*#"
#Event AttackOff "#*#Auto attack is off#*#"
#Event Enraged "#*#|${Target.CleanName}| has become ENRAGED#*#"
#Event NLEnraged "#*#|${Target.CleanName}| is no longer enraged#*#"
#Event TooFarAway "#*#Your target is too far away, get closer#*#"
#Event Exp "#*#You gain#*#experience#*#"
#Event Slain "#*# slain#*#"
#Event Zoned "#*#You have entered#*#"
#Event GotHit "#1#YOU for#*#points of damage."
#Event GotMissed "#1#to#*#YOU, but #*#"
#Event SpellBounced "#*#Your spell did not take hold#*#"
#Event SwitchWeapon "#*#|${switchtext}|#*#"
#Event FTrap "#*#You sense a trap in this direction."
#Event BTrap "#*#You are certain that #*#"
#Event TogEvade "[MQ2] Autoevade#*#"
#Event TogPick "[MQ2] Autopick#*#"
#Event TogStick "[MQ2] Autostick#*#"
#Event TogHS "[MQ2] Auto Hide & Sneak#*#"
#Event TogLeash "[MQ2] Leash#*#"
#Event TogAuto "[MQ2] Autoassist#*#"
#Event TogDynaggro "[MQ2] Dynaggro#*#"
#Event TogPause "[MQ2] Pause#*#"
#Event TogTSwitch "[MQ2] AutoTargetSwitch#*#"
#Event TogTraps "[MQ2] AutoTraps#*#"
#Event TogDynclose "[MQ2] Dynclose#*#"
#Event LinkParse "[MQ2] LinkParse#*#"
#Event SetStopFighting "[MQ2] SetStopFighting#*#"
#Event SetEndFloor "[MQ2] SetEndFloor#*#"
#Event SetStrikeDisc "[MQ2] SetStrikeDisc#*#"
#Event SetCloseness "[MQ2] SetCloseness#*#"
#Event SetFirstassist "[MQ2] SetMainassist#*#"
#Event SetSecondassist "[MQ2] SetSecondassist#*#"
#Event SetThirdassist "[MQ2] SetThirdassist#*#"
#Event SetAutoNinja "[MQ2] SetAutoNinja#*#"
#Event SetWeaponSwitch "[MQ2] SetWeaponSwitch#*#"
#Event SetStickDist "[MQ2] SetStickDist#*#"
#Event SetChicken "[MQ2] SetChicken#*#"
#Event SetDisc1 "[MQ2] SetDisc1#*#"
#Event SetDisc2 "[MQ2] SetDisc2#*#"
#Event SetLeashFlex "[MQ2] SetLeashFlex#*#"
#Event SetVerbosity "[MQ2] SetVerbosity#*#"
#Event SetChannel "[MQ2] SetChannel#*#"
#Event DragBodies "[MQ2] DragBodies#*#"
#Event LootMyCorpse "[MQ2] LootMyCorpse#*#"
#Event AutoFollow "[MQ2] AutoFollow#*#"
#Event AddMaster "[MQ2] AddMaster#*#"
#Event RemMaster "[MQ2] RemoveMaster#*#"
#Event ItemSet "[MQ2] ItemSet#*#"
#Event ItemBounce "[MQ2] ItemBounce#*#"
#Event ItemCast "[MQ2] ItemCast#*#"
#Event HelpInfo "[MQ2] RH Help#*#"
#Event StatInfo "[MQ2] RH Status#*#"
Sub Main
/echo Loading Rogue Helper... Please Wait!
/declare doEvade bool outer TRUE
/declare StopFightingHealth int outer 30
/declare StrikeSkill string outer Assassin
/declare MinEndurance int outer 80
/declare isEnraged bool outer FALSE
/declare strikeReady bool outer FALSE
/declare strikeTimer timer outer 0
/declare LDExp float outer ${Me.PctGroupLeaderExp}
/declare AAExp float outer ${Me.PctAAExp}
/declare Exp float outer ${Me.PctExp}
/declare doStick bool outer TRUE
/declare X float outer
/declare Y float outer
/declare behindTarget bool outer FALSE
/declare i int outer
/declare dir int outer
/declare delta int outer
/declare strafedir string outer
/declare closeness int outer 70
/declare doHideSneak bool outer TRUE
/declare doLeash bool outer FALSE
/declare leashlength int outer 0
/declare stakeX int outer ${Me.X}
/declare stakeY int outer ${Me.Y}
/declare leashholder string outer Nobody
/declare doAutoassist bool outer FALSE
/declare mainassist string outer Nobody
/declare firstassist string outer Nobody
/declare secondassist string outer Nobody
/declare thirdassist string outer Nobody
/declare assistpct int outer 98
/declare oldtargetID int outer ${Target.ID}
/declare assisttimer timer outer 0
/declare doDynaggro bool outer FALSE
/declare gotHit bool outer FALSE
/declare aggrotimer timer outer 0
/declare ialias string outer None
/declare doIclick bool outer FALSE
/declare bouncenum int outer 1
/declare ibounce string outer None
/declare itemspellname string outer None
/declare clicktimer timer outer 0
/declare isPaused bool outer FALSE
/declare ninjamode string outer OFF
/declare ninjadist int outer 50
/declare doPick bool outer FALSE
/declare doSwitch bool outer FALSE
/declare switchtext string outer +Undefined+
/declare weapon1 string outer None
/declare weapon2 string outer None
/declare wstype string outer Detrimental
/declare doTSwitch bool outer TRUE
/declare lastevent string outer None
/declare rngtarget int outer 200
/declare rngtank int outer 100
/declare useMU bool outer FALSE
/declare doTraps bool outer FALSE
/declare oldheading string outer Default
/declare doChicken bool outer FALSE
/declare nimblehealth int outer 20
/declare doEscape bool outer FALSE
/declare nimbletimer timer outer 0
/declare nimbleactive timer outer 0
/declare chickentimer timer outer 0
/declare doDisc1 bool outer FALSE
/declare disc1 string outer Deadly Precision
/declare disc1end int outer 60
/declare disc1reuse int outer 5
/declare disc1reusetimer timer outer 0
/declare doDisc2 bool outer FALSE
/declare disc2 string outer Kinesthetics
/declare disc2end int outer 60
/declare disc2reuse int outer 5
/declare disc2reusetimer timer outer 0
/declare discactive timer outer 0
/declare leashflex int outer 10
/declare doDynclose bool outer TRUE
/declare closenessdesired int outer 70
/declare acquiretimer timer outer 0
/declare snuggleup bool outer FALSE
/declare isTanking bool outer FALSE
/declare verbosity int outer 2
/declare channel string outer echo
/declare rhversion string outer 6.0
/goto :BypassVCheck
|- Check versions and load aliases if necessary
/if (${Ini[RHSettings.ini,General,Version].Equal[${rhversion}]}) /goto :EndAlias
:BypassVCheck
/if (${verbosity}>=0) /${channel} Setting Aliases...
/squelch /alias /status /echo RH Status
/squelch /alias /rhhelp /echo RH Help
/squelch /alias /autoevade /echo Autoevade
/squelch /alias /autopick /echo Autopick
/squelch /alias /stopfight /echo SetStopFighting
/squelch /alias /strikedisc /echo SetStrikeDisc
/squelch /alias /endfloor /echo SetEndFloor
/squelch /alias /autostick /echo Autostick
/squelch /alias /autohs /echo Auto Hide & Sneak
/squelch /alias /leash /echo Leash
/squelch /alias /autoassist /echo Autoassist
/squelch /alias /dynaggro /echo Dynaggro
/squelch /alias /closeness /echo SetCloseness
/squelch /alias /mainassist /echo SetMainassist
/squelch /alias /secondassist /echo SetSecondassist
/squelch /alias /thirdassist /echo SetThirdassist
/squelch /alias /drag /echo DragBodies
/squelch /alias /lootmycorpse /echo LootMyCorpse
/squelch /alias /autofollow /echo AutoFollow
/squelch /alias /iset /echo ItemSet
/squelch /alias /ibounce /echo ItemBounce
/squelch /alias /iclick /echo ItemCast
/squelch /alias /pause /echo Pause
/squelch /alias /autoninja /echo SetAutoNinja
/squelch /alias /addmaster /echo AddMaster
/squelch /alias /remmaster /echo RemoveMaster
/squelch /alias /weaponswitch /echo SetWeaponSwitch
/squelch /alias /targetswitch /echo AutoTargetSwitch
/squelch /alias /stickdist /echo SetStickDist
/squelch /alias /autotraps /echo AutoTraps
/squelch /alias /autochicken /echo SetChicken
/squelch /alias /autodisc1 /echo SetDisc1
/squelch /alias /autodisc2 /echo SetDisc2
/squelch /alias /leashflex /echo SetLeashFlex
/squelch /alias /verbosity /echo SetVerbosity
/squelch /alias /channel /echo SetChannel
/squelch /alias /dynclose /echo Dynclose
/squelch /alias /lp /echo LinkParse
:EndAlias
|-- Update the Version information
/ini "RHSettings.ini" "General" "Version" "${rhversion}"
|-- Read in INI settings, if defined... Leashing is only stored TRUE if there is a Leash-holding Master!
/if (${Ini[RHSettings.ini,General,AutoEvade].NotEqual[NULL]}) /varset doEvade
${Ini[RHSettings.ini,General,AutoEvade]}
/if (${Ini[RHSettings.ini,General,StopFightingHealth].NotEqual[NULL]}) /varset StopFightingHealth
${Ini[RHSettings.ini,General,StopFightingHealth]}
/if (${Ini[RHSettings.ini,General,StrikeSkill].NotEqual[NULL]}) /varset StrikeSkill
${Ini[RHSettings.ini,General,StrikeSkill]}
/if (${Ini[RHSettings.ini,General,MinEndurance].NotEqual[NULL]}) /varset MinEndurance
${Ini[RHSettings.ini,General,MinEndurance]}
/if (${Ini[RHSettings.ini,General,AutoStick].NotEqual[NULL]}) /varset doStick
${Ini[RHSettings.ini,General,AutoStick]}
/if (${Ini[RHSettings.ini,General,Closeness].NotEqual[NULL]}) /varset closeness
${Ini[RHSettings.ini,General,Closeness]}
/if (${Ini[RHSettings.ini,General,AutoHideSneak].NotEqual[NULL]}) /varset doHideSneak
${Ini[RHSettings.ini,General,AutoHideSneak]}
/if (${Ini[RHSettings.ini,General,Leashing].NotEqual[NULL]}) /varset doLeash
${Ini[RHSettings.ini,General,Leashing]}
/if (${Ini[RHSettings.ini,General,LeashHolder].NotEqual[NULL]}) /varset leashholder
${Ini[RHSettings.ini,General,LeashHolder]}
/if (${Ini[RHSettings.ini,General,LeashLength].NotEqual[NULL]}) /varset leashlength
${Ini[RHSettings.ini,General,LeashLength]}
/if (${Ini[RHSettings.ini,General,LeashFlex].NotEqual[NULL]}) /varset leashflex
${Ini[RHSettings.ini,General,LeashFlex]}
/if (${Ini[RHSettings.ini,General,AutoAssist].NotEqual[NULL]}) /varset doAutoassist
${Ini[RHSettings.ini,General,AutoAssist]}
/if (${Ini[RHSettings.ini,General,AssistPercentage].NotEqual[NULL]}) /varset assistpct
${Ini[RHSettings.ini,General,AssistPercentage]}
/if (${Ini[RHSettings.ini,General,MainAssist].NotEqual[NULL]}) /varset mainassist
${Ini[RHSettings.ini,General,MainAssist]}
/if (${Ini[RHSettings.ini,General,MainAssist].NotEqual[NULL]}) /varset firstassist
${Ini[RHSettings.ini,General,MainAssist]}
/if (${Ini[RHSettings.ini,General,SecondAssist].NotEqual[NULL]}) /varset secondassist
${Ini[RHSettings.ini,General,SecondAssist]}
/if (${Ini[RHSettings.ini,General,ThirdAssist].NotEqual[NULL]}) /varset thirdassist
${Ini[RHSettings.ini,General,ThirdAssist]}
/if (${Ini[RHSettings.ini,General,DynamicAggro].NotEqual[NULL]}) /varset doDynaggro
${Ini[RHSettings.ini,General,DynamicAggro]}
/if (${Ini[RHSettings.ini,General,AutoNinjaMode].NotEqual[NULL]}) /varset ninjamode
${Ini[RHSettings.ini,General,AutoNinjaMode]}
/if (${Ini[RHSettings.ini,General,AutoNinjaDistance].NotEqual[NULL]}) /varset ninjadist
${Ini[RHSettings.ini,General,AutoNinjaDistance]}
/if (${Ini[RHSettings.ini,General,AutoPickPocket].NotEqual[NULL]}) /varset doPick
${Ini[RHSettings.ini,General,AutoPickPocket]}
/if (${Ini[RHSettings.ini,General,WeaponSwitching].NotEqual[NULL]}) /varset doSwitch
${Ini[RHSettings.ini,General,WeaponSwitching]}
/if (${Ini[RHSettings.ini,General,TargetSwitching].NotEqual[NULL]}) /varset doTSwitch
${Ini[RHSettings.ini,General,TargetSwitching]}
/if (${Ini[RHSettings.ini,General,StickRangeToTarget].NotEqual[NULL]}) /varset rngtarget
${Ini[RHSettings.ini,General,StickRangeToTarget]}
/if (${Ini[RHSettings.ini,General,StickRangeToTank].NotEqual[NULL]}) /varset rngtank
${Ini[RHSettings.ini,General,StickRangeToTank]}
/if (${Ini[RHSettings.ini,General,TrapNegotiation].NotEqual[NULL]}) /varset doTraps
${Ini[RHSettings.ini,General,TrapNegotiation]}
/if (${Ini[RHSettings.ini,General,AutoChicken].NotEqual[NULL]}) /varset doChicken
${Ini[RHSettings.ini,General,AutoChicken]}
/if (${Ini[RHSettings.ini,General,NimbleHealth].NotEqual[NULL]}) /varset nimblehealth
${Ini[RHSettings.ini,General,NimbleHealth]}
/if (${Ini[RHSettings.ini,General,ContingencyEscape].NotEqual[NULL]}) /varset doEscape
${Ini[RHSettings.ini,General,ContingencyEscape]}
/if (${Ini[RHSettings.ini,General,AutoDisc1].NotEqual[NULL]}) /varset doDisc1
${Ini[RHSettings.ini,General,AutoDisc1]}
/if (${Ini[RHSettings.ini,General,Disc1].NotEqual[NULL]}) /varset disc1
${Ini[RHSettings.ini,General,Disc1]}
/if (${Ini[RHSettings.ini,General,Disc1Endurance].NotEqual[NULL]}) /varset disc1end
${Ini[RHSettings.ini,General,Disc1Endurance]}
/if (${Ini[RHSettings.ini,General,Disc1Reuse].NotEqual[NULL]}) /varset disc1reuse
${Ini[RHSettings.ini,General,Disc1Reuse]}
/if (${Ini[RHSettings.ini,General,AutoDisc2].NotEqual[NULL]}) /varset doDisc2
${Ini[RHSettings.ini,General,AutoDisc2]}
/if (${Ini[RHSettings.ini,General,Disc2].NotEqual[NULL]}) /varset disc2
${Ini[RHSettings.ini,General,Disc2]}
/if (${Ini[RHSettings.ini,General,Disc2Endurance].NotEqual[NULL]}) /varset disc2end
${Ini[RHSettings.ini,General,Disc2Endurance]}
/if (${Ini[RHSettings.ini,General,Disc2Reuse].NotEqual[NULL]}) /varset disc2reuse
${Ini[RHSettings.ini,General,Disc2Reuse]}
/if (${Ini[RHSettings.ini,General,DynamicCloseness].NotEqual[NULL]}) /varset dynclose
${Ini[RHSettings.ini,General,DynamicCloseness]}
/if (${Ini[RHSettings.ini,General,Verbosity].NotEqual[NULL]}) /varset verbosity
${Ini[RHSettings.ini,General,Verbosity]}
/if (${Ini[RHSettings.ini,General,Channel].NotEqual[NULL]}) /varset channel
${Ini[RHSettings.ini,General,Channel]}
/if (${Ini[RHSettings.ini,Weapons,Weapon1].NotEqual[NULL]}) /varset weapon1
${Ini[RHSettings.ini,Weapons,Weapon1]}
/if (${Ini[RHSettings.ini,Weapons,Weapon2].NotEqual[NULL]}) /varset weapon2
${Ini[RHSettings.ini,Weapons,Weapon2]}
/if (${Ini[RHSettings.ini,Weapons,SwitchText].NotEqual[NULL]}) /varset switchtext
${Ini[RHSettings.ini,Weapons,SwitchText]}
/varset closenessdesired ${closeness}
/varset wstype ${FindItem[${weapon1}].Spell.SpellType}
|- Build Empty master list in RHSettings.ini file if it doesn't exist
/if (!${Ini[RHSettings.ini,Masters,Controller1].Length}) {
|- It's not in there yet
/for i 1 to 20
/ini "RHSettings.ini" "Masters" "Controller${i}" "Nobody"
/next i
}
/echo =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/echo Jerle's Rogue Helper Macro (v${rhversion}) Starting...
/echo =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/echo Use "/rhhelp" to display help information
/echo RH Status
:ForeverLoop
|- Service any events
/doevents
|- If we're stunned or RH is paused, just service events
/if (${Me.State.Equal[STUN]} || ${isPaused}) {
/delay 2
/goto :ForeverLoop
}
|- While fighting or not fighting...
|- Turn attacking back on if enraged target, and no longer facing it
/if (${isEnraged} && ${Target.ID} && ${doAutoassist} && !${Me.Combat}) {
/call Check_Behind
/varset behindTarget ${Macro.Return}
/if (${Target.ID} && ${behindTarget}) {
/attack on
/if (${verbosity}>=1) /${channel} ** Attack re-started (No Enrage Risk): ${Target.CleanName}
}
}
|- Check if we should chicken out
/if (${doChicken} && (${Me.PctHPs}<=${nimblehealth}) && !${chickentimer}) {
/if (${verbosity}>=1) /${channel} Autochicken to the rescue!
/if (!${nimbletimer}) {
/disc nimble
/if (${verbosity}>=1) /${channel} Nimble mode activated!
/varset nimbletimer 21m
/varset nimbleactive 12s
} else /if (${Me.AltAbilityReady[Escape]} && !${nimbleactive}) {
/if (${verbosity}>=1) /${channel} Contingency Escape activated! (Nimble expired/unavailable)
/attack off
/alt activate 102
/varset chickentimer 30s
} else {
/if (${verbosity}>=1) /${channel} ... or not! Can't escape, can't nimble... Farewell!
/varset chickentimer 2m
}
}
|- Stop fighting if we lose our target
/if (${Me.Combat} && !${Target.ID}) /attack off
|- Are we suposed to stick to a target?
/if ((${Me.Combat} || ${strikeReady}) && ${Target.ID} && ${doStick} &&
(${Target.Distance}<${rngtarget}) && ${Target.Type.Equal[NPC]}) {
|- Check to see if we're too far from our tank (if applicable)
/if (${doAutoassist} && (${Spawn[${mainassist}].Distance}>${rngtank})) {
/if (${useMU} && ${Stick.Status.Equal[ON]}) /squelch /stick off
/goto :DoneSticking
}
|- Check to see if we're mounted and dismount if so
/if (${Me.Buff[Summon Drogmor].ID} || ${Me.Buff[Summon Horse].ID}) /dismount
|- Use MQ2MoveUtils ? If so, start sticking and bypass RH movement tools
/if (${useMU}) {
/varset isTanking FALSE
/if (${aggrotimer.Value} || ${Me.TargetOfTarget.Name.Equal[${Me}]}) /varset isTanking TRUE
/if (!${Stick.Status.Equal[ON]} || ${snuggleup}) {
/if (${isTanking}) {
/squelch /stick ${closeness}% mpause ${If[${Me.Swimming},uw,]}
} else {
/squelch /stick ${closeness}% behind mpause ${If[${Me.Swimming},uw,]}
}
/varset snuggleup FALSE
} else {
/if (${Stick.MoveBehind}) {
/if (${isTanking}) {
/squelch /stick off
/if (${verbosity}>=2) /${channel} Switched to frontal sticking...
}
} else {
/if (!${isTanking}) {
/squelch /stick off
/if (${verbosity}>=2) /${channel} Maneuvering behind target again...
}
}
}
/goto :DoneSticking
}
/if (${Target.ID}) /face ${If[${Me.Swimming},,nolook]}
|- If we're too far away to hit it, get 1 second closer, unless we can hit it in less time
/if (${Target.Distance}>${Math.Calc[${Target.MaxRangeTo}*${closeness}/100]}) {
|- Set current position first before potentially moving (in case we get stuck)
/varset X ${Me.X}
/varset Y ${Me.Y}
/if (!${Target.ID}) /goto :Foreverloop
|- Move
/keypress forward hold
/delay 1s ${Target.Distance}<${Math.Calc[${Target.MaxRangeTo}*${closeness}/100]}
/keypress forward
|- Check to see if we got stuck trying that
/if ((${Me.X}==${X}) && (${Me.Y}==${Y})) {
|- We're stuck, back off a second, move left or right (randomly) for .5 seconds
/if (${verbosity}>=2) /${channel} We're STUCK on something, backing up...
/keypress back hold
/delay 1s
/keypress back
/if (${Math.Rand[2]}) {
/varset strafedir STRAFE_LEFT
} else {
/varset strafedir STRAFE_RIGHT
}
/if (${verbosity}>=2) /${channel} Unsticking: Strafing ${strafedir} a half-second...
/keypress ${strafedir} hold
/delay 5
/keypress ${strafedir}
}
}
/if (!${Target.ID}) /goto :Foreverloop
|- If we are close enough to hit it (and don't have aggro), lets try to get behind it a little bit at a time
/if ((${Target.Distance}<=${Target.MaxRangeTo}) && !${aggrotimer.Value} &&
!${Me.TargetOfTarget.Name.Equal[${Me}]}) {
/call Check_Behind
/varset behindTarget ${Macro.Return}
|- If we're not behind it, strafe around it a little
/if (!${behindTarget}) {
|- Which way do we strafe?
/varcalc delta ${Me.Heading.Clock}-${Target.Heading.Clock}
/if (${delta}>6) /varcalc delta ${delta}-12
/if (${delta}<-6) /varcalc delta ${delta}+12
/if (${delta}<0) {
/varset strafedir STRAFE_LEFT
} else {
/varset strafedir STRAFE_RIGHT
}
|- Set current position first before moving (in case we get stuck)
/varset X ${Me.X}
/varset Y ${Me.Y}
/if (!${Target.ID}) /goto :Foreverloop
|- Execute a strafe in the correct direction
/keypress ${strafedir} hold
/delay 2
/keypress ${strafedir}
/if (${Target.ID}) /face fast ${If[${Me.Swimming},,nolook]}
|- Check if we're stuck and warn if so (go through target to fix it)
/if ((${Me.X}==${X}) && (${Me.Y}==${Y})) {
/if (${verbosity}>=2) /${channel} We're STUCK trying to get behind target!
/delay 1s
}
}
}
} else {
/if (${useMU} && ${Stick.Status.Equal[ON]}) /squelch /stick off
}
:DoneSticking
|- Check on switching weapons (assuming it's a buff-weapon and buff is down)
/if (${doSwitch} && ${wstype.Equal[Beneficial]}) {
/varset itemspellname ${FindItem[${weapon1}].Spell}
/if (${itemspellname.NotEqual[${Me.Buff[${itemspellname}]}]} &&
!${FindItem[${weapon1}].InvSlot.Name.Equal[mainhand]} &&
!${FindItem[${weapon1}].InvSlot.Name.Equal[offhand]}) {
/if (${verbosity}>=1) /${channel} ** Beneficial proc-weapon swapping...
/call Weapon_Swap "${weapon1}" "${weapon2}"
}
}
|- Are we fighting?
/if (${Me.Combat}) {
|- ** We are fighting **
|- Respond to enraged targets
/if (${isEnraged} && ${Target.ID}) {
/call Check_Behind
/varset behindTarget ${Macro.Return}
/if (${Target.ID} && !${behindTarget}) {
/attack off
/if (${verbosity}>=1) /${channel} ** Attack ceased (Enrage Risk): ${Target.CleanName}
}
}
|- If we're sneaking, stop... since it serves no purpose and affects strafing
/if (${Me.Sneaking}) /doability "Sneak"
|- Check up on our autoassist targets if applicable, and switch if MA switches (1 second checks)
/if (${doTSwitch} && ${doAutoassist} && ${Target.ID} && !${assisttimer}) {
/varset oldtargetID ${Target.ID}
/assist ${mainassist}
/varset assisttimer 1s
}
|- Did we just switch targets? If so, turn off attack and start the loop over!
/if (${doAutoassist} && ${Target.ID}!=${oldtargetID}) {
/if (${verbosity}>=1) /${channel} --> *SWITCH* target to: ${Target.CleanName}
/varset oldtargetID ${Target.ID}
/attack off
/delay 2
/varset assisttimer 1s
/goto :ForeverLoop
}
|- Check for leash tugging and move back to stake some if so
/if (${doLeash}) {
/if (${leashholder.Equal[Nobody]} &&
(${Math.Distance[${Me.Y},${Me.X}:${stakeY},${stakeX}]}>${leashlength})) {
/if (${verbosity}>=2) /${channel} CHOKE! We're at the leash's length! (${leashlength} ft.)
/if (${verbosity}>=1) /${channel} ** Autoassist is now OFF!
/varset doAutoassist FALSE
/attack off
/if (${useMU}) /squelch /stick off
/face ${If[${Me.Swimming},,nolook]} loc ${stakeY},${stakeX}
/keypress forward hold
/delay 1s
${Math.Distance[${Me.Y},${Me.X}:${stakeY},${stakeX}]}<${Math.Calc[${leashlength}*${leashflex}/100]}
/keypress forward
|- Slow 180degree turns take time, and we may have turned off attack, so...
/goto :ForeverLoop
}
/if (!${leashholder.Equal[Nobody]} && ${Spawn[${leashholder}].ID} &&
(${Spawn[${leashholder}].Distance}>${leashlength})) {
/if (${verbosity}>=2) /${channel} CHOKE! Tugging on ${leashholder}'s leash! (${leashlength} ft.)
/if (${verbosity}>=1) /${channel} ** Autoassist is now OFF!
/varset doAutoassist FALSE
/attack off
/if (${useMU}) /squelch /stick off
/squelch /face ${If[${Me.Swimming},,nolook]} id ${Spawn[${leashholder}].ID}
/keypress forward hold
/delay 1s ${Spawn[${leashholder}].Distance}<${Math.Calc[${leashlength}*${leashflex}/100]}
/keypress forward
|- Slow 180degree turns take time, and we may have turned off attack, so...
/goto :ForeverLoop
}
|- Broken leash check
/if (!${leashholder.Equal[Nobody]} && !${Spawn[${leashholder}].ID}) {
/if (${verbosity}>=1) /${channel} ** Master DEAD or ZONED! Leash is BROKEN!
/varset doLeash FALSE
/varset leashholder Nobody
/ini "RHSettings.ini" "General" "Leashing" "${doLeash}"
/ini "RHSettings.ini" "General" "LeashHolder" "${leashholder}"
/goto :ForeverLoop
}
}
|- Are we standing, have a target, have backstab ready and can we stick it in the back?
/call Check_Behind
/varset behindTarget ${Macro.Return}
/if (${Target.ID} && ${Me.Standing} && !${Me.Casting.ID} && ${behindTarget} &&
(${Target.Distance}<${Math.Calc[${Target.MaxRangeTo}*${closeness}/100]})) {
/if (${Me.AbilityReady["Flying Kick"]}) {
/doability "Flying Kick"
/if (${verbosity}>=2) /${channel} Flying Kicking: ${Target.CleanName}
/if (!${Me.Buff[Celestial Tranquility].ID} && !${Me.Buff[Speed of Vallon].ID} && !${Me.Buff[Speed
of Salik].ID} && !${Me.Buff[Spiritual Vigor].ID} && !${Me.Buff[Strength of Tunare].ID} &&
!${Me.Buff[Vallon's Quickening].ID} && !${Me.Buff[Salik's Quickening].ID}) /cast item "Celestial Fists"
}
}
|- Are we tanking? If so, just stab it in the face if we can!
/if (${Target.ID} && ${Me.Standing} && !${Me.Casting.ID} && (${aggrotimer.Value} ||
${Me.TargetOfTarget.Name.Equal[${Me}]})) {
/if (${Me.AbilityReady["Flying Kick"]}) {
/doability "Flying Kick"
/if (!${Me.Buff[Celestial Tranquility].ID} && !${Me.Buff[Speed of Vallon].ID} && !${Me.Buff[Speed
of Salik].ID} && !${Me.Buff[Spiritual Vigor].ID} && !${Me.Buff[Strength of Tunare].ID} &&
!${Me.Buff[Vallon's Quickening].ID} && !${Me.Buff[Salik's Quickening].ID}) /cast item "Celestial Fists"
/if (${verbosity}>=1) /${channel} Tanking -> : ${Target.CleanName}
}
}
|- Can we evade? Should we?
/if (${doEvade} && ${Target.ID} && !${Me.Casting.ID} && ${Me.AbilityReady["Hide"]} &&
(!${Me.Moving} || ${Me.AltAbilityReady[Nimble Evasion]})) {
/if (${verbosity}>=2) /${channel} Evading ${Target.CleanName}
/attack off
/delay 1
/doability "Hide"
/attack on
}
|- What's it got in it's pocketses?
/if (${doPick} && ${Target.ID} && !${Me.Casting.ID} && (${Target.Distance}<15) &&
${Me.AbilityReady["Pick Pockets"]}) {
/if (${verbosity}>=2) /${channel} Pick-pocketing ${Target.CleanName}
/attack off
/delay 1
/doability "Pick Pockets"
/attack on
/delay 1
/if (${Cursor.ID}) /autoinv
}
|- Are we so hurt we should stop fighting for a bit?
|
| /if (${Me.PctHPs}<=${StopFightingHealth}) {
| /attack off
| /if (${verbosity}>=1) /${channel} Getting my ass kicked, ceasing combat!
| }
|
|- Shall we do our optional discs?
/if (${doDisc1} && !${disc1reusetimer} && !${discactive} && !${strikeTimer} && ${Target.ID} &&
${Target.PctHPs}>=50 && ${Me.PctEndurance}>=${disc1end}) {
/disc ${disc1}
/if (${verbosity}>=1) /${channel} Disc #1: ${disc1} activated
/delay 1s
/varset discactive 1m
/varset disc1reusetimer ${disc1reuse}m
}
/if (${doDisc2} && !${disc2reusetimer} && !${discactive} && !${strikeTimer} && ${Target.ID} &&
${Target.PctHPs}>=50 && ${Me.PctEndurance}>=${disc2end}) {
/disc ${disc2}
/if (${verbosity}>=1) /${channel} Disc #2: ${disc2} activated
/delay 1s
/varset discactive 1m
/varset disc2reusetimer ${disc2reuse}m
}
} else {
|- ** We are not fighting
|- If we're not hiding or moving, check clicky maintained spells
/if (${Me.Invis} || ${Me.Moving} || ${clicktimer} || ${Me.State.Equal[BIND]}) /goto :DoneItemChecks
/varset i 1
:ItemCheckLoop
/varset ialias ${Ini[RHItems.ini].Arg[${i},|]}
/if (${ialias.NotEqual[NULL]}) {
|- Obtained an itemalias from the RHItems.ini file
|- We supposed to keep this spell up?
/if (${Ini[RHItems.ini,${ialias},KeepUp].Equal[FALSE]}) /goto :NextItem
|- Scan the item's bounce list for the active bouncers
/varset bouncenum 1
/varset doIclick TRUE
:BounceCheckLoop
/varset ibounce ${Ini[RHItems.ini,${ialias},BounceOff${bouncenum}]}
/if (${ibounce.NotEqual[NULL]}) {
/if (${ibounce.Equal[${Me.Buff[${ibounce}]}]}) /varset doIclick FALSE
} else /goto :DoneBounceChecks
/varcalc bouncenum ${bouncenum}+1
/goto :BounceCheckLoop
:DoneBounceChecks
|- By now we won't click the item if a bouncer spell is on us
|- Just have to check to see if the existing buff is on too
/varset itemspellname ${FindItem[${Ini[RHItems.ini,${ialias},FullName]}].Spell}
/if (${itemspellname.Equal[${Me.Buff[${itemspellname}]}]}) /varset doIclick FALSE
|- Finally, do it if we should
/if (${doIclick}) /docommand /iclick ${ialias}
|- Did we fail to find that previous item? (i.e. Dead and naked at bind point!)
/if (${clicktimer}) /goto :DoneItemChecks
:NextItem
/varcalc i ${i}+1
} else /goto :DoneItemChecks
/goto :ItemCheckLoop
:DoneItemChecks
|- Put the closeness value back to the user's desired setting...
/varset closeness ${closenessdesired}
|- Lets hide and sneak if not already and we're set to do so **
/if (${doHideSneak} && ${Me.AbilityReady["Sneak"]} && !${Me.Casting.ID} &&
${Me.State.NotEqual[BIND]} && !${Window[TradeWnd].Open} && !${Window[MerchantWnd].Open} &&
!${Window[BigBankWnd].Open}) /doability "Sneak"
/if (${doHideSneak} && ${Me.AbilityReady["Hide"]} && !${Me.Casting.ID} && ${Me.Sneaking} &&
(!${Me.Moving} || ${Me.AltAbilityReady[Nimble Evasion]}) && ${Me.State.NotEqual[BIND]} &&
!${Window[TradeWnd].Open} && !${Window[MerchantWnd].Open} && !${Window[BigBankWnd].Open})
/doability "Hide"
|- It's possible we're poised for a Strike, check and fight if so
/call Check_Behind
/varset behindTarget ${Macro.Return}
/if (${Target.ID} && ${Target.Type.Equal[NPC]} && ${Me.Standing} && ${Me.State.NotEqual[BIND]}
&& !${Me.Casting.ID} && ${behindTarget}) {
/if (${strikeReady} && ${Me.AbilityReady["Flying Kick"]}) {
/doability "Flying Kick"
/if (${verbosity}>=1) /${channel} Executing a strike: ${Target.CleanName}
/varset strikeReady FALSE
/attack on
}
}
|- It's also possible we never got behind a target and strike expired!
/if (${strikeReady} && ${Target.ID} && !${strikeTimer.Value} && ${Target.Type.Equal[NPC]}) {
/if (${verbosity}>=2) /${channel} Didn't find the back of a target in 30 seconds!
/varset strikeReady FALSE
/attack on
}
|- If we're set to autoassist, lets find a target
/if (${doAutoassist} && !${isEnraged} && !${Me.Casting.ID} && ${Me.State.NotEqual[BIND]}) {
|- Is main assist alive/in-zone?
/if (!${assisttimer} && !${strikeReady}) {
|- Lets try all the assists in priority order until we get an NPC to whack on
/if (!${Me.Casting.ID}) /assist ${firstassist}
/delay 1
/if (${Target.ID} && ${Target.Type.Equal[NPC]}) /goto :EngageCheck
/if (!${Me.Casting.ID}) /assist ${secondassist}
/delay 1
/if (${Target.ID} && ${Target.Type.Equal[NPC]}) /goto :EngageCheck
/if (!${Me.Casting.ID}) /assist ${thirdassist}
/delay 1
/if (${Target.ID} && ${Target.Type.Equal[NPC]}) /goto :EngageCheck
|- If we got here and don't have a target, tanks are invalid or no fighting is going on
/goto :EndAutoassist
:EngageCheck
/varset oldtargetID ${Target.ID}
/varset assisttimer ${Math.Calc[10+${Math.Rand[5]}].Int}
|- Who is the valid tank?
/if (${firstassist.Equal[Main]} || (${Math.Distance[${Target.Y},${Target.X}:${Spawn[pc
${firstassist}].Y},${Spawn[pc ${firstassist}].X}]}<${Target.MaxRangeTo})) {
/varset mainassist ${firstassist}
/goto :LastAttackCheck
}
/if (${secondassist.Equal[Main]} || (${Math.Distance[${Target.Y},${Target.X}:${Spawn[pc
${secondassist}].Y},${Spawn[pc ${secondassist}].X}]}<${Target.MaxRangeTo})) {
/varset mainassist ${secondassist}
/goto :LastAttackCheck
}
/if (${thirdassist.Equal[Main]} || (${Math.Distance[${Target.Y},${Target.X}:${Spawn[pc
${thirdassist}].Y},${Spawn[pc ${thirdassist}].X}]}<${Target.MaxRangeTo})) {
/varset mainassist ${thirdassist}
/goto :LastAttackCheck
}
/goto :EndAutoassist
:LastAttackCheck
|- Do we have an NPC targeted and is it hurt enough to attack?
/if (${Target.PctHPs}<=${assistpct} && ${Target.Animation}!=32 && ${Target.Animation}!=110) {
/if (${verbosity}>=1) /${channel} --> Assisting ${mainassist} on ${Target.CleanName} @
(${Target.PctHPs}%) HPs
/echo Seeking a Victim...
/goto :Foreverloop
}
}
}
:EndAutoassist
|- Are we supposed to look for traps?
/if (${doTraps}) {
/varset oldheading ${Me.Heading.DegreesCCW}
/if (${Me.AbilityReady["Sense Traps"]}) {
/doability "Sense Traps"
/if (${verbosity}>=2) /${channel} Looking for traps...
}
}
|- We could be on a leash, if so move 1s closer to our stake point (or master)\\
/if (${doLeash} && !${strikeReady}) {
/varset lastevent Event_Leashing
:LeashStart
|- Look for new events
/doevents
/if (!${lastevent.Equal[Event_Leashing]}) /goto :ForeverLoop
/if (${Me.Combat}) /goto :ForeverLoop
/if (${leashholder.Equal[Nobody]} &&
(${Math.Distance[${Me.Y},${Me.X}:${stakeY},${stakeX}]}>${Math.Calc[${leashlength}*${leashflex}/100]}
)) {
/if (${verbosity}>=2) /${channel} Moving closer to the Stake...
${Math.Distance[${Me.Y},${Me.X}:${stakeY},${stakeX}]} ft. away
/face ${If[${Me.Swimming},,nolook]} loc ${stakeY},${stakeX}
/keypress forward hold
/delay 1s
${Math.Distance[${Me.Y},${Me.X}:${stakeY},${stakeX}]}<${Math.Calc[${leashlength}*${leashflex}/100]}
/keypress forward
/if
(${Math.Distance[${Me.Y},${Me.X}:${stakeY},${stakeX}]}<${Math.Calc[${leashlength}*${leashflex}/100]}
) {
/if (${verbosity}>=2) /${channel} Arrived near enough to the Stake.
/face fast ${If[${Me.Swimming},,nolook]} away loc ${stakeY},${stakeX}
/goto :LeashEnd
}
/goto :LeashStart
}
/if (!${leashholder.Equal[Nobody]} && ${Spawn[${leashholder}].ID} &&
(${Spawn[${leashholder}].Distance}>${Math.Calc[${leashlength}*${leashflex}/100]})) {
/if (${verbosity}>=2) /${channel} Moving closer to ${leashholder}...
${Spawn[${leashholder}].Distance} ft. away
/if (${Target.ID}!=${Spawn[${leashholder}].ID}) /target id ${Spawn[${leashholder}].ID}
/if (${Me.Combat}) /attack off
/face ${If[${Me.Swimming},,nolook]}
/keypress forward hold
/delay 1s ${Spawn[${leashholder}].Distance}<${Math.Calc[${leashlength}*${leashflex}/100]}
/keypress forward
/if (${Spawn[${leashholder}].Distance}<${Math.Calc[${leashlength}*${leashflex}/100]}) {
/if (${verbosity}>=2) /${channel} Arrived near enough to Master (${leashholder}).
/goto :LeashEnd
}
/goto :LeashStart
}
|- Broken leash check
/if (!${leashholder.Equal[Nobody]} && !${Spawn[${leashholder}].ID}) {
/if (${verbosity}>=1) /${channel} ** Master DEAD or ZONED! Leash is BROKEN!
/varset doLeash FALSE
/varset leashholder Nobody
/ini "RHSettings.ini" "General" "Leashing" "${doLeash}"
/ini "RHSettings.ini" "General" "LeashHolder" "${leashholder}"
/goto :LeashEnd
}
:LeashEnd
}
}
/goto :ForeverLoop
/return
|---- SUBROUTINES
Sub Check_Behind
/declare behindIt FALSE
|- Are we behind our target?
/for i -1 to 1
/varcalc dir (${Target.Heading.Clock}+${i})%12
/if (${dir}<1) /varcalc dir ${dir}+12
/if (${dir}>12) /varcalc dir ${dir}-12
/if (${dir} == ${Me.Heading.Clock}) /varset behindIt TRUE
/next i
/return ${behindIt}
Sub Weapon_Swap(string weapon, string wieldedweapon)
|- Is it in a Bag?
/declare camefrom ${FindItem[${weapon}].InvSlot}
/declare goingto ${FindItem[${wieldedweapon}].InvSlot}
/if (${verbosity}>=2) /${channel} ** Looking for weapon: ${weapon}
/if (${FindItem[${weapon}].InvSlot.Pack}) {
:OpenPack
/if (!${Window[${FindItem[${weapon}].InvSlot.Pack.Name}].Open}) {
/itemnotify ${FindItem[${weapon}].InvSlot.Pack.Name} rightmouseup
/delay 2
/goto :OpenPack
}
:GrabItem
/if (!${Cursor.ID}) {
/itemnotify ${InvSlot[${camefrom}]} leftmouseup
/delay 2
/goto :GrabItem
}
/declare weaponID int local ${Cursor.ID}
:SwapIt
/if (${Cursor.ID}==${weaponID}) {
/itemnotify ${InvSlot[${goingto}]} leftmouseup
/delay 2
/goto :SwapIt
}
/delay 2
/if (${verbosity}>=2) /${channel} ** Swapping out: ${weapon}
/itemnotify ${InvSlot[${camefrom}]} leftmouseup
/delay 2
/if (${Cursor.ID}) {
/if (${verbosity}>=1) /${channel} ** Failed to use existing slot, dropping to inventory!
/autoinv
}
:ClosePack
/if (${Window[${InvSlot[${camefrom}].Pack.Name}].Open}) {
/itemnotify ${InvSlot[${camefrom}].Pack.Name} rightmouseup
/delay 2
/goto :ClosePack
}
} else {
|- It's in the main inventory
/if (${FindItem[${weapon}].InvSlot}) {
/itemnotify ${FindItem[${weapon}].InvSlot} leftmouseup
/delay 2
/itemnotify ${InvSlot[${goingto}]} leftmouseup
/delay 2
/if (${verbosity}>=2) /${channel} ** Swapping out: ${weapon}
/itemnotify ${InvSlot[${camefrom}]} leftmouseup
/delay 2
/if (${Cursor.ID}) {
/if (${verbosity}>=1) /${channel} ** Failed to use existing slot, dropping to inventory!
/autoinv
}
} else {
/if (${verbosity}>=1) /${channel} ** "${weapon}" not found!
}
}
/return
Sub NinjaLoot
|- Ninja the corpse's loot, if applicable
/if (${ninjamode.NotEqual[OFF]}) {
/declare LootTotal int local -1
/declare LootSlot int local
|- Get NPC corpse on target and continue if possible
/squelch /target npc corpse radius ${ninjadist}
/if (${Target.Type.NotEqual[CORPSE]} || !${Target.ID}) {
/if (${verbosity}>=1) /${channel} ** NPC corpse out of range or already looted!
/return
}
|- Get 5 seconds (max) closer; warning, no detecting being stuck!
/face ${If[${Me.Swimming},,nolook]} fast
/keypress forward hold
/delay 5s ${Target.Distance}<5
/keypress forward
|- Open up the loot window
/loot
/delay 1s
/if (${Me.State.NotEqual[BIND]}) {
/if (${verbosity}>=1) /${channel} ** Massive lag or error getting to corpse. Aborting!
/return
}
/if (${verbosity}>=1) /${channel} ** Looting ${Target.CleanName}
|- Get item count accurately
:LootLag
/if (${LootTotal}!=${Corpse.Items}) {
/varset LootTotal ${Corpse.Items}
/delay 5
/goto :LootLag
}
/if (!${LootTotal}) {
/if (${verbosity}>=1) /${channel} ** Empty corpse!
/goto :DoneLooting
}
|- Loot Loop
/for LootSlot 1 to ${LootTotal}
|- Check for full inventory
/if (!${Me.FreeInventory}) {
/beep
/if (${verbosity}>=1) /${channel} ** INVENTORY FULL !
/varset ninjamode OFF
/if (${verbosity}>=1) /${channel} ** AutoNinja is now OFF!
/goto :DoneLooting
}
|- Loot item if we should, skip it if not
/if (${Corpse.Item[${LootSlot}].ID}) {
/if (!${Corpse.Item[${LootSlot}].NoDrop}) /goto :LootItem
/if (${Corpse.Item[${LootSlot}].NoDrop} && ${ninjamode.Equal[ALL]}) {
/if (${verbosity}>=1) /${channel} ** Looting NODROP Item: ${Corpse.Item[${LootSlot}].Name}
/goto :LootItem
}
}
/if (${verbosity}>=1) /${channel} ** Skipping Item: ${Corpse.Item[${LootSlot}].Name}
/goto :SkipIt
:LootItem
/itemnotify loot${LootSlot} rightmouseup
/delay 3
/if (${Corpse.Item[${LootSlot}].ID}) {
/delay 2
/goto :LootItem
}
:SkipIt
/next LootSlot
/if (${verbosity}>=1) /${channel} ** Done looting ${Target.CleanName}
:DoneLooting
/delay 5
/notify LootWnd DoneButton leftmouseup
/delay 5
}
/return


