Check landing spot is actually open space, not just clear of the iris
computeSafeLanding() pushed the arrival point along the entry direction only until it cleared the destination's iris footprint - it never checked whether that spot was solid ground. A gate built close to a wall (e.g. inside a room/temple) could push the landing straight into that wall, embedding the player in it - which incidentally let them walk out through the wall instead of a door, since they're already clipped partway through it. Now checks feet AND head height at each step for solid blocks while searching forward (up to 8 blocks), stopping at the first spot that's both clear of the iris and open space. Falls back to the furthest wall-clear point found if nothing satisfies both within range, rather than the original blind offset.
This commit is contained in:
@@ -80,7 +80,10 @@ material, unsealed interior, too far from the sign, etc.
|
|||||||
- Travel is **one-way**: only the gate you dialed *from* can send anything anywhere.
|
- Travel is **one-way**: only the gate you dialed *from* can send anything anywhere.
|
||||||
Walking (or wandering, or drifting) into its event horizon teleports whatever
|
Walking (or wandering, or drifting) into its event horizon teleports whatever
|
||||||
entered to the destination, arriving just clear of its iris (never inside it) and
|
entered to the destination, arriving just clear of its iris (never inside it) and
|
||||||
still facing whatever direction it was already moving, so entering forward always
|
clear of any wall too - if the gate sits close to a wall (built inside a room, say),
|
||||||
|
the plugin checks the landing spot is actually open space and searches forward
|
||||||
|
along the entry direction for one instead of embedding the arrival in solid block.
|
||||||
|
It still faces whatever direction it was already moving, so entering forward always
|
||||||
means exiting forward. The destination's horizon is visible but not walkable -
|
means exiting forward. The destination's horizon is visible but not walkable -
|
||||||
stepping into it does nothing, same as a real Stargate only running one direction
|
stepping into it does nothing, same as a real Stargate only running one direction
|
||||||
at a time.
|
at a time.
|
||||||
|
|||||||
+25
-3
@@ -491,13 +491,35 @@ public class GateManager {
|
|||||||
if (dir.lengthSquared() < 0.0001) dir = new Vector(0, 0, 1);
|
if (dir.lengthSquared() < 0.0001) dir = new Vector(0, 0, 1);
|
||||||
dir.normalize();
|
dir.normalize();
|
||||||
|
|
||||||
for (int i = 0; i < 8 && !irisXZ.isEmpty(); i++) {
|
// Push clear of the iris footprint (so arrival doesn't immediately re-trigger the
|
||||||
long key = ((long) Math.floor(x) << 32) ^ ((long) Math.floor(z) & 0xFFFFFFFFL);
|
// teleport) AND clear of any solid block at foot/head height - a wall close behind the
|
||||||
if (!irisXZ.contains(key)) break;
|
// gate (e.g. built inside a room) can otherwise land the player embedded in it. Falls
|
||||||
|
// back to the furthest wall-clear spot found if nothing satisfies both within range.
|
||||||
|
double lastClearX = x, lastClearZ = z;
|
||||||
|
boolean foundClear = false;
|
||||||
|
for (int i = 0; i <= 16; i++) {
|
||||||
|
boolean inIris = irisXZ.contains(((long) Math.floor(x) << 32) ^ ((long) Math.floor(z) & 0xFFFFFFFFL));
|
||||||
|
Block feet = world.getBlockAt((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z));
|
||||||
|
Block head = feet.getRelative(0, 1, 0);
|
||||||
|
boolean solid = feet.getType().isSolid() || head.getType().isSolid();
|
||||||
|
|
||||||
|
if (!inIris && !solid) {
|
||||||
|
foundClear = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!solid) {
|
||||||
|
lastClearX = x;
|
||||||
|
lastClearZ = z;
|
||||||
|
}
|
||||||
x += dir.getX() * 0.5;
|
x += dir.getX() * 0.5;
|
||||||
z += dir.getZ() * 0.5;
|
z += dir.getZ() * 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!foundClear) {
|
||||||
|
x = lastClearX;
|
||||||
|
z = lastClearZ;
|
||||||
|
}
|
||||||
|
|
||||||
return new Location(world, x, y, z, yaw, pitch);
|
return new Location(world, x, y, z, yaw, pitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user