Introduction
What's an object func?
An object function is a key within an awful object that must be called
call()
to return a value.Most functions are non-case-sensitive and many have fallback aliases for added intuitiveness factor.
Function Performance
Functions are less performant than attributes, as a lot of them cannot / do not use the same caching techniques, but they do not face the same limitations.
General Functions
canAttack
Checks if the unit can attack another unit
unit.canAttack(otherUnit) : true | false
if target.canAttack(focus) then
print("My target unit and focus unit don't like each other!")
end
isUnit
Compares the object with another to determine if they're the same.
unit.isUnit(otherUnit) : true | nil
if target.isUnit(focus) then
print("My target unit and focus unit are the same!")
end
friendOf
Checks if the unit is friends with another unit
unit.friendOf(otherUnit) : true | false
if target.friendOf(focus) then
print("My target unit and focus unit are best friends!")
end
hasTalent
Checks if the object has the given talent or PvP talent selected.
unit.hasTalent(talent) : true | false
Note: Accepts talent name (non-case-sensitive string) or SpellID.
Note: This only works with members of your
group
, including theplayer
object.
print(healer.hasTalent("Ascendance")) -- checking if your friendly healer is spec'd into ascendance.
-- res: true
print(player.hasTalent("ring of frost")) -- is the player spec'd into ring of frost?
-- res: true
for _, member in ipairs(awful.group) do
if member.class == "Shaman" and member.hasTalent(204336) then
print("wow, our shaman has grounding totem!")
end
end
Buffs & Debuffs
Note:
All buff/debuff functions accept SpellID or Spell Names, and optionally any "Awful Object" as the second arg, which will only return a value if your given object was the caster of the buff/debuff. Spell name queries are non-case-sensitive.
target.buff('combustion')
works fine. SpellID is generally the only assuredly accurate method though, as there are several buffs & debuffs in game with the same name.
Be sure to check out what's available under the Buffs & Debuffs section in attributes before beginning your implementation.
buff
Provides information about a specific buff on the object.
unit.buff(spell[,sourceObject]) : "buff", ... | nil
Returns: Identical to UnitBuff - [1] string
name
, ... |nil
if enemy.buff("combustion") then
print("Wowie, I'm gonna die!")
iceBlock:Cast()
end
buffRemains
The time remaining of a specific buff on the object.
unit.buffRemains(spell[,sourceObject]) : remains | 0
if ourHealer.buffRemains("avenger's wrath") > 10 then
print("I feel very safe.")
end
buffStacks
Number of stacks the object has of the given buff.
unit.buffStacks(spell[,sourceObject]) : stacks | 0
if player.buffStacks("Well Fed") > 1 then
print("It's probably time to start counting our calories.")
end
buffUptime
The amount of time that the given buff has been active on the object.
unit.buffUptime(spell[,sourceObject]) : uptime | 0
if hunterPet.buffUptime("frenzy") > 10 then
print("That hunter has been keeping up his frenzy stacks for a while!")
end
buffFrom
Query the object for a list of any active buffs matching the Spell IDs / Spell Names within the given array.
unit.buffFrom(spellList[,sourceObject]) : { buff, buff, ... } | nil
Similar: buffsFrom - Same as buffFrom, except it returns the number of buffs from the list that are active
if friend.buffFrom({980, 172, 1822}) then
print("My friend is dotted! Oh no!")
end
debuff
Provides information about a specific debuff on the object.
unit.debuff(spell[,sourceObject]) : "debuff", ... | nil
Returns: Identical to UnitDebuff - [1] string
name
, ... |nil
if ourHealer.debuff("freezing trap") then
print("My mans is trapped")
end
debuffRemains
The time remaining of a specific debuff on the object.
unit.debuffRemains(spell[,sourceObject]) : remains | 0
if target.debuffRemains("Kidney Shot") > 4 then
print("time for a double wide surprise.")
end
debuffStacks
Number of stacks the object has of the given debuff.
unit.debuffStacks(spell[,sourceObject]) : stacks | 0
if friend.debuffStacks(980) > 3
and decurse:Cast(friend) then
return awful.alert("Decursed them stacks!", 475)
end
debuffUptime
The amount of time that the given debuff has been active on the object.
unit.debuffUptime(spell[,sourceObject]) : uptime | 0
if player.debuffUptime("Agony") > 25 then
decurse:Cast(player)
print("Agony's been up for way too long, yo!")
end
debuffFrom
Query the object for a list of any active buffs matching the Spell IDs / Spell Names within the given array.
unit.debuffFrom(spellList[,sourceObject]) : { debuff, debuff, ... } | nil
Similar: debuffsFrom - Same as debuffFrom, except it returns the number of debuffs from the list that are active
local badStuff = {"Storm Bolt", 408, "Cheap Shot"}
if player.debuffFrom(badStuff) then
if iceBlock:Cast() then
return awful.alert("I've had enough of that.", 45438)
end
end
Spells / Casting
cooldown
Estimates the cooldown of any Unit's spell based on combat log event tracking happening in the background by the framework.
unit.cooldown(spellID | spellName) : cooldown | 0
-- most performant with spellIDs
if enemy.cooldown(22812) > 6 then
if kidney:Cast(enemy) then
awful.alert("Kidney Shot (No Skin)", kidney.id)
end
end
-- works with spell names tho, non-case-sensitive
if enemy.cooldown("avenging wrath") > 30 then
print("we're probably safe yo")
end
used
Checks if the Unit has cast the given spell in the past x seconds, based on combat log event tracking happening in the background by the framework.
unit.used(spellID | spellName[,durationSeconds]) : true | nil
-- most performant with spellIDs
if player.used(22812, 15) then
print("we used barkskin in the last 15 sec")
end
-- works with spell names tho, non-case-sensitive
if enemy.used("avatar", 5) then
print("They used avatar recently yo")
end
Movement & Position
distanceTo
Distance between the object and another object, accounting for combat reach and bounding radius.
unit.distanceTo(otherObject) : distance | 9999
Sister Attribute: distance - checks distance from the player to the object
Similar: distanceToLiteral - same as distanceTo but ignores combatReach
if target.distanceTo(enemyHealer) > 40 then
print("He's out of range of heals!")
stormBolt:Cast(target)
end
facing
Checks if the object is facing another object [at a 180 degree angle by default - the required facing angle to cast spells]. You can check a specific angle (in degrees) by passing it as the 2nd arg.
unit.facing(otherUnit[,angle]) : isFacing | false
Sister Attribute:
playerFacing[,Angle]
- checks if the player is facing the object. e.g,target.playerFacing
ortarget.playerFacing45
if player.facing(target) then
print("I'm facing my target, so can cast normal spells that require facing!")
end
if player.facing(target, 45) then
print("I'm facing my target at a <45 degree angle!")
end
-- shockwave example
local bin = awful.bin
local angle = 45 + bin(30, player.hasTalent("big shockwave")) -- 75 degree angle with big shockwave!
local caught = 0
for _, enemy in ipairs(awful.enemies) do
caught = caught + bin(enemy.distance < 8 and player.facing(enemy, shockwaveAngle))
end
if caught >= 3 then
shockwave:Cast()
end
facingPosition
Same as facing, but you pass it an x, y, z position.
local x,y,z = example.position()
if enemy.facingPosition(x,y,z,45) then
print("nice!")
end
From the example above:
awful.bin
losOf
Checks if the object and another object are in line of sight of each other.
unit.losOf(otherUnit) : isLoS | false
Sister Attribute: los - checks between player & object
if not target.losOf(enemyHealer) then
print("Target is out of LoS of his healer, kill!")
end
losOfLiteral
Checks if the object is in line of sight of the given object, but ignores line of sight impairing effects like smoke bomb.
unit.losOfLiteral(otherUnit) : isLoS | false
Sister Attribute: losLiteral - checks between player & object
if target.debuff("Smoke Bomb") then
print(target.losOfLiteral(player))
end
-- true ... (ignores los-impairing effects!)
position
Current 3D position of the object.
unit.position() : x, y, z | nil
local x, y, z = target.position()
print(x, y, z)
-- 2039.393103, 1083.11938, 81.9
predictPosition
The object's estimated position after the given time, based on current velocity & moving direction.
unit.predictPosition(timeInSeconds) : x, y, z | curX, curY, curZ | nil
-- cast spell where linear prediction determines the object will be in 0.5s
local x,y,z = unit.predictPosition(0.5)
spell:AoECast(x,y,z)
predictDistance
The object's estimated distance from the given Awful Object [or player
] after the given time has elapsed. Based on current velocity and moving direction.
unit.predictPosition(timeInSeconds[,otherObject]) : dist | 9999
Similar:
predictDistanceLiteral - Same thing but ignores combat reach
predictDistanceToPosition - Same thing but passed position (x, y, z, elapsed)
print(healer.predictDistance(0.5))
print(healer.distance)
-- 41
-- 38
predictLoS
Estimates whether the object will be in line of sight of the given Awful Object [or player
] after the given time has elapsed. Based on current velocity and moving direction.
unit.predictLoS(timeInSeconds[,otherObject]) : isLoS | false
print(target.predictLoS(0.5, enemyHealer))
print(target.losOf(enemyHealer))
-- false
-- true
-- ^ Random use case: Target is moving out of LoS of their healer, prepare a swap to them.
meleeRangeOf
Checks if the unit is in melee range of another unit.
unit.meleeRangeOf(otherUnit) : true | false
Sister Attribute:
meleeRange
- Checks if the player is in melee range of the unit
if enemy.meleeRangeOf(healer) then
print("oh no, he's connected to our healer!")
end
movingToward
Checks if the unit is / has been moving toward another unit, given the angle and duration passed (if any) ...
unit.movingToward(otherUnit[,{ angle = degrees, duration = seconds }]) : true | false
Both angle and duration are optional. You may check one or the other, or neither.
Default duration is 0 (Immediately returns true when movement direction meets angle)
Default angle is 30deg (Returns true when object is moving toward at an acute angle)
if player.movingToward(target) then
print("Nice!")
end
if enemy.movingToward(player, { angle = 45 }) then
print("he wants my asshole!")
end
if enemy.movingToward(healer, { angle = 90, duration = 0.5 }) then
print("he wants my healer's pp real bad!")
end
movingAwayFrom
Checks if the unit is / has been moving away from another unit, given the angle and duration passed (if any) ...
unit.movingAwayFrom(otherUnit[,{ angle = degrees, duration = seconds }]) : true | false
Both angle and duration are optional. You may check one or the other, or neither.
Pass angle inverse of movingToward, more obtuse = more acute to opposing direction
Default duration is 0 (Immediately returns true when movement direction meets angle)
Default angle is 220deg (Returns true when object is moving away from at a 140deg angle)
if player.movingAwayFrom(enemy, { angle = 300, duration = 0.25 }) then
print("it looks like we're really fleeing from this guy")
end
if enemy.movingAwayFrom(player, { angle = 320 }) then
print("they are running from me lolz")
end
if healer.movingAwayFrom(enemy, { angle = 280, duration = 0.5 }) then
print("my healer is trying to kite them, maybe I should root them or somethin idk")
end
Actions
face
Faces the unit or angle as given
unit.face() : void
player.face(unit) : void
player.face(angle) : void
local exampleAngle = getExampleAngle
player.face(exampleAngle)
if enemy.stupid then
enemy.face() -- this works
player.face(enemy) -- this also works
end
setFocus
Sets the unit as focus
unit.setFocus() : void
setTarget
Sets the unit as target
unit.setTarget() : void