Commit Graph
13 Commits
Author SHA1 Message Date
Michael Burgess 8932dfed29 Fix chevron over-count, plane-lock diagonal frame connectivity, true one-way travel, iris shield independence
Chevron placement: the "protruding elbow" heuristic marked every
convex corner of a smooth ring as a chevron, which for a true
octagon/circle is *every* corner - producing 8 chevrons instead of a
deliberate subset. Replaced with a fixed, configurable count
(gate.chevron-count, default 7) evenly spaced along the ring's actual
geometric walk order.

Frame flood-fill leaking into unrelated structures: the diagonal
("stepped ring") connectivity fix from two commits ago used a full 3D
26-neighbor search, which let the flood leak sideways through the
ring's thickness into any other nearby structure sharing a frame
material (e.g. gilded blackstone used decoratively on a backdrop
wall), putting chevrons on it. The scan now bootstraps with a small
orthogonal-only flood to find the ring's plane first, then only
allows diagonal connectivity within that plane - never through depth.

One-way travel, properly this time: RuntimeGate gained an `outgoing`
flag, set true only on the gate that was actually dialed. The
teleport listener now only matches outgoing gates, so the destination
shows the event horizon but isn't walkable - stepping into it does
nothing, and only the dialing side can send a player anywhere.

Iris shield: it's a physical barrier independent of the wormhole, not
tied to "connected" state. Closed always means iris-shield-material
(default changed from IRON_BLOCK to BEDROCK per feedback), whether or
not the gate is even dialed right now. Only when the shield is open
does the idle/connected distinction (air vs event horizon) apply.
applyIrisMaterial() centralizes this so link, restart re-scan,
open/close, and the shield toggle all agree.
2026-08-09 11:52:04 -04:00
Michael Burgess b822389387 Fix one-way travel, rework iris to SG-1 mechanics, glowstone chevrons, pin-locked shield
One-way travel bug: the exit point landed players directly inside the
destination gate's own iris footprint. Since dialing opens both ends,
arriving there immediately re-triggered the teleport listener and
bounced them straight back - reading exactly like one-way travel.
GateManager.computeSafeLanding now nudges the landing spot along the
player's travel direction until it clears the destination's iris
blocks, and GateTeleportListener adds a short per-player cooldown as a
second guard against re-trigger. Same-server teleports now also
preserve the player's exact yaw/pitch and velocity instead of forcing
a fixed stored orientation, so entering forward always means exiting
forward; the cross-server plugin-messaging protocol was extended to
carry yaw/pitch through the proxy hop for the same reason.

Iris rework to match SG-1 rather than a binary open/closed gate:
- Idle (not connected): iris-idle-material, default AIR - you see
  straight through an inactive ring, not a wall.
- Connected: iris-open-material (WATER, the event horizon) unless the
  gate's separate iris shield is closed, in which case
  iris-shield-material (IRON_BLOCK) blocks travel even though the
  wormhole is active.
- A button placed directly below the control sign toggles the shield
  (GateIrisButtonListener). Closing needs nothing; opening a gate with
  a pin code set (/sg pin <code>) prompts the player to type it in
  chat within gate.pin-timeout-seconds first.

Also: gate.chevron-lit-material default changed from gilded blackstone
to glowstone per feedback.
2026-08-09 11:36:17 -04:00
Michael Burgess 190f875d23 Fix interior flood leaking out the front/back of free-standing rings
A one-block-thick ring standing free (nothing built behind it, like
every reference screenshot) has open air directly in front of and
behind the interior. The iris/interior flood-fill searched all 6
directions, so it always escaped through that open air and flooded
the surrounding world instead of staying inside the ring - reliably
producing "interior isn't fully enclosed" regardless of how sound the
ring actually was.

Fixed by detecting which world axis the ring is thinnest along (same
idea already used for chevron placement) and restricting both the
interior candidate search and the flood itself to the other two axes,
so it can only explore within the ring's own plane.

Also fixed iris material semantics per feedback: the interior is no
longer just air when idle. gate.iris-material is now split into
iris-closed-material (default BEDROCK - solid, blocks all passage)
and iris-open-material (default WATER, the event horizon), applied
at link time, on open/close, and after a restart re-scan.
2026-08-09 11:19:55 -04:00
Michael Burgess 282c8cfdbb Fix frame flood-fill to follow diagonal (stepped) ring connections
Round/octagonal rings built the normal Minecraft way step diagonally
at the corners - two frame blocks touching only edge-to-edge, not
face-to-face. The scanner only checked the 6 face-adjacent neighbours,
so those blocks were treated as disconnected fragments and the whole
ring failed to register (or only a fraction of it did).

Frame discovery now flood-fills using all 26 surrounding offsets
instead of just the 6 faces. The geometric chevron walk needed the
same fix - its in-plane adjacency now checks 8 directions (orthogonal
+ diagonal) instead of 4, so stepped rings still produce a clean
single-loop walk instead of falling back to evenly-spaced chevrons.

