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)
{
// 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 y = destination.getY();
int z = destination.getZ();
@@ -699,7 +701,27 @@ public class DDTeleporter
{
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)
{
// Search for a 3x3x3 cube of air with blocks underneath
// We can also match against a 3x2x3 box with replaceable blocks underneath
// Search for a 3x2x3 box with solid opaque blocks (without tile entities)
// 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,
// 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);
int height = world.getActualHeight();
int y, dx, dz, blockID;
int y, dx, dz, blockID, metadata;
boolean isSafe;
Block block;
@@ -98,8 +99,9 @@ public class yCoordHelper
int layers = -1000000;
// 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.
// Treat non-liquid replaceable blocks like air
// 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++)
{
isSafe = true;
@@ -108,10 +110,11 @@ public class yCoordHelper
for (dz = -1; dz <= 1 && isSafe; 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())
if (!block.blockMaterial.isReplaceable() && (!block.isOpaqueCube() || block.hasTileEntity(metadata)))
{
isSafe = false;
}
@@ -133,8 +136,9 @@ public class yCoordHelper
public static Point3D findSafeCubeDown(World world, int x, int startY, int z)
{
// Search for a 3x3x3 cube of air with blocks underneath
// We can also match against a 3x2x3 box with
// Search for a 3x2x3 box with solid opaque blocks (without tile entities)
// 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,
// 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);
int height = world.getActualHeight();
int y, dx, dz, blockID;
int y, dx, dz, blockID, metadata;
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.
// Treat non-liquid replaceable blocks like air
// 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--)
{
isSafe = true;
@@ -166,10 +171,11 @@ public class yCoordHelper
for (dz = -1; dz <= 1 && isSafe; 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())
if (!block.blockMaterial.isReplaceable() && (!block.isOpaqueCube() || block.hasTileEntity(metadata)))
{
if (layers >= 3)
{