One-Button Healing Macro (All Classes)
About 5 min
One-Button Healing Macro (All Classes)
Step 1: Open the Heitu client → click "Super Macro" → create a new macro → paste the code below.
Step 2: Create a regular macro in-game. Use /s S HealRaid() for full raid healing, or /s S HealRaidP() for your own party healing. Bind it to a key.
-- ============================================================
-- CONFIG AREA (modify as needed) Four core healing features below — scroll carefully, this macro is long
-- ============================================================
-- Enable healing debug output (true = print, false = silent)
local CFG_DEBUG_HEAL = false
-- Also heal pets (true = enabled, false = disabled)
local CFG_INCLUDE_PETS = false
-- Minimum health deficit for priority targets; targets below this won't be healed
local CFG_PRIORITY_MIN_LOST = 100
-- Priority target array (add targets via HealRaid_AddTarget())
local CFG_priorityTargets = {}
-- Healing spell tier config, sorted by priority (highest first)
-- minLost: minimum health deficit maxDist: max cast range (yards)
-- spellId: spell ID name: spell name (debug output only)
-- noAura: skip targets that already have this aura (e.g. Renew/Rejuvenation), 0 = don't check
-- Note: at equal health deficits, higher entries take priority
-- Re-fetched each invocation based on current class
function GetCfgLevels()
local me = GetMeInfo()
local classId = me and me.classId or 0
if classId == 2 then -- Paladin
-- Level 60 strategy: Paladins have plenty of mana, use max rank for everything
return {
{ minLost = 2000, maxDist = 40, spellId = 25292, name = "Holy Light (Max Rank)", noAura = 0 },
{ minLost = 100, maxDist = 40, spellId = 19943, name = "Flash of Light (Max Rank)", noAura = 0 },
}
elseif classId == 5 then -- Priest
-- Level 60 strategy: Heal R2 is the Priest's best-known downrank; Greater Heal for tanks; Flash Heal for emergencies
return {
{ minLost = 5000, maxDist = 40, spellId = 10929, name = "Renew (Max Rank)", noAura = 10929 }, -- Target without Renew gets Renew first
{ minLost = 5000, maxDist = 40, spellId = 10965, name = "Greater Heal (Max Rank)", noAura = 0 },
{ minLost = 1500, maxDist = 40, spellId = 6064, name = "Heal (Rank 4)", noAura = 0 },
{ minLost = 1000, maxDist = 40, spellId = 9474, name = "Flash Heal (Rank 4)", noAura = 0 },
{ minLost = 500, maxDist = 40, spellId = 2055, name = "Heal (Rank 2)", noAura = 0 },
{ minLost = 1, maxDist = 40, spellId = 2054, name = "Heal (Rank 1)", noAura = 0 },
}
elseif classId == 7 then -- Shaman
-- Level 60 strategy: Chain Heal auto-bounces for smart raid healing; Healing Wave for tanks; Lesser Healing Wave for quick top-ups
return {
{ minLost = 5000, maxDist = 40, spellId = 25357, name = "Healing Wave (Max Rank)", noAura = 0 },
{ minLost = 1000, maxDist = 40, spellId = 10622, name = "Chain Heal (Rank 2)", noAura = 0 },
{ minLost = 1, maxDist = 40, spellId = 1064, name = "Chain Heal (Rank 1)", noAura = 0 },
}
elseif classId == 11 then -- Druid
-- Level 60 strategy: Healing Touch R4 is the Druid's most mana-efficient downrank; R11 max rank for tanks; Regrowth for emergency + HOT
return {
{ minLost = 5000, maxDist = 40, spellId = 25299, name = "Rejuvenation (Max Rank)", noAura = 25299 }, -- If target lacks Rejuv, apply it first
{ minLost = 5000, maxDist = 40, spellId = 25297, name = "Healing Touch (Max Rank)", noAura = 0 },
{ minLost = 1500, maxDist = 40, spellId = 5188, name = "Healing Touch (Rank 4)", noAura = 0 },
{ minLost = 1000, maxDist = 40, spellId = 8941, name = "Regrowth (Rank 5)", noAura = 0 },
{ minLost = 500, maxDist = 40, spellId = 8938, name = "Regrowth (Rank 2)", noAura = 0 },
{ minLost = 1, maxDist = 40, spellId = 8936, name = "Regrowth (Rank 1)", noAura = 0 },
}
end
return {}
end
-- ============================================================
-- ================= One-Button Heal Core Feature 1: [Add Current Target to Priority List] =========================
-- Usage: Create a macro for assigning priority targets: /s S HealRaid_AddTarget() — mouse-select a player and click the macro to add them to the priority list
function HealRaid_AddTarget()
local info = GetMeInfo()
if not info or not info.targetGuid or info.targetGuid == "0" then
print("Please select a target first")
return
end
local tInfo = GetUnitInfo(info.targetGuid)
if not tInfo then
print("Cannot get target info")
return
end
-- Duplicate check: if target is already in list, show a message with current count
for _, guid in ipairs(CFG_priorityTargets) do
if guid == info.targetGuid then
print("Target already in priority list: " .. tInfo.name .. ",currently " .. #CFG_priorityTargets .. " priority targets")
return
end
end
table.insert(CFG_priorityTargets, info.targetGuid)
print("Added priority target: " .. tInfo.name .. " (guid=" .. info.targetGuid .. "),currently " .. #CFG_priorityTargets .. " priority targets")
end
-- ================= One-Button Heal Core Feature 2: [Clear All Priority Targets] =========================
-- Usage: Create a macro: /s S HealRaid_ClearTargets() — press once to clear all previously assigned priority targets
function HealRaid_ClearTargets()
local count = #CFG_priorityTargets
CFG_priorityTargets = {}
print("Cleared " .. count .. " priority targets")
end
-- Tracks the last healed target, used to determine whether to cancel casting on next keypress
local CFG_lastHealTarget = nil
-- ============================================================
-- Generic scan-heal function: iterates scanList by LEVELS priority, heals eligible targets
-- scanList: array like { { guid="xxx" }, ... }
-- minLostThreshold: extra minimum health deficit threshold, 0 = no limit
-- logPrefix: prefix for debug output (e.g. "Priority Heal" / "Heal")
-- Returns true if a spell was cast, false if no suitable target found
-- ============================================================
function TryHealScan(scanList, minLostThreshold, logPrefix)
minLostThreshold = minLostThreshold or 0
for _, lv in ipairs(GetCfgLevels()) do
local bestLost = 0
local bestInfo = nil
local bestGuid = ""
for _, m in ipairs(scanList) do
local guid = type(m) == "table" and m.guid or m
local info = GetUnitInfo(guid)
if info and info.health > 0 and info.maxHealth > 0 then
local lost = info.maxHealth - info.health
if lost >= lv.minLost and lost >= minLostThreshold then
local dist = Distance(guid)
if dist <= lv.maxDist and lost > bestLost then
-- noAura check: skip targets that already have this aura
local noAuraOk = true
if lv.noAura and lv.noAura ~= 0 then
if info.auras then
for _, aura in ipairs(info.auras) do
if aura.spellId == lv.noAura then
noAuraOk = false
break
end
end
end
end
if noAuraOk then
bestLost = lost
bestInfo = info
bestGuid = guid
end
end
end
end
end
if bestInfo ~= nil then
if CFG_DEBUG_HEAL then
print(logPrefix .. ": " .. bestInfo.name .. "[" .. lv.name .. "] deficit:" .. bestLost .. " distance:" .. math.floor(Distance(bestGuid)))
end
Spell(lv.spellId, bestGuid)
CFG_lastHealTarget = bestGuid
return true
end
end
return false
end
-- ============================================================
-- ================= One-Button Heal Core Feature 3: [Auto-Heal Full Raid] =========================
-- Usage: Create a macro: /s S HealRaid()
function HealRaid()
-- ============ Smart cancel: if the last healed target is now full HP, cancel current cast ============
if CFG_lastHealTarget then
local lastInfo = GetUnitInfo(CFG_lastHealTarget)
if lastInfo and lastInfo.health > 0 and lastInfo.health >= lastInfo.maxHealth then
StopCasting()
if CFG_DEBUG_HEAL then print("Cancel cast: " .. lastInfo.name .. " is full HP") end
CFG_lastHealTarget = nil
-- Continue scanning for the next teammate needing heals
end
end
-- Re-fetch healing tier config based on current class
local cfgLevels = GetCfgLevels()
if not cfgLevels or #cfgLevels == 0 then
if CFG_DEBUG_HEAL then print("One-Button Heal: class config is empty, check if your class is supported") end
return
end
-- ============ V6 new feature: priority target scan ============
-- Scan priority targets first; only heal if health deficit >= CFG_PRIORITY_MIN_LOST
if CFG_priorityTargets and #CFG_priorityTargets > 0 then
if TryHealScan(CFG_priorityTargets, CFG_PRIORITY_MIN_LOST, "Priority Heal") then
return
end
end
-- ==========================================
local me = GetMeInfo()
local members = TeamMembers()
-- ============ V5 addition: when not in a group, add yourself to scan list ============
local scanList = {}
if members and #members > 0 then
-- In a group, add all members normally
for i, m in ipairs(members) do
scanList[#scanList + 1] = m
end
else
-- Not in a group, add yourself
if me and me.guid then
scanList[#scanList + 1] = { guid = me.guid, name = "(self)" }
if CFG_DEBUG_HEAL then print("One-Button Heal: not in a group, healing self only") end
end
end
-- Full raid scan
if not TryHealScan(scanList, 0, "Heal") then
if CFG_DEBUG_HEAL then print("No healing needed") end
end
end
-- ================= One-Button Heal Core Feature 4: [Auto-Heal Your Own Party] =========================
-- Usage: Create a macro: /s S HealRaidP()
function HealRaidP()
-- ============ Smart cancel: if the last healed target is now full HP, cancel current cast ============
if CFG_lastHealTarget then
local lastInfo = GetUnitInfo(CFG_lastHealTarget)
if lastInfo and lastInfo.health > 0 and lastInfo.health >= lastInfo.maxHealth then
StopCasting()
if CFG_DEBUG_HEAL then print("Cancel cast: " .. lastInfo.name .. " is full HP") end
CFG_lastHealTarget = nil
-- Continue scanning for the next teammate needing heals
end
end
-- Re-fetch healing tier config based on current class
local cfgLevels = GetCfgLevels()
if not cfgLevels or #cfgLevels == 0 then
if CFG_DEBUG_HEAL then print("One-Button Heal: class config is empty, check if your class is supported") end
return
end
-- ============ V6 new feature: priority target scan ============
-- Scan priority targets first; only heal if health deficit >= CFG_PRIORITY_MIN_LOST
if CFG_priorityTargets and #CFG_priorityTargets > 0 then
if TryHealScan(CFG_priorityTargets, CFG_PRIORITY_MIN_LOST, "Priority Heal") then
return
end
end
-- ==========================================
local me = GetMeInfo()
local members = TeamMembers()
-- ========= Core modification: only filter [your own party] members =========
local scanList = {}
if members and #members > 0 then
-- Find your own subgroup number
local mySubGroup = nil
for _, m in ipairs(members) do
if m.guid == me.guid then
mySubGroup = m.subgroup
break
end
end
-- Only add members from the same subgroup
if mySubGroup ~= nil then
for _, m in ipairs(members) do
if m.subgroup == mySubGroup then
scanList[#scanList + 1] = m
end
end
end
else
-- Not in a raid/party, only heal yourself
if me and me.guid then
scanList[#scanList + 1] = { guid = me.guid, name = "(self)" }
if CFG_DEBUG_HEAL then print("One-Button Heal: not in a group, healing self only") end
end
end
-- Party scan
if not TryHealScan(scanList, 0, "Party Heal") then
if CFG_DEBUG_HEAL then print("Party: no healing needed") end
end
end