From 75eab42f3c83b09ac14d8014be217d2ebca936e5 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 30 Aug 2026 21:39:28 +0200 Subject: [PATCH] fix(render): rain draws only while the player stands outside The owner''s seam report (rain in the 0xF4180104/0xF4180101 crossing strip where retail has none) led straight to retail''s actual rain confinement, which is neither depth nor view clipping: GameSky::Draw @0x00506ff0 gates its WEATHER pass (arg2==1) on SmartBox::is_player_outside @0x00451e80 - Ghidra-arbitrated (BN''s body was flag-idiom mush): (player objcell_id & 0xFFFF) < 0x100. The sky pass always draws; rain draws ONLY while the PLAYER is in an outdoor cell. One boolean - rain on the ledges, none the instant the player crosses into an interior cell. Retail also runs the sky/weather draw at DEPTHTEST_ALWAYS write-off (pc 0x00507063), confirming our depth-disabled weather port; the missing piece was only this gate, now applied at the executor''s weather site from the frame''s PlayerCellId. Hermetic 6,762/0. Co-Authored-By: Claude Fable 5 --- src/AcDream.App/Rendering/RetailPViewPassExecutor.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/AcDream.App/Rendering/RetailPViewPassExecutor.cs b/src/AcDream.App/Rendering/RetailPViewPassExecutor.cs index 633ba405..0f3df8ca 100644 --- a/src/AcDream.App/Rendering/RetailPViewPassExecutor.cs +++ b/src/AcDream.App/Rendering/RetailPViewPassExecutor.cs @@ -470,7 +470,16 @@ internal sealed partial class RetailPViewPassExecutor : // DrawLandscapeStaticParticles after the slice loop (retail: one // unclipped alpha-list insertion per emitter), not per slice here. EnableClipDistances(); - if (frame.RenderSky && frame.RenderWeather) + // Retail GameSky::Draw @0x00506ff0 gates the WEATHER pass (arg2==1) + // on SmartBox::is_player_outside @0x00451e80 — Ghidra-arbitrated: + // (player objcell_id & 0xFFFF) < 0x100. The sky pass always draws; + // the rain draws ONLY while the PLAYER stands in an outdoor cell. + // That one boolean is retail's entire rain confinement (the + // owner-reported indoor/seam rain at the cathedral: rain on the + // ledges, none the instant the player crosses into an interior + // cell) — no depth or view-clip mechanism is involved. + bool playerOutside = (frame.PlayerCellId & 0xFFFFu) < 0x100u; + if (frame.RenderSky && frame.RenderWeather && playerOutside) { _sky?.RenderWeather( frame.Camera,