Added Quantity as a possible cost

This commit is contained in:
WBHarry 2025-08-28 01:08:03 +02:00
parent fa0fa1f9ee
commit 26ce421d9c
7 changed files with 89 additions and 53 deletions

View file

@ -1983,6 +1983,7 @@
"inactiveEffects": "Inactive Effects",
"inventory": "Inventory",
"itemResource": "Item Resource",
"itemQuantity": "Item Quantity",
"items": "Items",
"label": "Label",
"level": "Level",

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

@ -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
};
});

View file

@ -561,6 +561,19 @@ export const refreshTypes = {
}
};
export const itemAbilityCosts = {
resource: {
id: 'resource',
label: 'DAGGERHEART.GENERAL.resource',
group: 'Global'
},
quantity: {
id: 'quantity',
label: 'DAGGERHEART.GENERAL.quantity',
group: 'Global'
}
};
export const abilityCosts = {
hitPoints: {
id: 'hitPoints',
@ -587,16 +600,7 @@ export const abilityCosts = {
label: 'Fear',
group: 'TYPES.Actor.adversary'
},
resource: {
id: 'resource',
label: 'DAGGERHEART.GENERAL.resource',
group: 'Global'
},
quantity: {
id: 'quantity',
label: 'DAGGERHEART.GENERAL.quantity',
group: 'Global'
}
resource: itemAbilityCosts.resource
};
export const countdownTypes = {

View file

@ -46,16 +46,11 @@ export default class CostField extends fields.ArrayField {
if (this.parent?.parent) {
for (var cost of config.costs) {
if (cost.keyIsID) {
if (cost.itemId) {
usefulResources[cost.key] = {
value: cost.value,
target: this.parent.parent,
keyIsID: true
};
} else if (cost.key === 'quantity') {
usefulResources[cost.key] = {
value: cost.value,
target: this.parent.parent
itemId: cost.itemId
};
}
}
@ -74,7 +69,7 @@ export default class CostField extends fields.ArrayField {
key: c.key,
value: (c.total ?? c.value) * (resource.isReversed ? 1 : -1),
target: resource.target,
keyIsID: resource.keyIsID
itemId: resource.itemId
});
return a;
}
@ -107,7 +102,12 @@ export default class CostField extends fields.ArrayField {
*/
static calcCosts(costs) {
const resources = CostField.getResources.call(this, costs);
return costs.map(c => {
let filteredCosts = costs;
if (this.parent.metadata.isQuantifiable && this.parent.consumeOnUse === false) {
filteredCosts = filteredCosts.filter(c => c.key !== 'quantity');
}
return filteredCosts.map(c => {
c.scale = c.scale ?? 0;
c.step = c.step ?? 1;
c.total = c.value + c.scale * c.step;
@ -167,17 +167,8 @@ export default class CostField extends fields.ArrayField {
actorResources.hope = foundry.utils.deepClone(this.actor.system.partner.system.resources.hope);
const itemResources = {};
for (let itemResource of costs) {
if (itemResource.keyIsID) {
itemResources[itemResource.key] = {
value: this.parent.resource.value ?? 0,
max: CostField.formatMax.call(this, this.parent?.resource?.max)
};
}
if (itemResource.key === 'quantity') {
itemResources[itemResource.key] = {
value: this.parent.quantity ?? 0,
max: null
};
if (itemResource.itemId) {
itemResources[itemResource.key] = CostField.getItemIdCostResource.bind(this)(itemResource);
}
}
@ -187,6 +178,38 @@ export default class CostField extends fields.ArrayField {
};
}
static getItemIdCostResource(itemResource) {
switch (itemResource.key) {
case CONFIG.DH.GENERAL.itemAbilityCosts.resource.id:
return {
value: this.parent.resource.value ?? 0,
max: CostField.formatMax.call(this, this.parent?.resource?.max)
};
case CONFIG.DH.GENERAL.itemAbilityCosts.quantity.id:
return {
value: this.parent.quantity ?? 0,
max: this.parent.quantity ?? 0
};
default:
return { value: 0, max: 0 };
}
}
static getItemIdCostUpdate(r) {
switch (r.key) {
case CONFIG.DH.GENERAL.itemAbilityCosts.resource.id:
return {
'system.resource.value': r.target.system.resource.value + r.value
};
case CONFIG.DH.GENERAL.itemAbilityCosts.quantity.id:
return {
'system.quantity': r.target.system.quantity + r.value
};
default:
return {};
}
}
/**
*
* @param {*} costs

View file

@ -659,12 +659,10 @@ export default class DhpActor extends Actor {
};
resources.forEach(r => {
if (r.keyIsID) {
if (r.itemId) {
updates.items[r.key] = {
target: r.target,
resources: {
'system.resource.value': r.target.system.resource.value + r.value
}
resources: game.system.api.fields.ActionFields.CostField.getItemIdCostUpdate(r)
};
} else {
switch (r.key) {