From 7c1fee097ef6c943be5b70b4ee91eb46dcfa0023 Mon Sep 17 00:00:00 2001 From: Luis Gonzalez Date: Mon, 6 Jul 2026 12:26:19 -0700 Subject: [PATCH] Phase 0 stabilize: lifecycle-aware banner, RoomExplore location line, grounded crate + beacon, tamed beacon HDR - The center-top phase banner read the CyclePhase label ("AT BASE") inside expedition rooms - now shows ON EXPEDITION whenever a run is past Staging. - The location-line switch had no RoomExplore case, so "choose your boon" stuck through the whole loot window - added the portal-steer line. - Storage crate floated 1u: GridOrigin.y=1 is the CC capsule-CENTER plane; CellToWorld returns it, and the crate's mesh pivot is at its base (Turret/ Wall pivots are centered, which is why structures look grounded). The container now sits on the terrain; same grounding for the portal beacon, whose pos.y was the capsule plane too. - Beacon HDR 2.6/3.4 bloomed into a white egg that swallowed the prompt - tamed to 1.2/1.55 + slimmed the pillar. 456/456 EditMode before and after; Play smoke: crate at y=0, banner correct at Staging. Co-Authored-By: Claude Fable 5 --- .../Client/Presentation/CombatFeedbackSystem.cs | 11 ++++++----- .../_Project/Scripts/Client/Presentation/HudSystem.cs | 9 +++++++-- .../Server/HomeBase/SharedStorageSpawnSystem.cs | 4 ++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Assets/_Project/Scripts/Client/Presentation/CombatFeedbackSystem.cs b/Assets/_Project/Scripts/Client/Presentation/CombatFeedbackSystem.cs index 444227777..d7784045f 100644 --- a/Assets/_Project/Scripts/Client/Presentation/CombatFeedbackSystem.cs +++ b/Assets/_Project/Scripts/Client/Presentation/CombatFeedbackSystem.cs @@ -152,7 +152,7 @@ namespace ProjectM.Client _dangerMat.color = new Color(3.2f, 0.28f, 0.18f, 1f); // HDR red (per-zone intensity carried in vertex alpha) _portalMat = MakeParticleMaterial(); _portalMat.name = "RoomPortal"; - _portalMat.color = new Color(0.5f, 2.6f, 3.4f, 0.85f); // DR-046: HDR cyan portal glow (pushes past bloom) + _portalMat.color = new Color(0.25f, 1.2f, 1.55f, 0.85f); // DR-046: HDR cyan portal glow (Phase 0: tamed — 2.6/3.4 bloomed to a white blob) // Health-bar materials (UI/Default = always-included URP-compatible UI shader; per-instance Image.color carries alpha). Shader uiShader = Shader.Find("UI/Default") ?? Shader.Find("Sprites/Default"); @@ -1021,10 +1021,11 @@ void TriggerSlash(Vector3 pos, float2 facing, float range, float halfAngle, int float t = (float)SystemAPI.Time.ElapsedTime; float breathe = 0.5f + 0.5f * math.sin(t * 3.5f); var tr = _portalBeacon.transform; - // Cylinder is 2u tall in local space -> scale.y=3 gives a 6u pillar; lift the centre so the base sits on the ground. - tr.position = new Vector3(pos.x, pos.y + 3f, pos.z); - tr.localScale = new Vector3(1.4f + 0.15f * breathe, 3f, 1.4f + 0.15f * breathe); - _portalMat.color = new Color(0.5f, 2.6f, 3.4f, 0.55f + 0.35f * breathe); // glow throb (beacon-only mat, safe to mutate) + // Cylinder is 2u tall in local space -> scale.y=2.2 gives a 4.4u pillar; lift the centre so the base sits + // on the TERRAIN (y=0) — pos.y is the CC capsule-center plane (GridOrigin.y=1), 1 u above the ground. + tr.position = new Vector3(pos.x, 2.2f, pos.z); + tr.localScale = new Vector3(0.9f + 0.12f * breathe, 2.2f, 0.9f + 0.12f * breathe); + _portalMat.color = new Color(0.25f, 1.2f, 1.55f, 0.45f + 0.3f * breathe); // glow throb (beacon-only mat; Phase 0: tamed + slimmed — the fat 6u pillar bloomed to a white egg swallowing the prompt) } diff --git a/Assets/_Project/Scripts/Client/Presentation/HudSystem.cs b/Assets/_Project/Scripts/Client/Presentation/HudSystem.cs index 8a48474ff..84bce62ab 100644 --- a/Assets/_Project/Scripts/Client/Presentation/HudSystem.cs +++ b/Assets/_Project/Scripts/Client/Presentation/HudSystem.cs @@ -180,10 +180,12 @@ namespace ProjectM.Client int huskCount = _huskQuery.CalculateEntityCount(); // ---- Macro: phase + cycle + countdown (center-top banner) ---- + bool haveRun = SystemAPI.TryGetSingleton(out var runInfo); // hoisted: the phase banner is lifecycle-aware (Phase 0 fix — it read "AT BASE" inside expedition rooms) bool haveCycle = SystemAPI.TryGetSingleton(out var cyc); bool siege = haveCycle && cyc.Phase == CyclePhase.Siege; bool goalFull = SystemAPI.TryGetSingleton(out var goalNow) && goalNow.Target > 0 && goalNow.Charge >= goalNow.Target; bool finalSiege = siege && goalFull; // END-2: the climactic final siege (goal cap reached) + bool onRun = haveRun && !siege && runInfo.Lifecycle != RunLifecycle.Staging; // mid-run: the base's Calm label is wrong if (haveCycle) { var endTick = new NetworkTick(cyc.PhaseEndTick); @@ -199,7 +201,7 @@ namespace ProjectM.Client detail = ""; // END-2: the climax reads distinct (intense red), not a normal incursion/wave. var col = finalSiege || finalArming ? new Color(1f, 0.28f, 0.22f) : PhaseColor(cyc.Phase); - _phaseText.text = (finalSiege ? "HOLD THE ENGINE" : PhaseLabel(cyc.Phase)) + (detail.Length > 0 ? " - " + detail : ""); + _phaseText.text = (finalSiege ? "HOLD THE ENGINE" : onRun ? "ON EXPEDITION" : PhaseLabel(cyc.Phase)) + (detail.Length > 0 ? " - " + detail : ""); _phaseText.style.color = col; _cycleText.text = "CYCLE " + cyc.CycleNumber; _banner.style.borderBottomColor = col; @@ -215,7 +217,6 @@ namespace ProjectM.Client // (the old camera-X + walk-in-gate copy died with the gate; siege/final overrides below still win). var cam = Camera.main; // camera-X region signal still feeds downstream panels (atmosphere/threat) bool onExpedition = cam != null && cam.transform.position.x > ExpeditionRegionXMin; - bool haveRun = SystemAPI.TryGetSingleton(out var runInfo); SystemAPI.TryGetSingleton(out var obj); if (haveRun && !siege && !finalSiege) { @@ -255,6 +256,10 @@ namespace ProjectM.Client _locationText.text = "ROOM CLEARED - choose your boon"; _locationText.style.color = new Color(0.5f, 1f, 0.6f); break; + case RunLifecycle.RoomExplore: // Phase 0: without this case the RoomReward text stuck through the loot window + _locationText.text = "ROOM CLEAR - grab the loot, take the portal to move on"; + _locationText.style.color = new Color(0.5f, 1f, 0.6f); + break; case RunLifecycle.RouteSelect: _locationText.text = "CHOOSE YOUR PATH"; _locationText.style.color = new Color(0.55f, 0.85f, 1f); diff --git a/Assets/_Project/Scripts/Server/HomeBase/SharedStorageSpawnSystem.cs b/Assets/_Project/Scripts/Server/HomeBase/SharedStorageSpawnSystem.cs index 6f69c3212..34c260110 100644 --- a/Assets/_Project/Scripts/Server/HomeBase/SharedStorageSpawnSystem.cs +++ b/Assets/_Project/Scripts/Server/HomeBase/SharedStorageSpawnSystem.cs @@ -39,6 +39,10 @@ namespace ProjectM.Server { var container = ecb.Instantiate(spawner.Prefab); var position = BaseGridMath.CellToWorld(anchor, spawner.Cell); + // Phase 0: the grid Y (GridOrigin.y=1) is the CC capsule-CENTER plane; center-pivot structure + // meshes look grounded there, but the crate's pivot is at its base -> it floated 1 u. Sit it on + // the terrain surface instead. + position.y = 0f; // Preserve the prefab's baked scale/rotation (FromPosition would reset Scale to 1). var xform = SystemAPI.GetComponent(spawner.Prefab); xform.Position = position;