Files
DndGamePlayer/app/main/diceRoll/diceRollSessionStore.ts
T
Ivan Fontosh 712086ddca feat: кубики/таймер/кисть/спонсоры и задел игровых систем
Показ анимации кубиков игрокам, закрытие оверлеев с окнами, ручной ввод количества, меньший радиус кисти, блок спонсоров в «О программе»; плюс черновик game systems / character sheet.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:37:44 +08:00

81 lines
2.3 KiB
TypeScript

import {
clampDiceCount,
createInitialDiceRollState,
formatDiceNotation,
isDiceSides,
rollDiceValues,
type DiceRollEvent,
type DiceRollState,
} from '../../shared/types/diceRoll';
export class DiceRollSessionStore {
private state: DiceRollState = createInitialDiceRollState();
getState(): DiceRollState {
return this.state;
}
clear(): DiceRollState {
this.state = createInitialDiceRollState();
return this.state;
}
dispatch(event: DiceRollEvent): DiceRollState {
switch (event.kind) {
case 'clear': {
if (!this.state.active && this.state.values.length === 0) return this.state;
this.state = {
...createInitialDiceRollState(),
revision: this.state.revision + 1,
visibleToPlayers: this.state.visibleToPlayers,
};
return this.state;
}
case 'setVisibleToPlayers': {
if (this.state.visibleToPlayers === event.visible) return this.state;
this.state = {
...this.state,
revision: this.state.revision + 1,
visibleToPlayers: event.visible,
...(event.visible === false && this.state.active
? { active: false, startedAt: null }
: {}),
};
return this.state;
}
case 'hideOverlay': {
if (!this.state.active) return this.state;
this.state = {
...this.state,
revision: this.state.revision + 1,
active: false,
startedAt: null,
};
return this.state;
}
case 'roll': {
if (!isDiceSides(event.sides)) return this.state;
const count = clampDiceCount(event.count);
if (count < 1) return this.state;
const values = rollDiceValues(count, event.sides);
const total = values.reduce((a, b) => a + b, 0);
const showToPlayers = this.state.visibleToPlayers;
this.state = {
revision: this.state.revision + 1,
active: showToPlayers,
visibleToPlayers: showToPlayers,
notation: formatDiceNotation(count, event.sides),
values,
total,
startedAt: showToPlayers ? Date.now() : null,
};
return this.state;
}
default: {
const _exhaustive: never = event;
return _exhaustive;
}
}
}
}