[Feature] 1541 - Trigger Improvements (#1542)

* Improved registration and unregistration of triggers

* Added logging

* Fixed Feature level unregistration

* Fixed action deletion unregistration

* SceneEnvironment stub

* Update module/data/registeredTriggers.mjs

Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com>

---------

Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com>
This commit is contained in:
WBHarry 2026-01-16 07:43:25 +01:00 committed by GitHub
parent 4cd6fe58da
commit fad09a1b3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 226 additions and 66 deletions

View file

@ -78,6 +78,7 @@ CONFIG.ux.ContextMenu = applications.ux.DHContextMenu;
CONFIG.ux.TooltipManager = documents.DhTooltipManager;
CONFIG.ux.TemplateManager = new TemplateManager();
CONFIG.ux.TokenManager = new TokenManager();
CONFIG.debug.triggers = false;
Hooks.once('init', () => {
game.system.api = {
@ -89,7 +90,7 @@ Hooks.once('init', () => {
fields
};
game.system.registeredTriggers = new RegisteredTriggers();
game.system.registeredTriggers = new game.system.api.data.RegisteredTriggers();
const { DocumentSheetConfig } = foundry.applications.apps;
DocumentSheetConfig.unregisterSheet(TokenDocument, 'core', foundry.applications.sheets.TokenConfig);
@ -389,49 +390,12 @@ Hooks.on('refreshToken', (_, options) => {
Hooks.on('renderCompendiumDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html));
Hooks.on('renderDocumentDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html));
class RegisteredTriggers extends Map {
constructor() {
super();
}
/* Non actor-linked Actors should unregister the triggers of their tokens if a scene's token layer is torn down */
Hooks.on('canvasTearDown', canvas => {
game.system.registeredTriggers.unregisterSceneTriggers(canvas.scene);
});
async registerTriggers(trigger, actor, triggeringActorType, uuid, commands) {
const existingTrigger = this.get(trigger);
if (!existingTrigger) this.set(trigger, new Map());
this.get(trigger).set(uuid, { actor, triggeringActorType, commands });
}
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) {
for (let { actor, triggeringActorType, commands } of dualityTrigger.values()) {
const triggerData = CONFIG.DH.TRIGGER.triggers[trigger];
if (triggerData.usesActor && triggeringActorType !== 'any') {
if (triggeringActorType === 'self' && currentActor?.uuid !== actor) continue;
else if (triggeringActorType === 'other' && currentActor?.uuid === actor) continue;
}
for (let command of commands) {
try {
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;
}
}
/* Non actor-linked Actors should register the triggers of their tokens on a readied scene */
Hooks.on('canvasReady', canas => {
game.system.registeredTriggers.registerSceneTriggers(canvas.scene);
});