actors datas max/total rework (#332)

* actors datas max/total rework

* Removed unused translation

---------

Co-authored-by: WBHarry <williambjrklund@gmail.com>
This commit is contained in:
Dapoulp 2025-07-13 18:39:23 +02:00 committed by GitHub
parent 687500f191
commit 0fd62c610d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 133 additions and 306 deletions

View file

@ -110,7 +110,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
? {
value:
this.actor.system.resources.stress.value + selectedStressMarks.length + stressReductionStress,
maxTotal: this.actor.system.resources.stress.maxTotal
max: this.actor.system.resources.stress.max
}
: null;
@ -197,7 +197,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
: 0;
const currentStress =
this.actor.system.resources.stress.value + selectedStressMarks.length + stressReductionStress;
if (currentStress + stressReduction.cost > this.actor.system.resources.stress.maxTotal) {
if (currentStress + stressReduction.cost > this.actor.system.resources.stress.max) {
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.notEnoughStress'));
return;
}

View file

@ -223,8 +223,8 @@ export default class DhCharacterLevelUp extends LevelUpBase {
context.achievements = {
proficiency: {
old: this.actor.system.proficiency.total,
new: this.actor.system.proficiency.total + achivementProficiency,
old: this.actor.system.proficiency,
new: this.actor.system.proficiency + achivementProficiency,
shown: achivementProficiency > 0
},
damageThresholds: {
@ -332,16 +332,16 @@ export default class DhCharacterLevelUp extends LevelUpBase {
new: context.achievements.proficiency.new + (advancement.proficiency ?? 0)
},
hitPoints: {
old: this.actor.system.resources.hitPoints.maxTotal,
new: this.actor.system.resources.hitPoints.maxTotal + (advancement.hitPoint ?? 0)
old: this.actor.system.resources.hitPoints.max,
new: this.actor.system.resources.hitPoints.max + (advancement.hitPoint ?? 0)
},
stress: {
old: this.actor.system.resources.stress.maxTotal,
new: this.actor.system.resources.stress.maxTotal + (advancement.stress ?? 0)
old: this.actor.system.resources.stress.max,
new: this.actor.system.resources.stress.max + (advancement.stress ?? 0)
},
evasion: {
old: this.actor.system.evasion.total,
new: this.actor.system.evasion.total + (advancement.evasion ?? 0)
old: this.actor.system.evasion,
new: this.actor.system.evasion + (advancement.evasion ?? 0)
}
},
traits: Object.keys(this.actor.system.traits).reduce((acc, traitKey) => {
@ -349,8 +349,8 @@ export default class DhCharacterLevelUp extends LevelUpBase {
if (!acc) acc = {};
acc[traitKey] = {
label: game.i18n.localize(abilities[traitKey].label),
old: this.actor.system.traits[traitKey].total,
new: this.actor.system.traits[traitKey].total + advancement.trait[traitKey]
old: this.actor.system.traits[traitKey].max,
new: this.actor.system.traits[traitKey].max + advancement.trait[traitKey]
};
}
return acc;

View file

@ -122,12 +122,12 @@ export default class DhCompanionLevelUp extends BaseLevelUp {
context.advancements = {
statistics: {
stress: {
old: this.actor.system.resources.stress.maxTotal,
new: this.actor.system.resources.stress.maxTotal + (advancement.stress ?? 0)
old: this.actor.system.resources.stress.max,
new: this.actor.system.resources.stress.max + (advancement.stress ?? 0)
},
evasion: {
old: this.actor.system.evasion.total,
new: this.actor.system.evasion.total + (advancement.evasion ?? 0)
old: this.actor.system.evasion,
new: this.actor.system.evasion + (advancement.evasion ?? 0)
}
},
experiences:

View file

@ -157,8 +157,8 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
context.achievements = {
proficiency: {
old: this.actor.system.proficiency.total,
new: this.actor.system.proficiency.total + achivementProficiency,
old: this.actor.system.proficiency,
new: this.actor.system.proficiency + achivementProficiency,
shown: achivementProficiency > 0
},
damageThresholds: {
@ -265,16 +265,16 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
new: context.achievements.proficiency.new + (advancement.proficiency ?? 0)
},
hitPoints: {
old: this.actor.system.resources.hitPoints.maxTotal,
new: this.actor.system.resources.hitPoints.maxTotal + (advancement.hitPoint ?? 0)
old: this.actor.system.resources.hitPoints.max,
new: this.actor.system.resources.hitPoints.max + (advancement.hitPoint ?? 0)
},
stress: {
old: this.actor.system.resources.stress.maxTotal,
new: this.actor.system.resources.stress.maxTotal + (advancement.stress ?? 0)
old: this.actor.system.resources.stress.max,
new: this.actor.system.resources.stress.max + (advancement.stress ?? 0)
},
evasion: {
old: this.actor.system.evasion.total,
new: this.actor.system.evasion.total + (advancement.evasion ?? 0)
old: this.actor.system.evasion,
new: this.actor.system.evasion + (advancement.evasion ?? 0)
}
},
traits: Object.keys(this.actor.system.traits).reduce((acc, traitKey) => {
@ -282,8 +282,8 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
if (!acc) acc = {};
acc[traitKey] = {
label: game.i18n.localize(abilities[traitKey].label),
old: this.actor.system.traits[traitKey].total,
new: this.actor.system.traits[traitKey].total + advancement.trait[traitKey]
old: this.actor.system.traits[traitKey].value,
new: this.actor.system.traits[traitKey].value + advancement.trait[traitKey]
};
}
return acc;

View file

@ -93,7 +93,7 @@ export default class AdversarySheet extends DHBaseActorSheet {
const cls = getDocumentClass('ChatMessage');
const systemData = {
name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'),
description: `${experience.name} ${experience.total.signedString()}`
description: `${experience.name} ${experience.value.signedString()}`
};
const msg = new cls({
type: 'abilityUse',

View file

@ -650,7 +650,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
const cls = getDocumentClass('ChatMessage');
const systemData = {
name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'),
description: `${experience.name} ${experience.total < 0 ? experience.total : `+${experience.total}`}`
description: `${experience.name} ${experience.value.signedString()}`
};
const msg = new cls({
type: 'abilityUse',

View file

@ -59,7 +59,7 @@ export default class DhCompanionSheet extends DHBaseActorSheet {
const cls = getDocumentClass('ChatMessage');
const systemData = {
name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'),
description: `${experience.name} ${experience.total < 0 ? experience.total : `+${experience.total}`}`
description: `${experience.name} ${experience.value.signedString()}`
};
const msg = new cls({
type: 'abilityUse',

View file

@ -41,37 +41,37 @@ export const armorFeatures = {
img: 'icons/magic/control/buff-flight-wings-red.webp',
changes: [
{
key: 'system.traits.agility.bonus',
key: 'system.traits.agility.value',
mode: 2,
value: '-1'
},
{
key: 'system.traits.strength.bonus',
key: 'system.traits.strength.value',
mode: 2,
value: '-1'
},
{
key: 'system.traits.finesse.bonus',
key: 'system.traits.finesse.value',
mode: 2,
value: '-1'
},
{
key: 'system.traits.instinct.bonus',
key: 'system.traits.instinct.value',
mode: 2,
value: '-1'
},
{
key: 'system.traits.presence.bonus',
key: 'system.traits.presence.value',
mode: 2,
value: '-1'
},
{
key: 'system.traits.knowledge.bonus',
key: 'system.traits.knowledge.value',
mode: 2,
value: '-1'
},
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '-1'
}
@ -89,7 +89,7 @@ export const armorFeatures = {
img: 'icons/magic/movement/abstract-ribbons-red-orange.webp',
changes: [
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '1'
}
@ -125,7 +125,7 @@ export const armorFeatures = {
img: 'icons/magic/control/control-influence-crown-gold.webp',
changes: [
{
key: 'system.traits.presence.bonus',
key: 'system.traits.presence.value',
mode: 2,
value: '1'
}
@ -143,7 +143,7 @@ export const armorFeatures = {
img: 'icons/commodities/metal/ingot-worn-iron.webp',
changes: [
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '-1'
}
@ -372,12 +372,12 @@ export const armorFeatures = {
img: 'icons/commodities/metal/ingot-stamped-steel.webp',
changes: [
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '-2'
},
{
key: 'system.traits.agility.bonus',
key: 'system.traits.agility.value',
mode: 2,
value: '-1'
}
@ -413,7 +413,7 @@ export const weaponFeatures = {
{
changes: [
{
key: 'system.bonuses.armorScore',
key: 'system.armorScore',
mode: 2,
value: 'ITEM.@system.tier + 1'
}
@ -422,7 +422,7 @@ export const weaponFeatures = {
{
changes: [
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '-1'
}
@ -474,7 +474,7 @@ export const weaponFeatures = {
{
changes: [
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '-1'
}
@ -529,7 +529,7 @@ export const weaponFeatures = {
img: 'icons/magic/lightning/claws-unarmed-strike-teal.webp',
changes: [
{
key: 'system.proficiency.bonus',
key: 'system.proficiency',
mode: 2,
value: '1'
}
@ -569,7 +569,7 @@ export const weaponFeatures = {
img: 'icons/commodities/metal/mail-plate-steel.webp',
changes: [
{
key: 'system.traits.finesse.bonus',
key: 'system.traits.finesse.value',
mode: 2,
value: '-1'
}
@ -615,7 +615,7 @@ export const weaponFeatures = {
img: 'icons/skills/melee/hand-grip-sword-strike-orange.webp',
changes: [
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '@system.armorScore'
}
@ -645,7 +645,7 @@ export const weaponFeatures = {
img: 'icons/skills/melee/strike-flail-spiked-pink.webp',
changes: [
{
key: 'system.traits.agility.bonus',
key: 'system.traits.agility.value',
mode: 2,
value: '-1'
}
@ -683,7 +683,7 @@ export const weaponFeatures = {
img: 'icons/skills/melee/sword-shield-stylized-white.webp',
changes: [
{
key: 'system.bonuses.armorScore',
key: 'system.armorScore',
mode: 2,
value: '1'
},
@ -777,7 +777,7 @@ export const weaponFeatures = {
img: 'icons/commodities/currency/coins-crown-stack-gold.webp',
changes: [
{
key: 'system.proficiency.bonus',
key: 'system.proficiency',
mode: 2,
value: '1'
}
@ -819,7 +819,7 @@ export const weaponFeatures = {
img: 'icons/commodities/metal/ingot-worn-iron.webp',
changes: [
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '-1'
}
@ -941,7 +941,7 @@ export const weaponFeatures = {
img: '',
changes: [
{
key: 'system.evasion.bonus',
key: 'system.evasion',
mode: 2,
value: '-1'
},
@ -1031,7 +1031,7 @@ export const weaponFeatures = {
img: 'icons/magic/control/hypnosis-mesmerism-eye.webp',
changes: [
{
key: 'system.traits.presence.bonus',
key: 'system.traits.presence.value',
mode: 2,
value: '2'
}
@ -1088,7 +1088,7 @@ export const weaponFeatures = {
img: 'icons/skills/melee/shield-block-gray-orange.webp',
changes: [
{
key: 'system.bonuses.armorScore',
key: 'system.armorScore',
mode: 2,
value: '1'
}
@ -1218,7 +1218,7 @@ export const weaponFeatures = {
{
key: 'system.bonuses.damage.primaryWeapon.bonus',
mode: 2,
value: '@system.traits.agility.total'
value: '@system.traits.agility.value'
}
]
}

View file

@ -331,7 +331,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
.filter(c => c.enabled !== false)
.map(c => {
const resource = this.actor.system.resources[c.type];
return { type: c.type, value: (c.total ?? c.value) * (resource.hasOwnProperty('maxTotal') ? 1 : -1) };
return { type: c.type, value: (c.total ?? c.value) * (resource.isReversed ? 1 : -1) };
});
await this.actor.modifyResource(resources);
@ -384,12 +384,12 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
return false;
}
/* maxTotal is a sign that the resource is inverted, IE it counts upwards instead of down */
/* isReversed is a sign that the resource is inverted, IE it counts upwards instead of down */
const resources = this.actor.system.resources;
return realCosts.reduce(
(a, c) =>
a && resources[c.type].hasOwnProperty('maxTotal')
? resources[c.type].value + (c.total ?? c.value) <= resources[c.type].maxTotal
a && resources[c.type].isReversed
? resources[c.type].value + (c.total ?? c.value) <= resources[c.type].max
: resources[c.type]?.value >= (c.total ?? c.value),
true
);
@ -432,7 +432,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
name: actor.actor.name,
img: actor.actor.img,
difficulty: actor.actor.system.difficulty,
evasion: actor.actor.system.evasion?.total
evasion: actor.actor.system.evasion
};
}
/* TARGET */

View file

@ -5,8 +5,8 @@ import BaseDataActor from './base.mjs';
const resourceField = () =>
new foundry.data.fields.SchemaField({
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
max: new foundry.data.fields.NumberField({ initial: 0, integer: true })
max: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
isReversed: new foundry.data.fields.BooleanField({ initial: true })
});
export default class DhpAdversary extends BaseDataActor {
@ -76,7 +76,7 @@ export default class DhpAdversary extends BaseDataActor {
experiences: new fields.TypedObjectField(
new fields.SchemaField({
name: new fields.StringField(),
total: new fields.NumberField({ required: true, integer: true, initial: 1 })
value: new fields.NumberField({ required: true, integer: true, initial: 1 })
})
),
bonuses: new fields.SchemaField({
@ -95,9 +95,4 @@ export default class DhpAdversary extends BaseDataActor {
get features() {
return this.parent.items.filter(x => x.type === 'feature');
}
prepareDerivedData() {
this.resources.hitPoints.maxTotal = this.resources.hitPoints.max + this.resources.hitPoints.bonus;
this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus;
}
}

View file

@ -5,16 +5,15 @@ import BaseDataActor from './base.mjs';
const attributeField = () =>
new foundry.data.fields.SchemaField({
value: new foundry.data.fields.NumberField({ initial: null, integer: true }),
bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
tierMarked: new foundry.data.fields.BooleanField({ initial: false })
});
const resourceField = max =>
const resourceField = (max, reverse = false) =>
new foundry.data.fields.SchemaField({
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
max: new foundry.data.fields.NumberField({ initial: max, integer: true })
max: new foundry.data.fields.NumberField({ initial: max, integer: true }),
isReversed: new foundry.data.fields.BooleanField({ initial: reverse })
});
const stressDamageReductionRule = () =>
@ -38,11 +37,8 @@ export default class DhCharacter extends BaseDataActor {
return {
...super.defineSchema(),
resources: new fields.SchemaField({
hitPoints: new fields.SchemaField({
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true })
}),
stress: resourceField(6),
hitPoints: resourceField(0, true),
stress: resourceField(6, true),
hope: resourceField(6),
tokens: new fields.ObjectField(),
dice: new fields.ObjectField()
@ -55,18 +51,17 @@ export default class DhCharacter extends BaseDataActor {
presence: attributeField(),
knowledge: attributeField()
}),
proficiency: new fields.SchemaField({
value: new fields.NumberField({ initial: 1, integer: true }),
bonus: new fields.NumberField({ initial: 0, integer: true })
}),
evasion: new fields.SchemaField({
bonus: new fields.NumberField({ initial: 0, integer: true })
proficiency: new fields.NumberField({ initial: 1, integer: true }),
evasion: new fields.NumberField({ initial: 0, integer: true }),
armorScore: new fields.NumberField({ integer: true, initial: 0 }),
damageThresholds: new fields.SchemaField({
severe: new fields.NumberField({ integer: true, initial: 0 }),
major: new fields.NumberField({ integer: true, initial: 0 })
}),
experiences: new fields.TypedObjectField(
new fields.SchemaField({
name: new fields.StringField(),
value: new fields.NumberField({ integer: true, initial: 0 }),
bonus: new fields.NumberField({ integer: true, initial: 0 })
value: new fields.NumberField({ integer: true, initial: 0 })
})
),
gold: new fields.SchemaField({
@ -100,11 +95,6 @@ export default class DhCharacter extends BaseDataActor {
}),
levelData: new fields.EmbeddedDataField(DhLevelData),
bonuses: new fields.SchemaField({
armorScore: new fields.NumberField({ integer: true, initial: 0 }),
damageThresholds: new fields.SchemaField({
severe: new fields.NumberField({ integer: true, initial: 0 }),
major: new fields.NumberField({ integer: true, initial: 0 })
}),
roll: new fields.SchemaField({
attack: new fields.NumberField({ integer: true, initial: 0 }),
primaryWeapon: new fields.SchemaField({
@ -303,7 +293,7 @@ export default class DhCharacter extends BaseDataActor {
get deathMoveViable() {
return (
this.resources.hitPoints.maxTotal > 0 && this.resources.hitPoints.value >= this.resources.hitPoints.maxTotal
this.resources.hitPoints.max > 0 && this.resources.hitPoints.value >= this.resources.hitPoints.max
);
}
@ -347,32 +337,32 @@ export default class DhCharacter extends BaseDataActor {
for (let levelKey in this.levelData.levelups) {
const level = this.levelData.levelups[levelKey];
this.proficiency.bonus += level.achievements.proficiency;
this.proficiency += level.achievements.proficiency;
for (let selection of level.selections) {
switch (selection.type) {
case 'trait':
selection.data.forEach(data => {
this.traits[data].bonus += 1;
this.traits[data].value += 1;
this.traits[data].tierMarked = selection.tier === currentTier;
});
break;
case 'hitPoint':
this.resources.hitPoints.bonus += selection.value;
this.resources.hitPoints.max += selection.value;
break;
case 'stress':
this.resources.stress.bonus += selection.value;
this.resources.stress.max += selection.value;
break;
case 'evasion':
this.evasion.bonus += selection.value;
this.evasion += selection.value;
break;
case 'proficiency':
this.proficiency.bonus = selection.value;
this.proficiency = selection.value;
break;
case 'experience':
Object.keys(this.experiences).forEach(key => {
const experience = this.experiences[key];
experience.bonus += selection.value;
experience.value += selection.value;
});
break;
}
@ -380,7 +370,7 @@ export default class DhCharacter extends BaseDataActor {
}
const armor = this.armor;
this.armorScore = this.armor ? this.armor.system.baseScore + (this.bonuses.armorScore ?? 0) : 0; // Bonuses to armorScore won't have been applied yet. Need to solve in documentPreparation somehow
this.armorScore = armor ? armor.system.baseScore : 0;
this.damageThresholds = {
major: armor
? armor.system.baseThresholds.major + this.levelData.level.current
@ -389,29 +379,12 @@ export default class DhCharacter extends BaseDataActor {
? armor.system.baseThresholds.severe + this.levelData.level.current
: this.levelData.level.current * 2
};
this.resources.hope.max -= Object.keys(this.scars).length;
this.resources.hitPoints.max = this.class.value?.system?.hitPoints ?? 0;
}
prepareDerivedData() {
this.resources.hope.max -= Object.keys(this.scars).length;
this.resources.hope.value = Math.min(this.resources.hope.value, this.resources.hope.max);
for (var traitKey in this.traits) {
var trait = this.traits[traitKey];
trait.total = (trait.value ?? 0) + trait.bonus;
}
for (var experienceKey in this.experiences) {
var experience = this.experiences[experienceKey];
experience.total = experience.value + experience.bonus;
}
this.rules.damageReduction.maxArmorMarked.total =
this.rules.damageReduction.maxArmorMarked.value + this.rules.damageReduction.maxArmorMarked.bonus;
this.resources.hitPoints.maxTotal = (this.class.value?.system?.hitPoints ?? 0) + this.resources.hitPoints.bonus;
this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus;
this.evasion.total = (this.class?.evasion ?? 0) + this.evasion.bonus;
this.proficiency.total = this.proficiency.value + this.proficiency.bonus;
}
getRollData() {

View file

@ -25,20 +25,16 @@ export default class DhCompanion extends BaseDataActor {
resources: new fields.SchemaField({
stress: new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
bonus: new fields.NumberField({ initial: 0, integer: true }),
max: new fields.NumberField({ initial: 3, integer: true })
max: new fields.NumberField({ initial: 3, integer: true }),
isReversed: new foundry.data.fields.BooleanField({ initial: true })
}),
hope: new fields.NumberField({ initial: 0, integer: true })
}),
evasion: new fields.SchemaField({
value: new fields.NumberField({ required: true, min: 1, initial: 10, integer: true }),
bonus: new fields.NumberField({ initial: 0, integer: true })
}),
evasion: new fields.NumberField({ required: true, min: 1, initial: 10, integer: true }),
experiences: new fields.TypedObjectField(
new fields.SchemaField({
name: new fields.StringField({}),
value: new fields.NumberField({ integer: true, initial: 0 }),
bonus: new fields.NumberField({ integer: true, initial: 0 })
value: new fields.NumberField({ integer: true, initial: 0 })
}),
{
initial: {
@ -84,19 +80,17 @@ export default class DhCompanion extends BaseDataActor {
get traits() {
return {
instinct: { total: this.attack.roll.bonus }
instinct: { value: this.attack.roll.bonus }
};
}
get proficiency() {
return {
total: this.partner?.system?.proficiency?.total ?? 1
};
return this.partner?.system?.proficiency ?? 1;
}
prepareBaseData() {
const partnerSpellcastingModifier = this.partner?.system?.spellcastingModifiers?.main;
const spellcastingModifier = this.partner?.system?.traits?.[partnerSpellcastingModifier]?.total;
const spellcastingModifier = this.partner?.system?.traits?.[partnerSpellcastingModifier]?.value;
this.attack.roll.bonus = spellcastingModifier ?? 0; // Needs to expand on which modifier it is that should be used because of multiclassing;
for (let levelKey in this.levelData.levelups) {
@ -114,15 +108,15 @@ export default class DhCompanion extends BaseDataActor {
}
break;
case 'stress':
this.resources.stress.bonus += selection.value;
this.resources.stress.max += selection.value;
break;
case 'evasion':
this.evasion.bonus += selection.value;
this.evasion += selection.value;
break;
case 'experience':
Object.keys(this.experiences).forEach(key => {
const experience = this.experiences[key];
experience.bonus += selection.value;
experience.value += selection.value;
});
break;
}
@ -131,17 +125,9 @@ export default class DhCompanion extends BaseDataActor {
}
prepareDerivedData() {
for (var experienceKey in this.experiences) {
var experience = this.experiences[experienceKey];
experience.total = experience.value + experience.bonus;
}
if (this.partner) {
this.partner.system.resources.hope.max += this.resources.hope;
}
this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus;
this.evasion.total = this.evasion.value + this.evasion.bonus;
}
async _preDelete() {

View file

@ -32,9 +32,9 @@ export default class DHSubclass extends BaseDataItem {
get features() {
return [
{ ...this.foundationFeature.toObject(), identifier: 'foundationFeature' },
{ ...this.specializationFeature.toObject(), identifier: 'specializationFeature' },
{ ...this.masteryFeature.toObject(), identifier: 'masteryFeature' }
{ ...this.foundationFeature?.toObject(), identifier: 'foundationFeature' },
{ ...this.specializationFeature?.toObject(), identifier: 'specializationFeature' },
{ ...this.masteryFeature?.toObject(), identifier: 'masteryFeature' }
];
}

View file

@ -97,7 +97,7 @@ export default class D20Roll extends DHRoll {
if (this.options.data.experiences?.[m])
this.options.roll.modifiers.push({
label: this.options.data.experiences[m].name,
value: this.options.data.experiences[m].total ?? this.options.data.experiences[m].value
value: this.options.data.experiences[m].value
});
});

View file

@ -123,7 +123,7 @@ export default class DualityRoll extends D20Roll {
if (!this.options.roll.trait) return;
this.options.roll.modifiers.push({
label: `DAGGERHEART.CONFIG.Traits.${this.options.roll.trait}.name`,
value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data)
value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.value`, this.data)
});
}

View file

@ -371,96 +371,13 @@ export default class DhpActor extends Actor {
getRollData() {
const rollData = super.getRollData();
rollData.prof = this.system.proficiency?.total ?? 1;
rollData.cast = this.system.spellcast?.total ?? 1;
rollData.prof = this.system.proficiency ?? 1;
rollData.cast = this.system.spellcast ?? 1;
return rollData;
}
formatRollModifier(roll) {
const modifier = roll.modifier !== null ? Number.parseInt(roll.modifier) : null;
return modifier !== null
? [
{
value: modifier,
label: roll.label
? modifier >= 0
? `${roll.label} +${modifier}`
: `${roll.label} ${modifier}`
: null,
title: roll.label
}
]
: [];
}
async damageRoll(title, damage, targets, shiftKey) {
let rollString = damage.value;
let bonusDamage = damage.bonusDamage?.filter(x => x.initiallySelected) ?? [];
if (!shiftKey) {
const dialogClosed = new Promise((resolve, _) => {
new DamageSelectionDialog(rollString, bonusDamage, resolve).render(true);
});
const result = await dialogClosed;
bonusDamage = result.bonusDamage;
rollString = result.rollString;
const automateHope = await game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation.Hope);
if (automateHope && result.hopeUsed) {
await this.update({
'system.resources.hope.value': this.system.resources.hope.value - result.hopeUsed
});
}
}
const roll = new Roll(rollString);
let rollResult = await roll.evaluate();
const dice = [];
const modifiers = [];
for (var i = 0; i < rollResult.terms.length; i++) {
const term = rollResult.terms[i];
if (term.faces) {
dice.push({
type: `d${term.faces}`,
rolls: term.results.map(x => x.result),
total: term.results.reduce((acc, x) => acc + x.result, 0)
});
} else if (term.operator) {
} else if (term.number) {
const operator = i === 0 ? '' : rollResult.terms[i - 1].operator;
modifiers.push({ value: term.number, operator: operator });
}
}
const cls = getDocumentClass('ChatMessage');
const systemData = {
title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: title }),
roll: rollString,
damage: {
total: rollResult.total,
type: damage.type
},
dice: dice,
modifiers: modifiers,
targets: targets
};
const msg = new cls({
type: 'damageRoll',
user: game.user.id,
sound: CONFIG.sounds.dice,
system: systemData,
content: await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/ui/chat/damage-roll.hbs',
systemData
),
rolls: [roll]
});
cls.create(msg.toObject());
}
#canReduceDamage(hpDamage, type) {
const availableStress = this.system.resources.stress.maxTotal - this.system.resources.stress.value;
const availableStress = this.system.resources.stress.max - this.system.resources.stress.value;
const canUseArmor =
this.system.armor &&
@ -568,7 +485,7 @@ export default class DhpActor extends Actor {
updates.actor.resources[`system.resources.${r.type}.value`] = Math.max(
Math.min(
this.system.resources[r.type].value + r.value,
this.system.resources[r.type].maxTotal ?? this.system.resources[r.type].max
this.system.resources[r.type].max
),
0
);
@ -600,7 +517,7 @@ export default class DhpActor extends Actor {
convertStressDamageToHP(resources) {
const stressDamage = resources.find(r => r.type === 'stress'),
newValue = this.system.resources.stress.value + stressDamage.value;
if (newValue <= this.system.resources.stress.maxTotal) return;
if (newValue <= this.system.resources.stress.max) return;
const hpDamage = resources.find(r => r.type === 'hitPoints');
if (hpDamage) hpDamage.value++;
else

View file

@ -28,7 +28,7 @@ export default class RegisterHandlebarsHelpers {
}
static damageFormula(attack, actor) {
const traitTotal = actor.system.traits?.[attack.roll.trait]?.total;
const traitTotal = actor.system.traits?.[attack.roll.trait]?.value;
const instances = [
attack.damage.parts.map(x => Roll.replaceFormulaData(x.value.getFormula(), actor)).join(' + '),
traitTotal