Partially Improved Unsafe Exits

Partially completed the code for unsafe exits (used for trapdoors) so
that they drop players into air pockets. It's not complete yet, but I
want to merge in other changes before continuing.
This commit is contained in:
SenseiKiwi 2013-09-08 15:23:14 -04:00
parent 72213de437
commit 37b0510676
2 changed files with 82 additions and 10 deletions

View file

@ -150,7 +150,7 @@ public class DDTeleporter
{
throw new IllegalStateException("The destination world should be loaded!");
}
//Check if the block below that point is actually a door
int blockID = world.getBlockId(door.getX(), door.getY() - 1, door.getZ());
if (blockID != properties.DimensionalDoorID && blockID != properties.WarpDoorID &&
@ -436,9 +436,9 @@ public class DDTeleporter
private static boolean generateUnsafeExit(DimLink link)
{
// An unsafe exit teleports the user to exactly the same coordinates
// as the link source, except located at the dimension's root dimension.
// This is very risky, as we make no effort to clear an air pocket or
// An unsafe exit teleports the user to the first available air space
// in the pocket's root dimension. X and Z are kept roughly the same
// as the source location, but Y is set by searching down. We don't
// place a platform at the destination. We also don't place a reverse
// link at the destination, so it's a one-way trip. Good luck!
@ -449,13 +449,20 @@ public class DDTeleporter
if (current.isPocketDimension())
{
Point4D source = link.source();
current.root().setDestination(link, source.getX(), source.getY(), source.getZ());
return true;
}
else
{
return false;
World world = PocketManager.loadDimension(current.root().id());
if (world == null)
{
return false;
}
Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY(), source.getZ());
if (destination != null)
{
current.root().setDestination(link, source.getX(), source.getY(), source.getZ());
return true;
}
}
return false;
}
private static boolean generateSafeExit(DimLink link, DDProperties properties)

View file

@ -217,6 +217,71 @@ public class yCoordHelper
}
return target;
}
public static Point3D findDropPoint(World world, int x, int y, int z)
{
/*// Find a simple 2-block-high air gap
// Search across a 3x3 column
int localX = x < 0 ? (x % 16) + 16 : (x % 16);
int localZ = z < 0 ? (z % 16) + 16 : (z % 16);
int cornerX = x - localX;
int cornerZ = z - localZ;
localX = MathHelper.clamp_int(localX, 1, 14);
localZ = MathHelper.clamp_int(localZ, 1, 14);
Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4);
int height = world.getActualHeight();
int y, dx, dz, blockID;
boolean isSafe;
boolean hasBlocks;
Block block;
int layers = 0;
// Check if a 3x3 layer of blocks is empty
// If we find a layer that contains replaceable blocks, it can
// serve as the base where we'll place the player and door.
for (y = Math.min(startY + 2, height - 1); y >= 0; y--)
{
isSafe = true;
hasBlocks = false;
for (dx = -1; dx <= 1 && isSafe; dx++)
{
for (dz = -1; dz <= 1 && isSafe; dz++)
{
blockID = chunk.getBlockID(localX + dx, y, localZ + dz);
if (blockID != 0)
{
block = Block.blocksList[blockID];
if (!block.blockMaterial.isReplaceable())
{
if (layers >= 3)
{
return new Point3D(localX + cornerX, y + 1, localZ + cornerZ);
}
isSafe = false;
}
hasBlocks = true;
}
}
}
if (isSafe)
{
layers++;
if (hasBlocks)
{
if (layers >= 3)
{
return new Point3D(localX + cornerX, y, localZ + cornerZ);
}
layers = 0;
}
}
}
return null;*/
// Temporary measure to not break the build
return new Point3D(x, y - 2, z);
}
public static int adjustDestinationY(int y, int worldHeight, int entranceY, int dungeonHeight)
{