Brian Koponen

Programming and Tech Tips

Custom Hunter Macros for Vanilla World of Warcraft

I have created a new page for World of Warcraft: Classic Hunter Macros.

The Hunter is probably the easiest class to play solo in Vanilla World of Warcraft, but it is also easy to play poorly. Especially when soloing, you need quick, direct access to a lot of skills when an encounter starts to turn ugly. It is amazing the kind of situations a Hunter can deal with when you have your full arsenal of tools readily available.

Many Hunter abilities have very situational uses and the only effective way to use them is with a lot of macros. Many of these are advanced macros that bind many skills to a single key. These take some practice to get used to, but I promise it is worth the time and effort.

These macros are made for the 1.12.1 client version of World of Warcraft. I make use of these addons very heavily:

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


Change Action Bar

In many classes, you will have different sets of spells that are cast together. It can be very useful to have those spells organized onto different action bars and have macros switch to those bars as is appropriate.

Using the default UI, you can switch the active action bar like this:

/run CURRENT_ACTIONBAR_PAGE=1
/run ChangeActionBarPage()

A very popular action bar replacement addon is Bongos. Using the Bongos addon you can show or hide a bar like this:

/bob show [bar number]
/bob hide [bar number]

You may find these useful depending on your keybindings and play style.


Main Attack

This macro (technically a set of three macros) lets you bind your Melee attacks and AutoShot attack to a single button. It will automatically choose which attacks to perform based on your distance from the target.

Melee:

The Melee macro can be spammed without cancelling auto attack. Since I rarely melee, I added Raptor Strike and Mongoose Bite into a one button macro.

/run CURRENT_ACTIONBAR_PAGE=1
/run ChangeActionBarPage()
/bob show 1
/run castAttack()
/run castRaptor()
/run castMong()

Range:

The Range macro can also be spammed without cancelling AutoShot. While you could add other attacks into this macro, I find it is better to use each shot situationally for the best mana efficiency.

/run CURRENT_ACTIONBAR_PAGE=2
/run ChangeActionBarPage()
/bob hide 1
/run castAutoShot()

Main:

This is the macro that you will put on your action bar. It targets the nearest enemy and then attacks appropriately based on the distance to the target.

/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if CheckInteractDistance("target", 3) then RunMacro("Melee") else RunMacro("Range") end


Attacks

Arcane Shot

This gets a target if you don't have one and casts Arcane Shot. If you hold Shift, it will only cast the Rank 1 version and immediately clear the target. This is useful for pulling an enemy, but causing the least possible threat.

/run --CastSpellByName("Arcane Shot")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if IsShiftKeyDown() then castArcane(1); ClearTarget(); else castArcane() end


Stings

Zorlen's castSting() will choose the appropriate sting for the target. Specifically if the target is a boss, it will cast Viper Sting if they use mana, otherwise Serpent Sting. If the target is a player, it will cast Viper Sting if they use mana, otherwise Scorpid Sting. For normal mobs it always casts Serpent Sting, unless the mob is immune.

Against players and normal mobs, it won't cast a sting if they are below 20% health to conserve mana. That is why I have the modifier cast Serpent Sting directly. If I have to kite a mob, I can force that sting.

/run --CastSpellByName("Serpent Sting")
/run if GetUnitName("target")==nil then TargetNearestEnemy() end
/run if IsShiftKeyDown() then CastSpellByName("Serpent Sting") else castSting() end


Wing Clip / Concussive Shot

This is a simple one that casts either Wing Clip or Concussive Shot depending on distance. If the target is already Wing Clipped, it won't cast Concussive Shot.

/run --CastSpellByName("Concussive Shot")
/run if CheckInteractDistance("target", 3) then castClip() else castCon() end


Pet Management

Pet Attack and Recall

This is an amazing one button macro for handling your pet while in combat. You need to be able to command your pet to do three things while in combat: attack your target, assist an ally or stop attacking and return to you. This macro will do all of those with one press, based on the situations below.

Pet Command Situation
Attack Target Hunter's target is an enemy.
Assist Target Hunter's target is an ally.
Recall Pet Hunter and Pet have same target or Hunter has no target.

Each time the pet is told to move, Dash and Dive are cast. When the pet attacks, Furious Howl is cast as well as enabling Growl and disabling Cower. If you are doing primarily PvP or dungeons / raids, you should remove zGrowlAutocastOn() so Growl does not get cast.

/script if UnitExists("target") then if UnitIsFriend("player","target") then AssistUnit("target"); zFuriousHowl(); PetAttack(); zDash(); zDive(); else if UnitExists("pettarget") and UnitIsUnit("target", "pettarget") then PetFollow(); zDash(); zDive();else zCowerAutocastOff(); zGrowlAutocastOn(); zFuriousHowl(); PetAttack(); zDash(); zDive(); end;end;else PetFollow(); zDash(); zDive(); end;


Pet Feed / Mend / Revive / Call / Dismiss

These macros handle all the other pet commands. This requires SuperMacro's Extended Lua function to work. Similar to the pet combat macro, it performs different commands based on the current situation.

