feat: make it possible to affect the armor value spell malus with Active Effects

The corresponding key is `data.armorValueSpellMalus`
This commit is contained in:
Johannes Loher 2022-11-06 22:28:46 +01:00
parent 880726305d
commit acf48c4c44
2 changed files with 28 additions and 17 deletions

View file

@ -15,6 +15,7 @@ export interface DS4ActorDataPropertiesDataBase {
combatValues: DS4ActorDataPropertiesDataCombatValues; combatValues: DS4ActorDataPropertiesDataCombatValues;
rolling: DS4ActorDataPropertiesDataRolling; rolling: DS4ActorDataPropertiesDataRolling;
checks: DS4ActorDataPropertiesDataChecks; checks: DS4ActorDataPropertiesDataChecks;
armorValueSpellMalus: number;
} }
type DS4ActorDataPropertiesDataAttributes = { type DS4ActorDataPropertiesDataAttributes = {

View file

@ -32,7 +32,7 @@ export class DS4Actor extends Actor {
this.data.reset(); this.data.reset();
this.prepareBaseData(); this.prepareBaseData();
this.prepareEmbeddedDocuments(); this.prepareEmbeddedDocuments();
this.applyActiveEffectsToItems(); this.prepareIntermediateData();
this.applyActiveEffectsToBaseData(); this.applyActiveEffectsToBaseData();
this.prepareDerivedData(); this.prepareDerivedData();
this.applyActiveEffectsToDerivedData(); this.applyActiveEffectsToDerivedData();
@ -58,7 +58,20 @@ export class DS4Actor extends Actor {
); );
} }
private get actorEffects() { override prepareEmbeddedDocuments() {
super.prepareEmbeddedDocuments();
this.applyActiveEffectsToItems();
}
/**
* Apply transformations to the Actor data after embedded documents have been prepared, but before effects have been
* applied to the Actor.
*/
prepareIntermediateData() {
this.data.data.armorValueSpellMalus = this.armorValueSpellMalusOfEquippedItems;
}
protected get actorEffects() {
return this.effects.filter((effect) => !effect.data.flags.ds4?.itemEffectConfig?.applyToItems); return this.effects.filter((effect) => !effect.data.flags.ds4?.itemEffectConfig?.applyToItems);
} }
@ -93,7 +106,7 @@ export class DS4Actor extends Actor {
}); });
} }
private static replaceFormulaData(formula: string, data: object): string | undefined { protected static replaceFormulaData(formula: string, data: object): string | undefined {
const dataRgx = new RegExp(/@([a-z.0-9_\-]+)/gi); const dataRgx = new RegExp(/@([a-z.0-9_\-]+)/gi);
try { try {
return formula.replace(dataRgx, (_, term) => { return formula.replace(dataRgx, (_, term) => {
@ -163,6 +176,7 @@ export class DS4Actor extends Actor {
* Apply transformations to the Actor data after effects have been applied to the base data. * Apply transformations to the Actor data after effects have been applied to the base data.
*/ */
override prepareDerivedData(): void { override prepareDerivedData(): void {
this.data.data.armorValueSpellMalus = Math.max(this.data.data.armorValueSpellMalus, 0);
this.prepareCombatValues(); this.prepareCombatValues();
this.prepareChecks(); this.prepareChecks();
} }
@ -232,20 +246,18 @@ export class DS4Actor extends Actor {
*/ */
protected prepareCombatValues(): void { protected prepareCombatValues(): void {
const data = this.data.data; const data = this.data.data;
const armorValueOfEquippedItems = this.calculateArmorValueOfEquippedItems();
const spellMalusOfEquippedItems = this.calculateSpellMaluesOfEquippedItems();
data.combatValues.hitPoints.base = data.attributes.body.total + data.traits.constitution.total + 10; data.combatValues.hitPoints.base = data.attributes.body.total + data.traits.constitution.total + 10;
data.combatValues.defense.base = data.combatValues.defense.base =
data.attributes.body.total + data.traits.constitution.total + armorValueOfEquippedItems; data.attributes.body.total + data.traits.constitution.total + this.armorValueOfEquippedItems;
data.combatValues.initiative.base = data.attributes.mobility.total + data.traits.agility.total; data.combatValues.initiative.base = data.attributes.mobility.total + data.traits.agility.total;
data.combatValues.movement.base = data.attributes.mobility.total / 2 + 1; data.combatValues.movement.base = data.attributes.mobility.total / 2 + 1;
data.combatValues.meleeAttack.base = data.attributes.body.total + data.traits.strength.total; data.combatValues.meleeAttack.base = data.attributes.body.total + data.traits.strength.total;
data.combatValues.rangedAttack.base = data.attributes.mobility.total + data.traits.dexterity.total; data.combatValues.rangedAttack.base = data.attributes.mobility.total + data.traits.dexterity.total;
data.combatValues.spellcasting.base = data.combatValues.spellcasting.base =
data.attributes.mind.total + data.traits.aura.total - spellMalusOfEquippedItems; data.attributes.mind.total + data.traits.aura.total - data.armorValueSpellMalus;
data.combatValues.targetedSpellcasting.base = data.combatValues.targetedSpellcasting.base =
data.attributes.mind.total + data.traits.dexterity.total - spellMalusOfEquippedItems; data.attributes.mind.total + data.traits.dexterity.total - data.armorValueSpellMalus;
Object.values(data.combatValues).forEach( Object.values(data.combatValues).forEach(
(combatValue: ModifiableDataBaseTotal<number>) => (combatValue.total = combatValue.base + combatValue.mod), (combatValue: ModifiableDataBaseTotal<number>) => (combatValue.total = combatValue.base + combatValue.mod),
@ -253,19 +265,17 @@ export class DS4Actor extends Actor {
} }
/** /**
* Calculates the total armor value of the equipped items. * The total armor value of the equipped items.
*/ */
protected calculateArmorValueOfEquippedItems(): number { protected get armorValueOfEquippedItems(): number {
return this.getEquippedItemsWithArmor() return this.equippedItemsWithArmor.map((item) => item.data.data.armorValue).reduce((a, b) => a + b, 0);
.map((item) => item.data.data.armorValue)
.reduce((a, b) => a + b, 0);
} }
/** /**
* Calculates the spell malus from equipped items. * The armor value spell malus from equipped items.
*/ */
protected calculateSpellMaluesOfEquippedItems(): number { protected get armorValueSpellMalusOfEquippedItems(): number {
return this.getEquippedItemsWithArmor() return this.equippedItemsWithArmor
.filter( .filter(
(item) => (item) =>
!(item.data.type === "armor" && ["cloth", "natural"].includes(item.data.data.armorMaterialType)), !(item.data.type === "armor" && ["cloth", "natural"].includes(item.data.data.armorMaterialType)),
@ -274,7 +284,7 @@ export class DS4Actor extends Actor {
.reduce((a, b) => a + b, 0); .reduce((a, b) => a + b, 0);
} }
private getEquippedItemsWithArmor() { protected get equippedItemsWithArmor() {
return this.items return this.items
.filter( .filter(
(item): item is DS4Item & { data: DS4ArmorDataProperties | DS4ShieldDataProperties } => (item): item is DS4Item & { data: DS4ArmorDataProperties | DS4ShieldDataProperties } =>