Brian Koponen

Programming and Tech Tips

Custom Mage Macros for Vanilla World of Warcraft

The Mage is a fun class in Vanilla World of Warcraft. It's fairly straightforward to play and doesn't need a ton of macros to play well. Nonetheless, I created some macros that add utility and make some spells quicker to cast in hectic situations.

These macros are made for the 1.12.1 client version of World of Warcraft and require these addons:

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:


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

Melee 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

Wand Attack

This is the same macro, but it uses a wand instead of the melee weapon.

/run --CastSpellByName("Shoot")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if( IsShiftKeyDown() ) then stopShoot() else castShoot() end


Spell Casting

These macros will target an enemy if you need one, cast a spell and start auto attack. These will automatically downrank the spell when you are low on mana.

Arcane Missiles

/run --CastSpellByName("Arcane Missiles")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run castArcaneMissiles()
/run castAttack()

Frostbolt

/run --CastSpellByName("Frostbolt")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run castFrostbolt()
/run castAttack()

Fireball

/run --CastSpellByName("Fireball")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run castFireball()
/run castAttack()

Fire Blast

/run --CastSpellByName("Fire Blast")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run castFireBlast()
/run castAttack()

Flamestrike

/run --CastSpellByName("Flamestrike")
/run castFlamestrike()
/run castAttack()

Arcane Explosion

/run --CastSpellByName("Arcane Explosion")
/run castArcaneExplosion()
/run castAttack()


Frost Nova

This casts Frost Nova as fast as possible by interrupting your wand and other spell casting. You can spam this until Frost Nova fires.

Macro:

/run --CastSpellByName("Frost Nova")
/run if isShootActive() then stopShoot() end
/run if Zorlen_isCasting() then SpellStopCasting() end
/run castFrostNova()

Extended Lua:

function castFrostNova()
  local z = {}
  z.SpellName = LOCALIZATION_ZORLEN.FrostNova
  z.EnemyTargetNotNeeded = 1
  return Zorlen_CastCommonRegisteredSpell(z)
end


Buffs

Armor

This macro casts Frost or Ice Armor (depending on which you have learned) normally and casts Mage Armor if you hold down the shift key.

/run --CastSpellByName("Frost Armor")
/run if IsShiftKeyDown() then castMageArmor() else castIceArmor() end


Group Arcane Intellect

This is probably the most convenient macro to have on this whole page. It will first cast Arcane Intellect on your target, if you have one, and then on each unbuffed party member on repeated uses. Just spam this until it stops doing anything and everyone will be buffed.

Macro:

/run --CastSpellByName("Arcane Intellect")
/run castGroupArcaneIntellect()

Extended Lua:

function castGroupArcaneIntellect(pet)
  if not castArcaneIntellect() then
    local SpellName = LOCALIZATION_ZORLEN.ArcaneIntellect
    local SpellButton = Zorlen_Button[SpellName]
    local _ = nil
    local isUsable = nil
    local notEnoughMana = nil
    local duration = nil
    local isCurrent = nil
    local SpellID = nil
    if SpellButton then
      isUsable, notEnoughMana = IsUsableAction(SpellButton)
      _, duration, _ = GetActionCooldown(SpellButton)
      isCurrent = IsCurrentAction(SpellButton)
    elseif Zorlen_IsSpellKnown(SpellName) then
      SpellID = Zorlen_GetSpellID(SpellName)
    else
      return false
    end
    if not SpellButton or (( isUsable == 1 ) and ( not notEnoughMana ) and ( duration == 0 ) and not ( isCurrent == 1 )) then
      if SpellButton or Zorlen_checkCooldown(SpellID) then
        local counter = 1
        local notunitarray = {}
        while counter do
          local u = Zorlen_GiveGroupUnitWithoutBuffBySpellName(SpellName, pet, nil, nil, notunitarray)
          if u then
            if UnitIsUnit("target", u) or UnitIsUnit("player", u) then
              notunitarray[counter] = u
            else
              TargetUnit(u)
              if castArcaneIntellect() then
                TargetLastTarget()
                return true
              end
              TargetLastTarget()
              notunitarray[counter] = u
            end
            counter = counter + 1
            if not SpellButton then
              counter = nil
            end
          else
            counter = nil
          end
        end
      end
    end
  end
  return false
end


Miscellaneous

These all cancel your current actions and cast the spell for quick use.

/run if isShootActive() then stopShoot() end
/run if Zorlen_isCasting() then SpellStopCasting() end
/run CastSpellByName("Blink")

Counterspell

/run if isShootActive() then stopShoot() end
/run if Zorlen_isCasting() then SpellStopCasting() end
/run CastSpellByName("Counterspell")

Cold Snap

/run if isShootActive() then stopShoot() end
/run if Zorlen_isCasting() then SpellStopCasting() end
/run CastSpellByName("Cold Snap")

Polymorph

/run if isShootActive() then stopShoot() end
/run if Zorlen_isCasting() then SpellStopCasting() end
/run CastSpellByName("Polymorph")


Conclusion

As you can see, most of these macros let you cast the spell you want a little quicker by automatically canceling your other actions. It seems like a small detail, but it can make a huge difference in a panic situation. I find this lets me focus on the tactical play of choosing which spell to cast instead of the mechanics that get in the way of that.

You may also be interested in these World of Warcraft related pages:

Question or Comment?