mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 08:52:42 +00:00
Combat: fix wounded-carry HP display + auto-crit narration
Two bugs reported back-to-back from a Rogue's run: 1. HP display reset between battles. End of fight 1: 101/123 → start of fight 2: 100/100. applyDnDHPScaling was overwriting Stats.MaxHP with the scaled wound value, so the display denominator dropped along with the numerator. Wounded carry-over became invisible. Fix: introduce CombatStats.StartHP. Combat engine reads it as the entry-HP when set; MaxHP stays put. Display now reads "100/123" as intended. 2. Auto-crit fired on a roll of 11 with no narrative tell. Rogue passive AutoCritFirst was triggering correctly, but the renderer used the generic crit pool, so the player saw "🎲 11 vs AC 10 → CRIT" with no indication their *class* caused it. Fix: tag the crit event with Desc="auto_crit" when the passive (not the dice) caused it; new narrativePlayerAutoCrit pool calls out the training/instinct/exploit theme. Test bound for T5 dungeon death rate loosened from 0.02 to 0.01 — the new Sudden Death phase from the previous commit shifted geared-T5 fights slightly toward player wins. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,10 @@ func TestApplyDnDHPScaling_FullHP(t *testing.T) {
|
||||
c := &DnDCharacter{HPMax: 50, HPCurrent: 50}
|
||||
applyDnDHPScaling(&stats, c)
|
||||
if stats.MaxHP != 100 {
|
||||
t.Errorf("full HP: MaxHP scaled to %d, want unchanged 100", stats.MaxHP)
|
||||
t.Errorf("full HP: MaxHP changed to %d, want unchanged 100", stats.MaxHP)
|
||||
}
|
||||
if stats.StartHP != 0 {
|
||||
t.Errorf("full HP: StartHP = %d, want 0 (unset)", stats.StartHP)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +23,11 @@ func TestApplyDnDHPScaling_HalfHP(t *testing.T) {
|
||||
stats := CombatStats{MaxHP: 100}
|
||||
c := &DnDCharacter{HPMax: 50, HPCurrent: 25}
|
||||
applyDnDHPScaling(&stats, c)
|
||||
if stats.MaxHP != 50 {
|
||||
t.Errorf("50%% HP: MaxHP = %d, want 50", stats.MaxHP)
|
||||
if stats.MaxHP != 100 {
|
||||
t.Errorf("50%% HP: MaxHP = %d, want unchanged 100", stats.MaxHP)
|
||||
}
|
||||
if stats.StartHP != 50 {
|
||||
t.Errorf("50%% HP: StartHP = %d, want 50", stats.StartHP)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,21 +35,24 @@ func TestApplyDnDHPScaling_FloorAt25Pct(t *testing.T) {
|
||||
stats := CombatStats{MaxHP: 100}
|
||||
c := &DnDCharacter{HPMax: 50, HPCurrent: 0}
|
||||
applyDnDHPScaling(&stats, c)
|
||||
if stats.MaxHP != 25 {
|
||||
t.Errorf("0%% HP: MaxHP = %d, want 25 (floor)", stats.MaxHP)
|
||||
if stats.MaxHP != 100 {
|
||||
t.Errorf("0%% HP: MaxHP = %d, want unchanged 100", stats.MaxHP)
|
||||
}
|
||||
if stats.StartHP != 25 {
|
||||
t.Errorf("0%% HP: StartHP = %d, want 25 (floor)", stats.StartHP)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyDnDHPScaling_NoOpIfNilOrZero(t *testing.T) {
|
||||
stats := CombatStats{MaxHP: 100}
|
||||
applyDnDHPScaling(&stats, nil)
|
||||
if stats.MaxHP != 100 {
|
||||
t.Errorf("nil char: scaled to %d, want unchanged", stats.MaxHP)
|
||||
if stats.MaxHP != 100 || stats.StartHP != 0 {
|
||||
t.Errorf("nil char: MaxHP=%d StartHP=%d, want 100/0", stats.MaxHP, stats.StartHP)
|
||||
}
|
||||
c := &DnDCharacter{HPMax: 0}
|
||||
applyDnDHPScaling(&stats, c)
|
||||
if stats.MaxHP != 100 {
|
||||
t.Errorf("zero HPMax: scaled to %d, want unchanged", stats.MaxHP)
|
||||
if stats.MaxHP != 100 || stats.StartHP != 0 {
|
||||
t.Errorf("zero HPMax: MaxHP=%d StartHP=%d, want 100/0", stats.MaxHP, stats.StartHP)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user