// Temp HP: damage hits temp first, then regular. // setTempHp replaces (no stacking). Healing regular HP ignores temp. const shared = require('@ttrpg/shared'); const { makeParticipant, applyHpChange, setTempHp, addParticipant } = shared; const { mockCtx } = require('./_helpers'); function setupEnc() { const { ctx } = mockCtx(); return { enc: { id: 'enc1', name: 'TempEnc', participants: [], isStarted: false, isPaused: false, round: 0 }, ctx, }; } describe('temp HP', () => { test('setTempHp sets tempHp on participant', async () => { const { enc, ctx } = setupEnc(); const p = makeParticipant({ name: 'Hero', type: 'character', initiative: 10, maxHp: 20, currentHp: 20, }); let e = await addParticipant(enc, p, ctx); e = await setTempHp(e, p.id, 5, ctx); expect(e.participants[0].tempHp).toBe(5); }); test('setTempHp replaces existing temp (no stacking)', async () => { const { enc, ctx } = setupEnc(); const p = makeParticipant({ name: 'Hero', type: 'character', initiative: 10, maxHp: 20, currentHp: 20, }); let e = await addParticipant(enc, p, ctx); e = await setTempHp(e, p.id, 5, ctx); e = await setTempHp(e, p.id, 3, ctx); expect(e.participants[0].tempHp).toBe(3); }); test('setTempHp to 0 clears temp', async () => { const { enc, ctx } = setupEnc(); const p = makeParticipant({ name: 'Hero', type: 'character', initiative: 10, maxHp: 20, currentHp: 20, }); let e = await addParticipant(enc, p, ctx); e = await setTempHp(e, p.id, 5, ctx); e = await setTempHp(e, p.id, 0, ctx); expect(e.participants[0].tempHp).toBe(0); }); test('damage: temp absorbs before regular HP', async () => { const { enc, ctx } = setupEnc(); const p = makeParticipant({ name: 'Hero', type: 'character', initiative: 10, maxHp: 20, currentHp: 20, }); let e = await addParticipant(enc, p, ctx); e = await setTempHp(e, p.id, 5, ctx); e = await applyHpChange(e, p.id, 'damage', 8, ctx); expect(e.participants[0].tempHp).toBe(0); expect(e.participants[0].currentHp).toBe(17); }); test('damage less than temp: only temp reduced', async () => { const { enc, ctx } = setupEnc(); const p = makeParticipant({ name: 'Hero', type: 'character', initiative: 10, maxHp: 20, currentHp: 20, }); let e = await addParticipant(enc, p, ctx); e = await setTempHp(e, p.id, 10, ctx); e = await applyHpChange(e, p.id, 'damage', 4, ctx); expect(e.participants[0].tempHp).toBe(6); expect(e.participants[0].currentHp).toBe(20); }); test('heal: does not affect temp HP', async () => { const { enc, ctx } = setupEnc(); const p = makeParticipant({ name: 'Hero', type: 'character', initiative: 10, maxHp: 20, currentHp: 10, }); let e = await addParticipant(enc, p, ctx); e = await setTempHp(e, p.id, 5, ctx); e = await applyHpChange(e, p.id, 'heal', 8, ctx); expect(e.participants[0].tempHp).toBe(5); expect(e.participants[0].currentHp).toBe(18); }); test('damage exactly equals temp: temp gone, regular intact', async () => { const { enc, ctx } = setupEnc(); const p = makeParticipant({ name: 'Hero', type: 'character', initiative: 10, maxHp: 20, currentHp: 20, }); let e = await addParticipant(enc, p, ctx); e = await setTempHp(e, p.id, 5, ctx); e = await applyHpChange(e, p.id, 'damage', 5, ctx); expect(e.participants[0].tempHp).toBe(0); expect(e.participants[0].currentHp).toBe(20); }); test('makeParticipant: tempHp defaults to 0', async () => { const p = makeParticipant({ name: 'Hero', type: 'character', initiative: 10, maxHp: 20, currentHp: 20, }); expect(p.tempHp).toBe(0); }); });