Add advantage/disadvantage rolling for initiative
Right-click or long-press the d20 button (per-combatant or Roll All) to open a context menu with Advantage and Disadvantage options. Normal left-click behavior is unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { rollInitiative } from "../roll-initiative.js";
|
||||
import { rollInitiative, selectRoll } from "../roll-initiative.js";
|
||||
import { isDomainError } from "../types.js";
|
||||
import { expectDomainError } from "./test-helpers.js";
|
||||
|
||||
@@ -63,3 +63,31 @@ describe("rollInitiative", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("selectRoll", () => {
|
||||
it("normal mode returns the first roll", () => {
|
||||
expect(selectRoll(8, 15, "normal")).toBe(8);
|
||||
});
|
||||
|
||||
it("advantage returns the higher roll", () => {
|
||||
expect(selectRoll(8, 15, "advantage")).toBe(15);
|
||||
});
|
||||
|
||||
it("advantage returns the higher roll (reversed)", () => {
|
||||
expect(selectRoll(15, 8, "advantage")).toBe(15);
|
||||
});
|
||||
|
||||
it("disadvantage returns the lower roll", () => {
|
||||
expect(selectRoll(8, 15, "disadvantage")).toBe(8);
|
||||
});
|
||||
|
||||
it("disadvantage returns the lower roll (reversed)", () => {
|
||||
expect(selectRoll(15, 8, "disadvantage")).toBe(8);
|
||||
});
|
||||
|
||||
it("equal rolls return the same value for all modes", () => {
|
||||
expect(selectRoll(12, 12, "normal")).toBe(12);
|
||||
expect(selectRoll(12, 12, "advantage")).toBe(12);
|
||||
expect(selectRoll(12, 12, "disadvantage")).toBe(12);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -84,7 +84,11 @@ export {
|
||||
removeCombatant,
|
||||
} from "./remove-combatant.js";
|
||||
export { retreatTurn } from "./retreat-turn.js";
|
||||
export { rollInitiative } from "./roll-initiative.js";
|
||||
export {
|
||||
type RollMode,
|
||||
rollInitiative,
|
||||
selectRoll,
|
||||
} from "./roll-initiative.js";
|
||||
export { type SetAcSuccess, setAc } from "./set-ac.js";
|
||||
export { type SetHpSuccess, setHp } from "./set-hp.js";
|
||||
export {
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
import type { DomainError } from "./types.js";
|
||||
|
||||
export type RollMode = "normal" | "advantage" | "disadvantage";
|
||||
|
||||
/**
|
||||
* Selects the effective roll from two dice values based on the roll mode.
|
||||
* Advantage takes the higher, disadvantage takes the lower.
|
||||
*/
|
||||
export function selectRoll(
|
||||
roll1: number,
|
||||
roll2: number,
|
||||
mode: RollMode,
|
||||
): number {
|
||||
if (mode === "advantage") return Math.max(roll1, roll2);
|
||||
if (mode === "disadvantage") return Math.min(roll1, roll2);
|
||||
return roll1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure function that computes initiative from a resolved dice roll and modifier.
|
||||
* The dice roll must be an integer in [1, 20].
|
||||
|
||||
Reference in New Issue
Block a user