Shaman Auto-Canni/Slow/Haste/DoT/Healer/etc.. UPDATE 8/14/04

Post your completed (working) macros here. Only for macros using MQ2Data syntax!

Moderator: MacroQuest Developers

dedpoet
a hill giant
a hill giant
Posts: 247
Joined: Sat Aug 14, 2004 12:22 pm

Post by dedpoet » Sat Aug 14, 2004 3:46 pm

Thanks for the answer and for the fix. I'm playing with this trying to improve a few things. Breaking up the spell gems saves a lot of spell swapping and I'm also looking at making the DoT routine a bit less aggressive. Tossing a DoT immediately after the slow lands is stealing aggro every time for me.

Great macro!

dedpoet
a hill giant
a hill giant
Posts: 247
Joined: Sat Aug 14, 2004 12:22 pm

Post by dedpoet » Sun Aug 15, 2004 11:23 am

I made a few changes to this for my needs that I think are good general improvements. Feel free to use them or not, if you'd like.

~ I changed what spell gems are used for what purposes to greatly reduce spell swapping. Just change the gem# in each routine to whatever you would like. I found this works best for me:

1. Heal (note you have to change this in the heal and the canni routines)
2. Heal over Time
3. Canii
4. Malo
5. Slow
6. Disempower/Pet/Bear/Buff (have to change several places)
7. DoT
8. DD

~ I added configurable percentages to start DoT'ing and DD'ing because I found that my monk was losing aggro with a big dot being cast immediately after slow. This lets you tweak the aggresiveness a little bit depending on who your tank is, what you're fighting, etc.:

below this:

Code: Select all

/declare DotArray[1] string outer
/varset DotArray[1] "Your DoT Spell Here"
/declare timestotry outer 2
add this (change 80 to whatever you want):

Code: Select all

/declare Dotpercent outer 80
below this:

Code: Select all

/declare DDArray[1] string outer
/varset DDArray[1] "Your DD Spell Here"
add this (change the 50 to whatever you want):

Code: Select all

/declare DDpercent outer 50
Change Sub DoTs to this:

Code: Select all

Sub DoTs
/if (${malotoggle}==1 || ${slowtoggle}==1 || ${powertoggle}==1) {
   /if (${needmalo}==1 || ${needslow}==1 || ${needpower}==1) /return
}
   /if (${Dotted}==0 && ${Target.PctHPs}<${Dotpercent}) {
      /for g 1 to ${DotArray.Size}
      /varset SpellName ${DotArray[${g}]}
      /call DotTarget
|      /varadd tried 0
      /next g
      /varset Dotted 1
   }
/return
Note that there is something wrong with "tried", which is why it's commented out. Currently, if the DoT is resisted I get an error in the window about not being able to parse varadd tried 0, and it just recasts it until it lands. I haven't figured it out yet, so the line is still commented out.

Change Sub DD to this:

Code: Select all

Sub DD
/if (${malotoggle}==1 || ${slowtoggle}==1 || ${powertoggle}==1 || ${dottoggle}==1) {
   /if (${needmalo}==1 || ${needslow}==1 || ${needpower}==1 || ${Dotted}==0) /return
}
   /if (${Target.PctHPs}<${DDpercent}) {
     /for g 1 to ${DDArray.Size}
     /varset SpellName ${DDArray[${g}]}
     /varset wait4cast ${Math.Calc[${Spell[${SpellName}].MyCastTime}+${Spell[${SpellName}].RecastTime}+5].Int}
     /call checkmana
     /call sitstatus
     /call cast ${SpellName} gem8 ${wait4cast}s
     /if (${sitstatus}==1) /call standstatus
     /if (${healertoggle}==1) /call Healer
     /next g
   }
/return
Next steps will be to figure out why it's not counting the number of DoT attempts properly and then work on the heal routine to make it a bit smarter once my shaman hits 65. Does anyone out there have a shaman heal routine that effectively uses Quiescence and a patch heal like Tnarg's?

I hope these small contributions help someone else. This tool has been a great help for me.

rencro
Custom Builder
Custom Builder
Posts: 56
Joined: Sat Sep 27, 2003 12:39 am

Post by rencro » Sun Aug 15, 2004 1:33 pm

Cant log on and check today, and have work early tomorrow but dedpoet, might give this a try, not sure though..

Code: Select all

Sub DoTs
/if (${malotoggle}==1 || ${slowtoggle}==1 || ${powertoggle}==1) {
   /if (${needmalo}==1 || ${needslow}==1 || ${needpower}==1) /return
}
   /if (${Dotted}==0 && ${Target.PctHPs}<${Dotpercent}) {
      /for g 1 to ${DotArray.Size}
      /varset SpellName ${DotArray[${g}]}
      

       /varset tried 0
      

        /call DotTarget
|      /varadd tried 0 || not sure if varadding here is good idea if using multiple dots

      /next g
      /varset Dotted 1
   }
/return
This should declare the variable "tried" before the call to DotTarget.

Then in DotTarget, for T/S'ing untill you get it going try:

Code: Select all

Sub DotTarget
   /varset wait4cast ${Math.Calc[${Spell[${SpellName}].MyCastTime}+${Spell[${SpellName}].RecastTime}+5].Int}
   :retrycast
   /if (${timestotry}>${tried}) {
      
/echo This is Retry ${tried} out of ${timestotry}
    

      /call checkmana
      /call sitstatus
      /call cast ${SpellName} gem5 ${wait4cast}s
      /doevents
      /if (${String[${Macro.Return}].Equal[CAST_RESISTED]}) {
         /varadd tried 1
         /if (${healertoggle}==1) /call Healer
         /goto :retrycast
      }
      /if (${sitstatus}==1) /call standstatus
   }
/return
Echo really isnt neccesary, I just like feedback on where Im at..
This should attempt to cast your spell a max 3 times if your ${timestotry}=2

Lemme know

loadingpleasewait
a snow griffon
a snow griffon
Posts: 332
Joined: Sat Sep 14, 2002 8:46 am

Post by loadingpleasewait » Sun Aug 15, 2004 8:46 pm

rencro wrote:Cant log on and check today, and have work early tomorrow but dedpoet, might give this a try, not sure though..

Code: Select all

Sub DoTs
/if (${malotoggle}==1 || ${slowtoggle}==1 || ${powertoggle}==1) {
   /if (${needmalo}==1 || ${needslow}==1 || ${needpower}==1) /return
}
   /if (${Dotted}==0 && ${Target.PctHPs}<${Dotpercent}) {
      /for g 1 to ${DotArray.Size}
      /varset SpellName ${DotArray[${g}]}
      

       /varset tried 0
      

        /call DotTarget
|      /varadd tried 0 || not sure if varadding here is good idea if using multiple dots

      /next g
      /varset Dotted 1
   }
/return
This should declare the variable "tried" before the call to DotTarget.

Then in DotTarget, for T/S'ing untill you get it going try:
It shouldnt matter whether your /varset is before or after the dottarget sub, all that does really is reset the tried variable to 0 for the next dot to use. /varadd 0 wouldnt do anything.. it would add 0 to the current tried count, which would add nothing :D

dedpoet, what you would need to do to make the tried/timestotry work is change your /varadd tried 0 to /varset tried 0. making your new subroutine be as follows.

Code: Select all

Sub DoTs 
/if (${malotoggle}==1 || ${slowtoggle}==1 || ${powertoggle}==1) { 
   /if (${needmalo}==1 || ${needslow}==1 || ${needpower}==1) /return 
} 
   /if (${Dotted}==0 && ${Target.PctHPs}<${Dotpercent}) { 
      /for g 1 to ${DotArray.Size} 
      /varset SpellName ${DotArray[${g}]} 
      /call DotTarget 
      /varset tried 0 
      /next g 
      /varset Dotted 1 
   } 
/return
its funny, the dot is somthing thats always seemed to just work out of box.. Alot of this macro took alot of tweeking to get it to work sorta right, but the dot routine worked just like I wanted without changing anything.

One thing I added to my version that isnt in the posted version, is to heal pets, and my pet.. I found I kept letting my pet die :P if you want that, here ya go..

Code: Select all

