Merged with v14-Dev

This commit is contained in:
WBHarry 2026-03-14 00:31:12 +01:00
commit 4332a1ba7a
613 changed files with 4618 additions and 2996 deletions

View file

@ -1,3 +1,4 @@
import { getUnusedDamageTypes } from '../../helpers/utils.mjs';
import DaggerheartSheet from '../sheets/daggerheart-sheet.mjs';
const { ApplicationV2 } = foundry.applications.api;
@ -28,6 +29,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
removeEffect: this.removeEffect,
addElement: this.addElement,
removeElement: this.removeElement,
removeTransformActor: this.removeTransformActor,
editEffect: this.editEffect,
addDamage: this.addDamage,
removeDamage: this.removeDamage,
@ -41,7 +43,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
submitOnChange: true,
closeOnSubmit: false
},
dragDrop: [{ dragSelector: null, dropSelector: '#summon-drop-zone', handlers: ['_onDrop'] }]
dragDrop: [{ dragSelector: null, dropSelector: '[data-is-drop-zone]', handlers: ['_onDrop'] }]
};
static PARTS = {
@ -103,7 +105,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
}
};
static CLEAN_ARRAYS = ['damage.parts', 'cost', 'effects', 'summon'];
static CLEAN_ARRAYS = ['cost', 'effects', 'summon'];
_getTabs(tabs) {
for (const v of Object.values(tabs)) {
@ -120,6 +122,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) {
@ -133,6 +139,18 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
context.summons.push({ actor, count: summon.count });
}
if (context.source.transform) {
const actor = await foundry.utils.fromUuid(context.source.transform.actorUUID);
context.transform = {
...context.source.transform,
actor:
actor ??
(context.source.transform.actorUUID && !actor
? { error: game.i18n.localize('DAGGERHEART.ACTIONS.Settings.transform.actorIsMissing') }
: null)
};
}
context.openSection = this.openSection;
context.tabs = this._getTabs(this.constructor.TABS);
context.config = CONFIG.DH;
@ -155,6 +173,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
revealed: this.openTrigger === index
};
});
context.allDamageTypesUsed = !getUnusedDamageTypes(this.action.damage.parts).length;
const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers;
context.tierOptions = [
@ -266,20 +285,69 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
if (doc) return doc.sheet.render({ force: true });
}
static async removeTransformActor() {
const data = this.action.toObject();
data.transform.actorUUID = null;
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
}
static addDamage(_event) {
if (!this.action.damage.parts) return;
const data = this.action.toObject(),
part = {};
if (this.action.actor?.isNPC) part.value = { multiplier: 'flat' };
data.damage.parts.push(part);
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
const choices = getUnusedDamageTypes(this.action.damage.parts);
const content = new foundry.data.fields.StringField({
label: game.i18n.localize('Damage Type'),
choices,
required: true
}).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 = { applyTo: type };
if (this.action.actor?.isNPC) part.value = { multiplier: 'flat' };
data.damage.parts[type] = part;
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 }
)
],
content: content,
rejectClose: false,
modal: false,
window: {
title: game.i18n.localize('Add Damage')
},
position: { width: 300 }
});
typeDialog.render(true);
}
static removeDamage(_event, button) {
if (!this.action.damage.parts) return;
const data = this.action.toObject(),
index = button.dataset.index;
data.damage.parts.splice(index, 1);
const data = this.action.toObject();
const key = button.dataset.key;
delete data.damage.parts[key];
data.damage.parts[`${key}`] = _del;
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
}
@ -346,6 +414,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) {}
@ -364,6 +440,18 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
return;
}
const dropZone = event.target.closest('[data-is-drop-zone]');
if (!dropZone) return;
switch (dropZone.id) {
case 'summon-drop-zone':
return this.onSummonDrop(data);
case 'transform-drop-zone':
return this.onTransformDrop(data);
}
}
async onSummonDrop(data) {
const actionData = this.action.toObject();
let countvalue = 1;
for (const entry of actionData.summon) {
@ -380,4 +468,10 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
actionData.summon.push({ actorUUID: data.uuid, count: countvalue });
await this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(actionData) });
}
async onTransformDrop(data) {
const actionData = this.action.toObject();
actionData.transform.actorUUID = data.uuid;
await this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(actionData) });
}
}