mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
100 lines
4 KiB
JavaScript
100 lines
4 KiB
JavaScript
import { emitAsGM, GMUpdateEvent } from '../../../systemRegistration/socket.mjs';
|
|
|
|
const fields = foundry.data.fields;
|
|
|
|
export default class EffectsField extends fields.ArrayField {
|
|
/**
|
|
* Action Workflow order
|
|
*/
|
|
static order = 100;
|
|
|
|
/** @inheritDoc */
|
|
constructor(options = {}, context = {}) {
|
|
const element = new fields.SchemaField({
|
|
_id: new fields.DocumentIdField(),
|
|
onSave: new fields.BooleanField({ initial: false })
|
|
});
|
|
super(element, options, context);
|
|
}
|
|
|
|
/**
|
|
* Apply Effects Action Workflow part.
|
|
* Must be called within Action context or similar.
|
|
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
|
* @param {object[]} [targets=null] Array of targets to override pre-selected ones.
|
|
* @param {boolean} [force=false] If the method should be executed outside of Action workflow, for ChatMessage button for example.
|
|
*/
|
|
static async execute(config, targets = null, force = false) {
|
|
if (!config.hasEffect) return;
|
|
let message = config.message ?? ui.chat.collection.get(config.parent?._id);
|
|
if (!message) {
|
|
const roll = new CONFIG.Dice.daggerheart.DHRoll('');
|
|
roll._evaluated = true;
|
|
message = config.message = await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
|
|
}
|
|
if (EffectsField.getAutomation() || force) {
|
|
targets ??= (message.system?.targets ?? config.targets).filter(t => !config.hasRoll || t.hit);
|
|
await emitAsGM(GMUpdateEvent.UpdateEffect, EffectsField.applyEffects.bind(this), targets, this.uuid);
|
|
// EffectsField.applyEffects.call(this, config.targets.filter(t => !config.hasRoll || t.hit));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply Action Effects to a list of Targets
|
|
* Must be called within Action context or similar.
|
|
* @param {object[]} targets Array of formatted targets
|
|
*/
|
|
static async applyEffects(targets) {
|
|
if (!this.effects?.length || !targets?.length) return;
|
|
let effects = this.effects;
|
|
targets.forEach(async token => {
|
|
if (this.hasSave && token.saved.success === true) effects = this.effects.filter(e => e.onSave === true);
|
|
if (!effects.length) return;
|
|
effects.forEach(async e => {
|
|
const actor = canvas.tokens.get(token.id)?.actor,
|
|
effect = this.item.effects.get(e._id);
|
|
if (!actor || !effect) return;
|
|
await EffectsField.applyEffect(effect, actor);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Apply an Effect to a target or enable it if already on it
|
|
* @param {object} effect Effect object containing ActiveEffect UUID
|
|
* @param {object} actor Actor Document
|
|
*/
|
|
static async applyEffect(effect, actor) {
|
|
const existingEffect = actor.effects.find(e => e.origin === effect.uuid);
|
|
if (existingEffect) {
|
|
return effect.update(
|
|
foundry.utils.mergeObject({
|
|
...effect.constructor.getInitialDuration(),
|
|
disabled: false
|
|
})
|
|
);
|
|
}
|
|
|
|
// Otherwise, create a new effect on the target
|
|
const effectData = foundry.utils.mergeObject({
|
|
...effect.toObject(),
|
|
disabled: false,
|
|
transfer: false,
|
|
origin: effect.uuid
|
|
});
|
|
await ActiveEffect.implementation.create(effectData, { parent: actor });
|
|
}
|
|
|
|
/**
|
|
* Return the automation setting for execute method for current user role
|
|
* @returns {boolean} If execute should be triggered automatically
|
|
*/
|
|
static getAutomation() {
|
|
return (
|
|
(game.user.isGM &&
|
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.effect.gm) ||
|
|
(!game.user.isGM &&
|
|
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.effect.players)
|
|
);
|
|
}
|
|
}
|