Initial migration

This commit is contained in:
WBHarry 2025-08-27 21:58:25 +02:00
parent 1eb3ff11c0
commit 683907c62b
4 changed files with 98 additions and 22 deletions

View file

@ -586,6 +586,16 @@ export const abilityCosts = {
id: 'fear', id: 'fear',
label: 'Fear', label: 'Fear',
group: 'TYPES.Actor.adversary' group: 'TYPES.Actor.adversary'
},
resource: {
id: 'resource',
label: 'DAGGERHEART.GENERAL.resource',
group: 'Global'
},
quantity: {
id: 'quantity',
label: 'DAGGERHEART.GENERAL.quantity',
group: 'Global'
} }
}; };

View file

@ -5,7 +5,7 @@ export default class CostField extends fields.ArrayField {
* Action Workflow order * Action Workflow order
*/ */
static order = 150; static order = 150;
/** @inheritDoc */ /** @inheritDoc */
constructor(options = {}, context = {}) { constructor(options = {}, context = {}) {
const element = new fields.SchemaField({ const element = new fields.SchemaField({
@ -14,7 +14,7 @@ export default class CostField extends fields.ArrayField {
required: true, required: true,
initial: 'hope' initial: 'hope'
}), }),
keyIsID: new fields.BooleanField(), itemId: new fields.StringField({ nullable: true, initial: null }),
value: new fields.NumberField({ nullable: true, initial: 1, min: 0 }), value: new fields.NumberField({ nullable: true, initial: 1, min: 0 }),
scalable: new fields.BooleanField({ initial: false }), scalable: new fields.BooleanField({ initial: false }),
step: new fields.NumberField({ nullable: true, initial: null }), step: new fields.NumberField({ nullable: true, initial: null }),
@ -34,17 +34,17 @@ export default class CostField extends fields.ArrayField {
* @param {boolean} [successCost=false] Consume only resources configured as "On Success only" if not already consumed. * @param {boolean} [successCost=false] Consume only resources configured as "On Success only" if not already consumed.
*/ */
static async execute(config, successCost = false) { static async execute(config, successCost = false) {
const actor= this.actor.system.partner ?? this.actor, const actor = this.actor.system.partner ?? this.actor,
usefulResources = { usefulResources = {
...foundry.utils.deepClone(actor.system.resources), ...foundry.utils.deepClone(actor.system.resources),
fear: { fear: {
value: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear), value: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear),
max: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear, max: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear,
reversed: false reversed: false
} }
}; };
if(this.parent?.parent) { if (this.parent?.parent) {
for (var cost of config.costs) { for (var cost of config.costs) {
if (cost.keyIsID) { if (cost.keyIsID) {
usefulResources[cost.key] = { usefulResources[cost.key] = {
@ -52,6 +52,11 @@ export default class CostField extends fields.ArrayField {
target: this.parent.parent, target: this.parent.parent,
keyIsID: true keyIsID: true
}; };
} else if (cost.key === 'quantity') {
usefulResources[cost.key] = {
value: cost.value,
target: this.parent.parent
};
} }
} }
} }
@ -74,7 +79,7 @@ export default class CostField extends fields.ArrayField {
return a; return a;
} }
}, []); }, []);
await actor.modifyResource(resources); await actor.modifyResource(resources);
} }
@ -95,10 +100,10 @@ export default class CostField extends fields.ArrayField {
} }
/** /**
* *
* Must be called within Action context. * Must be called within Action context.
* @param {*} costs * @param {*} costs
* @returns * @returns
*/ */
static calcCosts(costs) { static calcCosts(costs) {
const resources = CostField.getResources.call(this, costs); const resources = CostField.getResources.call(this, costs);
@ -121,7 +126,7 @@ export default class CostField extends fields.ArrayField {
/** /**
* Check if the current Actor currently has all needed resources. * Check if the current Actor currently has all needed resources.
* Must be called within Action context. * Must be called within Action context.
* @param {*} costs * @param {*} costs
* @returns {boolean} * @returns {boolean}
*/ */
static hasCost(costs) { static hasCost(costs) {
@ -153,8 +158,8 @@ export default class CostField extends fields.ArrayField {
/** /**
* Get all Actor resources + parent Item potential one. * Get all Actor resources + parent Item potential one.
* Must be called within Action context. * Must be called within Action context.
* @param {*} costs * @param {*} costs
* @returns * @returns
*/ */
static getResources(costs) { static getResources(costs) {
const actorResources = foundry.utils.deepClone(this.actor.system.resources); const actorResources = foundry.utils.deepClone(this.actor.system.resources);
@ -168,6 +173,12 @@ export default class CostField extends fields.ArrayField {
max: CostField.formatMax.call(this, this.parent?.resource?.max) max: CostField.formatMax.call(this, this.parent?.resource?.max)
}; };
} }
if (itemResource.key === 'quantity') {
itemResources[itemResource.key] = {
value: this.parent.quantity ?? 0,
max: null
};
}
} }
return { return {
@ -177,9 +188,9 @@ export default class CostField extends fields.ArrayField {
} }
/** /**
* *
* @param {*} costs * @param {*} costs
* @returns * @returns
*/ */
static getRealCosts(costs) { static getRealCosts(costs) {
const realCosts = costs?.length ? costs.filter(c => c.enabled) : []; const realCosts = costs?.length ? costs.filter(c => c.enabled) : [];

View file

@ -96,5 +96,60 @@ export async function runMigrations() {
lastMigrationVersion = '1.1.1'; lastMigrationVersion = '1.1.1';
} }
if (foundry.utils.isNewerVersion('1.2.0', lastMigrationVersion)) {
const lockedPacks = [];
const compendiumItems = [];
for (let pack of game.packs) {
if (pack.locked) {
lockedPacks.push(pack.collection);
await pack.configure({ locked: false });
}
const documents = await pack.getDocuments();
compendiumItems.push(...documents.filter(x => x.system.metadata.hasActions));
compendiumItems.push(
...documents
.filter(x => x.items)
.flatMap(actor => actor.items.filter(x => x.system.metadata.hasActions))
);
}
const worldItems = game.items.filter(x => x.system.metadata.hasActions);
const worldActorItems = Array.from(game.actors).flatMap(actor =>
actor.items.filter(x => x.system.metadata.hasActions)
);
const validCostKeys = Object.keys(CONFIG.DH.GENERAL.abilityCosts);
for (let item of [...worldItems, ...worldActorItems, ...compendiumItems]) {
for (let action of item.system.actions) {
const resourceCostIndexes = Object.keys(action.cost).reduce(
(acc, index) => (!validCostKeys.includes(action.cost[index].key) ? [...acc, Number(index)] : acc),
[]
);
if (resourceCostIndexes.length === 0) continue;
await action.update({
cost: action.cost.map((cost, index) => {
const { keyIsID, ...rest } = cost;
if (!resourceCostIndexes.includes(index)) return { ...rest };
return {
...rest,
key: 'resource',
itemId: key
};
})
});
}
}
for (let packId of lockedPacks) {
const pack = game.packs.get(packId);
await pack.configure({ locked: true });
}
lastMigrationVersion = '1.2.0';
}
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion); await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion);
} }

View file

@ -2,7 +2,7 @@
"id": "daggerheart", "id": "daggerheart",
"title": "Daggerheart", "title": "Daggerheart",
"description": "An unofficial implementation of the Daggerheart system", "description": "An unofficial implementation of the Daggerheart system",
"version": "1.1.2", "version": "1.2.0",
"compatibility": { "compatibility": {
"minimum": "13", "minimum": "13",
"verified": "13.347", "verified": "13.347",