session:buff: Buffs
The buffs on one character’s buff bar, read through its session. session:buff() is that bar.
local session = hafen.session():current() -- the character on screen
if session and session:buff():find("poison") then hafen.log():write("poisoned!") end
for _, buff in ipairs(session and session:buff():list() or {}) do
hafen.log():write(buff:name() or buff:res())
end
| Method |
Returns |
Permission |
Description |
session:buff():list(filter) |
Buff[] |
Unprotected |
Every active buff on that bar, a 1-based array in bar order. |
session:buff():count(filter) |
number |
Unprotected |
How many match. |
session:buff():find(filter) |
Buff \| nil |
Unprotected |
The first active buff that matches. |
| Rule |
Detail |
filter |
A string filter is a substring match against the resource name and the display name. A miss is nil. |
No :get |
A buff has no key: two can share a resource, and the server can replace a live buff’s resource under it. session:buff():get("poison") raises: session:buff() has no verb 'get' — a buff has no key, since two can share a resource and the server can replace one under a live buff: session:buff():find(needle) is the search and session:buff():list()[n] takes a position. |
| Whose buffs |
hafen.session():get("alt"):buff():find("poison") answers for that character while you watch another. |
| One object |
session:buff() is the same object every call, minted once per session. A session the client no longer holds answers an empty array. |
| Interned per addon |
session:buff():find("poison") == session:buff():find("poison") and seen[buff] = true work while the buff is up. A Buff wraps the buff widget and re-reads it on every call, so a stashed one tracks its meters (snapshots vs handles). It carries its own character: buff:exists() is about that character’s bar. |
| Order |
The buffs on the bar in the order drawn, which is arrival order. A buff the server has removed is excluded even while it fades out on screen. |
| Res-only at first |
The display name and the meters arrive in a second server message, so every reader may answer nil just after a buff appears. |
| No write side |
The bar displays server state. Clicking a buff icon sends a message no buff is known to act on. |
Read
| Method |
Returns |
Permission |
Description |
buff:res() |
string \| nil |
Unprotected |
The resource name, such as "paginae/buff/poison". |
buff:name() |
string \| nil |
Unprotected |
The display name, once the resource has resolved. |
buff:amount() |
number \| nil |
Unprotected |
The buff’s own meter fraction, 0..1. |
buff:remaining() |
number \| nil |
Unprotected |
The radial overlay fraction, 0..1: how much of the buff is left. |
buff:number() |
number \| nil |
Unprotected |
The integer badge drawn on the icon. |
buff:widget() |
Widget \| nil |
Unprotected |
The widget that draws it: the crossing back into the tree. |
buff:exists() |
boolean |
Unprotected |
Whether the buff is still on the bar. Always answers. |
buff:info() |
Buff \| nil |
Unprotected |
A plain-table snapshot, for logging and serialising. |
| Rule |
Detail |
| Content-defined meters |
amount, remaining and number are published by the buff’s resource and often absent. remaining is a 0..1 fraction of the whole run (0.25 is a quarter left). The client has no seconds-based buff timer. |
| A removed buff keeps answering |
:exists() is false while :res(), :name() and the meters read the values it had, so a BuffRemoved payload or a stashed buff still reads. :exists() is the predicate :list() filters on. |
| Events |
BuffAdded, BuffRemoved, BuffChanged. Each payload is the Buff object. The buffs a character already has arrive as a burst of BuffAdded shortly after it enters the world. |
hafen.event():on("BuffRemoved", function(buff)
hafen.log():write((buff:name() or buff:res()) .. " wore off") -- readable; :exists() is false
end)
See Also