mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
Fixed Feature level unregistration
This commit is contained in:
parent
6f4ed1d6d9
commit
0b2241076c
5 changed files with 164 additions and 152 deletions
149
daggerheart.mjs
149
daggerheart.mjs
|
|
@ -90,7 +90,7 @@ Hooks.once('init', () => {
|
||||||
fields
|
fields
|
||||||
};
|
};
|
||||||
|
|
||||||
game.system.registeredTriggers = new RegisteredTriggers();
|
game.system.registeredTriggers = new game.system.api.data.RegisteredTriggers();
|
||||||
|
|
||||||
const { DocumentSheetConfig } = foundry.applications.apps;
|
const { DocumentSheetConfig } = foundry.applications.apps;
|
||||||
DocumentSheetConfig.unregisterSheet(TokenDocument, 'core', foundry.applications.sheets.TokenConfig);
|
DocumentSheetConfig.unregisterSheet(TokenDocument, 'core', foundry.applications.sheets.TokenConfig);
|
||||||
|
|
@ -395,152 +395,7 @@ Hooks.on('canvasTearDown', canvas => {
|
||||||
game.system.registeredTriggers.unregisterSceneTriggers(canvas.scene);
|
game.system.registeredTriggers.unregisterSceneTriggers(canvas.scene);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Non actor-linked Actors should register the triggers of their tokens on a readied scene */
|
||||||
Hooks.on('canvasReady', canas => {
|
Hooks.on('canvasReady', canas => {
|
||||||
game.system.registeredTriggers.registerSceneTriggers(canvas.scene);
|
game.system.registeredTriggers.registerSceneTriggers(canvas.scene);
|
||||||
});
|
});
|
||||||
|
|
||||||
class RegisteredTriggers extends Map {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
registerTriggers(triggers, actor, uuid) {
|
|
||||||
for (const triggerKey of Object.keys(CONFIG.DH.TRIGGER.triggers)) {
|
|
||||||
const match = triggers[triggerKey];
|
|
||||||
const existingTrigger = this.get(triggerKey);
|
|
||||||
|
|
||||||
if (!match) {
|
|
||||||
if (existingTrigger?.get(uuid)) this.get(triggerKey).delete(uuid);
|
|
||||||
} else {
|
|
||||||
const { trigger, triggeringActorType, commands } = match;
|
|
||||||
|
|
||||||
if (!existingTrigger) this.set(trigger, new Map());
|
|
||||||
this.get(trigger).set(uuid, { actor, triggeringActorType, commands });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
registerItemTriggers(item) {
|
|
||||||
for (const action of item.system.actions ?? []) {
|
|
||||||
if (!action.actor) continue;
|
|
||||||
|
|
||||||
/* Non actor-linked should only prep synthetic actors so they're not registering triggers unless they're on the canvas */
|
|
||||||
if (
|
|
||||||
!action.actor.prototypeToken.actorLink &&
|
|
||||||
(!(action.actor.parent instanceof game.system.api.documents.DhToken) || !action.actor.parent?.uuid)
|
|
||||||
)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const triggers = {};
|
|
||||||
for (const trigger of action.triggers) {
|
|
||||||
const { args } = CONFIG.DH.TRIGGER.triggers[trigger.trigger];
|
|
||||||
const fn = new foundry.utils.AsyncFunction(...args, `{${trigger.command}\n}`);
|
|
||||||
|
|
||||||
if (!triggers[trigger.trigger])
|
|
||||||
triggers[trigger.trigger] = {
|
|
||||||
trigger: trigger.trigger,
|
|
||||||
triggeringActorType: trigger.triggeringActorType,
|
|
||||||
commands: []
|
|
||||||
};
|
|
||||||
triggers[trigger.trigger].commands.push(fn.bind(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.registerTriggers(triggers, action.actor?.uuid, item.uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unregisterTriggers(triggerKeys, uuid) {
|
|
||||||
for (const triggerKey of triggerKeys) {
|
|
||||||
const existingTrigger = this.get(triggerKey);
|
|
||||||
if (!existingTrigger) return;
|
|
||||||
|
|
||||||
existingTrigger.delete(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unregisterItemTriggers(items) {
|
|
||||||
for (const item of items) {
|
|
||||||
if (!item.system.actions.size) continue;
|
|
||||||
|
|
||||||
const triggers = (item.system.actions ?? []).reduce((acc, action) => {
|
|
||||||
acc.push(...action.triggers.map(x => x.trigger));
|
|
||||||
return acc;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
this.unregisterTriggers(triggers, item.uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unregisterSceneTriggers(scene) {
|
|
||||||
for (const triggerKey of Object.keys(CONFIG.DH.TRIGGER.triggers)) {
|
|
||||||
const existingTrigger = this.get(triggerKey);
|
|
||||||
if (!existingTrigger) continue;
|
|
||||||
const filtered = new Map();
|
|
||||||
for (const [uuid, data] of existingTrigger.entries()) {
|
|
||||||
if (!uuid.startsWith(scene.uuid)) filtered.set(uuid, data);
|
|
||||||
}
|
|
||||||
this.set(triggerKey, filtered);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
registerSceneTriggers(scene) {
|
|
||||||
for (const actor of scene.tokens.filter(x => x.actor).map(x => x.actor)) {
|
|
||||||
if (actor.prototypeToken.actorLink) continue;
|
|
||||||
|
|
||||||
for (const item of actor.items) {
|
|
||||||
this.registerItemTriggers(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async runTrigger(trigger, currentActor, ...args) {
|
|
||||||
const updates = [];
|
|
||||||
const triggerSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).triggers;
|
|
||||||
if (!triggerSettings.enabled) return updates;
|
|
||||||
|
|
||||||
const dualityTrigger = this.get(trigger);
|
|
||||||
if (dualityTrigger) {
|
|
||||||
const tokenBoundActors = ['adversary', 'environment'];
|
|
||||||
const triggerActors = ['character', ...tokenBoundActors];
|
|
||||||
for (let [itemUuid, { actor: actorUuid, triggeringActorType, commands }] of dualityTrigger.entries()) {
|
|
||||||
const actor = await foundry.utils.fromUuid(actorUuid);
|
|
||||||
if (!actor || !triggerActors.includes(actor.type)) continue;
|
|
||||||
if (tokenBoundActors.includes(actor.type) && !actor.getActiveTokens().length) continue;
|
|
||||||
|
|
||||||
const triggerData = CONFIG.DH.TRIGGER.triggers[trigger];
|
|
||||||
if (triggerData.usesActor && triggeringActorType !== 'any') {
|
|
||||||
if (triggeringActorType === 'self' && currentActor?.uuid !== actorUuid) continue;
|
|
||||||
else if (triggeringActorType === 'other' && currentActor?.uuid === actorUuid) continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let command of commands) {
|
|
||||||
try {
|
|
||||||
if (CONFIG.debug.triggers) {
|
|
||||||
const item = await foundry.utils.fromUuid(itemUuid);
|
|
||||||
console.log(
|
|
||||||
game.i18n.format('DAGGERHEART.UI.ConsoleLogs.triggerRun', {
|
|
||||||
actor: actor.name ?? '<Missing Actor>',
|
|
||||||
item: item?.name ?? '<Missing Item>',
|
|
||||||
trigger: game.i18n.localize(triggerData.label)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await command(...args);
|
|
||||||
if (result?.updates?.length) updates.push(...result.updates);
|
|
||||||
} catch (_) {
|
|
||||||
const triggerName = game.i18n.localize(triggerData.label);
|
|
||||||
ui.notifications.error(
|
|
||||||
game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerError', {
|
|
||||||
trigger: triggerName,
|
|
||||||
actor: currentActor?.name
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return updates;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
export { default as DhCombat } from './combat.mjs';
|
export { default as DhCombat } from './combat.mjs';
|
||||||
export { default as DhCombatant } from './combatant.mjs';
|
export { default as DhCombatant } from './combatant.mjs';
|
||||||
export { default as DhTagTeamRoll } from './tagTeamRoll.mjs';
|
export { default as DhTagTeamRoll } from './tagTeamRoll.mjs';
|
||||||
|
export { default as RegisteredTriggers } from './registeredTriggers.mjs';
|
||||||
|
|
||||||
export * as countdowns from './countdowns.mjs';
|
export * as countdowns from './countdowns.mjs';
|
||||||
export * as actions from './action/_module.mjs';
|
export * as actions from './action/_module.mjs';
|
||||||
|
|
|
||||||
145
module/data/registeredTriggers.mjs
Normal file
145
module/data/registeredTriggers.mjs
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
export default class RegisteredTriggers extends Map {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
registerTriggers(triggers, actor, uuid) {
|
||||||
|
for (const triggerKey of Object.keys(CONFIG.DH.TRIGGER.triggers)) {
|
||||||
|
const match = triggers[triggerKey];
|
||||||
|
const existingTrigger = this.get(triggerKey);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
if (existingTrigger?.get(uuid)) this.get(triggerKey).delete(uuid);
|
||||||
|
} else {
|
||||||
|
const { trigger, triggeringActorType, commands } = match;
|
||||||
|
|
||||||
|
if (!existingTrigger) this.set(trigger, new Map());
|
||||||
|
this.get(trigger).set(uuid, { actor, triggeringActorType, commands });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerItemTriggers(item) {
|
||||||
|
for (const action of item.system.actions ?? []) {
|
||||||
|
if (!action.actor) continue;
|
||||||
|
|
||||||
|
/* Non actor-linked should only prep synthetic actors so they're not registering triggers unless they're on the canvas */
|
||||||
|
if (
|
||||||
|
!action.actor.prototypeToken.actorLink &&
|
||||||
|
(!(action.actor.parent instanceof game.system.api.documents.DhToken) || !action.actor.parent?.uuid)
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const triggers = {};
|
||||||
|
for (const trigger of action.triggers) {
|
||||||
|
const { args } = CONFIG.DH.TRIGGER.triggers[trigger.trigger];
|
||||||
|
const fn = new foundry.utils.AsyncFunction(...args, `{${trigger.command}\n}`);
|
||||||
|
|
||||||
|
if (!triggers[trigger.trigger])
|
||||||
|
triggers[trigger.trigger] = {
|
||||||
|
trigger: trigger.trigger,
|
||||||
|
triggeringActorType: trigger.triggeringActorType,
|
||||||
|
commands: []
|
||||||
|
};
|
||||||
|
triggers[trigger.trigger].commands.push(fn.bind(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.registerTriggers(triggers, action.actor?.uuid, item.uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unregisterTriggers(triggerKeys, uuid) {
|
||||||
|
for (const triggerKey of triggerKeys) {
|
||||||
|
const existingTrigger = this.get(triggerKey);
|
||||||
|
if (!existingTrigger) return;
|
||||||
|
|
||||||
|
existingTrigger.delete(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unregisterItemTriggers(items) {
|
||||||
|
for (const item of items) {
|
||||||
|
if (!item.system.actions.size) continue;
|
||||||
|
|
||||||
|
const triggers = (item.system.actions ?? []).reduce((acc, action) => {
|
||||||
|
acc.push(...action.triggers.map(x => x.trigger));
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
this.unregisterTriggers(triggers, item.uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unregisterSceneTriggers(scene) {
|
||||||
|
for (const triggerKey of Object.keys(CONFIG.DH.TRIGGER.triggers)) {
|
||||||
|
const existingTrigger = this.get(triggerKey);
|
||||||
|
if (!existingTrigger) continue;
|
||||||
|
const filtered = new Map();
|
||||||
|
for (const [uuid, data] of existingTrigger.entries()) {
|
||||||
|
if (!uuid.startsWith(scene.uuid)) filtered.set(uuid, data);
|
||||||
|
}
|
||||||
|
this.set(triggerKey, filtered);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSceneTriggers(scene) {
|
||||||
|
for (const actor of scene.tokens.filter(x => x.actor).map(x => x.actor)) {
|
||||||
|
if (actor.prototypeToken.actorLink) continue;
|
||||||
|
|
||||||
|
for (const item of actor.items) {
|
||||||
|
this.registerItemTriggers(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async runTrigger(trigger, currentActor, ...args) {
|
||||||
|
const updates = [];
|
||||||
|
const triggerSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).triggers;
|
||||||
|
if (!triggerSettings.enabled) return updates;
|
||||||
|
|
||||||
|
const dualityTrigger = this.get(trigger);
|
||||||
|
if (dualityTrigger) {
|
||||||
|
const tokenBoundActors = ['adversary', 'environment'];
|
||||||
|
const triggerActors = ['character', ...tokenBoundActors];
|
||||||
|
for (let [itemUuid, { actor: actorUuid, triggeringActorType, commands }] of dualityTrigger.entries()) {
|
||||||
|
const actor = await foundry.utils.fromUuid(actorUuid);
|
||||||
|
if (!actor || !triggerActors.includes(actor.type)) continue;
|
||||||
|
if (tokenBoundActors.includes(actor.type) && !actor.getActiveTokens().length) continue;
|
||||||
|
|
||||||
|
const triggerData = CONFIG.DH.TRIGGER.triggers[trigger];
|
||||||
|
if (triggerData.usesActor && triggeringActorType !== 'any') {
|
||||||
|
if (triggeringActorType === 'self' && currentActor?.uuid !== actorUuid) continue;
|
||||||
|
else if (triggeringActorType === 'other' && currentActor?.uuid === actorUuid) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let command of commands) {
|
||||||
|
try {
|
||||||
|
if (CONFIG.debug.triggers) {
|
||||||
|
const item = await foundry.utils.fromUuid(itemUuid);
|
||||||
|
console.log(
|
||||||
|
game.i18n.format('DAGGERHEART.UI.ConsoleLogs.triggerRun', {
|
||||||
|
actor: actor.name ?? '<Missing Actor>',
|
||||||
|
item: item?.name ?? '<Missing Item>',
|
||||||
|
trigger: game.i18n.localize(triggerData.label)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await command(...args);
|
||||||
|
if (result?.updates?.length) updates.push(...result.updates);
|
||||||
|
} catch (_) {
|
||||||
|
const triggerName = game.i18n.localize(triggerData.label);
|
||||||
|
ui.notifications.error(
|
||||||
|
game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerError', {
|
||||||
|
trigger: triggerName,
|
||||||
|
actor: currentActor?.name
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -105,7 +105,13 @@ export default class DhpActor extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _preDelete() {
|
async _preDelete() {
|
||||||
game.system.registeredTriggers.unregisterItemTriggers(this.items);
|
if (this.prototypeToken.actorLink) {
|
||||||
|
game.system.registeredTriggers.unregisterItemTriggers(this.items);
|
||||||
|
} else {
|
||||||
|
for (const token of this.getActiveTokens()) {
|
||||||
|
game.system.registeredTriggers.unregisterItemTriggers(token.actor.items);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDelete(options, userId) {
|
_onDelete(options, userId) {
|
||||||
|
|
|
||||||
|
|
@ -213,10 +213,15 @@ export default class DHItem extends foundry.documents.Item {
|
||||||
const actions = Array.from(this.system.actions ?? []);
|
const actions = Array.from(this.system.actions ?? []);
|
||||||
if (!actions.length) return;
|
if (!actions.length) return;
|
||||||
|
|
||||||
game.system.registeredTriggers.unregisterTriggers(
|
const triggerKeys = actions.flatMap(action => action.triggers.map(x => x.trigger));
|
||||||
actions.flatMap(action => action.triggers.map(x => x.trigger)),
|
|
||||||
this.uuid
|
game.system.registeredTriggers.unregisterTriggers(triggerKeys, this.uuid);
|
||||||
);
|
|
||||||
|
if (!(this.actor.parent instanceof game.system.api.documents.DhToken)) {
|
||||||
|
for (const token of this.actor.getActiveTokens()) {
|
||||||
|
game.system.registeredTriggers.unregisterTriggers(triggerKeys, `${token.document.uuid}.${this.uuid}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _preDelete() {
|
async _preDelete() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue