Efficient Macro Buff-Checking Buffer

A forum for macro code snippets to be used in writing other macros. Post routines or .inc files here only, completed macros go to the Macro Depot. MQ2Data format only!

Moderator: MacroQuest Developers

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Efficient Macro Buff-Checking Buffer

Post by Night Hawk » Thu Oct 28, 2004 3:18 am

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
Last edited by Night Hawk on Fri Jul 22, 2005 4:19 am, edited 5 times in total.

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Sun Oct 31, 2004 12:47 pm

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.

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Sun Oct 31, 2004 12:50 pm

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.
Last edited by Night Hawk on Tue Apr 12, 2005 1:31 pm, edited 1 time in total.

User avatar
Cr4zyb4rd
Plugins Czar
Posts: 1449
Joined: Tue Jul 20, 2004 11:46 am

Post by Cr4zyb4rd » Sun Oct 31, 2004 1:27 pm

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.

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Sun Oct 31, 2004 1:35 pm

Was definately thinking about the INI file to make it a bit easier. Could you educate me on the string thing tho?

User avatar
Cr4zyb4rd
Plugins Czar
Posts: 1449
Joined: Tue Jul 20, 2004 11:46 am

Post by Cr4zyb4rd » Sun Oct 31, 2004 2:01 pm

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*

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Sun Oct 31, 2004 4:17 pm

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

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Wed Nov 17, 2004 12:20 pm

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 :)

gonemental21
orc pawn
orc pawn
Posts: 23
Joined: Fri Nov 26, 2004 9:31 am

Great Macro I borrowed it for my program.

Post by gonemental21 » Wed Dec 01, 2004 3:17 pm

http://www.macroquest2.com/phpBB2/viewtopic.php?t=9230

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

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Sun Dec 05, 2004 8:20 pm

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.

insanitywiz
a hill giant
a hill giant
Posts: 250
Joined: Mon Jul 08, 2002 7:50 am

Post by insanitywiz » Mon Dec 06, 2004 3:37 am

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.

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Tue Apr 12, 2005 1:33 pm

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

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Sat Jul 02, 2005 4:15 pm

Updated to not use the ${String} TLO. Simple fix.

User avatar
Night Hawk
a grimling bloodguard
a grimling bloodguard
Posts: 590
Joined: Fri Aug 13, 2004 4:56 pm

Post by Night Hawk » Mon Aug 06, 2007 8:15 pm

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
Last edited by Night Hawk on Fri Aug 24, 2007 9:40 pm, edited 3 times in total.

Yunto?
a grimling bloodguard
a grimling bloodguard
Posts: 502
Joined: Sat Nov 19, 2005 12:05 pm

Post by Yunto? » Tue Aug 07, 2007 8:36 am

Youre using .Stacks wrong. It doesnt work like that anymore.
http://macroquest2.com/phpBB2/viewtopic ... 803#124803
(10:02:10 AM) fearless: kate beckinsale
(10:02:18 AM) fearless: chick from underpants
(10:02:27 AM) fearless: er . . . world, underworld