diff --git a/lang/en.json b/lang/en.json index c5a503c6..4a7f44d0 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1009,7 +1009,7 @@ }, "blazeOfGlory": { "name": "Blaze Of Glory", - "description": " Your character embraces death and goes out in a blaze of glory. Take one final action. It automatically critically succeeds (with GM approval), and then you cross through the veil of death. NOTE: A Blaze of Glory effect has been added to your character. Any Duality Roll will automatically be a critical." + "description": "Your character embraces death and goes out in a blaze of glory. Take one final action. It automatically critically succeeds (with GM approval), and then you cross through the veil of death. NOTE: A Blaze of Glory effect has been added to your character. Any Duality Roll will automatically be a critical." } }, "DomainCardTypes": { @@ -2605,7 +2605,13 @@ "currentTarget": "Current" }, "deathMove": { - "title": "Death Move" + "title": "Death Move", + "gainScar": "You gained a scar", + "avoidScar": "You have avoided a new scar", + "journeysEnd": "You have {scars} Scars and have crossed out your last Hope slot. Your character's journey ends.", + "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!" }, "dicePool": { "title": "Dice Pool" diff --git a/module/applications/dialogs/deathMove.mjs b/module/applications/dialogs/deathMove.mjs index 56260559..6021f607 100644 --- a/module/applications/dialogs/deathMove.mjs +++ b/module/applications/dialogs/deathMove.mjs @@ -1,9 +1,7 @@ import { enrichedFateRoll } from '../../enrichers/FateRollEnricher.mjs'; import { enrichedDualityRoll } from '../../enrichers/DualityRollEnricher.mjs'; - const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; - export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV2) { constructor(actor) { super({}); @@ -46,46 +44,44 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV const target = this.actor.uuid; const config = await enrichedFateRoll({ target, - title: "Avoid Death Hope Fate Roll", + title: 'Avoid Death Hope Fate Roll', label: 'test', - fateType: "Hope" + fateType: 'Hope' }); + 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 - } + await this.actor.update({ + system: { + scars: newScarAmount } - ); + }); if (newScarAmount >= this.actor.system.resources.hope.max) { - return "You have " + newScarAmount + " Scars and have crossed out your last Hope slot. Your character's journey ends." + return game.i18n.format('DAGGERHEART.UI.Chat.deathMove.journeysEnd', { scars: newScarAmount }); } - return "You have a new scar, total scars: " + newScarAmount; + return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.gainScar'); } - return "You have avoided a new scar."; + + return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.avoidScar'); } async clearAllStressAndHitpoints() { - await this.actor.update( - { - system: { - resources: { - hitPoints: { - value: 0 - }, - stress: { - value: 0 - } + await this.actor.update({ + system: { + resources: { + hitPoints: { + value: 0 + }, + stress: { + value: 0 } } } - ); + }); } async handleRiskItAll() { @@ -94,7 +90,7 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV traitValue: null, target: null, difficulty: null, - title: "Risk It All", + title: 'Risk It All', label: 'test', actionType: null, advantage: null @@ -102,25 +98,25 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV if (config.roll.isCritical) { this.clearAllStressAndHitpoints(); - return "Critical Rolled, clearing all marked Stress and Hit Points"; + return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.riskItAllCritical'); } - // Hope if (config.roll.result.duality == 1) { - console.log("Need to clear up Stress and HP up to hope value"); - console.log("Hope rolled", config.roll.hope.value); - if (config.roll.hope.value >= (this.actor.system.resources.hitPoints.value + this.actor.system.resources.stress.value)) { + console.log('Need to clear up Stress and HP up to hope value'); + console.log('Hope rolled', config.roll.hope.value); + if ( + config.roll.hope.value >= + this.actor.system.resources.hitPoints.value + this.actor.system.resources.stress.value + ) { this.clearAllStressAndHitpoints(); - return "Hope roll value is more than the marked Stress and Hit Points, clearing both."; + return 'Hope roll value is more than the marked Stress and Hit Points, clearing both.'; } - return "TODO - need to clear Stress and/or Hit Points up to: " + config.roll.hope.value; + return 'TODO - need to clear Stress and/or Hit Points up to: ' + config.roll.hope.value; } - //Fear if (config.roll.result.duality == -1) { - return "Fear rolled higher, you have died..."; + return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.riskItAllFailure'); } - } async handleBlazeOfGlory() { @@ -133,13 +129,13 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV { key: 'system.rules.roll.guaranteedCritical', mode: 2, - value: "true" + value: 'true' } ] } ]); - return "Blaze of Glory Effect Added!"; + return game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.blazeOfGlory'); } static selectMove(_, button) { @@ -150,10 +146,9 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV } static async takeMove() { - this.close(); - let result = ""; + let result = ''; if (CONFIG.DH.GENERAL.deathMoves.blazeOfGlory === this.selectedMove) { result = await this.handleBlazeOfGlory(); @@ -167,11 +162,10 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV result = await this.handleRiskItAll(); } - const autoExpandDescription = game.settings.get( - CONFIG.DH.id, - CONFIG.DH.SETTINGS.gameSettings.appearance - ).expandRollMessage?.desc; + const autoExpandDescription = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance) + .expandRollMessage?.desc; const cls = getDocumentClass('ChatMessage'); + const msg = { user: game.user.id, content: await foundry.applications.handlebars.renderTemplate( @@ -188,9 +182,7 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV chevron: autoExpandDescription ? 'fa-chevron-up' : 'fa-chevron-down' } ), - title: game.i18n.localize( - 'DAGGERHEART.UI.Chat.deathMove.title' - ), + title: game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.title'), speaker: cls.getSpeaker(), flags: { daggerheart: { diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 0108a80a..b729d590 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -686,10 +686,10 @@ export default class DhCharacter extends BaseDataActor { 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) { - changes.system.resources = { - hope: { - value: newHopeValue - } + 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 }; } } @@ -710,7 +710,7 @@ export default class DhCharacter extends BaseDataActor { } static migrateData(source) { - if (typeof (source.scars) === 'object') source.scars = 0; + if (typeof source.scars === 'object') source.scars = 0; return super.migrateData(source); } } diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 850c811d..d74c9492 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -85,9 +85,7 @@ export default class DualityRoll extends D20Roll { } get isCritical() { - if (this.guaranteedCritical) { - return true; - } + if (this.guaranteedCritical) return true; if (!this.dHope._evaluated || !this.dFear._evaluated) return; return this.dHope.total === this.dFear.total; } @@ -103,9 +101,13 @@ export default class DualityRoll extends D20Roll { } get totalLabel() { - const label = this.guaranteedCritical ? 'DAGGERHEART.GENERAL.guaranteedCriticalSuccess' : - this.isCritical ? 'DAGGERHEART.GENERAL.criticalSuccess' : - this.withHope ? 'DAGGERHEART.GENERAL.hope' : 'DAGGERHEART.GENERAL.fear'; + const label = this.guaranteedCritical + ? 'DAGGERHEART.GENERAL.guaranteedCriticalSuccess' + : this.isCritical + ? 'DAGGERHEART.GENERAL.criticalSuccess' + : this.withHope + ? 'DAGGERHEART.GENERAL.hope' + : 'DAGGERHEART.GENERAL.fear'; return game.i18n.localize(label); } @@ -117,8 +119,9 @@ export default class DualityRoll extends D20Roll { /** @inheritDoc */ static fromData(data) { if (data.options.guaranteedCritical) { - console.log("TODO: set the max values for Hope and Fear here?"); + console.log('TODO: set the max values for Hope and Fear here?'); } + data.terms[0].class = foundry.dice.terms.Die.name; data.terms[2].class = foundry.dice.terms.Die.name; return super.fromData(data); @@ -176,7 +179,7 @@ export default class DualityRoll extends D20Roll { config.dialog ??= {}; config.guaranteedCritical = config.data?.parent?.appliedEffects.reduce((a, c) => { const change = c.changes.find(ch => ch.key === 'system.rules.roll.guaranteedCritical'); - if (change) a = true; + if (change) a = true; return a; }, false); @@ -187,7 +190,6 @@ export default class DualityRoll extends D20Roll { return super.buildConfigure(config, message); } - static async buildEvaluate(roll, config = {}, message = {}) { await super.buildEvaluate(roll, config, message); diff --git a/module/dice/fateRoll.mjs b/module/dice/fateRoll.mjs index e0b8c9c2..418c8465 100644 --- a/module/dice/fateRoll.mjs +++ b/module/dice/fateRoll.mjs @@ -3,7 +3,7 @@ import D20Roll from './d20Roll.mjs'; import { setDiceSoNiceForHopeFateRoll, setDiceSoNiceForFearFateRoll } from '../helpers/utils.mjs'; export default class FateRoll extends D20Roll { - constructor(formula, data = {}, options = {}) { + constructor(formula, data = {}, options = {}) { super(formula, data, options); } @@ -12,42 +12,33 @@ export default class FateRoll extends D20Roll { static DefaultDialog = D20RollDialog; get title() { - return game.i18n.localize( - `DAGGERHEART.GENERAL.fateRoll` - ); + return game.i18n.localize(`DAGGERHEART.GENERAL.fateRoll`); } get dHope() { - // if ( !(this.terms[0] instanceof foundry.dice.terms.Die) ) return; if (!(this.dice[0] instanceof foundry.dice.terms.Die)) this.createBaseDice(); return this.dice[0]; - // return this.#hopeDice; } set dHope(faces) { if (!(this.dice[0] instanceof foundry.dice.terms.Die)) this.createBaseDice(); this.dice[0].faces = this.getFaces(faces); - // this.#hopeDice = `d${face}`; } get dFear() { - // if ( !(this.terms[1] instanceof foundry.dice.terms.Die) ) return; if (!(this.dice[0] instanceof foundry.dice.terms.Die)) this.createBaseDice(); return this.dice[0]; - // return this.#fearDice; } set dFear(faces) { if (!(this.dice[0] instanceof foundry.dice.terms.Die)) this.createBaseDice(); this.dice[0].faces = this.getFaces(faces); - // this.#fearDice = `d${face}`; } get isCritical() { return false; } - get fateDie() { return this.data.fateType; } @@ -73,16 +64,10 @@ export default class FateRoll extends D20Roll { static async buildEvaluate(roll, config = {}, message = {}) { await super.buildEvaluate(roll, config, message); - if (roll.fateDie === "Hope") { - await setDiceSoNiceForHopeFateRoll( - roll, - config.roll.fate.dice - ); + if (roll.fateDie === 'Hope') { + await setDiceSoNiceForHopeFateRoll(roll, config.roll.fate.dice); } else { - await setDiceSoNiceForFearFateRoll( - roll, - config.roll.fate.dice - ); + await setDiceSoNiceForFearFateRoll(roll, config.roll.fate.dice); } } @@ -90,12 +75,11 @@ export default class FateRoll extends D20Roll { const data = super.postEvaluate(roll, config); data.fate = { - dice: roll.fateDie === "Hope" ? roll.dHope.denomination : roll.dFear.denomination, - value: roll.fateDie === "Hope" ? roll.dHope.total : roll.dFear.total, + dice: roll.fateDie === 'Hope' ? roll.dHope.denomination : roll.dFear.denomination, + value: roll.fateDie === 'Hope' ? roll.dHope.total : roll.dFear.total, fateDie: roll.fateDie }; return data; } - } diff --git a/styles/less/dialog/death-move/death-move-container.less b/styles/less/dialog/death-move/death-move-container.less index e5803d95..903704e3 100644 --- a/styles/less/dialog/death-move/death-move-container.less +++ b/styles/less/dialog/death-move/death-move-container.less @@ -1,55 +1,56 @@ -@import '../../utils/spacing.less'; -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; - -.daggerheart.dh-style.dialog.death-move { - .death-move-container { - display: flex; - flex-direction: column; - gap: 5px; - - .moves-list { - .move-item { - display: flex; - align-items: center; - gap: 5px; - - &:hover { - background-color: light-dark(@soft-shadow, @soft-white-shadow); - cursor: pointer; - } - padding: 5px; - border-radius: 5px; - transition: background-color 0.3s ease-in-out; - - .label { - display: flex; - align-items: center; - gap: 10px; - cursor: pointer; - flex: 1; - i { - text-align: center; - width: 30px; - } - } - - input[type='radio'] { - margin-left: auto; - } - } - } - } - - footer { - margin-top: 8px; - display: flex; - gap: 8px; - - button { - flex: 1; - height: 40px; - font-weight: 600; - } - } -} +@import '../../utils/spacing.less'; +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.daggerheart.dh-style.dialog.death-move { + .death-move-container { + display: flex; + flex-direction: column; + gap: 5px; + + .moves-list { + .move-item { + display: flex; + align-items: center; + gap: 5px; + padding: 5px; + border-radius: 5px; + transition: background-color 0.3s ease-in-out; + height: 37px; + + &:hover { + background-color: light-dark(@soft-shadow, @soft-white-shadow); + cursor: pointer; + } + + .label { + display: flex; + align-items: center; + gap: 10px; + cursor: pointer; + flex: 1; + i { + text-align: center; + width: 30px; + } + } + + input[type='radio'] { + margin-left: auto; + } + } + } + } + + footer { + margin-top: 8px; + display: flex; + gap: 8px; + + button { + flex: 1; + height: 40px; + font-weight: 600; + } + } +} diff --git a/styles/less/ui/chat/deathmoves.less b/styles/less/ui/chat/deathmoves.less index 53f33137..9060e644 100644 --- a/styles/less/ui/chat/deathmoves.less +++ b/styles/less/ui/chat/deathmoves.less @@ -3,7 +3,7 @@ @import '../../utils/spacing.less'; #interface.theme-light { - .daggerheart.chat.deathmoves { + .daggerheart.chat.death-moves { .death-moves-list .death-move { &:hover { background: @dark-blue-10; @@ -36,7 +36,7 @@ } .daggerheart.chat { - &.deathmoves { + &.death-moves { display: flex; flex-direction: column; align-items: center; @@ -101,17 +101,13 @@ .description { padding: 8px; } - - .result { - padding: 8px; - } } .action-use-button-parent { width: 100%; .action-use-target { - display:flex; + display: flex; align-items: center; justify-content: space-between; gap: 4px; @@ -135,7 +131,11 @@ font-weight: 600; height: 40px; } + } + .result { + padding: 8px; + font-weight: bold; } } } diff --git a/styles/less/ui/index.less b/styles/less/ui/index.less index 7f9ada25..61508859 100644 --- a/styles/less/ui/index.less +++ b/styles/less/ui/index.less @@ -6,6 +6,7 @@ @import './chat/effect-summary.less'; @import './chat/group-roll.less'; @import './chat/refresh-message.less'; +@import './chat/deathmoves.less'; @import './chat/sheet.less'; @import './combat-sidebar/combat-sidebar.less'; diff --git a/templates/ui/chat/deathMove.hbs b/templates/ui/chat/deathMove.hbs index 0a20521f..3cca5fc7 100644 --- a/templates/ui/chat/deathMove.hbs +++ b/templates/ui/chat/deathMove.hbs @@ -1,4 +1,4 @@ -