Added support for keeping currently marked hitPoints/stress when transforming

This commit is contained in:
WBHarry 2026-03-07 14:25:39 +01:00
parent dcf0293008
commit 800eefbddf
6 changed files with 86 additions and 9 deletions

View file

@ -137,7 +137,9 @@
"dropSummonsHere": "Drop Summons Here"
},
"transform": {
"dropTransformHere": "Drop Transform Here"
"dropTransformHere": "Drop Transform Here",
"clearHitPoints": "Clear Hitpoints",
"clearStress": "Clear Stress"
}
}
},

View file

@ -121,6 +121,10 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
htmlElement.querySelectorAll('.summon-count-wrapper input').forEach(element => {
element.addEventListener('change', this.updateSummonCount.bind(this));
});
htmlElement.querySelectorAll('.transform-resource input').forEach(element => {
element.addEventListener('change', this.updateTransformResource.bind(this));
});
}
async _prepareContext(_options) {
@ -136,6 +140,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
if (context.source.transform) {
context.transform = {
...context.source.transform,
actor: await foundry.utils.fromUuid(context.source.transform.actorUUID)
};
}
@ -359,6 +364,14 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
}
updateTransformResource(event) {
event.stopPropagation();
const data = this.action.toObject();
data.transform.resourceRefresh[event.target.dataset.resource] = event.target.checked;
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
}
/** Specific implementation in extending classes **/
static async addEffect(_event) {}
static removeEffect(_event, _button) {}

View file

@ -197,7 +197,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
async executeWorkflow(config) {
for (const [key, part] of this.workflow) {
if (Hooks.call(`${CONFIG.DH.id}.pre${key.capitalize()}Action`, this, config) === false) return;
if ((await part.execute(config)) === false) return;
if ((await part.execute(config)) === false) return false;
if (Hooks.call(`${CONFIG.DH.id}.post${key.capitalize()}Action`, this, config) === false) return;
}
}
@ -224,7 +224,9 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
}
// Execute the Action Worflow in order based of schema fields
await this.executeWorkflow(config);
const result = await this.executeWorkflow(config);
if (result === false) return;
await config.resourceUpdates.updateResources();
if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return;

View file

@ -11,26 +11,60 @@ export default class DHSummonField extends fields.SchemaField {
actorUUID: new fields.DocumentUUIDField({
type: 'Actor',
required: true
}),
resourceRefresh: new fields.SchemaField({
hitPoints: new fields.BooleanField({ initial: true }),
stress: new fields.BooleanField({ initial: true })
})
};
super(transformFields, options, context);
}
static async execute() {
if (!canvas.scene)
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.canvasError'));
if (!canvas.scene) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.canvasError'));
return false;
}
if (!this.actor.token)
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.prototypeError'));
if (!this.actor.token) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.prototypeError'));
return false;
}
const actor = await DHSummonField.getWorldActor(await foundry.utils.fromUuid(this.transform.actorUUID));
const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes;
const tokenSize = actor?.system.metadata.usesSize ? tokenSizes[actor.system.size] : actor.prototypeToken.width;
await this.actor.token.update(
{ ...actor.prototypeToken.toJSON(), actorId: actor.id },
{ ...actor.prototypeToken.toJSON(), actorId: actor.id, width: tokenSize, height: tokenSize },
{ diff: false, recursive: false, noHook: true }
);
const marks = { hitPoints: 0, stress: 0 };
if (!this.transform.resourceRefresh.hitPoints) {
marks.hitPoints = Math.min(
this.actor.system.resources.hitPoints.value,
this.actor.token.actor.system.resources.hitPoints.max - 1
);
}
if (!this.transform.resourceRefresh.stress) {
marks.stress = Math.min(
this.actor.system.resources.stress.value,
this.actor.token.actor.system.resources.stress.max - 1
);
}
if (marks.hitPoints || marks.stress) {
this.actor.token.actor.update({
'system.resources': {
hitPoints: { value: marks.hitPoints },
stress: { value: marks.stress }
}
});
}
const prevPosition = { ...this.actor.sheet.position };
this.actor.sheet.close();
actor.sheet.render({ force: true });
this.actor.token.actor.sheet.render({ force: true, position: prevPosition });
}
/* Check for any available instances of the actor present in the world, or create a world actor based on compendium */

View file

@ -11,6 +11,21 @@
display: flex;
flex-direction: column;
gap: 10px;
.transform-resources {
display: flex;
justify-content: space-between;
.transform-resource {
display: flex;
flex-direction: column;
gap: 2px;
.resource-title {
font-size: var(--font-size-18);
}
}
}
}
.actor-drop-line {

View file

@ -40,5 +40,16 @@
<span>{{localize "DAGGERHEART.ACTIONS.Settings.transform.dropTransformHere"}}</span>
</div>
{{/unless}}
<div class="transform-resources">
<div class="transform-resource">
<span class="resource-title">{{localize "DAGGERHEART.ACTIONS.Settings.transform.clearHitPoints"}}</span>
<input type="checkbox" data-resource="hitPoints" {{checked transform.resourceRefresh.hitPoints}}/>
</div>
<div class="transform-resource">
<span>{{localize "DAGGERHEART.ACTIONS.Settings.transform.clearStress"}}</span>
<input type="checkbox" data-resource="stress" {{checked transform.resourceRefresh.stress}}/>
</div>
</div>
</div>
</fieldset>