diff --git a/src/main/java/ru/windcorp/progressia/client/Client.java b/src/main/java/ru/windcorp/progressia/client/Client.java index d8800c7..f356954 100644 --- a/src/main/java/ru/windcorp/progressia/client/Client.java +++ b/src/main/java/ru/windcorp/progressia/client/Client.java @@ -24,7 +24,7 @@ import ru.windcorp.progressia.client.graphics.world.Camera; import ru.windcorp.progressia.client.graphics.world.EntityAnchor; import ru.windcorp.progressia.client.graphics.world.LocalPlayer; import ru.windcorp.progressia.client.world.WorldRender; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.entity.EntityData; public class Client { @@ -36,7 +36,7 @@ public class Client { private final ServerCommsChannel comms; - public Client(WorldData world, ServerCommsChannel comms) { + public Client(DefaultWorldData world, ServerCommsChannel comms) { this.world = new WorldRender(world, this); this.comms = comms; diff --git a/src/main/java/ru/windcorp/progressia/client/ClientState.java b/src/main/java/ru/windcorp/progressia/client/ClientState.java index 75f0f07..31c366e 100644 --- a/src/main/java/ru/windcorp/progressia/client/ClientState.java +++ b/src/main/java/ru/windcorp/progressia/client/ClientState.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.client; import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel; import ru.windcorp.progressia.client.graphics.GUI; import ru.windcorp.progressia.client.graphics.world.LayerWorld; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.ServerState; import ru.windcorp.progressia.test.LayerAbout; import ru.windcorp.progressia.test.LayerTestUI; @@ -41,7 +41,7 @@ public class ClientState { public static void connectToLocalServer() { - WorldData world = new WorldData(); + DefaultWorldData world = new DefaultWorldData(); LocalServerCommsChannel channel = new LocalServerCommsChannel( ServerState.getInstance() diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index c69fcf3..e96166d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -30,26 +30,26 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderReference; import ru.windcorp.progressia.client.world.tile.TileRenderRegistry; import ru.windcorp.progressia.client.world.tile.TileRenderStack; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.tile.TileDataReference; -import ru.windcorp.progressia.common.world.tile.TileDataStack; public class ChunkRender - implements GenericChunk { + implements ChunkGenericRO { private final WorldRender world; - private final ChunkData data; + private final DefaultChunkData data; private final ChunkRenderModel model; private final Map tileRenderLists = Collections .synchronizedMap(new WeakHashMap<>()); - public ChunkRender(WorldRender world, ChunkData data) { + public ChunkRender(WorldRender world, DefaultChunkData data) { this.world = world; this.data = data; this.model = new ChunkRenderModel(this); @@ -93,7 +93,7 @@ public class ChunkRender return world; } - public ChunkData getData() { + public DefaultChunkData getData() { return data; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 832a7ee..cd8a1d8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -35,7 +35,7 @@ import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerRegistry; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderNone; import ru.windcorp.progressia.client.world.tile.TileRenderStack; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -55,12 +55,12 @@ public class ChunkRenderModel implements Renderable { public void render(ShapeRenderHelper renderer) { if (model == null) return; - float offset = ChunkData.BLOCKS_PER_CHUNK / 2 - 0.5f; + float offset = DefaultChunkData.BLOCKS_PER_CHUNK / 2 - 0.5f; renderer.pushTransform().translate( - chunk.getX() * ChunkData.BLOCKS_PER_CHUNK, - chunk.getY() * ChunkData.BLOCKS_PER_CHUNK, - chunk.getZ() * ChunkData.BLOCKS_PER_CHUNK + chunk.getX() * DefaultChunkData.BLOCKS_PER_CHUNK, + chunk.getY() * DefaultChunkData.BLOCKS_PER_CHUNK, + chunk.getZ() * DefaultChunkData.BLOCKS_PER_CHUNK ).translate(offset, offset, offset) .mul(AxisRotations.getResolutionMatrix4(chunk.getUp())) .translate(-offset, -offset, -offset); diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java index da3d10d..1e854f2 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.client.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AbsFace; @@ -37,12 +37,12 @@ class ChunkUpdateListener implements ChunkDataListener { } @Override - public void onChunkChanged(ChunkData chunk) { + public void onChunkChanged(DefaultChunkData chunk) { world.getChunk(chunk).markForUpdate(); } @Override - public void onChunkLoaded(ChunkData chunk) { + public void onChunkLoaded(DefaultChunkData chunk) { Vec3i cursor = new Vec3i(); for (AbsFace face : AbsFace.getFaces()) { cursor.set(chunk.getX(), chunk.getY(), chunk.getZ()); @@ -52,13 +52,13 @@ class ChunkUpdateListener implements ChunkDataListener { } @Override - public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { + public void onChunkBlockChanged(DefaultChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { onLocationChanged(chunk, blockInChunk); } @Override public void onChunkTilesChanged( - ChunkData chunk, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace face, TileData tile, @@ -67,7 +67,7 @@ class ChunkUpdateListener implements ChunkDataListener { onLocationChanged(chunk, blockInChunk); } - private void onLocationChanged(ChunkData chunk, Vec3i blockInChunk) { + private void onLocationChanged(DefaultChunkData chunk, Vec3i blockInChunk) { Vec3i chunkPos = Vectors.grab3i().set(chunk.getX(), chunk.getY(), chunk.getZ()); checkCoordinate(blockInChunk, chunkPos, VectorUtil.Axis.X); @@ -83,7 +83,7 @@ class ChunkUpdateListener implements ChunkDataListener { if (block == 0) { diff = -1; - } else if (block == ChunkData.BLOCKS_PER_CHUNK - 1) { + } else if (block == DefaultChunkData.BLOCKS_PER_CHUNK - 1) { diff = +1; } else { return; diff --git a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java index 7ff4df6..2ab9e7d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java @@ -38,54 +38,54 @@ import ru.windcorp.progressia.client.world.tile.TileRenderReference; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListeners; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.WorldDataListener; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.ChunkSet; import ru.windcorp.progressia.common.world.generic.ChunkSets; -import ru.windcorp.progressia.common.world.generic.GenericWorld; +import ru.windcorp.progressia.common.world.generic.WorldGenericRO; public class WorldRender - implements GenericWorld { + implements WorldGenericRO { - private final WorldData data; + private final DefaultWorldData data; private final Client client; - private final Map chunks = Collections.synchronizedMap(new HashMap<>()); + private final Map chunks = Collections.synchronizedMap(new HashMap<>()); private final Map entityModels = Collections.synchronizedMap(new WeakHashMap<>()); private final ChunkSet chunksToUpdate = ChunkSets.newSyncHashSet(); - public WorldRender(WorldData data, Client client) { + public WorldRender(DefaultWorldData data, Client client) { this.data = data; this.client = client; data.addListener(ChunkDataListeners.createAdder(new ChunkUpdateListener(this))); data.addListener(new WorldDataListener() { @Override - public void onChunkLoaded(WorldData world, ChunkData chunk) { + public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { addChunk(chunk); } @Override - public void beforeChunkUnloaded(WorldData world, ChunkData chunk) { + public void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) { removeChunk(chunk); } }); } - protected void addChunk(ChunkData chunk) { + protected void addChunk(DefaultChunkData chunk) { chunks.put(chunk, new ChunkRender(WorldRender.this, chunk)); markChunkForUpdate(chunk.getPosition()); } - protected void removeChunk(ChunkData chunk) { + protected void removeChunk(DefaultChunkData chunk) { chunks.remove(chunk); } - public WorldData getData() { + public DefaultWorldData getData() { return data; } @@ -93,7 +93,7 @@ public class WorldRender return client; } - public ChunkRender getChunk(ChunkData chunkData) { + public ChunkRender getChunk(DefaultChunkData chunkData) { return chunks.get(chunkData); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java index 2a3c8e1..6adbfde 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java @@ -19,18 +19,18 @@ package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.generic.BlockGeneric; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.Renderable; -public abstract class BlockRender extends Namespaced implements GenericBlock { +public abstract class BlockRender extends Namespaced implements BlockGeneric { public BlockRender(String id) { super(id); } - public Renderable createRenderable(ChunkData chunk, Vec3i relBlockInChunk) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i relBlockInChunk) { return null; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java index 84a2c4b..e9c10a8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.client.world.block; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.EmptyModel; import ru.windcorp.progressia.client.graphics.model.Renderable; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; public class BlockRenderNone extends BlockRender { @@ -30,7 +30,7 @@ public class BlockRenderNone extends BlockRender { } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk) { return EmptyModel.getInstance(); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java index 6ed7ef7..91d05e1 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java @@ -36,7 +36,7 @@ import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.BlockOptimizedSurface; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -69,7 +69,7 @@ public abstract class BlockRenderTexturedCube @Override public final void getShapeParts( - ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Consumer output, Vec3 offset @@ -78,7 +78,7 @@ public abstract class BlockRenderTexturedCube } private ShapePart createFace( - ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Vec3 offset ) { @@ -93,7 +93,7 @@ public abstract class BlockRenderTexturedCube } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk) { boolean opaque = isBlockOpaque(); ShapePart[] faces = new ShapePart[BLOCK_FACE_COUNT + (opaque ? BLOCK_FACE_COUNT : 0)]; diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java index 26ee23c..296e7b8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java @@ -18,8 +18,8 @@ package ru.windcorp.progressia.client.world.cro; -import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; -import static ru.windcorp.progressia.common.world.generic.GenericTileStack.TILES_PER_FACE; +import static ru.windcorp.progressia.common.world.DefaultChunkData.BLOCKS_PER_CHUNK; +import static ru.windcorp.progressia.common.world.generic.TileGenericStackRO.TILES_PER_FACE; import static ru.windcorp.progressia.common.world.rels.AbsFace.BLOCK_FACE_COUNT; import java.util.ArrayList; @@ -37,7 +37,7 @@ import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -71,7 +71,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { * vertices */ void getShapeParts( - ChunkData chunk, + DefaultChunkData chunk, Vec3i relBlockInChunk, RelFace blockFace, boolean inner, diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java index fcd50f6..1749ffb 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java @@ -23,9 +23,9 @@ import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; -public abstract class EntityRenderable implements Renderable, GenericEntity { +public abstract class EntityRenderable implements Renderable, EntityGeneric { private final EntityData data; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java index 38c4ae9..dcb6c54 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java @@ -22,17 +22,17 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizer; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.generic.TileGeneric; import ru.windcorp.progressia.common.world.rels.RelFace; -public class TileRender extends Namespaced implements GenericTile { +public class TileRender extends Namespaced implements TileGeneric { public TileRender(String id) { super(id); } - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace face) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk, RelFace face) { return null; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java index f8ad55b..894a42d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.client.world.tile; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.EmptyModel; import ru.windcorp.progressia.client.graphics.model.Renderable; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.RelFace; public class TileRenderNone extends TileRender { @@ -30,7 +30,7 @@ public class TileRenderNone extends TileRender { } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace face) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk, RelFace face) { return EmptyModel.getInstance(); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java index 3def556..9ec5194 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java @@ -19,9 +19,9 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; -import ru.windcorp.progressia.common.world.generic.GenericTileReference; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; public interface TileRenderReference - extends GenericTileReference { + extends TileGenericReferenceRO { } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java index ca95cd2..b0c6b65 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java @@ -18,13 +18,15 @@ package ru.windcorp.progressia.client.world.tile; +import java.util.AbstractList; + import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; -import ru.windcorp.progressia.common.world.generic.GenericTileStack; -import ru.windcorp.progressia.common.world.tile.TileDataStack; - +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; public abstract class TileRenderStack - extends GenericTileStack { + extends AbstractList + implements TileGenericStackRO { public abstract TileDataStack getData(); diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java index 91eeb00..604bf69 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java @@ -33,7 +33,7 @@ import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.TileOptimizedSurface; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -60,7 +60,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi @Override public final void getShapeParts( - ChunkData chunk, Vec3i relBlockInChunk, RelFace blockFace, + DefaultChunkData chunk, Vec3i relBlockInChunk, RelFace blockFace, boolean inner, Consumer output, Vec3 offset @@ -69,7 +69,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi } private ShapePart createFace( - ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Vec3 offset ) { @@ -84,7 +84,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace blockFace) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk, RelFace blockFace) { return new Shape( Usage.STATIC, WorldRenderProgram.getDefault(), diff --git a/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java b/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java index 69d2d4a..69b157d 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java @@ -24,7 +24,7 @@ import java.util.Collection; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.LowOverheadCache; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class WorldCollisionHelper { @@ -79,7 +79,7 @@ public class WorldCollisionHelper { * checked against * @param maxTime maximum collision time */ - public void tuneToCollideable(WorldData world, Collideable collideable, float maxTime) { + public void tuneToCollideable(DefaultWorldData world, Collideable collideable, float maxTime) { activeBlockModels.forEach(blockModelCache::release); activeBlockModels.clear(); CollisionPathComputer.forEveryBlockInCollisionPath( diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java index 62a7808..9b97e40 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java @@ -27,7 +27,7 @@ import glm.vec._3.Vec3; import ru.windcorp.progressia.common.collision.*; import ru.windcorp.progressia.common.util.LowOverheadCache; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class Collider { @@ -36,7 +36,7 @@ public class Collider { /** * Dear Princess Celestia, *

- * When {@linkplain #advanceTime(Collection, Collision, WorldData, float) + * When {@linkplain #advanceTime(Collection, Collision, DefaultWorldData, float) * advancing time}, * time step for all entities except currently colliding bodies is * the current @@ -61,7 +61,7 @@ public class Collider { public static void performCollisions( List colls, - WorldData world, + DefaultWorldData world, float tickLength, ColliderWorkspace workspace ) { @@ -96,7 +96,7 @@ public class Collider { private static Collision getFirstCollision( List colls, float tickLength, - WorldData world, + DefaultWorldData world, ColliderWorkspace workspace ) { Collision result = null; @@ -126,7 +126,7 @@ public class Collider { private static void tuneWorldCollisionHelper( Collideable coll, float tickLength, - WorldData world, + DefaultWorldData world, ColliderWorkspace workspace ) { WorldCollisionHelper wch = workspace.worldCollisionHelper; @@ -194,7 +194,7 @@ public class Collider { Collision collision, Collection colls, - WorldData world, + DefaultWorldData world, float tickLength, ColliderWorkspace workspace ) { @@ -361,7 +361,7 @@ public class Collider { private static void advanceTime( Collection colls, Collision exceptions, - WorldData world, + DefaultWorldData world, float step ) { world.advanceTime(step); diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java b/src/main/java/ru/windcorp/progressia/common/state/StateChange.java similarity index 66% rename from src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java rename to src/main/java/ru/windcorp/progressia/common/state/StateChange.java index b9699c2..38638a7 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StateChange.java @@ -16,12 +16,9 @@ * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.tile; - -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.generic.GenericTileReference; - -public interface TileDataReference extends GenericTileReference { +package ru.windcorp.progressia.common.state; +@FunctionalInterface +public interface StateChange { + void change(T object); } 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 728bc80..ab55863 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -1,527 +1,14 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package ru.windcorp.progressia.common.world; -import static ru.windcorp.progressia.common.world.rels.BlockFace.BLOCK_FACE_COUNT; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; - -import glm.vec._3.i.Vec3i; - import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.generic.GenericChunks; -import ru.windcorp.progressia.common.world.generic.GenericWritableChunk; -import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.generic.ChunkGenericWO; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataReference; -import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileStackIsFullException; -public class ChunkData - implements GenericWritableChunk { - - public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; - public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2; - - private final Vec3i position = new Vec3i(); - private final WorldData world; - - private final BlockData[] blocks = new BlockData[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK]; - - private final TileDataStack[] tiles = new TileDataStack[ - BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCK_FACE_COUNT - ]; +public interface ChunkData extends ChunkDataRO, ChunkGenericWO { - private final AbsFace up; - - private Object generationHint = null; - - private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); - - public ChunkData(Vec3i position, WorldData world) { - this.position.set(position.x, position.y, position.z); - this.world = world; - this.up = world.getGravityModel().getDiscreteUp(position); - } - - @Override - public Vec3i getPosition() { - return position; - } - - @Override - public AbsFace getUp() { - return up; - } - - @Override - public BlockData getBlock(Vec3i posInChunk) { - return blocks[getBlockIndex(posInChunk)]; - } - - @Override - public void setBlock(Vec3i posInChunk, BlockData block, boolean notify) { - BlockData previous = blocks[getBlockIndex(posInChunk)]; - blocks[getBlockIndex(posInChunk)] = block; - - if (notify) { - getListeners().forEach(l -> { - l.onChunkBlockChanged(this, posInChunk, previous, block); - l.onChunkChanged(this); - }); - } - } - - @Override - public TileDataStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { - return tiles[getTileIndex(blockInChunk, face)]; - } - - /** - * Internal use only. Modify a list returned by - * {@link #getTiles(Vec3i, BlockFace)} or - * {@link #getTilesOrNull(Vec3i, BlockFace)} - * to change tiles. - */ - protected void setTiles( - Vec3i blockInChunk, - BlockFace face, - TileDataStack tiles - ) { - this.tiles[getTileIndex(blockInChunk, face)] = tiles; - } - - @Override - public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { - return getTilesOrNull(blockInChunk, face) != null; - } - - @Override - public TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { - int index = getTileIndex(blockInChunk, face); - - if (tiles[index] == null) { - createTileStack(blockInChunk, face); - } - - return tiles[index]; - } - - private void createTileStack(Vec3i blockInChunk, BlockFace face) { - Vec3i independentBlockInChunk = conjureIndependentBlockInChunkVec3i(blockInChunk); - TileDataStackImpl stack = new TileDataStackImpl(independentBlockInChunk, face); - setTiles(blockInChunk, face, stack); - } - - private Vec3i conjureIndependentBlockInChunkVec3i(Vec3i blockInChunk) { - for (int i = 0; i < AbsFace.BLOCK_FACE_COUNT; ++i) { - TileDataStack stack = getTilesOrNull(blockInChunk, AbsFace.getFaces().get(i)); - if (stack instanceof TileDataStackImpl) { - return ((TileDataStackImpl) stack).blockInChunk; - } - } - - return new Vec3i(blockInChunk); - } - - private static int getBlockIndex(Vec3i posInChunk) { - checkLocalCoordinates(posInChunk); - - return posInChunk.z * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + - posInChunk.y * BLOCKS_PER_CHUNK + - posInChunk.x; - } - - private int getTileIndex(Vec3i posInChunk, BlockFace face) { - return getBlockIndex(posInChunk) * BLOCK_FACE_COUNT + - face.resolve(getUp()).getId(); - } - - private static void checkLocalCoordinates(Vec3i posInChunk) { - if (!GenericChunks.containsBiC(posInChunk)) { - throw new IllegalCoordinatesException( - "Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") " - + "are not legal chunk coordinates" - ); - } - } - - public WorldData getWorld() { - return world; - } - - public Collection getListeners() { - return listeners; - } - - public void addListener(ChunkDataListener listener) { - this.listeners.add(listener); - } - - public void removeListener(ChunkDataListener listener) { - this.listeners.remove(listener); - } - - protected void onLoaded() { - getListeners().forEach(l -> l.onChunkLoaded(this)); - } - - protected void beforeUnloaded() { - getListeners().forEach(l -> l.beforeChunkUnloaded(this)); - } - - public Object getGenerationHint() { - return generationHint; - } - - public void setGenerationHint(Object generationHint) { - this.generationHint = generationHint; - } - - /** - * Implementation of {@link TileDataStack} used internally by - * {@link ChunkData} to - * actually store the tiles. This is basically an array wrapper with - * reporting - * capabilities. - * - * @author javapony - */ - private class TileDataStackImpl extends TileDataStack { - private class TileDataReferenceImpl implements TileDataReference { - private int index; - - public TileDataReferenceImpl(int index) { - this.index = index; - } - - public void incrementIndex() { - this.index++; - } - - public void decrementIndex() { - this.index--; - } - - public void invalidate() { - this.index = 0; - } - - @Override - public TileData get() { - if (!isValid()) - return null; - return TileDataStackImpl.this.get(this.index); - } - - @Override - public int getIndex() { - return index; - } - - @Override - public TileDataStack getStack() { - return TileDataStackImpl.this; - } - - @Override - public boolean isValid() { - return this.index >= 0; - } - } - - private final TileData[] tiles = new TileData[TILES_PER_FACE]; - private int size = 0; - - private final TileDataReferenceImpl[] references = new TileDataReferenceImpl[tiles.length]; - private final int[] indicesByTag = new int[tiles.length]; - private final int[] tagsByIndex = new int[tiles.length]; - - { - Arrays.fill(indicesByTag, -1); - Arrays.fill(tagsByIndex, -1); - } - - /* - * Potentially shared - */ - private final Vec3i blockInChunk; - private final RelFace face; - - public TileDataStackImpl(Vec3i blockInChunk, BlockFace face) { - this.blockInChunk = blockInChunk; - this.face = face.relativize(getUp()); - } - - @Override - public Vec3i getBlockInChunk(Vec3i output) { - if (output == null) - output = new Vec3i(); - output.set(blockInChunk.x, blockInChunk.y, blockInChunk.z); - return output; - } - - @Override - public RelFace getFace() { - return face; - } - - @Override - public ChunkData getChunk() { - return ChunkData.this; - } - - @Override - public int size() { - return size; - } - - @Override - public TileData get(int index) { - checkIndex(index, false); - - return tiles[index]; - } - - @Override - public TileData set(int index, TileData tile) { - Objects.requireNonNull(tile, "tile"); - TileData previous = get(index); // checks index - - tiles[index] = tile; - - if (references[index] != null) { - references[index].invalidate(); - references[index] = null; - } - - assert checkConsistency(); - - report(previous, tile); - return previous; - } - - @Override - public void add(int index, TileData tile) { - Objects.requireNonNull(tile, "tile"); - checkIndex(index, true); - - if (index != size()) { - System.arraycopy(tiles, index + 1, tiles, index + 2, size - index); - - for (int i = index; i < size; ++i) { - if (references[i] != null) { - references[i].incrementIndex(); - } - - indicesByTag[tagsByIndex[i]]++; - } - - System.arraycopy(references, index + 1, references, index + 2, size - index); - System.arraycopy(tagsByIndex, index + 1, tagsByIndex, index + 2, size - index); - } - - size++; - tiles[index] = tile; - references[index] = null; - - for (int tag = 0; tag < indicesByTag.length; ++tag) { - if (indicesByTag[tag] == -1) { - indicesByTag[tag] = index; - tagsByIndex[index] = tag; - break; - } - } - - modCount++; - assert checkConsistency(); - - report(null, tile); - } - - @Override - public void load(TileData tile, int tag) { - addFarthest(tile); - - int assignedIndex = size() - 1; - - // Skip if we already have the correct tag - int assignedTag = getTagByIndex(assignedIndex); - if (assignedTag == tag) { - return; - } - assert assignedTag != -1 : "Adding farthest tile resulted in -1 tag"; - - // Make sure we aren't trying to assign a tag already in use - int tileWithRequestedTag = getIndexByTag(tag); - if (tileWithRequestedTag != -1) { - throw new IllegalArgumentException( - "Tag " + tag + " already used by tile at index " + tileWithRequestedTag - ); - } - assert tileWithRequestedTag != assignedIndex : "tag == assignedTag yet tileWithRequestedTag != assignedIndex"; - - // Do the tag editing - indicesByTag[assignedTag] = -1; // Release assigned tag - tagsByIndex[assignedIndex] = tag; // Reroute assigned index to requested tag - indicesByTag[tag] = assignedIndex; // Claim requested tag - assert checkConsistency(); - } - - @Override - public TileData remove(int index) { - TileData previous = get(index); // checks index - - if (references[index] != null) { - references[index].invalidate(); - } - - indicesByTag[tagsByIndex[index]] = -1; - - if (index != size() - 1) { - System.arraycopy(tiles, index + 1, tiles, index, size - index - 1); - - for (int i = index + 1; i < size; ++i) { - if (references[i] != null) { - references[i].decrementIndex(); - } - - indicesByTag[tagsByIndex[i]]--; - } - - System.arraycopy(references, index + 1, references, index, size - index - 1); - System.arraycopy(tagsByIndex, index + 1, tagsByIndex, index, size - index - 1); - } - - size--; - tiles[size] = null; - references[size] = null; - tagsByIndex[size] = -1; - - modCount++; - assert checkConsistency(); - - report(previous, null); - return previous; - } - - @Override - public TileDataReference getReference(int index) { - checkIndex(index, false); - - if (references[index] == null) { - references[index] = new TileDataReferenceImpl(index); - } - - return references[index]; - } - - @Override - public int getIndexByTag(int tag) { - return indicesByTag[tag]; - } - - @Override - public int getTagByIndex(int index) { - checkIndex(index, false); - return tagsByIndex[index]; - } - - @Override - public void clear() { - while (!isEmpty()) { - removeFarthest(); - } - } - - private void checkIndex(int index, boolean isSizeAllowed) { - if (isSizeAllowed ? (index > size()) : (index >= size())) - throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: size is " + size); - - if (index < 0) - throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: index cannot be negative"); - - if (index >= TILES_PER_FACE) - throw new TileStackIsFullException( - "Index " + index + " is out of bounds: maximum tile stack size is " + TILES_PER_FACE - ); - } - - private void report(TileData previous, TileData current) { - ChunkData.this.getListeners().forEach(l -> { - if (previous != null) { - l.onChunkTilesChanged(ChunkData.this, blockInChunk, face, previous, false); - } - - if (current != null) { - l.onChunkTilesChanged(ChunkData.this, blockInChunk, face, current, true); - } - - l.onChunkChanged(ChunkData.this); - }); - } - - private boolean checkConsistency() { - int index; - - for (index = 0; index < size(); ++index) { - if (get(index) == null) - throw new AssertionError("get(index) is null"); - - if (references[index] != null) { - TileDataReference ref = getReference(index); - if (ref == null) - throw new AssertionError("references[index] is not null but getReference(index) is"); - if (!ref.isValid()) - throw new AssertionError("Reference is not valid"); - if (ref.get() != get(index)) - throw new AssertionError("Reference points to " + (ref.get() == null ? "null" : "wrong tile")); - if (ref.getIndex() != index) - throw new AssertionError("Reference has invalid index"); - if (ref.getStack() != this) - throw new AssertionError("Reference has invalid TDS"); - } - - if (index != indicesByTag[tagsByIndex[index]]) - throw new AssertionError("Tag mapping is inconsistent"); - if (index != getIndexByTag(getTagByIndex(index))) - throw new AssertionError("Tag methods are inconsistent with tag mapping"); - } - - for (; index < tiles.length; ++index) { - if (tiles[index] != null) - throw new AssertionError("Leftover tile detected"); - if (references[index] != null) - throw new AssertionError("Leftover reference detected"); - if (tagsByIndex[index] != -1) - throw new AssertionError("Leftover tags detected"); - } - - return true; - } - - } +// @Override +// default TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { +// return null; +// } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java index 0dc7088..22b4fb3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java @@ -36,7 +36,7 @@ public interface ChunkDataListener { * @param previous the previous occupant of {@code blockInChunk} * @param current the current (new) occupant of {@code blockInChunk} */ - default void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { + default void onChunkBlockChanged(DefaultChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { } /** @@ -53,7 +53,7 @@ public interface ChunkDataListener { * {@code false} iff the tile has been removed */ default void onChunkTilesChanged( - ChunkData chunk, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace face, TileData tile, @@ -70,7 +70,7 @@ public interface ChunkDataListener { * * @param chunk the chunk that has changed */ - default void onChunkChanged(ChunkData chunk) { + default void onChunkChanged(DefaultChunkData chunk) { } /** @@ -78,7 +78,7 @@ public interface ChunkDataListener { * * @param chunk the chunk that has loaded */ - default void onChunkLoaded(ChunkData chunk) { + default void onChunkLoaded(DefaultChunkData chunk) { } /** @@ -86,7 +86,7 @@ public interface ChunkDataListener { * * @param chunk the chunk that is going to be loaded */ - default void beforeChunkUnloaded(ChunkData chunk) { + default void beforeChunkUnloaded(DefaultChunkData chunk) { } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java index b39437c..a9a4168 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java @@ -28,7 +28,7 @@ public class ChunkDataListeners { public static WorldDataListener createAdder(Supplier listenerSupplier) { return new WorldDataListener() { @Override - public void getChunkListeners(WorldData world, Vec3i chunk, Consumer chunkListenerSink) { + public void getChunkListeners(DefaultWorldData world, Vec3i chunk, Consumer chunkListenerSink) { chunkListenerSink.accept(listenerSupplier.get()); } }; diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataRO.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataRO.java new file mode 100644 index 0000000..08ce159 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataRO.java @@ -0,0 +1,12 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface ChunkDataRO + extends ChunkGenericRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java b/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java index 55f2076..b43231b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java +++ b/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world; -import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; +import static ru.windcorp.progressia.common.world.DefaultChunkData.BLOCKS_PER_CHUNK; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java new file mode 100644 index 0000000..5c1cd08 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java @@ -0,0 +1,525 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world; + +import static ru.windcorp.progressia.common.world.rels.BlockFace.BLOCK_FACE_COUNT; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; + +import glm.vec._3.i.Vec3i; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.GenericChunks; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.common.world.tile.TileStackIsFullException; + +public class DefaultChunkData implements ChunkData { + + public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; + public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2; + + private final Vec3i position = new Vec3i(); + private final DefaultWorldData world; + + private final BlockData[] blocks = new BlockData[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK]; + + private final TileDataStack[] tiles = new TileDataStack[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + * BLOCK_FACE_COUNT]; + + private final AbsFace up; + + private Object generationHint = null; + + private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); + + public DefaultChunkData(Vec3i position, DefaultWorldData world) { + this.position.set(position.x, position.y, position.z); + this.world = world; + this.up = world.getGravityModel().getDiscreteUp(position); + } + + @Override + public Vec3i getPosition() { + return position; + } + + @Override + public AbsFace getUp() { + return up; + } + + @Override + public BlockData getBlock(Vec3i posInChunk) { + return blocks[getBlockIndex(posInChunk)]; + } + + @Override + public void setBlock(Vec3i posInChunk, BlockData block, boolean notify) { + BlockData previous = blocks[getBlockIndex(posInChunk)]; + blocks[getBlockIndex(posInChunk)] = block; + + if (notify) { + getListeners().forEach(l -> { + l.onChunkBlockChanged(this, posInChunk, previous, block); + l.onChunkChanged(this); + }); + } + } + + @Override + public TileDataStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { + return tiles[getTileIndex(blockInChunk, face)]; + } + + /** + * Internal use only. Modify a list returned by + * {@link #getTiles(Vec3i, BlockFace)} or + * {@link #getTilesOrNull(Vec3i, BlockFace)} + * to change tiles. + */ + protected void setTiles( + Vec3i blockInChunk, + BlockFace face, + TileDataStack tiles + ) { + this.tiles[getTileIndex(blockInChunk, face)] = tiles; + } + + @Override + public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { + return getTilesOrNull(blockInChunk, face) != null; + } + + @Override + public TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { + int index = getTileIndex(blockInChunk, face); + + if (tiles[index] == null) { + createTileStack(blockInChunk, face); + } + + return tiles[index]; + } + + private void createTileStack(Vec3i blockInChunk, BlockFace face) { + Vec3i independentBlockInChunk = conjureIndependentBlockInChunkVec3i(blockInChunk); + TileDataStackImpl stack = new TileDataStackImpl(independentBlockInChunk, face); + setTiles(blockInChunk, face, stack); + } + + private Vec3i conjureIndependentBlockInChunkVec3i(Vec3i blockInChunk) { + for (int i = 0; i < AbsFace.BLOCK_FACE_COUNT; ++i) { + TileDataStack stack = getTilesOrNull(blockInChunk, AbsFace.getFaces().get(i)); + if (stack instanceof TileDataStackImpl) { + return ((TileDataStackImpl) stack).blockInChunk; + } + } + + return new Vec3i(blockInChunk); + } + + private static int getBlockIndex(Vec3i posInChunk) { + checkLocalCoordinates(posInChunk); + + return posInChunk.z * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + + posInChunk.y * BLOCKS_PER_CHUNK + + posInChunk.x; + } + + private int getTileIndex(Vec3i posInChunk, BlockFace face) { + return getBlockIndex(posInChunk) * BLOCK_FACE_COUNT + + face.resolve(getUp()).getId(); + } + + private static void checkLocalCoordinates(Vec3i posInChunk) { + if (!GenericChunks.containsBiC(posInChunk)) { + throw new IllegalCoordinatesException( + "Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") " + + "are not legal chunk coordinates" + ); + } + } + + public DefaultWorldData getWorld() { + return world; + } + + public Collection getListeners() { + return listeners; + } + + public void addListener(ChunkDataListener listener) { + this.listeners.add(listener); + } + + public void removeListener(ChunkDataListener listener) { + this.listeners.remove(listener); + } + + protected void onLoaded() { + getListeners().forEach(l -> l.onChunkLoaded(this)); + } + + protected void beforeUnloaded() { + getListeners().forEach(l -> l.beforeChunkUnloaded(this)); + } + + public Object getGenerationHint() { + return generationHint; + } + + public void setGenerationHint(Object generationHint) { + this.generationHint = generationHint; + } + + /** + * Implementation of {@link TileDataStack} used internally by + * {@link DefaultChunkData} to + * actually store the tiles. This is basically an array wrapper with + * reporting + * capabilities. + * + * @author javapony + */ + private class TileDataStackImpl extends AbstractList implements TileDataStack { + private class TileDataReferenceImpl implements TileDataReference { + private int index; + + public TileDataReferenceImpl(int index) { + this.index = index; + } + + public void incrementIndex() { + this.index++; + } + + public void decrementIndex() { + this.index--; + } + + public void invalidate() { + this.index = 0; + } + + @Override + public TileData get() { + if (!isValid()) + return null; + return TileDataStackImpl.this.get(this.index); + } + + @Override + public int getIndex() { + return index; + } + + @Override + public TileDataStack getStack() { + return TileDataStackImpl.this; + } + + @Override + public boolean isValid() { + return this.index >= 0; + } + } + + private final TileData[] tiles = new TileData[TILES_PER_FACE]; + private int size = 0; + + private final TileDataReferenceImpl[] references = new TileDataReferenceImpl[tiles.length]; + private final int[] indicesByTag = new int[tiles.length]; + private final int[] tagsByIndex = new int[tiles.length]; + + { + Arrays.fill(indicesByTag, -1); + Arrays.fill(tagsByIndex, -1); + } + + /* + * Potentially shared + */ + private final Vec3i blockInChunk; + private final RelFace face; + + public TileDataStackImpl(Vec3i blockInChunk, BlockFace face) { + this.blockInChunk = blockInChunk; + this.face = face.relativize(getUp()); + } + + @Override + public Vec3i getBlockInChunk(Vec3i output) { + if (output == null) + output = new Vec3i(); + output.set(blockInChunk.x, blockInChunk.y, blockInChunk.z); + return output; + } + + @Override + public RelFace getFace() { + return face; + } + + @Override + public DefaultChunkData getChunk() { + return DefaultChunkData.this; + } + + @Override + public int size() { + return size; + } + + @Override + public TileData get(int index) { + checkIndex(index, false); + + return tiles[index]; + } + + @Override + public TileData set(int index, TileData tile) { + Objects.requireNonNull(tile, "tile"); + TileData previous = get(index); // checks index + + tiles[index] = tile; + + if (references[index] != null) { + references[index].invalidate(); + references[index] = null; + } + + assert checkConsistency(); + + report(previous, tile); + return previous; + } + + @Override + public void add(int index, TileData tile) { + Objects.requireNonNull(tile, "tile"); + checkIndex(index, true); + + if (index != size()) { + System.arraycopy(tiles, index + 1, tiles, index + 2, size - index); + + for (int i = index; i < size; ++i) { + if (references[i] != null) { + references[i].incrementIndex(); + } + + indicesByTag[tagsByIndex[i]]++; + } + + System.arraycopy(references, index + 1, references, index + 2, size - index); + System.arraycopy(tagsByIndex, index + 1, tagsByIndex, index + 2, size - index); + } + + size++; + tiles[index] = tile; + references[index] = null; + + for (int tag = 0; tag < indicesByTag.length; ++tag) { + if (indicesByTag[tag] == -1) { + indicesByTag[tag] = index; + tagsByIndex[index] = tag; + break; + } + } + + modCount++; + assert checkConsistency(); + + report(null, tile); + } + + @Override + public void load(TileData tile, int tag) { + addFarthest(tile); + + int assignedIndex = size() - 1; + + // Skip if we already have the correct tag + int assignedTag = getTagByIndex(assignedIndex); + if (assignedTag == tag) { + return; + } + assert assignedTag != -1 : "Adding farthest tile resulted in -1 tag"; + + // Make sure we aren't trying to assign a tag already in use + int tileWithRequestedTag = getIndexByTag(tag); + if (tileWithRequestedTag != -1) { + throw new IllegalArgumentException( + "Tag " + tag + " already used by tile at index " + tileWithRequestedTag + ); + } + assert tileWithRequestedTag != assignedIndex + : "tag == assignedTag yet tileWithRequestedTag != assignedIndex"; + + // Do the tag editing + indicesByTag[assignedTag] = -1; // Release assigned tag + tagsByIndex[assignedIndex] = tag; // Reroute assigned index to + // requested tag + indicesByTag[tag] = assignedIndex; // Claim requested tag + assert checkConsistency(); + } + + @Override + public TileData remove(int index) { + TileData previous = get(index); // checks index + + if (references[index] != null) { + references[index].invalidate(); + } + + indicesByTag[tagsByIndex[index]] = -1; + + if (index != size() - 1) { + System.arraycopy(tiles, index + 1, tiles, index, size - index - 1); + + for (int i = index + 1; i < size; ++i) { + if (references[i] != null) { + references[i].decrementIndex(); + } + + indicesByTag[tagsByIndex[i]]--; + } + + System.arraycopy(references, index + 1, references, index, size - index - 1); + System.arraycopy(tagsByIndex, index + 1, tagsByIndex, index, size - index - 1); + } + + size--; + tiles[size] = null; + references[size] = null; + tagsByIndex[size] = -1; + + modCount++; + assert checkConsistency(); + + report(previous, null); + return previous; + } + + @Override + public TileDataReference getReference(int index) { + checkIndex(index, false); + + if (references[index] == null) { + references[index] = new TileDataReferenceImpl(index); + } + + return references[index]; + } + + @Override + public int getIndexByTag(int tag) { + return indicesByTag[tag]; + } + + @Override + public int getTagByIndex(int index) { + checkIndex(index, false); + return tagsByIndex[index]; + } + + @Override + public void clear() { + while (!isEmpty()) { + removeFarthest(); + } + } + + private void checkIndex(int index, boolean isSizeAllowed) { + if (isSizeAllowed ? (index > size()) : (index >= size())) + throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: size is " + size); + + if (index < 0) + throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: index cannot be negative"); + + if (index >= TILES_PER_FACE) + throw new TileStackIsFullException( + "Index " + index + " is out of bounds: maximum tile stack size is " + TILES_PER_FACE + ); + } + + private void report(TileData previous, TileData current) { + DefaultChunkData.this.getListeners().forEach(l -> { + if (previous != null) { + l.onChunkTilesChanged(DefaultChunkData.this, blockInChunk, face, previous, false); + } + + if (current != null) { + l.onChunkTilesChanged(DefaultChunkData.this, blockInChunk, face, current, true); + } + + l.onChunkChanged(DefaultChunkData.this); + }); + } + + private boolean checkConsistency() { + int index; + + for (index = 0; index < size(); ++index) { + if (get(index) == null) + throw new AssertionError("get(index) is null"); + + if (references[index] != null) { + TileDataReference ref = getReference(index); + if (ref == null) + throw new AssertionError("references[index] is not null but getReference(index) is"); + if (!ref.isValid()) + throw new AssertionError("Reference is not valid"); + if (ref.get() != get(index)) + throw new AssertionError("Reference points to " + (ref.get() == null ? "null" : "wrong tile")); + if (ref.getIndex() != index) + throw new AssertionError("Reference has invalid index"); + if (ref.getStack() != this) + throw new AssertionError("Reference has invalid TDS"); + } + + if (index != indicesByTag[tagsByIndex[index]]) + throw new AssertionError("Tag mapping is inconsistent"); + if (index != getIndexByTag(getTagByIndex(index))) + throw new AssertionError("Tag methods are inconsistent with tag mapping"); + } + + for (; index < tiles.length; ++index) { + if (tiles[index] != null) + throw new AssertionError("Leftover tile detected"); + if (references[index] != null) + throw new AssertionError("Leftover reference detected"); + if (tagsByIndex[index] != -1) + throw new AssertionError("Leftover tags detected"); + } + + return true; + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/DefaultWorldData.java b/src/main/java/ru/windcorp/progressia/common/world/DefaultWorldData.java new file mode 100644 index 0000000..1de79a6 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/DefaultWorldData.java @@ -0,0 +1,262 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; +import java.util.function.Consumer; + +import glm.vec._3.i.Vec3i; +import gnu.trove.TCollections; +import gnu.trove.map.TLongObjectMap; +import gnu.trove.map.hash.TLongObjectHashMap; +import gnu.trove.set.TLongSet; +import ru.windcorp.progressia.common.collision.CollisionModel; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.ChunkMap; +import ru.windcorp.progressia.common.world.generic.ChunkSet; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.generic.LongBasedChunkMap; + +public class DefaultWorldData implements WorldData { + + private final ChunkMap chunksByPos = new LongBasedChunkMap<>( + TCollections.synchronizedMap(new TLongObjectHashMap<>()) + ); + + private final Collection chunks = Collections.unmodifiableCollection(chunksByPos.values()); + + private final TLongObjectMap entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>()); + + private final Collection entities = Collections.unmodifiableCollection(entitiesById.valueCollection()); + + private GravityModel gravityModel = null; + + private float time = 0; + + private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); + + public DefaultWorldData() { + + } + + @Override + public DefaultChunkData getChunk(Vec3i pos) { + return chunksByPos.get(pos); + } + + @Override + public DefaultChunkData getChunkByBlock(Vec3i blockInWorld) { + return (DefaultChunkData) WorldData.super.getChunkByBlock(blockInWorld); + } + + @Override + public Collection getChunks() { + return chunks; + } + + public ChunkSet getLoadedChunks() { + return chunksByPos.keys(); + } + + @Override + public Collection getEntities() { + return entities; + } + + @Override + public void forEachEntity(Consumer action) { + synchronized (entitiesById) { // TODO HORRIBLY MUTILATE THE CORPSE OF + // TROVE4J so that + // gnu.trove.impl.sync.SynchronizedCollection.forEach + // is synchronized + getEntities().forEach(action); + } + } + + public TLongSet getLoadedEntities() { + return entitiesById.keySet(); + } + + private void addChunkListeners(DefaultChunkData chunk) { + getListeners().forEach(l -> l.getChunkListeners(this, chunk.getPosition(), chunk::addListener)); + } + + public synchronized void addChunk(DefaultChunkData chunk) { + addChunkListeners(chunk); + + DefaultChunkData previous = chunksByPos.get(chunk); + if (previous != null) { + throw new IllegalArgumentException( + String.format( + "Chunk at (%d; %d; %d) already exists", + chunk.getPosition().x, + chunk.getPosition().y, + chunk.getPosition().z + ) + ); + } + + chunksByPos.put(chunk, chunk); + + chunk.onLoaded(); + getListeners().forEach(l -> l.onChunkLoaded(this, chunk)); + } + + public synchronized void removeChunk(DefaultChunkData chunk) { + getListeners().forEach(l -> l.beforeChunkUnloaded(this, chunk)); + chunk.beforeUnloaded(); + + chunksByPos.remove(chunk); + } + + @Override + public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { + DefaultChunkData chunk = getChunkByBlock(blockInWorld); + if (chunk == null) + throw new IllegalCoordinatesException( + "Coordinates " + + "(" + blockInWorld.x + "; " + blockInWorld.y + "; " + blockInWorld.z + ") " + + "do not belong to a loaded chunk" + ); + + chunk.setBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null), block, notify); + } + + @Override + public TileDataStack getTiles(Vec3i blockInWorld, BlockFace face) { + return WorldData.super.getTiles(blockInWorld, face); + } + + @Override + public EntityData getEntity(long entityId) { + return entitiesById.get(entityId); + } + + @Override + public void addEntity(EntityData entity) { + Objects.requireNonNull(entity, "entity"); + + EntityData previous = entitiesById.putIfAbsent(entity.getEntityId(), entity); + + if (previous != null) { + String message = "Cannot add entity " + entity + ": "; + + if (previous == entity) { + message += "already present"; + } else { + message += "entity with the same EntityID already present (" + previous + ")"; + } + + throw new IllegalStateException(message); + } + + getListeners().forEach(l -> l.onEntityAdded(this, entity)); + } + + @Override + public void removeEntity(long entityId) { + synchronized (entitiesById) { + EntityData entity = entitiesById.get(entityId); + + if (entity == null) { + throw new IllegalArgumentException( + "Entity with EntityID " + EntityData.formatEntityId(entityId) + " not present" + ); + } else { + removeEntity(entity); + } + } + } + + @Override + public void removeEntity(EntityData entity) { + Objects.requireNonNull(entity, "entity"); + + getListeners().forEach(l -> l.beforeEntityRemoved(this, entity)); + entitiesById.remove(entity.getEntityId()); + } + + @Override + public void changeEntity(SE entity, StateChange change) { + change.change(entity); + } + + @Override + public float getTime() { + return time; + } + + @Override + public void advanceTime(float change) { + this.time += change; + } + + public CollisionModel getCollisionModelOfBlock(Vec3i blockInWorld) { + DefaultChunkData chunk = getChunkByBlock(blockInWorld); + if (chunk == null) + return null; + + BlockData block = chunk.getBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null)); + if (block == null) + return null; + return block.getCollisionModel(); + } + + /** + * @return the gravity model + */ + @Override + public GravityModel getGravityModel() { + return gravityModel; + } + + /** + * @param gravityModel the gravity model to set + */ + public void setGravityModel(GravityModel gravityModel) { + if (!chunks.isEmpty()) { + throw new IllegalStateException( + "Attempted to change gravity model to " + gravityModel + " while " + chunks.size() + + " chunks were loaded" + ); + } + + this.gravityModel = gravityModel; + } + + public Collection getListeners() { + return listeners; + } + + public void addListener(WorldDataListener e) { + listeners.add(e); + } + + public void removeListener(WorldDataListener o) { + listeners.remove(o); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java index 8433b9b..27731ab 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java @@ -26,6 +26,6 @@ public abstract class PacketAffectWorld extends Packet { super(id); } - public abstract void apply(WorldData world); + public abstract void apply(DefaultWorldData world); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java index c65b045..4849876 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java @@ -53,9 +53,9 @@ public class PacketRevokeChunk extends PacketAffectChunk { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { synchronized (world) { - ChunkData chunk = world.getChunk(position); + DefaultChunkData chunk = world.getChunk(position); if (chunk != null) { world.removeChunk(chunk); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java index ca079ff..71f2de6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java @@ -41,7 +41,7 @@ public class PacketSendChunk extends PacketAffectChunk { super(id); } - public void set(ChunkData chunk) { + public void set(DefaultChunkData chunk) { this.position.set(chunk.getX(), chunk.getY(), chunk.getZ()); try { @@ -67,7 +67,7 @@ public class PacketSendChunk extends PacketAffectChunk { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { try { world.addChunk(ChunkIO.load(world, position, data.getReader(), IOContext.COMMS)); } catch (DecodingException | IOException e) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java index 2fd30a6..454a1fa 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java @@ -61,7 +61,7 @@ public class PacketSetGravityModel extends PacketAffectWorld { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { GravityModel model = GravityModelRegistry.getInstance().create(gravityModelId); world.setGravityModel(model); try { diff --git a/src/main/java/ru/windcorp/progressia/common/world/TileDataReference.java b/src/main/java/ru/windcorp/progressia/common/world/TileDataReference.java new file mode 100644 index 0000000..ccc118b --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/TileDataReference.java @@ -0,0 +1,10 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceWO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataReference extends TileDataReferenceRO, + TileGenericReferenceWO { + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/TileDataReferenceRO.java b/src/main/java/ru/windcorp/progressia/common/world/TileDataReferenceRO.java new file mode 100644 index 0000000..59257ec --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/TileDataReferenceRO.java @@ -0,0 +1,12 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataReferenceRO + extends TileGenericReferenceRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/TileDataStack.java b/src/main/java/ru/windcorp/progressia/common/world/TileDataStack.java new file mode 100644 index 0000000..0c17ae4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/TileDataStack.java @@ -0,0 +1,25 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.TileGenericStackWO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataStack + extends TileDataStackRO, TileGenericStackWO { + + @Override + default boolean isFull() { + return TileDataStackRO.super.isFull(); + } + + /* + * Method specialization + */ + + @Override + TileDataReference getReference(int index); + + @Override + ChunkData getChunk(); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/TileDataStackRO.java b/src/main/java/ru/windcorp/progressia/common/world/TileDataStackRO.java new file mode 100644 index 0000000..ca74bc4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/TileDataStackRO.java @@ -0,0 +1,12 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataStackRO + extends TileGenericStackRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index 13138c5..65f13be 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -1,245 +1,52 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package ru.windcorp.progressia.common.world; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.Objects; -import java.util.function.Consumer; import glm.vec._3.i.Vec3i; -import gnu.trove.TCollections; -import gnu.trove.map.TLongObjectMap; -import gnu.trove.map.hash.TLongObjectHashMap; -import gnu.trove.set.TLongSet; -import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.ChunkMap; -import ru.windcorp.progressia.common.world.generic.ChunkSet; -import ru.windcorp.progressia.common.world.generic.GenericWritableWorld; -import ru.windcorp.progressia.common.world.generic.LongBasedChunkMap; +import ru.windcorp.progressia.common.world.generic.WorldGenericWO; +import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileDataReference; -public class WorldData - implements GenericWritableWorld { - - private final ChunkMap chunksByPos = new LongBasedChunkMap<>( - TCollections.synchronizedMap(new TLongObjectHashMap<>()) - ); - - private final Collection chunks = Collections.unmodifiableCollection(chunksByPos.values()); - - private final TLongObjectMap entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>()); - - private final Collection entities = Collections.unmodifiableCollection(entitiesById.valueCollection()); - - private GravityModel gravityModel = null; - - private float time = 0; - - private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); - - public WorldData() { - - } +public interface WorldData + extends WorldDataRO, WorldGenericWO { @Override - public ChunkData getChunk(Vec3i pos) { - return chunksByPos.get(pos); - } - - @Override - public Collection getChunks() { - return chunks; - } - - public ChunkSet getLoadedChunks() { - return chunksByPos.keys(); - } - - @Override - public Collection getEntities() { - return entities; - } - - @Override - public void forEachEntity(Consumer action) { - synchronized (entitiesById) { // TODO HORRIBLY MUTILATE THE CORPSE OF - // TROVE4J so that - // gnu.trove.impl.sync.SynchronizedCollection.forEach - // is synchronized - getEntities().forEach(action); - } - } - - public TLongSet getLoadedEntities() { - return entitiesById.keySet(); - } - - private void addChunkListeners(ChunkData chunk) { - getListeners().forEach(l -> l.getChunkListeners(this, chunk.getPosition(), chunk::addListener)); - } - - public synchronized void addChunk(ChunkData chunk) { - addChunkListeners(chunk); - - ChunkData previous = chunksByPos.get(chunk); - if (previous != null) { - throw new IllegalArgumentException( - String.format( - "Chunk at (%d; %d; %d) already exists", - chunk.getPosition().x, - chunk.getPosition().y, - chunk.getPosition().z - ) - ); - } - - chunksByPos.put(chunk, chunk); - - chunk.onLoaded(); - getListeners().forEach(l -> l.onChunkLoaded(this, chunk)); - } - - public synchronized void removeChunk(ChunkData chunk) { - getListeners().forEach(l -> l.beforeChunkUnloaded(this, chunk)); - chunk.beforeUnloaded(); - - chunksByPos.remove(chunk); - } - - @Override - public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { - ChunkData chunk = getChunkByBlock(blockInWorld); - if (chunk == null) - throw new IllegalCoordinatesException( - "Coordinates " - + "(" + blockInWorld.x + "; " + blockInWorld.y + "; " + blockInWorld.z + ") " - + "do not belong to a loaded chunk" - ); - - chunk.setBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null), block, notify); - } - - @Override - public EntityData getEntity(long entityId) { - return entitiesById.get(entityId); - } - - @Override - public void addEntity(EntityData entity) { - Objects.requireNonNull(entity, "entity"); - - EntityData previous = entitiesById.putIfAbsent(entity.getEntityId(), entity); - - if (previous != null) { - String message = "Cannot add entity " + entity + ": "; - - if (previous == entity) { - message += "already present"; - } else { - message += "entity with the same EntityID already present (" + previous + ")"; - } - - throw new IllegalStateException(message); - } - - getListeners().forEach(l -> l.onEntityAdded(this, entity)); - } - - @Override - public void removeEntity(long entityId) { - synchronized (entitiesById) { - EntityData entity = entitiesById.get(entityId); - - if (entity == null) { - throw new IllegalArgumentException( - "Entity with EntityID " + EntityData.formatEntityId(entityId) + " not present" - ); - } else { - removeEntity(entity); - } - } - } - - @Override - public void removeEntity(EntityData entity) { - Objects.requireNonNull(entity, "entity"); - - getListeners().forEach(l -> l.beforeEntityRemoved(this, entity)); - entitiesById.remove(entity.getEntityId()); - } - - public float getTime() { - return time; - } - - public void advanceTime(float change) { - this.time += change; - } - - public CollisionModel getCollisionModelOfBlock(Vec3i blockInWorld) { - ChunkData chunk = getChunkByBlock(blockInWorld); - if (chunk == null) - return null; - - BlockData block = chunk.getBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null)); - if (block == null) - return null; - return block.getCollisionModel(); + default TileDataStack getTiles(Vec3i blockInWorld, BlockFace face) { + return (TileDataStack) WorldDataRO.super.getTiles(blockInWorld, face); } /** - * @return the gravity model + * Increases in-game time of this world by {@code change}. Total time is + * decreased when {@code change} is negative. + * + * @param change the amount of time to add to current world time. May be + * negative. + * @see #getTime() */ - public GravityModel getGravityModel() { - return gravityModel; - } - - /** - * @param gravityModel the gravity model to set + void advanceTime(float change); + + /* + * Method specialization */ - public void setGravityModel(GravityModel gravityModel) { - if (!chunks.isEmpty()) { - throw new IllegalStateException( - "Attempted to change gravity model to " + gravityModel + " while " + chunks.size() - + " chunks were loaded" - ); - } - - this.gravityModel = gravityModel; + + @Override + ChunkData getChunk(Vec3i pos); + + @Override + Collection getChunks(); + + // TODO: rename WGRO.forEachChunk -> forEachChunkRO and define WGWO.forEachChunk + + @Override + default ChunkData getChunkByBlock(Vec3i blockInWorld) { + return (ChunkData) WorldDataRO.super.getChunkByBlock(blockInWorld); } - - public Collection getListeners() { - return listeners; - } - - public void addListener(WorldDataListener e) { - listeners.add(e); - } - - public void removeListener(WorldDataListener o) { - listeners.remove(o); + + @Override + default TileDataStack getTilesOrNull(Vec3i blockInWorld, BlockFace face) { + return (TileDataStack) WorldDataRO.super.getTilesOrNull(blockInWorld, face); } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java index 9211efd..0949566 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java @@ -26,11 +26,11 @@ import ru.windcorp.progressia.common.world.entity.EntityData; public interface WorldDataListener { /** - * Invoked when a new {@link ChunkData} instance is created. This method + * Invoked when a new {@link DefaultChunkData} instance is created. This method * should be used to add * {@link ChunkDataListener}s to a new chunk. When listeners are added with * this method, - * their {@link ChunkDataListener#onChunkLoaded(ChunkData) onChunkLoaded} + * their {@link ChunkDataListener#onChunkLoaded(DefaultChunkData) onChunkLoaded} * methods will be invoked. * * @param world the world instance @@ -41,7 +41,7 @@ public interface WorldDataListener { * {@link Consumer#accept(Object) accept} method * will be added to the chunk. */ - default void getChunkListeners(WorldData world, Vec3i chunk, Consumer chunkListenerSink) { + default void getChunkListeners(DefaultWorldData world, Vec3i chunk, Consumer chunkListenerSink) { } /** @@ -50,7 +50,7 @@ public interface WorldDataListener { * @param world the world instance * @param chunk the chunk that has loaded */ - default void onChunkLoaded(WorldData world, ChunkData chunk) { + default void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { } /** @@ -59,7 +59,7 @@ public interface WorldDataListener { * @param world the world instance * @param chunk the chunk that is going to be unloaded */ - default void beforeChunkUnloaded(WorldData world, ChunkData chunk) { + default void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) { } /** @@ -68,7 +68,7 @@ public interface WorldDataListener { * @param world the world instance * @param entity the entity that has been added */ - default void onEntityAdded(WorldData world, EntityData entity) { + default void onEntityAdded(DefaultWorldData world, EntityData entity) { } /** @@ -77,7 +77,7 @@ public interface WorldDataListener { * @param world the world instance * @param entity the entity that is going to be removed */ - default void beforeEntityRemoved(WorldData world, EntityData entity) { + default void beforeEntityRemoved(DefaultWorldData world, EntityData entity) { } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldDataRO.java b/src/main/java/ru/windcorp/progressia/common/world/WorldDataRO.java new file mode 100644 index 0000000..0fdfcbc --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldDataRO.java @@ -0,0 +1,29 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.WorldGenericRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface WorldDataRO + extends WorldGenericRO { + + /** + * Returns in-world time since creation. World time is zero before and + * during first tick. + *

+ * Game logic should assume that this value mostly increases uniformly. + * However, it is not guaranteed that in-world time always increments. + * + * @return time, in in-game seconds, since the world was created + */ + float getTime(); + + /** + * Gets the {@link GravityModel} used by this world. + * + * @return the gravity model + */ + GravityModel getGravityModel(); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java b/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java index e94f838..e2337c5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java @@ -21,9 +21,9 @@ package ru.windcorp.progressia.common.world.block; import ru.windcorp.progressia.common.collision.AABB; import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.generic.BlockGeneric; -public class BlockData extends Namespaced implements GenericBlock { +public class BlockData extends Namespaced implements BlockGeneric { public BlockData(String id) { super(id); diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java b/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java index 55d0eb2..eec2c46 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java @@ -24,7 +24,7 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketSetBlock extends PacketAffectBlock { @@ -60,7 +60,7 @@ public class PacketSetBlock extends PacketAffectBlock { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { BlockData block = BlockDataRegistry.getInstance().get(getBlockId()); world.setBlock(getBlockInWorld(), block, true); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java index ed6876d..bc00974 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java @@ -32,10 +32,10 @@ import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.util.Matrices; -import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; import ru.windcorp.progressia.common.world.rels.AbsFace; -public class EntityData extends StatefulObject implements Collideable, GenericEntity { +public class EntityData extends StatefulObject implements Collideable, EntityGeneric { private final Vec3 position = new Vec3(); private final Vec3 velocity = new Vec3(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java index f3bf792..252ca6c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java @@ -24,7 +24,7 @@ import java.io.IOException; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.PacketAffectWorld; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketAffectEntity extends PacketAffectWorld { @@ -53,7 +53,7 @@ public class PacketAffectEntity extends PacketAffectWorld { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { world.removeEntity(this.entityId); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java index d09b0f3..25eb94f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java @@ -26,7 +26,7 @@ import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.DataBuffer; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketChangeEntity extends PacketAffectEntity { @@ -68,7 +68,7 @@ public class PacketChangeEntity extends PacketAffectEntity { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { EntityData entity = world.getEntity(getEntityId()); if (entity == null) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java index 06dfc12..b006abf 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java @@ -23,7 +23,7 @@ import java.io.DataOutput; import java.io.IOException; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketRevokeEntity extends PacketAffectEntity { @@ -51,7 +51,7 @@ public class PacketRevokeEntity extends PacketAffectEntity { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { world.removeEntity(getEntityId()); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java index 6604d4a..1d1c792 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java @@ -26,7 +26,7 @@ import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.DataBuffer; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketSendEntity extends PacketAffectEntity { @@ -85,7 +85,7 @@ public class PacketSendEntity extends PacketAffectEntity { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { EntityData entity = EntityDataRegistry.getInstance().create(getEntityTypeId()); entity.setEntityId(getEntityId()); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java b/src/main/java/ru/windcorp/progressia/common/world/generic/BlockGeneric.java similarity index 96% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/BlockGeneric.java index d669b07..b8b05b2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/BlockGeneric.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world.generic; -public interface GenericBlock { +public interface BlockGeneric { String getId(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java similarity index 92% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java index 3643564..56482b5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java @@ -32,37 +32,37 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; /** * An unmodifiable chunk representation. Per default, it is usually one of - * {@link ru.windcorp.progressia.common.world.ChunkData ChunkData}, + * {@link ru.windcorp.progressia.common.world.DefaultChunkData ChunkData}, * {@link ru.windcorp.progressia.client.world.ChunkRender ChunkRender} or * {@link ru.windcorp.progressia.server.world.ChunkLogic ChunkLogic}, but this * interface may be implemented differently for various reasons. *

- * A generic chunk contains {@linkplain GenericBlock blocks} and - * {@linkplain GenericTileStack tile stacks} and is characterized by its + * A generic chunk contains {@linkplain BlockGeneric blocks} and + * {@linkplain TileGenericStackRO tile stacks} and is characterized by its * location. It also bears a discrete up direction. Note that no - * {@linkplain GenericWorld world} object is directly accessible through this + * {@linkplain WorldGenericRO world} object is directly accessible through this * interface. *

* This interface defines the most common methods for examining a chunk and * implements many of them as default methods. It also contains several static * methods useful when dealing with chunks. {@code GenericChunk} does not - * provide a way to modify a chunk; use {@link GenericWritableChunk} methods + * provide a way to modify a chunk; use {@link ChunkGenericWO} methods * when applicable. * * @param a reference to itself (required to properly reference a - * {@link GenericTileStack}) + * {@link TileGenericStackRO}) * @param block type * @param tile type * @param tile stack type * @author javapony */ // @formatter:off -public interface GenericChunk< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericTileStack , - TR extends GenericTileReference , - C extends GenericChunk +public interface ChunkGenericRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO > { // @formatter:on diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericWO.java new file mode 100644 index 0000000..1005454 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericWO.java @@ -0,0 +1,37 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.BlockFace; + +// @formatter:off +public interface ChunkGenericWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO +> { +// @formatter:on + + void setBlock(Vec3i posInChunk, B block, boolean notify); + + TS getTiles(Vec3i blockInChunk, BlockFace face); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java index 5b4f6f6..695ba91 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java @@ -77,27 +77,27 @@ public interface ChunkMap { // TODO implement (int, int, int) and GenericChunk versions of all of the // above - default boolean containsChunk(GenericChunk chunk) { + default boolean containsChunk(ChunkGenericRO chunk) { return containsKey(chunk.getPosition()); } - default V get(GenericChunk chunk) { + default V get(ChunkGenericRO chunk) { return get(chunk.getPosition()); } - default V put(GenericChunk chunk, V obj) { + default V put(ChunkGenericRO chunk, V obj) { return put(chunk.getPosition(), obj); } - default V remove(GenericChunk chunk) { + default V remove(ChunkGenericRO chunk) { return remove(chunk.getPosition()); } - default V getOrDefault(GenericChunk chunk, V def) { + default V getOrDefault(ChunkGenericRO chunk, V def) { return containsChunk(chunk) ? def : get(chunk); } - default > V compute( + default > V compute( C chunk, BiFunction remappingFunction ) { @@ -128,8 +128,8 @@ public interface ChunkMap { void forEach(BiConsumer action); - default > void forEachIn( - GenericWorld world, + default > void forEachIn( + WorldGenericRO world, BiConsumer action ) { forEach((pos, value) -> { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java index c194351..658f9ea 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java @@ -174,42 +174,42 @@ public class ChunkMaps { } @Override - public boolean containsChunk(GenericChunk chunk) { + public boolean containsChunk(ChunkGenericRO chunk) { synchronized (mutex) { return parent.containsChunk(chunk); } } @Override - public V get(GenericChunk chunk) { + public V get(ChunkGenericRO chunk) { synchronized (mutex) { return parent.get(chunk); } } @Override - public V put(GenericChunk chunk, V obj) { + public V put(ChunkGenericRO chunk, V obj) { synchronized (mutex) { return parent.put(chunk, obj); } } @Override - public V remove(GenericChunk chunk) { + public V remove(ChunkGenericRO chunk) { synchronized (mutex) { return parent.remove(chunk); } } @Override - public V getOrDefault(GenericChunk chunk, V def) { + public V getOrDefault(ChunkGenericRO chunk, V def) { synchronized (mutex) { return parent.getOrDefault(chunk, def); } } @Override - public > V compute( + public > V compute( C chunk, BiFunction remappingFunction ) { @@ -247,8 +247,8 @@ public class ChunkMaps { } @Override - public > void forEachIn( - GenericWorld world, + public > void forEachIn( + WorldGenericRO world, BiConsumer action ) { synchronized (mutex) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java index 199e780..9b75d3c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java @@ -78,20 +78,20 @@ public interface ChunkSet extends Iterable { return result; } - default boolean contains(GenericChunk chunk) { + default boolean contains(ChunkGenericRO chunk) { return contains(chunk.getPosition()); } - default boolean add(GenericChunk chunk) { + default boolean add(ChunkGenericRO chunk) { return add(chunk.getPosition()); } - default boolean remove(GenericChunk chunk) { + default boolean remove(ChunkGenericRO chunk) { return remove(chunk.getPosition()); } - default > void forEachIn( - GenericWorld world, + default > void forEachIn( + WorldGenericRO world, Consumer action ) { forEach(position -> { @@ -210,7 +210,7 @@ public interface ChunkSet extends Iterable { } } - default boolean containsAllChunks(Iterable> chunks) { + default boolean containsAllChunks(Iterable> chunks) { boolean[] hasMissing = new boolean[] { false }; chunks.forEach(c -> { @@ -222,7 +222,7 @@ public interface ChunkSet extends Iterable { return hasMissing[0]; } - default boolean containsAnyChunks(Iterable> chunks) { + default boolean containsAnyChunks(Iterable> chunks) { boolean[] hasPresent = new boolean[] { false }; chunks.forEach(c -> { @@ -234,11 +234,11 @@ public interface ChunkSet extends Iterable { return hasPresent[0]; } - default void addAllChunks(Iterable> chunks) { + default void addAllChunks(Iterable> chunks) { chunks.forEach(this::add); } - default void removeAllChunks(Iterable> chunks) { + default void removeAllChunks(Iterable> chunks) { chunks.forEach(this::remove); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java index 4ee643b..8123cbc 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java @@ -198,29 +198,29 @@ public class ChunkSets { } @Override - public boolean contains(GenericChunk chunk) { + public boolean contains(ChunkGenericRO chunk) { synchronized (mutex) { return parent.contains(chunk); } } @Override - public boolean add(GenericChunk chunk) { + public boolean add(ChunkGenericRO chunk) { synchronized (mutex) { return parent.add(chunk); } } @Override - public boolean remove(GenericChunk chunk) { + public boolean remove(ChunkGenericRO chunk) { synchronized (mutex) { return parent.remove(chunk); } } @Override - public > void forEachIn( - GenericWorld world, + public > void forEachIn( + WorldGenericRO world, Consumer action ) { synchronized (mutex) { @@ -320,28 +320,28 @@ public class ChunkSets { } @Override - public boolean containsAllChunks(Iterable> chunks) { + public boolean containsAllChunks(Iterable> chunks) { synchronized (mutex) { return parent.containsAllChunks(chunks); } } @Override - public boolean containsAnyChunks(Iterable> chunks) { + public boolean containsAnyChunks(Iterable> chunks) { synchronized (mutex) { return parent.containsAnyChunks(chunks); } } @Override - public void addAllChunks(Iterable> chunks) { + public void addAllChunks(Iterable> chunks) { synchronized (mutex) { parent.addAllChunks(chunks); } } @Override - public void removeAllChunks(Iterable> chunks) { + public void removeAllChunks(Iterable> chunks) { synchronized (mutex) { parent.removeAllChunks(chunks); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java b/src/main/java/ru/windcorp/progressia/common/world/generic/EntityGeneric.java similarity index 97% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/EntityGeneric.java index 3acfc23..481191f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/EntityGeneric.java @@ -22,7 +22,7 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -public interface GenericEntity { +public interface EntityGeneric { String getId(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java index 3d65785..83ba89a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java @@ -34,7 +34,7 @@ public class GenericChunks { output = new Vec3i(); } - final int offset = GenericChunk.BLOCKS_PER_CHUNK - 1; + final int offset = ChunkGenericRO.BLOCKS_PER_CHUNK - 1; output.set(relativeCoords.x, relativeCoords.y, relativeCoords.z); output.mul(2).sub(offset); @@ -51,7 +51,7 @@ public class GenericChunks { output = new Vec3i(); } - final int offset = GenericChunk.BLOCKS_PER_CHUNK - 1; + final int offset = ChunkGenericRO.BLOCKS_PER_CHUNK - 1; output.set(absoluteCoords.x, absoluteCoords.y, absoluteCoords.z); output.mul(2).sub(offset); @@ -73,7 +73,7 @@ public class GenericChunks { return hits; } - static boolean testBiC(Vec3i blockInWorld, GenericChunk chunk, Predicate test) { + static boolean testBiC(Vec3i blockInWorld, ChunkGenericRO chunk, Predicate test) { Vec3i v = Vectors.grab3i(); v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v); @@ -87,9 +87,9 @@ public class GenericChunks { } public static boolean containsBiC(Vec3i blockInChunk) { - return blockInChunk.x >= 0 && blockInChunk.x < GenericChunk.BLOCKS_PER_CHUNK && - blockInChunk.y >= 0 && blockInChunk.y < GenericChunk.BLOCKS_PER_CHUNK && - blockInChunk.z >= 0 && blockInChunk.z < GenericChunk.BLOCKS_PER_CHUNK; + return blockInChunk.x >= 0 && blockInChunk.x < ChunkGenericRO.BLOCKS_PER_CHUNK && + blockInChunk.y >= 0 && blockInChunk.y < ChunkGenericRO.BLOCKS_PER_CHUNK && + blockInChunk.z >= 0 && blockInChunk.z < ChunkGenericRO.BLOCKS_PER_CHUNK; } public static boolean isSurfaceBiC(Vec3i blockInChunk) { @@ -109,9 +109,9 @@ public class GenericChunks { 0, 0, 0, - GenericChunk.BLOCKS_PER_CHUNK, - GenericChunk.BLOCKS_PER_CHUNK, - GenericChunk.BLOCKS_PER_CHUNK, + ChunkGenericRO.BLOCKS_PER_CHUNK, + ChunkGenericRO.BLOCKS_PER_CHUNK, + ChunkGenericRO.BLOCKS_PER_CHUNK, action ); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java deleted file mode 100644 index 40fb010..0000000 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.common.world.generic; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.Vectors; - -// @formatter:off -public interface GenericWritableChunk< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericWritableTileStack , - TR extends GenericTileReference , - C extends GenericWritableChunk -> - extends GenericChunk { -// @formatter:on - - void setBlock(Vec3i posInChunk, B block, boolean notify); - - default void setBlockRel(Vec3i relativeBlockInChunk, B block, boolean notify) { - Vec3i absoluteBlockInChunk = Vectors.grab3i(); - resolve(relativeBlockInChunk, absoluteBlockInChunk); - setBlock(absoluteBlockInChunk, block, notify); - Vectors.release(absoluteBlockInChunk); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java index 11559ca..bed628e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java @@ -45,7 +45,7 @@ public class LongBasedChunkSet implements ChunkSet { addAll(copyFrom); } - public LongBasedChunkSet(TLongSet impl, GenericWorld copyFrom) { + public LongBasedChunkSet(TLongSet impl, WorldGenericRO copyFrom) { this(impl); addAllChunks(copyFrom.getChunks()); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGeneric.java similarity index 96% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/TileGeneric.java index e35aec2..4a2b2e3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGeneric.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world.generic; -public interface GenericTile { +public interface TileGeneric { String getId(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java new file mode 100644 index 0000000..64f7cfb --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java @@ -0,0 +1,50 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.generic; + +// @formatter:off +public interface TileGenericReferenceRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO +> { +// @formatter:on + + T get(); + + int getIndex(); + + TS getStack(); + + default boolean isValid() { + return get() != null; + } + + default int getTag() { + TS tileStack = getStack(); + if (tileStack == null) { + return -1; + } else { + return tileStack.getTagByIndex(getIndex()); + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceWO.java similarity index 70% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceWO.java index b3e7289..f31eca8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceWO.java @@ -19,23 +19,15 @@ package ru.windcorp.progressia.common.world.generic; // @formatter:off -public interface GenericTileReference< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericTileStack , - TR extends GenericTileReference , - C extends GenericChunk +public interface TileGenericReferenceWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO > { // @formatter:on - - T get(); - - int getIndex(); - - TS getStack(); - - default boolean isValid() { - return get() != null; - } + + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackRO.java similarity index 68% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackRO.java index ddf7e00..0a08fac 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackRO.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world.generic; -import java.util.AbstractList; +import java.util.List; import java.util.Objects; import java.util.RandomAccess; import java.util.function.Consumer; @@ -28,13 +28,13 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.RelFace; // @formatter:off -public abstract class GenericTileStack< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericTileStack , - TR extends GenericTileReference , - C extends GenericChunk -> extends AbstractList implements RandomAccess { +public interface TileGenericStackRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO +> extends List, RandomAccess { // @formatter:on public static interface TSConsumer { @@ -43,36 +43,36 @@ public abstract class GenericTileStack< public static final int TILES_PER_FACE = 8; - public abstract Vec3i getBlockInChunk(Vec3i output); + Vec3i getBlockInChunk(Vec3i output); - public abstract C getChunk(); + C getChunk(); - public abstract RelFace getFace(); + RelFace getFace(); - public abstract TR getReference(int index); + TR getReference(int index); - public abstract int getIndexByTag(int tag); + int getIndexByTag(int tag); - public abstract int getTagByIndex(int index); + int getTagByIndex(int index); - public Vec3i getBlockInWorld(Vec3i output) { + default Vec3i getBlockInWorld(Vec3i output) { // This is safe return Coordinates.getInWorld(getChunk().getPosition(), getBlockInChunk(output), output); } - public boolean isFull() { + default boolean isFull() { return size() >= TILES_PER_FACE; } - public T getClosest() { + default T getClosest() { return get(0); } - public T getFarthest() { + default T getFarthest() { return get(size() - 1); } - public void forEach(TSConsumer action) { + default void forEach(TSConsumer action) { Objects.requireNonNull(action, "action"); for (int i = 0; i < size(); ++i) { action.accept(i, get(i)); @@ -80,14 +80,14 @@ public abstract class GenericTileStack< } @Override - public void forEach(Consumer action) { + default void forEach(Consumer action) { Objects.requireNonNull(action, "action"); for (int i = 0; i < size(); ++i) { action.accept(get(i)); } } - public T findClosest(String id) { + default T findClosest(String id) { Objects.requireNonNull(id, "id"); for (int i = 0; i < size(); ++i) { @@ -100,7 +100,7 @@ public abstract class GenericTileStack< return null; } - public T findFarthest(String id) { + default T findFarthest(String id) { Objects.requireNonNull(id, "id"); for (int i = 0; i < size(); ++i) { @@ -113,11 +113,11 @@ public abstract class GenericTileStack< return null; } - public boolean contains(String id) { + default boolean contains(String id) { return findClosest(id) != null; } - public B getHost() { + default B getHost() { return getChunk().getBlock(getBlockInChunk(null)); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackWO.java similarity index 80% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackWO.java index b2363e3..ec5073e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackWO.java @@ -18,15 +18,18 @@ package ru.windcorp.progressia.common.world.generic; +import java.util.List; +import java.util.RandomAccess; + // @formatter:off -public abstract class GenericWritableTileStack< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericWritableTileStack, - TR extends GenericTileReference, - C extends GenericWritableChunk +public interface TileGenericStackWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO > - extends GenericTileStack { + extends List, RandomAccess { // @formatter:on /** @@ -45,7 +48,7 @@ public abstract class GenericWritableTileStack< * make sure to override it in subclass */ @Override - public abstract void add(int index, T tile); + void add(int index, T tile); /** * Adds the specified tile at the end of this stack assigning it the @@ -59,7 +62,7 @@ public abstract class GenericWritableTileStack< * with the * provided tag */ - public abstract void load(T tile, int tag); + void load(T tile, int tag); /** * Replaces the tile at the specified position in this stack with the @@ -74,7 +77,7 @@ public abstract class GenericWritableTileStack< * make sure to override it in subclass */ @Override - public abstract T set(int index, T tile); + T set(int index, T tile); /** * Removes the tile at the specified position in this list. Shifts any @@ -91,19 +94,21 @@ public abstract class GenericWritableTileStack< * make sure to override it in subclass */ @Override - public abstract T remove(int index); + T remove(int index); /* * Aliases and overloads */ - public void addClosest(T tile) { + default void addClosest(T tile) { add(0, tile); } - public void addFarthest(T tile) { + default void addFarthest(T tile) { add(size(), tile); } + + boolean isFull(); /** * Attempts to {@link #add(int, TileData) add} the provided {@code tile} @@ -114,45 +119,45 @@ public abstract class GenericWritableTileStack< * @param tile the tile to try to add * @return {@code true} iff this stack has changed */ - public boolean offer(int index, T tile) { + default boolean offer(int index, T tile) { if (isFull()) return false; add(index, tile); return true; } - public boolean offerClosest(T tile) { + default boolean offerClosest(T tile) { return offer(0, tile); } - public boolean offerFarthest(T tile) { + default boolean offerFarthest(T tile) { return offer(size(), tile); } - public T removeClosest() { + default T removeClosest() { return remove(0); } - public T removeFarthest() { + default T removeFarthest() { return remove(size() - 1); } - public T poll(int index) { + default T poll(int index) { if (size() <= index) return null; return remove(index); } - public T pollClosest() { + default T pollClosest() { return poll(0); } - public T pollFarthest() { + default T pollFarthest() { return poll(size() - 1); } @Override - public boolean add(T tile) { + default boolean add(T tile) { addFarthest(tile); return true; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java similarity index 90% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java index e17cf66..75ad1c3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java @@ -30,17 +30,17 @@ import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; // @formatter:off -public interface GenericWorld< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericTileStack , - TR extends GenericTileReference , - C extends GenericChunk , - E extends GenericEntity +public interface WorldGenericRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric > { // @formatter:on - Collection getChunks(); + Collection getChunks(); C getChunk(Vec3i pos); @@ -131,6 +131,15 @@ public interface GenericWorld< return stack.get(layer); } + /** + * Determines whether the specified position has a tile. + * + * @return {@code true} iff the tile exists + */ + default boolean hasTile(Vec3i location, BlockFace face, int layer) { + return hasTile(location, face, layer); + } + default boolean isChunkLoaded(Vec3i chunkPos) { return getChunk(chunkPos) != null; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericWO.java similarity index 52% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericWO.java index b970f89..3b9a81b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericWO.java @@ -18,21 +18,24 @@ package ru.windcorp.progressia.common.world.generic; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.world.rels.BlockFace; //@formatter:off -public interface GenericWritableWorld< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericWritableTileStack , - TR extends GenericTileReference , - C extends GenericWritableChunk , - E extends GenericEntity -> - extends GenericWorld { +public interface WorldGenericWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> { //@formatter:on - void setBlock(Vec3i blockInWorld, BlockData block, boolean notify); + void setBlock(Vec3i blockInWorld, B block, boolean notify); + + TS getTiles(Vec3i blockInWorld, BlockFace face); void addEntity(E entity); @@ -42,4 +45,13 @@ public interface GenericWritableWorld< removeEntity(entity.getEntityId()); } + /** + * Requests that the specified change is applied to the given entity. The + * {@code change} object provided may be stored until the change is applied. + * + * @param entity the entity to change + * @param change the change to apply + */ + void changeEntity(SE entity, StateChange change); + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java similarity index 70% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java index 430a4a3..212cc9b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java @@ -18,13 +18,7 @@ package ru.windcorp.progressia.common.world.generic.context; import ru.windcorp.progressia.common.world.context.Context; -import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.generic.GenericROChunk; -import ru.windcorp.progressia.common.world.generic.GenericEntity; -import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.generic.GenericROTileReference; -import ru.windcorp.progressia.common.world.generic.GenericROTileStack; -import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.generic.*; /** * A {@link Context} referencing a world with a block location and a block face @@ -32,23 +26,16 @@ import ru.windcorp.progressia.common.world.rels.RelFace; * not actually exist. */ //@formatter:off -public interface GenericROBlockFaceContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericROTileStack , - TR extends GenericROTileReference , - C extends GenericROChunk , - E extends GenericEntity -> extends GenericROBlockContext { +public interface BlockFaceGenericContextRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric +> extends WorldContexts.BlockFace, BlockGenericContextRO { //@formatter:on - /** - * Returns the face relevant to this context. - * - * @return the block face - */ - RelFace getFace(); - /** * Gets the tile stack at the relevant position. * diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java similarity index 72% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java index b2152f8..bcaa226 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java @@ -28,14 +28,14 @@ import ru.windcorp.progressia.common.world.generic.*; * stack may or may not actually exist. */ //@formatter:off -public interface GenericRWBlockFaceContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericRWTileStack , - TR extends GenericROTileReference , - C extends GenericRWChunk , - E extends GenericEntity -> extends GenericRWBlockContext, GenericROBlockFaceContext { +public interface BlockFaceGenericContextWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> extends WorldContexts.BlockFace, BlockGenericContextWO { //@formatter:on /** @@ -63,16 +63,4 @@ public interface GenericRWBlockFaceContext< removeTile(getLocation(), getFace(), tag); } - /** - * Requests that the referenced tile is removed from the specified tile - * stack. If the tile could not be found at the time of application this - * method fails silently. The location and the face of the block are implied - * by the context. - * - * @param tileReference a reference to the tile - */ - default void removeTile(TR tileReference) { - removeTile(getLocation(), getFace(), tileReference.getTag()); - } - } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java similarity index 69% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java index 4411407..91ac3d3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java @@ -17,14 +17,8 @@ */ package ru.windcorp.progressia.common.world.generic.context; -import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; -import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.generic.GenericROChunk; -import ru.windcorp.progressia.common.world.generic.GenericEntity; -import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.generic.GenericROTileReference; -import ru.windcorp.progressia.common.world.generic.GenericROTileStack; +import ru.windcorp.progressia.common.world.generic.*; import ru.windcorp.progressia.common.world.rels.BlockFace; /** @@ -32,29 +26,16 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * location may or may not be loaded. */ //@formatter:off -public interface GenericROBlockContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericROTileStack , - TR extends GenericROTileReference , - C extends GenericROChunk , - E extends GenericEntity -> extends GenericROWorldContext { +public interface BlockGenericContextRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric +> extends WorldContexts.Block, WorldGenericContextRO { //@formatter:on - /** - * Returns the location of the block. - *

- * The coordinate system in use is not specified, but it is consistent - * across all methods of this context. - *

- * The object returned by this method must not be modified. It is only valid - * while the context is {@linkplain valid}. - * - * @return a vector describing the block's position - */ - Vec3i getLocation(); - /** * Determines whether the location relevant to this context is currently * loaded. diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java similarity index 74% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java index 23fb6fe..f7a0eea 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java @@ -28,14 +28,14 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * {@link #isImmediate()}. The location may or may not be loaded. */ //@formatter:off -public interface GenericRWBlockContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericRWTileStack , - TR extends GenericROTileReference , - C extends GenericRWChunk , - E extends GenericEntity -> extends GenericRWWorldContext, GenericROBlockContext { +public interface BlockGenericContextWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> extends WorldContexts.Block, WorldGenericContextWO { //@formatter:on /** @@ -76,17 +76,4 @@ public interface GenericRWBlockContext< removeTile(getLocation(), face, tag); } - /** - * Requests that the referenced tile is removed from the specified tile - * stack. If the tile could not be found at the time of application this - * method fails silently. The location of the block is implied by the - * context. - * - * @param face the of the block to remove the tile from - * @param tileReference a reference to the tile - */ - default void removeTile(BlockFace face, TR tileReference) { - removeTile(getLocation(), face, tileReference.getTag()); - } - } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java similarity index 62% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java index 0ebc768..0bc04d0 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java @@ -18,12 +18,7 @@ package ru.windcorp.progressia.common.world.generic.context; import ru.windcorp.progressia.common.world.context.Context; -import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.generic.GenericROChunk; -import ru.windcorp.progressia.common.world.generic.GenericEntity; -import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.generic.GenericROTileReference; -import ru.windcorp.progressia.common.world.generic.GenericROTileStack; +import ru.windcorp.progressia.common.world.generic.*; /** * A {@link Context} referencing a world with a block location, a block face and @@ -31,23 +26,16 @@ import ru.windcorp.progressia.common.world.generic.GenericROTileStack; * or may not actually exist. */ //@formatter:off -public interface GenericROTileContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericROTileStack , - TR extends GenericROTileReference , - C extends GenericROChunk , - E extends GenericEntity -> extends GenericROBlockFaceContext { +public interface TileGenericContextRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric +> extends WorldContexts.Tile, BlockFaceGenericContextRO { //@formatter:on - /** - * Returns the tile layer relevant to this context. - * - * @return the tile layer - */ - int getLayer(); - /** * Determines whether the location relevant to this context has a tile. * @@ -67,12 +55,7 @@ public interface GenericROTileContext< return getTile(getLocation(), getFace(), getLayer()); } - /** - * Gets the tag of the tile at the relevant position. - * - * @return the tag of the tile or {@code -1} if the location is not loaded - * or the tile does not exist - */ + @Override default int getTag() { TS tileStack = getTilesOrNull(); if (tileStack == null) { @@ -82,4 +65,23 @@ public interface GenericROTileContext< return tileStack.getTagByIndex(getLayer()); } + /** + * Gets the {@link TileGenericReferenceRO TileReference} to the relevant + * tile. + * + * @return the reference to the tile relevant to this context or + * {@code null} if the location is not loaded or the tile does not + * exist + * + * @see TileGenericStackRO#getReference(int) + */ + default TR getTileReference() { + TS tileStack = getTilesOrNull(); + if (tileStack == null) { + return null; + } + + return tileStack.getReference(getLayer()); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java similarity index 80% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java index c7c0d5c..01a27d1 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java @@ -28,14 +28,14 @@ import ru.windcorp.progressia.common.world.generic.*; * The tile may or may not actually exist. */ //@formatter:off -public interface GenericRWTileContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericRWTileStack , - TR extends GenericROTileReference , - C extends GenericRWChunk , - E extends GenericEntity -> extends GenericRWBlockFaceContext, GenericROTileContext { +public interface TileGenericContextWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> extends WorldContexts.Tile, BlockFaceGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java new file mode 100644 index 0000000..69c5f94 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java @@ -0,0 +1,127 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.generic.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.rels.RelFace; + +/** + * This class defines several {@link Context} subinterfaces that are further + * extended by Generic contexts. These interfaces declare methods for + * determining which location is "relevant" to the context. Since they are not + * Java generics they can safely be extended more than once. + *

+ * Do not reuse these interfaces outside the Generic contexts' package; consider + * them to be an implementation detail. + * + * @author javapony + * + */ +class WorldContexts { + + /** + * A {@link Context} with a world instance. This interface should not be + * implemented directly; see {@link WorldGenericContextRO} or + * {@link WorldGenericContextWO}. + * + * @author javapony + * + */ + public static interface World extends Context { + + // currently empty + + } + + /** + * A {@link Context} with a world instance and a block location. This interface + * should not be implemented directly; see {@link BlockGenericContextRO} or + * {@link BlockGenericContextWO}. + * + * @author javapony + * + */ + public static interface Block extends World { + + /** + * Returns the location of the block. + *

+ * The coordinate system in use is not specified, but it is consistent across + * all methods of this context. + *

+ * The object returned by this method must not be modified. It is only valid + * while the context is {@linkplain valid}. + * + * @return a vector describing the block's position + */ + Vec3i getLocation(); + + } + + /** + * A {@link Context} with a world instance, a block location and a block face + * (block side). This interface should not be implemented directly; see + * {@link BlockFaceGenericContextRO} or {@link BlockFaceGenericContextWO}. + * + * @author javapony + * + */ + public static interface BlockFace extends Block { + + /** + * Returns the face relevant to this context. + * + * @return the block face + */ + RelFace getFace(); + + } + + /** + * A {@link Context} with a world instance, a block location, a block face + * (block side) and a tile layer. This interface should not be implemented + * directly; see {@link TileGenericContextRO} or {@link TileGenericContextWO}. + * + * @author javapony + * + */ + public static interface Tile extends BlockFace { + + /** + * Returns the tile layer relevant to this context. + * + * @return the tile layer + */ + int getLayer(); + + /** + * Gets the tag of the tile at the relevant position. + * + * @return the tag of the tile or {@code -1} if the location is not loaded + * or the tile does not exist + */ + int getTag(); + + } + + WorldContexts() { + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java similarity index 54% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java index 09629da..588c98f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java @@ -18,26 +18,20 @@ package ru.windcorp.progressia.common.world.generic.context; import ru.windcorp.progressia.common.world.context.Context; -import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.generic.GenericROChunk; -import ru.windcorp.progressia.common.world.generic.GenericEntity; -import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.generic.GenericROTileReference; -import ru.windcorp.progressia.common.world.generic.GenericROTileStack; -import ru.windcorp.progressia.common.world.generic.GenericROWorld; +import ru.windcorp.progressia.common.world.generic.*; /** * A {@link Context} with a world instance. */ // @formatter:off -public interface GenericROWorldContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericROTileStack , - TR extends GenericROTileReference , - C extends GenericROChunk , - E extends GenericEntity -> extends Context, GenericROWorld { +public interface WorldGenericContextRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric +> extends WorldContexts.World, WorldGenericRO { // @formatter:on // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java similarity index 80% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java index 55d83ff..ddac83d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java @@ -30,14 +30,14 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * may not be immediate, see {@link #isImmediate()}. */ // @formatter:off -public interface GenericRWWorldContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericRWTileStack , - TR extends GenericROTileReference , - C extends GenericRWChunk , - E extends GenericEntity -> extends GenericROWorldContext, GenericRWWorld { +public interface WorldGenericContextWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> extends WorldContexts.World, WorldGenericWO { // @formatter:on /** @@ -92,17 +92,20 @@ public interface GenericRWWorldContext< void removeTile(Vec3i location, BlockFace face, int tag); /** - * Requests that the referenced tile is removed from the specified tile - * stack. If the tile could not be found at the time of application this - * method fails silently. + * Requests that the referenced tile is removed from its tile stack. If the + * tile could not be found at the time of application this method fails + * silently. * - * @param location the location of the block from which the tile is to - * be removed - * @param face the of the block to remove the tile from * @param tileReference a reference to the tile */ - default void removeTile(Vec3i location, BlockFace face, TR tileReference) { - removeTile(location, face, tileReference.getTag()); + default void removeTile(TileGenericReferenceRO tileReference) { + TileGenericStackRO tileStack = tileReference.getStack(); + + if (tileStack == null) { + return; + } + + removeTile(tileStack.getBlockInWorld(null), tileStack.getFace(), tileReference.getTag()); } /** @@ -123,7 +126,7 @@ public interface GenericRWWorldContext< * * @param entityId the ID of the entity to remove * @see #isImmediate() - * @see #removeEntity(GenericEntity) + * @see #removeEntity(EntityGeneric) */ @Override void removeEntity(long entityId); @@ -140,12 +143,13 @@ public interface GenericRWWorldContext< void removeEntity(E entity); /** - * Requests that the specified change is applied to the given entity. The {@code change} object provided may be stored until the change is applied. + * Requests that the specified change is applied to the given entity. The + * {@code change} object provided may be stored until the change is applied. * * @param entity the entity to change * @param change the change to apply */ @Override - void changeEntity(SE entity, StateChange change); + void changeEntity(SE entity, StateChange change); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java index 7c2a35c..df47640 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java @@ -25,9 +25,9 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public abstract class ChunkCodec extends Namespaced { @@ -46,12 +46,12 @@ public abstract class ChunkCodec extends Namespaced { return signature; } - public abstract ChunkData decode(WorldData world, Vec3i position, DataInputStream input, IOContext context) + public abstract DefaultChunkData decode(DefaultWorldData world, Vec3i position, DataInputStream input, IOContext context) throws DecodingException, IOException; - public abstract boolean shouldEncode(ChunkData chunk, IOContext context); + public abstract boolean shouldEncode(DefaultChunkData chunk, IOContext context); - public abstract void encode(ChunkData chunk, DataOutputStream output, IOContext context) throws IOException; + public abstract void encode(DefaultChunkData chunk, DataOutputStream output, IOContext context) throws IOException; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java index 025738f..b2a1cd2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java @@ -31,16 +31,16 @@ import gnu.trove.map.TByteObjectMap; import gnu.trove.map.hash.TByteObjectHashMap; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class ChunkIO { private static final TByteObjectMap CODECS_BY_ID = new TByteObjectHashMap<>(); private static final List CODECS_BY_PRIORITY = new ArrayList<>(); - public static ChunkData load(WorldData world, Vec3i position, DataInputStream data, IOContext context) + public static DefaultChunkData load(DefaultWorldData world, Vec3i position, DataInputStream data, IOContext context) throws DecodingException, IOException { if (CODECS_BY_ID.isEmpty()) @@ -73,7 +73,7 @@ public class ChunkIO { } } - public static void save(ChunkData chunk, DataOutputStream output, IOContext context) + public static void save(DefaultChunkData chunk, DataOutputStream output, IOContext context) throws IOException { ChunkCodec codec = getCodec(chunk, context); @@ -100,7 +100,7 @@ public class ChunkIO { return CODECS_BY_ID.get(signature); } - public static ChunkCodec getCodec(ChunkData chunk, IOContext context) { + public static ChunkCodec getCodec(DefaultChunkData chunk, IOContext context) { for (ChunkCodec codec : CODECS_BY_PRIORITY) { if (codec.shouldEncode(chunk, context)) { return codec; diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java index 4a1e7a0..1655446 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java @@ -24,7 +24,7 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.rels.AbsFace; public class PacketAddTile extends PacketAffectTile { @@ -61,7 +61,7 @@ public class PacketAddTile extends PacketAffectTile { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { TileData tile = TileDataRegistry.getInstance().get(getTileId()); world.getTiles(getBlockInWorld(), getFace()).add(tile); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java index 9bb66af..6935368 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java @@ -25,7 +25,8 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; +import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.rels.AbsFace; public class PacketRemoveTile extends PacketAffectTile { @@ -54,7 +55,7 @@ public class PacketRemoveTile extends PacketAffectTile { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { TileDataStack stack = world.getTiles(getBlockInWorld(), getFace()); int index = stack.getIndexByTag(getTag()); diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java index d314445..54f09a9 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java @@ -19,9 +19,9 @@ package ru.windcorp.progressia.common.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.generic.TileGeneric; -public class TileData extends Namespaced implements GenericTile { +public class TileData extends Namespaced implements TileGeneric { public TileData(String id) { super(id); diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java deleted file mode 100644 index 7e88402..0000000 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.common.world.tile; - -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.generic.GenericWritableTileStack; - -public abstract class TileDataStack - extends GenericWritableTileStack { - -} diff --git a/src/main/java/ru/windcorp/progressia/server/Player.java b/src/main/java/ru/windcorp/progressia/server/Player.java index 734783f..008c000 100644 --- a/src/main/java/ru/windcorp/progressia/server/Player.java +++ b/src/main/java/ru/windcorp/progressia/server/Player.java @@ -22,7 +22,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.Units; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.PlayerData; import ru.windcorp.progressia.common.world.entity.EntityData; @@ -55,7 +55,7 @@ public class Player extends PlayerData implements ChunkLoader { Coordinates.convertInWorldToChunk(start, start); Vec3i cursor = new Vec3i(); - float radius = getServer().getLoadDistance(this) / Units.get(ChunkData.BLOCKS_PER_CHUNK, "m"); + float radius = getServer().getLoadDistance(this) / Units.get(DefaultChunkData.BLOCKS_PER_CHUNK, "m"); float radiusSq = radius * radius; int iRadius = (int) Math.ceil(radius); diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index a0febbf..9da227f 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -28,7 +28,7 @@ import ru.windcorp.jputil.functions.ThrowingRunnable; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.TaskQueue; import ru.windcorp.progressia.common.util.crash.ReportingEventBus; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.comms.ClientManager; import ru.windcorp.progressia.server.events.ServerEvent; import ru.windcorp.progressia.server.management.load.ChunkRequestDaemon; @@ -68,7 +68,7 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); - public Server(WorldData world) { + public Server(DefaultWorldData world) { this.world = new WorldLogic( world, this, diff --git a/src/main/java/ru/windcorp/progressia/server/ServerState.java b/src/main/java/ru/windcorp/progressia/server/ServerState.java index 774f17d..de505f5 100644 --- a/src/main/java/ru/windcorp/progressia/server/ServerState.java +++ b/src/main/java/ru/windcorp/progressia/server/ServerState.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.server; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class ServerState { @@ -33,7 +33,7 @@ public class ServerState { } public static void startServer() { - Server server = new Server(new WorldData()); + Server server = new Server(new DefaultWorldData()); setInstance(server); server.start(); } diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java index baf68f6..3071530 100644 --- a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java +++ b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java @@ -18,10 +18,10 @@ package ru.windcorp.progressia.server.management.load; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.PacketRevokeChunk; import ru.windcorp.progressia.common.world.PacketSendChunk; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.Player; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.test.TestWorldDiskIO; @@ -113,9 +113,9 @@ public class ChunkManager { return LoadResult.ALREADY_LOADED; } - WorldData world = getServer().getWorld().getData(); + DefaultWorldData world = getServer().getWorld().getData(); - ChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world, getServer()); + DefaultChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world, getServer()); if (chunk != null) { world.addChunk(chunk); return LoadResult.LOADED_FROM_DISK; @@ -133,8 +133,8 @@ public class ChunkManager { * this method */ public boolean unloadChunk(Vec3i chunkPos) { - WorldData world = getServer().getWorld().getData(); - ChunkData chunk = world.getChunk(chunkPos); + DefaultWorldData world = getServer().getWorld().getData(); + DefaultChunkData chunk = world.getChunk(chunkPos); if (chunk == null) { return false; @@ -147,7 +147,7 @@ public class ChunkManager { } public void sendChunk(Player player, Vec3i chunkPos) { - ChunkData chunk = getServer().getWorld().getData().getChunk(chunkPos); + DefaultChunkData chunk = getServer().getWorld().getData().getChunk(chunkPos); if (chunk == null) { throw new IllegalStateException( @@ -180,7 +180,7 @@ public class ChunkManager { /** * Checks whether or not the chunk at the specified location is loaded. A - * loaded chunk is accessible through the server's {@link WorldData} object. + * loaded chunk is accessible through the server's {@link DefaultWorldData} object. * * @param chunkPos the position of the chunk * @return {@code true} iff the chunk is loaded 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 a5177fe..f633179 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java @@ -26,14 +26,14 @@ import java.util.WeakHashMap; import java.util.function.BiConsumer; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataReference; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; import ru.windcorp.progressia.server.world.block.TickableBlock; @@ -45,10 +45,10 @@ import ru.windcorp.progressia.server.world.tile.TileLogicReference; import ru.windcorp.progressia.server.world.tile.TileLogicRegistry; import ru.windcorp.progressia.server.world.tile.TileLogicStack; -public class ChunkLogic implements GenericChunk { +public class ChunkLogic implements ChunkGenericRO { private final WorldLogic world; - private final ChunkData data; + private final DefaultChunkData data; private final Collection tickingBlocks = new ArrayList<>(); private final Collection tickingTiles = new ArrayList<>(); @@ -58,7 +58,7 @@ public class ChunkLogic implements GenericChunk tileLogicLists = Collections .synchronizedMap(new WeakHashMap<>()); - public ChunkLogic(WorldLogic world, ChunkData data) { + public ChunkLogic(WorldLogic world, DefaultChunkData data) { this.world = world; this.data = data; @@ -103,7 +103,7 @@ public class ChunkLogic implements GenericChunk tileStack); + TileStack withTS(TileGenericStackRO tileStack); - default Builder.Chunk withChunk(ChunkData chunk) { + default Builder.Chunk withChunk(DefaultChunkData chunk) { Objects.requireNonNull(chunk, "chunk"); return withChunk(chunk.getPosition()); } @@ -259,7 +259,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } @Override - public TileStack withTS(GenericTileStack tileStack) { + public TileStack withTS(TileGenericStackRO tileStack) { Objects.requireNonNull(tileStack, "tileStack"); return withBlock( @@ -324,7 +324,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont final int minX = Coordinates.getInWorld(chunk.x, 0); final int minY = Coordinates.getInWorld(chunk.y, 0); final int minZ = Coordinates.getInWorld(chunk.z, 0); - final int size = ChunkData.BLOCKS_PER_CHUNK; + final int size = DefaultChunkData.BLOCKS_PER_CHUNK; for (v.x = minX; v.x < minX + size; ++v.x) { for (v.y = minY; v.y < minY + size; ++v.y) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java index d0b9562..fc22047 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; @@ -37,7 +37,7 @@ public class UpdateTriggerer implements ChunkDataListener { @Override public void onChunkBlockChanged( - ChunkData chunk, + DefaultChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current @@ -47,7 +47,7 @@ public class UpdateTriggerer implements ChunkDataListener { @Override public void onChunkTilesChanged( - ChunkData chunk, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace face, TileData tile, diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index d080551..7028573 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -25,12 +25,12 @@ import java.util.Map; import glm.Glm; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListeners; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.WorldDataListener; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.GenericWorld; +import ru.windcorp.progressia.common.world.generic.WorldGenericRO; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.generation.WorldGenerator; @@ -41,20 +41,20 @@ import ru.windcorp.progressia.server.world.tile.TileLogicReference; import ru.windcorp.progressia.server.world.tile.TileLogicStack; public class WorldLogic - implements GenericWorld { - private final WorldData data; + private final DefaultWorldData data; private final Server server; private final WorldGenerator generator; - private final Map chunks = new HashMap<>(); + private final Map chunks = new HashMap<>(); private final Evaluation tickEntitiesTask = new TickEntitiesTask(); - public WorldLogic(WorldData data, Server server, WorldGenerator generator) { + public WorldLogic(DefaultWorldData data, Server server, WorldGenerator generator) { this.data = data; this.server = server; @@ -63,12 +63,12 @@ public class WorldLogic data.addListener(new WorldDataListener() { @Override - public void onChunkLoaded(WorldData world, ChunkData chunk) { + public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { chunks.put(chunk, new ChunkLogic(WorldLogic.this, chunk)); } @Override - public void beforeChunkUnloaded(WorldData world, ChunkData chunk) { + public void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) { chunks.remove(chunk); } }); @@ -104,7 +104,7 @@ public class WorldLogic return server; } - public WorldData getData() { + public DefaultWorldData getData() { return data; } @@ -112,8 +112,8 @@ public class WorldLogic return generator; } - public ChunkData generate(Vec3i chunkPos) { - ChunkData chunk = getGenerator().generate(chunkPos); + public DefaultChunkData generate(Vec3i chunkPos) { + DefaultChunkData chunk = getGenerator().generate(chunkPos); if (!Glm.equals(chunkPos, chunk.getPosition())) { throw CrashReports.report(null, "Generator %s has generated a chunk at (%d; %d; %d) when requested to generate a chunk at (%d; %d; %d)", @@ -147,7 +147,7 @@ public class WorldLogic return chunk; } - public ChunkLogic getChunk(ChunkData chunkData) { + public ChunkLogic getChunk(DefaultChunkData chunkData) { return chunks.get(chunkData); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java index fdc35e2..1d08194 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java @@ -19,10 +19,10 @@ package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.generic.BlockGeneric; import ru.windcorp.progressia.common.world.rels.RelFace; -public class BlockLogic extends Namespaced implements GenericBlock { +public class BlockLogic extends Namespaced implements BlockGeneric { public BlockLogic(String id) { super(id); diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java index e765d85..bd244a0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java @@ -23,11 +23,11 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.Objects; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.GravityModelRegistry; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.WorldLogic; @@ -71,11 +71,11 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { protected abstract boolean checkIsChunkReady(H hint); - protected H getHint(ChunkData chunk) { + protected H getHint(DefaultChunkData chunk) { return hintClass.cast(chunk.getGenerationHint()); } - protected void setHint(ChunkData chunk, H hint) { + protected void setHint(DefaultChunkData chunk, H hint) { chunk.setGenerationHint(hint); } @@ -95,7 +95,7 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { } @Override - public WorldData getWorldData() { + public DefaultWorldData getWorldData() { return server.getWorld().getData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java index f05674d..a7c9753 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -25,10 +25,10 @@ import java.io.IOException; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.WorldLogic; @@ -39,7 +39,7 @@ public abstract class WorldGenerator extends Namespaced { // package-private constructor; extend AbstractWorldGeneration } - public abstract ChunkData generate(Vec3i chunkPos); + public abstract DefaultChunkData generate(Vec3i chunkPos); public abstract Object readGenerationHint(DataInputStream input) throws IOException, DecodingException; @@ -53,6 +53,6 @@ public abstract class WorldGenerator extends Namespaced { public abstract Server getServer(); public abstract WorldLogic getWorldLogic(); - public abstract WorldData getWorldData(); + public abstract DefaultWorldData getWorldData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index 186fa55..df92442 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -27,9 +27,9 @@ import com.google.common.collect.ImmutableList; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.FloatMathUtil; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.tile.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; @@ -40,13 +40,13 @@ import ru.windcorp.progressia.server.world.ticking.TickingPolicy; import ru.windcorp.progressia.server.world.tile.TSTickContext; import ru.windcorp.progressia.server.world.tile.TickableTile; import ru.windcorp.progressia.server.world.tile.TileLogic; -import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; +import static ru.windcorp.progressia.common.world.DefaultChunkData.BLOCKS_PER_CHUNK; public class TickChunk extends Evaluation { - private static final int CHUNK_VOLUME = ChunkData.BLOCKS_PER_CHUNK * - ChunkData.BLOCKS_PER_CHUNK * - ChunkData.BLOCKS_PER_CHUNK; + private static final int CHUNK_VOLUME = DefaultChunkData.BLOCKS_PER_CHUNK * + DefaultChunkData.BLOCKS_PER_CHUNK * + DefaultChunkData.BLOCKS_PER_CHUNK; private final List> randomTickMethods; diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java index 7d58d6d..25dc4db 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java @@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableList; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.ChunkDataListeners; import ru.windcorp.progressia.server.Server; @@ -105,7 +105,7 @@ public class TickerCoordinator { server.getWorld().getData().addListener(ChunkDataListeners.createAdder(new ChunkDataListener() { @Override - public void onChunkChanged(ChunkData chunk) { + public void onChunkChanged(DefaultChunkData chunk) { if (!canChange.get()) { throw CrashReports.report(null, "A change has been detected during evaluation phase"); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java index e965ffb..4272919 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java @@ -22,9 +22,9 @@ import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.tile.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; import ru.windcorp.progressia.server.world.block.BlockTickContext; @@ -54,7 +54,7 @@ public interface TSTickContext extends BlockTickContext { } default TileDataStack getTDSOrNull() { - ChunkData chunkData = getChunkData(); + DefaultChunkData chunkData = getChunkData(); if (chunkData == null) return null; 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 index 2bd43f5..67466b5 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java @@ -19,10 +19,10 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.generic.TileGeneric; import ru.windcorp.progressia.common.world.rels.RelFace; -public class TileLogic extends Namespaced implements GenericTile { +public class TileLogic extends Namespaced implements TileGeneric { public TileLogic(String id) { super(id); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java index 97bf35c..36d4c2d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java @@ -17,11 +17,11 @@ */ package ru.windcorp.progressia.server.world.tile; -import ru.windcorp.progressia.common.world.generic.GenericTileReference; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.block.BlockLogic; public interface TileLogicReference - extends GenericTileReference { + extends TileGenericReferenceRO { } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java index b38a6f6..83d7d9a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java @@ -18,13 +18,16 @@ package ru.windcorp.progressia.server.world.tile; -import ru.windcorp.progressia.common.world.generic.GenericTileStack; -import ru.windcorp.progressia.common.world.tile.TileDataStack; +import java.util.AbstractList; + +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.block.BlockLogic; public abstract class TileLogicStack - extends GenericTileStack { + extends AbstractList + implements TileGenericStackRO { public abstract TileDataStack getData(); 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 index 7e7ae88..c3003d8 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java @@ -19,8 +19,8 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataReference; public interface TileTickContext extends TSTickContext { diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index caba6ea..f4e81c5 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -33,9 +33,9 @@ import gnu.trove.map.TObjectIntMap; import gnu.trove.map.hash.TObjectIntHashMap; import ru.windcorp.jputil.functions.ThrowingConsumer; import ru.windcorp.progressia.common.state.IOContext; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.generic.GenericChunks; @@ -76,7 +76,7 @@ public class TestChunkCodec extends ChunkCodec { } @Override - public boolean shouldEncode(ChunkData chunk, IOContext context) { + public boolean shouldEncode(DefaultChunkData chunk, IOContext context) { return true; } @@ -85,13 +85,13 @@ public class TestChunkCodec extends ChunkCodec { */ @Override - public ChunkData decode(WorldData world, Vec3i position, DataInputStream input, IOContext context) + public DefaultChunkData decode(DefaultWorldData world, Vec3i position, DataInputStream input, IOContext context) throws DecodingException, IOException { BlockData[] blockPalette = readBlockPalette(input); TileData[] tilePalette = readTilePalette(input); - ChunkData chunk = new ChunkData(position, world); + DefaultChunkData chunk = new DefaultChunkData(position, world); readBlocks(input, blockPalette, chunk); readTiles(input, tilePalette, chunk); @@ -121,7 +121,7 @@ public class TestChunkCodec extends ChunkCodec { return palette; } - private void readBlocks(DataInput input, BlockData[] blockPalette, ChunkData chunk) throws IOException { + private void readBlocks(DataInput input, BlockData[] blockPalette, DefaultChunkData chunk) throws IOException { try { GenericChunks.forEachBiC(guard(v -> { chunk.setBlock(v, blockPalette[input.readInt()], false); @@ -131,7 +131,7 @@ public class TestChunkCodec extends ChunkCodec { } } - private void readTiles(DataInput input, TileData[] tilePalette, ChunkData chunk) throws IOException { + private void readTiles(DataInput input, TileData[] tilePalette, DefaultChunkData chunk) throws IOException { Vec3i bic = new Vec3i(); while (true) { @@ -157,7 +157,7 @@ public class TestChunkCodec extends ChunkCodec { */ @Override - public void encode(ChunkData chunk, DataOutputStream output, IOContext context) throws IOException { + public void encode(DefaultChunkData chunk, DataOutputStream output, IOContext context) throws IOException { Palette blockPalette = createBlockPalette(chunk); Palette tilePalette = createTilePalette(chunk); @@ -168,13 +168,13 @@ public class TestChunkCodec extends ChunkCodec { writeTiles(chunk, tilePalette, output); } - private Palette createBlockPalette(ChunkData chunk) { + private Palette createBlockPalette(DefaultChunkData chunk) { Palette blockPalette = new Palette<>(); GenericChunks.forEachBiC(v -> blockPalette.add(chunk.getBlock(v))); return blockPalette; } - private Palette createTilePalette(ChunkData chunk) { + private Palette createTilePalette(DefaultChunkData chunk) { Palette tilePalette = new Palette<>(); chunk.forEachTile((ts, t) -> tilePalette.add(t)); return tilePalette; @@ -196,7 +196,7 @@ public class TestChunkCodec extends ChunkCodec { } } - private void writeBlocks(ChunkData chunk, Palette blockPalette, DataOutput output) throws IOException { + private void writeBlocks(DefaultChunkData chunk, Palette blockPalette, DataOutput output) throws IOException { try { GenericChunks.forEachBiC(guard(v -> { output.writeInt(blockPalette.getNid(chunk.getBlock(v))); @@ -206,7 +206,7 @@ public class TestChunkCodec extends ChunkCodec { } } - private void writeTiles(ChunkData chunk, Palette tilePalette, DataOutput output) throws IOException { + private void writeTiles(DefaultChunkData chunk, Palette tilePalette, DataOutput output) throws IOException { Vec3i bic = new Vec3i(); try { diff --git a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java index 97a0d99..ebfafde 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java +++ b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java @@ -34,9 +34,9 @@ import org.apache.logging.log4j.Logger; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.state.IOContext; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.io.ChunkIO; import ru.windcorp.progressia.server.Server; @@ -47,7 +47,7 @@ public class TestWorldDiskIO { private static final boolean ENABLE = false; - public static void saveChunk(ChunkData chunk, Server server) { + public static void saveChunk(DefaultChunkData chunk, Server server) { if (!ENABLE) return; @@ -83,12 +83,12 @@ public class TestWorldDiskIO { } } - private static void writeGenerationHint(ChunkData chunk, DataOutputStream output, Server server) + private static void writeGenerationHint(DefaultChunkData chunk, DataOutputStream output, Server server) throws IOException { server.getWorld().getGenerator().writeGenerationHint(output, chunk.getGenerationHint()); } - public static ChunkData tryToLoad(Vec3i chunkPos, WorldData world, Server server) { + public static DefaultChunkData tryToLoad(Vec3i chunkPos, DefaultWorldData world, Server server) { if (!ENABLE) return null; @@ -113,7 +113,7 @@ public class TestWorldDiskIO { } try { - ChunkData result = load(path, chunkPos, world, server); + DefaultChunkData result = load(path, chunkPos, world, server); LOG.debug( "Loaded {} {} {}", @@ -135,7 +135,7 @@ public class TestWorldDiskIO { } } - private static ChunkData load(Path path, Vec3i chunkPos, WorldData world, Server server) + private static DefaultChunkData load(Path path, Vec3i chunkPos, DefaultWorldData world, Server server) throws IOException, DecodingException { try ( @@ -143,13 +143,13 @@ public class TestWorldDiskIO { new InflaterInputStream(new BufferedInputStream(Files.newInputStream(path))) ) ) { - ChunkData chunk = ChunkIO.load(world, chunkPos, input, IOContext.SAVE); + DefaultChunkData chunk = ChunkIO.load(world, chunkPos, input, IOContext.SAVE); readGenerationHint(chunk, input, server); return chunk; } } - private static void readGenerationHint(ChunkData chunk, DataInputStream input, Server server) + private static void readGenerationHint(DefaultChunkData chunk, DataInputStream input, Server server) throws IOException, DecodingException { chunk.setGenerationHint(server.getWorld().getGenerator().readGenerationHint(input)); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java index 74e3335..21c1809 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java @@ -19,12 +19,12 @@ package ru.windcorp.progressia.test.gen; import java.util.Random; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.block.BlockData; @FunctionalInterface public interface TerrainLayer { - BlockData get(float north, float west, float depth, Random random, ChunkData chunk); + BlockData get(float north, float west, float depth, Random random, DefaultChunkData chunk); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index e8c8641..75d4eb0 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -27,10 +27,10 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.WorldDataListener; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; @@ -50,7 +50,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { getWorldData().addListener(new WorldDataListener() { @Override - public void onChunkLoaded(WorldData world, ChunkData chunk) { + public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { findAndPopulate(chunk.getPosition(), world); } }); @@ -77,17 +77,17 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } @Override - public ChunkData generate(Vec3i chunkPos) { - ChunkData chunk = generateUnpopulated(chunkPos, getWorldData()); + public DefaultChunkData generate(Vec3i chunkPos) { + DefaultChunkData chunk = generateUnpopulated(chunkPos, getWorldData()); getWorldData().addChunk(chunk); return chunk; } - private ChunkData generateUnpopulated(Vec3i chunkPos, WorldData world) { - ChunkData chunk = new ChunkData(chunkPos, world); + private DefaultChunkData generateUnpopulated(Vec3i chunkPos, DefaultWorldData world) { + DefaultChunkData chunk = new DefaultChunkData(chunkPos, world); chunk.setGenerationHint(false); - final int bpc = ChunkData.BLOCKS_PER_CHUNK; + final int bpc = DefaultChunkData.BLOCKS_PER_CHUNK; Random random = new Random(chunkPos.x + chunkPos.y + chunkPos.z); BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); @@ -130,7 +130,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { return chunk; } - private void findAndPopulate(Vec3i changePos, WorldData world) { + private void findAndPopulate(Vec3i changePos, DefaultWorldData world) { VectorUtil.iterateCuboidAround(changePos, 3, candidatePos -> { if (canBePopulated(candidatePos, world)) { populate(candidatePos, world); @@ -138,10 +138,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator { }); } - private boolean canBePopulated(Vec3i candidatePos, WorldData world) { + private boolean canBePopulated(Vec3i candidatePos, DefaultWorldData world) { Vec3i cursor = Vectors.grab3i(); - ChunkData candidate = world.getChunk(candidatePos); + DefaultChunkData candidate = world.getChunk(candidatePos); if (candidate == null || isChunkReady(candidate.getGenerationHint())) return false; @@ -156,7 +156,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { cursor.z = candidatePos.z + dz; - ChunkData chunk = world.getChunk(cursor); + DefaultChunkData chunk = world.getChunk(cursor); if (chunk == null) { return false; } @@ -169,10 +169,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator { return true; } - private void populate(Vec3i chunkPos, WorldData world) { + private void populate(Vec3i chunkPos, DefaultWorldData world) { Random random = new Random(chunkPos.x + chunkPos.y + chunkPos.z); - ChunkData chunk = world.getChunk(chunkPos); + DefaultChunkData chunk = world.getChunk(chunkPos); assert chunk != null : "Something went wrong when populating chunk at (" + chunkPos.x + "; " + chunkPos.y + "; " + chunkPos.z + ")"; @@ -188,7 +188,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { int minZ = chunk.getMinZ(); int maxZ = chunk.getMaxZ() + 1; - final int bpc = ChunkData.BLOCKS_PER_CHUNK; + final int bpc = DefaultChunkData.BLOCKS_PER_CHUNK; double[][] heightMap = new double[bpc][bpc]; double[][] gradMap = new double[bpc][bpc]; @@ -226,9 +226,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } private void addTiles( - ChunkData chunk, + DefaultChunkData chunk, Vec3i biw, - WorldData world, + DefaultWorldData world, Random random, boolean isDirt, double height, @@ -240,7 +240,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { addSnow(chunk, biw, world, random, isDirt, height, grad); } - private void addGrass(ChunkData chunk, Vec3i biw, WorldData world, Random random) { + private void addGrass(DefaultChunkData chunk, Vec3i biw, DefaultWorldData world, Random random) { BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); @@ -260,7 +260,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } } - private void addDecor(ChunkData chunk, Vec3i biw, WorldData world, Random random, boolean isDirt) { + private void addDecor(DefaultChunkData chunk, Vec3i biw, DefaultWorldData world, Random random, boolean isDirt) { if (isDirt) { if (random.nextInt(8) == 0) { world.getTiles(biw, AbsFace.POS_Z).addFarthest( @@ -289,9 +289,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } private void addSnow( - ChunkData chunk, + DefaultChunkData chunk, Vec3i biw, - WorldData world, + DefaultWorldData world, Random random, boolean isDirt, double height, diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java index 38b9d94..3637078 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java @@ -17,7 +17,7 @@ */ package ru.windcorp.progressia.test.gen.planet; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; public class Planet { @@ -47,7 +47,7 @@ public class Planet { } public float getRadius() { - return radiusInChunks * ChunkData.BLOCKS_PER_CHUNK + ChunkData.CHUNK_RADIUS; + return radiusInChunks * DefaultChunkData.BLOCKS_PER_CHUNK + DefaultChunkData.CHUNK_RADIUS; } public int getDiameterInChunks() { @@ -55,7 +55,7 @@ public class Planet { } public float getDiameter() { - return getDiameterInChunks() * ChunkData.BLOCKS_PER_CHUNK; + return getDiameterInChunks() * DefaultChunkData.BLOCKS_PER_CHUNK; } /** diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java index 6c14a2b..a33cb87 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java @@ -23,7 +23,7 @@ import java.util.Map; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.test.TestBushFeature; import ru.windcorp.progressia.test.TestGrassFeature; @@ -57,7 +57,7 @@ public class PlanetFeatureGenerator { return parent; } - public void generateFeatures(ChunkData chunk) { + public void generateFeatures(DefaultChunkData chunk) { if (isOrdinaryChunk(chunk.getPosition())) { generateOrdinaryFeatures(chunk); } else { @@ -72,11 +72,11 @@ public class PlanetFeatureGenerator { return sorted.x != sorted.y; } - private void generateOrdinaryFeatures(ChunkData chunk) { + private void generateOrdinaryFeatures(DefaultChunkData chunk) { surfaceGenerators.get(chunk.getUp()).generateFeatures(chunk); } - private void generateBorderFeatures(ChunkData chunk) { + private void generateBorderFeatures(DefaultChunkData chunk) { // Do nothing } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java index e8307cb..227187d 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java @@ -22,7 +22,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.ArrayFloatRangeMap; import ru.windcorp.progressia.common.util.FloatRangeMap; import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; @@ -40,7 +40,7 @@ class PlanetTerrainGenerator { this.parent = generator; SurfaceFloatField heightMap = new TestHeightMap( - generator.getPlanet().getRadius() - ChunkData.BLOCKS_PER_CHUNK, + generator.getPlanet().getRadius() - DefaultChunkData.BLOCKS_PER_CHUNK, generator.getPlanet().getRadius() / 4, 5, 6 @@ -61,8 +61,8 @@ class PlanetTerrainGenerator { return parent; } - public ChunkData generateTerrain(Vec3i chunkPos) { - ChunkData chunk = new ChunkData(chunkPos, getGenerator().getWorldData()); + public DefaultChunkData generateTerrain(Vec3i chunkPos) { + DefaultChunkData chunk = new DefaultChunkData(chunkPos, getGenerator().getWorldData()); if (isOrdinaryChunk(chunkPos)) { generateOrdinaryTerrain(chunk); @@ -80,11 +80,11 @@ class PlanetTerrainGenerator { return sorted.x != sorted.y; } - private void generateOrdinaryTerrain(ChunkData chunk) { + private void generateOrdinaryTerrain(DefaultChunkData chunk) { surfaceGenerator.generateTerrain(chunk); } - private void generateBorderTerrain(ChunkData chunk) { + private void generateBorderTerrain(DefaultChunkData chunk) { BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); @@ -100,7 +100,7 @@ class PlanetTerrainGenerator { Coordinates.getInWorld(chunk.getZ(), bic.z) ); - biw.sub(ChunkData.CHUNK_RADIUS - 0.5f); + biw.sub(DefaultChunkData.CHUNK_RADIUS - 0.5f); VectorUtil.sortAfterAbs(biw, biw); chunk.setBlock(bic, biw.x <= radius ? stone : air, false); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index 1dbd5b8..8b92470 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -24,7 +24,7 @@ import java.io.IOException; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; @@ -76,9 +76,9 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { } @Override - public ChunkData generate(Vec3i chunkPos) { + public DefaultChunkData generate(Vec3i chunkPos) { VectorUtil.iterateCuboidAround(chunkPos, 3, r -> conjureTerrain(r)); - ChunkData chunk = getWorldData().getChunk(chunkPos); + DefaultChunkData chunk = getWorldData().getChunk(chunkPos); if (!isChunkReady(chunk.getGenerationHint())) { featureGenerator.generateFeatures(chunk); @@ -88,7 +88,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { } private void conjureTerrain(Vec3i chunkPos) { - ChunkData chunk = getWorldData().getChunk(chunkPos); + DefaultChunkData chunk = getWorldData().getChunk(chunkPos); if (chunk == null) { chunk = getWorldData().getChunk(chunkPos); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java index cb5fc34..a7fb334 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.test.gen.planet; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.rels.AbsFace; @@ -93,9 +93,9 @@ public class TestPlanetGravityModel extends GravityModel { float g = getSurfaceGravitationalAcceleration(); // Change to a CS where (0;0;0) is the center of the center chunk - float px = pos.x - ChunkData.CHUNK_RADIUS + 0.5f; - float py = pos.y - ChunkData.CHUNK_RADIUS + 0.5f; - float pz = pos.z - ChunkData.CHUNK_RADIUS + 0.5f; + float px = pos.x - DefaultChunkData.CHUNK_RADIUS + 0.5f; + float py = pos.y - DefaultChunkData.CHUNK_RADIUS + 0.5f; + float pz = pos.z - DefaultChunkData.CHUNK_RADIUS + 0.5f; // Assume weightlessness when too close to center if ((px*px + py*py + pz*pz) < r*r) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java index 69e6d8b..0510d98 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java @@ -25,7 +25,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunks; public abstract class SurfaceFeature extends Namespaced { @@ -33,13 +33,13 @@ public abstract class SurfaceFeature extends Namespaced { public static class Request { private final SurfaceWorld world; - private final ChunkData chunk; + private final DefaultChunkData chunk; private final Vec3i minSfc = new Vec3i(); private final Vec3i maxSfc = new Vec3i(); private final Random random; - public Request(SurfaceWorld world, ChunkData chunk, Random random) { + public Request(SurfaceWorld world, DefaultChunkData chunk, Random random) { this.world = world; this.chunk = chunk; this.random = random; @@ -57,7 +57,7 @@ public abstract class SurfaceFeature extends Namespaced { maxSfc.z -= world.getSurface().getSeaLevel(); } - public ChunkData getChunk() { + public DefaultChunkData getChunk() { return chunk; } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java index 9a3c909..54b582e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java @@ -22,7 +22,7 @@ import java.util.Collection; import java.util.Random; import ru.windcorp.progressia.common.util.CoordinatePacker; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; public class SurfaceFeatureGenerator { @@ -42,7 +42,7 @@ public class SurfaceFeatureGenerator { return surface; } - public void generateFeatures(ChunkData chunk) { + public void generateFeatures(DefaultChunkData chunk) { SurfaceWorld world = new SurfaceWorld(surface, chunk.getWorld()); Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java index b05df5a..ec93d58 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java @@ -23,7 +23,7 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.CoordinatePacker; import ru.windcorp.progressia.common.util.FloatRangeMap; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.test.gen.TerrainLayer; @@ -38,35 +38,38 @@ public class SurfaceTerrainGenerator { this.layers = layers; } - public void generateTerrain(ChunkData chunk) { + public void generateTerrain(DefaultChunkData chunk) { Vec3i relBIC = new Vec3i(); Vec3 offset = new Vec3(chunk.getMinX(), chunk.getMinY(), chunk.getMinZ()); AxisRotations.relativize(offset, chunk.getUp(), offset); - offset.sub(ChunkData.CHUNK_RADIUS - 0.5f); + offset.sub(DefaultChunkData.CHUNK_RADIUS - 0.5f); Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); - for (relBIC.x = 0; relBIC.x < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.x) { - for (relBIC.y = 0; relBIC.y < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.y) { + for (relBIC.x = 0; relBIC.x < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.x) { + for (relBIC.y = 0; relBIC.y < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.y) { generateColumn(chunk, relBIC, offset, random); } } } - public void generateColumn(ChunkData chunk, Vec3i relBIC, Vec3 offset, Random random) { + public void generateColumn(DefaultChunkData chunk, Vec3i relBIC, Vec3 offset, Random random) { float north = relBIC.x + offset.x; float west = relBIC.y + offset.y; float relSurface = heightMap.get(chunk.getUp(), north, west) - offset.z; - for (relBIC.z = 0; relBIC.z < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.z) { + for (relBIC.z = 0; relBIC.z < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.z) { float depth = relSurface - relBIC.z; BlockData block = layers.get(depth).get(north, west, depth, random, chunk); - chunk.setBlockRel(relBIC, block, false); + + chunk.resolve(relBIC, relBIC); + chunk.setBlock(relBIC, block, false); + chunk.relativize(relBIC, relBIC); } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java index 12ff59a..7d3ec10 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java @@ -20,26 +20,29 @@ package ru.windcorp.progressia.test.gen.surface; import java.util.Collection; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; import ru.windcorp.progressia.common.world.generic.GenericChunks; -import ru.windcorp.progressia.common.world.generic.GenericWritableWorld; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataReference; -import ru.windcorp.progressia.common.world.tile.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.WorldData; public class SurfaceWorld - implements GenericWritableWorld { + implements WorldData { private final Surface surface; - private final GenericWritableWorld parent; + private final WorldData parent; public SurfaceWorld( Surface surface, - GenericWritableWorld parent + WorldData parent ) { this.surface = surface; this.parent = parent; @@ -55,7 +58,7 @@ public class SurfaceWorld /** * @return the parent */ - public GenericWritableWorld getParent() { + public WorldData getParent() { return parent; } @@ -64,7 +67,7 @@ public class SurfaceWorld */ @Override - public Collection getChunks() { + public Collection getChunks() { return parent.getChunks(); } @@ -179,4 +182,24 @@ public class SurfaceWorld return result; } + @Override + public float getTime() { + return parent.getTime(); + } + + @Override + public GravityModel getGravityModel() { + return parent.getGravityModel(); + } + + @Override + public void changeEntity(SE entity, StateChange change) { + parent.changeEntity(entity, change); + } + + @Override + public void advanceTime(float change) { + parent.advanceTime(change); + } + }