RnK : Reroll add a extra step

This commit is contained in:
Vlyan
2021-02-03 19:41:39 +01:00
parent ca5a164f7f
commit 7969c5f526
2 changed files with 89 additions and 55 deletions

View File

@@ -124,7 +124,7 @@ export class RollnKeepDialog extends FormApplication {
this.object.dicesList = this.roll.l5r5e.history; this.object.dicesList = this.roll.l5r5e.history;
let currentStep = this.roll.l5r5e.history.length - 1; let currentStep = this.roll.l5r5e.history.length - 1;
if (!this._haveChoice(currentStep)) { if (!this._haveChoice(currentStep, RollnKeepDialog.CHOICES.nothing)) {
currentStep += 1; currentStep += 1;
} }
this.object.currentStep = currentStep; this.object.currentStep = currentStep;
@@ -204,10 +204,11 @@ export class RollnKeepDialog extends FormApplication {
* @return {Object} * @return {Object}
*/ */
getData(options = null) { getData(options = null) {
// Check only on 1st step // Disable submit / edition
if (this.object.currentStep === 0) { this.object.submitDisabled = false;
const kept = this._getKeepCount(); if (this._checkKeepCount(this.object.currentStep)) {
this.object.submitDisabled = kept < 1 || kept > this.roll.l5r5e.ringsUsed; const kept = this._getKeepCount(this.object.currentStep);
this.object.submitDisabled = kept < 1 || kept > this.roll.l5r5e.keepLimit;
} else if (!this.object.dicesList[this.object.currentStep]) { } else if (!this.object.dicesList[this.object.currentStep]) {
this.options.editable = false; this.options.editable = false;
} }
@@ -264,26 +265,36 @@ export class RollnKeepDialog extends FormApplication {
const current = this.object.dicesList[data.step][data.die]; const current = this.object.dicesList[data.step][data.die];
delete current.newFace; delete current.newFace;
// FaceSwap switch (type) {
if (type === RollnKeepDialog.CHOICES.swap) { case RollnKeepDialog.CHOICES.swap: {
// Dice Type Ring/Skill // Dice Type Ring/Skill
const diceType = $(event.currentTarget).data("die"); const diceType = $(event.currentTarget).data("die");
const diceNewFace = $(event.currentTarget).data("face"); const diceNewFace = $(event.currentTarget).data("face");
if (current.type !== diceType || current.face === diceNewFace) { if (current.type !== diceType || current.face === diceNewFace) {
current.choice = RollnKeepDialog.CHOICES.nothing; current.choice = RollnKeepDialog.CHOICES.nothing;
this.render(false); this.render(false);
return false; return false;
}
current.newFace = diceNewFace;
break;
} }
current.newFace = diceNewFace; case RollnKeepDialog.CHOICES.reroll:
// If reroll, we need to keep all the line by default
this._forceChoiceForDiceWithoutOne(RollnKeepDialog.CHOICES.keep);
break;
} }
current.choice = type; current.choice = type;
// Little time saving : on 1st step, if we reach the max kept dices, discard all dices without a choice // Little time saving : if we reach the max kept dices, discard all dices without a choice
if (this.object.currentStep === 0 && this._getKeepCount() === this.roll.l5r5e.ringsUsed) { if (
this._discardDiceWithoutChoice(); this._checkKeepCount(this.object.currentStep) &&
this._getKeepCount(this.object.currentStep) === this.roll.l5r5e.keepLimit
) {
this._forceChoiceForDiceWithoutOne(RollnKeepDialog.CHOICES.discard);
} }
this.render(false); this.render(false);
@@ -294,53 +305,71 @@ export class RollnKeepDialog extends FormApplication {
* Return the current number of dices kept * Return the current number of dices kept
* @private * @private
*/ */
_getKeepCount() { _getKeepCount(step) {
return this.object.dicesList.reduce((acc, step) => { return this.object.dicesList[step].reduce((acc, die) => {
return ( if (
acc + !!die &&
step.reduce((acc2, die) => { [RollnKeepDialog.CHOICES.keep, RollnKeepDialog.CHOICES.reroll, RollnKeepDialog.CHOICES.swap].includes(
if ( die.choice
!!die && )
[ ) {
RollnKeepDialog.CHOICES.keep, acc = acc + 1;
RollnKeepDialog.CHOICES.reroll, }
RollnKeepDialog.CHOICES.swap, return acc;
].includes(die.choice)
) {
acc2 = acc2 + 1;
}
return acc2;
}, 0)
);
}, 0); }, 0);
} }
/** /**
* Return true if the player can make a choice for the current step * Return true if a "_getKeepCount" is needed
* @param {number} step
* @returns {boolean}
* @private * @private
*/ */
_haveChoice(currentStep) { _checkKeepCount(step) {
return (
!this._haveChoice(step, RollnKeepDialog.CHOICES.reroll) &&
(step === 0 || this._haveChoice(step - 1, RollnKeepDialog.CHOICES.reroll))
);
}
/**
* Return true if this choice exist in the current step
* @private
*/
_haveChoice(currentStep, choice) {
return ( return (
this.object.dicesList[currentStep] && this.object.dicesList[currentStep] &&
this.object.dicesList[currentStep].some((e) => !!e && e.choice === RollnKeepDialog.CHOICES.nothing) this.object.dicesList[currentStep].some((e) => !!e && e.choice === choice)
); );
} }
/** /**
* Discard all dices without a choice for the current step * Discard all dices without a choice for the current step
* @param {string} newChoice
* @private * @private
*/ */
_discardDiceWithoutChoice() { _forceChoiceForDiceWithoutOne(newChoice) {
this.object.dicesList[this.object.currentStep] this.object.dicesList[this.object.currentStep]
.filter((e) => !!e) .filter((e) => !!e)
.map((e) => { .map((e) => {
if (e.choice === RollnKeepDialog.CHOICES.nothing) { if (e.choice === RollnKeepDialog.CHOICES.nothing) {
e.choice = RollnKeepDialog.CHOICES.discard; e.choice = newChoice;
} }
return e; return e;
}); });
} }
/**
* Initialize dice array for "step" if needed
* @param {number} step
* @private
*/
_initializeDicesListStep(step) {
if (!this.object.dicesList[step]) {
this.object.dicesList[step] = Array(this.object.dicesList[0].length).fill(null);
}
}
/** /**
* Apply all choices to build the next step * Apply all choices to build the next step
* @returns {Promise<void>} * @returns {Promise<void>}
@@ -348,6 +377,7 @@ export class RollnKeepDialog extends FormApplication {
*/ */
async _applyChoices() { async _applyChoices() {
const nextStep = this.object.currentStep + 1; const nextStep = this.object.currentStep + 1;
const haveReroll = this._haveChoice(this.object.currentStep, RollnKeepDialog.CHOICES.reroll);
// Foreach kept dices, apply choices // Foreach kept dices, apply choices
const newRolls = {}; const newRolls = {};
@@ -357,8 +387,16 @@ export class RollnKeepDialog extends FormApplication {
} }
switch (die.choice) { switch (die.choice) {
case RollnKeepDialog.CHOICES.keep: case RollnKeepDialog.CHOICES.keep:
// Exploding dice : add a new dice in the next step if (haveReroll) {
if (game.l5r5e[die.type].FACES[die.face].explosive) { // Reroll line add all kept into a new line
this._initializeDicesListStep(nextStep);
this.object.dicesList[nextStep][idx] = duplicate(
this.object.dicesList[this.object.currentStep][idx]
);
this.object.dicesList[nextStep][idx].choice = RollnKeepDialog.CHOICES.nothing;
this.object.dicesList[this.object.currentStep][idx].choice = RollnKeepDialog.CHOICES.discard;
} else if (game.l5r5e[die.type].FACES[die.face].explosive) {
// Exploding dice : add a new dice in the next step
if (!newRolls[die.type]) { if (!newRolls[die.type]) {
newRolls[die.type] = 0; newRolls[die.type] = 0;
} }
@@ -376,9 +414,7 @@ export class RollnKeepDialog extends FormApplication {
case RollnKeepDialog.CHOICES.swap: case RollnKeepDialog.CHOICES.swap:
// FaceSwap : add a new dice with selected face in next step // FaceSwap : add a new dice with selected face in next step
if (!this.object.dicesList[nextStep]) { this._initializeDicesListStep(nextStep);
this.object.dicesList[nextStep] = Array(this.object.dicesList[0].length).fill(null);
}
this.object.dicesList[nextStep][idx] = { this.object.dicesList[nextStep][idx] = {
type: this.object.dicesList[this.object.currentStep][idx].type, type: this.object.dicesList[this.object.currentStep][idx].type,
face: this.object.dicesList[this.object.currentStep][idx].newFace, face: this.object.dicesList[this.object.currentStep][idx].newFace,
@@ -392,18 +428,16 @@ export class RollnKeepDialog extends FormApplication {
// If new rolls, roll and add them // If new rolls, roll and add them
if (Object.keys(newRolls).length > 0) { if (Object.keys(newRolls).length > 0) {
const newRollsResults = await this._newRoll(newRolls); const newRollsResults = await this._newRoll(newRolls);
this._initializeDicesListStep(nextStep);
if (!this.object.dicesList[nextStep]) {
this.object.dicesList[nextStep] = Array(this.object.dicesList[0].length).fill(null);
}
this.object.dicesList[this.object.currentStep].forEach((die, idx) => { this.object.dicesList[this.object.currentStep].forEach((die, idx) => {
if (!die) { if (!die) {
return; return;
} }
if ( if (
die.choice === RollnKeepDialog.CHOICES.reroll || die.choice === RollnKeepDialog.CHOICES.reroll ||
(die.choice === RollnKeepDialog.CHOICES.keep && game.l5r5e[die.type].FACES[die.face].explosive) (!haveReroll &&
die.choice === RollnKeepDialog.CHOICES.keep &&
game.l5r5e[die.type].FACES[die.face].explosive)
) { ) {
this.object.dicesList[nextStep][idx] = newRollsResults[die.type].shift(); this.object.dicesList[nextStep][idx] = newRollsResults[die.type].shift();
} }
@@ -573,7 +607,7 @@ export class RollnKeepDialog extends FormApplication {
} }
// Discard all dices without a choice for the current step // Discard all dices without a choice for the current step
this._discardDiceWithoutChoice(); this._forceChoiceForDiceWithoutOne(RollnKeepDialog.CHOICES.discard);
// Apply all choices to build the next step // Apply all choices to build the next step
await this._applyChoices(); await this._applyChoices();

View File

@@ -16,7 +16,7 @@ export class RollL5r5e extends Roll {
difficulty: 2, difficulty: 2,
difficultyHidden: false, difficultyHidden: false,
voidPointUsed: false, voidPointUsed: false,
ringsUsed: null, keepLimit: null,
isInitiativeRoll: false, isInitiativeRoll: false,
dicesTypes: { dicesTypes: {
std: false, std: false,
@@ -104,7 +104,7 @@ export class RollL5r5e extends Roll {
); // ignore math symbols ); // ignore math symbols
this.l5r5e.dicesTypes.l5r = this.dice.some((term) => term instanceof game.l5r5e.L5rBaseDie); this.l5r5e.dicesTypes.l5r = this.dice.some((term) => term instanceof game.l5r5e.L5rBaseDie);
summary.totalBonus = Math.max(0, summary.totalSuccess - this.l5r5e.difficulty); summary.totalBonus = Math.max(0, summary.totalSuccess - this.l5r5e.difficulty);
this.l5r5e.ringsUsed = this.dice.reduce( this.l5r5e.keepLimit = this.dice.reduce(
(acc, term) => (term instanceof game.l5r5e.RingDie ? acc + term.number : acc), (acc, term) => (term instanceof game.l5r5e.RingDie ? acc + term.number : acc),
0 0
); );