Code Snippet: How can I make this work better? BUFF PHASE

Need help with a macro you are writing? Ask here!

Moderator: MacroQuest Developers

bheathrow
orc pawn
orc pawn
Posts: 14
Joined: Sun Dec 21, 2003 9:27 am

Code Snippet: How can I make this work better? BUFF PHASE

Post by bheathrow » Sat Oct 16, 2004 11:52 am

I'm currently working on a macro to help me farm the undead dragon sineus from juggs in Old Seb. After spending a week killing jugg after jugg after jugg, I decided it was time I wrote a macro so I didn't lose my mind and start slipping in combats (had a few close calls with sloppy pulls) because each time I run combat I cast the SAME DAMN SPELLS over and over again.Currently I'm testing each section, making sure it's working right.

I was hopeing for some input on this snippet, because while it works, since this is my first major macro that I have written I know I'm doing things poorly.

Note that this used the spell_routines.inc file. Also note that this test snippet is made to loop forever for testing purposes *obvious*.

Oh, and this is for a necromancer.

Code: Select all

#turbo

#include spell_routines.inc



Sub Main

|==================================
|             VARIABLES
|==================================

/declare JUGGKILLS        int    outer 0

/declare PET_HASTE_TIMER  timer  outer 105s
/declare DMF_TIMER        timer  outer 420s

/declare LICH_ON          bool   outer false
/declare TARGETFOUND	  bool   outer false

/declare STARTXP	  float  outer
/declare Exper 		  float  outer
/declare AAExp            float  outer



/varset STARTXP ${Me.PctExp}
/varset Exper   ${Me.PctExp}
/varset AAExp   ${Me.PctAAExp}


|[======================= MAIN LOOP ========================]
:MAINLOOP
	/popup ENTERING BUFF PHASE

	/target Myself

| LOAD BUFF SPELL SET
	/memspellset BUFFS
/echo Spellset BUFFS should be loading now!

	/delay 20s 
	/doevents
	
| Check pet health. Let pet heal to full
	/if (${Me.Pet.PctHPs}<100) {
		:WaitForPetToHeal
		/if (${Me.Pet.PctHPs}<100) /goto :WaitForPetToHeal
	}
/echo "Pet at full health"
| Check PC health. If lower than 70 turn off lich, 
| sit and rest the good old fashoned way to 100
| (Wish I had HEB)

	/if (${Me.PctHPs}<70) {
| Turn off Lich NOW
	   	/declare i int local
	   	/for i 1 to 15
	      		/if ( ${Me.Buff[${i}].Name.Find[Seduct]} ) /notify BuffWindow buff${Math.Calc[${i}-1].Int} leftmouseup
	   	/next i 
		/varset LICH_ON 0


		/if (${Me.State.Equal["STAND"]}) {
   		/delay 1s
   		/sit
   		/deletevar i
	} 



		/Echo I better be sittign now, damnit
|Loop until I'm at 100
:SittingForHealth
		/if (${Me.PctHPs}<100) /goto :SittingForHealth
	}


| Recast DMF if timer < 4 minutes
	/if (${DMF_TIMER} < 2400) {
		/call cast "Dead Man Floating" gem6 20s
		/delay 7s
		/call cast "Shield of Maelin" gem2 20s
		/delay 7s
		/varset DMF_TIMER        4200s

	}
/echo DMF TIMER: ${DMF_TIMER}
/echo PET HASTE TIMER: ${PET_HASTE_TIMER}
| Recast Pet Haste < 4 minutes
	/if (${PET_HASTE_TIMER} < 2400) {
		/call cast "Rune of Death" gem8 20s
		/delay 7s
		/varset PET_HASTE_TIMER  1050s
	}

| Check Mana. If less than 70 mana, then med wait until 70.
	/if (${Me.PctMana}<70) {
	
		/if (${Me.State.Equal["STAND"]}) {
		   	/delay 1s
   			/sit
		} 

|Loop until I'm at 70
:MeddingForMana
		/if (${Me.PctMana}<70) /goto :MeddingForMana
	}

| Recast Lich if LICH_ON is false, we should be at full health again, yay
	/if (${LICH_ON} == 0) /call cast "Seduction of Saryrn" gem3 20s
	/varset LICH_ON 1
| LOAD COMBAT SPELLSET
	/memspellset SEB
	/doevents
	/delay 20s
/goto :MAINLOOP	
/return 

|[===================== END MAIN LOOP ======================]



Any feedback would be appreciated, including telling me to RTFM again because I suck so badly. :P

bheathrow
orc pawn
orc pawn
Posts: 14
Joined: Sun Dec 21, 2003 9:27 am

