9647e6b3d6
- Dice notation: exploding (Nd6!) and reroll-below (Nd6r2), capped + tested - Degrees of success / roll-vs-DC (PF2e ±10 + nat 20/1 steps; 5e crit on nat 20/1) - Global roll tray (shared store + RollTray in layout) with animated result + degree - Roll from the character sheet: skills, saves, and attack to-hit/damage are clickable and post to the tray + history (rollAndShow/rollCheck helpers) - Saved roll macros per campaign (persisted) on the Dice page 10 new unit tests (notation explode/reroll, degrees), interactive-dice e2e. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import type { SystemId } from '@/lib/rules';
|
|
|
|
export type Degree = 'critical-success' | 'success' | 'failure' | 'critical-failure';
|
|
|
|
export const DEGREE_LABEL: Record<Degree, string> = {
|
|
'critical-success': 'Critical Success',
|
|
success: 'Success',
|
|
failure: 'Failure',
|
|
'critical-failure': 'Critical Failure',
|
|
};
|
|
|
|
export const DEGREE_COLOR: Record<Degree, string> = {
|
|
'critical-success': 'text-success',
|
|
success: 'text-success',
|
|
failure: 'text-warning',
|
|
'critical-failure': 'text-danger',
|
|
};
|
|
|
|
/**
|
|
* Evaluate a d20 result against a DC.
|
|
* - PF2e: ≥DC+10 crit success, ≥DC success, ≤DC-10 crit failure; a natural 20
|
|
* improves the degree one step and a natural 1 worsens it one step.
|
|
* - 5e: success/failure vs DC, with natural 20/1 mapped to critical results.
|
|
*/
|
|
export function degreeOfSuccess(input: {
|
|
total: number;
|
|
dc: number;
|
|
system: SystemId;
|
|
/** the natural face of the d20, if known */
|
|
natural?: number | undefined;
|
|
}): Degree {
|
|
const { total, dc, system, natural } = input;
|
|
if (system === 'pf2e') {
|
|
let step = total >= dc + 10 ? 2 : total >= dc ? 1 : total <= dc - 10 ? -1 : 0;
|
|
if (natural === 20) step += 1;
|
|
else if (natural === 1) step -= 1;
|
|
step = Math.max(-1, Math.min(2, step));
|
|
return step === 2 ? 'critical-success' : step === 1 ? 'success' : step === 0 ? 'failure' : 'critical-failure';
|
|
}
|
|
// 5e
|
|
if (natural === 20) return 'critical-success';
|
|
if (natural === 1) return 'critical-failure';
|
|
return total >= dc ? 'success' : 'failure';
|
|
}
|