Sub Healer
/varset SpellName ${Healspell}
/varset wait4cast ${Math.Calc[${Spell[${SpellName}].MyCastTime}+${Spell[${SpellName}].RecastTime}+5].Int}
               /for g 1 to ${Group}
               /if (${Group[${g}].ID} && ${Group[${g}].PctHPs}<${healgrouppct}) {
               /call checkmana
               /if (${Me.PctHPs}<${HoTpercent}) /call Canni
               /call sitstatus
               /target PC ${Group[${g}]}
               /if (${verbose}==1) /gsay ${HealGroupVerbosity}
               /call Cast ${SpellName} Gem6 ${wait4cast}s
               /if (${sitstatus}==1) /call standstatus
               /keypress esc
               /if (${battle}==1) /target ${targetarray[3]}   
         }
         /next g
            /for g 1 to ${Group}
               /if (${Group[${g}].Pet.ID} && ${Group[${g}].Pet.PctHPs}<${healgrouppct}) {
               /call checkmana
               /call sitstatus
               /target Pet ${Group[${g}].Pet}
               /if (${verbose}==1) /gsay ${HealGroupVerbosity}
               /call cast ${SpellName} gem2 ${wait4cast}s
               /if (${sitstatus}==1) /call standstatus
               /keypress esc
               /if (${battle}==1) /target ${targetarray[3]}   
               }
            /next g
               /if (${Me.Pet.ID} && ${Me.Pet.PctHPs}<${healgrouppct}) {
               /call checkmana
               /call sitstatus
               /target Pet ${Me.Pet}
               /if (${verbose}==1) /gsay ${HealGroupVerbosity}
               /call cast ${SpellName} gem2 ${wait4cast}s
               /if (${sitstatus}==1) /call standstatus
               /keypress esc
               /if (${battle}==1) /target ${targetarray[3]} 
            }              
/return
I didnt add a seperate heal percent for pets yet, it would be easy to add, but I wrote it in on the fly last night, didnt want to go through adding the extra variables.. :cool:


Thats all I got for now.. the only other thing I added to my version is the fake link plugin, and added highlighted text to my verbositys :P
LOADING PLEASE WAIT...

rencro
Custom Builder
Custom Builder
Posts: 56
Joined: Sat Sep 27, 2003 12:39 am

Post by rencro » Sun Aug 15, 2004 11:14 pm

Hmm. Yea thats right, tried was getting reset to 0 after the return from DotTarget, and the initial value was 0 as declared, bah... :oops:

dedpoet
a hill giant
a hill giant
Posts: 247
Joined: Sat Aug 14, 2004 12:22 pm

Post by dedpoet » Mon Aug 16, 2004 2:04 am

Thanks for the help and the additions. I might be able to test everything thoroughly tomorrow. One thing I noticed in loading's new healer sub is that you use 2 different spell gems, 1 for healing people and 1 for healing pets, yet they are defined as the same spell. That causes unneeded spell swapping. If you're using Kragg's, adding 2 or 3 seconds to a 10 second cast could be the end of you =) All of my big heal calls use the same gem, with a different one for heal over time. I'm still interested to see a level 65 heal routine that uses Q and another heal though...I imagine it would be easier with something that watches text, and this macro is really only looking at effects on itself and its pet.

loadingpleasewait
a snow griffon
a snow griffon
Posts: 332
Joined: Sat Sep 14, 2002 8:46 am

Post by loadingpleasewait » Mon Aug 16, 2004 5:52 am

Bah! :D

Another of my cut and paste dealys.. I guess it never really affected me much because when my HEAL is already memmed in one of the gems, it doesnt move it.. I'll go through and reassign my spell gems when I get a chance..

Oh well..
LOADING PLEASE WAIT...

dedpoet
a hill giant
a hill giant
Posts: 247
Joined: Sat Aug 14, 2004 12:22 pm

Post by dedpoet » Wed Aug 18, 2004 11:17 am

I'm continuing to refine this for my needs, the more I use it. The latest thing I've come across is a few issues with the malo process.

