Renamed/structured resources/evasion/proficiency

This commit is contained in:
WBHarry 2025-06-01 18:22:29 +02:00
parent 84a41912a7
commit 84cdaab767
7 changed files with 69 additions and 132 deletions

View file

@ -210,9 +210,9 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
context.achievements = {
proficiency: {
old: this.actor.system.proficiency,
old: this.actor.system.proficiency.value,
new:
this.actor.system.proficiency +
this.actor.system.proficiency.value +
Object.values(this.levelup.allInitialAchievements).reduce(
(acc, x) => acc + x.proficiency,
0
@ -280,9 +280,9 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
Object.values(advancementChoices.proficiency ?? {}).reduce((acc, x) => acc + x.value, 0)
},
hitPoints: {
old: this.actor.system.resources.health.max,
old: this.actor.system.resources.hitPoints.max,
new:
this.actor.system.resources.health.max +
this.actor.system.resources.hitPoints.max +
Object.values(advancementChoices.hitPoint ?? {}).reduce((acc, x) => acc + x.value, 0)
},
stress: {

View file

@ -201,7 +201,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
context.storyEditor = this.storyEditor;
context.multiclassFeatureSetSelected = this.multiclassFeatureSetSelected;
const selectedAttributes = Object.values(this.document.system.traits).map(x => x.data.base);
const selectedAttributes = Object.values(this.document.system.traits).map(x => x.base);
context.abilityScoreArray = JSON.parse(
await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.AbilityArray)
).reduce((acc, x) => {
@ -492,7 +492,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
}
async attributeChange(event) {
const path = `system.traits.${event.currentTarget.dataset.attribute}.data.base`;
const path = `system.traits.${event.currentTarget.dataset.attribute}.base`;
await this.document.update({ [path]: event.currentTarget.value });
}
@ -557,8 +557,8 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
static async toggleHP(_, button) {
const healthValue = Number.parseInt(button.dataset.value);
const newValue = this.document.system.resources.health.value >= healthValue ? healthValue - 1 : healthValue;
await this.document.update({ 'system.resources.health.value': newValue });
const newValue = this.document.system.resources.hitPoints.value >= healthValue ? healthValue - 1 : healthValue;
await this.document.update({ 'system.resources.hitPoints.value': newValue });
}
static async toggleStress(_, button) {
@ -589,7 +589,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
type: weapon.system.damage.type,
bonusDamage: this.document.system.bonuses.damage
};
const modifier = this.document.system.traits[weapon.system.trait].data.value;
const modifier = this.document.system.traits[weapon.system.trait].value;
const { roll, hope, fear, advantage, disadvantage, modifiers, bonusDamageString } =
await this.document.dualityRoll(
@ -799,7 +799,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
}
static async makeDeathMove() {
if (this.document.system.resources.health.value === this.document.system.resources.health.max) {
if (this.document.system.resources.hitPoints.value === this.document.system.resources.hitPoints.max) {
await new DhpDeathMove(this.document).render(true);
await this.minimize();
}

View file

@ -5,26 +5,24 @@ const fields = foundry.data.fields;
const attributeField = () =>
new fields.SchemaField({
data: new fields.SchemaField({
bonus: new fields.NumberField({ initial: 0, integer: true }),
base: new fields.NumberField({ initial: 0, integer: true })
})
bonus: new fields.NumberField({ initial: 0, integer: true }),
base: new fields.NumberField({ initial: 0, integer: true })
});
const resourceField = max =>
new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
bonus: new fields.NumberField({ initial: 0, integer: true }),
min: new fields.NumberField({ initial: 0, integer: true }),
baseMax: new fields.NumberField({ initial: max, integer: true })
});
export default class DhpPC extends foundry.abstract.TypeDataModel {
static defineSchema() {
return {
resources: new fields.SchemaField({
health: new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
min: new fields.NumberField({ initial: 0, integer: true }),
max: new fields.NumberField({ initial: 6, integer: true })
}),
stress: new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
min: new fields.NumberField({ initial: 0, integer: true }),
max: new fields.NumberField({ initial: 6, integer: true })
}),
hitPoints: resourceField(6),
stress: resourceField(6),
hope: new fields.SchemaField({
value: new fields.NumberField({ initial: -1, integer: true }), // FIXME. Logic is gte and needs -1 in PC/Hope. Change to 0
min: new fields.NumberField({ initial: 0, integer: true })
@ -49,9 +47,12 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
presence: attributeField(),
knowledge: attributeField()
}),
proficiency: new fields.NumberField({ required: true, initial: 1, integer: true }),
proficiency: new fields.SchemaField({
base: new fields.NumberField({ required: true, initial: 1, integer: true }),
bonus: new fields.NumberField({ required: true, initial: 0, integer: true })
}),
evasion: new fields.SchemaField({
bonuses: new fields.NumberField({ initial: 0, integer: true })
bonus: new fields.NumberField({ initial: 0, integer: true })
}),
experiences: new fields.ArrayField(
new fields.SchemaField({
@ -98,12 +99,6 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
};
}
get canLevelUp() {
// return Object.values(this.levels.data).some(x => !x.completed);
// return this.levelData.currentLevel !== this.levelData.changedLevel;
return true;
}
get tier() {
return this.#getTier(this.levelData.currentLevel);
}
@ -236,42 +231,6 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
}
}
get inventoryWeapons() {
const inventoryWeaponFirst = this.parent.items.find(x => x.type === 'weapon' && x.system.inventoryWeapon === 1);
const inventoryWeaponSecond = this.parent.items.find(
x => x.type === 'weapon' && x.system.inventoryWeapon === 2
);
return {
first: this.#weaponData(inventoryWeaponFirst),
second: this.#weaponData(inventoryWeaponSecond)
};
}
// get totalAttributeMarks() {
// return Object.keys(this.levelData.levelups).reduce((nr, level) => {
// const nrAttributeMarks = Object.keys(this.levelData.levelups[level]).reduce((nr, tier) => {
// nr += Object.keys(this.levelData.levelups[level][tier]?.attributes ?? {}).length * 2;
// return nr;
// }, 0);
// nr.push(...Array(nrAttributeMarks).fill(Number.parseInt(level)));
// return nr;
// }, []);
// }
// get availableAttributeMarks() {
// const attributeMarks = Object.keys(this.attributes).flatMap(y => this.attributes[y].levelMarks);
// return this.totalAttributeMarks.reduce((acc, attribute) => {
// if (!attributeMarks.findSplice(x => x === attribute)) {
// acc.push(attribute);
// }
// return acc;
// }, []);
// }
get effects() {
return this.parent.items.reduce((acc, item) => {
const effects = item.system.effectData;
@ -322,19 +281,24 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
: null;
}
prepareBaseData() {
this.resources.hitPoints.max = this.resources.hitPoints.baseMax + this.resources.hitPoints.bonus;
this.resources.stress.max = this.resources.stress.baseMax + this.resources.stress.bonus;
this.evasion.value = (this.class?.system?.evasion ?? 0) + this.evasion.bonus;
this.proficiency.value = this.proficiency.base + this.proficiency.bonus;
for (var attributeKey in this.traits) {
const attribute = this.traits[attributeKey];
attribute.value = attribute.base + attribute.bonus;
}
}
prepareDerivedData() {
this.resources.hope.max = 6 - this.story.scars.length;
if (this.resources.hope.value >= this.resources.hope.max) {
this.resources.hope.value = Math.max(this.resources.hope.max - 1, 0);
}
for (var attributeKey in this.traits) {
const attribute = this.traits[attributeKey];
attribute.data.value = attribute.data.base + attribute.data.bonus;
}
this.evasion.value = (this.class?.system?.evasion ?? 0) + this.evasion.bonuses;
// this.armor.value = this.activeArmor?.baseScore ?? 0;
const armor = this.armor;
this.damageThresholds = {
major: armor
@ -345,29 +309,9 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
: this.levelData.level.current * 2
};
this.applyLevels();
this.applyEffects();
}
computeDamageThresholds() {
// TODO: missing weapon features and domain cards calculation
if (!this.armor) {
return {
major: this.levelData.currentLevel,
severe: this.levelData.currentLevel * 2
};
}
const {
baseThresholds: { major = 0, severe = 0 }
} = this.armor.system;
return {
major: major + this.levelData.currentLevel,
severe: severe + this.levelData.currentLevel
};
}
applyLevels() {}
applyEffects() {
const effects = this.effects;
for (var key in effects) {
@ -375,10 +319,10 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
for (var effect of effectType) {
switch (key) {
case SYSTEM.EFFECTS.effectTypes.health.id:
this.resources.health.max += effect.value.valueData.value;
this.resources.hitPoints.bonus += effect.value.valueData.value;
break;
case SYSTEM.EFFECTS.effectTypes.stress.id:
this.resources.stress.max += effect.value.valueData.value;
this.resources.stress.bonus += effect.value.valueData.value;
break;
case SYSTEM.EFFECTS.effectTypes.damage.id:
this.bonuses.damage.push({
@ -405,10 +349,6 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
return twoHanded ? 'twoHanded' : oneHanded ? 'oneHanded' : null;
}
isSameTier(level) {
return this.#getTier(this.levelData.currentLevel) === this.#getTier(level);
}
#getTier(level) {
if (level >= 8) return 3;
else if (level >= 5) return 2;

View file

@ -46,7 +46,7 @@ export default class DhpActor extends Actor {
}
var traitsUpdate = changes.traits.reduce((acc, trait) => {
acc[`${trait}.data.bonus`] = this.system.traits[trait].data.bonus - 1;
acc[`${trait}.bonus`] = this.system.traits[trait].bonus - 1;
return acc;
}, {});
@ -84,15 +84,15 @@ export default class DhpActor extends Actor {
'traits': traitsUpdate,
'experiences': experienceUpdate,
'resources': {
health: {
max: this.system.resources.health.max - changes.hitPoint
hitPoints: {
bonus: this.system.resources.hitPoints.bonus - changes.hitPoint
},
stress: {
max: this.system.resources.stress.max - changes.stress
bonus: this.system.resources.stress.bonus - changes.stress
}
},
'evasion.bonuses': this.system.evasion.bonuses - changes.evasion,
'proficiency': this.system.proficiency - changes.proficiency,
'evasion.bonus': this.system.evasion.bonus - changes.evasion,
'proficiency.bonus': this.system.proficiency.bonus - changes.proficiency,
'levelData': newLevelData
}
});
@ -191,7 +191,7 @@ export default class DhpActor extends Actor {
}
var traitsUpdate = changes.traits.reduce((acc, trait) => {
acc[`${trait}.data.bonus`] = this.system.traits[trait].data.bonus + 1;
acc[`${trait}.bonus`] = this.system.traits[trait].bonus + 1;
return acc;
}, {});
@ -222,15 +222,15 @@ export default class DhpActor extends Actor {
'traits': traitsUpdate,
'experiences': experienceUpdate,
'resources': {
health: {
max: this.system.resources.health.max + changes.hitPoint
hitPoints: {
bonus: this.system.resources.hitPoints.bonus + changes.hitPoint
},
stress: {
max: this.system.resources.stress.max + changes.stress
bonus: this.system.resources.stress.bonus + changes.stress
}
},
'evasion.bonuses': this.system.evasion.bonuses + changes.evasion,
'proficiency': this.system.proficiency + changes.proficiency,
'evasion.bonus': this.system.evasion.bonus + changes.evasion,
'proficiency.bonus': this.system.proficiency.bonus + changes.proficiency,
'levelData': {
'level.current': this.system.levelData.level.changed,
'levelups': levelupData
@ -462,9 +462,9 @@ export default class DhpActor extends Actor {
: 0;
const update = {
'system.resources.health.value': Math.min(
this.system.resources.health.value + hpDamage,
this.system.resources.health.max
'system.resources.hitPoints.value': Math.min(
this.system.resources.hitPoints.value + hpDamage,
this.system.resources.hitPoints.max
)
};
@ -487,9 +487,9 @@ export default class DhpActor extends Actor {
switch (type) {
case SYSTEM.GENERAL.healingTypes.health.id:
update = {
'system.resources.health.value': Math.min(
this.system.resources.health.value + healing,
this.system.resources.health.max
'system.resources.hitPoints.value': Math.min(
this.system.resources.hitPoints.value + healing,
this.system.resources.hitPoints.max
)
};
break;

View file

@ -103,7 +103,7 @@
<div class="form-group">
<label>{{localize "DAGGERHEART.Sheets.Adversary.HP"}}</label>
<div class="form-fields">
<input type="text" name="system.resources.health.max" value="{{source.system.resources.health.max}}" data-dtype="Number" />
<input type="text" name="system.resources.hitPoints.max" value="{{source.system.resources.hitPoints.max}}" data-dtype="Number" />
</div>
</div>
<div class="form-group">

View file

@ -7,22 +7,19 @@
{{#each this.attributes as |attribute key|}}
<div class="attribute">
<div class="attribute-banner">
<img class="attribute-roll" data-action="attributeRoll" data-attribute="{{key}}" data-value="{{attribute.data.value}}" src="icons/svg/d12-grey.svg" />
<img class="attribute-roll" data-action="attributeRoll" data-attribute="{{key}}" data-value="{{attribute.value}}" src="icons/svg/d12-grey.svg" />
<div class="attribute-text">{{key}}</div>
</div>
{{!-- <div class="attribute-mark {{#if (and (not attribute.levelMark) (and (not (includes attribute.levelMarks ../document.system.levelData.currentLevel)) (gt ../document.system.availableAttributeMarks.length 0)))}}selectable{{/if}}" data-action="toggleAttributeMark" data-attribute="{{key}}">
<i class="fa-solid fa-check {{#if attribute.levelMark}}selected{{/if}}"></i>
</div> --}}
<div class="attribute-image">
{{#if ../editAttributes}}
<select class="attribute-value{{#if (lt attribute.data.base 0)}} negative{{/if}}{{#if (and (not attribute.data.base) (not ../abilityScoresFinished))}} unselected{{/if}}" data-attribute="{{key}}">
{{#if (not (eq attribute.data.base 0))}}<option value="">{{attribute.data.base}}</option>{{/if}}
<select class="attribute-value{{#if (lt attribute.base 0)}} negative{{/if}}{{#if (and (not attribute.base) (not ../abilityScoresFinished))}} unselected{{/if}}" data-attribute="{{key}}">
{{#if (not (eq attribute.base 0))}}<option value="">{{attribute.base}}</option>{{/if}}
{{#each ../abilityScoreArray as |option|}}
<option value="{{option.value}}"{{#if (eq option.value attribute.data.base)}} selected="selected"{{/if}}>{{option.name}}</option>
<option value="{{option.value}}"{{#if (eq option.value attribute.base)}} selected="selected"{{/if}}>{{option.name}}</option>
{{/each}}
</select>
{{else}}
<div class="attribute-text {{#if (lt attribute.data.value 0)}}negative{{/if}}">{{attribute.data.value}}</div>
<div class="attribute-text {{#if (lt attribute.value 0)}}negative{{/if}}">{{attribute.value}}</div>
{{/if}}
<img src="systems/daggerheart/assets/AttributeShield.svg" />
<div>

View file

@ -21,7 +21,7 @@
<i class="fa-solid fa-caret-left"></i>
<div class="health-category">{{localize "DAGGERHEART.Sheets.PC.Health.Severe"}}</div>
</div>
<i data-action="makeDeathMove" class="fas fa-skull death-save {{#if (lt resources.health.value document.system.resources.health.max)}}disabled{{/if}}" title="{{localize "DAGGERHEART.Sheets.PC.Health.DeathMoveTooltip"}}"></i>
<i data-action="makeDeathMove" class="fas fa-skull death-save {{#if (lt resources.hitPoints.value document.system.resources.hitPoints.max)}}disabled{{/if}}" title="{{localize "DAGGERHEART.Sheets.PC.Health.DeathMoveTooltip"}}"></i>
</div>
<div class="flexrow" style="flex-wrap: nowrap; align-items: center;">
<div class="flexcol flex0">
@ -30,12 +30,12 @@
</div>
<div class="flexcol">
<div class="flexrow" style="flex-wrap: nowrap;">
{{#times document.system.resources.health.max}}
{{#times document.system.resources.hitPoints.max}}
{{#with (add this 1)}}
<input class="resource-box" type="checkbox" data-action="toggleHP" data-value="{{this}}" {{ checked (gte ../../document.system.resources.health.value this) }} />
<input class="resource-box" type="checkbox" data-action="toggleHP" data-value="{{this}}" {{ checked (gte ../../document.system.resources.hitPoints.value this) }} />
{{/with}}
{{/times}}
{{#times (subtract 12 document.system.resources.health.max)}}
{{#times (subtract 12 document.system.resources.hitPoints.max)}}
<input class="resource-box disabled" type="checkbox" disabled />
{{/times}}
</div>