Merge branch 'armor-value-spell-bonus' into 'main'
feat: make it possible to affect the armor value spell malus with Active Effects See merge request dungeonslayers/ds4!217
This commit is contained in:
commit
e814bd24e1
3 changed files with 29 additions and 18 deletions
|
@ -7,7 +7,7 @@
|
||||||
.ds4-checks {
|
.ds4-checks {
|
||||||
column-gap: 2em;
|
column-gap: 2em;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(11em, 1fr));
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
row-gap: 0.25em;
|
row-gap: 0.25em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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 } =>
|
||||||
|
|
Loading…
Reference in a new issue