Interior/iris flood-fill is intentionally left orthogonal-only: since
it only ever moves face-to-face, a diagonal-only frame corner already
blocks it from slipping past, so enclosure detection didn't need to
change.
2026-08-09 11:04:20 -04:00
Michael Burgess fe3b2b0f14 Revert to flexible flood-fill scanning with geometric chevron placement
The exact-template approach from the last commit over-fit to the
sample ASCII diagram, which was meant to teach the target shape, not
be matched literally cell-for-cell. Back to flood-filling any
connected, fully-enclosed ring the builder makes (any size/shape), but
chevrons are no longer evenly spaced by scan order - the scanner walks
the ring in geometric order and marks local maxima of distance from
the interior's centroid, i.e. the blocks that stick out further than
their ring-neighbours. That's where a real Stargate's chevrons sit
(the 11-wide reference ring naturally produces 7 this way: the top
apex, four shoulder elbows, two side bumps), without hardcoding a
specific size.

Falls back to the old evenly-spaced picker only if the ring isn't a
simple single-thickness loop (each frame block should have exactly
two in-plane neighbours) so odd/thick builds still work.

gate.max-frame-blocks/max-iris-blocks/min-frame-blocks are back;
gate.template is gone.
2026-08-09 10:57:00 -04:00
Michael Burgess ed8415a497 Replace flood-fill scanner with an exact gate template
Instead of guessing a gate's shape by flood-filling connected frame
material, the plugin now matches a fixed ASCII template against the
world (gate.template in config.yml), the same idea as the classic
Stargate plugin's .gate files. Default is an 11x11 ring with 7
chevrons at their real positions rather than auto-spaced.

- New GateTemplate parses the '*'/'1'/'2'/'0' grid.
- New GateTemplateScanner tries every plausible alignment of a
  punched block against a frame/chevron cell, then verifies the rest
  of the template matches; no more flood-fill leak/enclosure
  diagnostics needed since the shape is exact.
- The player's look direction at punch time (snapped to N/S/E/W)
  decides whether template columns run along world X or Z; this
  facing is now stored in Gate.facing (repurposing the old
  sign-attachment field) so restarts can re-scan deterministically.
- Exit-teleport yaw now comes from that stored facing instead of a
  geometric guess.
- Removed gate.chevron-count/max-frame-blocks/max-iris-blocks/
  min-frame-blocks - the template itself defines size and chevrons.
2026-08-09 10:48:47 -04:00
Michael Burgess 317602c00e Decouple the control sign from the gate frame: place then punch to link
Sign creation no longer scans the block it's mounted on. Instead,
placing a "[Stargate]" sign starts a pending link (shown as "Punch the
gate" on the sign) and the next block the owner left-clicks within
gate.link-timeout-seconds and gate.max-link-distance becomes the scan
seed. This lets the sign act like a DHD console standing apart from
the gate instead of being physically attached to the frame.

- Gate now stores the punched link block's coordinates (link_x/y/z)
  so restarts re-scan from there instead of deriving a seed from the
  sign's attachment, which no longer applies.
- New GateLinkListener handles the punch and reports scan failures
  via the existing diagnostic messages; also clears pending state on
  disconnect.
- Exit-location facing is now derived from the punched frame block's
  position relative to the iris, since a WallSign facing is no longer
  guaranteed to exist or be relevant.
2026-08-09 10:32:46 -04:00
Michael Burgess 89d4fa0b63 Stop bundling DB drivers into the proxy jars
stargate-common declared HikariCP/SQLite/MySQL as implementation deps,
which leaked transitively into stargate-velocity and stargate-bungee
even though neither touches storage. That bloated each proxy jar from
~15KB to ~18MB for nothing. Switched to compileOnly in stargate-common;
stargate-paper already redeclares them as implementation so its shaded
jar is unaffected.
2026-08-09 10:23:04 -04:00
Michael Burgess c99f4c9f85 Auto-select chevron slots instead of requiring a distinct unlit material
Chevrons no longer need to be built out of a special block - the plugin
picks gate.chevron-count frame blocks evenly spaced around the scanned
ring and remembers their resting material, so a chevron can rest as
plain obsidian (matching the rest of the frame) and only reveal itself
by swapping to gate.chevron-lit-material while dialing/open. Restoring
on close now puts back the original block instead of a fixed material,
so alternating decorative frames (e.g. obsidian/gilded blackstone) are
preserved exactly.
2026-08-09 10:20:14 -04:00
Michael Burgess 62277a8d7b Fix interior scan failing on ground-standing gates
The floor a gate stands on (grass, stone, etc.) is a solid block that
isn't part of the frame, so touching it during the interior flood-fill
was treated as a leak and failed the whole scan. Solid non-frame blocks
now act as boundaries instead of auto-failures; a real gap in the ring
is still caught by the max-iris-blocks size cap.
2026-08-09 10:12:52 -04:00
Michael Burgess 56c089f656 Add gilded blackstone to default frame materials, report scan failure reasons
Sign creation now tells the player exactly why the structure scan failed
(missing frame material, ring not sealed, interior too large, etc.)
instead of one generic error.
2026-08-09 10:08:21 -04:00
Michael Burgess d651f6586f Add fixed-destination gates and /sg networks command
Sign line 4 now accepts fixed:GateName to lock a gate to one destination
without cycling, and /sg networks lists every known network.
2026-08-09 09:56:12 -04:00
Michael Burgess 83a0392ee9 Initial Stargate plugin: Paper gate plugin + Velocity/Bungee cross-server bridges 2026-08-09 09:53:55 -04:00