awful has a lot of useful tools to help clean up code and make complex tasks easier to perform
i'm throwing them all in here, let's call it the toolbox
important variables
time
awful.time
current time in seconds, equal to
GetTime()
, but only updated when awful framework ticks.
buffer
awful.buffer
a combination of dynamic values which is roughly equal to the time it should take for what's displayed on your client to reach the servers, plus 1 tick of buffer for your script to react before it's too late, and 30ms to account for any latency jitter:
buffer = latency + tickRate + jitter
-- buffer is used in many places within the framework to dynamically account for latency.
-- here's a quick example of how you can use it yourself:
-- calculating when to time a spell reflection or interrupt at the VERY latest possible moment:
if enemy.castRemains <= awful.buffer then
if interrupt.cd == 0 and interrupt:Cast(enemy) then
awful.alert("interrupted thing")
elseif reflect:Cast() then
awful.alert("reflected thing!")
end
end
latency
awful.latency
Your latency to the game server, averaged out over the last 30 seconds, with HTTP overhead accounted for.
tickRate
awful.tickRate
The time between each awful framework tick.
Generally, if an event will happen before
time
+tickRate
, your script will not 'tick' again to react in time. That's why this is an important variable, it determines how manyticks
you want to think ahead.The value always varies for two reasons:
1.) Routine Actors can set a static tickrate, and the rest of the framework will comply with it, but if framerate is too low, the fastest it can run is once per frame.
2.) If an Actor is running once per frame, the value will still be > 0, roughly equal to the time between each frame
1/GetFramerate()
, but the value is actually calculated each tick (current tick time
-last tick time
) then averaged out between the last 5 ticks.
spellCastBuffer
awful.spellCastBuffer
The Spell Queue Window duration set by awful
This is also the maximum amount of time remaining on GCD or cast time that it will queue the next spell within.
gcd
awful.gcd
The total expected GCD duration per general 1.5s GCD incurring spell cast
Most spells on GCD incur a base 1.5s cooldown modified by haste, some incur their own shorter one
1.5 / ( 1 + player.haste )
see also: Spell Object Attribute
spell.gcd
- the gcd that the queried spell incurs
hasControl
awful.hasControl
whether or not the player has control of their character
zone
awful.zone
current zone text
mapID
awful.mapID
current mapID
powerTypes
awful.powerTypes = {
["mana"] = 0,
["rage"] = 1,
["focus"] = 2,
["energy"] = 3,
["combopoints"] = 4,
["cp"] = 4,
["runes"] = 5,
["runicpower"] = 6,
["soulshards"] = 7,
["shards"] = 7,
["astralpower"] = 8,
["ap"] = 8,
["lunarpower"] = 8,
["holypower"] = 9,
["alternatepower"] = 10,
["maelstrom"] = 11,
["chi"] = 12,
["insanity"] = 13,
["arcanecharges"] = 16,
["fury"] = 17,
["pain"] = 18,
["essence"] = 19
}
awesome functions
onTick
Adds a callback function to the main framework ticker. These are called in the order added, just before the routine actor.
awful.onTick(callback[,enabled])
-- only running while routine is enabled
awful.onTick(function()
print("This is being called a lot, but only while my routine is on!")
end, true)
-- running every tick, all the time
awful.onTick(function()
print("This is being called a lot, all the time!")
end)
onUpdate
Does the same thing as onTick
, but runs every frame instead (almost always faster).
awful.onUpdate(callback[,enabled])
onEvent
Assign a callback to a combat log or other event firing.
-- passing it a specific event type will create a frame, register that frame for the event, and assign it your callback as an OnEvent handler
local function printSpec()
print(awful.player.spec)
end
awful.onEvent(printSpec, "PLAYER_SPECIALIZATION_CHANGED")
-- if a specific event type is not passed, it will fire on combat log events,
-- passing event info, type, as well as source (and dest if applicable) units as awful objects.
awful.onEvent(function(info, event, source, dest)
local time = GetTime()
if event == "SPELL_CAST_SUCCESS" then
-- combat log event info is passed as a table, and can be unpacked like so
-- this is starting at the 12th entry of SPELL_CAST_SUCCESS, which is the spellID
local spellID, spellName = select(12, unpack(info))
print(time, spellID, spellName, source.name, source.class, dest.name)
end
end)
bin
Converts value of given expression / variable into binary.
- Any value (bool, string, number, float, function) is 1
- No value (nil, false) is 0.
bin(nil / false) : 0
bin(any value) : 1
awful.bin(conditions) : 1 | 0
local bin = awful.bin
print( bin(player.isPlayer) )
-- 1
print( bin(player.enemy) )
-- 0
print( bin(player.isPlayer) * 30 )
-- 30
print( bin(player.enemy) * 30 )
-- 0
-- example use case: only cast quarter DR sheep if 17.5/18s remains on the DR reset.
if target.incapDR == 1 or target.idrRemains > 14 + bin(target.idr == 0.25) * 3.5 and target.idr >= 0.25 then
sheep:Cast(target)
end
-- what this would have looked like without bin
if target.incapDR == 1 or target.idrRemains > 14 + (target.idr == 0.25 and 3.5 or 0) and target.idr >= 0.25 then
sheep:Cast(target)
end
controlMovement
Temporarily disables movement (and optionally facing) input from the player.
awful.controlMovement(duration[,facing])
see also:
stopMoving
spell:Cast option
-- somewhere in our actor, using super basic logic to take control of movement to finish a sheep cast
-- only controlling it for 2 frames, so that we
if player.castID == sheep.id and player.castTarget.los then
awful.alert("Controlling Movement (Sheep)", sheep.id)
awful.controlMovement(awful.tickRate * 2)
end
controlFacing
Temporarily disables facing input from the player, including right mouse button movement and keyboard turning actions.
awful.controlFacing(duration)
StopMoving
Immediately stops the player from moving, as long as they're not in the air.
awful.StopMoving()
Populate
Creates a reference to each entry within given associative array (Param 1) inside of all other given tables, namespaces, scopes, etc. as well (Params 2 - N)
awful.Populate(aArray, t1[, t2, t3, t4, t5, ...])
This is a useful tool when used correctly, that allows you to 'merge' references to all values (including functions, objects, tables, etc.) between multiple tables - which can be namespaces, lists of objects, etc.
For example, you can create a list of spells as an associative array like this:
local list = { healingTouch = Spell(1234), mightyBash = Spell(12345), ... }
Then make a reference to all keys in the list available to other table(s), namespaces, or scopes using Populate, like this:
local actor = project.druid.feral local otherList = {} -- param 1, the list we want to copy references from -- all other params are being copied to awful.Populate(list, otherList, actor, getfenv(1)) -- now otherList AND actor can access healingTouch & mightyBash! print(otherList.mightyBash.cooldown) print(actor.healingTouch.id) -- also, since we copied to `getfenv(1)`, they're available directly to the scope of this file! print(mightyBash.name)
Note: The key
parent
will be written to each table within the associative array. Mainly to allow objects to find their siblings in the list. For example, all spell objects in a list automatically have direct access to each other within their :Callback function environments afterPopulate
is calledtl;dr: This thing puts a copy of all the stuff in one table into other tables
Pull Timer
Creates a reference to a pull timer that has been used by things like DBM or BigWigs. Defaults to 0 if no pull timer.
awful.pullTimer : 0
awful.pullBradsWilly : 0