using Unity.Entities;
using Unity.NetCode;
namespace ProjectM.Simulation
{
///
/// END-2 — server-only marker of which run-phase the macro loop is in. Lives on the GLOBAL CycleDirector
/// entity beside //; NOT replicated
/// (the client never needs to distinguish "the final siege is armed" — the larger wave + telegraph already read
/// as escalation; the client shows the terminal banner from the replicated instead).
/// SINGLE writer: GoalReachedSystem flips ->
/// exactly once when reaches Target.
/// Added at spawn by CycleDirectorSpawnSystem (like CycleRuntime/ThreatState), so it is server-world-only
/// and never on the ghost serializer (no re-hash). A byte (never an enum) so a Bursted reader can't trip
/// the cross-assembly-enum Burst ICE.
///
public struct RunPhase : IComponentData
{
public byte Value;
}
/// Phase constants for (bytes — never an enum on a Bursted path).
public static class RunPhaseId
{
/// Normal play: scheduled / post-expedition sieges arm; the goal meter climbs +1 per survived siege.
public const byte Normal = 0;
/// The goal cap was reached: the larger FINAL siege is armed/running. No further sieges arm.
public const byte FinalDefense = 1;
}
///
/// END-2 — the terminal run outcome: the LATCHING win/lose state, REPLICATED so the client HUD shows the
/// victory/loss banner by simply observing it (no fragile client-side reconstruction). Rides the GLOBAL
/// untagged CycleDirector ghost (relevant to every connection in every region — it must NEVER be region-tagged;
/// the shared-global-state rule), one [GhostField] byte alongside /
/// . SINGLE writer: CyclePhaseSystem latches
/// (final siege cleared) or (Core breached during the final siege). Once it is
/// non- the run HALTS (GoalReachedSystem + ThreatDirectorSystem stop arming;
/// CoreRestoreSystem stops regen). Baked onto the prefab so it is part of the ghost (adding this [GhostField]
/// re-hashes the CycleDirector ghost -> one re-bake); born-correct at spawn (InProgress for a New Game, or the
/// persisted value on Continue — SaveData v5).
///
public struct RunOutcome : IComponentData
{
[GhostField] public byte Value;
}
/// Outcome constants for (bytes — never an enum on a Bursted/serialized path).
public static class RunOutcomeId
{
/// The run is live (no terminal result yet).
public const byte InProgress = 0;
/// The final siege was survived — the Engine holds. Terminal; the run halts.
public const byte Victory = 1;
/// The Core was breached during the final siege — overrun. Terminal; the run halts.
public const byte Loss = 2;
}
}