[Feature] 1033 - Consume Quantity On Use (#1106)

* Initial migration

* Updated compendium YML

* Added Quantity as a possible cost

* Added quantity consumption to all Compendium Consumables

* .

* Added DestroyOnEmpty property
This commit is contained in:
WBHarry 2025-08-28 18:29:17 +02:00 committed by GitHub
parent 9dd773001d
commit 8fd63d5963
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
397 changed files with 1276 additions and 930 deletions

View file

@ -1,4 +1,4 @@
import { abilities } from "../../config/actorConfig.mjs";
import { abilities } from '../../config/actorConfig.mjs';
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
@ -83,7 +83,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
);
context.costs = updatedCosts.map(x => ({
...x,
label: x.keyIsID
label: x.itemId
? this.action.parent.parent.name
: game.i18n.localize(CONFIG.DH.GENERAL.abilityCosts[x.key].label)
}));
@ -115,7 +115,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
context.isLite = this.config.roll?.lite;
context.extraFormula = this.config.extraFormula;
context.formula = this.roll.constructFormula(this.config);
if(this.actor.system.traits) context.abilities = this.getTraitModifiers();
if (this.actor.system.traits) context.abilities = this.getTraitModifiers();
context.showReaction = !this.config.roll?.type && context.rollType === 'DualityRoll';
context.reactionOverride = this.reactionOverride;
@ -124,12 +124,15 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
}
getTraitModifiers() {
return Object.values(abilities).map(a => ({ id: a.id, label: `${game.i18n.localize(a.label)} (${this.actor.system.traits[a.id]?.value.signedString() ?? 0})` }))
return Object.values(abilities).map(a => ({
id: a.id,
label: `${game.i18n.localize(a.label)} (${this.actor.system.traits[a.id]?.value.signedString() ?? 0})`
}));
}
static updateRollConfiguration(event, _, formData) {
const { ...rest } = foundry.utils.expandObject(formData.object);
this.config.selectedRollMode = rest.selectedRollMode;
if (this.config.costs) {
@ -141,7 +144,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
this.roll[key] = value;
});
}
if(rest.hasOwnProperty("trait")) {
if (rest.hasOwnProperty('trait')) {
this.config.roll.trait = rest.trait;
this.config.title = game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
ability: game.i18n.localize(abilities[this.config.roll.trait]?.label)
@ -169,14 +172,14 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
this.config.costs.indexOf(this.config.costs.find(c => c.extKey === button.dataset.key)) > -1
? this.config.costs.filter(x => x.extKey !== button.dataset.key)
: [
...this.config.costs,
{
extKey: button.dataset.key,
key: this.config?.data?.parent?.isNPC ? 'fear' : 'hope',
value: 1,
name: this.config.data?.experiences?.[button.dataset.key]?.name
}
];
...this.config.costs,
{
extKey: button.dataset.key,
key: this.config?.data?.parent?.isNPC ? 'fear' : 'hope',
value: 1,
name: this.config.data?.experiences?.[button.dataset.key]?.name
}
];
this.render();
}

View file

@ -132,12 +132,19 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
const options = foundry.utils.deepClone(CONFIG.DH.GENERAL.abilityCosts);
const resource = this.action.parent.resource;
if (resource) {
options[this.action.parent.parent.id] = {
options.resource = {
label: 'DAGGERHEART.GENERAL.itemResource',
group: 'Global'
};
}
if (this.action.parent.metadata.isQuantifiable) {
options.quantity = {
label: 'DAGGERHEART.GENERAL.itemQuantity',
group: 'Global'
};
}
return options;
}
@ -164,13 +171,14 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
_prepareSubmitData(_event, formData) {
const submitData = foundry.utils.expandObject(formData.object);
const itemAbilityCostKeys = Object.keys(CONFIG.DH.GENERAL.itemAbilityCosts);
for (const keyPath of this.constructor.CLEAN_ARRAYS) {
const data = foundry.utils.getProperty(submitData, keyPath);
const dataValues = data ? Object.values(data) : [];
if (keyPath === 'cost') {
for (var value of dataValues) {
const item = this.action.parent.parent.id === value.key;
value.keyIsID = Boolean(item);
value.itemId = itemAbilityCostKeys.includes(value.key) ? this.action.parent.parent.id : null;
}
}

View file

@ -132,6 +132,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
});
htmlElement.querySelectorAll('.inventory-item-quantity').forEach(element => {
element.addEventListener('change', this.updateItemQuantity.bind(this));
element.addEventListener('click', e => e.stopPropagation());
});
// Add listener for armor marks input
@ -676,7 +677,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
})
});
if(result) game.system.api.fields.ActionFields.CostField.execute.call(this, result);
if (result) game.system.api.fields.ActionFields.CostField.execute.call(this, result);
}
//TODO: redo toggleEquipItem method

View file

@ -84,8 +84,7 @@ export default class DhCompanionSheet extends DHBaseActorSheet {
return {
key: c.key,
value: (c.total ?? c.value) * (resource.isReversed ? 1 : -1),
target: resource.target,
keyIsID: resource.keyIsID
target: resource.target
};
});