Skip to content

RPD Update 3: Third Times the Charm#216

Open
rebaserHEAD wants to merge 26 commits into
Triad-Sector:mainfrom
rebaserHEAD:fix/rpd-pipe-layers
Open

RPD Update 3: Third Times the Charm#216
rebaserHEAD wants to merge 26 commits into
Triad-Sector:mainfrom
rebaserHEAD:fix/rpd-pipe-layers

Conversation

@rebaserHEAD

Copy link
Copy Markdown
Collaborator

About the PR

The RPD now commits builds and deconstructs to the pipe layer you're aiming at, across the whole catalog. Pipes already worked this way; this extends the cursor-quadrant aim to vents, scrubbers, injectors, the dual-port vent, filters, mixers, the pneumatic valve, and the canister port, and makes deconstruct respect the same aim, including pipes buried under floor tiles or shadowed by firelocks.

Under the hood the client pushes the chosen layer to the server (replacing the old eye-rotation streaming), RCDSystem stops knowing what an RPD is (sibling admission via event seams instead), and recipe rotation is applied at spawn so the anchor-time overlap check sees the real facing.

For anyone cherry-picking, this sits on top of:

Why / Balance

Quality of life for atmos work. No balance impact: same costs, same materials, same recipes. The only thing that changes is that the layer you aim at is the layer you get. Radiators are deliberately excluded since they're single-layer by design; their recipes now say so instead of showing layer dots that don't do anything.

Media

u when you use this. trust me. i'm too tired to add footage.

image

Requirements

  • I have read relevant guidelines/documentation to this PR found on our devwiki.
  • I have added media to this PR or it does not require an ingame showcase.
  • I can confirm this PR contains either no AI-generated content, or AI-generated content that meets our guidelines.

How to test

  1. Spawn an RPD, pick any pipe or device recipe, and hover a tile: the three guide dots show the layer your cursor quadrant selects. Build on each layer and check the device lands on it (examine, or t-ray the connectors).
  2. Stack pipes on different layers on one tile, switch to Deconstruct, and aim at a quadrant: the pipe on the aimed layer is the one that gets chewed, including under a floor tile or a firelock.
  3. Build a flipped filter/mixer off-Primary and confirm it spawns flipped on the aimed layer; flip it in-world and confirm it stays on its layer.
  4. Radiators show no layer dots and always build normally.
  5. dotnet test --filter FullyQualifiedName~RPD covers the alt-prototype wiring, layer coexistence, overlap, and spawn rotation.

Breaking changes

  • RPDEyeRotationEvent and RPDComponent.LastKnownEyeRotation are removed; the client now sends RPDLayerSelectEvent and the server stores the pick via RPDSystem.SetLayer.
  • RCDDeconstructAttemptEvent gains an Admitted flag (sibling systems admit targets RCD would reject).
  • New RCDConstructionAttemptEvent raised during construct validation so a sibling can veto placement.

Changelog
🆑

  • tweak: The RPD builds vents, scrubbers, injectors, filters, mixers, valves, and canister ports on the pipe layer you're aiming at, just like pipes.
  • fix: The RPD can deconstruct pipes hidden under floor tiles or sitting beneath firelocks, and it targets the layer you aim at.
  • fix: RPD-built devices respect their facing at placement time, so rotated builds no longer collide with devices they don't actually overlap.

rebaserHEAD and others added 26 commits June 12, 2026 16:58
Subfloor pipes carry SubFloorHideComponent, so they render invisible and the
click resolves no target. Scoped to the RPD in Deconstruct mode, resolve an
RPD-deconstructable entity anchored on the clicked tile, chosen deterministically
by lowest NetEntity id so server and client prediction agree. The RCD path is
unaffected.
… entities

The subfloor-deconstruct gate only fired when the click resolved no target. A visible
anchored entity sharing the tile (a firelock, a window) becomes the click target and
shadowed the hidden pipe beneath it, so the RPD could not reach it. Fire the fallback
whenever the resolved target is not itself RPD-deconstructable, falling back to the
original target so a non-pipe click still no-ops and a bare tile still deconstructs the
floor.
The RPD deconstructs an existing pipe through AfterInteract, so the construct-style
whole-tile ghost only painted a misleading tile highlight over an operation that places
nothing. Suppress the placer for the RPD in Deconstruct mode. The RCD and RPD construct
ghosts are unchanged.
When several atmos pipes shared a tile across layers, deconstructing a covered
pipe (one hidden under a floor tile) picked an arbitrary one by lowest
NetEntity, ignoring which layer the operator was aiming at. That was
inconsistent with construct, which places on the cursor-quadrant layer.

Resolve the covered-pipe target through a new RCDDeconstructTargetResolveEvent
so RPDSystem (which owns the aimed layer and atmos access) picks the anchored
pipe whose CurrentPipeLayer matches the aimed layer, falling back to
lowest-NetEntity for single-layer or non-layered atmos devices. The aimed
layer comes from eye rotation, now streamed in deconstruct mode too since the
construct placement mode that normally streams it is suppressed there. A world
overlay draws the same three layer-guide dots construct shows, so the operator
aims the same way they place.

Server-authoritative: CurrentLayer is server-only state and the deconstruct
do-after only starts server-side, so the client's placeholder pick stays
cosmetic and never desyncs the result.
…he cursor-aimed pipe layer

Extends the alt-prototype + graph-node treatment from the Vents pass to the
rest of the RPD catalog. Flipped filter/mixer variants carry their own
alternativePrototypes maps (inheritance would merge the unflipped parent's in)
and their alts re-point Flippable at the same layer's mirror so an in-world
flip keeps the layer. Radiators are numberOfPipeLayers: 1 by design, so their
recipes opt out via noLayers instead of growing alts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant