Moderator: MacroQuest Developers
Code: Select all
| - chant.mac - By Raebis
| Version: REV5c.ice_0 Jan 06 20:30
|
| edited by: icehouse33 concept revision by Artyx
|
| This mac is used mostly for big open zones with not a lot of
| big hills (cause hills cause pain - unless you have levitate)
| Unless you have Singing Steel Boots! *See Below*
|
| Features:------------------------------------------------------------------------
|
| * Automatically selects high light blue, dark blue, or white mob
| * Runs to mob before targeting it (Stealth! No cross-zone targeting!)
| * Aggro/Add Detection: Automatically targets and kites aggroed mobs (adds)
| * Ignores greens and low light blues unless they are aggroed (adds)
| * Caster Detection: Automatically will switch target to aggroed casting mobs
| * Compatible with level 49 and level 6 selos
| * Auto Healing: If health gets low, it will automatically heal
| * Fleeing Mob Catcher: If mob runs away, macro keeps you in range!
| * Detects WMS (Warping Mob Syndrom) and gets a new target if a mob warps away!
| * NEW: Rubber Anchor: kites mobs closest to macro starting point - no wandering!
| * NEW: Support for Singing Steel Boots
| * NEW: Snare Song when Mob low on health
| ---------------------------------------------------------------------------------
|
| usage: chant.mac <DOTs/LVL6 Selos> <49selo> <radius> <snare song> [<heal song>]
|
|
| Usage Examples:
| -Scenario 1: If you are using...
| ...DOTs in Gems 4, 5, 6, and 7
| ...Level 49 Selo in Gem 2
| ...Snare Song in Gem 3
| ...Hymn of Restoration in Gem 1
| ...Radius of 55
| syntax: /mac chant 4567 2 55 3 1
|
| -Scenario 2: If you are using...
| ...DOTs in Gems 6 and 7
| ...Level 6 Selo in gem 3
| ...No Snare Song
| ...Hymn of Restoration in gem 8
| ...Radius of 80
| syntax: /mac chant 673 0 80 0 8
|
|
| If <heal song> is defined then when health goes below @HealthMin (default is 70%)
| it will replace the first song in <DOTs> with <heal song> until health is above
| @HealthMax (default is 85%)
|
| If <selos> is 0 then the macro will not try to cast selos every 150 seconds
|
| If <snare> is 0 then the macro will not try to snare the mob when it reaches a % hp
| User may change HP% to begin Snare. <SnarePerc> Defaulted to 23%
| User may Change if he wishes Snare to override Heal song Defaulted to yes.
| <SnareOverHeal> = 1 for Yes, 0 for No
|
| Note about the rubber anchor:
| The macro will target the mob closest to the RubberAnchor (your /loc when first
| starting the macro)
|
| REV5b was Tested in EW for bout an hour
|
| Note: If you don't have Singing Steel Boots, and you don't have a levitate buff
| then the function to click your boots won't be called.
|
| Warning: You may wander from your starting point but after killing a mob, the
| next mob that the macro targets will be closest to your starting point
|
| Note: Rev information moved to the top
|
#event NeedTarget "You must first select a target for this spell!"
#event Exp "You gain "
#event Died "You have entered"
#event Caster " begins to cast a spell."
#event Levitate "You feel as if you are about to fall"
#turbo
Sub Main(DOTs,Selos,CRadius,Snare,Health)
/zapvars
/if $defined(CRadius)==false {
/echo usage: chant.mac <DOTs, LVL6 Selos> <49selo> <radius> <snare song> [<heal song>]
/return
}
/declare CirR global
/declare Songs array
/declare nSongs global
/declare CurSong global
/declare PrevSong global
/declare Exper global
/declare AAExp global
/declare SongTimer timer
/declare SeloSong global
/declare Selolvl global
/declare HealSong global
/declare OrigSong global
/declare SnareSong global
/declare SnarePerc global
/declare SnareOverHeal global
/declare HealthMin global
/declare HealthMax global
/declare DBLevel global
/declare TargetUpNext global
/declare RubberX global
/declare RubberY global
/declare EachSong local
/varset nSongs $strlen(@DOTs)
/for EachSong 1 to @nSongs
/varset Songs(@EachSong) $mid($calc(@EachSong-1),1,@DOTs)
/echo Song @EachSong: $char(gem,@Songs(@EachSong))
/next EachSong
/if n @Selos!=0 {
/varset Selolvl ($char(level))
/echo Selolvl is now set to: ***@Selolvl***
}
/if n @Selolvl<=48 {
/varset SeloSong @Selos
/echo Selo's: $char(gem,@SeloSong) level 6 selos
}
/if n @Selolvl>=49 {
/varset SeloSong @Selos
/echo Selo's: $char(gem,@SeloSong)
| initializiing Selolvl variable
/varset Selolvl 0
} else {
/varset SeloSong 0
/echo Not twisting Selos.
/if n @Selolvl!=0 {
/varset SeloSong @Selos
}
}
/if n @Snare!=0 {
/varset SnareSong @Snare
/echo Snare's: $char(gem,@SnareSong)
} else {
/varset SnareSong 0
/echo Not using a Snare Song. Welcome to warpville.
}
/if $defined(Health)!=false {
/varset HealSong @Health
/echo Healsong: $char(gem,@HealSong)
} else {
/echo No HealSong. Please watch your health.
/varset HealSong 0
}
/varset CirR @CRadius
/echo Radius: @CRadius
/varset OrigSong @Songs(1)
/varset CurSong 1
/varset Exper $char(exp)
/varset AAExp $char(aa,exp)
/varset SongTimer 1
/varset DBLevel $int($calc($calc($char(level)*.7)+8))
/varset HealthMin 70
/varset HealthMax 85
/varset SnarePerc 23
/varset SnareOverHeal 1
/varset TargetUpNext 0
/varset RubberX $char(x)
/varset RubberY $char(y)
/echo Rubber Anchor dropped at @RubberX,@RubberY
:Loop
/if n @CurSong>@nSongs /varset CurSong 1
/if n @TargetUpNext<=0 /if n $target(id)<=0 {
/call gettarget
}
/if n @TargetUpNext>0 /if n $target(id)>0 /if n $target(id)!=@TargetUpNext {
/echo User Selected Target or Aggroed while running
/varset TargetUpNext 0
}
/if n $target(distance)>1000 /if n $target(hp,pct)<=50 {
/echo Target Warped... Distance: $target(distance) HP: $target(hp,pct)
/echo getting new target
/cleanup
/call GetTarget
}
| Change - will only look to Set Snare or Heal song into twist when trying to cast 1st song
/if n @CurSong==1 {
/call Snareorheal
}
/if n @SeloSong!=0 /if $char(casting)==FALSE /if n $char(buff,"$char(gem,@SeloSong)")==0 /varset SongTimer 1
/if n @SongTimer>0 /if $char(casting)==FALSE /call SongFailed
/call Circ
/doevents
/delay 0
/goto :Loop
/return
Sub Event_Timer(TimerName)
/if @TimerName==SongTimer {
/if n @SeloSong!=0 /if n $char(buff,"$char(gem,@SeloSong)")==0 {
/delay 2
/stopsong
/cast @SeloSong
/varset PrevSong 0
/varset SongTimer 30
/call Circ
/doevents
/return
}
/echo checking if Selosong !=0 current value for Selolvl is : ***@Selolvl***
/if n @Selolvl!=0 {
/echo Inside the check, checking if song,selos is running
/if $char(song,"$char(gem,@SeloSong)")!=0 /if n $char(song,$char(song,"$char(gem,@SeloSong)"),duration)<=1
{
/delay 1
/stopsong
/echo ***Refreshing Selos SONG***
/cast @SeloSong
/varset PrevSong 0
/varset SongTimer 30
/call Circ
/doevents
/delay 2
/stopsong
/return
}
else /echo Passed the first IF
/echo Checking if Selosong,buff is running
/if n $char(buff,"$char(gem,@SeloSong)")!=0 /if n $char(buff,$char(buff,"$char(gem,@SeloSong)"),duration)<=6
{
/delay 2
/stopsong
/echo refreshing selos buff
/cast @SeloSong
/varset PrevSong 0
/varset SongTimer 30
/call Circ
/doevents
/return
}
}
| stop trying to dot while running to target but Heal if needed
/if n $target(id)>0 /if n $target(distance)<=200 {
/if n @CurSong>@nSongs /varset CurSong 1
/cast @Songs(@CurSong)
/varset PrevSong @CurSong
/varadd CurSong 1
} else {
/if n @Songs(@Cursong)==@HealSong /cast @Songs(@CurSong)
}
/varset SongTimer 30
/call Circ
/doevents
}
/return
Sub Circ
/declare CirX local
/declare CirY local
/if n @TargetUpNext!=0 {
/varset CirX $spawn(@TargetUpNext,y)
/varset CirY $spawn(@TargetUpNext,x)
/if n $spawn(@TargetUpNext,distance)<=$calc(@CirR*2) {
/target id @TargetUpNext
/varset TargetUpNext 0
}
}
/if n $target(id)>0 {
/varset CirX $target(y)
/varset CirY $target(x)
}
/if n $distance(@CirX,@CirY)<$calc(@CirR/2) {
/face heading $calc($heading(@CirX,@CirY)+180)
} else {
/face heading $calc($heading(@CirX,@CirY)+$calc(90*$calc(@CirR/$distance(@CirX,@CirY))))
}
/return
Sub Snareorheal
/if n @SnareSong!=0 /if n $target(id)>0 {
/if n $target(hp,pct)<=@SnarePerc {
/if n @Songs(1)!=@SnareSong {
/if n @SnareOverHeal!=1 /if n @Songs(1)==@HealSong {
/echo Snare NOT set to override Heal ..
/return
}
/if n @Songs(1)==@HealSong {
/echo Snare on, but Heal Song overridden *Caution*
/varset Songs(1) @SnareSong
} else {
/echo Snare On - TargetHealth: $target(hp,pct)%
/varset Songs(1) @SnareSong
}
/return
}
}
}
/if n @SnareSong!=0 /if $target(id)>0 {
/if n $target(hp,pct)>@SnarePerc {
/if n @Songs(1)==@SnareSong {
/echo Snare song off
/varset Songs(1) @OrigSong
/return
}
}
}
/if n @HealSong!=0 /if n $char(hp,pct)<@HealthMin {
/if n @Songs(1)!=@HealSong {
/if n @SnareOverHeal==1 /if n Songs(1)==@SnareSong {
/echo Heal can NOT override Snare *Caution*
/return
}
/if n @Songs(1)==@SnareSong {
/echo Healing On - Snare Off - Health: $char(hp,pct)% to @HealthMax%
/varset Songs(1) @HealSong
} else {
/echo Healing On - Health: $char(hp,pct)% to @HealthMax%
/varset Songs(1) @HealSong
}
/return
}
}
/if n @HealSong!=0 /if n $char(hp,pct)>=@HealthMax {
/if n @Songs(1)==@HealSong {
/echo Healing Off
/varset Songs(1) @OrigSong
}
}
/return
Sub SongFailed
/if n @PrevSong==0 {
/varset SongTimer 1
/return
}
/varset CurSong @PrevSong
/varset SongTimer 1
/return
Sub Event_NeedTarget
/if n @TargetUpNext<=0 /call GetTarget
/return
Sub Event_Died
/delay 10
/sit
/delay 10
/camp desktop
/return
Sub Event_Exp
/varset AAExp $calc($char(aa,exp)-@AAExp)
/varset Exper $calc($char(exp)-@Exper)
/echo EXP: @Exper%:$char(exp)% - AAXP: @AAExp%:$char(aa,exp)% - $calc($running/60) minutes
/varset Exper $char(exp)
/varset AAExp $char(aa,exp)
/varset DBLevel $int($calc($calc($char(level)*.7)+1))
/if n @TargetUpNext==0 /if n $target(id)==0 /call gettarget
/return
Sub GetTarget
/declare MobID local
/declare SRadius local
/varset MobID $searchspawn(npc,radius:$calc(@CirR*2))
/if n @Songs(1)==@SnareSong /varset Songs(1) @OrigSong
/if n @MobID!=0 /if n $spawn(@MobID,speed)>100 {
/target id @MobID
/echo Kiting aggro'd mob: $target(name,clean)
/return
}
/varset MobID 0
/for SRadius 0 to 10000 step 100
/varset MobID $searchspawn(npc,range:@DBLevel:$char(level),loc:@RubberX:@RubberY,radius:@SRadius)
/if n @MobID!=0 {
/goto :Done
}
/next SRadius
/echo No mobs found, action required!
/beep
/echo Ending Macro
/beep
/endmac
:Done
/varset TargetUpNext @MobID
/echo Next: $spawn(@MobID,level) $spawn(@MobID,name,clean) - Distance: $spawn(@MobID,distance)
/return
Sub Event_Caster(CastText)
/declare CasterID local
/varset CasterID $searchspawn(name,"$left($calc($strlen("@CastText")-24),"@CastText")")
/if $spawn(@CasterID,type)!=NPC /return
/if n $target(id)==@CasterID /return
/if n $spawn(@CasterID,distance)<=$calc(@CirR*2) {
/target id @CasterID
/echo Targeting Caster: $spawn(@CasterID,name,clean)
}
/return
Sub Event_Levitate
/delay 2
/stopsong
/cast item "Singing Steel Boots"
:Levloop
/delay 2
/call Circ
/if $char(casting)!=FALSE /goto :Levloop
/return
Alert/noalert lists shoudl be an easy implement. I quickly added this as a test when i was hunting epic mobs for a friendEl wrote:1. It would be really, really neat if we had some way of excluding certain mobs from the targeting algorithm. i.e. I'm in EW hunting Ulthorks, but I don't want to go after Icefang.
.
.
3. Similar to #1, it would be cool if I specify a mob that I would always kill, no matter the con. Think snow bunnies in our EW example... they're PH's for Ulthorks, and I want to kill them whenever I see one.
how long does levitate last? gonna add levitate support that autodetects if you have singing steel boots, levi song memed, etc...El wrote:2. Would be nice to be able to work in Levitate into the song mix. Unlike most songs, it doesn't wear off in 3 ticks, so it needs its own timer.
check hereSpace-Boy wrote: have a 51 bard im using this with, was wondering where are some good zones this macro works well in for xp at this level?

