From 48b17be458a380a96c4df455754a247f515a1eca Mon Sep 17 00:00:00 2001 From: Vlyan Date: Wed, 10 Feb 2021 17:41:35 +0100 Subject: [PATCH] RnK : Added ability to GM to undo the last choices --- system/lang/en-en.json | 3 +- system/lang/es-es.json | 3 +- system/lang/fr-fr.json | 5 +- system/scripts/dice/roll-n-keep-dialog.js | 62 +++++- system/templates/dice/roll-n-keep-dialog.html | 210 +++++++++--------- 5 files changed, 169 insertions(+), 114 deletions(-) diff --git a/system/lang/en-en.json b/system/lang/en-en.json index 6014268..a6de56f 100644 --- a/system/lang/en-en.json +++ b/system/lang/en-en.json @@ -109,7 +109,8 @@ "reroll_drop_here": "Re-roll", "swap_drop_here": "Swap", "keep_drop_here": "Keep", - "bt_validate": "Finalize this step" + "bt_validate": "Finalize this step", + "undo": "[GM] Undo the last step choices" }, "gm_toolbox": { "title": "GM ToolBox", diff --git a/system/lang/es-es.json b/system/lang/es-es.json index 5c7ba77..f564e96 100644 --- a/system/lang/es-es.json +++ b/system/lang/es-es.json @@ -109,7 +109,8 @@ "reroll_drop_here": "Relanzar", "swap_drop_here": "Swap", "keep_drop_here": "Guardar", - "bt_validate": "Finalizar" + "bt_validate": "Finalizar", + "undo": "[GM] Undo the last step choices" }, "gm_toolbox": { "title": "GM ToolBox", diff --git a/system/lang/fr-fr.json b/system/lang/fr-fr.json index 3ad1c51..f9b0376 100644 --- a/system/lang/fr-fr.json +++ b/system/lang/fr-fr.json @@ -109,7 +109,8 @@ "reroll_drop_here": "Relancer", "swap_drop_here": "Modifier", "keep_drop_here": "Garder", - "bt_validate": "Finaliser cette étape" + "bt_validate": "Finaliser cette étape", + "undo": "[GM] Annuler les choix de la dernière étape" }, "gm_toolbox": { "title": "GM ToolBox", @@ -117,7 +118,7 @@ "difficulty": "Modifier la difficulté (droite: ajout, gauche: soustraction, milieu: ND 2)", "sleep": "Repos confortable pour tous les personnages (Enlève Eau x2 de fatigue)", "sleep_info": "Les personnages ont passé une bonne nuit de sommeil.", - "scene_end": "Fin de scène (Conflit et Fatigue reset à moitié pour tous les personnages)", + "scene_end": "Fin de scène (Conflit et Fatigue à moitié pour tous les personnages dont la valeur dépasse ce seuil)", "scene_end_info": "La tension de la scène retombe enfin" }, "max": "Max", diff --git a/system/scripts/dice/roll-n-keep-dialog.js b/system/scripts/dice/roll-n-keep-dialog.js index 7c5acbe..d22fc42 100644 --- a/system/scripts/dice/roll-n-keep-dialog.js +++ b/system/scripts/dice/roll-n-keep-dialog.js @@ -217,7 +217,9 @@ export class RollnKeepDialog extends FormApplication { */ getData(options = null) { // Disable submit / edition + this.options.classes = this.options.classes.filter((e) => e !== "finalized"); this.object.submitDisabled = false; + if (this._checkKeepCount(this.object.currentStep)) { const kept = this._getKeepCount(this.object.currentStep); this.object.submitDisabled = kept < 1 || kept > this.roll.l5r5e.keepLimit; @@ -241,6 +243,18 @@ export class RollnKeepDialog extends FormApplication { activateListeners(html) { super.activateListeners(html); + // GM Only, need to be before the editable check + if (game.user.isGM && this.object.currentStep > 0) { + // Add Context menu to rollback choices + new ContextMenu(html, ".l5r5e.profil", [ + { + name: game.i18n.localize("l5r5e.roll_n_keep.undo"), + icon: '', + callback: () => this._undoLastStepChoices(), + }, + ]); + } + // *** Everything below here is only needed if the sheet is editable *** if (!this.options.editable) { return; @@ -517,16 +531,19 @@ export class RollnKeepDialog extends FormApplication { /** * Rebuild the message roll + * @param {boolean} forceKeep If true keep all dice regardless their choice + * @returns {Promise} * @private */ - async _rebuildRoll() { + async _rebuildRoll(forceKeep = false) { // Get all kept dices + new (choice null) const diceList = this.object.dicesList.reduce((acc, step, stepIdx) => { const haveReroll = stepIdx > 0 && this._haveChoice(stepIdx - 1, RollnKeepDialog.CHOICES.reroll); step.forEach((die, idx) => { if ( !!die && - (die.choice === RollnKeepDialog.CHOICES.keep || + (forceKeep || + die.choice === RollnKeepDialog.CHOICES.keep || (haveReroll && die.choice === RollnKeepDialog.CHOICES.nothing)) ) { if (!acc[die.type]) { @@ -648,21 +665,56 @@ export class RollnKeepDialog extends FormApplication { await this._applyChoices(); // *** Below this the current step become the next step *** - this.object.currentStep += 1; + this.object.currentStep++; // Rebuild the roll - await this._rebuildRoll(); + await this._rebuildRoll(false); // Send the new roll in chat and delete the old message await this._toChatMessage(); // If a next step exist, rerender, else close if (this.object.dicesList[this.object.currentStep]) { - return this.render(); + return this.render(false); } return this.close(); } + /** + * Undo the last step choice + * @returns {Promise} + * @private + */ + async _undoLastStepChoices() { + // Find the step to work to + this.object.currentStep = this.object.dicesList[this.object.currentStep] + ? this.object.currentStep + : Math.max(0, this.object.currentStep - 1); + + // If all clear, delete this step + if (this._haveChoice(this.object.currentStep, RollnKeepDialog.CHOICES.nothing)) { + if (this.object.currentStep === 0) { + return; + } + this.object.dicesList.pop(); + this.object.dicesList = this.object.dicesList.filter((e) => !!e); + this.object.currentStep--; + } + + // Clear choices + this.object.dicesList[this.object.currentStep] + .filter((e) => !!e) + .map((e) => { + e.choice = RollnKeepDialog.CHOICES.nothing; + return e; + }); + + this.options.editable = true; + await this._rebuildRoll(true); + await this._toChatMessage(); + return this.render(false); + } + /** * Handle execution of a chat card action via a click event on the RnK button * @param {Event} event The originating click event diff --git a/system/templates/dice/roll-n-keep-dialog.html b/system/templates/dice/roll-n-keep-dialog.html index 7249647..853cee6 100644 --- a/system/templates/dice/roll-n-keep-dialog.html +++ b/system/templates/dice/roll-n-keep-dialog.html @@ -40,111 +40,111 @@ - - {{!-- Body --}} - {{#if options.editable}} - - {{!-- Face Rings --}} - + {{!-- Center --}} + + {{!-- Face Skills --}} + + + + + + {{else}} + {{!-- Non editable DiceList history --}} + {{#each data.dicesList as |item idxStep|}} + + {{#each item as |dice idxDie|}} + + {{/each}} + + {{/each}} + {{/if}} +
- - {{ localize 'l5r5e.roll_n_keep.swap_drop_here' }} - + + {{!-- Body --}} + {{#if options.editable}} + + {{!-- Face Rings --}} + - {{!-- Center --}} - - {{!-- Face Skills --}} - - - - - - {{else}} - {{!-- Non editable DiceList history --}} - {{#each data.dicesList as |item idxStep|}} - - {{#each item as |dice idxDie|}} - {{#if dice.face}} - - {{/if}} - {{/each}} - + {{#each data.swapDiceFaces.rings}} +
+ {{this}} +
{{/each}} - {{/if}} -
+ + {{localize 'l5r5e.roll_n_keep.swap_drop_here'}} + - {{#each data.swapDiceFaces.rings}} -
- {{this}} -
- {{/each}} -
- {{!-- Discard & ReRoll --}} - - - - - - -
-
- - {{ localize 'l5r5e.roll_n_keep.discard_drop_here' }} - -
-
  -
- - {{ localize 'l5r5e.roll_n_keep.reroll_drop_here' }} - -
-
- {{!-- DiceList history --}} - - {{#each data.dicesList as |item idxStep|}} - - {{#each item as |dice idxDie|}} - {{#if dice.face}} - - {{/if}} - {{/each}} - - {{/each}} -
- {{#if dice.newFace}} - {{idxStep}}_{{idxDie}} - {{else}} - {{idxStep}}_{{idxDie}} - {{/if}} -
- {{!-- Keep --}} - - - - -
-
- - {{ localize 'l5r5e.roll_n_keep.keep_drop_here' }} - -
-
-
- - {{ localize 'l5r5e.roll_n_keep.swap_drop_here' }} - - {{#each data.swapDiceFaces.skills}} -
- {{this}} -
- {{/each}} -
- -
- {{#if dice.newFace}} - {{idxStep}}_{{idxDie}} - {{else}} - {{idxStep}}_{{idxDie}} - {{/if}} -
+
+ {{!-- Discard & ReRoll --}} + + + + + + +
+
+ + {{localize 'l5r5e.roll_n_keep.discard_drop_here'}} + +
+
  +
+ + {{localize 'l5r5e.roll_n_keep.reroll_drop_here'}} + +
+
+ {{!-- DiceList history --}} + + {{#each data.dicesList as |item idxStep|}} + + {{#each item as |dice idxDie|}} + + {{/each}} + + {{/each}} +
+ {{#if dice.face}} + {{#if dice.newFace}} + {{idxStep}}_{{idxDie}} + {{else}} + {{idxStep}}_{{idxDie}} + {{/if}} + {{/if}} +
+ {{!-- Keep --}} + + + + +
+
+ + {{localize 'l5r5e.roll_n_keep.keep_drop_here'}} + +
+
+
+ + {{localize 'l5r5e.roll_n_keep.swap_drop_here'}} + + {{#each data.swapDiceFaces.skills}} +
+ {{this}} +
+ {{/each}} +
+ +
+ {{#if dice.face}} + {{#if dice.newFace}} + {{idxStep}}_{{idxDie}} + {{else}} + {{idxStep}}_{{idxDie}} + {{/if}} + {{/if}} +