Adv 2.0 L4d reader flip: pet helpers off AdvCharacter to PetState

All ten helpers in adventure_pets.go now take PetState (or *PetState
for petGrantXP) instead of *AdventureCharacter. mistyHousingHint takes
raw NPC counters since Misty fields stay on AdvCharacter for a later
phase. mistyReactivatePet returns bool; caller flips both stores.

DeathTransitionParams gained Pet PetState so combat_bridge no longer
touches the DB; arena caller loads PetState. PetState.HasPet() mirrors
AdvCharacter's. petMidnightCheck loads PetState per char.

L4 grep-empty exit criterion now holds for adventure_pets.go.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-09 11:07:40 -07:00
parent 0004a2e35c
commit 81cce0169f
9 changed files with 147 additions and 148 deletions

View File

@@ -323,6 +323,8 @@ This is also the right shape because zone-boss plumbing (bestiary, mood events,
- `go vet ./...` + `go test ./...` clean.
- **Reader flip deferred.** The L4 exit criterion (`grep 'AdventureCharacter\|CombatLevel' adventure_pets.go` empty) is NOT met yet: `adventure_pets.go`'s helpers (`petGrantXP`, `petRollCombatActions`, `petRollDitchRecovery`, `petVictoryText`, `petDeathText`, `petShouldArrive`, `petMorningEvent`, `petCheckSupplyShopUnlock`, `mistyHousingHint`, `mistyReactivatePet`) still take `*AdventureCharacter` because they're called from many external files (`adventure_babysit.go`, `adventure_scheduler.go`, `adventure_npcs.go`, `combat_bridge.go`, `combat_stats.go`, `dnd_sheet.go`, `adventure_arena.go`, `adventure_character.go`). Flipping these signatures is a cross-file refactor that can land after the soak window — at which point the helpers can take `userID` (and call `loadPetState`) and the call sites drop their `*AdventureCharacter` access. The DB-level migration (this step) is the prerequisite that unblocks that refactor.
**Reader flip (cross-file signature port) SHIPPED 2026-05-09.** All ten pet helpers in `adventure_pets.go` now take `PetState` (or `*PetState` for the test-only mutator `petGrantXP`) instead of `*AdventureCharacter`. `mistyHousingHint` takes `(mistyEncounterCount, mistyDonatedCount int, house HouseState)` — Misty NPC counters still live on AdvCharacter pending a later NPC phase. `mistyReactivatePet` returns `bool` (caller flips both AdvCharacter and `PetState`). `PetState` gained a `HasPet()` method mirroring `AdventureCharacter.HasPet()`. Call sites updated: `adventure_scheduler.go` (load PetState alongside HouseState in morning loop), `adventure_npcs.go::resolveMisty` (load PetState before reactivation check; pass NPC counters by value to the housing hint), `combat_bridge.go::transitionDeath` (now takes `Pet PetState` in `DeathTransitionParams`; arena caller in `adventure_arena.go::resolveArenaDeath` loads it; bridge no longer touches the DB so unit tests don't need DB init), and `petMidnightCheck` (loads PetState per char). Tests in `adventure_pets_test.go` and `combat_bridge_test.go` ported to construct `PetState` literals directly. Exit criterion now holds: `grep 'AdventureCharacter\|CombatLevel' internal/plugin/adventure_pets.go` is empty. `go vet ./... && go test ./...` clean.
### 6.5 L4e — Housing & mortgage
- `adventure_housing.go`, `adventure_mortgage.go`: HouseTier/loan fields → `player_meta`. `houseHPBonus` → applied to `DnDCharacter.HPMax` calculation (already a parallel hook in `dnd_sheet.go`'s `recomputeHPMax`).
- Mortgage scheduler tick stays — only the field source changes.