feat: кубики/таймер/кисть/спонсоры и задел игровых систем
Показ анимации кубиков игрокам, закрытие оверлеев с окнами, ручной ввод количества, меньший радиус кисти, блок спонсоров в «О программе»; плюс черновик game systems / character sheet. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -13,12 +13,37 @@ void test('diceRoll: roll produces values in range and notation', () => {
|
||||
store.dispatch({ kind: 'roll', count: 3, sides: 6 });
|
||||
const st = store.getState();
|
||||
assert.equal(st.active, true);
|
||||
assert.equal(st.visibleToPlayers, true);
|
||||
assert.equal(st.notation, '3d6');
|
||||
assert.equal(st.values.length, 3);
|
||||
assert.ok(st.values.every((v) => v >= 1 && v <= 6));
|
||||
assert.equal(st.total, st.values.reduce((a, b) => a + b, 0));
|
||||
});
|
||||
|
||||
void test('diceRoll: roll without visibleToPlayers keeps master result only', () => {
|
||||
const store = new DiceRollSessionStore();
|
||||
store.dispatch({ kind: 'setVisibleToPlayers', visible: false });
|
||||
store.dispatch({ kind: 'roll', count: 2, sides: 8 });
|
||||
const st = store.getState();
|
||||
assert.equal(st.visibleToPlayers, false);
|
||||
assert.equal(st.active, false);
|
||||
assert.equal(st.notation, '2d8');
|
||||
assert.equal(st.values.length, 2);
|
||||
assert.ok(st.values.every((v) => v >= 1 && v <= 8));
|
||||
assert.equal(st.startedAt, null);
|
||||
});
|
||||
|
||||
void test('diceRoll: unchecking visibleToPlayers hides overlay', () => {
|
||||
const store = new DiceRollSessionStore();
|
||||
store.dispatch({ kind: 'roll', count: 1, sides: 20 });
|
||||
assert.equal(store.getState().active, true);
|
||||
const values = [...store.getState().values];
|
||||
store.dispatch({ kind: 'setVisibleToPlayers', visible: false });
|
||||
assert.equal(store.getState().active, false);
|
||||
assert.equal(store.getState().visibleToPlayers, false);
|
||||
assert.deepEqual(store.getState().values, values);
|
||||
});
|
||||
|
||||
void test('diceRoll: d100 values are tens faces only', () => {
|
||||
const store = new DiceRollSessionStore();
|
||||
store.dispatch({ kind: 'roll', count: 5, sides: 100 });
|
||||
@@ -30,12 +55,14 @@ void test('diceRoll: d100 values are tens faces only', () => {
|
||||
assert.equal(st.total, st.values.reduce((a, b) => a + b, 0));
|
||||
});
|
||||
|
||||
void test('diceRoll: clear resets', () => {
|
||||
void test('diceRoll: clear resets but keeps visibleToPlayers', () => {
|
||||
const store = new DiceRollSessionStore();
|
||||
store.dispatch({ kind: 'setVisibleToPlayers', visible: false });
|
||||
store.dispatch({ kind: 'roll', count: 1, sides: 20 });
|
||||
store.dispatch({ kind: 'clear' });
|
||||
assert.equal(store.getState().active, false);
|
||||
assert.deepEqual(store.getState().values, []);
|
||||
assert.equal(store.getState().visibleToPlayers, false);
|
||||
});
|
||||
|
||||
void test('diceRoll: hideOverlay keeps values for master UI', () => {
|
||||
@@ -48,6 +75,16 @@ void test('diceRoll: hideOverlay keeps values for master UI', () => {
|
||||
assert.deepEqual(store.getState().values, values);
|
||||
assert.equal(store.getState().total, total);
|
||||
assert.equal(store.getState().notation, '2d6');
|
||||
assert.equal(store.getState().visibleToPlayers, true);
|
||||
});
|
||||
|
||||
void test('diceRoll: roll with zero count is no-op', () => {
|
||||
const store = new DiceRollSessionStore();
|
||||
store.dispatch({ kind: 'setVisibleToPlayers', visible: false });
|
||||
const before = store.getState().revision;
|
||||
store.dispatch({ kind: 'roll', count: 0, sides: 6 });
|
||||
assert.equal(store.getState().revision, before);
|
||||
assert.deepEqual(store.getState().values, []);
|
||||
});
|
||||
|
||||
void test('formatPredeterminedDiceNotation', () => {
|
||||
|
||||
Reference in New Issue
Block a user