284 - Armor/Weapon Feature Improvements (#292)

* Added parsing of effect values from Item data model. Almost finished with itemConfig.

* Added the last to itemConfig

* Fixed armor

* ContextMenu localization fixes

* Better tooltips for tagify

* Corrected resource logic
This commit is contained in:
WBHarry 2025-07-09 13:06:49 +02:00 committed by GitHub
parent eae4f12910
commit b3e7c6b9b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 3043 additions and 2310 deletions

View file

@ -3,7 +3,7 @@ import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs';
const { DialogV2, ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
export default class DamageReductionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
constructor(resolve, reject, actor, damage) {
constructor(resolve, reject, actor, damage, damageType) {
super({});
this.resolve = resolve;
@ -11,37 +11,46 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
this.actor = actor;
this.damage = damage;
const maxArmorMarks = Math.min(
actor.system.armorScore - actor.system.armor.system.marks.value,
actor.system.rules.maxArmorMarked.total
);
const canApplyArmor = actor.system.armorApplicableDamageTypes[damageType];
const maxArmorMarks = canApplyArmor
? Math.min(
actor.system.armorScore - actor.system.armor.system.marks.value,
actor.system.rules.damageReduction.maxArmorMarked.total
)
: 0;
const armor = [...Array(maxArmorMarks).keys()].reduce((acc, _) => {
acc[foundry.utils.randomID()] = { selected: false };
return acc;
}, {});
const stress = [...Array(actor.system.rules.maxArmorMarked.stressExtra ?? 0).keys()].reduce((acc, _) => {
acc[foundry.utils.randomID()] = { selected: false };
return acc;
}, {});
const stress = [...Array(actor.system.rules.damageReduction.maxArmorMarked.stressExtra ?? 0).keys()].reduce(
(acc, _) => {
acc[foundry.utils.randomID()] = { selected: false };
return acc;
},
{}
);
this.marks = { armor, stress };
this.availableStressReductions = Object.keys(actor.system.rules.stressDamageReduction).reduce((acc, key) => {
const dr = actor.system.rules.stressDamageReduction[key];
if (dr.enabled) {
if (acc === null) acc = {};
this.availableStressReductions = Object.keys(actor.system.rules.damageReduction.stressDamageReduction).reduce(
(acc, key) => {
const dr = actor.system.rules.damageReduction.stressDamageReduction[key];
if (dr.enabled) {
if (acc === null) acc = {};
const damage = damageKeyToNumber(key);
acc[damage] = {
cost: dr.cost,
selected: false,
from: getDamageLabel(damage),
to: getDamageLabel(damage - 1)
};
}
const damage = damageKeyToNumber(key);
acc[damage] = {
cost: dr.cost,
selected: false,
from: getDamageLabel(damage),
to: getDamageLabel(damage - 1)
};
}
return acc;
}, null);
return acc;
},
null
);
}
get title() {
@ -90,7 +99,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
context.armorScore = this.actor.system.armorScore;
context.armorMarks = currentMarks;
context.basicMarksUsed = selectedArmorMarks.length === this.actor.system.rules.maxArmorMarked.total;
context.basicMarksUsed =
selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.total;
const stressReductionStress = this.availableStressReductions
? stressReductions.reduce((acc, red) => acc + red.cost, 0)
@ -122,12 +132,15 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
getDamageInfo = () => {
const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected);
const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected);
const stressReductions = Object.values(this.availableStressReductions ?? {}).filter(red => red.selected);
const stressReductions = this.availableStressReductions
? Object.values(this.availableStressReductions).filter(red => red.selected)
: [];
const currentMarks =
this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.length;
const currentDamage =
this.damage - selectedArmorMarks.length - selectedStressMarks.length - stressReductions.length;
const armorMarkReduction =
selectedArmorMarks.length * this.actor.system.rules.damageReduction.increasePerArmorMark;
const currentDamage = this.damage - armorMarkReduction - selectedStressMarks.length - stressReductions.length;
return { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage };
};
@ -216,11 +229,11 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
await super.close({});
}
static async armorStackQuery({actorId, damage}) {
static async armorStackQuery({ actorId, damage, type }) {
return new Promise(async (resolve, reject) => {
const actor = await fromUuid(actorId);
if(!actor || !actor?.isOwner) reject();
new DamageReductionDialog(resolve, reject, actor, damage).render({ force: true });
})
if (!actor || !actor?.isOwner) reject();
new DamageReductionDialog(resolve, reject, actor, damage, type).render({ force: true });
});
}
}

View file

@ -35,7 +35,7 @@ export default class ArmorSheet extends DHBaseItemSheet {
switch (partId) {
case 'settings':
context.features = this.document.system.features.map(x => x.value);
context.features = this.document.system.armorFeatures.map(x => x.value);
break;
}
@ -47,6 +47,6 @@ export default class ArmorSheet extends DHBaseItemSheet {
* @param {Array<Object>} selectedOptions - The currently selected tag objects.
*/
static async #onFeatureSelect(selectedOptions) {
await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) });
await this.document.update({ 'system.armorFeatures': selectedOptions.map(x => ({ value: x.value })) });
}
}

View file

@ -33,7 +33,7 @@ export default class WeaponSheet extends DHBaseItemSheet {
super._preparePartContext(partId, context);
switch (partId) {
case 'settings':
context.features = this.document.system.features.map(x => x.value);
context.features = this.document.system.weaponFeatures.map(x => x.value);
context.systemFields.attack.fields = this.document.system.attack.schema.fields;
break;
}
@ -45,6 +45,6 @@ export default class WeaponSheet extends DHBaseItemSheet {
* @param {Array<Object>} selectedOptions - The currently selected tag objects.
*/
static async #onFeatureSelect(selectedOptions) {
await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) });
await this.document.update({ 'system.weaponFeatures': selectedOptions.map(x => ({ value: x.value })) });
}
}

View file

@ -80,8 +80,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
actor.system.attack?._id === actionId
? actor.system.attack
: item.system.attack?._id === actionId
? item.system.attack
: item?.system?.actions?.find(a => a._id === actionId);
? item.system.attack
: item?.system?.actions?.find(a => a._id === actionId);
return action;
}