RnK : Added ability to GM to undo the last choices
This commit is contained in:
@@ -109,7 +109,8 @@
|
|||||||
"reroll_drop_here": "Re-roll",
|
"reroll_drop_here": "Re-roll",
|
||||||
"swap_drop_here": "Swap",
|
"swap_drop_here": "Swap",
|
||||||
"keep_drop_here": "Keep",
|
"keep_drop_here": "Keep",
|
||||||
"bt_validate": "Finalize this step"
|
"bt_validate": "Finalize this step",
|
||||||
|
"undo": "[GM] Undo the last step choices"
|
||||||
},
|
},
|
||||||
"gm_toolbox": {
|
"gm_toolbox": {
|
||||||
"title": "GM ToolBox",
|
"title": "GM ToolBox",
|
||||||
|
|||||||
@@ -109,7 +109,8 @@
|
|||||||
"reroll_drop_here": "Relanzar",
|
"reroll_drop_here": "Relanzar",
|
||||||
"swap_drop_here": "Swap",
|
"swap_drop_here": "Swap",
|
||||||
"keep_drop_here": "Guardar",
|
"keep_drop_here": "Guardar",
|
||||||
"bt_validate": "Finalizar"
|
"bt_validate": "Finalizar",
|
||||||
|
"undo": "[GM] Undo the last step choices"
|
||||||
},
|
},
|
||||||
"gm_toolbox": {
|
"gm_toolbox": {
|
||||||
"title": "GM ToolBox",
|
"title": "GM ToolBox",
|
||||||
|
|||||||
@@ -109,7 +109,8 @@
|
|||||||
"reroll_drop_here": "Relancer",
|
"reroll_drop_here": "Relancer",
|
||||||
"swap_drop_here": "Modifier",
|
"swap_drop_here": "Modifier",
|
||||||
"keep_drop_here": "Garder",
|
"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": {
|
"gm_toolbox": {
|
||||||
"title": "GM ToolBox",
|
"title": "GM ToolBox",
|
||||||
@@ -117,7 +118,7 @@
|
|||||||
"difficulty": "Modifier la difficulté (droite: ajout, gauche: soustraction, milieu: ND 2)",
|
"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": "Repos confortable pour tous les personnages (Enlève Eau x2 de fatigue)",
|
||||||
"sleep_info": "Les personnages ont passé une bonne nuit de sommeil.",
|
"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"
|
"scene_end_info": "La tension de la scène retombe enfin"
|
||||||
},
|
},
|
||||||
"max": "Max",
|
"max": "Max",
|
||||||
|
|||||||
@@ -217,7 +217,9 @@ export class RollnKeepDialog extends FormApplication {
|
|||||||
*/
|
*/
|
||||||
getData(options = null) {
|
getData(options = null) {
|
||||||
// Disable submit / edition
|
// Disable submit / edition
|
||||||
|
this.options.classes = this.options.classes.filter((e) => e !== "finalized");
|
||||||
this.object.submitDisabled = false;
|
this.object.submitDisabled = false;
|
||||||
|
|
||||||
if (this._checkKeepCount(this.object.currentStep)) {
|
if (this._checkKeepCount(this.object.currentStep)) {
|
||||||
const kept = this._getKeepCount(this.object.currentStep);
|
const kept = this._getKeepCount(this.object.currentStep);
|
||||||
this.object.submitDisabled = kept < 1 || kept > this.roll.l5r5e.keepLimit;
|
this.object.submitDisabled = kept < 1 || kept > this.roll.l5r5e.keepLimit;
|
||||||
@@ -241,6 +243,18 @@ export class RollnKeepDialog extends FormApplication {
|
|||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.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 ***
|
// *** Everything below here is only needed if the sheet is editable ***
|
||||||
if (!this.options.editable) {
|
if (!this.options.editable) {
|
||||||
return;
|
return;
|
||||||
@@ -517,16 +531,19 @@ export class RollnKeepDialog extends FormApplication {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuild the message roll
|
* Rebuild the message roll
|
||||||
|
* @param {boolean} forceKeep If true keep all dice regardless their choice
|
||||||
|
* @returns {Promise<void>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async _rebuildRoll() {
|
async _rebuildRoll(forceKeep = false) {
|
||||||
// Get all kept dices + new (choice null)
|
// Get all kept dices + new (choice null)
|
||||||
const diceList = this.object.dicesList.reduce((acc, step, stepIdx) => {
|
const diceList = this.object.dicesList.reduce((acc, step, stepIdx) => {
|
||||||
const haveReroll = stepIdx > 0 && this._haveChoice(stepIdx - 1, RollnKeepDialog.CHOICES.reroll);
|
const haveReroll = stepIdx > 0 && this._haveChoice(stepIdx - 1, RollnKeepDialog.CHOICES.reroll);
|
||||||
step.forEach((die, idx) => {
|
step.forEach((die, idx) => {
|
||||||
if (
|
if (
|
||||||
!!die &&
|
!!die &&
|
||||||
(die.choice === RollnKeepDialog.CHOICES.keep ||
|
(forceKeep ||
|
||||||
|
die.choice === RollnKeepDialog.CHOICES.keep ||
|
||||||
(haveReroll && die.choice === RollnKeepDialog.CHOICES.nothing))
|
(haveReroll && die.choice === RollnKeepDialog.CHOICES.nothing))
|
||||||
) {
|
) {
|
||||||
if (!acc[die.type]) {
|
if (!acc[die.type]) {
|
||||||
@@ -648,21 +665,56 @@ export class RollnKeepDialog extends FormApplication {
|
|||||||
await this._applyChoices();
|
await this._applyChoices();
|
||||||
|
|
||||||
// *** Below this the current step become the next step ***
|
// *** Below this the current step become the next step ***
|
||||||
this.object.currentStep += 1;
|
this.object.currentStep++;
|
||||||
|
|
||||||
// Rebuild the roll
|
// Rebuild the roll
|
||||||
await this._rebuildRoll();
|
await this._rebuildRoll(false);
|
||||||
|
|
||||||
// Send the new roll in chat and delete the old message
|
// Send the new roll in chat and delete the old message
|
||||||
await this._toChatMessage();
|
await this._toChatMessage();
|
||||||
|
|
||||||
// If a next step exist, rerender, else close
|
// If a next step exist, rerender, else close
|
||||||
if (this.object.dicesList[this.object.currentStep]) {
|
if (this.object.dicesList[this.object.currentStep]) {
|
||||||
return this.render();
|
return this.render(false);
|
||||||
}
|
}
|
||||||
return this.close();
|
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
|
* Handle execution of a chat card action via a click event on the RnK button
|
||||||
* @param {Event} event The originating click event
|
* @param {Event} event The originating click event
|
||||||
|
|||||||
@@ -40,111 +40,111 @@
|
|||||||
</span>
|
</span>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
<table>
|
<table>
|
||||||
{{!-- Body --}}
|
{{!-- Body --}}
|
||||||
{{#if options.editable}}
|
{{#if options.editable}}
|
||||||
<tr>
|
<tr>
|
||||||
{{!-- Face Rings --}}
|
{{!-- Face Rings --}}
|
||||||
<td>
|
<td>
|
||||||
<legend class="section-header">
|
<legend class="section-header">
|
||||||
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{ localize 'l5r5e.roll_n_keep.swap_drop_here' }}
|
<i class="fa fa-arrow-down" aria-hidden="true"></i> {{localize 'l5r5e.roll_n_keep.swap_drop_here'}}
|
||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
{{#each data.swapDiceFaces.rings}}
|
{{#each data.swapDiceFaces.rings}}
|
||||||
<div class="dice dropbox faces-change" data-type="swap" data-face="{{this}}" data-die="RingDie">
|
<div class="dice dropbox faces-change" data-type="swap" data-face="{{this}}" data-die="RingDie">
|
||||||
<img src="{{getDiceFaceUrl 'RingDie' this}}" alt="{{this}}" />
|
<img src="{{getDiceFaceUrl 'RingDie' this}}" alt="{{this}}" />
|
||||||
</div>
|
</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> </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}}
|
{{/each}}
|
||||||
{{/if}}
|
</td>
|
||||||
</table>
|
{{!-- 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> </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>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user