Added TileLogic
This commit is contained in:
parent
fcf5da731f
commit
068f229a45
@ -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);
|
||||||
// }
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user