Post by bheathrow » Sat Oct 16, 2004 11:56 am

I also set the timers at the start of this macro to such a low number so I could see it perform rapidly when I restarted the macro after each edit.

Also, I know that DMF has a 72 minute duration,, not 100% sure if I'm sticking with 42 minute recast or if I will go longer.

Also, I had a problem with declaring the inner variable I, in earlier versions I never got an error stating that it was already declared, but in the past few versions, it gave me the already declared error, so I added /deletevar i to counteract it.

Not sure what impact that will have on memory and such.

User avatar
SimpleMynd_01
a lesser mummy
a lesser mummy
Posts: 71
Joined: Thu May 08, 2003 3:16 pm

Some tips...

Post by SimpleMynd_01 » Mon Oct 18, 2004 11:01 am

Just some tips you might find helpful:

1) Move your "/declare i int outer" to just after "/declare JUGGKILLS int outer 0". This will get rid of your error there.

2) Try using this code for watching your buffs instead of using timers. This is a slimmed down version of what I use, but should work for ya based on your posted code.

Code: Select all

sub Main
.
/call CheckForBuff "Dead Man Floating"
/call CheckForBuff "Shield of Maelin"
.
/return

Sub CheckForBuff(string BuffName) 
    /if (${Me.Buff[${BuffName}].Duration}<2400 || !${Me.Buff[${BuffName}].ID}) {
        /call cast "${BuffName}"
        /delay 20s
    }    
/return
3) I had trouble reading exactly what you wanted to do with some of your /if statements with the odd indenting. I don't know if you're doing exactly what you think you're doing though... Might want to double check some of them.

Nice to see a good first effort!

-SimpleMynd

Chill
Contributing Member
Contributing Member
Posts: 435
Joined: Fri May 07, 2004 5:06 pm
Location: Erie, PA

Post by Chill » Mon Oct 18, 2004 11:35 am

A couple things I noticed:
1) buff durations are in 6-second ticks, not miliseconds. so "2400" is 240 minutes. If you are aiming for 4 minutes, then you want to use 40 (10 ticks in a minute).

2) If you dont have a buff up, then ${Me.Buff[<Some Faded Buff>].Duration} will be null and evaluate to 0. 0 is less than 40, so you do not need to check if the buff isnt up.

3) Spell_Routines.inc automatically delays for you while your spells cast, so you do not need to delay again after you /call cast "Something"

4) You can add a condition to end a /delay early, so you dont have to waste time waiting after something has happened.

So based on that:

Code: Select all

Sub CheckForBuff(string BuffName) 
    /if (${Me.Buff[${BuffName}].Duration}<2400 || !${Me.Buff[${BuffName}].ID}) { 
        /call cast "${BuffName}" 
        /delay 20s 
    }    
/return
becomes:

Code: Select all

Sub CheckForBuff(string BuffName) 
    /if (${Me.Buff[${BuffName}].Duration}<40) /call cast "${BuffName}"
/return
Kinda thinking you dont really need a sub for that :P

You can clean up a lot more along these lines tho.

bheathrow
orc pawn
orc pawn
Posts: 14
Joined: Sun Dec 21, 2003 9:27 am

Post by bheathrow » Mon Oct 18, 2004 3:56 pm

Many thanks for the tips. Applying them and testing them locally.

:D

Dark_Lord_X
orc pawn
orc pawn
Posts: 16
Joined: Fri Oct 01, 2004 5:42 pm

Post by Dark_Lord_X » Fri Oct 22, 2004 5:09 am

If this helps you at all, heres how I have my buff routine in one of my necro macros.

Code: Select all

Sub BuffSelf
/declare b int local
/echo Notify: Checking buff status and rebuffing.
/target myself
/if (${Me.Buff[${LichBuff}].Duration} < 50) /call Cast "${LichBuff}" gem8 20s
/if (${Me.Buff[${RuneBuff}].Duration} < 50) /call Cast "${RuneBuff}" gem8 20s
/if (${Me.Buff[${ShieldBuff}].Duration} < 50) /call Cast "${ShieldBuff}" gem7 20s
/if (${Me.Buff[${LevBuff}].Duration} < 50) /call Cast "${LevBuff}" gem7 20s
/for b 1 to 5
	/if ((${String[${ClickItem${b}}].NotEqual[NULL]}) && (${String[${ClickBuff${b}}].NotEqual[NULL]})) {
		/if ((${Me.Buff[${ClickBuff${b}}].Duration} < 50) && (${FindItem[${ClickItem${b}}].ID})) /call Cast "${ClickItem${b}}" item
	}
/next b
/return
Everything is declared in the Main Sub of course. Note the for loop is for clicky buffs and untested at this time.