diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 2625d6b..86b226c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -115,7 +115,14 @@ public class ChunkData { getTiles(pos, BlockFace.TOP).add(grass); for (BlockFace face : BlockFace.getFaces()) { if (face.getVector().z != 0) continue; - getTiles(pos, face).add(grass); + pos.add(face.getVector()); + + if (!isInBounds(pos) || (getBlock(pos) == air)) { + pos.sub(face.getVector()); + getTiles(pos, face).add(grass); + } else { + pos.sub(face.getVector()); + } } int hash = x*x * 19 ^ y*y * 41 ^ pos.z*pos.z * 147; diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java b/src/main/java/ru/windcorp/progressia/server/world/TickContext.java index de41d98..82b18e0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContext.java @@ -1,5 +1,7 @@ package ru.windcorp.progressia.server.world; +import java.util.Random; + import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; @@ -18,6 +20,10 @@ public interface TickContext { return getServer().getWorldAccessor(); } + default Random getRandom() { + return getServer().getAdHocRandom(); + } + default WorldData getWorldData() { return getWorld().getData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/EdgeTileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/EdgeTileLogic.java index 0c72f8a..516d6a5 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/EdgeTileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/EdgeTileLogic.java @@ -19,10 +19,10 @@ public class EdgeTileLogic extends TileLogic implements UpdateableTile { @Override public boolean canOccupyFace(TileTickContext context) { - boolean canOccupy = false; - canOccupy ^= canOccupyFace(context, context.getCurrentFace(), context.getCurrentBlockContext()); - canOccupy ^= canOccupyFace(context, context.getCounterFace(), context.getCounterBlockContext()); - return canOccupy; + boolean canOccupyCurrent = canOccupyFace(context, context.getCurrentFace(), context.getCurrentBlockContext()); + boolean canOccupyCounter = canOccupyFace(context, context.getCounterFace(), context.getCounterBlockContext()); + + return (canOccupyCurrent != canOccupyCounter) || (canOccupyCurrent && canOccupyCounter && canBeSquashed(context)); } public boolean canOccupyFace(TileTickContext ownContext, BlockFace blockFace, BlockTickContext blockContext) { @@ -31,5 +31,9 @@ public class EdgeTileLogic extends TileLogic implements UpdateableTile { return block.isSolid(blockContext, ownContext.getCurrentFace()); } + + public boolean canBeSquashed(TileTickContext context) { + return false; + } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index 4358d2c..b3212bc 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -6,43 +6,56 @@ import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockTickContext; +import ru.windcorp.progressia.server.world.ticking.TickingPolicy; import ru.windcorp.progressia.server.world.tile.EdgeTileLogic; +import ru.windcorp.progressia.server.world.tile.TickableTile; import ru.windcorp.progressia.server.world.tile.TileTickContext; -public class TestTileLogicGrass extends EdgeTileLogic { +public class TestTileLogicGrass extends EdgeTileLogic implements TickableTile { public TestTileLogicGrass(String id) { super(id); } - private boolean isBlockAboveTransparent(Server server, Vec3i blockInWorld) { - BlockTickContext blockAboveContext = TickAndUpdateUtil.getBlockTickContext(server, blockInWorld.add_(BlockFace.TOP.getVector())); - - BlockLogic blockAbove = blockAboveContext.getBlock(); - if (blockAbove == null) return true; - - return blockAbove.isTransparent(blockAboveContext); + @Override + public TickingPolicy getTickingPolicy(TileTickContext context) { + return TickingPolicy.RANDOM; } @Override - public void update(TileTickContext context) { - super.update(context); - - if ( - !( - context.getCurrentFace() == BlockFace.BOTTOM - || - isBlockAboveTransparent(context.getServer(), context.getCurrentBlockInWorld()) - ) - || - !( - context.getCounterFace() == BlockFace.BOTTOM - || - isBlockAboveTransparent(context.getServer(), context.getCounterBlockInWorld()) - ) - ) { + public void tick(TileTickContext context) { + if (!isLocationSuitable(context)) { context.removeThisTile(); } } + @Override + public boolean canBeSquashed(TileTickContext context) { + return true; + } + + private boolean isLocationSuitable(TileTickContext context) { + return + isSuitableHost(context.getCurrentBlockContext(), context.getCurrentFace()) != + isSuitableHost(context.getCounterBlockContext(), context.getCounterFace()); + } + + private boolean isSuitableHost(BlockTickContext bctxt, BlockFace face) { + if (face == BlockFace.BOTTOM) return false; + + BlockLogic block = bctxt.getBlock(); + if (block == null) return false; + if (!block.isSolid(bctxt, face)) return false; + return isBlockAboveTransparent(bctxt.getServer(), bctxt.getBlockInWorld()); + } + + private boolean isBlockAboveTransparent(Server server, Vec3i blockInWorld) { + BlockTickContext bctxt = TickAndUpdateUtil.getBlockTickContext(server, blockInWorld.add_(BlockFace.TOP.getVector())); + + BlockLogic block = bctxt.getBlock(); + if (block == null) return true; + + return block.isTransparent(bctxt); + } + }