Page 1 of 2

Efficient Macro Buff-Checking Buffer

Posted: Thu Oct 28, 2004 3:18 am
by Night Hawk
Well I was messing around with a buffing macro, and thought why not find a way to avoid adding an IF statement each time I find a buff that doesn't stack. AND, made it fairly easy to add more :)

Anyhow, here's some snippets of the code.

Code: Select all

#include spellcast.inc

#define B_AC     "Shifting Shield"

#define B_Virtue "Virtue"
#define B_Conviction "Conviction"

Sub Main

|-- Ammount of buffs that do not stack with AC
/declare ${Spell[B_AC].ID}_Ammount int outer 2
|-- Names from #define list
/declare ${Spell[B_AC].ID}_Unstack string outer B_Virtue|B_Conviction

|Buffs to be kept up on self
/declare NumberOfBuffs int outer 1
/declare MyBuffs[${NumberOfBuffs}] string outer
/varset MyBuffs[1] B_SD

|-- Buffs to be kept on pet
/declare NumberOfPetBuffs int outer 1
/declare PetBuffs[${NumberOfPetBuffs}] string outer
/varset PetBuffs[1] B_AC

/call MaintainBuffs

/return

Sub MaintainBuffs
/declare PetBuffLoop    int outer  0
/declare MyBuffLoop    int outer  0
/declare iCount int outer 1
/declare c int outer

   /for MyBuffLoop 1 to ${NumberOfBuffs}
      /if (!${Me.Buff["${MyBuffs[${iCount}]}"].ID}) {
         /for c 1 to ${${Spell[${MyBuffs[${iCount}]}].ID}_Ammount}
            /if (${Me.Buff["${${Spell[${MyBuffs[${iCount}]}].ID}_Unstack.Arg[${c},|]}"].ID}) /goto :SkipSpell
         /next c

         /target myself
         /call Cast "${MyBuffs[${iCount}]}" gem6
         /delay 1s
         :SkipSpell
         /doevents
      }
      /varcalc iCount ${iCount}+1
   /next MyBuffLoop

   /varset iCount 1
   
   /for PetBuffLoop 1 to ${NumberOfPetBuffs}
      /if (!${Me.PetBuff["${PetBuffs[${iCount}]}"]}) {
         /for c 1 to ${${Spell[${PetBuffs[${iCount}]}].ID}_Ammount}
            /if (${Me.PetBuff["${${Spell[${PetBuffs[${iCount}]}].ID}_Unstack.Arg[${c},|]}"]}) /goto :SkipSpell
         /next c

         /target ${Me.Pet.Name}
         /call Cast "${PetBuffs[${iCount}]}" gem6
         /delay 1s
         :SkipSpell
         /doevents
      }
      /varcalc iCount ${iCount}+1
   /next PetBuffLoop
   
/return
Probably one of the most out-of-the-way-routes to code it. But hey, I was bored. Can easily duplicated it for doing self buffs as well. The reason I'm using the #define's up at the top, is it makes it MUCH more easier to change your current buff name for your level. So using it from low to high, all you have to do is change the buff names (and of course possibly add more). There is probably a better, and easier way to do this. But it seems to run through it quickly non-the-less.

Enjoy.

(edit) You could also change the /call cast line into an /echo to just have a buff checker, for buff bitching, ect

Posted: Sun Oct 31, 2004 12:47 pm
by Night Hawk
Fixed one little part of the PetBuff part and added self buffs.

Tested it a bunch of a times, seems to be working quite well.

Posted: Sun Oct 31, 2004 12:50 pm
by Night Hawk
Last Updated :: April 12th, 2005

Making a running list of buffs, and buffs that don't stack:

Code: Select all

#define B_SD "Spiritual Dominion"
#define B_DEX "Dexterity"
#define B_STA "Stamina"
#define B_AC "Shifting Shield"
#define B_STR "Furious Strength"
#define B_HP "Talisman of Kragg"
#define B_IOS "Infusion of Spirit"
#define B_SOW "Spirit of Wolf"
#define B_SV "Spiritual Vigor"
#define B_REGEN "Regrowth"
#define B_HASTE "Celerity"
#define B_SELF "Frenzy"
#define B_PROC "Spirit of Rellic"
#define B_PHASTE "Arag`s Celerity"
#define B_ATK "Spiritual Strength"
#define S_PET "Spirit of Sorsha"
#define B_Virtue "Virtue"
#define B_HoV "Hand of Virtue"
#define B_Conviction "Conviction"
#define B_Temperance "Temperance"
#define B_Affirmation "Affirmation"
#define B_Fo7 "Focus of the Seventh"
#define B_Focus "Focus of Soul"
#define B_REGEN2 "Replenishment"
#define B_REGEN3 "Blessing of Replenishment"
#define B_Boar "Talisman of Boar"
#define B_Boar2 "Talisman of Fortitude"
#define B_CHaste "Speed of Vallon"
#define B_CHaste2 "Speed of Salik"
#define B_STR2 "Nature's Might"
#define B_FoE "Flight of Eagles"
#define B_SoE "Spirit of Eagle"
#define B_KEI "Koadic's Endless Intellect"
#define B_BSS "Brell's Stalwart Shield"

/declare ${Spell[B_AC].ID}_Ammount int outer 5
/declare ${Spell[B_AC].ID}_Unstack string outer B_Virtue|B_Conviction|B_HoV|B_Temperance|B_Affirmation
/declare ${Spell[B_DEX].ID}_Ammount int outer 2
/declare ${Spell[B_DEX].ID}_Unstack string outer B_Fo7|B_Focus
/declare ${Spell[B_STR].ID}_Ammount int outer 3
/declare ${Spell[B_STR].ID}_Unstack string outer B_Fo7|B_Focus|B_STR2
/declare ${Spell[B_HP].ID}_Ammount int outer 2
/declare ${Spell[B_HP].ID}_Unstack string outer B_Fo7|B_Focus
/declare ${Spell[B_IOS].ID}_Ammount int outer 2
/declare ${Spell[B_IOS].ID}_Unstack string outer B_Fo7|B_Focus
/declare ${Spell[B_STA].ID}_Ammount int outer 2
/declare ${Spell[B_STA].ID}_Unstack string outer B_Boar|B_Boar2
/declare ${Spell[B_HASTE].ID}_Ammount int outer 2
/declare ${Spell[B_HASTE].ID}_Unstack string outer B_CHaste|B_CHaste2
/declare ${Spell[B_SOW].ID}_Ammount int outer 2
/declare ${Spell[B_SOW].ID}_Unstack string outer B_FoE|B_SoE
/declare ${Spell[B_REGEN].ID}_Ammount int outer 1
/declare ${Spell[B_REGEN].ID}_Unstack string outer B_REGEN3
/declare ${Spell[B_SV].ID}_Ammount int outer 1
/declare ${Spell[B_SV].ID}_Unstack string outer B_BSS
I'll continue to update as I go through it all.

Posted: Sun Oct 31, 2004 1:27 pm
by Cr4zyb4rd
Excellent, I like it.

If you play with String.Count you can get away from having to hard-code the number of buffs of a given type. Also this seems to lend itself easily to an INI file rather than all the hard-coded defines.

Posted: Sun Oct 31, 2004 1:35 pm
by Night Hawk
Was definately thinking about the INI file to make it a bit easier. Could you educate me on the string thing tho?

Posted: Sun Oct 31, 2004 2:01 pm
by Cr4zyb4rd
Suppose i have

Code: Select all

/declare MyString string local Item1|Item2|Item3|Item4
I can then use

Code: Select all

${MyString.Count["|"]}
to return the number of | (and pass this information to the math type or varcalc to give me the total number of items). You're already using .Arg, so this just seemed natural to me. *shrug*

Posted: Sun Oct 31, 2004 4:17 pm
by Night Hawk
I see. I just used code from what I saw around the Macro Depot and experimented. So I just gotta use the ${MyString.Count["|"]} and add 1 to it. I'll try it out

Posted: Wed Nov 17, 2004 12:20 pm
by Night Hawk
Well I was having trouble with the pet buffs, and it was just a lil typ-o :?

/if (${Me.PetBuff["${String[${${Spell[${PetBuffs[${iCount}]}].ID}_Unstack}].Arg[${c},|]}"]}) { /goto :SkipSpell
never gave me any syntax error. All better now tho :)

Great Macro I borrowed it for my program.

Posted: Wed Dec 01, 2004 3:17 pm
by gonemental21
http://www.macroquest2.com/phpBB2/viewtopic.php?t=9230

Will have to tweak it for all the beast buffs though.

