Add slaying dice behaviour.
This commit is contained in:
parent
55beeb92c9
commit
aaa10d7469
2 changed files with 33 additions and 23 deletions
|
@ -314,13 +314,12 @@ describe("DS4 Rolls with multiple and slaying dice, first throw", () => {
|
|||
});
|
||||
});
|
||||
|
||||
// TODO: Implement & reactivate
|
||||
xdescribe("DS4 Rolls with multiple and slaying dice, recurrent throw", () => {
|
||||
describe("DS4 Rolls with multiple and slaying dice, recurrent throw", () => {
|
||||
it("Should regularly succeed with the first roll being a `20`", () => {
|
||||
const rollProvider = mockMultipleThrows([20, 2, 19]);
|
||||
|
||||
expect(rollCheckMultipleDice(48, {}, rollProvider)).toEqual(
|
||||
new RollResult(40, RollResultStatus.CRITICAL_FAILURE, [20, 2, 19]),
|
||||
expect(rollCheckMultipleDice(48, { useSlayingDice: true, slayingDiceRepetition: true }, rollProvider)).toEqual(
|
||||
new RollResult(41, RollResultStatus.SUCCESS, [20, 19, 2]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -33,24 +33,7 @@ export function rollCheckSingleDie(
|
|||
}
|
||||
}
|
||||
|
||||
export function rollCheckMultipleDice(
|
||||
testValue: number,
|
||||
rollOptions: Partial<RollOptions>,
|
||||
provider: RollProvider = new DS4RollProvider(),
|
||||
): RollResult {
|
||||
const usedOptions = new DefaultRollOptions().mergeWith(rollOptions);
|
||||
const finalCheck = testValue % 20;
|
||||
const numberOfDice = Math.ceil(testValue / 20);
|
||||
|
||||
const dice = provider.getNextRolls(numberOfDice);
|
||||
|
||||
const firstResult = dice[0];
|
||||
|
||||
// Slaying Dice require a different handling.
|
||||
if (firstResult >= usedOptions.minCritFail && !isSlayingDiceRepetition(usedOptions)) {
|
||||
return new RollResult(0, RollResultStatus.CRITICAL_FAILURE, dice);
|
||||
}
|
||||
|
||||
function separateCriticalHits(dice: Array<number>, usedOptions: RollOptions): [Array<number>, Array<number>] {
|
||||
const partitionCallback = (prev: [Array<number>, Array<number>], cur: number) => {
|
||||
if (cur <= usedOptions.maxCritSucc) {
|
||||
prev[0].push(cur);
|
||||
|
@ -64,6 +47,30 @@ export function rollCheckMultipleDice(
|
|||
.reduce(partitionCallback, [[], []])
|
||||
.map((a) => a.sort((r1, r2) => r2 - r1));
|
||||
|
||||
return [critSuccesses, otherRolls];
|
||||
}
|
||||
|
||||
export function rollCheckMultipleDice(
|
||||
testValue: number,
|
||||
rollOptions: Partial<RollOptions>,
|
||||
provider: RollProvider = new DS4RollProvider(),
|
||||
): RollResult {
|
||||
const usedOptions = new DefaultRollOptions().mergeWith(rollOptions);
|
||||
const finalCheck = testValue % 20;
|
||||
const numberOfDice = Math.ceil(testValue / 20);
|
||||
|
||||
const dice = provider.getNextRolls(numberOfDice);
|
||||
|
||||
const firstResult = dice[0];
|
||||
const slayingDiceRepetition = isSlayingDiceRepetition(usedOptions);
|
||||
|
||||
// Slaying Dice require a different handling.
|
||||
if (firstResult >= usedOptions.minCritFail && !slayingDiceRepetition) {
|
||||
return new RollResult(0, RollResultStatus.CRITICAL_FAILURE, dice);
|
||||
}
|
||||
|
||||
const [critSuccesses, otherRolls] = separateCriticalHits(dice, usedOptions);
|
||||
|
||||
const swapLastWithCrit: boolean = isDiceSwapNecessary(critSuccesses, otherRolls, finalCheck);
|
||||
|
||||
let sortedRollResults: Array<number>;
|
||||
|
@ -96,5 +103,9 @@ export function rollCheckMultipleDice(
|
|||
})
|
||||
.reduce((a, b) => a + b);
|
||||
|
||||
if (usedOptions.useSlayingDice && firstResult <= usedOptions.maxCritSucc) {
|
||||
return new RollResult(evaluationResult, RollResultStatus.CRITICAL_SUCCESS, sortedRollResults);
|
||||
} else {
|
||||
return new RollResult(evaluationResult, RollResultStatus.SUCCESS, sortedRollResults);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue