One of the things I've been asked a lot is how in the heck some of these macros work. I hope to explain some of that with this post.
First off, let me say that FORMATTING THE MACRO LIKE REAL CODE makes a huge difference as to how understandable it is. For example, consider this line from a macro:
Code:
/run f=0; if UnitExists("focus") then for i=1,40 do d={UnitBuff("focus",i)}; if d~=nil and d[1]=="Earth Shield" and d[8]=="player" and d[4]>1 and d[7]-GetTime()>=60 then f=1; break end end if f==0 then RunMacroText("/cast [@focus] Earth Shield") end end;
WTF? Now format it properly...
Code:
/run f=0;
if UnitExists("focus") then
for i=1,40 do
d={UnitBuff("focus",i)};
if d~=nil and d[1]=="Earth Shield" and d[8]=="player" and d[4]>1 and d[7]-GetTime()>=60 then
f=1;
break
end
end
if f==0 then
RunMacroText("/cast [@focus] Earth Shield")
end
end;
Hopefully that makes more sense...you can see it's saying "if the focus exists" and then it's looking 1 to 40 checking each buff to see if it is Earth Shield from the player and some other stuff (they are checking the number of charges and time remaining). If it find such a buff on the focus, it sets f=1. So if the loop finishes and never found the buff, f will still be 0 (from the first line). So then we say "if f==0 then" and cast a new earth shield. Voila!
Now for something a bit more complex...this is the "heal" line from my Resto Shaman macro...I've formatted it and added in comments in green to explain what each part is doing:
Code:
RT=2500; -- Set variable for minimum damage taken to use Riptide
RT2=5000; -- Set variable for maximum damage taken to use Riptide
LHW=4000; -- Set variable for min dmg taken to use Lesser Healing Wave
HW=10000; [COLOR="SeaGreen"]-- Set variable for min dmg taken to use Healing Wavev
CH=10000; -- Set variable for "chain hheal threshold"
NS=0.10; -- Set variable for health threshold that will trigger use of Nature's Swiftness
-- So we're going to be scanning the party/raid to find out who to heal...so we need unitids
-- If it's a party, we need: player, party1, party2, party3, party4
-- If it's a raid, we need: raid1, raid2, ..., raid40
-- So we want to set 3 variables:
-- t is the prefix of the unitid, either raid or party
-- nps is "num players start"...so start with 1 for raid...start with 0 for party (party0 will become "player" later)
-- npe is "num players end"...so it is the number of people in the raid/party
t="raid"; nps=1;
npe=GetNumRaidMembers(); -- How many members in raid? If no raid, we'll get 0.
if npe==0 then -- if it was not a raid
-- then go party mode
t="party"; nps=0; npe=GetNumPartyMembers()
end;
s=nil; -- s will eventually hold the name of the spell we're going to cast
m=0; -- m will hold the maximum amount of damage taken by any raid/party member
w=f; -- w will hold the unitid of the person who took the max dmg
-- loop through all the people in the raid/partyv
for i=nps,npe do
-- set tt to the unitid to check
-- normally just t..i is correct...but there is no partyN unitid for you,
-- so we use this if statement to change "party0" into "player"
if i==0 then tt="player" else tt=t..i end;
-- if that unit exists, is in range, and isn't dead
if UnitExists(tt) and UnitInRange(tt)==1 and UnitIsDeadOrGhost(tt)~=1 then
-- a holds how much damage they've taken
a=UnitHealthMax(tt)-UnitHealth(tt);
-- if a is more than m, this person is our new "max damage" person
if a>m then
-- save the damage they took (m) and their unit (w)
m=a w=tt
end
end
end;
-- after the loop is complete, we now know who is missing the most hp (w is their unitid)
-- and how much hp they are missing (m), so use those values to choose a spell (s)
-- If Riptide is ready and the damage falls within Riptide's range, then set our spell to Riptide
if GetSpellCooldown("Riptide")==0 and m>=RT and m<RT2 then
s="Riptide"
-- Else if the damage is high enough to warrant a full Healing Wave...
elseif m>=HW then
-- If NS is ready and their health is below the NS threshold, then set our spell to NS
if GetSpellCooldown("Nature's Swiftness")==0 and UnitHealth(w)/UnitHealthMax(w)<NS then
s="NS"
-- Else if you have Tidal Waves or Bloodlust, then set our spell to Healing Wave
elseif UnitBuff("player","Tidal Waves") or UnitBuff("player","Bloodlust") or UnitBuff("player","Heroism") then
s="Healing Wave"
-- Otherwise just use LHW
else
s="Lesser Healing Wave"
end
-- Else if they've taken enough damage to warrant healing at all...
elseif m>=LHW then
-- If their maximum "power" is less than the Chain Heal threshold, set our spell to CH
-- The premise is that people with low max "power" are melee and so they are close enough
-- to each other to let CH bounce. People with higher max "power" are likely ranged and so
-- CH may not bounce so then LHW is faster/better.
if UnitPowerMax(w) < CH then
s="Chain Heal"
-- Otherwise just use LHW
else
s="Lesser Healing Wave"
end
end;
-- now we know who to heal and how to heal them...so let's do it.
-- If we're using NS, stop casting and pop NS...then set the spell to Healing Wave
if s=="NS" then
SpellStopCasting();
CastSpellByName("Nature's Swiftness");
SpellStopCasting();
s="Healing Wave"
end;
-- Finally...if a spell was selected, cast that spell (s) on the appropriate unitid (w)
-- If the person with the most damage wasn't hurt enough to warrrant healing, s will
-- still be nil and so no spell will be cast.
if s~=nil then
RunMacroText("/cast [@"..w.."] "..s)
end;
This is how I write them...properly formatted...then at the very end I just delete all the new lines to combine each concrete step into it's own /run line.
Hopefully someone finds this useful or at least interesting and maybe it helps some understand a bit more about what in the heck is going on in these macros. If you have any specific questions, just ask! =)