Posted: Sun Dec 05, 2004 8:20 pm
by Night Hawk
Guess you missed the part of this being a Snippets forum that topic being a whole seperate macro. Plus that code doesn't check against buffs that don't stack.

Posted: Mon Dec 06, 2004 3:37 am
by insanitywiz
I think he meant to say something along the lines of awsome, borrowing it for my macro, he just said it in his topic rather then the body of his message.

Posted: Tue Apr 12, 2005 1:33 pm
by Night Hawk
Updated the running list above a bit, but the main reason I'm posting here is because I'm planning on revising this code a bit more, and to do a cross check between player and pet. Reason being, if you have a spell memorized, why not both player and pet while it's there? Also thinking of checking buff time, maybe by percentage of time left or 30 second mark. Something like that...

Posted: Sat Jul 02, 2005 4:15 pm
by Night Hawk
Updated to not use the ${String} TLO. Simple fix.

Posted: Mon Aug 06, 2007 8:15 pm
by Night Hawk
I eventually scratched the method of constantly updating a list of what buffs don't stack.
It was nice since it would replace buffs like Spirit of Eagle if you had Spirit of Wolf, but otherwise it was a big inconvenience.

Here's my current source of code in which I just use the .Stacks check, and a refresh option which will cast all buffs regardless of any checks.
Otherwise, it will cast missing buffs, or any buffs with a duration less than 20% (with some smart checks for short buffs).

I've used the ZoneInfo method from the Krust macro which holds all the zones in it's own INI file as to weather each zone allows Run Speed or Levitation buffs.

Requires:
MQ2Cast
MQ2Cast_Spell_Routines.inc
http://macroquest2.com/phpBB2/viewtopic.php?t=12758

To use, add this line to your macro:
/call Init_Buffs

See below for INI example.

Code: Select all

|-- Buff Include
|
| Usage:
|  /echo buffs [1|self|2|pet|both] (refresh)
|
| Examples:
|
|  Normal call. Cast missing buffs. If pet is up, do the same.
|  /echo buffs
|
|  Only check missing buffs on self
|  /echo buffs 1
|
|  Refresh buffs on pet only.
|  /echo buffs pet refresh
|
|--
#turbo 40

#define INI_FILE			buffs.ini
#include MQ2Cast_Spell_Routines.inc
#Event Buffs               "[MQ2] buffs#*#"

Sub Init_Buffs
   /declare SelfOnly bool outer false
   /declare PetOnly bool outer false
   /declare DoRefresh bool outer false
   /declare ZoneOutdoors int outer
   /declare ZoneLevitate int outer
/return

Sub Event_Buffs(string BuffLine)
   /varset BuffLine ${BuffLine.Right[-5]}
   /varset SelfOnly false
   /varset PetOnly false
   /varset DoRefresh false
   
   /varset ZoneOutdoors ${Ini[INI_FILE, ZoneInfo, ${Zone.ShortName}_Outdoors, -1]}
   /varset ZoneLevitate ${Ini[INI_FILE, ZoneInfo, ${Zone.ShortName}_Levitate, -1]}
   /if (${ZoneOutdoors} == -1) {
      /echo FIXME: Zone ${Zone.ShortName} data missing in INI
      /ini INI_FILE "ZoneInfo" "${Zone.ShortName}_Outdoors" "???"
      /ini INI_FILE "ZoneInfo" "${Zone.ShortName}_Levitate" "???"
      /return
   }
   
   /if (${BuffLine.Find[1]}||${BuffLine.Find[self]}||!${Me.Pet.ID}) /varset SelfOnly true
   /if (${BuffLine.Find[2]}||${BuffLine.Find[pet]}) /varset PetOnly true
   /if (${BuffLine.Find[refresh]}) /varset DoRefresh true

   /if (${SelfOnly}) {
      /echo -Buffing self only.
      /call SelfBuffs
   } else /if (${PetOnly}) {
      /if (!${Me.Pet.ID}) {
         /echo -No pet available to buff.
         /return
      }
      /echo -Buffing pet only.
      /call PetBuffs
   } else {
      /echo -Buffing both.
      /call SelfBuffs
      /call PetBuffs
   }
   /echo -Buffs complete.
/return

