Fixes: adv/dis as a global toggle, auto-number duplicate combatants

- 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>
This commit is contained in:
2026-06-08 01:50:02 +02:00
parent ed3d967526
commit d5977e4c63
8 changed files with 135 additions and 18 deletions
+10 -2
View File
@@ -1,5 +1,5 @@
import { create } from 'zustand';
import type { RollResult } from '@/lib/dice/notation';
import type { RollResult, RollMode } from '@/lib/dice/notation';
import type { Degree } from '@/lib/dice/check';
export interface TrayRoll {
@@ -13,13 +13,21 @@ export interface TrayRoll {
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) => ({
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 }),
}));