using ProjectM.Simulation; using Unity.Entities; using Unity.NetCode; using UnityEngine; namespace ProjectM.Client { /// /// Client-side route-pick sender: a static enqueue (the Step-14 map panel's option buttons / execute_code) /// drained into RPCs. The request is stamped from the CLIENT's replicated /// : ForRunEpoch = (int)RunSeed (the re-meaned run-identity token — the server-only /// RunEpoch is not client-knowable) and ForLayer = CurrentRoom VERBATIM (during a gate that is still the /// just-cleared layer — never +1). The server re-validates everything; a stale/possessed pick is simply dropped. /// Statics reset on play-enter (the stale-bridge hazard). /// [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)] public partial class RouteSendSystem : SystemBase { static int s_Pending; static byte s_PendingIndex; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void ResetStatics() { s_Pending = 0; s_PendingIndex = 0; } /// Queue a route pick (0..RouteOptionCount-1). HUD map panel + execute_code drive this. public static void PickRoute(byte optionIndex) { s_PendingIndex = optionIndex; s_Pending++; } protected override void OnCreate() { RequireForUpdate(); RequireForUpdate(); } protected override void OnUpdate() { if (s_Pending == 0) return; var runInfo = SystemAPI.GetSingleton(); while (s_Pending > 0) { s_Pending--; var req = EntityManager.CreateEntity(typeof(RouteSelectRequest), typeof(SendRpcCommandRequest)); EntityManager.SetComponentData(req, new RouteSelectRequest { OptionIndex = s_PendingIndex, ForRunEpoch = (int)runInfo.RunSeed, // the re-meaned replicated run token ForLayer = runInfo.CurrentRoom, // the gate's un-incremented cleared layer }); } } } }