RnK : Added ability to GM to undo the last choices

This commit is contained in:
Vlyan
2021-02-10 17:41:35 +01:00
parent 7d7d62f950
commit 48b17be458
5 changed files with 169 additions and 114 deletions

View File

@@ -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",

View File

@@ -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",

View File

@@ -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",

View File

@@ -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: '<i class="fas fa-undo"></i>',
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<void>}
* @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<Application|any>}
* @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

View File

@@ -40,111 +40,111 @@
</span>
</header>
</div>
<table>
{{!-- Body --}}
{{#if options.editable}}
<tr>
{{!-- Face Rings --}}
<td>
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{ localize 'l5r5e.roll_n_keep.swap_drop_here' }}
</legend>
<table>
{{!-- Body --}}
{{#if options.editable}}
<tr>
{{!-- Face Rings --}}
<td>
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{localize 'l5r5e.roll_n_keep.swap_drop_here'}}
</legend>
{{#each data.swapDiceFaces.rings}}
<div class="dice dropbox faces-change" data-type="swap" data-face="{{this}}" data-die="RingDie">
<img src="{{getDiceFaceUrl 'RingDie' this}}" alt="{{this}}" />
</div>
{{/each}}
</td>
{{!-- Center --}}
<td>
{{!-- Discard & ReRoll --}}
<table>
<tr>
<td>
<fieldset class="dropbox discards" data-type="discard">
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{ localize 'l5r5e.roll_n_keep.discard_drop_here' }}
</legend>
</fieldset>
</td>
<td>&nbsp;</td>
<td>
<fieldset class="dropbox rerolls" data-type="reroll">
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{ localize 'l5r5e.roll_n_keep.reroll_drop_here' }}
</legend>
</fieldset>
</td>
</tr>
</table>
{{!-- DiceList history --}}
<table>
{{#each data.dicesList as |item idxStep|}}
<tr>
{{#each item as |dice idxDie|}}
{{#if dice.face}}
<td>
{{#if dice.newFace}}
<img class="dice {{dice.choice}}{{#ifCond ../../data.currentStep '==' idxStep}} draggable{{/ifCond}}" data-step="{{idxStep}}" data-die="{{idxDie}}" src="{{getDiceFaceUrl dice.type dice.newFace}}" alt="{{idxStep}}_{{idxDie}}" />
{{else}}
<img class="dice {{dice.choice}}{{#ifCond ../../data.currentStep '==' idxStep}} draggable{{/ifCond}}" data-step="{{idxStep}}" data-die="{{idxDie}}" src="{{getDiceFaceUrl dice.type dice.face}}" alt="{{idxStep}}_{{idxDie}}" />
{{/if}}
</td>
{{/if}}
{{/each}}
</tr>
{{/each}}
</table>
{{!-- Keep --}}
<table>
<tr>
<td>
<fieldset class="dropbox keeps" data-type="keep">
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{ localize 'l5r5e.roll_n_keep.keep_drop_here' }}
</legend>
</fieldset>
</td>
</tr>
</table>
</td>
{{!-- Face Skills --}}
<td>
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{ localize 'l5r5e.roll_n_keep.swap_drop_here' }}
</legend>
{{#each data.swapDiceFaces.skills}}
<div class="dice dropbox faces-change" data-type="swap" data-face="{{this}}" data-die="AbilityDie">
<img src="{{getDiceFaceUrl 'AbilityDie' this}}" alt="{{this}}" />
</div>
{{/each}}
</td>
</tr>
<tr>
<td colspan="3">
<button id="finalize" name="finalize" type="button" {{#if data.submitDisabled}}disabled{{/if}}>
{{ localize 'l5r5e.roll_n_keep.bt_validate' }} <i class="fas fa-arrow-circle-right"></i>
</button>
</td>
</tr>
{{else}}
{{!-- Non editable DiceList history --}}
{{#each data.dicesList as |item idxStep|}}
<tr>
{{#each item as |dice idxDie|}}
{{#if dice.face}}
<td>
{{#if dice.newFace}}
<img class="dice {{dice.choice}}" src="{{getDiceFaceUrl dice.type dice.newFace}}" alt="{{idxStep}}_{{idxDie}}" />
{{else}}
<img class="dice {{dice.choice}}" src="{{getDiceFaceUrl dice.type dice.face}}" alt="{{idxStep}}_{{idxDie}}" />
{{/if}}
</td>
{{/if}}
{{/each}}
</tr>
{{#each data.swapDiceFaces.rings}}
<div class="dice dropbox faces-change" data-type="swap" data-face="{{this}}" data-die="RingDie">
<img src="{{getDiceFaceUrl 'RingDie' this}}" alt="{{this}}" />
</div>
{{/each}}
{{/if}}
</table>
</td>
{{!-- Center --}}
<td>
{{!-- Discard & ReRoll --}}
<table>
<tr>
<td>
<fieldset class="dropbox discards" data-type="discard">
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{localize 'l5r5e.roll_n_keep.discard_drop_here'}}
</legend>
</fieldset>
</td>
<td>&nbsp;</td>
<td>
<fieldset class="dropbox rerolls" data-type="reroll">
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{localize 'l5r5e.roll_n_keep.reroll_drop_here'}}
</legend>
</fieldset>
</td>
</tr>
</table>
{{!-- DiceList history --}}
<table>
{{#each data.dicesList as |item idxStep|}}
<tr>
{{#each item as |dice idxDie|}}
<td>
{{#if dice.face}}
{{#if dice.newFace}}
<img class="dice {{dice.choice}}{{#ifCond ../../data.currentStep '==' idxStep}} draggable{{/ifCond}}" data-step="{{idxStep}}" data-die="{{idxDie}}" src="{{getDiceFaceUrl dice.type dice.newFace}}" alt="{{idxStep}}_{{idxDie}}" />
{{else}}
<img class="dice {{dice.choice}}{{#ifCond ../../data.currentStep '==' idxStep}} draggable{{/ifCond}}" data-step="{{idxStep}}" data-die="{{idxDie}}" src="{{getDiceFaceUrl dice.type dice.face}}" alt="{{idxStep}}_{{idxDie}}" />
{{/if}}
{{/if}}
</td>
{{/each}}
</tr>
{{/each}}
</table>
{{!-- Keep --}}
<table>
<tr>
<td>
<fieldset class="dropbox keeps" data-type="keep">
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{localize 'l5r5e.roll_n_keep.keep_drop_here'}}
</legend>
</fieldset>
</td>
</tr>
</table>
</td>
{{!-- Face Skills --}}
<td>
<legend class="section-header">
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{localize 'l5r5e.roll_n_keep.swap_drop_here'}}
</legend>
{{#each data.swapDiceFaces.skills}}
<div class="dice dropbox faces-change" data-type="swap" data-face="{{this}}" data-die="AbilityDie">
<img src="{{getDiceFaceUrl 'AbilityDie' this}}" alt="{{this}}" />
</div>
{{/each}}
</td>
</tr>
<tr>
<td colspan="3">
<button id="finalize" name="finalize" type="button" {{#if data.submitDisabled}}disabled{{/if}}>
{{ localize 'l5r5e.roll_n_keep.bt_validate' }} <i class="fas fa-arrow-circle-right"></i>
</button>
</td>
</tr>
{{else}}
{{!-- Non editable DiceList history --}}
{{#each data.dicesList as |item idxStep|}}
<tr>
{{#each item as |dice idxDie|}}
<td>
{{#if dice.face}}
{{#if dice.newFace}}
<img class="dice {{dice.choice}}" src="{{getDiceFaceUrl dice.type dice.newFace}}" alt="{{idxStep}}_{{idxDie}}" />
{{else}}
<img class="dice {{dice.choice}}" src="{{getDiceFaceUrl dice.type dice.face}}" alt="{{idxStep}}_{{idxDie}}" />
{{/if}}
{{/if}}
</td>
{{/each}}
</tr>
{{/each}}
{{/if}}
</table>
</form>