If I have malo and slow both turned on, it always canni's in between, which I don't want, as it adds several seconds before a slow due to the cast time on Canni4. I'm still learning this code, but I'm pretty sure it's because at the end of the malo sub, it calls healer if it's on, which then returns to the main loop. Since Canni comes before Debuff in the main loop, I get the canni in between malo and slow. Does anyone see a problem with taking the call to healer after the malo out? Will that make it move right on to slow, or will that cause other problems?

Also, I noticed that my bot isn't calling out when a malo lands. I'm pretty sure it's because of this:

Code: Select all

/if (${verbose}==1 && ${Target.ID}==${targetarray[4]} && ${needmalo}==0 && ${Me.Gem[Malaisement]}) {
   /gsay ${MaloVerbosity}
Is it safe to change [Malaisement] to [${Malospell}]? To be honest, I'm not sure I uderstand what that check is doing.

And finally, there is still a problem with recasting the DoT if it is resisted, even with the changes posted above. When a DoT is reisted, I still get this, (my line numbers will be a bit different than standard), and then it casts again. It seems to move on after it lands, but it's doesn't seem to try the correct number of times. It just recasts until it lands. I usually want that anyway, but I'd like to get rid of the error...

Code: Select all

Couldn't parse /varadd tried 1
@452 (DotTarget) /varadd tried 1
@436 (DoTs) /call DotTarget
@337 (battle) if ($(dottoggle)==1) /call dots
@297 (main) /call battle
Any ideas what might be going on with that?

** Edited for formatting **

dedpoet
a hill giant
a hill giant
Posts: 247
Joined: Sat Aug 14, 2004 12:22 pm

Post by dedpoet » Wed Aug 18, 2004 12:54 pm

Actually, now that I look at this more, it's going to call Canni before Slow even if Healer is not on. I'm just going to bump the /call canni down a few spots in Main and see how that works out.

loadingpleasewait
a snow griffon
a snow griffon
Posts: 332
Joined: Sat Sep 14, 2002 8:46 am

Post by loadingpleasewait » Wed Aug 18, 2004 5:01 pm

dedpoet wrote: It seems to move on after it lands, but it's doesn't seem to try the correct number of times. It just recasts until it lands. I usually want that anyway, but I'd like to get rid of the error...

Code: Select all

Couldn't parse /varadd tried 1
@452 (DotTarget) /varadd tried 1
@436 (DoTs) /call DotTarget
@337 (battle) if ($(dottoggle)==1) /call dots
@297 (main) /call battle
Any ideas what might be going on with that?
Should be

Code: Select all

/varset tried 0
/call DotTarget
I'll log in tonight and see what the dot routine is doing..


What I did with the call to canni during the battle subroutine, is I set it to only call canni after the target has been slowed..

Code: Select all

  :battleloop 
         /call LoM
         /if (${pettoggle}==1 && ${petsent}==0 && ${Target.PctHPs}<${sendpethp}) {
            /pet attack
            /varset petsent 1
         }
         /if (${healertoggle}==1) /call Healer 
         /if (${siting}==1 && !${Me.State.Equal[SIT]}) /sit
         /if (${Me.Combat}) /attack off
         /if (${malotoggle}==1 || ${slowtoggle}==1 || ${powertoggle}==1) /call DeBuffs
         /if (${dottoggle}==1) /call DoTs 
         /if (${ddtoggle}==1) /call DD

| change the call CANNI to this.. 

         /if (${slowtoggle}==1 && ${needslow}==0) {
            /call canni
         } else {
            /if (${slowtoggle}==0) /call canni
         }

| End cut and paste...  

         /if (!${Target.Name.Equal[${targetarray[3]}]} || !${Target.ID}) /goto :endbattle 
         /doevents 
         /goto :battleloop 
and you can get rid of the ${Me.Gem[Malaisement]} all together in that if.. I honestly dont know why I put it in there?!? I may be a sloppy macro writer, but hey, it does the job.... (most of the time) :D
LOADING PLEASE WAIT...

mcswanbeck
a lesser mummy
a lesser mummy
Posts: 70
Joined: Fri Jan 16, 2004 5:16 am

Post by mcswanbeck » Fri Aug 20, 2004 10:36 am

This looks quite awesome... Big kudos for the work put into this...

BUT... :P

I have EP pants (with clicky dot "Pox of Bertoxxulous") and ornate BP (with clicky haste "Swift like the Wind")... Maybe add the dot on the shaman epic too... This macro only use spells, it would be mighty nice if you could say that some of the spells are for items instead...
Kinda like you can do with the CanniV AA...

Also, though I'm a bit unsure about this as I might have missed something, then the HoT spells is only used in conjuction with canni... I like to duo in i.e. Plane of Hate, where I even have my shaman out of group. The HoT spell is sufficient when xping in this zone, so there isn't really a need for using heal spells... It would be awesome if this macro could cast a Quiescence on my toon when he goes under 75% (and of course not recast Q untill the one just casted has worn off)...

I understand adding the above two issues are difficult, but it would really rock ;)
/mcswanbeck

