mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Feature/336 damage targeted resources (#376)
* Unify healing & damage * create DHResourceData * Damages parts roll * h * ChatMessage & takeDamage updates * Adapt healing * No, there was not a console.log !
This commit is contained in:
parent
26376b49db
commit
7cbbb3168e
25 changed files with 415 additions and 232 deletions
|
|
@ -93,10 +93,32 @@ export class DHDamageField extends fields.SchemaField {
|
|||
}
|
||||
}
|
||||
|
||||
export class DHDamageData extends foundry.abstract.DataModel {
|
||||
export class DHResourceData extends foundry.abstract.DataModel {
|
||||
/** @override */
|
||||
static defineSchema() {
|
||||
return {
|
||||
applyTo: new fields.StringField({
|
||||
choices: CONFIG.DH.GENERAL.healingTypes,
|
||||
required: true,
|
||||
blank: false,
|
||||
initial: CONFIG.DH.GENERAL.healingTypes.hitPoints.id,
|
||||
label: 'DAGGERHEART.ACTIONS.Settings.applyTo.label'
|
||||
}),
|
||||
resultBased: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label'
|
||||
}),
|
||||
value: new fields.EmbeddedDataField(DHActionDiceData),
|
||||
valueAlt: new fields.EmbeddedDataField(DHActionDiceData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class DHDamageData extends DHResourceData {
|
||||
/** @override */
|
||||
static defineSchema() {
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
base: new fields.BooleanField({ initial: false, readonly: true, label: 'Base' }),
|
||||
type: new fields.SetField(
|
||||
new fields.StringField({
|
||||
|
|
@ -106,16 +128,9 @@ export class DHDamageData extends foundry.abstract.DataModel {
|
|||
required: true
|
||||
}),
|
||||
{
|
||||
label: 'Type',
|
||||
initial: 'physical'
|
||||
label: 'Type'
|
||||
}
|
||||
),
|
||||
resultBased: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label'
|
||||
}),
|
||||
value: new fields.EmbeddedDataField(DHActionDiceData),
|
||||
valueAlt: new fields.EmbeddedDataField(DHActionDiceData)
|
||||
};
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DHActionDiceData, DHActionRollData, DHDamageField } from './actionDice.mjs';
|
||||
import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField, DHResourceData } from './actionDice.mjs';
|
||||
import DhpActor from '../../documents/actor.mjs';
|
||||
import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs';
|
||||
|
||||
|
|
@ -96,21 +96,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
|
|||
onSave: new fields.BooleanField({ initial: false })
|
||||
})
|
||||
),
|
||||
healing: new fields.SchemaField({
|
||||
type: new fields.StringField({
|
||||
choices: CONFIG.DH.GENERAL.healingTypes,
|
||||
required: true,
|
||||
blank: false,
|
||||
initial: CONFIG.DH.GENERAL.healingTypes.hitPoints.id,
|
||||
label: 'Healing'
|
||||
}),
|
||||
resultBased: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label'
|
||||
}),
|
||||
value: new fields.EmbeddedDataField(DHActionDiceData),
|
||||
valueAlt: new fields.EmbeddedDataField(DHActionDiceData)
|
||||
}),
|
||||
healing: new fields.EmbeddedDataField(DHResourceData),
|
||||
beastform: new fields.SchemaField({
|
||||
tierAccess: new fields.SchemaField({
|
||||
exact: new fields.NumberField({ integer: true, nullable: true, initial: null })
|
||||
|
|
@ -156,7 +142,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
|
|||
static getSourceConfig(parent) {
|
||||
const updateSource = {};
|
||||
updateSource.img ??= parent?.img ?? parent?.system?.img;
|
||||
if (parent?.type === 'weapon') {
|
||||
if (parent?.type === 'weapon' && this === game.system.api.models.actions.actionsTypes.attack) {
|
||||
updateSource['damage'] = { includeBase: true };
|
||||
updateSource['range'] = parent?.system?.attack?.range;
|
||||
updateSource['roll'] = {
|
||||
|
|
@ -177,6 +163,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
getRollData(data = {}) {
|
||||
if(!this.actor) return null;
|
||||
const actorData = this.actor.getRollData(false);
|
||||
|
||||
// Add Roll results to RollDatas
|
||||
|
|
@ -191,6 +178,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
async use(event, ...args) {
|
||||
if(!this.actor) throw new Error("An Action can't be used outside of an Actor context.");
|
||||
|
||||
const isFastForward = event.shiftKey || (!this.hasRoll && !this.hasSave);
|
||||
// Prepare base Config
|
||||
const initConfig = this.initActionConfig(event);
|
||||
|
|
@ -227,7 +216,6 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
|
|||
if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return;
|
||||
|
||||
// Display configuration window if necessary
|
||||
// if (config.dialog?.configure && this.requireConfigurationDialog(config)) {
|
||||
if (this.requireConfigurationDialog(config)) {
|
||||
config = await D20RollDialog.configure(null, config);
|
||||
if (!config) return;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { setsEqual } from '../../helpers/utils.mjs';
|
||||
import DHBaseAction from './baseAction.mjs';
|
||||
|
||||
export default class DHDamageAction extends DHBaseAction {
|
||||
|
|
@ -18,28 +19,40 @@ export default class DHDamageAction extends DHBaseAction {
|
|||
return formulaValue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
async rollDamage(event, data) {
|
||||
const systemData = data.system ?? data;
|
||||
let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '),
|
||||
damageTypes = [...new Set(this.damage.parts.reduce((a, c) => a.concat([...c.type]), []))];
|
||||
|
||||
let formulas = this.damage.parts.map(p => ({
|
||||
formula: this.getFormulaValue(p, data).getFormula(this.actor),
|
||||
damageTypes: p.applyTo === 'hitPoints' && !p.type.size ? new Set(['physical']) : p.type,
|
||||
applyTo: p.applyTo
|
||||
}));
|
||||
|
||||
damageTypes = !damageTypes.length ? ['physical'] : damageTypes;
|
||||
if(!formulas.length) return;
|
||||
|
||||
if (!formula || formula == '') return;
|
||||
let roll = { formula: formula, total: formula },
|
||||
bonusDamage = [];
|
||||
|
||||
if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(systemData));
|
||||
formulas = this.formatFormulas(formulas, systemData);
|
||||
|
||||
const config = {
|
||||
title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: this.name }),
|
||||
roll: { formula },
|
||||
roll: formulas,
|
||||
targets: systemData.targets.filter(t => t.hit) ?? data.targets,
|
||||
hasSave: this.hasSave,
|
||||
isCritical: systemData.roll?.isCritical ?? false,
|
||||
source: systemData.source,
|
||||
data: this.getRollData(),
|
||||
damageTypes,
|
||||
event
|
||||
};
|
||||
if (this.hasSave) config.onSave = this.save.damageMod;
|
||||
|
|
@ -50,10 +63,6 @@ export default class DHDamageAction extends DHBaseAction {
|
|||
config.directDamage = true;
|
||||
}
|
||||
|
||||
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
||||
return CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
||||
}
|
||||
|
||||
// get modifiers() {
|
||||
// return [];
|
||||
// }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,25 +15,25 @@ export default class DHHealingAction extends DHBaseAction {
|
|||
}
|
||||
|
||||
async rollHealing(event, data) {
|
||||
let formulaValue = this.getFormulaValue(data),
|
||||
formula = formulaValue.getFormula(this.actor);
|
||||
|
||||
if (!formula || formula == '') return;
|
||||
let roll = { formula: formula, total: formula },
|
||||
bonusDamage = [];
|
||||
|
||||
const systemData = data.system ?? data;
|
||||
let formulas = [{
|
||||
formula: this.getFormulaValue(data).getFormula(this.actor),
|
||||
applyTo: this.healing.applyTo
|
||||
}];
|
||||
|
||||
const config = {
|
||||
title: game.i18n.format('DAGGERHEART.UI.Chat.healingRoll.title', {
|
||||
healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.type].label)
|
||||
healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.applyTo].label)
|
||||
}),
|
||||
roll: { formula },
|
||||
roll: formulas,
|
||||
targets: (data.system?.targets ?? data.targets).filter(t => t.hit),
|
||||
messageType: 'healing',
|
||||
type: this.healing.type,
|
||||
source: systemData.source,
|
||||
data: this.getRollData(),
|
||||
event
|
||||
};
|
||||
|
||||
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
||||
return CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
||||
}
|
||||
|
||||
get chatTemplate() {
|
||||
|
|
|
|||
|
|
@ -170,11 +170,10 @@ export default class DhCharacter extends BaseDataActor {
|
|||
rules: new fields.SchemaField({
|
||||
damageReduction: new fields.SchemaField({
|
||||
maxArmorMarked: new fields.SchemaField({
|
||||
value: new fields.NumberField({ required: true, integer: true, initial: 1 }),
|
||||
bonus: new fields.NumberField({
|
||||
value: new fields.NumberField({
|
||||
required: true,
|
||||
integer: true,
|
||||
initial: 0,
|
||||
initial: 1,
|
||||
label: 'DAGGERHEART.GENERAL.Rules.damageReduction.maxArmorMarkedBonus'
|
||||
}),
|
||||
stressExtra: new fields.NumberField({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue