This commit is contained in:
@@ -4,25 +4,33 @@ import { getBestTokenDocumentForActor } from "../utils/token-utils.js";
|
||||
|
||||
export function registerDnd5eDamageTrigger() {
|
||||
Hooks.on("dnd5e.applyDamage", async (actor, amount, options = {}) => {
|
||||
if (!game.user.isGM) return;
|
||||
if (!actor) return;
|
||||
await handleDamageReceivedHook(actor, amount, options);
|
||||
});
|
||||
|
||||
const hookOptions = normalizeDamageHookOptions(options);
|
||||
const tokenDocument = resolveDamageTokenDocument(actor, hookOptions);
|
||||
const damageTypes = extractDamageTypes(hookOptions);
|
||||
const numericAmount = Number(amount) || 0;
|
||||
Hooks.on("dnd5e.damageActor", async (actor, changes = {}, update = {}, userId = null) => {
|
||||
const amount = normalizeDamageActorAmount(changes, update);
|
||||
await handleDamageReceivedHook(actor, amount, { changes, update, userId });
|
||||
});
|
||||
}
|
||||
|
||||
await handleTrigger(TRIGGER_TYPES.DAMAGE_RECEIVED, {
|
||||
actor: tokenDocument?.actor ?? actor,
|
||||
targetActor: tokenDocument?.actor ?? actor,
|
||||
tokenDocument,
|
||||
targetTokenDocument: tokenDocument,
|
||||
targetToken: tokenDocument?.object ?? null,
|
||||
amount: numericAmount,
|
||||
damageAmount: numericAmount,
|
||||
damageTypes,
|
||||
options: hookOptions
|
||||
});
|
||||
async function handleDamageReceivedHook(actor, amount, options = {}) {
|
||||
if (!game.user.isGM || !actor) return;
|
||||
|
||||
const hookOptions = normalizeDamageHookOptions(options);
|
||||
const tokenDocument = resolveDamageTokenDocument(actor, hookOptions);
|
||||
const targetActor = tokenDocument?.actor ?? actor;
|
||||
const numericAmount = Number(amount) || 0;
|
||||
|
||||
await handleTrigger(TRIGGER_TYPES.DAMAGE_RECEIVED, {
|
||||
actor: targetActor,
|
||||
targetActor,
|
||||
tokenDocument,
|
||||
targetTokenDocument: tokenDocument,
|
||||
targetToken: tokenDocument?.object ?? null,
|
||||
amount: numericAmount,
|
||||
damageAmount: numericAmount,
|
||||
damageTypes: extractDamageTypes(hookOptions),
|
||||
options: hookOptions
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,16 +38,28 @@ function normalizeDamageHookOptions(options) {
|
||||
return options && typeof options === "object" ? options : {};
|
||||
}
|
||||
|
||||
function normalizeDamageActorAmount(changes, update) {
|
||||
const candidates = [changes?.total, changes?.amount, changes?.value, update?.total, update?.amount, update?.value];
|
||||
const value = candidates.find(candidate => Number.isFinite(Number(candidate)));
|
||||
return Number(value) || 0;
|
||||
}
|
||||
|
||||
function resolveDamageTokenDocument(actor, options) {
|
||||
return options.tokenDocument ??
|
||||
options.token?.document ??
|
||||
options.token ??
|
||||
options.targetTokenDocument ??
|
||||
options.targetToken?.document ??
|
||||
actor.token ??
|
||||
return asTokenDocument(options.tokenDocument) ??
|
||||
asTokenDocument(options.token) ??
|
||||
asTokenDocument(options.targetTokenDocument) ??
|
||||
asTokenDocument(options.targetToken) ??
|
||||
asTokenDocument(actor.token) ??
|
||||
getBestTokenDocumentForActor(actor);
|
||||
}
|
||||
|
||||
function asTokenDocument(value) {
|
||||
if (!value) return null;
|
||||
if (value.documentName === "Token") return value;
|
||||
if (value.document?.documentName === "Token") return value.document;
|
||||
return null;
|
||||
}
|
||||
|
||||
function extractDamageTypes(options) {
|
||||
const knownTypes = getKnownDamageTypes();
|
||||
const collected = new Set();
|
||||
@@ -55,8 +75,7 @@ function collectDamageTypes(value, knownTypes, collected, seen = new WeakSet(),
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof value !== "object") return;
|
||||
if (seen.has(value)) return;
|
||||
if (typeof value !== "object" || seen.has(value)) return;
|
||||
seen.add(value);
|
||||
|
||||
if (Array.isArray(value) || value instanceof Set) {
|
||||
@@ -69,7 +88,7 @@ function collectDamageTypes(value, knownTypes, collected, seen = new WeakSet(),
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key of ["type", "damageType", "damageTypeId", "types", "damageTypes", "damage", "damages", "damageDetail", "parts"]) {
|
||||
for (const key of ["type", "damageType", "damageTypeId", "types", "damageTypes", "damage", "damages", "damageDetail", "parts", "workflow"]) {
|
||||
collectDamageTypes(value[key], knownTypes, collected, seen, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user