NumberField draft buffer; surface massive-damage / death-at-0 rules in combat
- NumberField keeps a focus-time string draft so min-bounded fields (point-buy, HP, quantities) no longer snap to the minimum on every keystroke while retyping; the committed value is still always a clamped integer. - Combat tracker now logs the 5e death rules when a downed PC takes damage: instant death from massive damage (leftover >= max HP), otherwise a reminder to mark a death save failure (two on a crit). Surfaced, not auto-applied — the player owns their character's death-save count (consistent with the no-auto-roll design). New tested isMassiveDamageDeath() engine helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
applyInitiatives,
|
||||
currentCombatant,
|
||||
endEncounter,
|
||||
isMassiveDamageDeath,
|
||||
moveCombatant,
|
||||
nextTurn,
|
||||
previousTurn,
|
||||
@@ -216,3 +217,13 @@ describe('applyInitiatives', () => {
|
||||
expect(currentCombatant(e)?.id).toBe('b');
|
||||
});
|
||||
});
|
||||
|
||||
describe('isMassiveDamageDeath', () => {
|
||||
it('kills when leftover damage past 0 is >= max HP', () => {
|
||||
// 12-max PC at 4 HP takes 17 → current -13; 13 >= 12 → instant death
|
||||
expect(isMassiveDamageDeath(12, -13)).toBe(true);
|
||||
expect(isMassiveDamageDeath(12, -12)).toBe(true); // exactly max → dead
|
||||
expect(isMassiveDamageDeath(12, -11)).toBe(false); // one short → dying, not dead
|
||||
expect(isMassiveDamageDeath(12, 0)).toBe(false); // dropped to 0, no overflow
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user