namespace ProjectM.Simulation { /// One base "prep loadout" option: spend a base resource before launch for a RUN-SCOPED stat buff /// (stripped on the Returning edge like a boon). Mechanical fields only — the HUD supplies display labels. public struct PrepRow { public byte Id; public byte CostResId; // ResourceId.* public int Cost; public byte Target; // StatTarget public byte Op; // ModOp public float Value; } /// /// The base PREP-LOADOUT catalog (DR-046): the player funds each run's power from base resources at Staging. A /// purchase appends ONE run-scoped in the prep SourceId band /// ( + Id), which 's PrepPurchaseSystem gates once-per-run /// by that SourceId's PRESENCE (its lifetime == the band, stripped on Returning — so it re-buys next run for free, /// no separate latch). A plain managed static table (read by the non-Burst receiver + the managed HUD). /// public static class PrepCatalog { public static readonly PrepRow[] Rows = { new PrepRow { Id = 0, CostResId = ResourceId.Ore, Cost = 30, Target = (byte)StatTarget.MaxHealth, Op = (byte)ModOp.Flat, Value = 30f }, new PrepRow { Id = 1, CostResId = ResourceId.Biomass, Cost = 40, Target = (byte)StatTarget.MoveSpeed, Op = (byte)ModOp.PercentMult, Value = 0.12f }, new PrepRow { Id = 2, CostResId = ResourceId.Aether, Cost = 25, Target = (byte)StatTarget.MeleeDamage, Op = (byte)ModOp.PercentMult, Value = 0.20f }, new PrepRow { Id = 3, CostResId = ResourceId.Aether, Cost = 25, Target = (byte)StatTarget.Damage, Op = (byte)ModOp.PercentMult, Value = 0.20f }, }; public static int Count => Rows.Length; public static bool TryGet(byte id, out PrepRow row) { for (int i = 0; i < Rows.Length; i++) if (Rows[i].Id == id) { row = Rows[i]; return true; } row = default; return false; } } }