Custom Lua triggers provide unlimited flexibility by allowing you to write your own trigger logic in Lua. They can monitor any game state, process complex conditions, and create sophisticated detection systems.
Custom triggers run frequently and can impact performance. Profile and optimize your code.
function() -- Return true to activate the display local health = UnitHealth("player") local maxHealth = UnitHealthMax("player") return health < maxHealth * 0.3end
-- Trigger functionfunction(event, ...) if event == "PLAYER_REGEN_DISABLED" then return true -- Show on combat start end return falseend-- Untrigger function (optional)function(event, ...) if event == "PLAYER_REGEN_ENABLED" then return true -- Hide on combat end end return falseend
-- Check continuouslyfunction() local mana = UnitPower("player", 0) local maxMana = UnitPowerMax("player", 0) local percent = (mana / maxMana) * 100 return percent < 20end
function(allStates, event, ...) allStates[""] = allStates[""] or {} local state = allStates[""] state.value = UnitHealth("player") state.total = UnitHealthMax("player") state.changed = true return trueend
function(allStates, event, ...) -- Create state for each combo point local comboPoints = GetComboPoints("player", "target") for i = 1, 5 do local cloneId = "cp" .. i allStates[cloneId] = allStates[cloneId] or {} allStates[cloneId].show = i <= comboPoints allStates[cloneId].changed = true allStates[cloneId].index = i end return trueend
function(allStates, event, unit) if not unit then return false end allStates[unit] = allStates[unit] or {} local state = allStates[unit] state.show = UnitExists(unit) state.changed = true state.unit = unit state.name = UnitName(unit) state.health = UnitHealth(unit) return trueend
-- EventsUNIT_HEALTH, UNIT_MAXHEALTH-- Trigger function function(event, unit) if unit ~= "player" then return false end local health = UnitHealth("player") local maxHealth = UnitHealthMax("player") return (health / maxHealth) < 0.5end
-- Duration function (separate from trigger)function() local start, duration = GetSpellCooldown(12345) if duration and duration > 0 then return duration, start + duration end return 0, 0end
-- Use aura_env for persistent storageaura_env.lastValue = aura_env.lastValue or 0function(allStates, event) local currentValue = UnitHealth("player") local changed = currentValue ~= aura_env.lastValue aura_env.lastValue = currentValue if changed then allStates[""] = { show = true, changed = true } return true end return falseend
aura_env.lastUpdate = aura_env.lastUpdate or 0function(allStates, event) local now = GetTime() -- Only update every 0.5 seconds if now - aura_env.lastUpdate < 0.5 then return false end aura_env.lastUpdate = now -- Process trigger logic... return trueend
function(allStates, event, triggerId, states) if event ~= "TRIGGER" then return false end -- React to trigger 1's state changes if triggerId == 1 then allStates[""] = { show = true, changed = true, otherShow = states[""] and states[""].show } return true end return falseend
Use “Watched Trigger Events” in the advanced trigger options to enable trigger watching.
-- Unit infoUnitName("player")UnitClass("player")UnitLevel("player")UnitRace("player")-- Unit stateUnitHealth("player")UnitHealthMax("player")UnitPower("player", 0) -- 0 = manaUnitPowerMax("player", 0)-- Unit statusUnitExists("target")UnitIsDeadOrGhost("player")UnitAffectingCombat("player")UnitIsPlayer("target")
-- Bad: Multiple API callsfunction() if UnitHealth("player") < UnitHealthMax("player") * 0.3 then return UnitHealth("player") > 0 endend-- Good: Cache valuesfunction() local health = UnitHealth("player") local maxHealth = UnitHealthMax("player") if health < maxHealth * 0.3 then return health > 0 endend
Early Returns
function(event, unit) -- Filter early if unit ~= "player" then return false end -- Expensive checks only if needed local comboPoints = GetComboPoints("player", "target") return comboPoints >= 5end
Avoid Table Creation
-- Bad: Creates table every callfunction(allStates) allStates[""] = { -- New table! show = true, changed = true }end-- Good: Reuse tablefunction(allStates) allStates[""] = allStates[""] or {} local state = allStates[""] state.show = true state.changed = trueend
function(allStates, event, unit) if unit and unit ~= "player" then return false end local state = allStates[""] or {} state.show = true state.changed = true state.value = UnitPower("player", 0) state.total = UnitPowerMax("player", 0) state.progressType = "static" allStates[""] = state return trueend
aura_env.targets = aura_env.targets or {}function(allStates, event, ...) -- Scan nameplates for your DoTs for i = 1, 40 do local unit = "nameplate" .. i if UnitExists(unit) then local name, _, _, count, _, duration, expires = UnitDebuff(unit, "Shadow Word: Pain", nil, "player") local guid = UnitGUID(unit) if name and guid then allStates[guid] = { show = true, changed = true, name = UnitName(unit), stacks = count, duration = duration, expirationTime = expires, progressType = "timed" } elseif allStates[guid] then allStates[guid].show = false allStates[guid].changed = true end end end return trueend
function(allStates, event) -- Print current states for cloneId, state in pairs(allStates) do print("Clone:", cloneId, "Show:", state.show) end return trueend
function(allStates, event) local success, result = pcall(function() -- Your trigger code return UnitHealth("player") < 1000 end) if not success then print("Trigger error:", result) return false end return resultend
WeakAuras automatically wraps trigger functions in pcall. Errors will be logged but won’t break the addon.