Commit Graph

160 Commits

Author SHA1 Message Date
Bastian Wagner
909f793eb6 feat(api): expose effective HP and regen anchor from GET /characters/me
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 14:45:31 +02:00
Bastian Wagner
02037b2917 feat(api): CharacterStatsService reports effective (regenerated) HP
- Update CharacterStatsService constructor to accept CharacterVitalsService
- Compute currentHp via CharacterVitalsService.effectiveHp() instead of raw pass-through
- Add hpRegenPerSecond and hpRegenSince fields to EffectiveCharacterStats return type
- Update spec with new test cases for regeneration calculation and field pass-through
- Equipment and combat tests now fail as expected (separate tasks will fix constructor calls)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 14:41:17 +02:00
Bastian Wagner
47494abf50 feat(api): provide CharacterVitalsService from CharactersModule 2026-08-21 14:36:22 +02:00
Bastian Wagner
71f58bc1b6 feat(api): add CharacterVitalsService for anchored HP regeneration
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 14:32:18 +02:00
Bastian Wagner
ea26e4b844 feat(api): add HP regeneration rate constant 2026-08-21 14:29:35 +02:00
Bastian Wagner
19e08f0b16 feat(api): add hp_regen_since column for persistent HP regeneration
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 14:26:44 +02:00
Bastian Wagner
b55518b451 refactor(api): move Clock abstraction from travel to shared 2026-08-21 14:21:39 +02:00
Bastian Wagner
2579b23a5c Add implementation plan for persistent HP and out-of-combat regeneration
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 14:12:38 +02:00
Bastian Wagner
a75a670509 Add design doc for persistent character HP and out-of-combat regeneration
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 13:56:43 +02:00
Bastian Wagner
dd90e05446 optik 2026-08-21 13:39:52 +02:00
Bastian Wagner
987242541d inventory 2026-08-21 12:52:44 +02:00
Bastian Wagner
a376fb7128 Add implementation plan for Playable Slice 0.6.5 (Renown & Reputation)
16 tasks: pure-function power curve and rank resolver, one migration
covering Character/ItemDefinition/ItemType/CombatReward changes plus
five new tables, three new domain services (Renown, Reputation,
TurnIn), XP removal from the combat reward pipeline, requiredLevel
gate removal, seed content for Grenzwacht/Räuberabzeichen/turn-ins,
a fixture sweep, and the web-side Renown/Reputation surfaces.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 08:34:22 +02:00
Bastian Wagner
65dfb466cd Add design doc for Playable Slice 0.6.5 (Renown & Reputation Foundation)
Records every judgment call the spec left open — Renown/Reputation
data model, service signatures, migration strategy, combat reward
pipeline changes, and API/frontend surface — as an explicit, auditable
ruling with its cost if wrong, per instruction to implement this slice
without confirmation stops.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 08:21:14 +02:00
Bastian Wagner
62d6677298 fix(combat): show the potion heal immediately instead of folding it into the monster's reply 2026-08-20 23:54:02 +02:00
Bastian Wagner
1aac3416fa fix(combat): clear the monster's pending action once it is defeated 2026-08-20 23:10:47 +02:00
Bastian Wagner
e2f29d5eb6 fix(combat): keep the busy() re-entrancy guard, split the action-mapping test instead
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 22:38:52 +02:00
Bastian Wagner
0126d1dea1 feat(combat): add the five-action bar, telegraph banner, and generalized round animation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 22:19:13 +02:00
Bastian Wagner
b8d00278b8 feat(combat): generalize the web combat action and expose potions/monster intent 2026-08-20 22:01:28 +02:00
Bastian Wagner
c7b9601eb4 feat(combat): validate potions, persist telegraph state, and expose both on the combat DTO
Also updates the pre-existing exact-equality playerState assertion in
combat-equipment-integration.spec.ts, which broke from the new
potionsRemaining field but wasn't listed in the task brief's file scope.
2026-08-20 21:48:51 +02:00
Bastian Wagner
43d2085d2c feat(combat): add the COMBAT_NO_POTIONS_REMAINING domain error 2026-08-20 21:40:56 +02:00
Bastian Wagner
6eb0f21360 test(combat): cover DEFEND mitigating a resolving Heavy Attack 2026-08-20 21:37:36 +02:00
Bastian Wagner
b3dac8f61c feat(combat): implement HEAVY_STRIKE, SHIELD_BASH, DEFEND, POTION, and monster telegraphing 2026-08-20 21:27:12 +02:00
Bastian Wagner
fc1873e41f feat(combat): model monster intent and potion count in combat state types 2026-08-20 21:21:08 +02:00
Bastian Wagner
922c12f20f feat(combat): migrate combat_event_type_enum for Slice 0.6 event types 2026-08-20 21:17:37 +02:00
Bastian Wagner
6f1afaf5a3 feat(combat): add the Slice 0.6 action and event-type enum members 2026-08-20 21:12:46 +02:00
Bastian Wagner
eed247d318 feat(combat): support a damage multiplier in calculateDamage 2026-08-20 21:06:54 +02:00
Bastian Wagner
96d04d8ba3 Fix plan defect found in SDD pre-flight scan: Task 8 fixture patch
hunt-page.component.spec.ts and resume-combat.spec.ts each build a
direct type-annotated Combat literal that the new required
CombatPlayer/CombatMonster fields would break at compile time.
Verified with an isolated tsc --strict probe, and used the same probe
to confirm the combat.service.spec.ts `as Combat` fixtures do NOT
break (structural widening through the type assertion), so no change
needed there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 21:04:19 +02:00
Bastian Wagner
67df86a818 Ignore .worktrees/ for isolated feature-branch workspaces
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 20:52:36 +02:00
Bastian Wagner
9d396b7d96 Add implementation plan for Playable Slice 0.6 (Full First Combat)
Covers the engine rewrite for HEAVY_STRIKE/SHIELD_BASH/DEFEND/POTION,
deterministic monster telegraphing/interrupt, the DB migration for the
new combat event types, and the web action bar + telegraph banner.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 20:51:17 +02:00
Bastian Wagner
49a0008a2b Merge branch 'worktree-playable-slice-0.5-first-upgrade'
# Conflicts:
#	apps/web/src/app/core/api/game-api.service.ts
#	apps/web/src/app/features/combat/combat-page/combat-page.component.html
#	apps/web/src/app/features/combat/combat-page/combat-page.component.scss
#	apps/web/src/app/features/combat/combat-page/combat-page.component.spec.ts
#	apps/web/src/app/features/combat/combat-page/combat-page.component.ts
2026-08-20 19:42:10 +02:00
Bastian Wagner
0ce3b420e6 fix: address final-review findings (TopBar hydration, snapshot test, armor doc, inventory refresh test)
Fixes 4 Important findings from the final whole-branch review:
- /inventory never called WorldStore.load(), leaving the TopBar stuck on
  "loading" and characterLevel() silently defaulting to 1 for any character
  above level 1. Mirrors the same guard already used in HuntPageComponent.
