Tests: EB-1 structure damage/death, fortress targeting, persistence v3

10 new EditMode tests (312 total, all green): HealthApplyDamage destroys a Destructible at 0 + a wounded structure survives clamped; PickWeightedNearest x5 (player-only, structure-preferred-by-weight, player-in-the-way wins, raze undefended base, no targets); persistence (StructureSave.HP round-trip + writes v3, v2 in the load floor, SaveApply.ToPending maps the wounded HP - the staging-copy bug the pre-code review caught); + the StructureAggroWeight default pin. See DR-032.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 23:53:50 -07:00
parent 73cfe2943d
commit 66edbdec69
4 changed files with 139 additions and 0 deletions
@@ -103,5 +103,44 @@ namespace ProjectM.Tests
Assert.AreEqual(0, em.GetBuffer<StorageEntry>(e).Length);
}
[Test]
public void StructureSave_HP_RoundTrips_And_Writes_V3()
{
var data = new SaveData { Structures = new[] { new StructureSave { Type = 1, CellX = 1, CellZ = 2, HP = 37f } } };
var back = JsonUtility.FromJson<SaveData>(JsonUtility.ToJson(data));
Assert.AreEqual(3, back.Version, "EB-1: new saves write v3.");
Assert.AreEqual(1, back.Structures.Length);
Assert.AreEqual(37f, back.Structures[0].HP, 1e-4f, "the wounded HP round-trips through JSON.");
}
[Test]
public void V2_Save_IsWithinLoadableRange_And_ZeroHp_Restores_Full()
{
// A pre-EB-1 v2 save sits inside the additive load floor [Min,Current], so SaveService.Load accepts it;
// an unset HP (0) is mapped by BaseRestoreSystem to the baked Max (structures come back at full HP).
var v2 = new SaveData { Version = 2, GoalCharge = 3, GoalTarget = 10, Structures = new[] { new StructureSave { Type = 1, CellX = 2, CellZ = 4 } } };
var back = JsonUtility.FromJson<SaveData>(JsonUtility.ToJson(v2));
Assert.AreEqual(2, back.Version);
Assert.GreaterOrEqual(back.Version, SaveData.MinLoadableVersion, "v2 is at/above the load floor.");
Assert.LessOrEqual(back.Version, SaveData.CurrentVersion);
Assert.AreEqual(0f, back.Structures[0].HP, 1e-4f, "unset HP (0) -> restore maps to baked Max.");
}
[Test]
public void ToPending_Maps_All_Fields_Including_The_Wounded_HP()
{
// The WorldLauncher save->stage copy: omitting any field here silently restores at full HP (review-caught).
var s = new StructureSave { Type = 1, CellX = 3, CellZ = -2, Direction = 2, RemainingTicks = 50, ConveyorResId = 1, ConveyorCount = 4, HP = 37f };
var p = SaveApply.ToPending(s);
Assert.AreEqual(1, p.Type);
Assert.AreEqual(3, p.CellX);
Assert.AreEqual(-2, p.CellZ);
Assert.AreEqual(2, p.Direction);
Assert.AreEqual(50u, p.RemainingTicks);
Assert.AreEqual(1, p.ConveyorResId);
Assert.AreEqual(4, p.ConveyorCount);
Assert.AreEqual(37f, p.HP, 1e-4f, "the wounded HP survives the save->staging copy.");
}
}
}