Effect Situation
Call Pet Pet isn't out.
Revive Pet Pet is dead.
Mend Pet (Max Level) Pet is in combat and has a target.
Mend Pet (Most Efficient) Shift Modifier.
Feed Pet Pet is out of combat and not happy. (Special Case: Pet is in combat without a target. Often after reviving, the pet is still marked as in combat even though it isn't.)
Dismiss Pet Pet is happy and not in combat.

Pet Care

The main macro is written using the Extended Lua feature of SuperMacro. This allows us to write functions in the Lua scripting language to create more sophisticated functions than can be created in the raw macro language.

Macro:

/run PetCare();

Extended Lua:

function PetCare()
    if( IsShiftKeyDown()) then
      castMend();
    elseif (not UnitExists("pet")) then
      CastSpellByName("Call Pet");
    elseif (UnitHealth("pet")==0) then
      CastSpellByName("Revive Pet");
    elseif (Zorlen_petInCombat()) then
      if UnitExists("pettarget") then
        castMaxMend()
      else
        RunMacro("Feed Pet")
      end
    elseif (GetPetHappiness()~=3) then
      RunMacro("Feed Pet");
    else
      CastSpellByName("Dismiss Pet");
    end
end


Feed Pet

Since there are multiple ways to make a macro to feed your pet, I have the PetCare function run the "Feed Pet" macro, so you can easily choose how you want to create it. I have two options for the "Feed Pet" macro.

The first simply uses the SmartRestore addon feed pet feature.

/sr feed

The second doesn't need any addon, but you have to place a stack of food in the top left corner of your backpack.

/run if (Zorlen_notInCombat() and GetContainerItemLink(0,1)) then CastSpellByName("Feed Pet"); PickupContainerItem(0,1); end


Threat Management

When you are soloing with your pet, it's nice to be able to pull a target off your pet or have your pet pull a target off you. These macros use a combination of Distracting Shot, Disengage, Growl and Cower to raise and lower your threat level compared to your pet.

Threat Up

The first raises your threat level by casting Distracting Shot and lowers your pet's threat by enabling Cower and disabling Growl.

/run --CastSpellByName("Distracting Shot")
/run castDistract();
/run zCowerAutocastOn();
/run zGrowlAutocastOff();


Threat Down

The second is the reverse, lowering your threat level by casting Disengage and raising your pet's threat by enabling Growl, disabling Cower and having your pet attack your current target.

/run --CastSpellByName("Disengage")
/run zCowerAutocastOff();
/run zGrowlAutocastOn();
/run PetAttack();
/run castDisengage();


Traps

For traps, these macros cast Feign Death if the hunter is in combat, then cast the trap on the second try. These are designed to be spammed, so keep hitting the macro until the trap is laid.

Immolation / Explosive Trap

Casts Immolation Trap, or Explosive Trap if you hold the Shift key.

/run --CastSpellByName("Immolation Trap")
/run if (canTrap()) then if IsShiftKeyDown() then castExplosiveTrap() else castImmolationTrap() end else castFeign() end


Freezing / Frost Trap

Casts Freezing Trap, or Frost Trap is you hold the Shift key. In these macros, the pet is told to stop attacking so it doesn't break the trap. Technically, you don't need to stop the pet when casting Frost Trap, but I don't use it frequently enough for it to be a bother.

/run --CastSpellByName("Freezing Trap")
/run if UnitAffectingCombat("player") then castFeign(); PetFollow(); PetPassiveMode(); ClearTarget(); TargetLastEnemy(); else if IsShiftKeyDown() then castFrostTrap(); else CastSpellByName("Freezing Trap");end end


Utility

Aspects

This macro casts Aspect of the Monkey or Aspect of the Hawk based on the distance to the target.

/run if CheckInteractDistance("target", 3) then castMonkey() else castHawk() end


Hunter's Mark

This will only cast Hunter's Mark if the target is not already marked.

/run --CastSpellByName("Hunter's Mark")
/run if(not isMarked()) then castMark();end


Feign Death

This casts Feign Death only if the hunter is in combat.

/run --CastSpellByName("Feign Death")
/run if UnitAffectingCombat("player") then castFeign() end


Healing

This uses the SmartRestore addon to use a potion depending on need. Hold shift to use a bandage.

/run if IsShiftKeyDown() then SR_Bandage(); else SR_SmartUse(); end


Bombs

This uses the SmartEngineer addon to throw a bomb or grenade. Especially useful when leveling and you have several types in your inventory.

/se boom


Fishing / Mounting

This is a general purpose macro that casts Fishing if a fishing pole is equipped, otherwise it mounts/dismounts. Replace "Brown Kodo" with the name of your mount.

/run local i = GetInventoryItemTexture("player", GetInventorySlotInfo("MainHandSlot")) if i and string.find(i,"INV_Fishingpole") then CastSpellByName("Fishing") else Zorlen_useItemByName("Brown Kodo") end


Addons

I have a whole page dedicated to some of the most useful Vanilla World of Warcraft Addons that are universal to all classes. But these addons are specific to the Hunter class. Most of these just get rid of annoyances that build up over time.


Conclusion

When I started creating all these macros, it really transformed the game for me. I found it much easier to solo content and survive situations that were otherwise too much for me. I hope these have the same effect for you as well.

To make the most of these macros, I highly recommend trying The Best Control Scheme for World of Warcraft. It allows you to use tons of keybindings very easily, which is useful when you have a lot of macros like this.

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

World of Warcraft Macros

Question or Comment?