Macro Reference
A macro is the body of an async function. It gets four names: swade holds everything that comes from the SWADE action, and fx, sequence() and preview are this module's helpers. No wrapper, import or args lookup is needed. Create a sequence with sequence() and finish with await s.play(). Check values that can be null when a macro is meant for several events, or for actors without a token on the scene.
If you prefer short names, unpack them at the top: const { caster, targets, hit } = swade;.
The editor's Variables and helpers panel lists all of this: search it, click a row to insert it, see which rows your code uses and, after Play, the value each swade.* and t.* field had.
Changed in 0.2.0: the action's data moved into swade. Macros written for 0.1 that use bare names such as caster, targets or hit stop with an error until you add swade. in front. Two bare names don't fail but read something else: target (TokenMove's global, when TokenMove is active) and event (the browser's).
Event and document variables
| Variable | Meaning |
|---|---|
swade.event |
trait, damage, template, effect or consume |
swade.caster |
The acting token on the scene, preferring a selected token of the actor; or null |
swade.targets |
Array of target entries (see below), not raw tokens |
swade.target |
The first target's token, or null |
swade.item, swade.actor |
The item and its actor, or null |
swade.action |
{ key, kind, name } or null. The key is formula for the main trait roll, damage for the main damage roll, the action's ID for additional actions, or the row name (template, effect, consume) |
swade.roll, swade.message |
The SWADE roll and its chat message; null in previews and for events without a roll |
swade.template |
Template information on a template event, otherwise null |
swade.effect |
The created active effect on an effect event, otherwise null |
preview |
True when played from the editor or the assignment window |
Trait results
swade.hit, swade.raise, swade.miss, swade.outcome and swade.margin describe the first target. swade.critfail describes the trait roll itself, with or without targets, and swade.fizzle a failed power activation. Without a trait result, hit, raise and miss are false and outcome and margin are null; this includes powers rolled without a target, so check swade.fizzle for those.
Every entry t in swade.targets has:
| Field | Meaning |
|---|---|
token |
The target's token |
outcome |
hit, raise, miss, critfail, or null |
hit, raise, miss, critfail |
Results for this target; a raise is also a hit, a Critical Failure also a miss |
tn, margin, raises |
Target number, roll total minus target number, number of raises |
adjacent |
The target's and caster's token bounds touch or overlap |
distance |
Center-to-center distance in grid units, or null |
damage |
On damage events: { toughness, margin, shaken, wounds }, or null |
shaken, wounds |
Shortcuts to the damage result on damage events |
Target numbers are the target's Parry for melee attacks and for ranged or thrown attacks against an adjacent target, otherwise 4; Bolt against an adjacent target uses the higher of 4 and Parry. With SWADE Clarity active (and its setting on), Clarity's per-target target numbers take precedence, and targets captured in its roll dialog replace your current targets. See Troubleshooting and Limits before you use these values as rules automation.
swade.attack is { mode, skill, rof }. mode is melee, ranged, thrown, power or null; skill is the SWADE ID of the rolled skill when known. rof is informational: the module does not split a Rate of Fire roll into dice per target.
swade.power, for powers, is { trapping, element, activated, raise }, and null for other items (use swade.power?.element). element is read from English or German words in the trapping, then the item name, or null. swade.power.raise is a raise on the activation roll, which is not the same as a raise against a target (t.raise).
swade.damage, on damage events, is { total, raise }. raise means SWADE's bonus damage die was rolled (in previews: a stand-in). The per-target damage fields are estimates for the animation; nothing is applied.
Template information
swade.template is { document, preset, shape, size, center, origin, end, direction }. document is the RegionDocument. preset is sbt, mbt, lbt, cone, smallCone, stream or custom. size is the circle radius, cone length or line length in grid squares. Points are canvas pixels; direction is in degrees for cones and lines.
The presets are circles of radius 1, 2 and 3 squares, cones 9 and 4 squares long, and a stream 12 squares long and 1 wide. Circles, cones and lines of other sizes keep their full geometry: a custom cone still has its tip (origin), end and direction. Other shapes get the center of their bounds, with origin and end at that center. fx.templateSize() returns { squares, px, diameterPx, widthPx }; use widthPx for a stream's width.
Helpers
| Call | What it does |
|---|---|
fx.missPoint(t, { style = "auto" }) |
Canvas point a miss flies to; styles auto (by margin), past, short, wide. With auto, a near miss lands just outside the target's edge and a clear or wild miss a little further out; a Critical Failure drops short or goes a bit wider. The same within one run |
fx.edgePoint(t, { inset = 0.15 }) |
Point on the target's edge facing the caster, moved inward by inset of its radius |
fx.shake(token, { strength = 8, duration = 400, smoothness = 0.37 }) |
Shakes the token's picture on every screen; it moves at most strength / 2 pixels, duration in ms, lower smoothness moves more often; nothing to await |
fx.nudge(token, { from = caster, distance = 0.25, duration = 300 }) |
Pushes the picture away from from and back on every screen; distance in grid squares; returns a Promise |
fx.shakeScreen({ strength = 6, duration = 400 }) |
Sequencer camera shake; returns the playback Promise |
fx.forEachTarget(fn, { stagger = 0 }) |
Awaits fn(t) for each target in turn; with stagger, starts them stagger ms apart and awaits them all |
fx.templateSize(tpl = swade.template) |
Template sizes, or null |
fx.has(key) |
Whether the key exists in the Sequencer database; does not check file paths |
fx.wait(ms) |
Promise that resolves after ms |
fx.element(item = swade.item) |
Element named by the trapping or item name, or null |
fx.random() |
Seeded random number in [0, 1) |
Helpers that take a target accept either t or t.token. from in fx.nudge can also be a canvas point { x, y }. The random seed is the chat message's ID, so replaying a roll gives the same results; previews use a fresh seed.
sequence() returns a Sequencer Sequence with Sequencer's full API, for example .filter("ColorMatrix", { hue: 180 }), .scaleToObject(1.2) or .waitUntilFinished(-250). await s.play() does not necessarily wait until every effect has finished; use section waits when the timing matters.
API for Foundry script macros
const trappings = game.modules.get("swade-trappings").api;
await trappings.openLibrary();
await trappings.openAssignments(item);
Also available:
openLibrary(entryId): opens the library at an entry; returns a Promise for the window.library(): the current library data, for reading.assign(item, actionKey, macroId): assigns a macro to an item action; you need permission to update the item.pickAsset(options): opens the asset picker; resolves to the chosen key, or null when closed.runEntry(id, partialContext): plays a saved entry with the context you pass. Provide whatever its code needs, at least the caster and targets;targetshere is an array of tokens, not target entries, and defaults to empty. The macro reads these fields underswade(swade.caster,swade.targets…). This only plays the animation; it rolls nothing and triggers no SWADE action.
await trappings.runEntry("YOUR_ENTRY_ID", {
caster: canvas.tokens.controlled[0],
targets: [...game.user.targets],
item
});