So I have used this beyond usefulness so I figured I'd release it.
Notes:
Notes:
- 1. You need to record a path from brell's arena to gilbot named 'arena_to_gilbot' using mq2advpath. See wiki for details. I am not including this because well... it helps to be unique.
- 2. This supports 3 toons in a group. It helps if the requester is a rogue as it will hide/sneak. (people like to train the boomerang requester area on my server)
- 3. This uses EQBC to communicate in group. You should be running it.
- 4. I don't plan on fixing any bugs or anything, so if its not working for you, twiddle with it.
Code:
|**------------------------------------------------------
BOOMERANG.mac
Task Get/Run/ETC by meta53 22 DECEMBER 09
Version: 1.0
Boomerang main sub by jlm462, 12/2009
with contributions from Ralindal and dascott
v0.4
--This macro is to be only posted on MMOBugs.com-*-
Required Plugins: MQ2MoveUtils,MQ2AdvPath
Spell_Routines.inc
MQ2eqbc
Notes:
1.brells_rest.ini, with the path 'arena_to_gilbot' NOT INCLUDED
Please record your own, from arena->gilbot, this is to keep
A zillion people from running the same fricken path.
2.waypoint BA_ZO is something you will have to set right in front
of Brells Arena (in brells rest) if you, like me, get placed
under the zone on zone out.
Usage: From the requesting toon...
/mac boomerang TASKLEADER
I would have the other 2 toons already setup near the door to Brell's Arena,
but if not, have them at gilbot, they will run to BA.
**|
|------------------------------------------------------
#turbo 10
#include spell_routines.inc
#Event Ended "#*#The results of the contest are as follows#*#"
#Event DoShroud "#*#Get your shroud#*#"
#Event TimeWait "#*#You may not request this shared task because you must wait#*#"
#Event Assigned "#*#You have been assigned#*#"
Sub Main
/echo [boomerang.mac active]
/if (!${AdvPath.Active}) /plugin mq2advpath
/declare boolActive string outer TRUE
/declare strMainRequester string outer ${Param0}
/declare intTemplate int outer ${Param1}
/declare intDoorX int outer -561
/declare intDoorY int outer -236
/declare intExitX int outer 1
/declare intExitY int outer -307
/declare strTimeWait string outer 0m
/declare boolShroudCalled bool outer FALSE
/declare boolHasTimer bool outer FALSE
/declare intDoorRadius int outer 10
:mainloop
/echo This macro has been running for: ${Macro.RunTime}
/if (${Zone.ShortName.Equal[GuildLobby]}) {
/echo I am in guildlobby! Shutting my crap down!
/delay 30s
/bcaa //melee off
/bcaa //camp desktop
/bcaa //end
/end
}
/if (${Zone.ShortName.NotEqual[brellsarena]}) {
|--Are you a requester? If so you should probably go get the mission
| This might be the place you want to change BCA to /bct [toonName] based on INI?
| Or better yet, shit can the INI file, and use the group members !requester.
| This change would allow multiple groups running at same time!
/if (${Me.CleanName.Equal[${strMainRequester}]}) {
/varset intTemplate 1
/bct ${Group.Member[1]} //mac boomerang ${strMainRequester} 2
/bct ${Group.Member[2]} //mac boomerang ${strMainRequester} 3
/delay 1s
/call Get_Event
/doevents
/echo Delaying 10s.
/delay 10s
/if (${boolHasTimer}) {
/echo Have a timer still...
/gsay We still have some time left before reget, waiting 16m!
/gsay Last Run at ${Time.Time24}
/afk Waiting for boomerang lockout to be up. Leave message!
/delay 16m
/goto :mainloop
}
/echo Calling MoveTo_Event on requester.
/call MoveTo_Event
/gsay Get your shroud!
} else {
/if (${Math.Distance[${intDoorX},${intDoorY}]} >= ${intDoorRadius}) {
|-close to gilbot, move to event
/call MoveTo_Event
}
/varset boolShroudCalled FALSE
| need to add a loop here for having the requester tell everyone to select template and continue
:shroudWait
/doevents
/if (!${boolShroudCalled}) {
/delay 5s
/if (${String[${Me.Class}].Equal[Shadow Knight]} && (${Me.Invis} == FALSE)) {
/alt activate 531
}
/goto :shroudWait
}
}
|--Time to select the template.
/call TemplateSelect
/echo Template Selected
|--OK! Mission Gotten! Now Let us Zone in and start up.
/call Check_ZoneIN
/echo I am in the correct Zone, Continuing.
}
/if (${Me.CleanName.Equal[${strMainRequester}]}) {
/call Trigger_Event
}
/call Event_StartMatch
/call Event_EndMatch
/call Check_ZoneOut
/delay 30s
/taskquit
/taskquit
/goto :mainloop
/return
Sub Get_Event
/echo requesting Gilbot the Magnificent
/target npc Gilbot the Magnificent
/delay 1s
/if (${Target.Distance}>20) {
|-not close to gilbot, sigh
/call MoveTo_Gilbot
}
/if (${String[${Me.Class}].Equal[Rogue]}) {
/echo Hi, Rogue Hide/Sneak is now off!
/if (${Me.Sneaking}) /doability "Sneak"
/delay 1s
/if (${Me.Invis}) /doability "Hide"
/delay 1s
}
/varset boolHasTimer TRUE
/delay 3s
/say specific
/delay 1s
/if (${String[${Me.Class}].Equal[Rogue]}) {
/echo Hi, Rogue Hide/Sneak is now on.
/if (!${Me.Invis}) /doability "Hide"
/delay 1s
/if (!${Me.Sneaking}) /doability "Sneak"
/delay 1s
}
/return
Sub Trigger_Event
/gsay Triggering the Event
/if (${String[${Me.Class}].Equal[Rogue]}) {
/echo Hi, Rogue Hide/Sneak is now off!
/if (${Me.Sneaking}) /doability "Sneak"
/delay 1s
/if (${Me.Invis}) /doability "Hide"
/delay 1s
}
/target npc Gilbot the Wary
/delay 1s
/saytarget start
/delay 1s
/target npc Gilbot the Wary
/saytarget start
/delay 10
/return
}
Sub MoveTo_Gilbot
/play arena_to_gilbot smart
:movement
/if (${AdvPath.State} == 2) {
/delay 1s
/goto :movement
}
/delay 2s
/return
Sub MoveTo_Event
/echo Moving To Event.
/if (${String[${Me.Class}].Equal[Shadow Knight]}) {
/alt activate 531
}
/play arena_to_gilbot reverse smart
:movement
/if (${AdvPath.State} == 2) {
/delay 1s
/goto :movement
}
/delay 1s
/return
Sub TemplateSelect
/gsay Selecting ${intTemplate}
/delay 10
|**
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired listselect ${Window[TaskTemplateSelectWnd].Child[TaskTemplateSelectListRequired].List[${intTemplate}]}
/delay 10
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired leftmouse ${Window[TaskTemplateSelectWnd].Child[TaskTemplateSelectListRequired].List[${intTemplate}]}
/delay 10
**|
|-Brute force this.
/if (${intTemplate} == 1) {
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired listselect 1
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired leftmouse 1
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired listselect 1
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired leftmouse 1
/gsay Banged on Option 1!
/delay 1s
} else /if (${intTemplate} == 2) {
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired listselect 2
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired leftmouse 2
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired listselect 2
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired leftmouse 2
/gsay Banged on Option 2!
} else {
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired listselect 3
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired leftmouse 3
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired listselect 3
/delay 1s
/notify TaskTemplateSelectWnd TaskTemplateSelectListRequired leftmouse 3
/delay 1s
/gsay Banged on Option 3!
}
/notify TaskTemplateSelectWnd TaskTemplateSelectAcceptButton leftmouseup
/delay 5s
/return
Sub Check_ZoneIN
/echo Checking Zone
/if (${String[${Me.Class}].Equal[Rogue]}) {
/echo Hi, Rogue Hide/Sneak is now off!
/if (${Me.Sneaking}) /doability "Sneak"
/delay 1s
/if (${Me.Invis}) /doability "Hide"
/delay 1s
}
:zonecheckloop
/if (${Zone.ShortName.Equal[brellsarena]}) {
/return
} else {
/switch 2
/delay 30s
/goto :zonecheckloop
}
/return
Sub Check_ZoneOut
|-- Apparently clicking out is putting me under the fucking world.
|-- so once in BR, will warp to where it should put you (not noticeable to people..)
/echo Checking Zone
/taskquit
/taskquit
:zonecheckloop
/if (${Zone.ShortName.Equal[brellsrest]}) {
/delay 10s
/warp wp BA_ZO
/delay 1s
/warp wp BA_ZO
/return
} else {
/taskquit
/taskquit
/delay 1m
/goto :zonecheckloop
}
/return
Sub Event_EndMatch
/echo match ended, moving to door.
|-- Apparently clicking out is putting me under the fucking world.
/moveto loc ${intExitY} ${intExitX}
:movement
/if (${Math.Distance[${Me.Y},${Me.X}:${intExitY},${intExitX}]}>=${intDoorRadius}) {
/goto :movement
}
/moveto off
/return
Sub Event_StartMatch
/echo Beginning StartMatch Routine
/call AlertTimer
/if (!${Defined[lasteventnum]}) /declare lasteventnum int outer 0
/if (!${Defined[strafedir]}) /declare strafedir string local
/if (!${Defined[X2]}) /declare X2 int local
/if (!${Defined[Y2]}) /declare Y2 int local
/if (!${Defined[spawnID]}) /declare spawnID int local 0
/if (!${Defined[spawn2id]}) /declare spawn2id int local 0
/if (!${Defined[spawn2]}) /declare spawn2 string local
/if (!${Defined[spawn2dist]}) /declare spawn2dist int local 0
/if (!${Defined[spawn2locY]}) /declare spawn2locY int local 0
/if (!${Defined[spawn2locX]}) /declare spawn2locX int local 0
/if (!${Defined[boolFinished]}) /declare boolFinished bool local false
/varset lasteventnum 0
/varset boolActive TRUE
/target clear
/echo determining team color
|- updated teamcolor logic from Ralindal
/if (!${Defined[teamColor]}) /declare teamColor string outer NULL
/if (${FindItemCount[=Red Boomerang]}>0 && ${FindItemCount[=Yellow Boomerang]}>0) {
/varset teamColor BLUE
} else /if (${FindItemCount[=Blue Boomerang]}>0 && ${FindItemCount[=Yellow Boomerang]}>0) {
/varset teamColor RED
} else {
/echo team color yello
/varset teamColor YELLOW
}
:boomerangloop
/if (${Zone.ShortName.NotEqual[brellsarena]}) {
/taskquit
/return
}
/doevents
/if (${lasteventnum}==9 || ${Me.State.Equal[HOVER]}) /return
/if (!${boolActive}) /return
/if (${Me.State.Equal[FEIGN]}) /stand
/delay 3s ${Me.State.Equal[STAND]}
/varset spawnID 0
|- Set the BLUE Team
/if (${teamColor.Equal[BLUE]}) /varset spawnID ${Me.NearestSpawn[1, npc noalert 1 range 86 89].ID}
|- Set the BLUE Team
|- updated so yellow team will pick up blue and red instead of just red, due to split level range
/if (${teamColor.Equal[YELLOW]}) {
/varset spawnID ${Me.NearestSpawn[1, npc noalert 1 range 89 89].ID}
/if (!${spawnID}) {
/varset spawnID ${Me.NearestSpawn[1, npc noalert 1 range 84 84].ID}
}
}
|- Set the RED Team
/if (${teamColor.Equal[RED]}) /varset spawnID ${Me.NearestSpawn[1, npc noalert 1 range 84 86].ID}
/if (${spawnID} && ${Spawn[id ${spawnID}].State.NotEqual[FEIGN]}) {
/target id ${spawnID}
/delay 1s ${Target.ID}==${spawnID}
}
/if (!${Target.ID}) {
/call AlertTimer
} else {
:moveloop
/if (${Me.State.Equal[FEIGN]}) /stand
/delay 3s ${Me.State.Equal[STAND]}
/if (${Target.Distance}>50) {
|- Get the details of the nearest powder keg
/varset spawn2id ${Me.NearestSpawn[1, race "Powder Keg"].ID}
/if (${spawn2id}) {
/varset spawn2 ${Spawn[${spawn2id}]}
/varset spawn2dist ${Spawn[${spawn2id}].Distance}
/varset spawn2locY ${Spawn[${spawn2id}].Y}
/varset spawn2locX ${Spawn[${spawn2id}].X}
}
|- If the barrel is too close, lets back off and strafe around it before moving towards our target
/if (${spawn2id} && ${spawn2dist}<90) {
|/echo TOO CLOSE TO NEAREST POWDER KEG, BACK AWAY!
/face fast nolook loc ${spawn2locY},${spawn2locX}
/keypress back hold
/delay 1s
/keypress back
/if (${Math.Rand[2]}) {
/varset strafedir STRAFE_LEFT
} else {
/varset strafedir STRAFE_RIGHT
}
/keypress ${strafedir} hold
/delay 8
/keypress ${strafedir}
}
|- Set current position first before heading towards our target (in case we get stuck)
/varset X2 ${Int[${Me.X}]}
/varset Y2 ${Int[${Me.Y}]}
/if (${Me.State.Equal[FEIGN]}) /stand
/delay 3s ${Me.State.Equal[STAND]}
/face fast nolook
/keypress forward hold
/delay 5 ${Target.Distance}<=50
/keypress forward
/if (${Me.State.Equal[FEIGN]}) /stand
/delay 3s ${Me.State.Equal[STAND]}
/face fast nolook
|- Check to see if we got stuck trying that
/if ((${Int[${Me.X}]}==${X2}) && (${Int[${Me.Y}]}==${Y2})) {
|- We're stuck, back off a second, move left or right (randomly) for .5 seconds
/keypress back hold
/delay 5
/keypress back
/if (${Math.Rand[2]}) {
/varset strafedir STRAFE_LEFT
} else {
/varset strafedir STRAFE_RIGHT
}
/keypress ${strafedir} hold
/delay 5
/keypress ${strafedir}
}
/goto :moveloop
}
/if (${Target.Level}==89 && ${FindItemCount[=Red Boomerang]}>0) {
|- updated to revert back to moveloop if boomerang not ready, per dascott's idea
/if (${FindItem[Red Boomerang].Timer}) /goto :moveloop
/if (${Me.State.Equal[FEIGN]}) /stand
/delay 3s ${Me.State.Equal[STAND]}
/face fast nolook
|/echo Throwing Red Boomerang
/cast item "Red Boomerang"
/cast item "Red Boomerang"
}
/if (${Target.Level}==86 && ${FindItemCount[=Yellow Boomerang]}>0) {
/if (${FindItem[Yellow Boomerang].Timer}) /goto :moveloop
/if (${Me.State.Equal[FEIGN]}) /stand
/delay 3s ${Me.State.Equal[STAND]}
/face fast nolook
|/echo Throwing Yellow Boomerang
/cast item "Yellow Boomerang"
/cast item "Yellow Boomerang"
}
/if (${Target.Level}==84 && ${FindItemCount[=Blue Boomerang]}>0) {
/if (${FindItem[Blue Boomerang].Timer}) /goto :moveloop
/if (${Me.State.Equal[FEIGN]}) /stand
/delay 3s ${Me.State.Equal[STAND]}
/face fast nolook
|/echo Throwing Blue Boomerang
/cast item "Blue Boomerang"
/cast item "Blue Boomerang"
}
/squelch /alert add 1 id ${Target.ID}
/squelch /target clear
}
/goto :boomerangloop
/return
Sub AlertTimer
/squelch /alert clear 1
/squelch /alert add 1 BRADiscusController
/return
Sub Event_DoShroud
/varset boolShroudCalled TRUE
/return
Sub Event_Ended
/varset boolActive FALSE
/return
Sub Event_TimeWait
/echo event_timewait, boolHasTimer is now TRUE
/varset boolHasTimer TRUE
/return
Sub Event_Assigned
/gsay got our event.
/echo event_assigned, boolHasTimer is now FALSE
/varset boolHasTimer FALSE
/return