[Feature] Death moves and Fate rolls (#1463)

* Update the death move descriptions

* Renamed to DhDeathMove

* Partial Fate Roll creation and Fate Roll Enricher (/fr)

* Hide stuff not required for fate roll

* Hide formula display; code removal; start to add Fear die as a choice for Fate roll

* Fix chat message display; start moving towards supporting Hope and Fear for Fate roll

* /fr now supports type=X, where X is Hope or Fear, if not supplied, defaults to Hope

* Fixed DSN rolling; removed console messages; chat message clean up

* Add localisation entry

* Trying to sort out the button for the fate roll

* Style the fate message based on Hope/Fear colors.

* Partial improvement on the fate template buttons - chat display is correct, but the roll dialog is wrong

* Fixed enricher button; localization fixes; debug cleanup

* Error checking for the fate type parsing in all potential problem locations

* Added localization for the fate type parsing error

* Start on Avoid Death death move

* debug stuff

* More death moves setup/testing

* Avoid fate scars update in place, with scars migrating to an integer value.

* Remove some debug code; add Blaze Of Glory shell

* Start on Guaranteed Critical for Blaze of Glory

* Partial implementation of Blaze of Glory

* Dice/critical checks/tests

* Moved detection of guaranteed critical to before the roll dialog is created, so it can be skipped; removed debug code

* Remove debug

* Update Blaze of Glory effect description

* Risk It All - critical roll - clear all stress and HP

* Auto remove all marked stress and HP for Risk It All, if Hope value rolled covers it.

* Display the Death Move description in chat expanded if the appropriate config setting is on

* Made the Blaze of Glory ActiveEffect image use configured version

* Update the current Hope value if the scar value change affects it

* Scars management in the Character details editor

* Separate less file for the Death Moves instead of reusing Downtime

* Added result messages to the Death Move chat output and removed debug statements

* Some localization, style and smaller changes

* Fixed RiskItAll resource handling method

* Risk It All success chat message start

* [Add] Hope/Scar Interplay (#1531)

* Migrated character.maxHope to homebrew settings

* Added a visual for scars

* .

* .

* Pass the hope value in the button data; skeleton risk it all dialog to fill out.

* Start on risk it dialog

* More dialog stuff

* Remove non-existent field

* Dialog templating and logic

* .

* Ensure effect is Applied to Actor (#1547)

Co-authored-by: Chris Ryan <chrisr@blackhole>

* [Fix] 1548 - Standalone Item Add Actions (#1549)

* Fixed so that items not on an actor don't error out on creating actions

* Fixed deletion of items error

* Raised version

* Fix the sliders to do the correct maximums

* Pass the actor id through the button; fix /dr and /fr flavor text

* Remove debug message

---------

Co-authored-by: Chris Ryan <chrisr@blackhole>
Co-authored-by: WBHarry <williambjrklund@gmail.com>
Co-authored-by: WBHarry <89362246+WBHarry@users.noreply.github.com>
This commit is contained in:
Chris Ryan 2026-01-18 00:11:50 +10:00 committed by GitHub
parent 3103a40c26
commit 9d75157e17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 1166 additions and 258 deletions

View file

@ -376,14 +376,14 @@ export class ResourceUpdateMap extends Map {
if (!resource.key) continue;
const existing = this.get(resource.key);
if (existing) {
if (!existing || resource.clear) {
this.set(resource.key, resource);
} else if (!existing?.clear) {
this.set(resource.key, {
...existing,
value: existing.value + (resource.value ?? 0),
total: existing.total + (resource.total ?? 0)
});
} else {
this.set(resource.key, resource);
}
}
}

View file

@ -35,7 +35,14 @@ export default class DhCharacter extends BaseDataActor {
'DAGGERHEART.ACTORS.Character.maxHPBonus'
),
stress: resourceField(6, 0, 'DAGGERHEART.GENERAL.stress', true),
hope: resourceField(6, 2, 'DAGGERHEART.GENERAL.hope')
hope: new fields.SchemaField({
value: new fields.NumberField({
initial: 2,
min: 0,
integer: true,
label: 'DAGGERHEART.GENERAL.hope'
})
})
}),
traits: new fields.SchemaField({
agility: attributeField('DAGGERHEART.CONFIG.Traits.agility.name'),
@ -78,12 +85,7 @@ export default class DhCharacter extends BaseDataActor {
bags: new fields.NumberField({ initial: 0, integer: true }),
chests: new fields.NumberField({ initial: 0, integer: true })
}),
scars: new fields.TypedObjectField(
new fields.SchemaField({
name: new fields.StringField({}),
description: new fields.StringField()
})
),
scars: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.scars' }),
biography: new fields.SchemaField({
background: new fields.HTMLField(),
connections: new fields.HTMLField(),
@ -301,6 +303,9 @@ export default class DhCharacter extends BaseDataActor {
runeWard: new fields.BooleanField({ initial: false }),
burden: new fields.SchemaField({
ignore: new fields.BooleanField()
}),
roll: new fields.SchemaField({
guaranteedCritical: new fields.BooleanField()
})
})
};
@ -642,7 +647,9 @@ 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;
const globalHopeMax = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxHope;
this.resources.hope.max = globalHopeMax - this.scars;
this.resources.hitPoints.max += this.class.value?.system?.hitPoints ?? 0;
}
@ -699,6 +706,20 @@ export default class DhCharacter extends BaseDataActor {
changes.system.experiences[experience].core = true;
}
}
/* Scars can alter the amount of current hope */
if (changes.system?.scars) {
const diff = this.system.scars - changes.system.scars;
const newHopeMax = this.system.resources.hope.max + diff;
const newHopeValue = Math.min(newHopeMax, this.system.resources.hope.value);
if (newHopeValue != this.system.resources.hope.value) {
if (!changes.system.resources) changes.system.resources = { hope: { value: 0 } };
changes.system.resources.hope = {
...changes.system.resources.hope,
value: changes.system.resources.hope.value + newHopeValue
};
}
}
}
async _preDelete() {
@ -714,4 +735,11 @@ export default class DhCharacter extends BaseDataActor {
t => !!t
);
}
static migrateData(source) {
if (typeof source.scars === 'object') source.scars = 0;
if (source.resources?.hope?.max) source.scars = Math.max(6 - source.resources.hope.max, 0);
return super.migrateData(source);
}
}

View file

@ -8,6 +8,7 @@ export const config = {
adversaryRoll: DHActorRoll,
damageRoll: DHActorRoll,
dualityRoll: DHActorRoll,
fateRoll: DHActorRoll,
groupRoll: DHGroupRoll,
systemMessage: DHSystemMessage
};

View file

@ -23,6 +23,13 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
initial: 12,
label: 'DAGGERHEART.SETTINGS.Homebrew.FIELDS.maxFear.label'
}),
maxHope: new fields.NumberField({
required: true,
integer: true,
min: 0,
initial: 6,
label: 'DAGGERHEART.SETTINGS.Homebrew.FIELDS.maxHope.label'
}),
maxLoadout: new fields.NumberField({
required: true,
integer: true,