From 8d718879242903e6a9112b7785073bb8101871c5 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Fri, 16 Jan 2026 15:24:29 +0100 Subject: [PATCH] Dialog templating and logic --- lang/en.json | 14 +-- module/applications/dialogs/_module.mjs | 1 + module/applications/dialogs/deathMove.mjs | 8 +- .../applications/dialogs/riskItAllDialog.mjs | 85 ++++++++++++------- module/applications/ui/chatLog.mjs | 19 ++--- styles/less/dialog/index.less | 4 +- styles/less/dialog/risk-it-all/sheet.less | 60 +++++++++++++ templates/dialogs/riskItAllDialog.hbs | 58 +++++++------ templates/ui/chat/deathMove.hbs | 2 +- 9 files changed, 171 insertions(+), 80 deletions(-) create mode 100644 styles/less/dialog/risk-it-all/sheet.less diff --git a/lang/en.json b/lang/en.json index 82129bac..b5f6d612 100755 --- a/lang/en.json +++ b/lang/en.json @@ -615,9 +615,11 @@ "rerollDice": "Reroll Dice" }, "RiskItAllDialog": { - "title": "Character: {name} - Risk It All - Clear Stress and/or Hit Points", - "subtitle": "Clear {hope} Stress and/or Hit Points", - "submit": "Submit" + "title": "{name} - Risk It All", + "subtitle": "Clear Stress and Hit Points", + "remainingTitle": "Remaining Points", + "clearResource": "Clear {resource}", + "finalTitle": "Final Character Resources" }, "TagTeamSelect": { "title": "Tag Team Roll", @@ -2675,9 +2677,9 @@ "riskItAllCritical": "Critical Rolled, clearing all marked Stress and Hit Points.", "riskItAllFailure": "The fear die rolled higher. You have crossed through the veil of death.", "blazeOfGlory": "Blaze of Glory Effect Added!", - "riskItAllClearStressAndHitPoints": "Clear {hope} Stress Or Hit Points.", - "riskItAllSuccessWithEnoughHope": "Hope roll value is more than the marked Stress and Hit Points, clearing both.", - "riskItAllSuccess": "The hope die rolled higher, clear up to {hope} Stress Or Hit Points." + "riskItAllDialogButton": "Clear Stress And Hit Points.", + "riskItAllSuccessWithEnoughHope": "Hope roll value is more than the marked Stress and Hit Points. Both are cleared fully.", + "riskItAllSuccess": "The hope die rolled higher, clear up to {hope} Stress And Hit Points." }, "dicePool": { "title": "Dice Pool" diff --git a/module/applications/dialogs/_module.mjs b/module/applications/dialogs/_module.mjs index 92038c41..d43045e6 100644 --- a/module/applications/dialogs/_module.mjs +++ b/module/applications/dialogs/_module.mjs @@ -14,3 +14,4 @@ export { default as ResourceDiceDialog } from './resourceDiceDialog.mjs'; export { default as ActionSelectionDialog } from './actionSelectionDialog.mjs'; export { default as GroupRollDialog } from './group-roll-dialog.mjs'; export { default as TagTeamDialog } from './tagTeamDialog.mjs'; +export { default as RiskItAllDialog } from './riskItAllDialog.mjs'; diff --git a/module/applications/dialogs/deathMove.mjs b/module/applications/dialogs/deathMove.mjs index ea7a18eb..5cc78b5f 100644 --- a/module/applications/dialogs/deathMove.mjs +++ b/module/applications/dialogs/deathMove.mjs @@ -9,7 +9,7 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV this.actor = actor; this.selectedMove = null; this.showRiskItAllButton = false; - this.riskItAllButtonLabel = ""; + this.riskItAllButtonLabel = ''; this.riskItAllHope = 0; } @@ -108,10 +108,12 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV config.resourceUpdates.addResources(clearAllStressAndHitpointsUpdates); chatMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.riskItAllSuccessWithEnoughHope'); } else { - chatMessage = game.i18n.format('DAGGERHEART.UI.Chat.deathMove.riskItAllSuccess', { hope: config.roll.hope.value }) + chatMessage = game.i18n.format('DAGGERHEART.UI.Chat.deathMove.riskItAllSuccess', { + hope: config.roll.hope.value + }); this.showRiskItAllButton = true; this.riskItAllHope = config.roll.hope.value; - this.riskItAllButtonLabel = game.i18n.format('DAGGERHEART.UI.Chat.deathMove.riskItAllClearStressAndHitPoints', { hope: config.roll.hope.value }) + this.riskItAllButtonLabel = game.i18n.format('DAGGERHEART.UI.Chat.deathMove.riskItAllDialogButton'); } } diff --git a/module/applications/dialogs/riskItAllDialog.mjs b/module/applications/dialogs/riskItAllDialog.mjs index fef76e66..9bdd5dc2 100644 --- a/module/applications/dialogs/riskItAllDialog.mjs +++ b/module/applications/dialogs/riskItAllDialog.mjs @@ -1,11 +1,14 @@ const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class RiskItAllDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(actor, config) { + constructor(actor, resourceValue) { super({}); this.actor = actor; - this.validChoices = null; - this.config = config; + this.resourceValue = resourceValue; + this.choices = { + hitPoints: 0, + stress: 0 + }; } get title() { @@ -14,10 +17,10 @@ export default class RiskItAllDialog extends HandlebarsApplicationMixin(Applicat static DEFAULT_OPTIONS = { classes: ['daggerheart', 'dh-style', 'dialog', 'views', 'risk-it-all'], - position: { width: 'auto', height: 'auto' }, - window: { icon: 'fa-solid fa-skull' }, + position: { width: 280, height: 'auto' }, + window: { icon: 'fa-solid fa-dice fa-xl' }, actions: { - submit: this.submit + finish: RiskItAllDialog.#finish } }; @@ -28,42 +31,62 @@ export default class RiskItAllDialog extends HandlebarsApplicationMixin(Applicat } }; + _attachPartListeners(partId, htmlElement, options) { + super._attachPartListeners(partId, htmlElement, options); + + for (const input of htmlElement.querySelectorAll('.resource-container input')) + input.addEventListener('change', this.updateChoice.bind(this)); + } + async _prepareContext(_options) { const context = await super._prepareContext(_options); - context.RiskItAllDialog = this.RiskItAllDialog; - context.title = game.i18n.format('DAGGERHEART.APPLICATIONS.RiskItAllDialog.subtitle', { hope: this.config.hope }); - context.currentHitPointsLabel = "Current Marked Hit Points: " + this.actor.system.resources.hitPoints.value; - context.currentStressLabel = "Current Marked Stress: " + this.actor.system.resources.stress.value; + context.resourceValue = this.resourceValue; + context.remainingResource = this.resourceValue - this.choices.hitPoints - this.choices.stress; + context.unfinished = context.remainingResource !== 0; - context.newHitPoints = this.actor.system.resources.hitPoints.value; - context.newStress = this.actor.system.resources.stress.value; + context.choices = this.choices; + context.final = { + hitPoints: { + value: this.actor.system.resources.hitPoints.value - this.choices.hitPoints, + max: this.actor.system.resources.hitPoints.max + }, + stress: { + value: this.actor.system.resources.stress.value - this.choices.stress, + max: this.actor.system.resources.stress.max + } + }; + + context; return context; } - static checkForValidChoice() { - /* - TODO: + updateChoice(event) { + let value = Number.parseInt(event.target.value); + const choiceKey = event.target.dataset.choice; + const actorValue = this.actor.system.resources[choiceKey].value; + const remaining = this.resourceValue - this.choices.hitPoints - this.choices.stress; + const changeAmount = value - this.choices[choiceKey]; - return (this.config.hope == (this.actor.system.resources.hitPoints.value - newHitPointValue) + (this.actor.system.resources.stress.value - newStressValue)); - */ - return true; + /* If trying to increase beyond remaining resource points, just increase to max available */ + if (remaining - changeAmount < 0) value = this.choices[choiceKey] + remaining; + else if (actorValue - value < 0) value = actorValue; + + this.choices[choiceKey] = value; + this.render(); } - static async submit() { - this.close(); - // TODO: Update actor with changes. + static async #finish() { + const resourceUpdate = Object.keys(this.choices).reduce((acc, resourceKey) => { + const value = this.actor.system.resources[resourceKey].value - this.choices[resourceKey]; + acc[resourceKey] = { value }; + return acc; + }, {}); + await this.actor.update({ - system: { - resources: { - hitPoints: { - value: 0 // TODO put editted value here - }, - stress: { - value: 0 // TODO put editted value here - } - } - } + 'system.resources': resourceUpdate }); + + this.close(); } } diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index b4aa246a..f0c7288c 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -1,6 +1,5 @@ import { abilities } from '../../config/actorConfig.mjs'; import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; -import RiskItAllDialog from '../dialogs/riskItAllDialog.mjs'; export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog { constructor(options) { @@ -98,15 +97,17 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo /** Ensure the chat theme inherits the interface theme */ _replaceHTML(result, content, options) { - const themedElement = result.log?.querySelector(".chat-log"); - themedElement?.classList.remove("themed", "theme-light", "theme-dark"); + const themedElement = result.log?.querySelector('.chat-log'); + themedElement?.classList.remove('themed', 'theme-light', 'theme-dark'); super._replaceHTML(result, content, options); } /** Remove chat log theme from notifications area */ async _onFirstRender(result, content) { await super._onFirstRender(result, content); - document.querySelector("#chat-notifications .chat-log")?.classList.remove("themed", "theme-light", "theme-dark") + document + .querySelector('#chat-notifications .chat-log') + ?.classList.remove('themed', 'theme-light', 'theme-dark'); } async onRollSimple(event, message) { @@ -388,14 +389,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo event.target.closest('.group-roll-section').querySelector('.group-roll-content').classList.toggle('closed'); } - async riskItAllClearStressAndHitPoints(event, data) { - const hopeValue = event.target.dataset.hope; - const config = { - hope: hopeValue - } - await new RiskItAllDialog(data.actor, config).render({ force: true }); + const resourceValue = event.target.dataset.resourceValue; + new game.system.api.applications.dialogs.RiskItAllDialog(data.actor, resourceValue).render({ force: true }); } - - } diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less index b5ed8764..01a3f954 100644 --- a/styles/less/dialog/index.less +++ b/styles/less/dialog/index.less @@ -38,4 +38,6 @@ @import './item-transfer/sheet.less'; -@import './settings/change-currency-icon.less'; \ No newline at end of file +@import './settings/change-currency-icon.less'; + +@import './risk-it-all/sheet.less'; diff --git a/styles/less/dialog/risk-it-all/sheet.less b/styles/less/dialog/risk-it-all/sheet.less new file mode 100644 index 00000000..db34a5c1 --- /dev/null +++ b/styles/less/dialog/risk-it-all/sheet.less @@ -0,0 +1,60 @@ +.daggerheart.dialog.dh-style.views.risk-it-all { + .risk-it-all-container { + display: flex; + align-items: center; + flex-direction: column; + gap: 8px; + text-align: center; + + header { + font-weight: bold; + font-size: var(--font-size-20); + } + + .section-label { + font-size: var(--font-size-18); + text-decoration: underline; + } + + .remaining-section { + display: flex; + flex-direction: column; + gap: 2px; + } + + .resource-section { + width: 100%; + display: flex; + gap: 8px; + } + + .final-section { + width: 100%; + display: flex; + flex-direction: column; + gap: 2px; + + .final-section-values-container { + width: 100%; + display: flex; + align-items: center; + justify-content: space-evenly; + + .final-section-value-container { + display: flex; + flex-direction: column; + gap: 2px; + } + } + } + } + + footer { + width: 100%; + display: flex; + + button { + flex: 1; + } + } +} diff --git a/templates/dialogs/riskItAllDialog.hbs b/templates/dialogs/riskItAllDialog.hbs index 9f494f58..edb2fbf6 100644 --- a/templates/dialogs/riskItAllDialog.hbs +++ b/templates/dialogs/riskItAllDialog.hbs @@ -1,33 +1,39 @@
-
-

{{title}}

-
-
- Remaining points to use here. -
-
- {{currentHitPointsLabel}} -
- New Hit Points Value - -
+
{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.subtitle"}}
- {{currentStressLabel}} -
- New Stress Value - +
+ +
{{this.remainingResource}}
+
+ +
+
+ + +
+
+ +
+ +
+ +
+
+ + {{this.final.hitPoints.value}}/{{this.final.hitPoints.max}} +
+
+ + {{this.final.stress.value}}/{{this.final.stress.max}} +
+
+
+ +
+ +
-
- - -
\ No newline at end of file diff --git a/templates/ui/chat/deathMove.hbs b/templates/ui/chat/deathMove.hbs index b36ee590..02691c7c 100644 --- a/templates/ui/chat/deathMove.hbs +++ b/templates/ui/chat/deathMove.hbs @@ -19,7 +19,7 @@
{{#if this.showRiskItAllButton}}
-