712086ddca
Показ анимации кубиков игрокам, закрытие оверлеев с окнами, ручной ввод количества, меньший радиус кисти, блок спонсоров в «О программе»; плюс черновик game systems / character sheet. Co-authored-by: Cursor <cursoragent@cursor.com>
81 lines
2.3 KiB
TypeScript
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;
|
|
}
|
|
}
|
|
}
|
|
}
|