Death source tracking + combat threat/jitter fixes

- Adventure characters now record DeathSource ("adventure"|"arena") and
  DeathLocation when killed. Threaded through Kill() and transitionDeath.
  Daily report uses the recorded death location instead of misattributing
  arena deaths to the day's adventure log: when DeathSource != "adventure",
  the adventure block shows the alive icon and a separate "Later fell in
  {location}." line. Standout-loss flavor uses DeathLocation. Empty
  DeathSource (legacy rows) falls back to current behavior.
- calcDamage applies a ±15% per-hit jitter, so successive hits in a phase
  no longer produce identical numbers. Previously every hit in a phase was
  flat (e.g. 17, 17, 17, 17) and mirror-symmetric between player/enemy,
  reading as scripted.
- assessThreat rewritten to use the engine's actual penetration formula:
  damage-per-round each direction, then rounds-to-kill ratio. The old
  additive HP+Attack*3 model ignored Defense, so even fights could be
  rated trivial — players died after consumables were skipped with the
  "threat assessed as manageable" message.
- SelectConsumables never skips on trivial when arenaRound > 0. Arena
  losses cost real money and equipment, so the cost of a wrong assessment
  is too high to gamble on; adventure-side fights still skip trivial
  threats to avoid wasting items on chump enemies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-03 11:42:00 -07:00
parent a00987e75c
commit 8e0fe0230c
9 changed files with 93 additions and 19 deletions

View File

@@ -142,6 +142,8 @@ func runMigrations(d *sql.DB) error {
`ALTER TABLE coop_dungeon_gifts ADD COLUMN applied_at DATETIME`,
`ALTER TABLE coop_dungeon_gifts ADD COLUMN stack_lead_id INTEGER`,
`ALTER TABLE adventure_characters ADD COLUMN crafts_succeeded INTEGER NOT NULL DEFAULT 0`,
`ALTER TABLE adventure_characters ADD COLUMN death_source TEXT NOT NULL DEFAULT ''`,
`ALTER TABLE adventure_characters ADD COLUMN death_location TEXT NOT NULL DEFAULT ''`,
}
for _, stmt := range columnMigrations {
if _, err := d.Exec(stmt); err != nil {