Grass tiles in unsuitable locations now disappear slowly

This commit is contained in:
OLEGSHA 2020-12-01 23:49:55 +03:00
parent f8e763c0d6
commit 89e24b05c0
4 changed files with 59 additions and 29 deletions

View File

@ -115,7 +115,14 @@ public class ChunkData {
getTiles(pos, BlockFace.TOP).add(grass); getTiles(pos, BlockFace.TOP).add(grass);
for (BlockFace face : BlockFace.getFaces()) { for (BlockFace face : BlockFace.getFaces()) {
if (face.getVector().z != 0) continue; 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; int hash = x*x * 19 ^ y*y * 41 ^ pos.z*pos.z * 147;

View File

@ -1,5 +1,7 @@
package ru.windcorp.progressia.server.world; package ru.windcorp.progressia.server.world;
import java.util.Random;
import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.tasks.WorldAccessor;
@ -18,6 +20,10 @@ public interface TickContext {
return getServer().getWorldAccessor(); return getServer().getWorldAccessor();
} }
default Random getRandom() {
return getServer().getAdHocRandom();
}
default WorldData getWorldData() { default WorldData getWorldData() {
return getWorld().getData(); return getWorld().getData();
} }

View File

@ -19,10 +19,10 @@ public class EdgeTileLogic extends TileLogic implements UpdateableTile {
@Override @Override
public boolean canOccupyFace(TileTickContext context) { public boolean canOccupyFace(TileTickContext context) {
boolean canOccupy = false; boolean canOccupyCurrent = canOccupyFace(context, context.getCurrentFace(), context.getCurrentBlockContext());
canOccupy ^= canOccupyFace(context, context.getCurrentFace(), context.getCurrentBlockContext()); boolean canOccupyCounter = canOccupyFace(context, context.getCounterFace(), context.getCounterBlockContext());
canOccupy ^= canOccupyFace(context, context.getCounterFace(), context.getCounterBlockContext());
return canOccupy; return (canOccupyCurrent != canOccupyCounter) || (canOccupyCurrent && canOccupyCounter && canBeSquashed(context));
} }
public boolean canOccupyFace(TileTickContext ownContext, BlockFace blockFace, BlockTickContext blockContext) { public boolean canOccupyFace(TileTickContext ownContext, BlockFace blockFace, BlockTickContext blockContext) {
@ -32,4 +32,8 @@ public class EdgeTileLogic extends TileLogic implements UpdateableTile {
return block.isSolid(blockContext, ownContext.getCurrentFace()); return block.isSolid(blockContext, ownContext.getCurrentFace());
} }
public boolean canBeSquashed(TileTickContext context) {
return false;
}
} }

View File

@ -6,43 +6,56 @@ import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.TickAndUpdateUtil; import ru.windcorp.progressia.server.world.TickAndUpdateUtil;
import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockLogic;
import ru.windcorp.progressia.server.world.block.BlockTickContext; 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.EdgeTileLogic;
import ru.windcorp.progressia.server.world.tile.TickableTile;
import ru.windcorp.progressia.server.world.tile.TileTickContext; import ru.windcorp.progressia.server.world.tile.TileTickContext;
public class TestTileLogicGrass extends EdgeTileLogic { public class TestTileLogicGrass extends EdgeTileLogic implements TickableTile {
public TestTileLogicGrass(String id) { public TestTileLogicGrass(String id) {
super(id); super(id);
} }
private boolean isBlockAboveTransparent(Server server, Vec3i blockInWorld) { @Override
BlockTickContext blockAboveContext = TickAndUpdateUtil.getBlockTickContext(server, blockInWorld.add_(BlockFace.TOP.getVector())); public TickingPolicy getTickingPolicy(TileTickContext context) {
return TickingPolicy.RANDOM;
BlockLogic blockAbove = blockAboveContext.getBlock();
if (blockAbove == null) return true;
return blockAbove.isTransparent(blockAboveContext);
} }
@Override @Override
public void update(TileTickContext context) { public void tick(TileTickContext context) {
super.update(context); if (!isLocationSuitable(context)) {
if (
!(
context.getCurrentFace() == BlockFace.BOTTOM
||
isBlockAboveTransparent(context.getServer(), context.getCurrentBlockInWorld())
)
||
!(
context.getCounterFace() == BlockFace.BOTTOM
||
isBlockAboveTransparent(context.getServer(), context.getCounterBlockInWorld())
)
) {
context.removeThisTile(); 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);
}
} }