diff --git a/src/main/java/ru/windcorp/progressia/client/TestContent.java b/src/main/java/ru/windcorp/progressia/client/TestContent.java index b866d76..3a93f54 100644 --- a/src/main/java/ru/windcorp/progressia/client/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/client/TestContent.java @@ -26,6 +26,8 @@ import ru.windcorp.progressia.server.comms.Client; import ru.windcorp.progressia.server.comms.controls.ControlLogic; import ru.windcorp.progressia.server.comms.controls.ControlLogicRegistry; import ru.windcorp.progressia.server.world.block.*; +import ru.windcorp.progressia.server.world.tile.TileLogic; +import ru.windcorp.progressia.server.world.tile.TileLogicRegistry; public class TestContent { @@ -64,15 +66,19 @@ public class TestContent { private static void registerTiles() { register(new TileData("Test", "Grass")); register(new TileRenderGrass("Test", "Grass", getTileTexture("grass_top"), getTileTexture("grass_side"))); + register(new TileLogic("Test", "Grass")); register(new TileData("Test", "Stones")); register(new TileRenderSimple("Test", "Stones", getTileTexture("stones"))); + register(new TileLogic("Test", "Stones")); register(new TileData("Test", "YellowFlowers")); register(new TileRenderSimple("Test", "YellowFlowers", getTileTexture("yellow_flowers"))); + register(new TileLogic("Test", "YellowFlowers")); register(new TileData("Test", "Sand")); register(new TileRenderSimple("Test", "Sand", getTileTexture("sand"))); + register(new TileLogic("Test", "Sand")); } private static void regsiterControls() { @@ -117,8 +123,8 @@ public class TestContent { BlockLogicRegistry.getInstance().register(x); } -// private static void register(TileRender x) { -// TileLogicRegistry.getInstance().register(x); -// } + private static void register(TileLogic x) { + TileLogicRegistry.getInstance().register(x); + } } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileLocation.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileLocation.java new file mode 100644 index 0000000..9590454 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileLocation.java @@ -0,0 +1,22 @@ +package ru.windcorp.progressia.client.world.tile; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.BlockFace; + +public class TileLocation { + + public final Vec3i pos = new Vec3i(); + public BlockFace face; + public int layer; + + public TileLocation() { + // Do nothing + } + + public TileLocation(TileLocation src) { + this.pos.set(src.pos.x, src.pos.y, src.pos.z); + this.face = src.face; + this.layer = src.layer; + } + +} 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 64033a6..f1f2bb8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -21,11 +21,13 @@ import static ru.windcorp.progressia.common.world.block.BlockFace.*; import java.util.ArrayList; import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Consumer; import com.google.common.collect.Lists; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.client.world.tile.TileLocation; import ru.windcorp.progressia.common.util.SizeLimitedList; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; @@ -249,6 +251,34 @@ public class ChunkData { action ); } + + /** + * Iterates over all tiles in this chunk. Tiles are referenced using their + * primary block (so that the face is + * {@linkplain BlockFace#isPrimary() primary}). + * + * @param action the action to perform. {@code TileLocation} refers to each + * tile using its primary block + */ + public void forEachTile(BiConsumer action) { + TileLocation loc = new TileLocation(); + + forEachBlock(blockInChunk -> { + loc.pos.set(blockInChunk.x, blockInChunk.y, blockInChunk.z); + + for (BlockFace face : BlockFace.getPrimaryFaces()) { + List list = getTilesOrNull(blockInChunk, face); + if (list == null) continue; + + loc.face = face; + + for (loc.layer = 0; loc.layer < list.size(); ++loc.layer) { + TileData tile = list.get(loc.layer); + action.accept(loc, tile); + } + } + }); + } public int getX() { return position.x; diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java index 9b489a4..6ba1087 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java @@ -2,43 +2,82 @@ package ru.windcorp.progressia.server.world; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; import java.util.function.BiConsumer; +import com.google.common.collect.Lists; + import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.client.world.tile.TileLocation; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; -import ru.windcorp.progressia.server.world.block.Tickable; +import ru.windcorp.progressia.server.world.block.TickableBlock; +import ru.windcorp.progressia.server.world.tile.TickableTile; +import ru.windcorp.progressia.server.world.tile.TileLogic; +import ru.windcorp.progressia.server.world.tile.TileLogicRegistry; public class ChunkLogic { private final WorldLogic world; private final ChunkData data; - private final Collection ticking = new ArrayList<>(); + private final Collection tickingBlocks = new ArrayList<>(); + private final Collection tickingTiles = new ArrayList<>(); + + private final Map, List> tileLogicLists = + Collections.synchronizedMap(new WeakHashMap<>()); public ChunkLogic(WorldLogic world, ChunkData data) { this.world = world; this.data = data; - generateTickList(); + generateTickLists(); } - private void generateTickList() { + private void generateTickLists() { MutableBlockTickContext blockTickContext = new MutableBlockTickContext(); + MutableTileTickContext tileTickContext = + new MutableTileTickContext(); + blockTickContext.setWorld(getWorld()); blockTickContext.setChunk(this); + tileTickContext.setWorld(getWorld()); + tileTickContext.setChunk(this); + data.forEachBlock(blockInChunk -> { BlockLogic block = getBlock(blockInChunk); - if (block instanceof Tickable) { + if (block instanceof TickableBlock) { blockTickContext.setCoordsInChunk(blockInChunk); - if (((Tickable) block).doesTickRegularly(blockTickContext)) { - ticking.add(new Vec3i(blockInChunk)); + if (((TickableBlock) block) + .doesTickRegularly(blockTickContext) + ) { + tickingBlocks.add(new Vec3i(blockInChunk)); + } + } + }); + + data.forEachTile((loc, tileData) -> { + TileLogic tile = + TileLogicRegistry.getInstance().get(tileData.getId()); + + if (tile instanceof TickableTile) { + tileTickContext.setCoordsInChunk(loc.pos); + tileTickContext.setFace(loc.face); + tileTickContext.setLayer(loc.layer); + + if (((TickableTile) tile).doesTickRegularly(tileTickContext)) { + tickingTiles.add(new TileLocation(loc)); } } }); @@ -53,19 +92,57 @@ public class ChunkLogic { } public boolean hasTickingBlocks() { - return ticking.isEmpty(); + return !tickingBlocks.isEmpty(); + } + + public boolean hasTickingTiles() { + return !tickingTiles.isEmpty(); } public void forEachTickingBlock(BiConsumer action) { - ticking.forEach(blockInChunk -> { + tickingBlocks.forEach(blockInChunk -> { action.accept(blockInChunk, getBlock(blockInChunk)); }); } + public void forEachTickingTile(BiConsumer action) { + tickingTiles.forEach(location -> { + action.accept( + location, + getTilesOrNull(location.pos, location.face) + .get(location.layer) + ); + }); + } + public BlockLogic getBlock(Vec3i blockInChunk) { return BlockLogicRegistry.getInstance().get( getData().getBlock(blockInChunk).getId() ); } + + public List getTiles(Vec3i blockInChunk, BlockFace face) { + return wrapTileList(getData().getTiles(blockInChunk, face)); + } + + public List getTilesOrNull(Vec3i blockInChunk, BlockFace face) { + List tiles = getData().getTilesOrNull(blockInChunk, face); + if (tiles == null) return null; + return wrapTileList(tiles); + } + + private List wrapTileList(List tileDataList) { + return tileLogicLists.computeIfAbsent( + tileDataList, + ChunkLogic::createWrapper + ); + } + + private static List createWrapper(List tileDataList) { + return Lists.transform( + tileDataList, + data -> TileLogicRegistry.getInstance().get(data.getId()) + ); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/MutableBlockTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/MutableBlockTickContext.java index 0b03a5c..b23731a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/MutableBlockTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/MutableBlockTickContext.java @@ -3,57 +3,15 @@ package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockTickContext; -public class MutableBlockTickContext implements BlockTickContext { - - private double tickLength; - - private Server server; - private WorldLogic world; - - private ChunkLogic chunk; +public class MutableBlockTickContext +extends MutableChunkTickContext +implements BlockTickContext { private final Vec3i blockInWorld = new Vec3i(); private final Vec3i blockInChunk = new Vec3i(); - public double getTickLength() { - return tickLength; - } - - public void setTickLength(double tickLength) { - this.tickLength = tickLength; - } - - @Override - public Server getServer() { - return server; - } - - public void setServer(Server server) { - this.server = server; - setWorld(server.getWorld()); - } - - @Override - public WorldLogic getWorld() { - return world; - } - - public void setWorld(WorldLogic world) { - this.world = world; - } - - @Override - public ChunkLogic getChunk() { - return chunk; - } - - public void setChunk(ChunkLogic chunk) { - this.chunk = chunk; - } - @Override public Vec3i getCoords() { return this.blockInWorld; @@ -82,10 +40,4 @@ public class MutableBlockTickContext implements BlockTickContext { ); } - @Override - public void requestBlockTick(Vec3i blockInWorld) { - // TODO implement - throw new UnsupportedOperationException("Not yet implemented"); - } - } diff --git a/src/main/java/ru/windcorp/progressia/server/world/MutableChunkTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/MutableChunkTickContext.java new file mode 100644 index 0000000..775cc1e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/MutableChunkTickContext.java @@ -0,0 +1,66 @@ +package ru.windcorp.progressia.server.world; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.server.Server; + +public class MutableChunkTickContext implements ChunkTickContext { + + private double tickLength; + private Server server; + private WorldLogic world; + private ChunkLogic chunk; + + public MutableChunkTickContext() { + super(); + } + + public double getTickLength() { + return tickLength; + } + + public void setTickLength(double tickLength) { + this.tickLength = tickLength; + } + + @Override + public Server getServer() { + return server; + } + + public void setServer(Server server) { + this.server = server; + setWorld(server.getWorld()); + } + + @Override + public WorldLogic getWorld() { + return world; + } + + public void setWorld(WorldLogic world) { + this.world = world; + } + + @Override + public ChunkLogic getChunk() { + return chunk; + } + + public void setChunk(ChunkLogic chunk) { + this.chunk = chunk; + } + + @Override + public void requestBlockTick(Vec3i blockInWorld) { + // TODO implement + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public void requestTileTick(Vec3i blockInWorld, BlockFace face, int layer) { + // TODO implement + throw new UnsupportedOperationException("Not yet implemented"); + } + +} \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/server/world/MutableTileTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/MutableTileTickContext.java new file mode 100644 index 0000000..6770834 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/MutableTileTickContext.java @@ -0,0 +1,65 @@ +package ru.windcorp.progressia.server.world; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.server.world.tile.TileTickContext; + +public class MutableTileTickContext +extends MutableChunkTickContext +implements TileTickContext { + + private final Vec3i blockInWorld = new Vec3i(); + private final Vec3i blockInChunk = new Vec3i(); + + private BlockFace face; + private int layer; + + @Override + public Vec3i getCoords() { + return this.blockInWorld; + } + + @Override + public Vec3i getChunkCoords() { + return this.blockInChunk; + } + + public void setCoordsInWorld(Vec3i coords) { + getCoords().set(coords.x, coords.y, coords.z); + Coordinates.convertInWorldToInChunk(getCoords(), getChunkCoords()); + + Vec3i chunk = Vectors.grab3i(); + Coordinates.convertInWorldToChunk(coords, chunk); + setChunk(getWorld().getChunk(chunk)); + Vectors.release(chunk); + } + + public void setCoordsInChunk(Vec3i coords) { + getChunkCoords().set(coords.x, coords.y, coords.z); + Coordinates.getInWorld( + getChunkData().getPosition(), getChunkCoords(), + getCoords() + ); + } + + @Override + public BlockFace getFace() { + return face; + } + + public void setFace(BlockFace face) { + this.face = face; + } + + @Override + public int getLayer() { + return layer; + } + + public void setLayer(int layer) { + this.layer = layer; + } + +} 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 d572fec..73d43e0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContext.java @@ -2,6 +2,7 @@ package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.block.BlockFace; import ru.windcorp.progressia.server.Server; public interface TickContext { @@ -19,5 +20,7 @@ public interface TickContext { } void requestBlockTick(Vec3i blockInWorld); + + void requestTileTick(Vec3i blockInWorld, BlockFace face, int layer); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/Ticker.java b/src/main/java/ru/windcorp/progressia/server/world/Ticker.java index 975ddcb..ec4b4e5 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/Ticker.java +++ b/src/main/java/ru/windcorp/progressia/server/world/Ticker.java @@ -1,7 +1,8 @@ package ru.windcorp.progressia.server.world; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.block.Tickable; +import ru.windcorp.progressia.server.world.block.TickableBlock; +import ru.windcorp.progressia.server.world.tile.TickableTile; public class Ticker implements Runnable { @@ -11,6 +12,9 @@ public class Ticker implements Runnable { private final MutableBlockTickContext blockTickContext = new MutableBlockTickContext(); + private final MutableTileTickContext tileTickContext = + new MutableTileTickContext(); + private final Server server; public Ticker(Server server) { @@ -26,30 +30,41 @@ public class Ticker implements Runnable { } private void tickChunk(ChunkLogic chunk) { - MutableBlockTickContext context = this.blockTickContext; + MutableBlockTickContext blockContext = this.blockTickContext; + MutableTileTickContext tileContext = this.tileTickContext; - context.setServer(server); - context.setChunk(chunk); + blockContext.setServer(server); + tileContext.setServer(server); - tickRegularBlocks(chunk, context); - tickRandomBlocks(chunk, context); + tickRegularTickers(chunk, blockContext, tileContext); + tickRandomBlocks(chunk, blockContext, tileContext); flushChanges(chunk); } - private void tickRegularBlocks( + private void tickRegularTickers( ChunkLogic chunk, - MutableBlockTickContext context + MutableBlockTickContext blockContext, + MutableTileTickContext tileContext ) { chunk.forEachTickingBlock((blockInChunk, block) -> { - context.setCoordsInChunk(blockInChunk); - ((Tickable) block).tick(context, tracker); + blockContext.setCoordsInChunk(blockInChunk); + ((TickableBlock) block).tick(blockContext, tracker); + }); + + chunk.forEachTickingTile((locInChunk, tile) -> { + tileContext.setCoordsInChunk(locInChunk.pos); + tileContext.setFace(locInChunk.face); + tileContext.setLayer(locInChunk.layer); + + ((TickableTile) tile).tick(tileContext, tracker); }); } private void tickRandomBlocks( ChunkLogic chunk, - MutableBlockTickContext context + MutableBlockTickContext blockContext, + MutableTileTickContext tileContext ) { // TODO implement } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/ForwardingBlockTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/block/ForwardingBlockTickContext.java index 49bb42c..03be3be 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/ForwardingBlockTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/ForwardingBlockTickContext.java @@ -4,11 +4,12 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.WorldLogic; -public class ForwardingBlockTickContext { +public class ForwardingBlockTickContext implements BlockTickContext { private BlockTickContext parent; @@ -24,46 +25,62 @@ public class ForwardingBlockTickContext { this.parent = parent; } + @Override public ChunkLogic getChunk() { return parent.getChunk(); } - + + @Override public ChunkData getChunkData() { return parent.getChunkData(); } + @Override public double getTickLength() { return parent.getTickLength(); } + @Override public Server getServer() { return parent.getServer(); } + @Override public Vec3i getCoords() { return parent.getCoords(); } + @Override public WorldLogic getWorld() { return parent.getWorld(); } + @Override public WorldData getWorldData() { return parent.getWorldData(); } + @Override public Vec3i getChunkCoords() { return parent.getChunkCoords(); } + @Override public void requestBlockTick(Vec3i blockInWorld) { parent.requestBlockTick(blockInWorld); } + @Override + public void requestTileTick(Vec3i blockInWorld, BlockFace face, int layer) { + parent.requestTileTick(blockInWorld, face, layer); + } + + @Override public BlockLogic getBlock() { return parent.getBlock(); } + @Override public BlockData getBlockData() { return parent.getBlockData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/Tickable.java b/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java similarity index 87% rename from src/main/java/ru/windcorp/progressia/server/world/block/Tickable.java rename to src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java index cb12d80..4bdfceb 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/Tickable.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java @@ -2,7 +2,7 @@ package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.server.world.Changer; -public interface Tickable { +public interface TickableBlock { void tick(BlockTickContext context, Changer changer); diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/Updatable.java b/src/main/java/ru/windcorp/progressia/server/world/block/UpdatableBlock.java similarity index 79% rename from src/main/java/ru/windcorp/progressia/server/world/block/Updatable.java rename to src/main/java/ru/windcorp/progressia/server/world/block/UpdatableBlock.java index ab13886..b76f6da 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/Updatable.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/UpdatableBlock.java @@ -2,7 +2,7 @@ package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.server.world.Changer; -public interface Updatable { +public interface UpdatableBlock { void update(BlockTickContext context, Changer changer); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/ForwardingTileTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/ForwardingTileTickContext.java new file mode 100644 index 0000000..0f2c29e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/ForwardingTileTickContext.java @@ -0,0 +1,132 @@ +package ru.windcorp.progressia.server.world.tile; + +import java.util.List; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.ChunkLogic; +import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.block.BlockLogic; + +public class ForwardingTileTickContext implements TileTickContext { + + private TileTickContext parent; + + public ForwardingTileTickContext(TileTickContext parent) { + this.parent = parent; + } + + public TileTickContext getParent() { + return parent; + } + + public void setParent(TileTickContext parent) { + this.parent = parent; + } + + @Override + public ChunkLogic getChunk() { + return parent.getChunk(); + } + + @Override + public ChunkData getChunkData() { + return parent.getChunkData(); + } + + @Override + public double getTickLength() { + return parent.getTickLength(); + } + + @Override + public Server getServer() { + return parent.getServer(); + } + + @Override + public WorldLogic getWorld() { + return parent.getWorld(); + } + + @Override + public WorldData getWorldData() { + return parent.getWorldData(); + } + + @Override + public void requestBlockTick(Vec3i blockInWorld) { + parent.requestBlockTick(blockInWorld); + } + + @Override + public void requestTileTick(Vec3i blockInWorld, BlockFace face, int layer) { + parent.requestTileTick(blockInWorld, face, layer); + } + + @Override + public Vec3i getCoords() { + return parent.getCoords(); + } + + @Override + public Vec3i getChunkCoords() { + return parent.getChunkCoords(); + } + + @Override + public BlockFace getFace() { + return parent.getFace(); + } + + @Override + public int getLayer() { + return parent.getLayer(); + } + + @Override + public TileLogic getTile() { + return parent.getTile(); + } + + @Override + public TileData getTileData() { + return parent.getTileData(); + } + + @Override + public List getTiles() { + return parent.getTiles(); + } + + @Override + public List getTilesOrNull() { + return parent.getTilesOrNull(); + } + + @Override + public List getTileDataList() { + return parent.getTileDataList(); + } + + @Override + public List getTileDataListOrNull() { + return parent.getTileDataListOrNull(); + } + + @Override + public BlockLogic getBlock() { + return parent.getBlock(); + } + + @Override + public BlockData getBlockData() { + return parent.getBlockData(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java new file mode 100644 index 0000000..d078ba0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java @@ -0,0 +1,17 @@ +package ru.windcorp.progressia.server.world.tile; + +import ru.windcorp.progressia.server.world.Changer; + +public interface TickableTile { + + void tick(TileTickContext context, Changer changer); + + default boolean doesTickRegularly(TileTickContext context) { + return false; + } + + default boolean doesTickRandomly(TileTickContext context) { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java new file mode 100644 index 0000000..f530c26 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java @@ -0,0 +1,28 @@ +package ru.windcorp.progressia.server.world.tile; + +import ru.windcorp.progressia.common.util.Namespaced; +import ru.windcorp.progressia.common.world.block.BlockFace; + +public class TileLogic extends Namespaced { + + public TileLogic(String namespace, String name) { + super(namespace, name); + } + + public boolean canOccupyFace(TileTickContext context) { + return canOccupyFace(context.getFace()); + } + + public boolean canOccupyFace(BlockFace face) { + return true; + } + + public boolean isSolid(TileTickContext context) { + return isSolid(); + } + + public boolean isSolid() { + return false; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicRegistry.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicRegistry.java new file mode 100644 index 0000000..a5b522b --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicRegistry.java @@ -0,0 +1,13 @@ +package ru.windcorp.progressia.server.world.tile; + +import ru.windcorp.progressia.common.util.NamespacedRegistry; + +public class TileLogicRegistry extends NamespacedRegistry { + + private static final TileLogicRegistry INSTANCE = new TileLogicRegistry(); + + public static TileLogicRegistry getInstance() { + return INSTANCE; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java new file mode 100644 index 0000000..0b80b5f --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java @@ -0,0 +1,71 @@ +package ru.windcorp.progressia.server.world.tile; + +import java.util.List; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.world.ChunkTickContext; +import ru.windcorp.progressia.server.world.block.BlockLogic; + +public interface TileTickContext extends ChunkTickContext { + + /** + * Returns the current world coordinates. + * @return the world coordinates of the tile being ticked + */ + Vec3i getCoords(); + + /** + * Returns the current chunk coordinates. + * @return the chunk coordinates of the tile being ticked + */ + Vec3i getChunkCoords(); + + /** + * Returns the current block face. This face is always + * {@linkplain BlockFace#isPrimary() primary}. + * @return the block face that the tile being ticked occupies + */ + BlockFace getFace(); + + /** + * Returns the current layer. + * @return the layer that the tile being ticked occupies in the tile stack + */ + int getLayer(); + + default TileLogic getTile() { + return getTiles().get(getLayer()); + } + + default TileData getTileData() { + return getTileDataList().get(getLayer()); + } + + default List getTiles() { + return getChunk().getTiles(getChunkCoords(), getFace()); + } + + default List getTilesOrNull() { + return getChunk().getTilesOrNull(getChunkCoords(), getFace()); + } + + default List getTileDataList() { + return getChunkData().getTiles(getChunkCoords(), getFace()); + } + + default List getTileDataListOrNull() { + return getChunkData().getTilesOrNull(getChunkCoords(), getFace()); + } + + default BlockLogic getBlock() { + return getChunk().getBlock(getChunkCoords()); + } + + default BlockData getBlockData() { + return getChunkData().getBlock(getChunkCoords()); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/UpdatableTile.java b/src/main/java/ru/windcorp/progressia/server/world/tile/UpdatableTile.java new file mode 100644 index 0000000..00613f0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/UpdatableTile.java @@ -0,0 +1,9 @@ +package ru.windcorp.progressia.server.world.tile; + +import ru.windcorp.progressia.server.world.Changer; + +public interface UpdatableTile { + + void update(TileTickContext context, Changer changer); + +}