62 lines
3.0 KiB
C#
62 lines
3.0 KiB
C#
using Unity.Entities;
|
|
using Unity.NetCode;
|
|
|
|
namespace ProjectM.Simulation
|
|
{
|
|
/// <summary>
|
|
/// Macro-loop state for "The Aether Cycle": which phase the run is in, the cycle number, and the server
|
|
/// tick the current (timed) phase ends. Server-authoritative, maintained by CyclePhaseSystem. Currently a
|
|
/// server-side singleton; the [GhostField]s below are inert until it is moved onto the runtime-spawned
|
|
/// CycleDirector ghost (when the client HUD is wired), at which point the same struct replicates unchanged.
|
|
/// The Defend phase is NOT timed — it ends when the base-defense wave is cleared — so PhaseEndTick is only
|
|
/// meaningful in Expedition/Build (0 during Defend).
|
|
/// </summary>
|
|
public struct CycleState : IComponentData
|
|
{
|
|
/// <summary>Current phase (see <see cref="CyclePhase"/>).</summary>
|
|
[GhostField] public byte Phase;
|
|
|
|
/// <summary>1-based cycle counter (increments when a new Expedition begins).</summary>
|
|
[GhostField] public int CycleNumber;
|
|
|
|
/// <summary>Server tick the current timed phase ends (Expedition/Build only; 0 in Defend).</summary>
|
|
[GhostField] public uint PhaseEndTick;
|
|
}
|
|
|
|
/// <summary>Phase constants for <see cref="CycleState.Phase"/> (a byte, not an enum, for trivial Burst/serialization).</summary>
|
|
public static class CyclePhase
|
|
{
|
|
/// <summary>Out in the procedural field gathering resources (timed).</summary>
|
|
public const byte Expedition = 0;
|
|
|
|
/// <summary>The base is under assault by a Husk wave (ends when the wave is cleared).</summary>
|
|
public const byte Defend = 1;
|
|
|
|
/// <summary>Calm at base: spend resources to build/upgrade (timed).</summary>
|
|
public const byte Build = 2;
|
|
|
|
/// <summary>Expedition phase duration in server ticks (SimulationTickRate = 60). Tunable; short for the M6 slice.</summary>
|
|
public const uint ExpeditionTicks = 3600; // ~60s cap (early return via the gate ends it sooner)
|
|
|
|
/// <summary>Build phase duration in server ticks.</summary>
|
|
public const uint BuildTicks = 1200; // ~20s
|
|
}
|
|
|
|
/// <summary>
|
|
/// Server-only bookkeeping for the cycle state machine that must NOT replicate (kept separate from the
|
|
/// replicated <see cref="CycleState"/>). Records the wave number captured when the Defend phase began so
|
|
/// the director can detect "this Defend's wave has now been spawned and cleared".
|
|
/// </summary>
|
|
public struct CycleRuntime : IComponentData
|
|
{
|
|
/// <summary>WaveState.WaveNumber captured at the moment the current Defend phase started.</summary>
|
|
public int DefendStartWave;
|
|
|
|
/// <summary>Cycle phase from the previous tick — lets ExpeditionFieldSystem edge-detect entering/leaving Expedition.</summary>
|
|
public byte PrevPhase;
|
|
|
|
/// <summary>CycleNumber the expedition field was last seeded for (compared by int equality, never tick math).</summary>
|
|
public int LastSpawnedCycle;
|
|
}
|
|
}
|