Mimatas
a hill giant
a hill giant
Posts: 262
Joined: Wed Mar 10, 2004 4:22 pm

Post by Mimatas » Fri Aug 20, 2004 12:27 pm

I think Spell_Routines.inc handles all of that. It may not be as hard as it initially seems

dedpoet
a hill giant
a hill giant
Posts: 247
Joined: Sat Aug 14, 2004 12:22 pm

Post by dedpoet » Fri Aug 20, 2004 4:13 pm

spell_routines.inc does, in fact, handle click items:

Code: Select all

/call cast "Spear of Fate" item
I have an epic dot click toggle in my own copy of this macro, but I haven't tested it out, as I won't be able to play until at least Sunday. It's very simple in theory - I just added a new sub called Epicdot, and I call it in the battle loop just before the normal dot sub. I only have it try to cast once, since the cast time is so long.

What I'm wondering now (I'm still new to this) is if you could put an item click in as part of your defined dot array. For example, could your dot array look like this?

Code: Select all

/declare DotArray[2] string outer
/varset DotArray[1] "Spear of Fate" item
/varset DotArray[2] "Rosrak's Greaves of the Primal" item
I don't see why not, since the macro just calls the cast routine in spell_routines.inc, which supports it. Give it a shot - worst case is you get an error. I still like having the epic toggle separate though, because the dot sub will recast each dot until it lands, or exceeds your timestotry. That could take too long with click dots. Of course, you could always just set that to 1...

As for the healing, I'm trying to work out a smarter healer routine, but I am not 65 with Q yet, so it's only a theory right now. It gets fairly complex when you get into this because if you want the macro to be flexible you have to allow for lower level people who don't want to cast their slowing and snaring HoT on people in battle. The AFCleric macro already does something like this. I invision making another toggle on the macro called HoTHealer or something like that. You would use that instead of healer once you had Q. It would use Q/Trushar/whatever to heal as long as the tank stayed at reasonable health, and patch with a Tnarg's/Daluda's when he gets low.

The other complexity with HoT's is that you don't have a convenient way to tell when the first one wore off. There is no message to the healer, and MQ can't really tell what buffs are on another character. I'd love to hear ideas on this.

I'll probably see what I can do in a few more levels. :-)

loadingpleasewait
a snow griffon
a snow griffon
Posts: 332
Joined: Sat Sep 14, 2002 8:46 am

Post by loadingpleasewait » Fri Aug 20, 2004 10:47 pm

/varadd problem.. there isnt a /varadd command anymore? at least not that I can see.. seeking more info on this..
LOADING PLEASE WAIT...

mcswanbeck
a lesser mummy
a lesser mummy
Posts: 70
Joined: Fri Jan 16, 2004 5:16 am

Post by mcswanbeck » Sat Aug 21, 2004 9:13 am

dedpoet wrote:

Code: Select all

/declare DotArray[2] string outer
/varset DotArray[1] "Spear of Fate" item
/varset DotArray[2] "Rosrak's Greaves of the Primal" item
This would indeed work when you remove the "gem1-8" from the actual cast rutines, however when adding the word "item" after those variables, then you can no longer use that variable to find i.e. the casting time for the spell.

I tried to make new arrays and variables, like hotspell_gem, healspell_gem, dotgemarray and then set them to either "gem1-8" or "item" and that also works, however I believe there must be a better way around it.
/mcswanbeck