Custom Paladin Macros for Vanilla World of Warcraft
People often joke about how Paladins can be boring to play in Vanilla World of Warcraft. As such, I think they often get overlooked when it comes to building macros. I created these macros to add some much needed functionality, especially for healing and buffing party members.
These macros are made for the 1.12.1 client version of World of Warcraft and make use of these addons extensively:
- SuperMacro allows the creation of longer macros than the default and the ability to run Lua code from within a macro, which is used in several macros below.
- Zorlen is a function library that provides tons of benefits and they are used throughout all the macros.
Also, many of these macros use modifier keys to alter their functionality. You may want to switch those modifier keys depending on your preference. Those functions are:
- IsShiftKeyDown()
- IsAltKeyDown()
- IsControlKeyDown()
Macro Tips
Action Bar Range and Cooldown
A really handy macro trick is to make the first line:
/run --CastSpellByName("Spell")
This will give the macro the cool down and range check on your action bar of the spell you put in the quotes. This doesn't actually cast the spell because the double dash is used as a comment delimiter and prevents the rest of the line from being executed. However, the World of Warcraft client simply looks for the first CastSpellByName reference, even if it is in a comment, to decide how the cool down and range check will be determined.
Target Nearest Enemy
This is a useful line to have in many macros. It simply targets the nearest enemy if you don't already have a target.
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
Attacks
Auto Attack
This macro automatically targets the nearest enemy if you don't have a target and starts the auto attack. Using this repeatedly won't turn off your auto attack. Hold shift to turn off your auto attack.
/run --CastSpellByName("Attack")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if( IsShiftKeyDown() ) then stopAttack() else castAttack() end
Exorcism
This will cast Exorcism only if the target is Undead or a Demon.
/run --CastSpellByName("Exorcism")
/run if isUndead() or isDemon() then CastSpellByName("Exorcism") end
Seals
These will cast Judgement if a Seal is already active before casting the Seal itself.
Seal of Command
/run --CastSpellByName("Seal of Command")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if not isSealActive() or IsShiftKeyDown() then CastSpellByName("Seal of Command") else castJudgement() end
/run castAttack()
Seal of the Crusader
/run --CastSpellByName("Seal of the Crusader")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if not isSealActive() or IsShiftKeyDown() then castSotC() else castJudgement() end
/run castAttack()
Seal of Righteousness
/run --CastSpellByName("Seal of Righteousness")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if not isSealActive() or IsShiftKeyDown() then castSoR() else castJudgement() end
/run castAttack()
Seal of Light
/run --CastSpellByName("Seal of Light")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if not isSealActive() or IsShiftKeyDown() then castSoL() else castJudgement() end
/run castAttack()
Seal of Wisdom
/run --CastSpellByName("Seal of Wisdom")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if not isSealActive() or IsShiftKeyDown() then castSoW() else castJudgement() end
/run castAttack()
Seal of Justice
Unlike the others, this macro will cast Seal of Justice before casting Judgement. This is designed to quickly stop mobs running away from you.
/run --CastSpellByName("Seal of Justice")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if isSealOfJusticeActive() then castJudgement() else castSoJ() end
/run castAttack()
Combos
You can easily make combos out of the seals using the macros above. As you activate this macro, it will cast Seal of the Crusader, Judgement of the Crusader, Seal of Command, then Judgement of Command.
/run if buffed("judgement of the crusader","target") then RunMacro("Command") else RunMacro("Crusader") end
Blessings
This macro makes it trivial to keep all of your party members properly Blessed. Every 5 minutes, just spam this macro until everyone in your party gets their Blessing applied. This is designed to pick a Blessing based on the class of the party member.
Macro:
/run --CastSpellByName("Blessing of Wisdom")
/run castGroupBlessing()
Extended Lua:
You can easily change which Blessing will be cast in the blessingForUnit() function. The Blessing returned when there is no unit targeted is the one that will be cast on yourself.
The available Blessing that can be used are:
- LOCALIZATION_ZORLEN.BlessingOfFreedom
- LOCALIZATION_ZORLEN.BlessingOfKings
- LOCALIZATION_ZORLEN.BlessingOfLight
- LOCALIZATION_ZORLEN.BlessingOfMight
- LOCALIZATION_ZORLEN.BlessingOfProtection
- LOCALIZATION_ZORLEN.BlessingOfSacrifice
- LOCALIZATION_ZORLEN.BlessingOfSalvation
- LOCALIZATION_ZORLEN.BlessingOfSanctuary
- LOCALIZATION_ZORLEN.BlessingOfWisdom
- LOCALIZATION_ZORLEN.GreaterBlessingOfKings
- LOCALIZATION_ZORLEN.GreaterBlessingOfLight
- LOCALIZATION_ZORLEN.GreaterBlessingOfMight
- LOCALIZATION_ZORLEN.GreaterBlessingOfSalvation
- LOCALIZATION_ZORLEN.GreaterBlessingOfSanctuary
- LOCALIZATION_ZORLEN.GreaterBlessingOfWisdom
function blessingForUnit(unit)
local unit = unit or "target"
if not UnitExists(unit) then
return LOCALIZATION_ZORLEN.BlessingOfMight
end
if isDruid(unit) or isHunter(unit) or isPriest(unit) or isMage(unit) or isWarlock(unit) then
return LOCALIZATION_ZORLEN.BlessingOfWisdom
end
if isPaladin(unit) or isWarrior(unit) or isRogue(unit) then
return LOCALIZATION_ZORLEN.BlessingOfMight
end
end
function castBlessing()
local SpellName = blessingForUnit()
local SpellID = Zorlen_GetSpellID(SpellName)
if not Zorlen_checkCooldown(SpellID) then
return false
end
if (UnitIsFriend("player", "target") and not UnitIsUnit("player", "target") and not Zorlen_checkBuffByName(SpellName, "target")) then
CastSpell(SpellID, 0)
if SpellIsTargeting() then
SpellStopTargeting()
return false
end
return true
end
if ((not UnitExists("target") or not UnitIsFriend("player", "target")) and not Zorlen_checkBuffByName(SpellName)) then
if (UnitIsFriend("player", "target") and not UnitIsUnit("player", "target")) then
retarget = UnitExists("target");
TargetUnit("player");
end
CastSpell(SpellID, 0)
if (retarget) then
TargetLastTarget();
end
if SpellIsTargeting() then
if SpellCanTargetUnit("player") then
SpellTargetUnit("player")
else
SpellStopTargeting()
return false
end
end
return true
end
return false
end
function castGroupBlessing()
if not castBlessing() then
local NumMembers = GetNumPartyMembers()
local counter = 0
local group = "party"
local PET = ""
local PLAYER = "player"
while counter <= NumMembers do
if counter == 0 then
u = PLAYER..""..PET
else
u = group..""..PET..""..counter
end
if UnitExists(u) and UnitIsVisible(u) and not UnitIsDeadOrGhost(u) then
if not UnitIsUnit("target", u) and not UnitIsUnit("player", u) then
TargetUnit(u)
if castBlessing() then
TargetLastTarget()
return true
end
TargetLastTarget()
end
end
counter = counter + 1
end
end
end
Healing
Group Holy Light
This will cast Healing Light on the party member with the lowest health, without losing your current target. If you already have a friendly target, it will cast Holy Light on them directly, so you can still prioritize your healing.
If you are in combat, it will switch to the Concentration Aura to prevent spell pushback.
Macro:
/run --CastSpellByName("Holy Light")
/run if Zorlen_inCombat() and not isCAA() then CastSpellByName("Concentration Aura") end
/run castGroupHolyLight()
Extended Lua:
function castHolyLight(Mode, RankAdj, unit)
if Zorlen_isMoving() then
return false
end
local SpellName = LOCALIZATION_ZORLEN.HolyLight
local SpellButton = Zorlen_Button[SpellName]
local LevelLearnedArray={1,6,14,22,30,38,46,54}
local ManaArray={35,60,110,190,275,365,465,580}
local MinHealArray={39,76,159,310,491,698,945,1246}
local MaxHealArray={47,90,187,356,553,780,1053,1388}
local TimeArray={2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5}
return Zorlen_CastHealingSpell(SpellName, ManaArray, MinHealArray, MaxHealArray, TimeArray, LevelLearnedArray, Mode, RankAdj, unit, SpellButton)
end
function castGroupHolyLight(pet, Mode, RankAdj)
if Zorlen_isMoving() then
return false
end
local SpellName = LOCALIZATION_ZORLEN.HolyLight
if UnitExists("target") and castHolyLight(Mode, RankAdj, "target") then
return true
elseif not Zorlen_IsSpellKnown(SpellName) or UnitMana("player") < 35 then
return false
else
local u = nil
local counter = 1
local notunitarray = {}
if Zorlen_isCasting(SpellName) then
u = Zorlen_GiveGroupUnitWithLowestHealth(pet, 0, nil, Zorlen_CastingNotUnitArray)
if u and Zorlen_CastingUnit == u then
return false
elseif not u or Zorlen_CastingUnit then
SpellStopCasting()
return true
end
return false
elseif Zorlen_checkCooldownByName(SpellName) then
while counter do
u = Zorlen_GiveGroupUnitWithLowestHealth(pet, nil, nil, notunitarray)
if u then
if UnitIsUnit("target", u) then
notunitarray[counter] = u
elseif UnitIsUnit("player", u) then
return castHolyLight(Mode, RankAdj, u)
else
TargetUnit(u)
if castHolyLight(Mode, RankAdj, u) then
Zorlen_CastingUnit = u
Zorlen_CastingNotUnitArray = notunitarray
TargetLastTarget()
return true
end
TargetLastTarget()
notunitarray[counter] = u
end
counter = counter + 1
else
counter = nil
end
if not u and (Zorlen_isCasting(SpellName)) then
SpellStopCasting()
end
end
end
end
return false
end
Group Flash of Light
This will cast Flash of Light on the party member with the lowest health, without losing your current target. If you already have a friendly target, it will cast Flash of Light on them directly, so you can still prioritize your healing.
Macro:
/run --CastSpellByName("Flash Of Light")
/run castGroupFlashOfLight()
Extended Lua:
function castFlashOfLight(Mode, RankAdj, unit)
if Zorlen_isMoving() then
return false
end
local SpellName = LOCALIZATION_ZORLEN.FlashOfLight
local SpellButton = Zorlen_Button[SpellName]
local LevelLearnedArray={20,26,34,42,50,58}
local ManaArray={35,50,70,90,115,140}
local MinHealArray={62,96,145,197,267,343}
local MaxHealArray={72,110,163,221,299,383}
local TimeArray={1.5,1.5,1.5,1.5,1.5,1.5}
return Zorlen_CastHealingSpell(SpellName, ManaArray, MinHealArray, MaxHealArray, TimeArray, LevelLearnedArray, Mode, RankAdj, unit, SpellButton)
end
function castGroupFlashOfLight(pet, Mode, RankAdj)
if Zorlen_isMoving() then
return false
end
local SpellName = LOCALIZATION_ZORLEN.FlashOfLight
if UnitExists("target") and castFlashOfLight(Mode, RankAdj, "target") then
return true
elseif not Zorlen_IsSpellKnown(SpellName) or UnitMana("player") < 35 then
return false
else
local u = nil
local counter = 1
local notunitarray = {}
if Zorlen_isCasting(SpellName) then
u = Zorlen_GiveGroupUnitWithLowestHealth(pet, 0, nil, Zorlen_CastingNotUnitArray)
if u and Zorlen_CastingUnit == u then
return false
elseif not u or Zorlen_CastingUnit then
SpellStopCasting()
return true
end
return false
elseif Zorlen_checkCooldownByName(SpellName) then
while counter do
u = Zorlen_GiveGroupUnitWithLowestHealth(pet, nil, nil, notunitarray)
if u then
if UnitIsUnit("target", u) then
notunitarray[counter] = u
elseif UnitIsUnit("player", u) then
return castFlashOfLight(Mode, RankAdj, u)
else
TargetUnit(u)
if castFlashOfLight(Mode, RankAdj, u) then
Zorlen_CastingUnit = u
Zorlen_CastingNotUnitArray = notunitarray
TargetLastTarget()
return true
end
TargetLastTarget()
notunitarray[counter] = u
end
counter = counter + 1
else
counter = nil
end
if not u and (Zorlen_isCasting(SpellName)) then
SpellStopCasting()
end
end
end
end
return false
end
Divine Protection / Blessing of Protection
This macro will cast Blessing of Protection if you are targeting a friendly unit. If you have no target or are targeting an enemy, it will find the party member with the lowest health (including yourself) and cast Blessing of Protection or Divine Protection if they have less than 40% health. You can also change this to cast Divine Shield on yourself once you learn it. It will do all of this without losing your current target.
Macro:
/run castProtection()
Extended Lua:
function castProtection()
if UnitExists("target") and UnitIsFriend("player", "target") then
CastSpellByName("Blessing Of Protection")
return true
end
local u = Zorlen_GiveGroupUnitWithLowestHealth()
if u then
TargetUnit(u)
local unitHealth = UnitHealth("target") / UnitHealthMax("target")
if(unitHealth <= 0.4) then
if UnitIsUnit("player", u) then
CastSpellByName("Divine Protection")
else
CastSpellByName("Blessing Of Protection")
end
TargetLastTarget()
return true
end
TargetLastTarget()
end
return false
end
Conclusion
I did not expect the Paladin class to require such elaborate macros, but it turned out there was a lot that could be done. These also demonstrate the immense power that is available when you can use raw Lua code in a macro. It's no wonder that Blizzard would remove this entire system starting with The Burning Crusade expansion.
You may also be interested in these World of Warcraft related pages: