From 35b33daee02a181654ed9555fe901d4226dc4021 Mon Sep 17 00:00:00 2001 From: Eric Dahl Date: Fri, 22 May 2026 02:03:07 -0400 Subject: [PATCH] Add damage-dealing random events to events.json (#104). - array_burnout: damages solar_array (minDay 18, weight 1, requiresBuilding solar_array) - systems_fault: damageRandomBuilt with morale -4 (minDay 15, weight 1) - survival_45.json: add periodic repair every 3 days so damage events are recovered - Two new damage tests: TestDamageEvent_SolarArrayDamagedViaApplyEventByID, TestDamageEvent_RandomBuilt_DamagesBuiltFacility Assisted-by: Crush:claude-sonnet-4-5 --- data/events.json | 19 ++++++++++ internal/game/damage_test.go | 71 ++++++++++++++++++++++++++++++++++++ scripts/survival_45.json | 38 ++++++++++++++++++- 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/data/events.json b/data/events.json index 33d5b26..bf55c3f 100644 --- a/data/events.json +++ b/data/events.json @@ -59,5 +59,24 @@ "description": "Fine regolith infiltrated the greenhouse seals.", "effects": { "food": -6, "morale": -3 }, "minDay": 14 + }, + { + "id": "array_burnout", + "title": "Array Burnout", + "description": "A voltage spike scorched the primary collector. Daily output halved until repaired.", + "effects": {}, + "damageBuilding": "solar_array", + "requiresBuilding": "solar_array", + "minDay": 18, + "weight": 1 + }, + { + "id": "systems_fault", + "title": "Systems Fault", + "description": "An untraced fault took down a key facility. Output halved until the crew gets to it.", + "effects": { "morale": -4 }, + "damageRandomBuilt": true, + "minDay": 15, + "weight": 1 } ] diff --git a/internal/game/damage_test.go b/internal/game/damage_test.go index b51abad..0a3a9b8 100644 --- a/internal/game/damage_test.go +++ b/internal/game/damage_test.go @@ -63,3 +63,74 @@ func TestRepairBuilding_ClearsDamageAndChargesByLevel(t *testing.T) { t.Fatalf("Credits = %d, want %d", s.Credits, 100-wantCost) } } + +func TestDamageEvent_SolarArrayDamagedViaApplyEventByID(t *testing.T) { + content, err := LoadEmbeddedContent() + if err != nil { + t.Fatalf("LoadEmbeddedContent: %v", err) + } + s := NewState(content) + s.Buildings["solar_array"] = Building{DefID: "solar_array", Level: 2} + s.Day = 10 + + // Find an event that damages solar_array + var damageEventID string + for _, e := range s.Content.Events { + if e.DamageBuilding == "solar_array" { + damageEventID = e.ID + break + } + } + if damageEventID == "" { + t.Skip("no solar_array damage event in events.json — add one first") + } + + s.applyEventByID(damageEventID) + if !s.Buildings["solar_array"].Damaged { + t.Fatal("solar_array should be Damaged after damage event") + } + + // Daily output should be halved + def, _ := s.FindBuilding("solar_array") + effects := dailyEffectsScaled(def, s.Buildings["solar_array"]) + b := s.Buildings["solar_array"] + b.Damaged = false + fullEffects := dailyEffectsScaled(def, b) + if effects["power"] != fullEffects["power"]/2 { + t.Fatalf("damaged power %d want %d (half of %d)", effects["power"], fullEffects["power"]/2, fullEffects["power"]) + } +} + +func TestDamageEvent_RandomBuilt_DamagesBuiltFacility(t *testing.T) { + content, err := LoadEmbeddedContent() + if err != nil { + t.Fatalf("LoadEmbeddedContent: %v", err) + } + s := NewState(content) + s.Buildings["solar_array"] = Building{DefID: "solar_array", Level: 1} + s.Day = 20 + + var randDamageEventID string + for _, e := range s.Content.Events { + if e.DamageRandomBuilt { + randDamageEventID = e.ID + break + } + } + if randDamageEventID == "" { + t.Skip("no damageRandomBuilt event in events.json — add one first") + } + + s.applyEventByID(randDamageEventID) + // at least one built building should be damaged + anyDamaged := false + for _, b := range s.Buildings { + if b.Damaged { + anyDamaged = true + break + } + } + if !anyDamaged { + t.Fatal("expected at least one building damaged after damageRandomBuilt event") + } +} diff --git a/scripts/survival_45.json b/scripts/survival_45.json index 7638692..f1207e4 100644 --- a/scripts/survival_45.json +++ b/scripts/survival_45.json @@ -23,6 +23,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "build", "building_id": "workshop" @@ -42,6 +45,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "build", "building_id": "hydroponics" @@ -65,6 +71,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -91,6 +100,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -100,6 +112,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -109,6 +124,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -118,6 +136,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -127,6 +148,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -136,6 +160,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -145,6 +172,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -154,6 +184,9 @@ { "type": "next_day" }, + { + "type": "repair" + }, { "type": "next_day" }, @@ -162,6 +195,9 @@ }, { "type": "next_day" + }, + { + "type": "repair" } ] -} \ No newline at end of file +}