mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-18 07:59:03 +01:00
Update Beastform action
This commit is contained in:
parent
9d9c636dbc
commit
cf55659097
15 changed files with 324 additions and 132 deletions
|
|
@ -4,10 +4,6 @@ import { ActionMixin } from '../fields/actionField.mjs';
|
|||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
/*
|
||||
!!! I'm currently refactoring the whole Action thing, it's a WIP !!!
|
||||
*/
|
||||
|
||||
/*
|
||||
ToDo
|
||||
- Target Check / Target Picker
|
||||
|
|
@ -19,6 +15,7 @@ const fields = foundry.data.fields;
|
|||
export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel) {
|
||||
static extraSchemas = ['cost', 'uses', 'range'];
|
||||
|
||||
/** @inheritDoc */
|
||||
static defineSchema() {
|
||||
const schemaFields = {
|
||||
_id: new fields.DocumentIdField({ initial: () => foundry.utils.randomID() }),
|
||||
|
|
@ -36,23 +33,33 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
};
|
||||
|
||||
this.extraSchemas.forEach(s => {
|
||||
let clsField;
|
||||
if ((clsField = this.getActionField(s)))
|
||||
let clsField = this.getActionField(s);
|
||||
if (clsField)
|
||||
schemaFields[s] = new clsField();
|
||||
});
|
||||
|
||||
return schemaFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Map containing each Action step based on fields define in schema. Ordered by Fields order property.
|
||||
* @returns {Map}
|
||||
*/
|
||||
defineWorkflow() {
|
||||
const workflow = new Map();
|
||||
Object.entries(this.schema.fields).forEach(([k,s]) => {
|
||||
if(s.execute) workflow.set(k, { order: s.order, execute: s.execute.bind(this) } );
|
||||
this.constructor.extraSchemas.forEach(s => {
|
||||
let clsField = this.constructor.getActionField(s);
|
||||
if (clsField?.execute) {
|
||||
workflow.set(s, { order: clsField.order, execute: clsField.execute.bind(this) } );
|
||||
if( s === "damage" ) workflow.set("applyDamage", { order: 75, execute: clsField.applyDamage.bind(this) } );
|
||||
}
|
||||
});
|
||||
if(this.schema.fields.damage) workflow.set("applyDamage", { order: 75, execute: game.system.api.fields.ActionFields.DamageField.applyDamage.bind(this) } );
|
||||
return new Map([...workflow.entries()].sort(([aKey, aValue], [bKey, bValue]) => aValue.order - bValue.order));
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter returning the workflow property or creating it the first time the property is called
|
||||
*/
|
||||
get workflow() {
|
||||
if ( this.hasOwnProperty("_workflow") ) return this._workflow;
|
||||
const workflow = Object.freeze(this.defineWorkflow());
|
||||
|
|
@ -60,24 +67,39 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return workflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Field class from ActionFields global config
|
||||
* @param {string} name Field short name, equal to Action property
|
||||
* @returns Action Field
|
||||
*/
|
||||
static getActionField(name) {
|
||||
const field = game.system.api.fields.ActionFields[`${name.capitalize()}Field`];
|
||||
return fields.DataField.isPrototypeOf(field) && field;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
prepareData() {
|
||||
this.name = this.name || game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[this.type].name);
|
||||
this.img = this.img ?? this.parent?.parent?.img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Action ID
|
||||
*/
|
||||
get id() {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Item the action is attached too.
|
||||
*/
|
||||
get item() {
|
||||
return this.parent.parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first Actor parent found.
|
||||
*/
|
||||
get actor() {
|
||||
return this.item instanceof DhpActor
|
||||
? this.item
|
||||
|
|
@ -90,6 +112,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return 'trait';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare base data based on Action Type & Parent Type
|
||||
* @param {object} parent
|
||||
* @returns {object}
|
||||
*/
|
||||
static getSourceConfig(parent) {
|
||||
const updateSource = {};
|
||||
if (parent?.parent?.type === 'weapon' && this === game.system.api.models.actions.actionsTypes.attack) {
|
||||
|
|
@ -112,6 +139,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return updateSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a data object used to evaluate any dice rolls associated with this particular Action
|
||||
* @param {object} [data ={}] Optional data object from previous configuration/rolls
|
||||
* @returns {object}
|
||||
*/
|
||||
getRollData(data = {}) {
|
||||
if (!this.actor) return null;
|
||||
const actorData = this.actor.getRollData(false);
|
||||
|
|
@ -127,6 +159,10 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return actorData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute each part of the Action workflow in order, calling a specific event before and after each part.
|
||||
* @param {object} config Config object usually created from prepareConfig method
|
||||
*/
|
||||
async executeWorkflow(config) {
|
||||
for(const [key, part] of this.workflow) {
|
||||
if (Hooks.call(`${CONFIG.DH.id}.pre${key.capitalize()}Action`, this, config) === false) return;
|
||||
|
|
@ -135,7 +171,12 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
}
|
||||
}
|
||||
|
||||
async use(event, options = {}) {
|
||||
/**
|
||||
* Main method to use the Action
|
||||
* @param {Event} event Event from the button used to trigger the Action
|
||||
* @returns {object}
|
||||
*/
|
||||
async use(event) {
|
||||
if (!this.actor) throw new Error("An Action can't be used outside of an Actor context.");
|
||||
|
||||
if (this.chatDisplay) await this.toChat();
|
||||
|
|
@ -159,7 +200,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return config;
|
||||
}
|
||||
|
||||
/* */
|
||||
/**
|
||||
* Create the basic config common to every action type
|
||||
* @param {Event} event Event from the button used to trigger the Action
|
||||
* @returns {object}
|
||||
*/
|
||||
prepareBaseConfig(event) {
|
||||
const config = {
|
||||
event,
|
||||
|
|
@ -174,7 +219,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
hasRoll: this.hasRoll,
|
||||
hasDamage: this.hasDamage,
|
||||
hasHealing: this.hasHealing,
|
||||
hasEffect: !!this.effects?.length,
|
||||
hasEffect: this.hasEffect,
|
||||
hasSave: this.hasSave,
|
||||
isDirect: !!this.damage?.direct,
|
||||
selectedRollMode: game.settings.get('core', 'rollMode'),
|
||||
|
|
@ -185,6 +230,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the config for that action used for its workflow
|
||||
* @param {Event} event Event from the button used to trigger the Action
|
||||
* @returns {object}
|
||||
*/
|
||||
prepareConfig(event) {
|
||||
const config = this.prepareBaseConfig(event);
|
||||
for(const clsField of Object.values(this.schema.fields)) {
|
||||
|
|
@ -194,10 +244,20 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to know if a configuration dialog must be shown or not when there is no roll.
|
||||
* @param {*} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
requireConfigurationDialog(config) {
|
||||
return !config.event.shiftKey && !config.hasRoll && (config.costs?.length || config.uses);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
* @param {boolean} successCost
|
||||
*/
|
||||
async consume(config, successCost = false) {
|
||||
await this.workflow.get("cost")?.execute(config, successCost);
|
||||
await this.workflow.get("uses")?.execute(config, successCost);
|
||||
|
|
@ -209,12 +269,16 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if a configuration dialog must be shown or not if a special keyboard key is pressed.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
*/
|
||||
static applyKeybindings(config) {
|
||||
config.dialog.configure ??= !(config.event.shiftKey || config.event.altKey || config.event.ctrlKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getters to know which parts the action of composed of. A field can exist but configured to not be used.
|
||||
* Getters to know which parts the action is composed of. A field can exist but configured to not be used.
|
||||
* @returns {boolean} If that part is in the action.
|
||||
*/
|
||||
|
||||
|
|
@ -229,10 +293,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
get hasHealing() {
|
||||
return this.damage?.parts?.length && this.type === 'healing'
|
||||
}
|
||||
|
||||
get hasDamagePart() {
|
||||
return this.damage?.parts?.length;
|
||||
}
|
||||
|
||||
get hasSave() {
|
||||
return !!this.save?.trait;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import BeastformDialog from '../../applications/dialogs/beastformDialog.mjs';
|
||||
import DHBaseAction from './baseAction.mjs';
|
||||
|
||||
export default class DhBeastformAction extends DHBaseAction {
|
||||
static extraSchemas = [...super.extraSchemas, 'beastform'];
|
||||
|
||||
async use(event, options) {
|
||||
/* async use(event, options) {
|
||||
const beastformConfig = this.prepareBeastformConfig();
|
||||
|
||||
const abort = await this.handleActiveTransformations();
|
||||
|
|
@ -82,5 +81,5 @@ export default class DhBeastformAction extends DHBaseAction {
|
|||
beastformEffects.map(x => x.id)
|
||||
);
|
||||
return existingEffects;
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
import BeastformDialog from "../../../applications/dialogs/beastformDialog.mjs";
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
export default class BeastformField extends fields.SchemaField {
|
||||
/**
|
||||
* Action Workflow order
|
||||
*/
|
||||
static order = 90;
|
||||
|
||||
constructor(options = {}, context = {}) {
|
||||
const beastformFields = {
|
||||
tierAccess: new fields.SchemaField({
|
||||
|
|
@ -27,4 +34,96 @@ export default class BeastformField extends fields.SchemaField {
|
|||
};
|
||||
super(beastformFields, options, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Beastform Transformation 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.
|
||||
*/
|
||||
static async execute(config) {
|
||||
// Should not be useful anymore here
|
||||
await BeastformField.handleActiveTransformations.call(this);
|
||||
|
||||
const { selected, evolved, hybrid } = await BeastformDialog.configure(config, this.item);
|
||||
if (!selected) return false;
|
||||
|
||||
return await BeastformField.transform.call(this, selected, evolved, hybrid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Action Workflow config object.
|
||||
* Must be called within Action context.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
*/
|
||||
prepareConfig(config) {
|
||||
if(this.actor.effects.find(x => x.type === 'beastform')) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.beastformAlreadyApplied'));
|
||||
return false;
|
||||
}
|
||||
|
||||
const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers;
|
||||
const actorLevel = this.actor.system.levelData.level.current;
|
||||
const actorTier =
|
||||
Object.values(settingsTiers).find(
|
||||
tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end
|
||||
) ?? 1;
|
||||
|
||||
config.tierLimit = this.beastform.tierAccess.exact ?? actorTier;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO by Harry
|
||||
* @param {*} selectedForm
|
||||
* @param {*} evolvedData
|
||||
* @param {*} hybridData
|
||||
* @returns
|
||||
*/
|
||||
static async transform(selectedForm, evolvedData, hybridData) {
|
||||
const formData = evolvedData?.form ? evolvedData.form.toObject() : selectedForm.toObject();
|
||||
const beastformEffect = formData.effects.find(x => x.type === 'beastform');
|
||||
if (!beastformEffect) {
|
||||
ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (evolvedData?.form) {
|
||||
const evolvedForm = selectedForm.effects.find(x => x.type === 'beastform');
|
||||
if (!evolvedForm) {
|
||||
ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect');
|
||||
return false;
|
||||
}
|
||||
|
||||
beastformEffect.changes = [...beastformEffect.changes, ...evolvedForm.changes];
|
||||
formData.system.features = [...formData.system.features, ...selectedForm.system.features.map(x => x.uuid)];
|
||||
}
|
||||
|
||||
if (selectedForm.system.beastformType === CONFIG.DH.ITEM.beastformTypes.hybrid.id) {
|
||||
formData.system.advantageOn = Object.values(hybridData.advantages).reduce((advantages, formCategory) => {
|
||||
Object.keys(formCategory).forEach(advantageKey => {
|
||||
advantages[advantageKey] = formCategory[advantageKey];
|
||||
});
|
||||
return advantages;
|
||||
}, {});
|
||||
formData.system.features = [
|
||||
...formData.system.features,
|
||||
...Object.values(hybridData.features).flatMap(x => Object.keys(x))
|
||||
];
|
||||
}
|
||||
|
||||
this.actor.createEmbeddedDocuments('Item', [formData]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove existing beastform effect and return true if there was one
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static async handleActiveTransformations() {
|
||||
const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform');
|
||||
const existingEffects = beastformEffects.length > 0;
|
||||
await this.actor.deleteEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
beastformEffects.map(x => x.id)
|
||||
);
|
||||
return existingEffects;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ export default class CostField extends fields.ArrayField {
|
|||
/**
|
||||
* Action Workflow order
|
||||
*/
|
||||
order = 150;
|
||||
static order = 150;
|
||||
|
||||
/** @inheritDoc */
|
||||
constructor(options = {}, context = {}) {
|
||||
|
|
@ -29,11 +29,11 @@ export default class CostField extends fields.ArrayField {
|
|||
/**
|
||||
* Cost Consumption Action Workflow part.
|
||||
* Consume configured action resources.
|
||||
* Must be called within Action context.
|
||||
* Must be called within Action context or similar.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
* @param {boolean} [successCost=false] Consume only resources configured as "On Success only" if not already consumed.
|
||||
*/
|
||||
async execute(config, successCost = false) {
|
||||
static async execute(config, successCost = false) {
|
||||
const actor= this.actor.system.partner ?? this.actor,
|
||||
usefulResources = {
|
||||
...foundry.utils.deepClone(actor.system.resources),
|
||||
|
|
@ -44,13 +44,15 @@ export default class CostField extends fields.ArrayField {
|
|||
}
|
||||
};
|
||||
|
||||
for (var cost of config.costs) {
|
||||
if (cost.keyIsID) {
|
||||
usefulResources[cost.key] = {
|
||||
value: cost.value,
|
||||
target: this.parent.parent,
|
||||
keyIsID: true
|
||||
};
|
||||
if(this.parent?.parent) {
|
||||
for (var cost of config.costs) {
|
||||
if (cost.keyIsID) {
|
||||
usefulResources[cost.key] = {
|
||||
value: cost.value,
|
||||
target: this.parent.parent,
|
||||
keyIsID: true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +80,7 @@ export default class CostField extends fields.ArrayField {
|
|||
|
||||
/**
|
||||
* Update Action Workflow config object.
|
||||
* Must be called within Action context.
|
||||
* Must be called within Action context or similar.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
* @returns {boolean} Return false if fast-forwarded and no more uses.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export default class DamageField extends fields.SchemaField {
|
|||
/**
|
||||
* Action Workflow order
|
||||
*/
|
||||
order = 20;
|
||||
static order = 20;
|
||||
|
||||
/** @inheritDoc */
|
||||
constructor(options, context = {}) {
|
||||
|
|
@ -24,12 +24,12 @@ export default class DamageField extends fields.SchemaField {
|
|||
|
||||
/**
|
||||
* Roll Damage/Healing Action Workflow part.
|
||||
* Must be called within Action context.
|
||||
* Must be called within Action context or similar.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
* @param {string} [messageId=null] ChatMessage Id where the clicked button belong.
|
||||
* @param {boolean} [force=false] If the method should be executed outside of Action workflow, for ChatMessage button for example.
|
||||
*/
|
||||
async execute(config, messageId = null, force = false) {
|
||||
static async execute(config, messageId = null, force = false) {
|
||||
if((this.hasRoll && DamageField.getAutomation() === CONFIG.DH.SETTINGS.actionAutomationChoices.never.id) && !force) return;
|
||||
|
||||
let formulas = this.damage.parts.map(p => ({
|
||||
|
|
@ -97,11 +97,11 @@ export default class DamageField extends fields.SchemaField {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Must be called within Action context.
|
||||
* @param {*} part
|
||||
* @param {*} data
|
||||
* @returns
|
||||
* Return value or valueAlt from damage part
|
||||
* Must be called within Action context or similar.
|
||||
* @param {object} part Damage Part
|
||||
* @param {object} data Action getRollData
|
||||
* @returns Formula value object
|
||||
*/
|
||||
static getFormulaValue(part, data) {
|
||||
let formulaValue = part.value;
|
||||
|
|
@ -118,10 +118,10 @@ export default class DamageField extends fields.SchemaField {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Must be called within Action context.
|
||||
* @param {*} formulas
|
||||
* @param {*} systemData
|
||||
* Prepare formulas for Damage Roll
|
||||
* Must be called within Action context or similar.
|
||||
* @param {object[]} formulas Array of formatted formulas object
|
||||
* @param {object} data Action getRollData
|
||||
* @returns
|
||||
*/
|
||||
static formatFormulas(formulas, data) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ export default class EffectsField extends fields.ArrayField {
|
|||
/**
|
||||
* Action Workflow order
|
||||
*/
|
||||
order = 100;
|
||||
static order = 100;
|
||||
|
||||
/** @inheritDoc */
|
||||
constructor(options = {}, context = {}) {
|
||||
|
|
@ -17,12 +17,12 @@ export default class EffectsField extends fields.ArrayField {
|
|||
|
||||
/**
|
||||
* Apply Effects Action Workflow part.
|
||||
* Must be called within Action context.
|
||||
* 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.
|
||||
*/
|
||||
async execute(config, targets = null, force = false) {
|
||||
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) {
|
||||
|
|
@ -37,10 +37,9 @@ export default class EffectsField extends fields.ArrayField {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Must be called within Action context.
|
||||
* @param {*} targets
|
||||
* @returns
|
||||
* 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;
|
||||
|
|
@ -59,10 +58,9 @@ export default class EffectsField extends fields.ArrayField {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} effect
|
||||
* @param {*} actor
|
||||
* @returns
|
||||
* 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);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
const fields = foundry.data.fields;
|
||||
|
||||
export default class MacroField extends fields.DocumentUUIDField {
|
||||
order = 70;
|
||||
/**
|
||||
* Action Workflow order
|
||||
*/
|
||||
static order = 70;
|
||||
|
||||
/** @inheritDoc */
|
||||
constructor(context = {}) {
|
||||
|
|
@ -10,9 +13,10 @@ export default class MacroField extends fields.DocumentUUIDField {
|
|||
|
||||
/**
|
||||
* Macro Action Workflow part.
|
||||
* Must be called within Action context or similar or similar.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods. Currently not used.
|
||||
*/
|
||||
async execute(config) {
|
||||
static async execute(config) {
|
||||
const fixUUID = !this.macro.includes('Macro.') ? `Macro.${this.macro}` : this.macro,
|
||||
macro = await fromUuid(fixUUID);
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,10 @@ export class DHActionRollData extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
export default class RollField extends fields.EmbeddedDataField {
|
||||
order = 10;
|
||||
/**
|
||||
* Action Workflow order
|
||||
*/
|
||||
static order = 10;
|
||||
|
||||
/** @inheritDoc */
|
||||
constructor(options, context = {}) {
|
||||
|
|
@ -119,10 +122,10 @@ export default class RollField extends fields.EmbeddedDataField {
|
|||
|
||||
/**
|
||||
* Roll Action Workflow part.
|
||||
* Must be called within Action context.
|
||||
* Must be called within Action context or similar.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
*/
|
||||
async execute(config) {
|
||||
static async execute(config) {
|
||||
if(!config.hasRoll) return;
|
||||
config = await this.actor.diceRoll(config);
|
||||
if(!config) return false;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export default class SaveField extends fields.SchemaField {
|
|||
/**
|
||||
* Action Workflow order
|
||||
*/
|
||||
order = 50;
|
||||
static order = 50;
|
||||
|
||||
/** @inheritDoc */
|
||||
constructor(options = {}, context = {}) {
|
||||
|
|
@ -27,12 +27,12 @@ export default class SaveField extends fields.SchemaField {
|
|||
|
||||
/**
|
||||
* Reaction Roll Action Workflow part.
|
||||
* Must be called within Action context.
|
||||
* 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.
|
||||
*/
|
||||
async execute(config, targets = null, force = false) {
|
||||
static async execute(config, targets = null, force = false) {
|
||||
if(!config.hasSave) return;
|
||||
let message = config.message ?? ui.chat.collection.get(config.parent?._id);
|
||||
if(!message) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export default class UsesField extends fields.SchemaField {
|
|||
/**
|
||||
* Action Workflow order
|
||||
*/
|
||||
order = 160;
|
||||
static order = 160;
|
||||
|
||||
/** @inheritDoc */
|
||||
constructor(options = {}, context = {}) {
|
||||
|
|
@ -29,11 +29,11 @@ export default class UsesField extends fields.SchemaField {
|
|||
/**
|
||||
* Uses Consumption Action Workflow part.
|
||||
* Increment Action spent uses by 1.
|
||||
* Must be called within Action context.
|
||||
* Must be called within Action context or similar or similar.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
* @param {boolean} [successCost=false] Consume only resources configured as "On Success only" if not already consumed.
|
||||
*/
|
||||
async execute(config, successCost = false) {
|
||||
static async execute(config, successCost = false) {
|
||||
if (
|
||||
config.uses?.enabled &&
|
||||
((!successCost && (!config.uses?.consumeOnSuccess || config.roll?.success)) ||
|
||||
|
|
@ -60,9 +60,9 @@ export default class UsesField extends fields.SchemaField {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Prepare Uses object for Action Workflow
|
||||
* Must be called within Action context.
|
||||
* @param {*} uses
|
||||
* @param {object} uses
|
||||
* @returns {object}
|
||||
*/
|
||||
static calcUses(uses) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue