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
|
describe("DS4 Rolls with multiple and slaying dice, recurrent throw", () => {
|
||||||
xdescribe("DS4 Rolls with multiple and slaying dice, recurrent throw", () => {
|
|
||||||
it("Should regularly succeed with the first roll being a `20`", () => {
|
it("Should regularly succeed with the first roll being a `20`", () => {
|
||||||
const rollProvider = mockMultipleThrows([20, 2, 19]);
|
const rollProvider = mockMultipleThrows([20, 2, 19]);
|
||||||
|
|
||||||
expect(rollCheckMultipleDice(48, {}, rollProvider)).toEqual(
|
expect(rollCheckMultipleDice(48, { useSlayingDice: true, slayingDiceRepetition: true }, rollProvider)).toEqual(
|
||||||
new RollResult(40, RollResultStatus.CRITICAL_FAILURE, [20, 2, 19]),
|
new RollResult(41, RollResultStatus.SUCCESS, [20, 19, 2]),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,24 +33,7 @@ export function rollCheckSingleDie(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rollCheckMultipleDice(
|
function separateCriticalHits(dice: Array<number>, usedOptions: RollOptions): [Array<number>, Array<number>] {
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
const partitionCallback = (prev: [Array<number>, Array<number>], cur: number) => {
|
const partitionCallback = (prev: [Array<number>, Array<number>], cur: number) => {
|
||||||
if (cur <= usedOptions.maxCritSucc) {
|
if (cur <= usedOptions.maxCritSucc) {
|
||||||
prev[0].push(cur);
|
prev[0].push(cur);
|
||||||
|
@ -64,6 +47,30 @@ export function rollCheckMultipleDice(
|
||||||
.reduce(partitionCallback, [[], []])
|
.reduce(partitionCallback, [[], []])
|
||||||
.map((a) => a.sort((r1, r2) => r2 - r1));
|
.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);
|
const swapLastWithCrit: boolean = isDiceSwapNecessary(critSuccesses, otherRolls, finalCheck);
|
||||||
|
|
||||||
let sortedRollResults: Array<number>;
|
let sortedRollResults: Array<number>;
|
||||||
|
@ -96,5 +103,9 @@ export function rollCheckMultipleDice(
|
||||||
})
|
})
|
||||||
.reduce((a, b) => a + b);
|
.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);
|
return new RollResult(evaluationResult, RollResultStatus.SUCCESS, sortedRollResults);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue