mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 07:36:26 +01:00
Action Worflow #1
This commit is contained in:
parent
b3c0344b91
commit
180c4d2a53
6 changed files with 164 additions and 34 deletions
|
|
@ -111,8 +111,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
if (game.user.character?.id !== actor.id && !game.user.isGM) return true;
|
||||
if (message.system.source.item && message.system.source.action) {
|
||||
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
|
||||
if (!action || !action?.rollDamage) return;
|
||||
await action.rollDamage(event, message);
|
||||
if (!action || !action?.hasDamagePart) return;
|
||||
await game.system.api.fields.ActionFields.DamageField.execute.call(action, message, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,26 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return actorData;
|
||||
}
|
||||
|
||||
prepareWorkflow(workflow) {
|
||||
for (let i = 0; i < this.constructor.extraSchemas.length; i++) {
|
||||
let clsField = this.constructor.getActionField(this.constructor.extraSchemas[i]);
|
||||
if (clsField?.execute) {
|
||||
workflow.push({ order: clsField.order, exec: clsField.execute});
|
||||
// const keep = clsField.prepareConfig.call(this, config);
|
||||
// if (config.isFastForward && !keep) return;
|
||||
}
|
||||
}
|
||||
workflow.sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
async executeWorkflow(workflow, config) {
|
||||
console.log(workflow)
|
||||
for(const part of workflow) {
|
||||
console.log(part)
|
||||
if(await part.exec.call(this, config) === false) return;
|
||||
}
|
||||
}
|
||||
|
||||
async use(event, options = {}) {
|
||||
if (!this.actor) throw new Error("An Action can't be used outside of an Actor context.");
|
||||
|
||||
|
|
@ -133,25 +153,30 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
if (!config) return;
|
||||
}
|
||||
|
||||
if (config.hasRoll) {
|
||||
const rollConfig = this.prepareRoll(config);
|
||||
config.roll = rollConfig;
|
||||
config = await this.actor.diceRoll(config);
|
||||
if (!config) return;
|
||||
}
|
||||
const workflow = [];
|
||||
|
||||
if (this.doFollowUp(config)) {
|
||||
if (this.rollDamage && this.damage.parts.length) await this.rollDamage(event, config);
|
||||
else if (this.trigger) await this.trigger(event, config);
|
||||
else if (this.hasSave || this.hasEffect) {
|
||||
const roll = new CONFIG.Dice.daggerheart.DHRoll('');
|
||||
roll._evaluated = true;
|
||||
await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
|
||||
}
|
||||
}
|
||||
this.prepareWorkflow(workflow);
|
||||
await this.executeWorkflow(workflow, config);
|
||||
|
||||
// if (config.hasRoll) {
|
||||
// const rollConfig = this.prepareRoll(config);
|
||||
// config.roll = rollConfig;
|
||||
// config = await this.actor.diceRoll(config);
|
||||
// if (!config) return;
|
||||
// }
|
||||
|
||||
// if (this.doFollowUp(config)) {
|
||||
// if (this.rollDamage && this.damage.parts.length) await this.rollDamage(event, config);
|
||||
// else if (this.trigger) await this.trigger(event, config);
|
||||
// else if (this.hasSave || this.hasEffect) {
|
||||
// const roll = new CONFIG.Dice.daggerheart.DHRoll('');
|
||||
// roll._evaluated = true;
|
||||
// await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config);
|
||||
// }
|
||||
// }
|
||||
|
||||
// Consume resources
|
||||
await this.consume(config);
|
||||
// await this.consume(config);
|
||||
|
||||
if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return;
|
||||
|
||||
|
|
@ -174,8 +199,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
},
|
||||
type: this.type,
|
||||
hasRoll: hasRoll,
|
||||
hasDamage: this.damage?.parts?.length && this.type !== 'healing',
|
||||
hasHealing: this.damage?.parts?.length && this.type === 'healing',
|
||||
hasDamage: this.hasDamagePart && this.type !== 'healing',
|
||||
hasHealing: this.hasDamagePart && this.type === 'healing',
|
||||
hasEffect: !!this.effects?.length,
|
||||
isDirect: !!this.damage?.direct,
|
||||
hasSave: this.hasSave,
|
||||
|
|
@ -190,19 +215,19 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return !config.event.shiftKey && !config.hasRoll && (config.costs?.length || config.uses);
|
||||
}
|
||||
|
||||
prepareRoll() {
|
||||
const roll = {
|
||||
baseModifiers: this.roll.getModifier(),
|
||||
label: 'Attack',
|
||||
type: this.actionType,
|
||||
difficulty: this.roll?.difficulty,
|
||||
formula: this.roll.getFormula(),
|
||||
advantage: CONFIG.DH.ACTIONS.advantageState[this.roll.advState].value
|
||||
};
|
||||
if (this.roll?.type === 'diceSet' || !this.hasRoll) roll.lite = true;
|
||||
// prepareRoll() {
|
||||
// const roll = {
|
||||
// baseModifiers: this.roll.getModifier(),
|
||||
// label: 'Attack',
|
||||
// type: this.actionType,
|
||||
// difficulty: this.roll?.difficulty,
|
||||
// formula: this.roll.getFormula(),
|
||||
// advantage: CONFIG.DH.ACTIONS.advantageState[this.roll.advState].value
|
||||
// };
|
||||
// if (this.roll?.type === 'diceSet' || !this.hasRoll) roll.lite = true;
|
||||
|
||||
return roll;
|
||||
}
|
||||
// return roll;
|
||||
// }
|
||||
|
||||
doFollowUp(config) {
|
||||
return !config.hasRoll;
|
||||
|
|
@ -272,6 +297,10 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return !!this.roll?.type;
|
||||
}
|
||||
|
||||
get hasDamagePart() {
|
||||
return this.damage?.parts?.length;
|
||||
}
|
||||
|
||||
get modifiers() {
|
||||
if (!this.actor) return [];
|
||||
const modifiers = [];
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import DHBaseAction from './baseAction.mjs';
|
|||
export default class DHDamageAction extends DHBaseAction {
|
||||
static extraSchemas = [...super.extraSchemas, 'damage', 'target', 'effects'];
|
||||
|
||||
getFormulaValue(part, data) {
|
||||
/* getFormulaValue(part, data) {
|
||||
let formulaValue = part.value;
|
||||
|
||||
if (data.hasRoll && part.resultBased && data.roll.result.duality === -1) return part.valueAlt;
|
||||
|
|
@ -61,5 +61,5 @@ export default class DHDamageAction extends DHBaseAction {
|
|||
}
|
||||
|
||||
return CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import FormulaField from '../formulaField.mjs';
|
|||
const fields = foundry.data.fields;
|
||||
|
||||
export default class DamageField extends fields.SchemaField {
|
||||
static order = 50;
|
||||
|
||||
constructor(options, context = {}) {
|
||||
const damageFields = {
|
||||
parts: new fields.ArrayField(new fields.EmbeddedDataField(DHDamageData)),
|
||||
|
|
@ -14,6 +16,67 @@ export default class DamageField extends fields.SchemaField {
|
|||
};
|
||||
super(damageFields, options, context);
|
||||
}
|
||||
|
||||
static async execute(data, force = false) {
|
||||
if(this.hasRoll && !force) return;
|
||||
|
||||
const systemData = data.system ?? data;
|
||||
|
||||
let formulas = this.damage.parts.map(p => ({
|
||||
formula: DamageField.getFormulaValue.call(this, p, systemData).getFormula(this.actor),
|
||||
damageTypes: p.applyTo === 'hitPoints' && !p.type.size ? new Set(['physical']) : p.type,
|
||||
applyTo: p.applyTo
|
||||
}));
|
||||
|
||||
if (!formulas.length) return false;
|
||||
|
||||
formulas = DamageField.formatFormulas.call(this, formulas, systemData);
|
||||
|
||||
delete systemData.evaluate;
|
||||
const config = {
|
||||
...systemData,
|
||||
roll: formulas,
|
||||
dialog: {},
|
||||
data: this.getRollData()
|
||||
};
|
||||
if (this.hasSave) config.onSave = this.save.damageMod;
|
||||
if (data.system) {
|
||||
config.source.message = data._id;
|
||||
config.directDamage = false;
|
||||
} else {
|
||||
config.directDamage = true;
|
||||
}
|
||||
|
||||
if(!CONFIG.Dice.daggerheart.DamageRoll.build(config)) return false;
|
||||
}
|
||||
|
||||
static getFormulaValue(part, data) {
|
||||
let formulaValue = part.value;
|
||||
|
||||
if (data.hasRoll && part.resultBased && data.roll.result.duality === -1) return part.valueAlt;
|
||||
|
||||
const isAdversary = this.actor.type === 'adversary';
|
||||
if (isAdversary && this.actor.system.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id) {
|
||||
const hasHordeDamage = this.actor.effects.find(x => x.type === 'horde');
|
||||
if (hasHordeDamage && !hasHordeDamage.disabled) return part.valueAlt;
|
||||
}
|
||||
|
||||
return formulaValue;
|
||||
}
|
||||
|
||||
static formatFormulas(formulas, systemData) {
|
||||
const formattedFormulas = [];
|
||||
formulas.forEach(formula => {
|
||||
if (isNaN(formula.formula))
|
||||
formula.formula = Roll.replaceFormulaData(formula.formula, this.getRollData(systemData));
|
||||
const same = formattedFormulas.find(
|
||||
f => setsEqual(f.damageTypes, formula.damageTypes) && f.applyTo === formula.applyTo
|
||||
);
|
||||
if (same) same.formula += ` + ${formula.formula}`;
|
||||
else formattedFormulas.push(formula);
|
||||
});
|
||||
return formattedFormulas;
|
||||
}
|
||||
}
|
||||
|
||||
export class DHActionDiceData extends foundry.abstract.DataModel {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,20 @@
|
|||
const fields = foundry.data.fields;
|
||||
|
||||
export default class MacroField extends fields.DocumentUUIDField {
|
||||
static order = 100;
|
||||
|
||||
constructor(context = {}) {
|
||||
super({ type: "Macro" }, context);
|
||||
}
|
||||
|
||||
static async execute(config) {
|
||||
const fixUUID = !this.macro.includes('Macro.') ? `Macro.${this.macro}` : this.macro,
|
||||
macro = await fromUuid(fixUUID);
|
||||
try {
|
||||
if (!macro) throw new Error(`No macro found for the UUID: ${this.macro}.`);
|
||||
macro.execute();
|
||||
} catch (error) {
|
||||
ui.notifications.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,32 @@ export class DHActionRollData extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
export default class RollField extends fields.EmbeddedDataField {
|
||||
static order = 10;
|
||||
|
||||
constructor(options, context = {}) {
|
||||
super(DHActionRollData, options, context);
|
||||
}
|
||||
|
||||
static async execute(config) {
|
||||
if(!config.hasRoll) return;
|
||||
config = await this.actor.diceRoll(config);
|
||||
if(!config) return false;
|
||||
}
|
||||
|
||||
static prepareConfig(config) {
|
||||
if(!config.hasRoll) return true;
|
||||
|
||||
const roll = {
|
||||
baseModifiers: this.roll.getModifier(),
|
||||
label: 'Attack',
|
||||
type: this.actionType,
|
||||
difficulty: this.roll?.difficulty,
|
||||
formula: this.roll.getFormula(),
|
||||
advantage: CONFIG.DH.ACTIONS.advantageState[this.roll.advState].value
|
||||
};
|
||||
if (this.roll.type === 'diceSet' || !this.hasRoll) roll.lite = true;
|
||||
|
||||
config.roll = roll;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue