d5977e4c63
- Advantage/Disadvantage are now toggle modes (rollStore.mode) applied to d20 rolls everywhere (dice page, sheet skills/saves/attacks), preserving modifiers; applyRollMode() rewrites the first d20 -> 2d20kh1/kl1 - addCombatant auto-numbers duplicate names (Goblin 1, Goblin 2, …); the first duplicate also renames the original. Quantity add relies on this. - Tests for applyRollMode + duplicate numbering Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
34 lines
1001 B
TypeScript
34 lines
1001 B
TypeScript
import { create } from 'zustand';
|
|
import type { RollResult, RollMode } from '@/lib/dice/notation';
|
|
import type { Degree } from '@/lib/dice/check';
|
|
|
|
export interface TrayRoll {
|
|
/** increments each roll, used as an animation key */
|
|
seq: number;
|
|
label: string;
|
|
result: RollResult;
|
|
dc?: number;
|
|
degree?: Degree;
|
|
}
|
|
|
|
interface RollState {
|
|
last: TrayRoll | null;
|
|
/** advantage/disadvantage toggle applied to d20 rolls everywhere */
|
|
mode: RollMode;
|
|
push: (roll: Omit<TrayRoll, 'seq'>) => void;
|
|
dismiss: () => void;
|
|
setMode: (mode: RollMode) => void;
|
|
/** click the same mode again to turn it off */
|
|
toggleMode: (mode: Exclude<RollMode, 'normal'>) => void;
|
|
}
|
|
|
|
let seq = 0;
|
|
export const useRollStore = create<RollState>((set, get) => ({
|
|
last: null,
|
|
mode: 'normal',
|
|
push: (roll) => set({ last: { ...roll, seq: ++seq } }),
|
|
dismiss: () => set({ last: null }),
|
|
setMode: (mode) => set({ mode }),
|
|
toggleMode: (mode) => set({ mode: get().mode === mode ? 'normal' : mode }),
|
|
}));
|