Add encounter difficulty indicator (5.5e XP budget)
Live 3-bar difficulty indicator in the top bar showing encounter difficulty (Trivial/Low/Moderate/High) based on the 2024 5.5e XP budget system. Automatically derived from PC levels and bestiary creature CRs. - Add optional level field (1-20) to PlayerCharacter - Add CR-to-XP and XP Budget per Character lookup tables in domain - Add calculateEncounterDifficulty pure function - Add DifficultyIndicator component with color-coded bars and tooltip - Add useDifficulty hook composing encounter, PC, and bestiary contexts - Indicator hidden when no PCs with levels or no bestiary-linked monsters - Level field in PC create/edit forms, persisted in storage Closes #18 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -186,6 +186,38 @@ describe("player-character-storage", () => {
|
||||
expect(loadPlayerCharacters()).toEqual([]);
|
||||
});
|
||||
|
||||
it("preserves level through save/load round-trip", () => {
|
||||
const pc = makePC({ level: 5 });
|
||||
savePlayerCharacters([pc]);
|
||||
const loaded = loadPlayerCharacters();
|
||||
expect(loaded[0].level).toBe(5);
|
||||
});
|
||||
|
||||
it("preserves undefined level through save/load round-trip", () => {
|
||||
const pc = makePC();
|
||||
savePlayerCharacters([pc]);
|
||||
const loaded = loadPlayerCharacters();
|
||||
expect(loaded[0].level).toBeUndefined();
|
||||
});
|
||||
|
||||
it("discards character with invalid level", () => {
|
||||
mockStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
JSON.stringify([
|
||||
{
|
||||
id: "pc-1",
|
||||
name: "Test",
|
||||
ac: 10,
|
||||
maxHp: 50,
|
||||
color: "blue",
|
||||
icon: "sword",
|
||||
level: 25,
|
||||
},
|
||||
]),
|
||||
);
|
||||
expect(loadPlayerCharacters()).toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps valid characters and discards invalid ones", () => {
|
||||
mockStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
|
||||
Reference in New Issue
Block a user