Added TileLogic

This commit is contained in:
OLEGSHA 2020-08-31 20:39:35 +03:00
parent fcf5da731f
commit 068f229a45
18 changed files with 601 additions and 78 deletions

View File

@ -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.ControlLogic;
import ru.windcorp.progressia.server.comms.controls.ControlLogicRegistry; import ru.windcorp.progressia.server.comms.controls.ControlLogicRegistry;
import ru.windcorp.progressia.server.world.block.*; 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 { public class TestContent {
@ -64,15 +66,19 @@ public class TestContent {
private static void registerTiles() { private static void registerTiles() {
register(new TileData("Test", "Grass")); register(new TileData("Test", "Grass"));
register(new TileRenderGrass("Test", "Grass", getTileTexture("grass_top"), getTileTexture("grass_side"))); register(new TileRenderGrass("Test", "Grass", getTileTexture("grass_top"), getTileTexture("grass_side")));
register(new TileLogic("Test", "Grass"));
register(new TileData("Test", "Stones")); register(new TileData("Test", "Stones"));
register(new TileRenderSimple("Test", "Stones", getTileTexture("stones"))); register(new TileRenderSimple("Test", "Stones", getTileTexture("stones")));
register(new TileLogic("Test", "Stones"));
register(new TileData("Test", "YellowFlowers")); register(new TileData("Test", "YellowFlowers"));
register(new TileRenderSimple("Test", "YellowFlowers", getTileTexture("yellow_flowers"))); register(new TileRenderSimple("Test", "YellowFlowers", getTileTexture("yellow_flowers")));
register(new TileLogic("Test", "YellowFlowers"));
register(new TileData("Test", "Sand")); register(new TileData("Test", "Sand"));
register(new TileRenderSimple("Test", "Sand", getTileTexture("sand"))); register(new TileRenderSimple("Test", "Sand", getTileTexture("sand")));
register(new TileLogic("Test", "Sand"));
} }
private static void regsiterControls() { private static void regsiterControls() {
@ -117,8 +123,8 @@ public class TestContent {
BlockLogicRegistry.getInstance().register(x); BlockLogicRegistry.getInstance().register(x);
} }
// private static void register(TileRender x) { private static void register(TileLogic x) {
// TileLogicRegistry.getInstance().register(x); TileLogicRegistry.getInstance().register(x);
// } }
} }

View File

@ -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;
}
}

View File

