Generic (non-5e) ruleset mode + UI polish + combat switch fix #7
@@ -0,0 +1,49 @@
|
|||||||
|
// addParticipants (bulk) must slot by initiative, not append.
|
||||||
|
const shared = require('@ttrpg/shared');
|
||||||
|
const { mockCtx } = require('./_helpers');
|
||||||
|
const { buildCharacterParticipant, buildMonsterParticipant, addParticipants, makeParticipant } = shared;
|
||||||
|
|
||||||
|
function enc(ps = []) {
|
||||||
|
return { name:'t', participants: ps, isStarted: false, isPaused: false,
|
||||||
|
round: 0, currentTurnParticipantId: null, turnOrderIds: [] };
|
||||||
|
}
|
||||||
|
function p(id, init) {
|
||||||
|
return makeParticipant({ id, name: id, type: 'monster', initiative: init, maxHp: 10, currentHp: 10 });
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('addParticipants slot order', () => {
|
||||||
|
test('bulk add slots by initiative desc', async () => {
|
||||||
|
const { ctx } = mockCtx();
|
||||||
|
let e = enc([]);
|
||||||
|
e = await addParticipants(e, [p('a', 5), p('b', 20), p('c', 10)], ctx);
|
||||||
|
expect(e.participants.map(x => x.id)).toEqual(['b', 'c', 'a']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('bulk add preserves existing order + slots new', async () => {
|
||||||
|
const { ctx } = mockCtx();
|
||||||
|
let e = enc([p('a', 20), p('b', 5)]);
|
||||||
|
e = await addParticipants(e, [p('c', 10)], ctx);
|
||||||
|
expect(e.participants.map(x => x.id)).toEqual(['a', 'c', 'b']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('bulk add same-init appends after existing (stable tie)', async () => {
|
||||||
|
const { ctx } = mockCtx();
|
||||||
|
let e = enc([p('a', 10)]);
|
||||||
|
e = await addParticipants(e, [p('b', 10), p('c', 10)], ctx);
|
||||||
|
expect(e.participants.map(x => x.id)).toEqual(['a', 'b', 'c']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('bulk add mixed inits into existing list', async () => {
|
||||||
|
const { ctx } = mockCtx();
|
||||||
|
let e = enc([p('a', 15), p('b', 5)]);
|
||||||
|
e = await addParticipants(e, [p('c', 20), p('d', 10), p('e', 15)], ctx);
|
||||||
|
expect(e.participants.map(x => x.id)).toEqual(['c', 'a', 'e', 'd', 'b']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('bulk add updates turnOrderIds to match', async () => {
|
||||||
|
const { ctx } = mockCtx();
|
||||||
|
let e = enc([]);
|
||||||
|
e = await addParticipants(e, [p('a', 5), p('b', 20)], ctx);
|
||||||
|
expect(e.turnOrderIds).toEqual(['b', 'a']);
|
||||||
|
});
|
||||||
|
});
|
||||||
+9
-3
@@ -479,14 +479,20 @@ async function addParticipant(encounter, participant, ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function addParticipants(encounter, newParticipants, ctx) {
|
async function addParticipants(encounter, newParticipants, ctx) {
|
||||||
const updatedParticipants = [...(encounter.participants || []), ...newParticipants];
|
// Slot each new participant into list by initiative (desc), preserve
|
||||||
|
// existing order + drag-established ties. Matches addParticipant semantics.
|
||||||
|
let base = [...(encounter.participants || [])];
|
||||||
|
for (const np of newParticipants) {
|
||||||
|
const idx = slotIndexForInit(base, np.initiative);
|
||||||
|
base.splice(idx, 0, np);
|
||||||
|
}
|
||||||
const names = newParticipants.map(p => p.name).join(', ');
|
const names = newParticipants.map(p => p.name).join(', ');
|
||||||
const patch = { participants: updatedParticipants };
|
const patch = { participants: base, ...syncTurnOrder(base) };
|
||||||
const log = {
|
const log = {
|
||||||
type: 'add_participants',
|
type: 'add_participants',
|
||||||
message: `Added ${newParticipants.length} participant${newParticipants.length === 1 ? '' : 's'}: ${names}`,
|
message: `Added ${newParticipants.length} participant${newParticipants.length === 1 ? '' : 's'}: ${names}`,
|
||||||
delta: { count: newParticipants.length },
|
delta: { count: newParticipants.length },
|
||||||
undo: { participants: newParticipants },
|
undo: { participants: newParticipants, newTurnOrderIds: patch.turnOrderIds },
|
||||||
};
|
};
|
||||||
return commit(encounter, patch, log, ctx);
|
return commit(encounter, patch, log, ctx);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user