-
-
Notifications
You must be signed in to change notification settings - Fork 321
Useful Snippets
This page will be a repository of potentially useful snippets of code that don't find a clear home elsewhere.
This will also allow a parent dynamic group to sort them by order of creation.
function(allstates, ...)
--do some stuff
--maybe decision trees or whatever
local newState = {
--state info goes here
show = true,
index = 0, --this bit is important
}
tinsert(allstates, newState)
--this functions as a queue; the oldest clones will be deleted first
for _,v in pairs(allstates) do
v.index = v.index + 1
v.changed = true
if v.index > cloneLimit then --where cloneLimit is some number > 0
v.show = false
end
end
return true
end
for unit in WA_IterateGroupMembers() do
<block>
end
The GetSpellinfo()
API call is not idempotent when used on a spellid (to my knowledge, it is idempotent when you pass localized spell names, however)
GetSpellInfo(GetSpellInfo(spellid)) == GetSpellInfo(spellid)
is not necessarily true.
You can use this to your advantage in situations where you have one spell that replaces another, such as with New/Half/Full Moon for balance druids, or Blunderbuss/Pistol Shot for outlaw rogues. You can use the following script to detect when a spell has been replaced:
local spellid = 123 --replace 123 with the appropriate spellid
if select(7,GetSpellInfo(GetSpellInfo(spellid))) ~= spellid then --that spell has been replaced
--do something here
else --the spell has not been replaced
--do something else here
end
GetSpellPowerCost(spellid)
returns a table.
Cost is found at:
GetSpellPowerCost(spellid)[1].cost
An example of how this could be used would be a custom function that you can call by sending the spellID and get the cost returned:
aura_env.GetCost = function(spellID, powerType)
if not spellID then return end
powerType = powerType or UnitPowerType("player")
local cost = 0
local costTable = GetSpellPowerCost(spellID);
for _, costInfo in pairs(costTable) do
if costInfo.type == powerType then
return costInfo.cost;
end
end
end
aura_env.GetCost(spellID [, powerType])
An example of this function's use in a Weak Aura: Link
If you're looking to attach an aura to a specific unit's nameplate, then use the following to get the correct frame.
C_NamePlate.GetNamePlateForUnit(unitID)
Using the above call we can get the nameplate for a specific unit and anchor a WA frame to it. Here's an example of how you might do that, in this case to attach a WA to our target's nameplate.
Starting with whatever regular trigger you're using to show the info you want, add a trigger using the settings:
Custom - status - Every Frame
and in the trigger paste the code:
function()
local region = aura_env.region
local plate = C_NamePlate.GetNamePlateForUnit("target")
if plate then
region:ClearAllPoints()
region:SetPoint("BOTTOM", plate, "TOP", 0, 0)
return true
else
return false
end
end
Lastly ensure that this new trigger is not required for activation of the overall WA by using ANY at the top of the trigger tab. (If your WA requires multiple triggers before adding this new one then you may need to use Custom trigger logic to exclude this new one - https://github.com/WeakAuras/WeakAuras2/wiki/Aura-Activation-and-Deactivation#custom)
This will anchor the WA to your target's nameplate, or if they're off screen it will hide it. To alter the position of the WA relative to the nameplate adjust the arguments in SetPoint() (https://wow.gamepedia.com/API_Region_SetPoint)
To avoid Every Frame you could use the events "Event - PLAYER_TARGET_CHANGED, NAME_PLATE_UNIT_ADDED, NAME_PLATE_UNIT_REMOVED, NAME_PLATE_CREATED
". To avoid all issues though you would, in some situations, need to add a WeakAuras.ScanEvents("NAMEPLATE_ANCHOR")
to Actions - On Show - Custom, then add NAMEPLATE_ANCHOR
to the list of events.
Works on all classes and specs.
local gcd = UnitPowerType("player") == 3 and (WA_GetUnitBuff("player",13750) and .8 or 1) or max(1.5/(1 + .01 * UnitSpellHaste("player")), WA_GetUnitBuff("player", 194249) and .67 or .75)
WeakAuras now has a default trigger status - Range Check
that allows for range checks to specified units. If you do need to do some range checking in custom functions then you can also use the WeakAuras functions to simplify things:
WeakAuras.IsSpellInRange(spellId | spellName, unit)
This is very similar to the regular Blizzard function but allows the use of spellIDs or spell names. Returns a single value of nil, 0, or 1 for invalid target, out of range, in range respectively.
WeakAuras.GetRange(unit)
Since there's no way to get precise range info this is as close as it gets. Returns two number values for min and max possible distance from the given unit.
WeakAuras.CheckRange(unit, range, operator)
Allows to check if in or out of a given distance from the target. Give a unit, range number and either ">=" or "<=". Returns boolean.
With precise Unit positions being locked in meaningful content we're limited in the functions we can use to check ranges. The main options are IsItemInRange()
and IsSpellInRange()
. Although they seem very similar IsSpellInRange requires a spell name and a unit, while IsItemInRange will accept an item name, ID or Link, along with the unit. Also while IsItemInRange returns a simple boolean, IsSpellInRange returns a 1/0/nil for true/false/invalid.
A simple spell range check would look like:
function()
return IsSpellInRange((GetSpellInfo(203782)), "target") == 1
end
While a simple item range check would be:
function()
return IsItemInRange(33278, "target")
end
Say you want a trigger to check if there are 3 or more nameplates in range:
function()
local count = 0
for i = 1, 40 do
local unit = "nameplate"..i
if UnitCanAttack("player", unit)
and WeakAuras.CheckRange(unit, 8, "<=")
then
count = count + 1
end
end
return count >= 3 -- change as needed
end
Honourable mentions for range checking go to:
• UnitInRange("unit")
which checks a generic distance for group members only (generally, are people close enough to be healed?)
• CheckInteractDistance("unit", distIndex)
which can be used to check some set distances like within range to trade/follow etc.
This snippet is for use in a custom text function and will return a player name with class colouring.
function()
if aura_env.state and aura_env.state.sourceName and UnitExists(aura_env.state.sourceName) then
return WA_ClassColorName(aura_env.state.sourceName)
end
end
This example uses aura_env.state.sourceName
which is something that event - combat log - spell - cast success
triggers might produce, and would work when the source of the event was someone in your group. The 4th, 5th and 6th lines are the important ones and they just need a valid UnitId.
tooltipText, debuffType, tooltipSize = WeakAuras.GetAuraTooltipInfo(unit, index, filter)
-- index is the actual aura index, not spellID etc.
-- tooltipSize is probably formatted with commas if a large number
WeakAuras.WatchSpellCooldown(id)
-- Once initialised, will fire "events" for the spell on:
SPELL_COOLDOWN_READY
SPELL_COOLDOWN_STARTED
SPELL_COOLDOWN_CHANGED
These events all carry the spellID of the CD that's changing as their first arg.
Some aura settings (several in the display tab) can't be easily adjusted from within custom functions. In these instances you can use the following to acquire the aura's settings, adjust them, then save them back again.
-- Get the aura data
local data = WeakAuras.GetData(aura_env.id)
local region = aura_env.region
local regionType = WeakAuras.regions[aura_env.id].regionType
-- Make alterations
data.inverse = not data.inverse -- this is an example of a change that could be made
-- Save the altered aura data
WeakAuras.regionTypes[regionType].modify( WeakAurasFrame, region, data)
This is an expensive function, so call it sparingly.
NOTE - aura_env.region
now returns the correct region for clones as well as normal Auras. this makes the following much less frequently needed.
Especially useful for TSU auras.
WeakAuras.GetRegion(auraID, cloneID)
If this is being used within a code block that's specific to the clone (i.e. Custom Text, Custom Animations, On Show/Hide) then you can simply use WeakAuras.GetRegion(aura_env.id, aura_env.cloneId)
To set a progress bar to start full, even with a trigger that uses a "remaining" value that's less than max, you can use this in Actions > On Show > Custom:
aura_env.region:SetDurationInfo(aura_env.state.expirationTime - GetTime(), aura_env.state.expirationTime)
To invert a progress bar programmatically (can now be done in Conditions if you don't need it to be in code) you can use:
aura_env.region:SetDurationInfo(aura_env.state.duration, aura_env.state.expirationTime, nil, true)
Specifically this is for checking against a spell's CD to ensure that it is on CD and not just showing the global.
local gcdSTART, gcdDUR = GetSpellCooldown(61304) -- GCD
local GCD_expirationTime = gcdSTART + gcdDUR
if spell_expirationTime == GCD_expirationTime then
--we are NOT on CD
elseif spell_expirationTime > GCD_expirationTime then
--we ARE on CD.
end
This can also be done with the assistance of a couple of WeakAuras functions:
Putting WeakAuras.WatchGCD()
in an Aura's "On Init" gives access to:
local start, duration = GetSpellCooldown(spellId)
if duration > 0 and duration ~= WeakAuras.gcdDuration() then
--We ARE on CD
else
--We ARE NOT on CD
end
If using a status - health
or status - power
trigger, a variable will be available for percentages. However the placeholders %percenthealth
and %percentpower
are unformatted, and generally return many decimal places. To round it and add a percent sign you can use %c
in the text box to open a custom code block, then paste:
function()
if aura_env.state and aura_env.state.percenthealth then
return Round(aura_env.state.percenthealth).."%"
end
end
Paste the following into Actions - On Init - Custom
and adjust the 4 values in brackets for the required colour and opacity - (red, green, blue, alpha)
aura_env.region.cooldown:SetSwipeTexture([[Interface\AddOns\WeakAuras\Media\Textures\Square_White]])
aura_env.region.cooldown:SetSwipeColor(0.17,0,0,0.8)
Add this to a code block that runs every frame (e.g. Custom Text), and set the text
variable to what you want it to show (handles placeholders)
function()
local text = "%p"
local r = aura_env.region
if not r.text3 then
local text3 = r.bar:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
r.text3 = text3
r.text3:SetFont(r.text:GetFont()) -- reload UI if you need this to update
r.text3:SetPoint("CENTER", r.bar)
end
r.text3:SetText(WeakAuras.ReplacePlaceHolders(text, r))
end
Put this into Actions - On Init - custom
local aura_env = aura_env
local GetBossInfo = function()
aura_env.bossUnit = {}
for i = 1,5 do
local unit = "boss"..i
if UnitExists(unit) then
local GUID = UnitGUID(unit)
local NPCID = select(6, strsplit("-", GUID))
aura_env.bossUnit[tonumber(NPCID)] = unit
end
end
end
local spawnChecker = CreateFrame("Frame")
spawnChecker:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT")
spawnChecker:SetScript("OnEvent", GetBossInfo)
This will give you a table of Boss unit IDs accessible via their NPC ID throughout your Aura.
e.g. UnitIsUnit("player", aura_env.bossUnit[123456].."target")
aura_env.GetTriggerState = function(trigger, field, aura, clone)
if not clone then clone = aura_env.cloneId or "" end
if not aura then
if aura_env.id then
aura = aura_env.id
else
return false
end
end
if WeakAuras.triggerState[aura]
and WeakAuras.triggerState[aura][trigger]
and WeakAuras.triggerState[aura][trigger][clone] then
return field and WeakAuras.triggerState[aura][trigger][clone][field]
or WeakAuras.triggerState[aura][trigger][clone]
end
end
GetTriggerState = function(trigger[, field[, aura[, clone]]])
-
trigger
: number - trigger number as it appears in the trigger tab -
field
: string - a valid key in the state table -
aura
: string - aura_env.id -
clone
: string or number - aura_env.cloneId
e.g.
GetTriggerState(4, "expirationTime")
Would try to fetch the expirationTime value from trigger 4
GetTriggerState(2, nil, "New 3")
Would try to get the whole state table from the Aura called "New 3"'s trigger2
Use /dump VAR_NAME
in game to check their contents.
-
ICON_LIST
: Raid target marker texture paths -
RAID_CLASS_COLORS
: Default colour info for classes -
COMBATLOG_DEFAULT_COLORS.schoolColoring
: Default colour info for damage schools
- Home
- API Documentation
- Getting Involved
- Setting up a Lua Dev Environment
- Deprecations
- Useful Snippets
- Aura Types
- Trigger Types
- Triggers and Untriggers
- Aura Activation
- Dynamic Information
- Text Replacements