- The combat/equipment snapshot-immutability integration test asserted only
  status/round, never the actual playerState snapshot the whole test claims
  to prove is untouched after a post-fight equip.
- Documented (comment only, no behavior change) that the demo character's
  armor dropping from the old hardcoded 6 to 0 is an intentional,
  spec-sanctioned tradeoff (Slice 0.5 spec Section19), not a bug.
- inventory.store.spec.ts's equip test used an identical inventory fixture
  before and after equip(), so a regression dropping the post-equip
  inventory re-fetch would still have passed. Now asserts the refetched
  fixture is actually reflected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 18:44:39 +02:00
Bastian Wagner
7f031ac1ce test(web): update app.spec.ts for the now-enabled Inventar nav button 2026-08-20 18:15:30 +02:00
Bastian Wagner
b1968da754 feat(web): add Inventar öffnen button to the victory screen 2026-08-20 18:04:13 +02:00
Bastian Wagner
724443de1e feat(web): route and enable the Inventar nav entry 2026-08-20 17:58:32 +02:00
Bastian Wagner
fdd8ae4e41 test(web): cover the same-slot equipped-item filter in InventoryPageComponent
The equippedItemInSelectedSlot computed is the riskiest logic this
component owns, but every existing test mocked selectedItem() as null,
so the slot-matching branch never ran and a regression to "any equipped
item" would have gone unnoticed. Adds a test with three items across two
slots that asserts the detail panel receives the same-slot equipped item,
not just any equipped item.
2026-08-20 17:54:38 +02:00
Bastian Wagner
9cb0158d80 import aufgeräumt 2026-08-20 17:52:04 +02:00
Bastian Wagner
1015505f38 feat(web): add inventory page with grid, detail panel, and equipment overview 2026-08-20 17:46:09 +02:00
Bastian Wagner
973d4e3ab4 feat(web): add inventory item detail/comparison panel 2026-08-20 17:39:46 +02:00
Bastian Wagner
10dd838465 feat(web): add InventoryStore 2026-08-20 17:32:52 +02:00
Bastian Wagner
c994a4c46f feat(web): add inventory/equipment API models and client methods 2026-08-20 17:27:15 +02:00
Bastian Wagner
90094ba1ae fix(api): key starting-sword seed idempotency on its real unique index
The CharacterItem idempotency check was looking up by the seed's own
literal id instead of the (characterId, itemDefinitionId) unique index
that CharacterItem actually enforces. If the demo character had already
looted a worn-short-sword naturally, re-running the seed would miss
that row and try to insert a colliding duplicate, breaking seeding
instead of being a safe no-op. Look up by the real domain key and reuse
whatever id is found when wiring up the CharacterEquipment row.
2026-08-20 17:23:45 +02:00
Bastian Wagner
6178b88573 feat(api): seed the starting sword as a real, equipped CharacterItem 2026-08-20 17:11:18 +02:00
Bastian Wagner
2526ac230d items 2026-08-20 17:07:40 +02:00
Bastian Wagner
2859a00597 test(api): prove equipping a weapon upgrade increases future combat damage 2026-08-20 17:01:45 +02:00
Bastian Wagner
820c69704f feat(api): add inventory API (GET /api/inventory) 2026-08-20 16:50:50 +02:00
Bastian Wagner
d1c7ffea86 Merge branch 'worktree-local-location-view' 2026-08-20 16:42:57 +02:00
Bastian Wagner
9df740e7d4 feat(api): add equipment API (GET/POST /api/equipment) 2026-08-20 16:39:23 +02:00
Bastian Wagner
3ee107694c address code review: POI order matches plan, self-documenting height reserve
Reorders the Verbrannte Straße POIs to plan §8's authored sequence
(hunt, investigate, search, then the scout) — purely a keyboard tab-order
fix, since hotspots are placed by percentage, not list order.

Rewrites the location page's viewport-height reserve as a calc() over the
same rem values the top bar and footer already declare as their own
min-block-size, with file:line pointers to both, instead of an opaque
191px constant. Doesn't remove the underlying coupling (still no
ResizeObserver / shared token), but a future edit to either component's
minimum height now has a documented, unit-matching term to update instead
of an unexplained magic number.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:33:42 +02:00
Bastian Wagner
f45f4b03cb feat(api): combat snapshots now use CharacterStatsService 2026-08-20 16:32:15 +02:00
Bastian Wagner
e5746dec5c feat(api): retire CharacterCombatStatsService; characters/me returns effective stats 2026-08-20 16:26:33 +02:00