Still working on Contexts. Introduced a billion interfaces. WIP.
*takes a deep breath - Renamed Generic world structure interfaces to the following scheme: {Block,Tile,Chunk,World}Generic{,Stack,Reference}{RO,WO} (e.g. GenericWritableChunk -> ChunkGenericWO) - RO is Read Only, WO is Write Only - Generic writable interfaces no longer extend their read-only counterparts (thus Write Only) - TileGenericStack{RO,WO} are now interfaces; AbstractList is only introduced by final implementations - TileGenericReferenceRO now has a WO counterpart - Fixed compilation issues with the previous commit - Declared some additional functionality for Generic interfaces - Old ChunkData and WorldData renamed to DefaultChunkData and DefaultWorldData - Now considered to be an implementation detail; references will be minimized - Introduced TileDataStack{,RO}, TileDataReference{,RO}, ChunkData{,RO}, WorldData{,RO} interfaces - Suffix -RO indicates Read Only, no suffix means read-write - To be used in place of DefaultChunk and DefaultWorld - Designed to support wrappers and "fake" implementations - May need some refinement (fix return/parameter types, ...) - Surface world generator is now implemented poorly (WIP) - Should compile. May work fine. Unless Java inheritance rules have screwed me over.
This commit is contained in:
parent
d7afe39f00
commit
9a326603cd
@ -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;
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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<BlockRender, TileRender, TileRenderStack, TileRenderReference, ChunkRender> {
|
||||
implements ChunkGenericRO<BlockRender, TileRender, TileRenderStack, TileRenderReference, ChunkRender> {
|
||||
|
||||
private final WorldRender world;
|
||||
private final ChunkData data;
|
||||
private final DefaultChunkData data;
|
||||
|
||||
private final ChunkRenderModel model;
|
||||
|
||||
private final Map<TileDataStack, TileRenderStackImpl> 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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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<BlockRender, TileRender, TileRenderStack, TileRenderReference, ChunkRender, EntityRenderable> {
|
||||
implements WorldGenericRO<BlockRender, TileRender, TileRenderStack, TileRenderReference, ChunkRender, EntityRenderable> {
|
||||
|
||||
private final WorldData data;
|
||||
private final DefaultWorldData data;
|
||||
private final Client client;
|
||||
|
||||
private final Map<ChunkData, ChunkRender> chunks = Collections.synchronizedMap(new HashMap<>());
|
||||
private final Map<DefaultChunkData, ChunkRender> chunks = Collections.synchronizedMap(new HashMap<>());
|
||||
private final Map<EntityData, EntityRenderable> 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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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<ShapePart> 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)];
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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<BlockRender, TileRender, TileRenderStack, TileRenderReference, ChunkRender> {
|
||||
extends TileGenericReferenceRO<BlockRender, TileRender, TileRenderStack, TileRenderReference, ChunkRender> {
|
||||
|
||||
}
|
||||
|
@ -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<BlockRender, TileRender, TileRenderStack, TileRenderReference, ChunkRender> {
|
||||
extends AbstractList<TileRender>
|
||||
implements TileGenericStackRO<BlockRender, TileRender, TileRenderStack, TileRenderReference, ChunkRender> {
|
||||
|
||||
public abstract TileDataStack getData();
|
||||
|
||||
|
@ -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<ShapePart> 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(),
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
* <p>
|
||||
* When {@linkplain #advanceTime(Collection, Collision, WorldData, float)
|
||||
* When {@linkplain #advanceTime(Collection, Collision, DefaultWorldData, float)
|
||||
* advancing time},
|
||||
* time step for all entities <em>except</em> currently colliding bodies is
|
||||
* the current
|
||||
@ -61,7 +61,7 @@ public class Collider {
|
||||
|
||||
public static void performCollisions(
|
||||
List<? extends Collideable> colls,
|
||||
WorldData world,
|
||||
DefaultWorldData world,
|
||||
float tickLength,
|
||||
ColliderWorkspace workspace
|
||||
) {
|
||||
@ -96,7 +96,7 @@ public class Collider {
|
||||
private static Collision getFirstCollision(
|
||||
List<? extends Collideable> 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<? extends Collideable> colls,
|
||||
WorldData world,
|
||||
DefaultWorldData world,
|
||||
float tickLength,
|
||||
ColliderWorkspace workspace
|
||||
) {
|
||||
@ -361,7 +361,7 @@ public class Collider {
|
||||
private static void advanceTime(
|
||||
Collection<? extends Collideable> colls,
|
||||
Collision exceptions,
|
||||
WorldData world,
|
||||
DefaultWorldData world,
|
||||
float step
|
||||
) {
|
||||
world.advanceTime(step);
|
||||
|
@ -16,12 +16,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<BlockData, TileData, TileDataStack, TileDataReference, ChunkData> {
|
||||
package ru.windcorp.progressia.common.state;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface StateChange<T> {
|
||||
void change(T object);
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<BlockData, TileData, TileDataStack, TileDataReference, ChunkData> {
|
||||
public interface ChunkData extends ChunkDataRO, ChunkGenericWO<BlockData, TileData, TileDataStack, TileDataReference, 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 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
|
||||
];
|
||||
|
||||
private final AbsFace up;
|
||||
|
||||
private Object generationHint = null;
|
||||
|
||||
private final Collection<ChunkDataListener> 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<ChunkDataListener> 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;
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class ChunkDataListeners {
|
||||
public static WorldDataListener createAdder(Supplier<ChunkDataListener> listenerSupplier) {
|
||||
return new WorldDataListener() {
|
||||
@Override
|
||||
public void getChunkListeners(WorldData world, Vec3i chunk, Consumer<ChunkDataListener> chunkListenerSink) {
|
||||
public void getChunkListeners(DefaultWorldData world, Vec3i chunk, Consumer<ChunkDataListener> chunkListenerSink) {
|
||||
chunkListenerSink.accept(listenerSupplier.get());
|
||||
}
|
||||
};
|
||||
|
@ -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<BlockData, TileData, TileDataStackRO, TileDataReferenceRO, ChunkDataRO> {
|
||||
|
||||
// currently empty
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<ChunkDataListener> 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<ChunkDataListener> 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<TileData> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<DefaultChunkData> chunksByPos = new LongBasedChunkMap<>(
|
||||
TCollections.synchronizedMap(new TLongObjectHashMap<>())
|
||||
);
|
||||
|
||||
private final Collection<DefaultChunkData> chunks = Collections.unmodifiableCollection(chunksByPos.values());
|
||||
|
||||
private final TLongObjectMap<EntityData> entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>());
|
||||
|
||||
private final Collection<EntityData> entities = Collections.unmodifiableCollection(entitiesById.valueCollection());
|
||||
|
||||
private GravityModel gravityModel = null;
|
||||
|
||||
private float time = 0;
|
||||
|
||||
private final Collection<WorldDataListener> 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<DefaultChunkData> getChunks() {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
public ChunkSet getLoadedChunks() {
|
||||
return chunksByPos.keys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EntityData> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachEntity(Consumer<? super EntityData> 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 <SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> 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<WorldDataListener> getListeners() {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
public void addListener(WorldDataListener e) {
|
||||
listeners.add(e);
|
||||
}
|
||||
|
||||
public void removeListener(WorldDataListener o) {
|
||||
listeners.remove(o);
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,6 @@ public abstract class PacketAffectWorld extends Packet {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract void apply(WorldData world);
|
||||
public abstract void apply(DefaultWorldData world);
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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<BlockData, TileData, TileDataStack, TileDataReference, ChunkData> {
|
||||
|
||||
}
|
@ -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<BlockData, TileData, TileDataStackRO, TileDataReferenceRO, ChunkDataRO> {
|
||||
|
||||
// currently empty
|
||||
|
||||
}
|
@ -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<BlockData, TileData, TileDataStack, TileDataReference, ChunkData> {
|
||||
|
||||
@Override
|
||||
default boolean isFull() {
|
||||
return TileDataStackRO.super.isFull();
|
||||
}
|
||||
|
||||
/*
|
||||
* Method specialization
|
||||
*/
|
||||
|
||||
@Override
|
||||
TileDataReference getReference(int index);
|
||||
|
||||
@Override
|
||||
ChunkData getChunk();
|
||||
|
||||
}
|
@ -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<BlockData, TileData, TileDataStackRO, TileDataReferenceRO, ChunkDataRO> {
|
||||
|
||||
// currently empty
|
||||
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<BlockData, TileData, TileDataStack, TileDataReference, ChunkData, EntityData> {
|
||||
|
||||
private final ChunkMap<ChunkData> chunksByPos = new LongBasedChunkMap<>(
|
||||
TCollections.synchronizedMap(new TLongObjectHashMap<>())
|
||||
);
|
||||
|
||||
private final Collection<ChunkData> chunks = Collections.unmodifiableCollection(chunksByPos.values());
|
||||
|
||||
private final TLongObjectMap<EntityData> entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>());
|
||||
|
||||
private final Collection<EntityData> entities = Collections.unmodifiableCollection(entitiesById.valueCollection());
|
||||
|
||||
private GravityModel gravityModel = null;
|
||||
|
||||
private float time = 0;
|
||||
|
||||
private final Collection<WorldDataListener> listeners = Collections.synchronizedCollection(new ArrayList<>());
|
||||
|
||||
public WorldData() {
|
||||
|
||||
}
|
||||
public interface WorldData
|
||||
extends WorldDataRO, WorldGenericWO<BlockData, TileData, TileDataStack, TileDataReference, ChunkData, EntityData> {
|
||||
|
||||
@Override
|
||||
public ChunkData getChunk(Vec3i pos) {
|
||||
return chunksByPos.get(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ChunkData> getChunks() {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
public ChunkSet getLoadedChunks() {
|
||||
return chunksByPos.keys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EntityData> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachEntity(Consumer<? super EntityData> 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;
|
||||
}
|
||||
void advanceTime(float change);
|
||||
|
||||
/**
|
||||
* @param gravityModel the gravity model to set
|
||||
/*
|
||||
* 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<? extends ChunkData> getChunks();
|
||||
|
||||
// TODO: rename WGRO.forEachChunk -> forEachChunkRO and define WGWO.forEachChunk
|
||||
|
||||
@Override
|
||||
default ChunkData getChunkByBlock(Vec3i blockInWorld) {
|
||||
return (ChunkData) WorldDataRO.super.getChunkByBlock(blockInWorld);
|
||||
}
|
||||
|
||||
public Collection<WorldDataListener> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<ChunkDataListener> chunkListenerSink) {
|
||||
default void getChunkListeners(DefaultWorldData world, Vec3i chunk, Consumer<ChunkDataListener> 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) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<BlockData, TileData, TileDataStackRO, TileDataReferenceRO, ChunkDataRO, EntityData> {
|
||||
|
||||
/**
|
||||
* Returns in-world time since creation. World time is zero before and
|
||||
* during first tick.
|
||||
* <p>
|
||||
* 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();
|
||||
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package ru.windcorp.progressia.common.world.generic;
|
||||
|
||||
public interface GenericBlock {
|
||||
public interface BlockGeneric {
|
||||
|
||||
String getId();
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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 <Self> a reference to itself (required to properly reference a
|
||||
* {@link GenericTileStack})
|
||||
* {@link TileGenericStackRO})
|
||||
* @param <B> block type
|
||||
* @param <T> tile type
|
||||
* @param <TS> tile stack type
|
||||
* @author javapony
|
||||
*/
|
||||
// @formatter:off
|
||||
public interface GenericChunk<
|
||||
B extends GenericBlock,
|
||||
T extends GenericTile,
|
||||
TS extends GenericTileStack <B, T, TS, TR, C>,
|
||||
TR extends GenericTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericChunk <B, T, TS, TR, C>
|
||||
public interface ChunkGenericRO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackRO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericRO <B, T, TS, TR, C>
|
||||
> {
|
||||
// @formatter:on
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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 <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericWO <B, T, TS, TR, C>
|
||||
> {
|
||||
// @formatter:on
|
||||
|
||||
void setBlock(Vec3i posInChunk, B block, boolean notify);
|
||||
|
||||
TS getTiles(Vec3i blockInChunk, BlockFace face);
|
||||
|
||||
}
|
@ -77,27 +77,27 @@ public interface ChunkMap<V> {
|
||||
// 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 <C extends GenericChunk<?, ?, ?, ?, C>> V compute(
|
||||
default <C extends ChunkGenericRO<?, ?, ?, ?, C>> V compute(
|
||||
C chunk,
|
||||
BiFunction<? super C, ? super V, ? extends V> remappingFunction
|
||||
) {
|
||||
@ -128,8 +128,8 @@ public interface ChunkMap<V> {
|
||||
|
||||
void forEach(BiConsumer<? super Vec3i, ? super V> action);
|
||||
|
||||
default <C extends GenericChunk<?, ?, ?, ?, C>> void forEachIn(
|
||||
GenericWorld<?, ?, ?, ?, C, ?> world,
|
||||
default <C extends ChunkGenericRO<?, ?, ?, ?, C>> void forEachIn(
|
||||
WorldGenericRO<?, ?, ?, ?, C, ?> world,
|
||||
BiConsumer<? super C, ? super V> action
|
||||
) {
|
||||
forEach((pos, value) -> {
|
||||
|
@ -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 <C extends GenericChunk<?, ?, ?, ?, C>> V compute(
|
||||
public <C extends ChunkGenericRO<?, ?, ?, ?, C>> V compute(
|
||||
C chunk,
|
||||
BiFunction<? super C, ? super V, ? extends V> remappingFunction
|
||||
) {
|
||||
@ -247,8 +247,8 @@ public class ChunkMaps {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C extends GenericChunk<?, ?, ?, ?, C>> void forEachIn(
|
||||
GenericWorld<?, ?, ?, ?, C, ?> world,
|
||||
public <C extends ChunkGenericRO<?, ?, ?, ?, C>> void forEachIn(
|
||||
WorldGenericRO<?, ?, ?, ?, C, ?> world,
|
||||
BiConsumer<? super C, ? super V> action
|
||||
) {
|
||||
synchronized (mutex) {
|
||||
|
@ -78,20 +78,20 @@ public interface ChunkSet extends Iterable<Vec3i> {
|
||||
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 <C extends GenericChunk<?, ?, ?, ?, C>> void forEachIn(
|
||||
GenericWorld<?, ?, ?, ?, C, ?> world,
|
||||
default <C extends ChunkGenericRO<?, ?, ?, ?, C>> void forEachIn(
|
||||
WorldGenericRO<?, ?, ?, ?, C, ?> world,
|
||||
Consumer<? super C> action
|
||||
) {
|
||||
forEach(position -> {
|
||||
@ -210,7 +210,7 @@ public interface ChunkSet extends Iterable<Vec3i> {
|
||||
}
|
||||
}
|
||||
|
||||
default boolean containsAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?, ?>> chunks) {
|
||||
default boolean containsAllChunks(Iterable<? extends ChunkGenericRO<?, ?, ?, ?, ?>> chunks) {
|
||||
boolean[] hasMissing = new boolean[] { false };
|
||||
|
||||
chunks.forEach(c -> {
|
||||
@ -222,7 +222,7 @@ public interface ChunkSet extends Iterable<Vec3i> {
|
||||
return hasMissing[0];
|
||||
}
|
||||
|
||||
default boolean containsAnyChunks(Iterable<? extends GenericChunk<?, ?, ?, ?, ?>> chunks) {
|
||||
default boolean containsAnyChunks(Iterable<? extends ChunkGenericRO<?, ?, ?, ?, ?>> chunks) {
|
||||
boolean[] hasPresent = new boolean[] { false };
|
||||
|
||||
chunks.forEach(c -> {
|
||||
@ -234,11 +234,11 @@ public interface ChunkSet extends Iterable<Vec3i> {
|
||||
return hasPresent[0];
|
||||
}
|
||||
|
||||
default void addAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?, ?>> chunks) {
|
||||
default void addAllChunks(Iterable<? extends ChunkGenericRO<?, ?, ?, ?, ?>> chunks) {
|
||||
chunks.forEach(this::add);
|
||||
}
|
||||
|
||||
default void removeAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?, ?>> chunks) {
|
||||
default void removeAllChunks(Iterable<? extends ChunkGenericRO<?, ?, ?, ?, ?>> chunks) {
|
||||
chunks.forEach(this::remove);
|
||||
}
|
||||
|
||||
|
@ -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 <C extends GenericChunk<?, ?, ?, ?, C>> void forEachIn(
|
||||
GenericWorld<?, ?, ?, ?, C, ?> world,
|
||||
public <C extends ChunkGenericRO<?, ?, ?, ?, C>> void forEachIn(
|
||||
WorldGenericRO<?, ?, ?, ?, C, ?> world,
|
||||
Consumer<? super C> action
|
||||
) {
|
||||
synchronized (mutex) {
|
||||
@ -320,28 +320,28 @@ public class ChunkSets {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?, ?>> chunks) {
|
||||
public boolean containsAllChunks(Iterable<? extends ChunkGenericRO<?, ?, ?, ?, ?>> chunks) {
|
||||
synchronized (mutex) {
|
||||
return parent.containsAllChunks(chunks);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAnyChunks(Iterable<? extends GenericChunk<?, ?, ?, ?, ?>> chunks) {
|
||||
public boolean containsAnyChunks(Iterable<? extends ChunkGenericRO<?, ?, ?, ?, ?>> chunks) {
|
||||
synchronized (mutex) {
|
||||
return parent.containsAnyChunks(chunks);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?, ?>> chunks) {
|
||||
public void addAllChunks(Iterable<? extends ChunkGenericRO<?, ?, ?, ?, ?>> chunks) {
|
||||
synchronized (mutex) {
|
||||
parent.addAllChunks(chunks);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?, ?>> chunks) {
|
||||
public void removeAllChunks(Iterable<? extends ChunkGenericRO<?, ?, ?, ?, ?>> chunks) {
|
||||
synchronized (mutex) {
|
||||
parent.removeAllChunks(chunks);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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<Vec3i> test) {
|
||||
static boolean testBiC(Vec3i blockInWorld, ChunkGenericRO<?, ?, ?, ?, ?> chunk, Predicate<Vec3i> 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
|
||||
);
|
||||
}
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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 <B, T, TS, TR, C>,
|
||||
TR extends GenericTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericWritableChunk <B, T, TS, TR, C>
|
||||
>
|
||||
extends GenericChunk<B, T, TS, TR, C> {
|
||||
// @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);
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package ru.windcorp.progressia.common.world.generic;
|
||||
|
||||
public interface GenericTile {
|
||||
public interface TileGeneric {
|
||||
|
||||
String getId();
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ru.windcorp.progressia.common.world.generic;
|
||||
|
||||
// @formatter:off
|
||||
public interface TileGenericReferenceRO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackRO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericRO <B, T, TS, TR, C>
|
||||
> {
|
||||
// @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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericChunk <B, T, TS, TR, C>
|
||||
public interface TileGenericReferenceWO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackWO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericWO <B, T, TS, TR, C>
|
||||
> {
|
||||
// @formatter:on
|
||||
|
||||
T get();
|
||||
|
||||
int getIndex();
|
||||
|
||||
TS getStack();
|
||||
|
||||
default boolean isValid() {
|
||||
return get() != null;
|
||||
}
|
||||
// currently empty
|
||||
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericChunk <B, T, TS, TR, C>
|
||||
> extends AbstractList<T> implements RandomAccess {
|
||||
public interface TileGenericStackRO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackRO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericRO <B, T, TS, TR, C>
|
||||
> extends List<T>, RandomAccess {
|
||||
// @formatter:on
|
||||
|
||||
public static interface TSConsumer<T> {
|
||||
@ -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<T> action) {
|
||||
default void forEach(TSConsumer<T> 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<? super T> action) {
|
||||
default void forEach(Consumer<? super T> 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));
|
||||
}
|
||||
|
@ -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<B, T, TS, TR, C>,
|
||||
TR extends GenericTileReference<B, T, TS, TR, C>,
|
||||
C extends GenericWritableChunk<B, T, TS, TR, C>
|
||||
public interface TileGenericStackWO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackWO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericWO <B, T, TS, TR, C>
|
||||
>
|
||||
extends GenericTileStack<B, T, TS, TR, C> {
|
||||
extends List<T>, 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,20 +94,22 @@ 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}
|
||||
* at {@code index}. If the stack is {@linkplain #isFull() full}, does
|
||||
@ -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;
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
public interface WorldGenericRO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackRO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericRO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> {
|
||||
// @formatter:on
|
||||
|
||||
Collection<C> getChunks();
|
||||
Collection<? extends C> 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;
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericWritableChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
>
|
||||
extends GenericWorld<B, T, TS, TR, C, E> {
|
||||
public interface WorldGenericWO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackWO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericWO <B, T, TS, TR, C>,
|
||||
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
|
||||
*/
|
||||
<SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> change);
|
||||
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericROTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericROChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
> extends GenericROBlockContext<B, T, TS, TR, C, E> {
|
||||
public interface BlockFaceGenericContextRO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackRO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericRO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> extends WorldContexts.BlockFace, BlockGenericContextRO<B, T, TS, TR, C, E> {
|
||||
//@formatter:on
|
||||
|
||||
/**
|
||||
* Returns the face relevant to this context.
|
||||
*
|
||||
* @return the block face
|
||||
*/
|
||||
RelFace getFace();
|
||||
|
||||
/**
|
||||
* Gets the tile stack at the relevant position.
|
||||
*
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericROTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericRWChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
> extends GenericRWBlockContext<B, T, TS, TR, C, E>, GenericROBlockFaceContext<B, T, TS, TR, C, E> {
|
||||
public interface BlockFaceGenericContextWO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackWO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericWO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> extends WorldContexts.BlockFace, BlockGenericContextWO<B, T, TS, TR, C, E> {
|
||||
//@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());
|
||||
}
|
||||
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericROTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericROChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
> extends GenericROWorldContext<B, T, TS, TR, C, E> {
|
||||
public interface BlockGenericContextRO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackRO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericRO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> extends WorldContexts.Block, WorldGenericContextRO<B, T, TS, TR, C, E> {
|
||||
//@formatter:on
|
||||
|
||||
/**
|
||||
* Returns the location of the block.
|
||||
* <p>
|
||||
* The coordinate system in use is not specified, but it is consistent
|
||||
* across all methods of this context.
|
||||
* <p>
|
||||
* 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.
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericROTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericRWChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
> extends GenericRWWorldContext<B, T, TS, TR, C, E>, GenericROBlockContext<B, T, TS, TR, C, E> {
|
||||
public interface BlockGenericContextWO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackWO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericWO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> extends WorldContexts.Block, WorldGenericContextWO<B, T, TS, TR, C, E> {
|
||||
//@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());
|
||||
}
|
||||
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericROTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericROChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
> extends GenericROBlockFaceContext<B, T, TS, TR, C, E> {
|
||||
public interface TileGenericContextRO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackRO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericRO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> extends WorldContexts.Tile, BlockFaceGenericContextRO<B, T, TS, TR, C, E> {
|
||||
//@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());
|
||||
}
|
||||
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericROTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericRWChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
> extends GenericRWBlockFaceContext<B, T, TS, TR, C, E>, GenericROTileContext<B, T, TS, TR, C, E> {
|
||||
public interface TileGenericContextWO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackWO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericWO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> extends WorldContexts.Tile, BlockFaceGenericContextWO<B, T, TS, TR, C, E> {
|
||||
//@formatter:on
|
||||
|
||||
/**
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* The coordinate system in use is not specified, but it is consistent across
|
||||
* all methods of this context.
|
||||
* <p>
|
||||
* 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() {
|
||||
}
|
||||
|
||||
}
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericROTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericROChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
> extends Context, GenericROWorld<B, T, TS, TR, C, E> {
|
||||
public interface WorldGenericContextRO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackRO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericRO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> extends WorldContexts.World, WorldGenericRO<B, T, TS, TR, C, E> {
|
||||
// @formatter:on
|
||||
|
||||
// currently empty
|
@ -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 <B, T, TS, TR, C>,
|
||||
TR extends GenericROTileReference <B, T, TS, TR, C>,
|
||||
C extends GenericRWChunk <B, T, TS, TR, C>,
|
||||
E extends GenericEntity
|
||||
> extends GenericROWorldContext<B, T, TS, TR, C, E>, GenericRWWorld<B, T, TS, TR, C, E> {
|
||||
public interface WorldGenericContextWO<
|
||||
B extends BlockGeneric,
|
||||
T extends TileGeneric,
|
||||
TS extends TileGenericStackWO <B, T, TS, TR, C>,
|
||||
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
|
||||
C extends ChunkGenericWO <B, T, TS, TR, C>,
|
||||
E extends EntityGeneric
|
||||
> extends WorldContexts.World, WorldGenericWO<B, T, TS, TR, C, E> {
|
||||
// @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
|
||||
<SE extends StatefulObject & GenericEntity> void changeEntity(SE entity, StateChange<SE> change);
|
||||
<SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> change);
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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<ChunkCodec> CODECS_BY_ID = new TByteObjectHashMap<>();
|
||||
private static final List<ChunkCodec> 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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<BlockData, TileData, TileDataStack, TileDataReference, ChunkData> {
|
||||
|
||||
}
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
public class ChunkLogic implements ChunkGenericRO<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
|
||||
private final WorldLogic world;
|
||||
private final ChunkData data;
|
||||
private final DefaultChunkData data;
|
||||
|
||||
private final Collection<Vec3i> tickingBlocks = new ArrayList<>();
|
||||
private final Collection<TileDataReference> tickingTiles = new ArrayList<>();
|
||||
@ -58,7 +58,7 @@ public class ChunkLogic implements GenericChunk<BlockLogic, TileLogic, TileLogic
|
||||
private final Map<TileDataStack, TileLogicStackImpl> 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<BlockLogic, TileLogic, TileLogic
|
||||
return world;
|
||||
}
|
||||
|
||||
public ChunkData getData() {
|
||||
public DefaultChunkData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ package ru.windcorp.progressia.server.world;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
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.generic.GenericChunks;
|
||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||
import ru.windcorp.progressia.server.world.block.BlockTickContext;
|
||||
@ -34,7 +34,7 @@ public interface ChunkTickContext extends TickContext {
|
||||
return getWorld().getChunk(getChunk());
|
||||
}
|
||||
|
||||
default ChunkData getChunkData() {
|
||||
default DefaultChunkData getChunkData() {
|
||||
ChunkLogic chunkLogic = getChunkLogic();
|
||||
return chunkLogic == null ? null : chunkLogic.getData();
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ package ru.windcorp.progressia.server.world;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
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.tasks.WorldAccessor;
|
||||
|
||||
@ -42,7 +42,7 @@ public interface TickContext {
|
||||
return getServer().getAdHocRandom();
|
||||
}
|
||||
|
||||
default WorldData getWorldData() {
|
||||
default DefaultWorldData getWorldData() {
|
||||
return getWorld().getData();
|
||||
}
|
||||
|
||||
|
@ -23,13 +23,13 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
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.GenericTileStack;
|
||||
import ru.windcorp.progressia.common.world.generic.TileGenericStackRO;
|
||||
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.Server;
|
||||
import ru.windcorp.progressia.server.world.block.BlockTickContext;
|
||||
import ru.windcorp.progressia.server.world.tile.TSTickContext;
|
||||
@ -109,9 +109,9 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont
|
||||
|
||||
Block withBlock(Vec3i blockInWorld);
|
||||
|
||||
TileStack withTS(GenericTileStack<?, ?, ?, ?, ?> 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) {
|
||||
|
@ -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,
|
||||
|
@ -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<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic, EntityData
|
||||
implements WorldGenericRO<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic, EntityData
|
||||
// not using EntityLogic because it is stateless
|
||||
> {
|
||||
|
||||
private final WorldData data;
|
||||
private final DefaultWorldData data;
|
||||
private final Server server;
|
||||
|
||||
private final WorldGenerator generator;
|
||||
|
||||
private final Map<ChunkData, ChunkLogic> chunks = new HashMap<>();
|
||||
private final Map<DefaultChunkData, ChunkLogic> 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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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<H> 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<H> extends WorldGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldData getWorldData() {
|
||||
public DefaultWorldData getWorldData() {
|
||||
return server.getWorld().getData();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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<Consumer<Server>> randomTickMethods;
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
extends TileGenericReferenceRO<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
|
||||
}
|
||||
|
@ -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<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
extends AbstractList<TileLogic>
|
||||
implements TileGenericStackRO<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
|
||||
public abstract TileDataStack getData();
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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<BlockData> blockPalette = createBlockPalette(chunk);
|
||||
Palette<TileData> tilePalette = createTilePalette(chunk);
|
||||
|
||||
@ -168,13 +168,13 @@ public class TestChunkCodec extends ChunkCodec {
|
||||
writeTiles(chunk, tilePalette, output);
|
||||
}
|
||||
|
||||
private Palette<BlockData> createBlockPalette(ChunkData chunk) {
|
||||
private Palette<BlockData> createBlockPalette(DefaultChunkData chunk) {
|
||||
Palette<BlockData> blockPalette = new Palette<>();
|
||||
GenericChunks.forEachBiC(v -> blockPalette.add(chunk.getBlock(v)));
|
||||
return blockPalette;
|
||||
}
|
||||
|
||||
private Palette<TileData> createTilePalette(ChunkData chunk) {
|
||||
private Palette<TileData> createTilePalette(DefaultChunkData chunk) {
|
||||
Palette<TileData> 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<BlockData> blockPalette, DataOutput output) throws IOException {
|
||||
private void writeBlocks(DefaultChunkData chunk, Palette<BlockData> 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<TileData> tilePalette, DataOutput output) throws IOException {
|
||||
private void writeTiles(DefaultChunkData chunk, Palette<TileData> tilePalette, DataOutput output) throws IOException {
|
||||
Vec3i bic = new Vec3i();
|
||||
|
||||
try {
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user