[Rework] ChatMessage Damage (#2079)
Some checks are pending
Project CI / build (24.x) (push) Waiting to run

* Initial rework

* Removed unneeded method

* Removed outcommented code

* Added migration

* Fixed DamageActions

* Semi-corrected reroll of one of multiple results on a die

* Code improvement

* Added aseDie.rerollResult method to specifically reroll a specific result die in a grouping

* TagTeamDialog somewhat working

* Added migration for TagTeamData

* Fix for mean tagTeamDialog.finish

* .

* Improved migration

* Internalised ChatDamageData.prepareRolls to its own constructor

* Moved DamageTypes to roll.options

* TagTeamDialog fixes to accomodate new flat damage.types structure

* Changed so all default rolls become BaseRolls to access convenience functions and getters

* .

* Fixed so that party.tagTeam now uses a declared damageRollData(ChatDamageData) field. rollData.options.damage is retired.

* Critical damage fixes

* Corrected TagTeamDialog rerender logic when selecting a roll

* Fixed so that DamageTypes are retained and joined together throughout TagTeamDialog

* Removed some remaining types.<>.roll references

* [Rework] Damage and Damage Resource split (#2094)

* Changed the label of ActionSheet damage.resources to Mark Resources

* Fix assigning includeBase

* Localize add resource

* Maybe simplify API

* Fix onRollSimple

* Handle erroring action update differently

---------

Co-authored-by: Carlos Fernandez <cfern1990@gmail.com>
This commit is contained in:
WBHarry 2026-07-19 03:02:57 +02:00 committed by GitHub
parent 4b651836ff
commit effab8db0c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 1007 additions and 788 deletions

View file

@ -1,4 +1,4 @@
import { getUnusedDamageTypes } from '../../helpers/utils.mjs';
import { DHDamageData } from '../../data/fields/action/damageField.mjs';
import DaggerheartSheet from '../sheets/daggerheart-sheet.mjs';
const { ApplicationV2 } = foundry.applications.api;
@ -31,8 +31,10 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
removeElement: this.removeElement,
removeTransformActor: this.removeTransformActor,
editEffect: this.editEffect,
addDamage: this.addDamage,
removeDamage: this.removeDamage,
addDamage: this.#onAddDamage,
removeDamage: this.#onRemoveDamage,
addDamageResource: this.#onAddDamageResource,
removeDamageResource: this.#onRemoveDamageResource,
editDoc: this.editDoc,
addTrigger: this.addTrigger,
removeTrigger: this.removeTrigger,
@ -157,9 +159,9 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
context.tabs = this._getTabs(this.constructor.TABS);
context.config = CONFIG.DH;
if (this.action.damage) {
context.allDamageTypesUsed = !getUnusedDamageTypes(this.action.damage.parts).length;
if (this.action.damage.hasOwnProperty('includeBase') && this.action.type === 'attack')
const allKeys = Object.keys(CONFIG.DH.GENERAL.healingTypes);
context.allDamageTypesUsed = allKeys.every(k => k in this.action._source.damage.resources);
if (this.action.damage?.main?.hasOwnProperty('includeBase') && this.action.type === 'attack')
context.hasBaseDamage = !!this.action.parent.attack;
}
@ -253,7 +255,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
const submitData = this._prepareSubmitData(event, formData);
const data = foundry.utils.mergeObject(this.action.toObject(), submitData);
this.action = await this.action.update(data);
this.action = (await this.action.update(data)) ?? this.action;
this.sheetUpdate?.(this.action);
this.render();
@ -299,53 +301,70 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
}
static addDamage(_event) {
if (!this.action.damage.parts) return;
/** @this DHActionBaseConfig */
static #onAddDamage() {
if (!this.action.damage || this.action.damage?.main) return;
const choices = getUnusedDamageTypes(this.action._source.damage.parts);
const data = this.action.toObject();
data.damage.main = {
...DHDamageData.schema.getInitialValue(),
applyTo: 'hitPoints',
type: 'physical'
};
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
}
/** @this DHActionBaseConfig */
static #onRemoveDamage() {
if (!this.action.damage?.main) return;
const data = this.action.toObject();
data.damage.main = null;
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
}
/** @this DHActionBaseConfig */
static #onAddDamageResource(_event) {
if (!this.action.damage) return;
const allKeys = Object.keys(CONFIG.DH.GENERAL.healingTypes);
const unused = allKeys.filter(k => !(k in this.action._source.damage.resources));
const choices = unused.map(k => ({ value: k, label: _loc(CONFIG.DH.GENERAL.healingTypes[k].label) }));
const content = new foundry.data.fields.StringField({
label: game.i18n.localize('Damage Type'),
label: _loc('DAGGERHEART.GENERAL.Resource.single'),
choices,
required: true
}).toFormGroup(
{},
{
name: 'type',
localize: true,
nameAttr: 'value',
labelAttr: 'label'
}
).outerHTML;
}).toFormGroup({}, {
name: 'type',
localize: true,
nameAttr: 'value',
labelAttr: 'label'
}).outerHTML;
const callback = (_, button) => {
const data = this.action.toObject();
const type = choices[button.form.elements.type.value].value;
const part = this.action.schema.fields.damage.fields.parts.element.getInitialValue();
part.applyTo = type;
if (type === CONFIG.DH.GENERAL.healingTypes.hitPoints.id)
part.type = this.action.schema.fields.damage.fields.parts.element.fields.type.element.initial;
data.damage.parts[type] = part;
data.damage.resources[type] = {
...this.action.schema.fields.damage.fields.resources.element.getInitialValue(),
applyTo: type
};
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
};
const typeDialog = new foundry.applications.api.DialogV2({
buttons: [
foundry.utils.mergeObject(
{
action: 'ok',
label: 'Confirm',
icon: 'fas fa-check',
default: true
},
{ callback: callback }
)
{
action: 'ok',
label: 'Confirm',
icon: 'fas fa-check',
default: true,
callback
}
],
content: content,
rejectClose: false,
modal: false,
window: {
title: game.i18n.localize('Add Damage')
title: _loc('DAGGERHEART.ACTIONS.Config.damage.addResource')
},
position: { width: 300 }
});
@ -353,12 +372,12 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
typeDialog.render(true);
}
static removeDamage(_event, button) {
if (!this.action.damage.parts) return;
/** @this DHActionBaseConfig */
static #onRemoveDamageResource(_event, button) {
if (!this.action.damage?.resources) return;
const data = this.action.toObject();
const key = button.dataset.key;
delete data.damage.parts[key];
data.damage.parts[`${key}`] = _del;
data.damage.resources[key] = _del;
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
}