Removed Exit Platforms for Safe Cases

Updated our code to stop Fabric of Reality platforms from generating
under exits all the time. Now they generate only when the supporting
blocks are replaceable (in which case they're replaced by FoR) or when
they're not opaque solids or have tile entities (then FoR generates on
top). The exit search algorithm treats replaceable non-liquid blocks as
air, so an attempt is made to build against the ground and not on top of
replaceable blocks. The area around the door is cleared of blocks to
avoid killing the player with lingering replaceable blocks that might be
harmful, like poison ivy.
This commit is contained in:
SenseiKiwi
2014-01-24 07:16:32 -04:00
parent f6a6b1d374
commit 149e0319f1
2 changed files with 46 additions and 18 deletions

View File

@@ -692,6 +692,8 @@ public class DDTeleporter
if (destination != null) if (destination != null)
{ {
// Set up a 3x3 platform at the destination // Set up a 3x3 platform at the destination
// Only place fabric of reality if the block is replaceable or air
// Don't cause block updates
int x = destination.getX(); int x = destination.getX();
int y = destination.getY(); int y = destination.getY();
int z = destination.getZ(); int z = destination.getZ();
@@ -699,7 +701,27 @@ public class DDTeleporter
{ {
for (int dz = -1; dz <= 1; dz++) for (int dz = -1; dz <= 1; dz++)
{ {
world.setBlock(x + dx, y, z + dz, properties.FabricBlockID); // Checking if the block is not an opaque solid is equivalent
// checking for a replaceable block, because we only allow
// exits intersecting blocks on those two surfaces.
if (!world.isBlockNormalCube(x + dx, y, z + dz))
{
world.setBlock(x + dx, y, z + dz, properties.FabricBlockID, 0, 2);
}
}
}
// Clear out any blocks in the space above the platform layer
// This removes any potential threats like replaceable Poison Ivy from BoP
// Remember to avoid block updates to keep gravel from collapsing
for (int dy = 1; dy <= 2; dy++)
{
for (int dx = -1; dx <= 1; dx++)
{
for (int dz = -1; dz <= 1; dz++)
{
world.setBlock(x + dx, y + dy, z + dz, 0, 0, 2);
}
} }
} }

View File

@@ -73,8 +73,9 @@ public class yCoordHelper
public static Point3D findSafeCubeUp(World world, int x, int startY, int z) public static Point3D findSafeCubeUp(World world, int x, int startY, int z)
{ {
// Search for a 3x3x3 cube of air with blocks underneath // Search for a 3x2x3 box with solid opaque blocks (without tile entities)
// We can also match against a 3x2x3 box with replaceable blocks underneath // or replaceable blocks underneath. The box must contain either air and
// non-liquid replaceable blocks only.
// We shift the search area into the bounds of a chunk for the sake of simplicity, // We shift the search area into the bounds of a chunk for the sake of simplicity,
// so that we don't need to worry about working across chunks. // so that we don't need to worry about working across chunks.
@@ -88,7 +89,7 @@ public class yCoordHelper
Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4); Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4);
int height = world.getActualHeight(); int height = world.getActualHeight();
int y, dx, dz, blockID; int y, dx, dz, blockID, metadata;
boolean isSafe; boolean isSafe;
Block block; Block block;
@@ -98,8 +99,9 @@ public class yCoordHelper
int layers = -1000000; int layers = -1000000;
// Check if a 3x3 layer of blocks is empty // Check if a 3x3 layer of blocks is empty
// If we find a layer that contains replaceable blocks, it can // Treat non-liquid replaceable blocks like air
// serve as the base where we'll place the player and door. // If we find a layer that contains replaceable blocks or solid opaque blocks without
// tile entities, then it can serve as the base where we'll place the player and door.
for (y = Math.max(startY - 1, 0); y < height; y++) for (y = Math.max(startY - 1, 0); y < height; y++)
{ {
isSafe = true; isSafe = true;
@@ -108,10 +110,11 @@ public class yCoordHelper
for (dz = -1; dz <= 1 && isSafe; dz++) for (dz = -1; dz <= 1 && isSafe; dz++)
{ {
blockID = chunk.getBlockID(localX + dx, y, localZ + dz); blockID = chunk.getBlockID(localX + dx, y, localZ + dz);
if (blockID != 0) metadata = chunk.getBlockMetadata(localX + dx, y, localZ + dz);
block = Block.blocksList[blockID];
if (blockID != 0 && (!block.blockMaterial.isReplaceable() || block.blockMaterial.isLiquid()))
{ {
block = Block.blocksList[blockID]; if (!block.blockMaterial.isReplaceable() && (!block.isOpaqueCube() || block.hasTileEntity(metadata)))
if (!block.blockMaterial.isReplaceable())
{ {
isSafe = false; isSafe = false;
} }
@@ -133,8 +136,9 @@ public class yCoordHelper
public static Point3D findSafeCubeDown(World world, int x, int startY, int z) public static Point3D findSafeCubeDown(World world, int x, int startY, int z)
{ {
// Search for a 3x3x3 cube of air with blocks underneath // Search for a 3x2x3 box with solid opaque blocks (without tile entities)
// We can also match against a 3x2x3 box with // or replaceable blocks underneath. The box must contain either air and
// non-liquid replaceable blocks only.
// We shift the search area into the bounds of a chunk for the sake of simplicity, // We shift the search area into the bounds of a chunk for the sake of simplicity,
// so that we don't need to worry about working across chunks. // so that we don't need to worry about working across chunks.
@@ -148,15 +152,16 @@ public class yCoordHelper
Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4); Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4);
int height = world.getActualHeight(); int height = world.getActualHeight();
int y, dx, dz, blockID; int y, dx, dz, blockID, metadata;
boolean isSafe; boolean isSafe;
boolean hasBlocks; boolean hasBlocks;
Block block; Block block;
int layers = 0; int layers = 0;
// Check if a 3x3 layer of blocks is empty // Check if a 3x3 layer of blocks is empty
// If we find a layer that contains replaceable blocks, it can // Treat non-liquid replaceable blocks like air
// serve as the base where we'll place the player and door. // If we find a layer that contains replaceable blocks or solid opaque blocks without
// tile entities, then 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--) for (y = Math.min(startY + 2, height - 1); y >= 0; y--)
{ {
isSafe = true; isSafe = true;
@@ -166,10 +171,11 @@ public class yCoordHelper
for (dz = -1; dz <= 1 && isSafe; dz++) for (dz = -1; dz <= 1 && isSafe; dz++)
{ {
blockID = chunk.getBlockID(localX + dx, y, localZ + dz); blockID = chunk.getBlockID(localX + dx, y, localZ + dz);
if (blockID != 0) metadata = chunk.getBlockMetadata(localX + dx, y, localZ + dz);
{ block = Block.blocksList[blockID];
block = Block.blocksList[blockID]; if (blockID != 0 && (!block.blockMaterial.isReplaceable() || block.blockMaterial.isLiquid()))
if (!block.blockMaterial.isReplaceable()) {
if (!block.blockMaterial.isReplaceable() && (!block.isOpaqueCube() || block.hasTileEntity(metadata)))
{ {
if (layers >= 3) if (layers >= 3)
{ {