[Feature] DeathMove Condition Improvement (#1562)

* Added DeathMove condition and automated changing to the correct condition depending on the result of death moves

* .

* Update module/data/settings/Automation.mjs

Co-authored-by: Chris Ryan <73275196+chrisryan10@users.noreply.github.com>

* Update lang/en.json

Co-authored-by: Chris Ryan <73275196+chrisryan10@users.noreply.github.com>

* Fixed DefeatedCondition localizations

---------

Co-authored-by: Chris Ryan <73275196+chrisryan10@users.noreply.github.com>
This commit is contained in:
WBHarry 2026-01-20 11:03:52 +01:00 committed by GitHub
parent 77bac647a8
commit cc998bffa7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 60 additions and 15 deletions

View file

@ -54,10 +54,9 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
if (!config.roll.fate) return;
let returnMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.avoidScar');
if (config.roll.fate.value <= this.actor.system.levelData.level.current) {
// apply scarring - for now directly apply - later add a button.
const newScarAmount = this.actor.system.scars + 1;
await this.actor.update({
system: {
scars: newScarAmount
@ -65,13 +64,15 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
});
if (newScarAmount >= this.actor.system.resources.hope.max) {
await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.dead.id);
return game.i18n.format('DAGGERHEART.UI.Chat.deathMove.journeysEnd', { scars: newScarAmount });
}
return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.gainScar');
returnMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.gainScar');
}
return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.avoidScar');
await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.unconscious.id);
return returnMessage;
}
async handleRiskItAll() {
@ -118,6 +119,7 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
}
if (config.roll.result.duality == -1) {
await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.dead.id);
chatMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.riskItAllFailure');
}
@ -141,6 +143,7 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
}
]);
await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.dead.id);
return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.blazeOfGlory');
}

View file

@ -171,7 +171,7 @@ export const defeatedConditions = () => {
acc[key] = {
...choice,
img: defeated[`${choice.id}Icon`],
description: `DAGGERHEART.CONFIG.Condition.${choice.id}.description`
description: game.i18n.localize(`DAGGERHEART.CONFIG.Condition.${choice.id}.description`)
};
return acc;
@ -179,6 +179,10 @@ export const defeatedConditions = () => {
};
export const defeatedConditionChoices = {
deathMove: {
id: 'deathMove',
name: 'DAGGERHEART.CONFIG.Condition.deathMove.name'
},
defeated: {
id: 'defeated',
name: 'DAGGERHEART.CONFIG.Condition.defeated.name'

View file

@ -549,7 +549,18 @@ export default class DhCharacter extends BaseDataActor {
}
get deathMoveViable() {
return this.resources.hitPoints.max > 0 && this.resources.hitPoints.value >= this.resources.hitPoints.max;
const { characterDefault } = game.settings.get(
CONFIG.DH.id,
CONFIG.DH.SETTINGS.gameSettings.Automation
).defeated;
const deathMoveOutcomeStatuses = Object.keys(CONFIG.DH.GENERAL.defeatedConditionChoices).filter(
key => key !== characterDefault
);
const deathMoveNotResolved = this.parent.statuses.every(status => !deathMoveOutcomeStatuses.includes(status));
const allHitPointsMarked =
this.resources.hitPoints.max > 0 && this.resources.hitPoints.value >= this.resources.hitPoints.max;
return deathMoveNotResolved && allHitPointsMarked;
}
get armorApplicableDamageTypes() {

View file

@ -58,7 +58,7 @@ export default class DhAutomation extends foundry.abstract.DataModel {
defeated: new fields.SchemaField({
enabled: new fields.BooleanField({
required: true,
initial: false,
initial: true,
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.enabled.label'
}),
overlay: new fields.BooleanField({
@ -69,7 +69,7 @@ export default class DhAutomation extends foundry.abstract.DataModel {
characterDefault: new fields.StringField({
required: true,
choices: CONFIG.DH.GENERAL.defeatedConditionChoices,
initial: CONFIG.DH.GENERAL.defeatedConditionChoices.unconscious.id,
initial: CONFIG.DH.GENERAL.defeatedConditionChoices.deathMove.id,
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.characterDefault.label'
}),
adversaryDefault: new fields.StringField({
@ -84,23 +84,29 @@ export default class DhAutomation extends foundry.abstract.DataModel {
initial: CONFIG.DH.GENERAL.defeatedConditionChoices.defeated.id,
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.companionDefault.label'
}),
deathMoveIcon: new fields.FilePathField({
initial: 'icons/magic/life/heart-cross-purple-orange.webp',
categories: ['IMAGE'],
base64: false,
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.deathMove.label'
}),
deadIcon: new fields.FilePathField({
initial: 'icons/magic/death/grave-tombstone-glow-teal.webp',
categories: ['IMAGE'],
base64: false,
label: 'Dead'
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.dead.label'
}),
defeatedIcon: new fields.FilePathField({
initial: 'icons/magic/control/fear-fright-mask-orange.webp',
categories: ['IMAGE'],
base64: false,
label: 'Defeated'
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.defeated.label'
}),
unconsciousIcon: new fields.FilePathField({
initial: 'icons/magic/control/sleep-bubble-purple.webp',
categories: ['IMAGE'],
base64: false,
label: 'Unconcious'
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.unconscious.label'
})
}),
roll: new fields.SchemaField({

View file

@ -849,8 +849,8 @@ export default class DhpActor extends Actor {
async toggleDefeated(defeatedState) {
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).defeated;
const { unconscious, defeated, dead } = CONFIG.DH.GENERAL.conditions();
const defeatedConditions = new Set([unconscious.id, defeated.id, dead.id]);
const { deathMove, unconscious, defeated, dead } = CONFIG.DH.GENERAL.conditions();
const defeatedConditions = new Set([deathMove.id, unconscious.id, defeated.id, dead.id]);
if (!defeatedState) {
for (let defeatedId of defeatedConditions) {
await this.toggleStatusEffect(defeatedId, { overlay: settings.overlay, active: defeatedState });
@ -864,6 +864,18 @@ export default class DhpActor extends Actor {
}
}
async setDeathMoveDefeated(defeatedIconId) {
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).defeated;
const actorDefault = settings[`${this.type}Default`];
if (!settings.enabled || !settings.enabled || !actorDefault || actorDefault === defeatedIconId) return;
for (let defeatedId of Object.keys(CONFIG.DH.GENERAL.defeatedConditionChoices)) {
await this.toggleStatusEffect(defeatedId, { overlay: settings.overlay, active: false });
}
if (defeatedIconId) await this.toggleStatusEffect(defeatedIconId, { overlay: settings.overlay, active: true });
}
queueScrollText(scrollingTextData) {
this.#scrollTextQueue.push(...scrollingTextData.map(data => () => createScrollText(this, data)));
if (!this.#scrollTextInterval) {