@ -21,11 +21,13 @@ import static ru.windcorp.progressia.common.world.block.BlockFace.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import glm.vec._3.i.Vec3i; 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.SizeLimitedList;
import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.VectorUtil;
import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.Vectors;
@ -249,6 +251,34 @@ public class ChunkData {
action 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<TileLocation, TileData> action) {
TileLocation loc = new TileLocation();
forEachBlock(blockInChunk -> {
loc.pos.set(blockInChunk.x, blockInChunk.y, blockInChunk.z);
for (BlockFace face : BlockFace.getPrimaryFaces()) {
List<TileData> 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() { public int getX() {
return position.x; return position.x;

View File

@ -2,43 +2,82 @@ package ru.windcorp.progressia.server.world;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; 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 java.util.function.BiConsumer;
import com.google.common.collect.Lists;
import glm.vec._3.i.Vec3i; 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.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.BlockLogic;
import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; 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 { public class ChunkLogic {
private final WorldLogic world; private final WorldLogic world;
private final ChunkData data; private final ChunkData data;
private final Collection<Vec3i> ticking = new ArrayList<>(); private final Collection<Vec3i> tickingBlocks = new ArrayList<>();
private final Collection<TileLocation> tickingTiles = new ArrayList<>();
private final Map<List<TileData>, List<TileLogic>> tileLogicLists =
Collections.synchronizedMap(new WeakHashMap<>());
public ChunkLogic(WorldLogic world, ChunkData data) { public ChunkLogic(WorldLogic world, ChunkData data) {
this.world = world; this.world = world;
this.data = data; this.data = data;
generateTickList(); generateTickLists();
} }
private void generateTickList() { private void generateTickLists() {
MutableBlockTickContext blockTickContext = MutableBlockTickContext blockTickContext =
new MutableBlockTickContext(); new MutableBlockTickContext();
MutableTileTickContext tileTickContext =
new MutableTileTickContext();
blockTickContext.setWorld(getWorld()); blockTickContext.setWorld(getWorld());
blockTickContext.setChunk(this); blockTickContext.setChunk(this);
tileTickContext.setWorld(getWorld());
tileTickContext.setChunk(this);
data.forEachBlock(blockInChunk -> { data.forEachBlock(blockInChunk -> {
BlockLogic block = getBlock(blockInChunk); BlockLogic block = getBlock(blockInChunk);
if (block instanceof Tickable) { if (block instanceof TickableBlock) {
blockTickContext.setCoordsInChunk(blockInChunk); blockTickContext.setCoordsInChunk(blockInChunk);
if (((Tickable) block).doesTickRegularly(blockTickContext)) { if (((TickableBlock) block)
ticking.add(new Vec3i(blockInChunk)); .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() { public boolean hasTickingBlocks() {
return ticking.isEmpty(); return !tickingBlocks.isEmpty();
}
public boolean hasTickingTiles() {
return !tickingTiles.isEmpty();
} }
public void forEachTickingBlock(BiConsumer<Vec3i, BlockLogic> action) { public void forEachTickingBlock(BiConsumer<Vec3i, BlockLogic> action) {
ticking.forEach(blockInChunk -> { tickingBlocks.forEach(blockInChunk -> {
action.accept(blockInChunk, getBlock(blockInChunk)); action.accept(blockInChunk, getBlock(blockInChunk));
}); });
} }
public void forEachTickingTile(BiConsumer<TileLocation, TileLogic> action) {
tickingTiles.forEach(location -> {
action.accept(
location,
getTilesOrNull(location.pos, location.face)
.get(location.layer)
);
});
}
public BlockLogic getBlock(Vec3i blockInChunk) { public BlockLogic getBlock(Vec3i blockInChunk) {
return BlockLogicRegistry.getInstance().get( return BlockLogicRegistry.getInstance().get(
getData().getBlock(blockInChunk).getId() getData().getBlock(blockInChunk).getId()
); );
} }
public List<TileLogic> getTiles(Vec3i blockInChunk, BlockFace face) {
return wrapTileList(getData().getTiles(blockInChunk, face));
}
public List<TileLogic> getTilesOrNull(Vec3i blockInChunk, BlockFace face) {
List<TileData> tiles = getData().getTilesOrNull(blockInChunk, face);
if (tiles == null) return null;
return wrapTileList(tiles);
}
private List<TileLogic> wrapTileList(List<TileData> tileDataList) {
return tileLogicLists.computeIfAbsent(
tileDataList,
ChunkLogic::createWrapper
);
}
private static List<TileLogic> createWrapper(List<TileData> tileDataList) {
return Lists.transform(
tileDataList,
data -> TileLogicRegistry.getInstance().get(data.getId())
);
}
} }

View File

@ -3,57 +3,15 @@ package ru.windcorp.progressia.server.world;
import glm.vec._3.i.Vec3i; import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.Vectors;
import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.Coordinates;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.block.BlockTickContext; import ru.windcorp.progressia.server.world.block.BlockTickContext;
public class MutableBlockTickContext implements BlockTickContext { public class MutableBlockTickContext
extends MutableChunkTickContext
private double tickLength; implements BlockTickContext {
private Server server;
private WorldLogic world;
private ChunkLogic chunk;
private final Vec3i blockInWorld = new Vec3i(); private final Vec3i blockInWorld = new Vec3i();
private final Vec3i blockInChunk = 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 @Override
public Vec3i getCoords() { public Vec3i getCoords() {
return this.blockInWorld; 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");
}
} }

View File

@ -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");
}
}

View File

@ -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;
}
}

View File

@ -2,6 +2,7 @@ package ru.windcorp.progressia.server.world;
import glm.vec._3.i.Vec3i; import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.block.BlockFace;
import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.Server;
public interface TickContext { public interface TickContext {
@ -19,5 +20,7 @@ public interface TickContext {
} }
void requestBlockTick(Vec3i blockInWorld); void requestBlockTick(Vec3i blockInWorld);
void requestTileTick(Vec3i blockInWorld, BlockFace face, int layer);
} }

View File

@ -1,7 +1,8 @@
package ru.windcorp.progressia.server.world; package ru.windcorp.progressia.server.world;
import ru.windcorp.progressia.server.Server; 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 { public class Ticker implements Runnable {
@ -11,6 +12,9 @@ public class Ticker implements Runnable {
private final MutableBlockTickContext blockTickContext = private final MutableBlockTickContext blockTickContext =
new MutableBlockTickContext(); new MutableBlockTickContext();
private final MutableTileTickContext tileTickContext =
new MutableTileTickContext();
private final Server server; private final Server server;
public Ticker(Server server) { public Ticker(Server server) {
@ -26,30 +30,41 @@ public class Ticker implements Runnable {
} }
private void tickChunk(ChunkLogic chunk) { private void tickChunk(ChunkLogic chunk) {
MutableBlockTickContext context = this.blockTickContext; MutableBlockTickContext blockContext = this.blockTickContext;
MutableTileTickContext tileContext = this.tileTickContext;
context.setServer(server); blockContext.setServer(server);
context.setChunk(chunk); tileContext.setServer(server);
tickRegularBlocks(chunk, context); tickRegularTickers(chunk, blockContext, tileContext);
tickRandomBlocks(chunk, context); tickRandomBlocks(chunk, blockContext, tileContext);
flushChanges(chunk); flushChanges(chunk);
} }
private void tickRegularBlocks( private void tickRegularTickers(
ChunkLogic chunk, ChunkLogic chunk,
MutableBlockTickContext context MutableBlockTickContext blockContext,
MutableTileTickContext tileContext
) { ) {
chunk.forEachTickingBlock((blockInChunk, block) -> { chunk.forEachTickingBlock((blockInChunk, block) -> {
context.setCoordsInChunk(blockInChunk); blockContext.setCoordsInChunk(blockInChunk);
((Tickable) block).tick(context, tracker); ((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( private void tickRandomBlocks(
ChunkLogic chunk, ChunkLogic chunk,
MutableBlockTickContext context MutableBlockTickContext blockContext,
MutableTileTickContext tileContext
) { ) {
// TODO implement // TODO implement
} }

View File

@ -4,11 +4,12 @@ import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.ChunkData;
import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.block.BlockData; 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.Server;
import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.ChunkLogic;
import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.WorldLogic;
public class ForwardingBlockTickContext { public class ForwardingBlockTickContext implements BlockTickContext {
private BlockTickContext parent; private BlockTickContext parent;
@ -24,46 +25,62 @@ public class ForwardingBlockTickContext {
this.parent = parent; this.parent = parent;
} }
@Override
public ChunkLogic getChunk() { public ChunkLogic getChunk() {
return parent.getChunk(); return parent.getChunk();
} }
@Override
public ChunkData getChunkData() { public ChunkData getChunkData() {
return parent.getChunkData(); return parent.getChunkData();
} }
@Override
public double getTickLength() { public double getTickLength() {
return parent.getTickLength(); return parent.getTickLength();
} }
@Override
public Server getServer() { public Server getServer() {
return parent.getServer(); return parent.getServer();
} }
@Override
public Vec3i getCoords() { public Vec3i getCoords() {
return parent.getCoords(); return parent.getCoords();
} }
@Override
public WorldLogic getWorld() { public WorldLogic getWorld() {
return parent.getWorld(); return parent.getWorld();
} }
@Override
public WorldData getWorldData() { public WorldData getWorldData() {
return parent.getWorldData(); return parent.getWorldData();
} }
@Override
public Vec3i getChunkCoords() { public Vec3i getChunkCoords() {
return parent.getChunkCoords(); return parent.getChunkCoords();
} }
@Override
public void requestBlockTick(Vec3i blockInWorld) { public void requestBlockTick(Vec3i blockInWorld) {
parent.requestBlockTick(blockInWorld); parent.requestBlockTick(blockInWorld);
} }
@Override
public void requestTileTick(Vec3i blockInWorld, BlockFace face, int layer) {
parent.requestTileTick(blockInWorld, face, layer);
}
@Override
public BlockLogic getBlock() { public BlockLogic getBlock() {
return parent.getBlock(); return parent.getBlock();
} }
@Override
public BlockData getBlockData() { public BlockData getBlockData() {
return parent.getBlockData(); return parent.getBlockData();
} }

View File

@ -2,7 +2,7 @@ package ru.windcorp.progressia.server.world.block;
import ru.windcorp.progressia.server.world.Changer; import ru.windcorp.progressia.server.world.Changer;
public interface Tickable { public interface TickableBlock {
void tick(BlockTickContext context, Changer changer); void tick(BlockTickContext context, Changer changer);

View File

@ -2,7 +2,7 @@ package ru.windcorp.progressia.server.world.block;
import ru.windcorp.progressia.server.world.Changer; import ru.windcorp.progressia.server.world.Changer;
public interface Updatable { public interface UpdatableBlock {
void update(BlockTickContext context, Changer changer); void update(BlockTickContext context, Changer changer);

View File

@ -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<TileLogic> getTiles() {
return parent.getTiles();
}
@Override
public List<TileLogic> getTilesOrNull() {
return parent.getTilesOrNull();
}
@Override
public List<TileData> getTileDataList() {
return parent.getTileDataList();
}
@Override
public List<TileData> getTileDataListOrNull() {
return parent.getTileDataListOrNull();
}
@Override
public BlockLogic getBlock() {
return parent.getBlock();
}
@Override
public BlockData getBlockData() {
return parent.getBlockData();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,13 @@
package ru.windcorp.progressia.server.world.tile;
import ru.windcorp.progressia.common.util.NamespacedRegistry;
public class TileLogicRegistry extends NamespacedRegistry<TileLogic> {
private static final TileLogicRegistry INSTANCE = new TileLogicRegistry();
public static TileLogicRegistry getInstance() {
return INSTANCE;
}
}

View File

@ -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<TileLogic> getTiles() {
return getChunk().getTiles(getChunkCoords(), getFace());
}
default List<TileLogic> getTilesOrNull() {
return getChunk().getTilesOrNull(getChunkCoords(), getFace());
}
default List<TileData> getTileDataList() {
return getChunkData().getTiles(getChunkCoords(), getFace());
}
default List<TileData> getTileDataListOrNull() {
return getChunkData().getTilesOrNull(getChunkCoords(), getFace());
}
default BlockLogic getBlock() {
return getChunk().getBlock(getChunkCoords());
}
default BlockData getBlockData() {
return getChunkData().getBlock(getChunkCoords());
}
}

View File

@ -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);
}