4f0b4e8087
At GoalProgress.Charge>=Target a new server-only GoalReachedSystem arms a larger final siege (x live FinalSiegeMultiplier) and flips RunPhase=FinalDefense; CyclePhaseSystem latches a REPLICATED RunOutcome (Victory on clear / Loss on Core breach) and halts the director. RunOutcome is a [GhostField] byte on the global CycleDirector ghost (the client banner observes it); RunPhase stays server-only. ThreatDirector/CoreRestore/CoreDamage halt once decided; SiegeTimeout is off during the final siege. SaveData v5 persists the outcome so a won/lost run loads finished. GoalProgress.Target 10->4. Completes Path A's spine. See DR-036. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
71 lines
3.1 KiB
C#
71 lines
3.1 KiB
C#
using Unity.Entities;
|
|
|
|
namespace ProjectM.Simulation
|
|
{
|
|
/// <summary>
|
|
/// Server-world, UNMANAGED bridge holding a save slice the menu staged for a "Continue" session, applied
|
|
/// AT SPAWN by the server CycleDirectorSpawnSystem so the director ghost is BORN correct — it never
|
|
/// serializes a default <see cref="GoalProgress"/> / empty ledger to clients (no replication flicker). The
|
|
/// menu creates exactly one of these (with the <see cref="PendingSaveLedgerRow"/> buffer) in the freshly
|
|
/// created ServerWorld BEFORE the gameplay subscene streams in; the spawn system consumes + destroys it.
|
|
/// Unmanaged so the Bursted spawn system reads it without a managed bridge.
|
|
/// </summary>
|
|
public struct PendingSave : IComponentData
|
|
{
|
|
public int GoalCharge;
|
|
public int GoalTarget;
|
|
|
|
/// <summary>END-1: Engine Core integrity to restore (0 = pre-v4 save / New Game -> born full at baked Max).</summary>
|
|
public int CoreCurrent;
|
|
|
|
/// <summary>END-2: terminal run outcome to restore (0 = InProgress / pre-v5 save / New Game; 1 = Victory,
|
|
/// 2 = Loss -> the run loads finished + halted, no re-arm). Born-correct at director spawn.</summary>
|
|
public byte RunOutcome;
|
|
|
|
/// <summary>0 = nothing staged (New Game); non-zero = apply the staged slice at director spawn.</summary>
|
|
public byte HasData;
|
|
}
|
|
|
|
/// <summary>One staged ledger row for a Continue session; copied into the director's StorageEntry buffer at spawn.</summary>
|
|
public struct PendingSaveLedgerRow : IBufferElementData
|
|
{
|
|
public ushort ItemId;
|
|
public int Count;
|
|
}
|
|
/// <summary>One staged player-built structure row for a Continue session (M7); BaseRestoreSystem replays it
|
|
/// charge-free into the freshly-streamed base. Mirrors <see cref="StructureSave"/> but as an unmanaged ECS
|
|
/// buffer element (staged in the ServerWorld before the subscene streams).</summary>
|
|
public struct PendingStructure : IBufferElementData
|
|
{
|
|
public byte Type;
|
|
public int CellX;
|
|
public int CellZ;
|
|
public byte Direction;
|
|
public uint RemainingTicks;
|
|
public byte ConveyorResId;
|
|
public int ConveyorCount;
|
|
public float HP; // EB-1: staged hit points (BaseRestoreSystem restores 0 -> baked Max)
|
|
}
|
|
|
|
/// <summary>One staged machine I/O row (M7), joined to the <see cref="PendingStructure"/> buffer by index.
|
|
/// Slot 0 = MachineInput, 1 = MachineOutput.</summary>
|
|
public struct PendingStructureIo : IBufferElementData
|
|
{
|
|
public int StructureIndex;
|
|
public byte Slot;
|
|
public byte ResourceId;
|
|
public int Count;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Host-only autosave request flag on the CycleDirector entity (added at spawn). The Bursted CyclePhaseSystem
|
|
/// sets <see cref="Pending"/>=1 on the Siege->Calm checkpoint; the managed SaveWriteSystem reads it, writes
|
|
/// the JSON save, and clears it. A plain byte => Burst-safe (no managed/string/file touch in the sim loop).
|
|
/// </summary>
|
|
public struct SaveRequest : IComponentData
|
|
{
|
|
public byte Pending;
|
|
}
|
|
}
|