diff --git a/internal/plugin/combat_narrative.go b/internal/plugin/combat_narrative.go index 2a7c750..5337ff3 100644 --- a/internal/plugin/combat_narrative.go +++ b/internal/plugin/combat_narrative.go @@ -326,9 +326,9 @@ func renderEvent(e CombatEvent, playerName, enemyName string, result CombatResul case "survive_at_1": return pickRand(narrativeSurvive) case "stat_drain": - return pickRand(narrativeStatDrain) + return fmt.Sprintf(pickRand(narrativeStatDrain), e.Damage) case "debuff": - return pickRand(narrativeDebuff) + return fmt.Sprintf(pickRand(narrativeDebuff), e.Damage) case "max_hp_drain": return fmt.Sprintf(pickRand(narrativeMaxHPDrain), e.Damage) @@ -346,7 +346,7 @@ func renderEvent(e CombatEvent, playerName, enemyName string, result CombatResul case "fear_resist": return pickRand(narrativeFearResist) case "ally_buff": - return pickRand(narrativeAllyBuff) + return fmt.Sprintf(pickRand(narrativeAllyBuff), e.Damage) case "timeout": return pickRand(narrativeTimeout) diff --git a/internal/plugin/combat_narrative_drain_test.go b/internal/plugin/combat_narrative_drain_test.go new file mode 100644 index 0000000..94c9813 --- /dev/null +++ b/internal/plugin/combat_narrative_drain_test.go @@ -0,0 +1,24 @@ +package plugin + +import ( + "strings" + "testing" +) + +// TestRenderEvent_StatefulDrainsFormatMagnitude is a regression test for the +// leaked "%d" in stateful enemy-effect narration. stat_drain, debuff and +// ally_buff carry their magnitude in CombatEvent.Damage and their flavor +// pools contain a %d placeholder; renderEvent must fmt.Sprintf them rather +// than emit the template raw (which surfaced "-%d damage" to players). +func TestRenderEvent_StatefulDrainsFormatMagnitude(t *testing.T) { + for _, action := range []string{"stat_drain", "debuff", "ally_buff"} { + e := CombatEvent{Actor: "enemy", Action: action, Damage: 4} + out := renderEvent(e, "Rurina", "Shadow", CombatResult{}, newActionPicker()) + if strings.Contains(out, "%") { + t.Errorf("%s: leaked format placeholder in output: %q", action, out) + } + if !strings.Contains(out, "4") { + t.Errorf("%s: expected magnitude 4 in output: %q", action, out) + } + } +}