Sub SelfBuffs
   /declare NumberOfBuffs int local ${Ini[INI_FILE, ${Me.Name}, SelfBuffCount, NOT_FOUND]}
   /declare MyBuffs[${NumberOfBuffs}] string local
   /declare n int local
   /for n 1 to ${NumberOfBuffs}
      /varset MyBuffs[${n}] ${Ini[INI_FILE, ${Me.Name}, SelfBuff${n}, NOT_FOUND]}
   /next n

   /declare b int local 1
   /for b 1 to ${NumberOfBuffs}
      /if (${Me.FreeBuffSlots}<1) {
         /echo -Buff slots full.
         /return
      }
      /if (${DoRefresh}||(!${Me.Buff[${MyBuffs[${b}]}].ID}&&${Spell[${MyBuffs[${b}]}].Stacks})||(${Me.Buff[${MyBuffs[${b}]}].ID}&&${Spell[${MyBuffs[${b}]}].Duration}*.2>${Me.Buff[${MyBuffs[${b}]}].Duration}&&${Me.Buff[${MyBuffs[${b}]}].Duration}<100)) {
         /if (${Select[${MyBuffs[${b}]},Spirit of Wolf,Spirit of Eagle,Flight of Eagles]}&&!${ZoneOutdoors}) {
            /echo -Cannot cast ${MyBuffs[${b}]} inside.
            /next b
         }
         /if (${Select[${MyBuffs[${b}]},Spirit of Eagle,Flight of Eagles,Levitate,Levitation,Dead Man Floating,Dead Men Floating]}&&!${ZoneLevitate}) {
            /echo -Cannot cast ${MyBuffs[${b}]} here.
            /next b
         }
         /target myself
         /call MQ2Cast "${MyBuffs[${b}]}" gem6 NULL -maxtries|6
         /doevents
      }
   /next b
/return

Sub PetBuffs
   /declare NumberOfPetBuffs int local ${Ini[INI_FILE, ${Me.Name}, PetBuffCount, NOT_FOUND]}
   /declare PetBuffs[${NumberOfPetBuffs}] string local
   /declare n int local
   /for n 1 to ${NumberOfPetBuffs}
      /varset PetBuffs[${n}] ${Ini[INI_FILE, ${Me.Name}, PetBuff${n}, NOT_FOUND]}
   /next n

   /declare b int local
   /for b 1 to ${NumberOfPetBuffs}
      /if (${DoRefresh}||(!${Me.PetBuff[${PetBuffs[${b}]}]}&&${Spell[${PetBuffs[${b}]}].StacksPet})) {
         /if (${Select[${PetBuffs[${b}]},Spirit of Wolf,Spirit of Eagle,Flight of Eagles]}&&!${ZoneOutdoors}) {
            /echo -Cannot cast ${PetBuffs[${b}]} inside.
            /next b
         }
         /if (${Select[${PetBuffs[${b}]},Spirit of Eagle,Flight of Eagles,Levitate,Levitation,Dead Man Floating,Dead Men Floating]}&&!${ZoneLevitate}) {
            /echo -Cannot cast ${MyBuffs[${b}]} here.
            /next b
         }
         /target ${Me.Pet.Name}
         /call MQ2Cast "${PetBuffs[${b}]}" gem6 NULL -maxtries|6
         /doevents
      }
   /next b
/return
Here's an example INI build in your Buffs.ini

Code: Select all

[Bigbadmage]
SelfBuffCount=3
SelfBuff1=Circle of Magmaskin
SelfBuff2=Phantasmal Warden
SelfBuff3=Prime Shielding
PetBuffCount=1
PetBuff1=Burnout VI

;use ${Zone.ShortName}
;dont bother with mount entry on indoors zones
;NoMount=0 default on outdoor zones, only specify if its 1
;fix-only list indoor and no-levi zones
[ZoneInfo]
Provinggrounds_Outdoors=1
Provinggrounds_Levitate=0
Provinggrounds_NoMount=1
Lavastorm_Outdoors=1
Lavastorm_Levitate=1
delveb_70_Outdoors=0
delveb_70_Levitate=1
PoKnowledge_Outdoors=1
PoKnowledge_Levitate=1
See the Krust macro files for all the [ZoneInfo]:
http://macroquest2.com/phpBB2/viewtopic.php?t=13016

Posted: Tue Aug 07, 2007 8:36 am
by Yunto?
Youre using .Stacks wrong. It doesnt work like that anymore.
http://macroquest2.com/phpBB2/viewtopic ... 803#124803