advchant.mac - Advanced Chant REV7

A forum for you to dump all the macros you create, allowing users to use, modify, and comment on your work.

Moderator: MacroQuest Developers

El
a ghoul
a ghoul
Posts: 108
Joined: Mon Dec 29, 2003 12:34 pm

Post by El » Thu Jan 08, 2004 12:26 am

Raebis, I spent some time testing rev 5c tonight. Everything seems to be working wonderfully! However, you know I'd have a few comments :-)

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.

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.

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.

All I can think of for now. As always, wonderful job!

Space-Boy
a hill giant
a hill giant
Posts: 242
Joined: Wed Dec 04, 2002 12:53 pm
Contact:

Post by Space-Boy » Thu Jan 08, 2004 4:13 am

just a simple question

i 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?

thanks
-spaceboy
You have gotten better at Carpal Tunnel! (247)

Sporked
orc pawn
orc pawn
Posts: 28
Joined: Tue Jan 06, 2004 7:08 am

Chant Rev 5c-icehouse.0 Ready for bruising

Post by Sporked » Thu Jan 08, 2004 1:55 pm

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
Last edited by Sporked on Sat Jan 10, 2004 10:42 am, edited 1 time in total.

Raebis
a ghoul
a ghoul
Posts: 81
Joined: Fri Dec 12, 2003 6:23 am

Post by Raebis » Thu Jan 08, 2004 4:04 pm

El 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.
Alert/noalert lists shoudl be an easy implement. I quickly added this as a test when i was hunting epic mobs for a friend

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.
how long does levitate last? gonna add levitate support that autodetects if you have singing steel boots, levi song memed, etc...
Space-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?
check here
Always say what you want to say. Because those who mind, don't matter. And those who matter, don't mind.

El
a ghoul
a ghoul
Posts: 108
Joined: Mon Dec 29, 2003 12:34 pm

Post by El » Fri Jan 09, 2004 12:23 pm

Couple of more items that came up during my test last night:

1. Still some "you haven't recovered yet" messages running by. Much reduced from previously, though.

2. I wonder if it would make sense to prioritize targets? I got a bunch of ulthorks chasing me last night, and a few green walruses. The macro kept picking the walruses (proximity based?) over the ulthorks. Really cuts down on the xp gained/hour. I'd rather see it go after higher level targets first, and then clear agro'ed greens before picking a new blue.

3. It occurred to me that you have 90% of the basics for a swarm kiting macro at this point. Just something to consider.

4. If you do levitate, it might make sense to also check for Amp as well. Another 5-tick song that needs its own timer.

SkiD_PL8
decaying skeleton
decaying skeleton
Posts: 5
Joined: Fri Dec 26, 2003 4:54 am

Post by SkiD_PL8 » Sat Jan 10, 2004 10:46 am

This macro I am sure is great for lower level bards but it is flat out useless for me as a 65 bard simply for the fact that it will attack ANY dark blue mobs. I would love to use this in say plane of storms for kiting the frogs but I can't because it will grab trees, bears, snakes, and giants as well. I don't know if it is possible but could you make it where you could specify a certain type or a few certain types of mobs and it would only pull those? If anyone can help me with this it would be greatly appreciated. Thank you for your time in advance.

EDIT: Forgot to note that the reason this is a problem is because at 65 most Dark Blue mobs summon.
______________________________________
Mind over matter, if you don't mind it doesn't matter...

ml2517
a grimling bloodguard
a grimling bloodguard
Posts: 1216
Joined: Wed Nov 12, 2003 1:12 am

Post by ml2517 » Sat Jan 10, 2004 12:52 pm

<== Bored.

So I'm working on the mob avoidance code right now. I'll post it later today if I get it done.

Drunkensloth
a lesser mummy
a lesser mummy
Posts: 67
Joined: Sat Oct 18, 2003 2:54 am

Post by Drunkensloth » Sat Jan 10, 2004 2:52 pm

whats the lowest level bard you could run this on?
And here I was clicking like a sucker!

ml2517
a grimling bloodguard
a grimling bloodguard
Posts: 1216
Joined: Wed Nov 12, 2003 1:12 am

Post by ml2517 » Sat Jan 10, 2004 6:12 pm

This is a test version with Mob avoidance routines added in. Please read the entire description at the top of the script so that you understand how it works.

If/when this is deemed to be working 100 percent I'll ask Raebis to replace the script on the main page and delete this one.

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 

El
a ghoul
a ghoul
Posts: 108
Joined: Mon Dec 29, 2003 12:34 pm

Post by El » Sun Jan 11, 2004 2:54 am

Still something funny going on with the level 6 Selo's. I was trying rev 5c tonight, and put in 3 dots + Selos... al la:

/macro chant 1234 0 95 5

Where 1-3 were chants, 4 was lvl 6 Selo's, and 5 was Hymn.

I was seeing Selo's drop regularly, as I would expect with 4 songs, but occasionally, it would not be the most immediate song to be played, but the macro would cycle through the 3 dots before casting Selo's. If I understood your comments earlier, I thought you were trying to make it so that Selo's would be inserted into the song queue if it was in danger of wearing off. That doesn't seem to be happening.

Also, I purposely targeted myself while kiting, and it didn't retarget the closest mob.

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Sun Jan 11, 2004 4:18 am

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.

drax
orc pawn
orc pawn
Posts: 12
Joined: Wed Oct 15, 2003 12:02 am

Post by drax » Sun Jan 11, 2004 11:38 am

Raebis wrote:how long does levitate last? gonna add levitate support that autodetects if you have singing steel boots, levi song memed, etc...
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.

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)
/return

SkiD_PL8
decaying skeleton
decaying skeleton
Posts: 5
Joined: Fri Dec 26, 2003 4:54 am

Post by SkiD_PL8 » Sun Jan 11, 2004 1:09 pm

I am getting ready to test the mob avoidance. I have one more suggestion is there anyway you could do the opposite and make it where you take a list of only the mobs you want to kill?
______________________________________
Mind over matter, if you don't mind it doesn't matter...

El
a ghoul
a ghoul
Posts: 108
Joined: Mon Dec 29, 2003 12:34 pm

Post by El » Sun Jan 11, 2004 1:44 pm

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.
Bard 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.

I believe lev lasts for 5 ticks.

El
a ghoul
a ghoul
Posts: 108
Joined: Mon Dec 29, 2003 12:34 pm

Post by El » Sun Jan 11, 2004 1:45 pm

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.
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.