Code: Select all
| - chant.mac - By Raebis
| - Mob avoidance added by ml2517
|
| Version: REV5c(w/ avoidance mod) Jan 10 4:30pm
|
| This mac is used mostly for big open zones with not a lot of
| big hills (cause hills cause pain - unless you have levitate)
|
| Features:------------------------------------------------------------------------
|
| * Automatically selects high light blue, dark blue, or white mob
| * Runs to mob before targeting it (Stealth! No cross-zone targeting!)
| * Aggro/Add Detection: Automatically targets and kites aggroed mobs (adds)
| * Ignores greens and low light blues unless they are aggroed (adds)
| * Caster Detection: Automatically will switch target to aggroed casting mobs
| * Compatible with level 49 and level 6 selos
| * Auto Healing: If health gets low, it will automatically heal
| * Fleeing Mob Catcher: If mob runs away, macro keeps you in range!
| * Detects WMS (Warping Mob Syndrom) and gets a new target if a mob warps away!
| * NEW: Rubber Anchor: kites mobs closest to macro starting point - no wandering!
| * NEW: Mob avoidance by name. Add/Remove from the list on the fly. (See the description of use below)
| * NEW: Script pausing upon startup or during the script. (See the description of use below)
| ---------------------------------------------------------------------------------
|
| usage: chant.mac <DOTs/LVL6 Selos> <49selo> <radius> [<heal song>] [<pause on startup>]
|
|
| Usage Examples:
| -Scenario 1: If you are using...
| ...DOTs in Gems 4, 5, 6, and 7
| ...Level 49 Selo in Gem 2
| ...Radius of 55
| ...Hymn of Restoration in Gem 1
| ...If you wanted the script to start paused
| syntax: /mac chant 4567 2 55 1 1
|
| -Scenario 2: If you are using...
| ...DOTs in Gems 6 and 7
| ...Level 6 Selo in gem 3
| ...Radius of 80
| ...Hymn of Restoration in gem 8
| ...If you want the script to start un-paused
| syntax: /mac chant 673 0 80 8 0
|
|
| If <heal song> is defined then when health goes below @HealthMin (default is 70%)
| it will replace the first song in <DOTs> with <heal song> until health is above
| @HealthMax (default is 85%)
|
| If <pause on startup> is a 1 the script will pause upon startup so that you can add mobs to your avoid list.
| If <pause on startup> is a 0 the script will start immediately and go hunting.
| If you don't define <pause on startup> it assumes you want to immediately start hunting.
|
| If <selo> is 0 then the macro will not try to cast selos every 150 seconds
|
| Note about the rubber anchor:
| The macro will target the mob closest to the RubberAnchor (your /loc when first
| starting the macro)
|
| REV5b was Tested in EW for bout an hour
|
| Warning: You may wander from your starting point but after killing a mob, the
| next mob that the macro targets will be closest to your starting point
|
| Note: Rev information moved to the top
|
| -----------------------------------------------------------------------------------
|
| New Commands:
| -------------
| /echo avoid add mobname
| /echo avoid remove mobname
| /echo pause
|
| Examples:
| ---------
| /echo avoid add A Large Trout
| /echo avoid remove A Large Trout
| /echo pause
|
| When adding mobs to the avoidance list initially you can use the /echo pause command.
| This will pause the script but still allow you to target and add/remove the mobs you'd
| like to avoid/not avoid. You can also pause the script upon startup by using the pause parameter.
|
| The best way to use the avoid add command is to use a hotkey with this:
| /echo avoid add $target(name,clean)
|
| The best way to use the avoid remove command is to use a hotkey with this:
| /echo avoid remove $target(name,clean)
|
| Then you simply run around the zone targeting mobs that you know you'd like to avoid and add/remove them
| to your avoidance list. The list is written to an INI file so you won't have to add them to the list
| the next time you play.
|
#event NeedTarget "You must first select a target for this spell!"
#event Exp "You gain "
#event Died "You have entered"
#event Caster " begins to cast a spell."
#event AddAvoid "[MQ2] avoid add "
#event RemoveAvoid "[MQ2] avoid remove "
#event Pause "[MQ2] pause"
#turbo
Sub Main(DOTs,Selos,CRadius,Health,Paused)
/zapvars
/if $defined(CRadius)==false {
/echo usage: chant.mac <DOTs, LVL6 Selos> <49selo> <radius> [<heal song>]
/return
}
/declare PauseFlag global
/if $defined(Paused)==TRUE {
/if n @Paused==1 {
/varset PauseFlag 1
} else {
/varset PauseFlag 0
}
} else {
/varset PauseFlag 0
}
/declare CirR global
/declare Songs array
/declare nSongs global
/declare CurSong global
/declare PrevSong global
/declare Exper global
/declare AAExp global
/declare SongTimer timer
/declare SeloSong global
/declare HealSong global
/declare OrigSong global
/declare HealthMin global
/declare HealthMax global
/declare DBLevel global
/declare TargetUpNext global
/declare RubberX global
/declare RubberY global
/declare AvoidList array
/call AvoidINILoad
/declare EachSong local
/varset nSongs $strlen(@DOTs)
/for EachSong 1 to @nSongs
/varset Songs(@EachSong) $mid($calc(@EachSong-1),1,@DOTs)
/echo Song @EachSong: $char(gem,@Songs(@EachSong))
/next EachSong
/if n @Selos!=0 {
/varset SeloSong @Selos
/echo Selo's: $char(gem,@SeloSong)
} else {
/varset SeloSong 0
/echo Not using level 49 Selos.
}
/if $defined(Health)!=false {
/varset HealSong @Health
/echo Healsong: $char(gem,@HealSong)
} else {
/echo No HealSong. Please watch your health.
/varset HealSong 0
}
/varset CirR @CRadius
/echo Radius: @CRadius
/varset OrigSong @Songs(1)
/varset CurSong 1
/varset Exper $char(exp)
/varset AAExp $char(aa,exp)
/varset SongTimer 1
/varset DBLevel $int($calc($calc($char(level)*.7)+1))
/varset HealthMin 70
/varset HealthMax 85
/varset TargetUpNext 0
/varset RubberX $char(x)
/varset RubberY $char(y)
/echo Rubber Anchor dropped at @RubberX,@RubberY
/if n @PauseFlag==1 {
/echo Script [PAUSED] issue an "/echo pause" to unpause it.
}
:Loop
/if n @PauseFlag==1 {
/delay 1
/doevents AddAvoid
/doevents RemoveAvoid
/doevents Pause
/goto :Loop
}
/if n @TargetUpNext<=0 /if n $target(id)<=0 {
/call gettarget
}
/if n @TargetUpNext>0 /if n $target(id)>0 {
/echo User Selected Target or Aggroed while running
/varset TargetUpNext 0
}
/if n $target(distance)>1000 /if n $target(hp,pct)<=50 {
/cleanup
/echo Target Warped... Getting a new target
/call GetTarget
}
/if n @HealSong!=0 /if n $char(hp,pct)<@HealthMin {
/if n @Songs(1)!=@HealSong {
/echo Healing On - Health: $char(hp,pct)% to @HealthMax%
/varset Songs(1) @HealSong
}
}
/if n @HealSong!=0 /if n $char(hp,pct)>=@HealthMax {
/if n @Songs(1)!=@OrigSong {
/echo Healing Off
/varset Songs(1) @OrigSong
}
}
/if n @SeloSong!=0 /if $char(casting)==FALSE /if n $char(buff,"$char(gem,@SeloSong)")==0 /varset SongTimer 1
/if n @SongTimer>0 /if $char(casting)==FALSE /call SongFailed
/call Circ
/doevents
/delay 0
/goto :Loop
/return
Sub Event_Timer(TimerName)
/if @TimerName==SongTimer {
/if n @SeloSong!=0 /if n $char(buff,"$char(gem,@SeloSong)")==0 {
/delay 2
/stopsong
/cast @SeloSong
/varset PrevSong 0
/varset SongTimer 30
/call Circ
/doevents
/return
}
/if n @SeloSong!=0 /if n $char(buff,"$char(gem,@SeloSong)")!=0 /if n $char(buff,$char(buff,"$char(gem,@SeloSong)"),duration)<=6 {
/delay 2
/stopsong
/cast @SeloSong
/varset PrevSong 0
/varset SongTimer 30
/call Circ
/doevents
/return
}
/delay 2
/stopsong
/cast @Songs(@CurSong)
/varset PrevSong @CurSong
/varadd CurSong 1
/varset SongTimer 30
/call Circ
/doevents
/if n @CurSong>@nSongs /varset CurSong 1
}
/return
Sub Circ
/declare CirX local
/declare CirY local
/if n @TargetUpNext!=0 {
/varset CirX $spawn(@TargetUpNext,y)
/varset CirY $spawn(@TargetUpNext,x)
/if n $spawn(@TargetUpNext,distance)<=$calc(@CirR*2) {
/if $target()==TRUE {
/if n $target(id)!=@TargetUpNext {
/target id @TargetUpNext
}
} else {
/target id @TargetUpNext
}
/varset TargetUpNext 0
}
}
/if n $target(id)>0 {
/varset CirX $target(y)
/varset CirY $target(x)
}
/if n $distance(@CirX,@CirY)<$calc(@CirR/2) {
/face heading $calc($heading(@CirX,@CirY)+180)
} else {
/face heading $calc($heading(@CirX,@CirY)+$calc(90*$calc(@CirR/$distance(@CirX,@CirY))))
}
/return
Sub SongFailed
/if n @PrevSong==0 {
/varset SongTimer 1
/return
}
/varset CurSong @PrevSong
/varset SongTimer 1
/return
Sub Event_NeedTarget
/if n @TargetUpNext<=0 /call GetTarget
/return
Sub Event_Died
/delay 10
/sit
/delay 10
/camp desktop
/return
Sub Event_Exp
/varset AAExp $calc($char(aa,exp)-@AAExp)
/varset Exper $calc($char(exp)-@Exper)
/echo EXP: @Exper%:$char(exp)% - AAXP: @AAExp%:$char(aa,exp)% - $calc($running/60) minutes
/varset Exper $char(exp)
/varset AAExp $char(aa,exp)
/varset DBLevel $int($calc($calc($char(level)*.7)+1))
/if n @TargetUpNext==0 /if n $target(id)==0 /call gettarget
/return
Sub GetTarget
/declare LastMobID local
/declare FirstMobID local
/declare MobID local
/declare SRadius local
/varset MobID 0
/varset FirstMobID 0
/varset LastMobID 0
/varset MobID $searchspawn(npc,radius:$calc(@CirR*2))
/varset FirstMobID @MobID
:CheckAggrodMobs
/if n @MobID!=0 {
/if n $spawn(@MobID,speed)>100 {
/call AvoidTargets @MobID
/if n $return==1 {
/target id @MobID
/echo Kiting aggro'd mob: $target(name,clean)
/return
}
}
/varset LastMobID @MobID
/varset MobID $searchspawn(npc,id:@LastMobID,radius:$calc(@CirR*2),next)
/if n @FirstMobID==@MobID {
/goto :NoAggrodMobs
}
/goto :CheckAggrodMobs
:NoAggrodMobs
}
/varset MobID 0
/varset FirstMobID 0
/varset LastMobID 0
/for SRadius 0 to 10000 step 100
/if n @MobID==0 {
/varset MobID $searchspawn(npc,range:@DBLevel:$char(level),loc:@RubberX:@RubberY,radius:@SRadius)
/varset FirstMobID @MobID
} else {
/varset LastMobID @MobID
/varset MobID $searchspawn(npc,range:@DBLevel:$char(level),id:@LastMobID,loc:@RubberX:@RubberY,radius:@SRadius,next)
/if n @FirstMobID==@MobID {
/next SRadius
}
}
/if n @MobID!=0 {
/call AvoidTargets @MobID
/if n $return==1 {
/goto :Done
}
}
/next SRadius
/echo No mobs found, action required!
/beep
/echo Ending Macro
/beep
/endmac
:Done
/varset TargetUpNext @MobID
/echo Next: $spawn(@MobID,level) $spawn(@MobID,name,clean) - Distance: $spawn(@MobID,distance)
/return
Sub AvoidTargets(TempMobID)
/declare Element local
/varset Element 0
:AvoidCheckLoop
/if "@AvoidList(@Element)"=="UNDEFINED-ARRAY-ELEMENT" {
/return 1
}
/if "@AvoidList(@Element)"=="$spawn(@TempMobID,name,clean)" {
/return 0
}
/varadd Element 1
/goto :AvoidCheckLoop
/return 1
Sub AvoidINIRemove(RemoveName)
/declare TempElements local
/declare TempVar local
/declare TempItem local
/varset TempVar 0
/varset TempElements 0
:RemCheckLoop
/varset TempItem "$ini("AvoidList.ini","Avoid","$int(@TempVar)")"
/if "@TempItem"=="NOTFOUND" {
/echo "@RemoveName" not in AvoidList.ini
/goto :RemFoundInArray
}
/if "@TempItem"=="@RemoveName" {
/varset AvoidList(@TempVar) "Empty"
/echo "@RemoveName" removed from AvoidList.ini
/ini "AvoidList.ini" "Avoid" "$int(@TempVar)" "Empty"
:VerifyRemoval
/if "$ini("AvoidList.ini","Avoid","$int(@TempVar)")"!="Empty" {
/goto :VerifyRemoval
}
/goto :RemFoundInArray
}
/varadd TempVar 1
/goto :RemCheckLoop
:RemFoundInArray
/return
Sub AvoidINIAdd(AddName)
/declare TempElements local
/declare TempVar local
/declare TempItem local
/varset TempVar 0
/varset TempElements 0
:AddCheckLoop
/varset TempItem "$ini("AvoidList.ini","Avoid","$int(@TempVar)")"
/if "@TempItem"=="NOTFOUND" {
/varset AvoidList(@TempVar) "@AddName"
/goto :AddItem
}
/if "@TempItem"=="@AddName" {
/echo "@AddName" already in AvoidList.ini
/goto :FoundInArray
}
/if "@TempItem"=="Empty" {
/varset AvoidList(@TempVar) "@AddName"
/goto :AddItem
}
/varadd TempVar 1
/goto :AddCheckLoop
:AddItem
/ini "AvoidList.ini" "Avoid" "$int(@TempVar)" "@AddName"
:VerifyAdd
/if "$ini("AvoidList.ini","Avoid","$int(@TempVar)")"!="@AddName" {
/goto :VerifyAdd
}
/echo "@AddName" added to AvoidList.ini
:FoundInArray
/return
Sub AvoidINILoad
/declare TempItem local
/declare AvoidItemNum local
/varset AvoidItemNum 0
:LoadAvoidLoop
/varset TempItem "$ini("AvoidList.ini","Avoid","$int(@AvoidItemNum)")"
/if "@TempItem"=="NOTFOUND" {
/goto :DoneLoading
}
/varset AvoidList(@AvoidItemNum) "@TempItem"
/varadd AvoidItemNum 1
/goto :LoadAvoidLoop
:DoneLoading
/return
Sub Event_AddAvoid(EvtText)
/if "$mid(6,10,"@EvtText")"=="avoid add " {
/call AvoidINIAdd "$mid(16,$calc($strlen("@EvtText")-16),"@EvtText")"
}
/return
Sub Event_RemoveAvoid(EvtText)
/if "$mid(6,13,"@EvtText")"=="avoid remove " {
/call AvoidINIRemove "$mid(19,$calc($strlen("@EvtText")-19),"@EvtText")"
}
/return
Sub Event_Pause(EvtText)
/if "$mid(6,5,"@EvtText")"=="pause" {
/if n @PauseFlag==0 {
/echo Script [PAUSED]
/varset PauseFlag 1
} else {
/echo Script [UNPAUSED]
/varset PauseFlag 0
}
}
/return
Sub Event_Caster(CastText)
/declare CasterID local
/varset CasterID $searchspawn(name,"$left($calc($strlen("@CastText")-24),"@CastText")")
/if $spawn(@CasterID,type)!=NPC /return
/if n $target(id)==@CasterID /return
/if n $spawn(@CasterID,distance)<=$calc(@CirR*2) {
/target id @CasterID
/echo Targeting Caster: $spawn(@CasterID,name,clean)
}
/return

Does it really make any difference how long lev lasts? We could just check for about to fall event and either find/use SS boots or Lev song based on another variable in the command line. My reasoning behind this is that I beleive that Lev is variable and can drop just like invis.Raebis wrote:how long does levitate last? gonna add levitate support that autodetects if you have singing steel boots, levi song memed, etc...
Code: Select all
#event Levitate "You feel as if you are about to fall" Code: Select all
Sub Event_Levitate
(if lev is set)
(if lev is SS)
(find/click SS boots)
(end if)
(if lev is spellslot)
(cast spellslot)
(end if)
(end if)
/returnBard lev and invis songs are not variable, though. And... you don't want lev to actually drop... you want to catch it before it does drop.drax wrote:Does it really make any difference how long lev lasts? We could just check for about to fall event and either find/use SS boots or Lev song based on another variable in the command line. My reasoning behind this is that I beleive that Lev is variable and can drop just like invis.
I don't think this is the problem, though. It appears to be far more cyclical than I would expect for a packet loss scenario.dont_know_at_all wrote:When you play Selos, the client sends a notification to the server that you have completed the song and the server replies that it is okay to speed up. As far as can tell, one of these packets goes missing. It's an annoying bug that has nothing to do with MQ. Check some of the bard forums.