Polishes
This commit is contained in:
@@ -139,6 +139,16 @@ namespace ProjectM.Server
|
||||
bool due = info.LaunchTick == 0u || !new NetworkTick(info.LaunchTick).IsNewerThan(serverTick);
|
||||
if (due)
|
||||
{
|
||||
// Conscript the party: the launch roster is EVERYONE connected (N7 co-location — all at
|
||||
// base, all ready). Room advances teleport ONLY RunParticipants, so a mid-run late joiner
|
||||
// is never yanked into the fight; the tag is released on the Returning edge.
|
||||
var conscript = new EntityCommandBuffer(Allocator.Temp);
|
||||
foreach (var (_, playerE) in
|
||||
SystemAPI.Query<RefRO<PlayerReady>>().WithAll<PlayerTag>().WithEntityAccess())
|
||||
conscript.AddComponent<RunParticipant>(playerE);
|
||||
conscript.Playback(state.EntityManager);
|
||||
conscript.Dispose();
|
||||
|
||||
// Enter room 0 (the guaranteed Combat landing at column 0, sub-slot 0).
|
||||
var map = RunMapMath.Generate(run.RunSeed);
|
||||
EnterRoom(ref state, ref info, ref run, in map, layer: 0, col: 0, baseCenter, bumpEpoch: true);
|
||||
@@ -187,15 +197,24 @@ namespace ProjectM.Server
|
||||
|
||||
// Exit gate: every SURVIVING player has picked (BoonOffer.Pending==0 — inert until Step 10)
|
||||
// OR the grace elapsed (wrap-safe IsNewerThan, never raw uint — F4).
|
||||
// Only EXPEDITION players hold the gate (BoonOfferSystem's documented contract): a player who
|
||||
// died and respawned to base must not stall the party (post-impl review, confirmed major).
|
||||
bool anyPending = false;
|
||||
foreach (var offer in SystemAPI.Query<RefRO<BoonOffer>>().WithAll<PlayerTag>())
|
||||
if (offer.ValueRO.Pending != 0) { anyPending = true; break; }
|
||||
foreach (var (offer, pregion) in
|
||||
SystemAPI.Query<RefRO<BoonOffer>, RefRO<RegionTag>>().WithAll<PlayerTag>())
|
||||
if (pregion.ValueRO.Region == RegionId.Expedition && offer.ValueRO.Pending != 0)
|
||||
{ anyPending = true; break; }
|
||||
bool graceElapsed = run.RewardGraceTick == 0u
|
||||
|| !new NetworkTick(run.RewardGraceTick).IsNewerThan(serverTick);
|
||||
if (anyPending && !graceElapsed)
|
||||
break;
|
||||
|
||||
run.RewardGraceTick = 0u;
|
||||
// NO offer survives this gate: zero every straggler (a dead-respawned base player the
|
||||
// auto-pick deliberately skips, a grace-expired AFK) so a stale Pending can never wedge the
|
||||
// HUD modal open or stall a later reward gate (post-impl review, confirmed major).
|
||||
foreach (var offer in SystemAPI.Query<RefRW<BoonOffer>>().WithAll<PlayerTag>())
|
||||
offer.ValueRW = default;
|
||||
if (run.LastTerminalCleared != 0)
|
||||
{
|
||||
info.Lifecycle = RunLifecycle.Returning; // boss cleared — go home a winner
|
||||
@@ -279,18 +298,25 @@ namespace ProjectM.Server
|
||||
|
||||
case RunLifecycle.Returning:
|
||||
{
|
||||
// Party teleport HOME + region flip back to Base.
|
||||
// PARTICIPANT teleport home + region flip + roster release. Only the launch roster comes
|
||||
// home (a mid-run joiner already at base keeps its position); the tag removal re-opens the
|
||||
// next run's conscription cleanly (post-impl review, confirmed medium).
|
||||
int idx = 0;
|
||||
foreach (var (region, xform) in
|
||||
SystemAPI.Query<RefRW<RegionTag>, RefRW<LocalTransform>>().WithAll<PlayerTag>())
|
||||
var homebound = new EntityCommandBuffer(Allocator.Temp);
|
||||
foreach (var (region, xform, playerE) in
|
||||
SystemAPI.Query<RefRW<RegionTag>, RefRW<LocalTransform>>()
|
||||
.WithAll<PlayerTag, RunParticipant>().WithEntityAccess())
|
||||
{
|
||||
region.ValueRW.Region = RegionId.Base;
|
||||
var p = baseCenter;
|
||||
p.x += 1.5f * idx;
|
||||
p.y = xform.ValueRO.Position.y;
|
||||
xform.ValueRW.Position = p;
|
||||
homebound.RemoveComponent<RunParticipant>(playerE);
|
||||
idx++;
|
||||
}
|
||||
homebound.Playback(state.EntityManager);
|
||||
homebound.Dispose();
|
||||
|
||||
// THE terminal bank — once per RunEpoch (equality latch, F7), CLEAR-GATED (D-F3).
|
||||
if (run.LastBankedRunEpoch != run.RunEpoch)
|
||||
@@ -393,7 +419,7 @@ namespace ProjectM.Server
|
||||
float3 roomOrigin = RegionMath.ExpeditionRoomOrigin(baseCenter, run.ActiveSubSlot);
|
||||
int idx = 0;
|
||||
foreach (var (region, xform) in
|
||||
SystemAPI.Query<RefRW<RegionTag>, RefRW<LocalTransform>>().WithAll<PlayerTag>())
|
||||
SystemAPI.Query<RefRW<RegionTag>, RefRW<LocalTransform>>().WithAll<PlayerTag, RunParticipant>())
|
||||
{
|
||||
region.ValueRW.Region = RegionId.Expedition;
|
||||
var p = roomOrigin;
|
||||
|
||||
Reference in New Issue
Block a user