A change to the class hierarchy of WorldLogic similar to prev commit
- Renamed ChunkLogic -> DefaultChunkLogic, WorldLogic -> DefaultWorldLogic - Created/rewritten TileLogicReference{,RO}, TileLogicStack{,RO}, ChunkLogic{,RO} - Drafted up something for ServerWorldContext & friends, WIP (see commit 9a32660 for more details)
This commit is contained in:
parent
9a326603cd
commit
a338a00f1d
@ -4,11 +4,9 @@ import ru.windcorp.progressia.common.world.block.BlockData;
|
||||
import ru.windcorp.progressia.common.world.generic.ChunkGenericWO;
|
||||
import ru.windcorp.progressia.common.world.tile.TileData;
|
||||
|
||||
public interface ChunkData extends ChunkDataRO, ChunkGenericWO<BlockData, TileData, TileDataStack, TileDataReference, ChunkData> {
|
||||
public interface ChunkData
|
||||
extends ChunkDataRO, ChunkGenericWO<BlockData, TileData, TileDataStack, TileDataReference, ChunkData> {
|
||||
|
||||
// @Override
|
||||
// default TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) {
|
||||
// return null;
|
||||
// }
|
||||
// currently empty
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,10 @@ import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.common.world.tile.TileData;
|
||||
import ru.windcorp.progressia.common.world.tile.TileStackIsFullException;
|
||||
|
||||
/**
|
||||
* The implementation of {@link ChunkData} used to store the actual game world.
|
||||
* This class should be considered an implementation detail.
|
||||
*/
|
||||
public class DefaultChunkData implements ChunkData {
|
||||
|
||||
public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE;
|
||||
@ -222,7 +226,7 @@ public class DefaultChunkData implements ChunkData {
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
this.index = 0;
|
||||
this.index = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,7 +34,7 @@ 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.DefaultChunkData ChunkData},
|
||||
* {@link ru.windcorp.progressia.client.world.ChunkRender ChunkRender} or
|
||||
* {@link ru.windcorp.progressia.server.world.ChunkLogic ChunkLogic}, but this
|
||||
* {@link ru.windcorp.progressia.server.world.DefaultChunkLogic ChunkLogic}, but this
|
||||
* interface may be implemented differently for various reasons.
|
||||
* <p>
|
||||
* A generic chunk contains {@linkplain BlockGeneric blocks} and
|
||||
|
@ -18,6 +18,16 @@
|
||||
|
||||
package ru.windcorp.progressia.common.world.generic;
|
||||
|
||||
/**
|
||||
* A reference to a single tile in a tile stack. A {@code TileReference} remains
|
||||
* valid until the tile is removed from its stack.
|
||||
* <p>
|
||||
* Tile reference objects may be reused for other tiles; {@link #isValid()} only
|
||||
* shows if there exists <em>some</em> tile that this object references; it may
|
||||
* or may not be the tile this reference was acquired for. It is the
|
||||
* responsibility of the programmer to discard references when the tile is
|
||||
* removed.
|
||||
*/
|
||||
// @formatter:off
|
||||
public interface TileGenericReferenceRO<
|
||||
B extends BlockGeneric,
|
||||
@ -28,16 +38,49 @@ public interface TileGenericReferenceRO<
|
||||
> {
|
||||
// @formatter:on
|
||||
|
||||
T get();
|
||||
|
||||
/**
|
||||
* Gets the index that the referenced tile currently occupies. This value
|
||||
* may change as tiles are added to or removed from the stack.
|
||||
*
|
||||
* @return the index of the tile or {@code -1} if this reference is invalid
|
||||
*/
|
||||
int getIndex();
|
||||
|
||||
/**
|
||||
* Gets the tile stack that contains the referenced tile.
|
||||
*
|
||||
* @return the tile stack of the relevant tile or {@code null} if this
|
||||
* reference is invalid.
|
||||
*/
|
||||
TS getStack();
|
||||
|
||||
/**
|
||||
* Gets the tile that this object references.
|
||||
*
|
||||
* @return the relevant tile or {@code null} if this reference is invalid
|
||||
*/
|
||||
default T get() {
|
||||
return getStack().get(getIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this reference is valid. A reference is valid if it points
|
||||
* to <em>some</em> tile; it may or may not be the tile that this reference
|
||||
* was acquired for. (A tile reference can only change the referenced tile
|
||||
* after the previous tile is removed from the stack.)
|
||||
*
|
||||
* @return {@code true} iff there exists a tile that this reference points
|
||||
* to.
|
||||
*/
|
||||
default boolean isValid() {
|
||||
return get() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag of the referenced tile.
|
||||
*
|
||||
* @return the tag or {@code -1} iff this reference is invalid.
|
||||
*/
|
||||
default int getTag() {
|
||||
TS tileStack = getStack();
|
||||
if (tileStack == null) {
|
||||
|
@ -34,7 +34,7 @@ import ru.windcorp.progressia.server.events.ServerEvent;
|
||||
import ru.windcorp.progressia.server.management.load.ChunkRequestDaemon;
|
||||
import ru.windcorp.progressia.server.management.load.EntityRequestDaemon;
|
||||
import ru.windcorp.progressia.server.management.load.LoadManager;
|
||||
import ru.windcorp.progressia.server.world.WorldLogic;
|
||||
import ru.windcorp.progressia.server.world.DefaultWorldLogic;
|
||||
import ru.windcorp.progressia.server.world.tasks.WorldAccessor;
|
||||
import ru.windcorp.progressia.server.world.ticking.Change;
|
||||
import ru.windcorp.progressia.server.world.ticking.Evaluation;
|
||||
@ -53,7 +53,7 @@ public class Server {
|
||||
return ServerThread.getCurrentServer();
|
||||
}
|
||||
|
||||
private final WorldLogic world;
|
||||
private final DefaultWorldLogic world;
|
||||
private final WorldAccessor worldAccessor = new WorldAccessor(this);
|
||||
|
||||
private final ServerThread serverThread;
|
||||
@ -69,7 +69,7 @@ public class Server {
|
||||
private final TickingSettings tickingSettings = new TickingSettings();
|
||||
|
||||
public Server(DefaultWorldData world) {
|
||||
this.world = new WorldLogic(
|
||||
this.world = new DefaultWorldLogic(
|
||||
world,
|
||||
this,
|
||||
new TestPlanetGenerator("Test:PlanetGenerator", this, new Planet(4, 9.8f, 16f, 16f))
|
||||
@ -91,9 +91,9 @@ public class Server {
|
||||
/**
|
||||
* Returns this server's world.
|
||||
*
|
||||
* @return this server's {@link WorldLogic}
|
||||
* @return this server's {@link DefaultWorldLogic}
|
||||
*/
|
||||
public WorldLogic getWorld() {
|
||||
public DefaultWorldLogic getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
|
@ -15,230 +15,27 @@
|
||||
* 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.server.world;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.Coordinates;
|
||||
import ru.windcorp.progressia.common.world.generic.ChunkGenericRO;
|
||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||
import ru.windcorp.progressia.common.world.ChunkData;
|
||||
import ru.windcorp.progressia.common.world.rels.BlockFace;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
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;
|
||||
import ru.windcorp.progressia.server.world.tasks.TickChunk;
|
||||
import ru.windcorp.progressia.server.world.ticking.TickingPolicy;
|
||||
import ru.windcorp.progressia.server.world.tile.TickableTile;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogic;
|
||||
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 ChunkGenericRO<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
public interface ChunkLogic extends ChunkLogicRO {
|
||||
|
||||
private final WorldLogic world;
|
||||
private final DefaultChunkData data;
|
||||
/*
|
||||
* Override return type
|
||||
*/
|
||||
|
||||
private final Collection<Vec3i> tickingBlocks = new ArrayList<>();
|
||||
private final Collection<TileDataReference> tickingTiles = new ArrayList<>();
|
||||
@Override
|
||||
ChunkData getData();
|
||||
|
||||
private final TickChunk tickTask = new TickChunk(this);
|
||||
|
||||
private final Map<TileDataStack, TileLogicStackImpl> tileLogicLists = Collections
|
||||
.synchronizedMap(new WeakHashMap<>());
|
||||
|
||||
public ChunkLogic(WorldLogic world, DefaultChunkData data) {
|
||||
this.world = world;
|
||||
this.data = data;
|
||||
|
||||
tmp_generateTickLists();
|
||||
@Override
|
||||
default TileLogicStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) {
|
||||
return (TileLogicStack) ChunkLogicRO.super.getTilesOrNull(blockInChunk, face);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getPosition() {
|
||||
return getData().getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbsFace getUp() {
|
||||
return getData().getUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockLogic getBlock(Vec3i blockInChunk) {
|
||||
return BlockLogicRegistry.getInstance().get(
|
||||
getData().getBlock(blockInChunk).getId()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogicStack getTiles(Vec3i blockInChunk, BlockFace face) {
|
||||
return getTileStackWrapper(getData().getTiles(blockInChunk, face));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTiles(Vec3i blockInChunk, BlockFace face) {
|
||||
return getData().hasTiles(blockInChunk, face);
|
||||
}
|
||||
|
||||
private TileLogicStack getTileStackWrapper(TileDataStack tileDataList) {
|
||||
return tileLogicLists.computeIfAbsent(
|
||||
tileDataList,
|
||||
TileLogicStackImpl::new
|
||||
);
|
||||
}
|
||||
|
||||
public WorldLogic getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public DefaultChunkData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return getWorld().getGenerator().isChunkReady(getData().getGenerationHint());
|
||||
}
|
||||
|
||||
public boolean hasTickingBlocks() {
|
||||
return !tickingBlocks.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasTickingTiles() {
|
||||
return !tickingTiles.isEmpty();
|
||||
}
|
||||
|
||||
public void forEachTickingBlock(BiConsumer<Vec3i, BlockLogic> action) {
|
||||
tickingBlocks.forEach(blockInChunk -> {
|
||||
action.accept(blockInChunk, getBlock(blockInChunk));
|
||||
});
|
||||
}
|
||||
|
||||
public void forEachTickingTile(BiConsumer<TileDataReference, TileLogic> action) {
|
||||
tickingTiles.forEach(ref -> {
|
||||
action.accept(
|
||||
ref,
|
||||
TileLogicRegistry.getInstance().get(ref.get().getId())
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public TickChunk getTickTask() {
|
||||
return tickTask;
|
||||
}
|
||||
|
||||
private class TileLogicStackImpl extends TileLogicStack {
|
||||
private class TileLogicReferenceImpl implements TileLogicReference {
|
||||
private final TileDataReference parent;
|
||||
|
||||
public TileLogicReferenceImpl (TileDataReference parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogic get() {
|
||||
return TileLogicRegistry.getInstance().get(parent.get().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return parent.getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogicStack getStack() {
|
||||
return TileLogicStackImpl.this;
|
||||
}
|
||||
}
|
||||
|
||||
private final TileDataStack parent;
|
||||
|
||||
public TileLogicStackImpl(TileDataStack parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getBlockInChunk(Vec3i output) {
|
||||
return parent.getBlockInChunk(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkLogic getChunk() {
|
||||
return ChunkLogic.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelFace getFace() {
|
||||
return parent.getFace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogicReference getReference(int index) {
|
||||
return new TileLogicReferenceImpl(parent.getReference(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexByTag(int tag) {
|
||||
return parent.getIndexByTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTagByIndex(int index) {
|
||||
return parent.getTagByIndex(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogic get(int index) {
|
||||
return TileLogicRegistry.getInstance().get(parent.get(index).getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return parent.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileDataStack getData() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void tmp_generateTickLists() {
|
||||
ChunkTickContext context = TickContextMutable.start().withChunk(this).build();
|
||||
|
||||
context.forEachBlock(bctxt -> {
|
||||
BlockLogic block = bctxt.getBlock();
|
||||
|
||||
if (!(block instanceof TickableBlock))
|
||||
return;
|
||||
|
||||
if (((TickableBlock) block).getTickingPolicy(bctxt) == TickingPolicy.REGULAR) {
|
||||
tickingBlocks.add(Coordinates.convertInWorldToInChunk(bctxt.getBlockInWorld(), null));
|
||||
}
|
||||
|
||||
bctxt.forEachFace(fctxt -> fctxt.forEachTile(tctxt -> {
|
||||
TileLogic tile = tctxt.getTile();
|
||||
|
||||
if (!(tile instanceof TickableTile))
|
||||
return;
|
||||
|
||||
if (((TickableTile) tile).getTickingPolicy(tctxt) == TickingPolicy.REGULAR) {
|
||||
tickingTiles.add(tctxt.getReference());
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
TileLogicStack getTiles(Vec3i blockInChunk, BlockFace face);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package ru.windcorp.progressia.server.world;
|
||||
|
||||
import ru.windcorp.progressia.common.world.ChunkDataRO;
|
||||
import ru.windcorp.progressia.common.world.generic.ChunkGenericRO;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogic;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogic;
|
||||
|
||||
public interface ChunkLogicRO
|
||||
extends ChunkGenericRO<BlockLogic, TileLogic, TileLogicStackRO, TileLogicReferenceRO, ChunkLogicRO> {
|
||||
|
||||
ChunkDataRO getData();
|
||||
|
||||
boolean isReady();
|
||||
|
||||
}
|
@ -30,12 +30,12 @@ public interface ChunkTickContext extends TickContext {
|
||||
|
||||
Vec3i getChunk();
|
||||
|
||||
default ChunkLogic getChunkLogic() {
|
||||
default DefaultChunkLogic getChunkLogic() {
|
||||
return getWorld().getChunk(getChunk());
|
||||
}
|
||||
|
||||
default DefaultChunkData getChunkData() {
|
||||
ChunkLogic chunkLogic = getChunkLogic();
|
||||
DefaultChunkLogic chunkLogic = getChunkLogic();
|
||||
return chunkLogic == null ? null : chunkLogic.getData();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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.server.world;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.Coordinates;
|
||||
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.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;
|
||||
import ru.windcorp.progressia.server.world.tasks.TickChunk;
|
||||
import ru.windcorp.progressia.server.world.ticking.TickingPolicy;
|
||||
import ru.windcorp.progressia.server.world.tile.TickableTile;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogic;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogicRegistry;
|
||||
|
||||
public class DefaultChunkLogic implements ChunkLogic {
|
||||
|
||||
private final DefaultWorldLogic world;
|
||||
private final DefaultChunkData data;
|
||||
|
||||
private final Collection<Vec3i> tickingBlocks = new ArrayList<>();
|
||||
private final Collection<TileDataReference> tickingTiles = new ArrayList<>();
|
||||
|
||||
private final TickChunk tickTask = new TickChunk(this);
|
||||
|
||||
private final Map<TileDataStack, TileLogicStackImpl> tileLogicLists = Collections
|
||||
.synchronizedMap(new WeakHashMap<>());
|
||||
|
||||
public DefaultChunkLogic(DefaultWorldLogic world, DefaultChunkData data) {
|
||||
this.world = world;
|
||||
this.data = data;
|
||||
|
||||
tmp_generateTickLists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getPosition() {
|
||||
return getData().getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbsFace getUp() {
|
||||
return getData().getUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockLogic getBlock(Vec3i blockInChunk) {
|
||||
return BlockLogicRegistry.getInstance().get(
|
||||
getData().getBlock(blockInChunk).getId()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogicStack getTiles(Vec3i blockInChunk, BlockFace face) {
|
||||
return getTileStackWrapper(getData().getTiles(blockInChunk, face));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTiles(Vec3i blockInChunk, BlockFace face) {
|
||||
return getData().hasTiles(blockInChunk, face);
|
||||
}
|
||||
|
||||
private TileLogicStack getTileStackWrapper(TileDataStack tileDataList) {
|
||||
return tileLogicLists.computeIfAbsent(
|
||||
tileDataList,
|
||||
TileLogicStackImpl::new
|
||||
);
|
||||
}
|
||||
|
||||
public DefaultWorldLogic getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultChunkData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return getWorld().getGenerator().isChunkReady(getData().getGenerationHint());
|
||||
}
|
||||
|
||||
public boolean hasTickingBlocks() {
|
||||
return !tickingBlocks.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasTickingTiles() {
|
||||
return !tickingTiles.isEmpty();
|
||||
}
|
||||
|
||||
public void forEachTickingBlock(BiConsumer<Vec3i, BlockLogic> action) {
|
||||
tickingBlocks.forEach(blockInChunk -> {
|
||||
action.accept(blockInChunk, getBlock(blockInChunk));
|
||||
});
|
||||
}
|
||||
|
||||
public void forEachTickingTile(BiConsumer<TileDataReference, TileLogic> action) {
|
||||
tickingTiles.forEach(ref -> {
|
||||
action.accept(
|
||||
ref,
|
||||
TileLogicRegistry.getInstance().get(ref.get().getId())
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public TickChunk getTickTask() {
|
||||
return tickTask;
|
||||
}
|
||||
|
||||
private class TileLogicStackImpl extends AbstractList<TileLogic> implements TileLogicStack {
|
||||
private class TileLogicReferenceImpl implements TileLogicReference {
|
||||
private final TileDataReference parent;
|
||||
|
||||
public TileLogicReferenceImpl (TileDataReference parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileDataReference getDataReference() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogic get() {
|
||||
return TileLogicRegistry.getInstance().get(parent.get().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return parent.getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogicStack getStack() {
|
||||
return TileLogicStackImpl.this;
|
||||
}
|
||||
}
|
||||
|
||||
private final TileDataStack parent;
|
||||
|
||||
public TileLogicStackImpl(TileDataStack parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getBlockInChunk(Vec3i output) {
|
||||
return parent.getBlockInChunk(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultChunkLogic getChunk() {
|
||||
return DefaultChunkLogic.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelFace getFace() {
|
||||
return parent.getFace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogicReference getReference(int index) {
|
||||
return new TileLogicReferenceImpl(parent.getReference(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexByTag(int tag) {
|
||||
return parent.getIndexByTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTagByIndex(int index) {
|
||||
return parent.getTagByIndex(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileLogic get(int index) {
|
||||
return TileLogicRegistry.getInstance().get(parent.get(index).getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return parent.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileDataStack getData() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void tmp_generateTickLists() {
|
||||
ChunkTickContext context = TickContextMutable.start().withChunk(this).build();
|
||||
|
||||
context.forEachBlock(bctxt -> {
|
||||
BlockLogic block = bctxt.getBlock();
|
||||
|
||||
if (!(block instanceof TickableBlock))
|
||||
return;
|
||||
|
||||
if (((TickableBlock) block).getTickingPolicy(bctxt) == TickingPolicy.REGULAR) {
|
||||
tickingBlocks.add(Coordinates.convertInWorldToInChunk(bctxt.getBlockInWorld(), null));
|
||||
}
|
||||
|
||||
bctxt.forEachFace(fctxt -> fctxt.forEachTile(tctxt -> {
|
||||
TileLogic tile = tctxt.getTile();
|
||||
|
||||
if (!(tile instanceof TickableTile))
|
||||
return;
|
||||
|
||||
if (((TickableTile) tile).getTickingPolicy(tctxt) == TickingPolicy.REGULAR) {
|
||||
tickingTiles.add(tctxt.getReference());
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.server.world;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
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.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.ChunkDataListeners;
|
||||
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.server.Server;
|
||||
import ru.windcorp.progressia.server.world.generation.WorldGenerator;
|
||||
import ru.windcorp.progressia.server.world.tasks.TickEntitiesTask;
|
||||
import ru.windcorp.progressia.server.world.ticking.Evaluation;
|
||||
|
||||
public class DefaultWorldLogic implements WorldLogic {
|
||||
|
||||
private final DefaultWorldData data;
|
||||
private final Server server;
|
||||
|
||||
private final WorldGenerator generator;
|
||||
|
||||
private final Map<DefaultChunkData, DefaultChunkLogic> chunks = new HashMap<>();
|
||||
|
||||
private final Evaluation tickEntitiesTask = new TickEntitiesTask();
|
||||
|
||||
public DefaultWorldLogic(DefaultWorldData data, Server server, WorldGenerator generator) {
|
||||
this.data = data;
|
||||
this.server = server;
|
||||
|
||||
this.generator = generator;
|
||||
data.setGravityModel(getGenerator().getGravityModel());
|
||||
|
||||
data.addListener(new WorldDataListener() {
|
||||
@Override
|
||||
public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) {
|
||||
chunks.put(chunk, new DefaultChunkLogic(DefaultWorldLogic.this, chunk));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) {
|
||||
chunks.remove(chunk);
|
||||
}
|
||||
});
|
||||
|
||||
data.addListener(ChunkDataListeners.createAdder(new UpdateTriggerer(server)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultChunkLogic getChunk(Vec3i pos) {
|
||||
return chunks.get(getData().getChunk(pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<DefaultChunkLogic> getChunks() {
|
||||
return chunks.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EntityData> getEntities() {
|
||||
return getData().getEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityData getEntity(long entityId) {
|
||||
return getData().getEntity(entityId);
|
||||
}
|
||||
|
||||
public Evaluation getTickEntitiesTask() {
|
||||
return tickEntitiesTask;
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public DefaultWorldData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public WorldGenerator getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
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)",
|
||||
getGenerator(),
|
||||
chunk.getX(), chunk.getY(), chunk.getZ(),
|
||||
chunkPos.x, chunkPos.y, chunkPos.z
|
||||
);
|
||||
}
|
||||
|
||||
if (getData().getChunk(chunk.getPosition()) != chunk) {
|
||||
if (isChunkLoaded(chunkPos)) {
|
||||
throw CrashReports.report(null, "Generator %s has returned a chunk different to the chunk that is located at (%d; %d; %d)",
|
||||
getGenerator(),
|
||||
chunkPos.x, chunkPos.y, chunkPos.z
|
||||
);
|
||||
} else {
|
||||
throw CrashReports.report(null, "Generator %s has returned a chunk that is not loaded when requested to generate a chunk at (%d; %d; %d)",
|
||||
getGenerator(),
|
||||
chunkPos.x, chunkPos.y, chunkPos.z
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!getChunk(chunk).isReady()) {
|
||||
throw CrashReports.report(null, "Generator %s has returned a chunk that is not ready when requested to generate a chunk at (%d; %d; %d)",
|
||||
getGenerator(),
|
||||
chunkPos.x, chunkPos.y, chunkPos.z
|
||||
);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public DefaultChunkLogic getChunk(DefaultChunkData chunkData) {
|
||||
return chunks.get(chunkData);
|
||||
}
|
||||
|
||||
}
|
@ -44,7 +44,7 @@ public class TickAndUpdateUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void tickBlock(WorldLogic world, Vec3i blockInWorld) {
|
||||
public static void tickBlock(DefaultWorldLogic world, Vec3i blockInWorld) {
|
||||
BlockLogic block = world.getBlock(blockInWorld);
|
||||
if (!(block instanceof TickableBlock))
|
||||
return; // also checks nulls
|
||||
@ -61,7 +61,7 @@ public class TickAndUpdateUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void tickTile(WorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) {
|
||||
public static void tickTile(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) {
|
||||
TileLogic tile = world.getTile(blockInWorld, face, layer);
|
||||
if (!(tile instanceof TickableTile)) {
|
||||
return;
|
||||
@ -72,7 +72,7 @@ public class TickAndUpdateUtil {
|
||||
tickTile((TickableTile) tile, tickContext);
|
||||
}
|
||||
|
||||
public static void tickTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) {
|
||||
public static void tickTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) {
|
||||
if (!world.isBlockLoaded(blockInWorld)) {
|
||||
return;
|
||||
}
|
||||
@ -94,7 +94,7 @@ public class TickAndUpdateUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateBlock(WorldLogic world, Vec3i blockInWorld) {
|
||||
public static void updateBlock(DefaultWorldLogic world, Vec3i blockInWorld) {
|
||||
BlockLogic block = world.getBlock(blockInWorld);
|
||||
if (!(block instanceof UpdateableBlock))
|
||||
return; // also checks nulls
|
||||
@ -111,7 +111,7 @@ public class TickAndUpdateUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateTile(WorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) {
|
||||
public static void updateTile(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) {
|
||||
TileLogic tile = world.getTile(blockInWorld, face, layer);
|
||||
if (!(tile instanceof UpdateableTile)) {
|
||||
return;
|
||||
@ -122,7 +122,7 @@ public class TickAndUpdateUtil {
|
||||
updateTile((UpdateableTile) tile, tickContext);
|
||||
}
|
||||
|
||||
public static void updateTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) {
|
||||
public static void updateTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) {
|
||||
if (!world.isBlockLoaded(blockInWorld)) {
|
||||
return;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public interface TickContext {
|
||||
|
||||
Server getServer();
|
||||
|
||||
default WorldLogic getWorld() {
|
||||
default DefaultWorldLogic getWorld() {
|
||||
return getServer().getWorld();
|
||||
}
|
||||
|
||||
|
@ -93,12 +93,12 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont
|
||||
public static interface Empty /* does not extend Builder */ {
|
||||
World withServer(Server server);
|
||||
|
||||
default Builder.World withWorld(WorldLogic world) {
|
||||
default Builder.World withWorld(DefaultWorldLogic world) {
|
||||
Objects.requireNonNull(world, "world");
|
||||
return withServer(world.getServer());
|
||||
}
|
||||
|
||||
default Builder.Chunk withChunk(ChunkLogic chunk) {
|
||||
default Builder.Chunk withChunk(DefaultChunkLogic chunk) {
|
||||
Objects.requireNonNull(chunk, "chunk");
|
||||
return withWorld(chunk.getWorld()).withChunk(chunk.getPosition());
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.server.world;
|
||||
|
||||
import ru.windcorp.progressia.common.world.TileDataReference;
|
||||
import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO;
|
||||
import ru.windcorp.progressia.common.world.tile.TileData;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogic;
|
||||
|
||||
/**
|
||||
* A read-only {@link TileGenericReferenceRO TileReference} for a
|
||||
* {@link TileData} that provides convenient read-write access to the matching
|
||||
* {@link TileLogic} instance.
|
||||
* <p>
|
||||
* For all methods other than {@link #get()}, {@link #getStack()} and
|
||||
* {@link #getDataReference()},
|
||||
* <tt>logicRef.<i>method</i>() == logicRef.getDataReference().<i>method</i>()</tt>.
|
||||
*/
|
||||
public interface TileLogicReference
|
||||
extends TileLogicReferenceRO {
|
||||
|
||||
/*
|
||||
* Override return type
|
||||
*/
|
||||
|
||||
@Override
|
||||
TileDataReference getDataReference();
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.server.world;
|
||||
|
||||
import ru.windcorp.progressia.common.world.TileDataReference;
|
||||
import ru.windcorp.progressia.common.world.TileDataReferenceRO;
|
||||
import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO;
|
||||
import ru.windcorp.progressia.common.world.tile.TileData;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogic;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogic;
|
||||
|
||||
/**
|
||||
* A {@link TileGenericReferenceRO TileReference} for a {@link TileData} that
|
||||
* provides convenient access to the matching {@link TileLogic} instance.
|
||||
* <p>
|
||||
* For all methods other than {@link #get()}, {@link #getStack()} and
|
||||
* {@link #getDataReference()},
|
||||
* <tt>logicRef.<i>method</i>() == logicRef.getDataReference().<i>method</i>()</tt>.
|
||||
*/
|
||||
public interface TileLogicReferenceRO
|
||||
extends TileGenericReferenceRO<BlockLogic, TileLogic, TileLogicStackRO, TileLogicReferenceRO, ChunkLogicRO> {
|
||||
|
||||
/**
|
||||
* Returns a reference to the {@link TileData} that this object references.
|
||||
*
|
||||
* @return a {@link TileDataReference} equivalent to this object
|
||||
*/
|
||||
TileDataReferenceRO getDataReference();
|
||||
|
||||
/**
|
||||
* Returns the {@link TileData} that is referenced by this object, or
|
||||
* {@code null} if the tile does not exist.
|
||||
*
|
||||
* @return the relevant {@link TileData}
|
||||
*/
|
||||
default TileData getData() {
|
||||
return getDataReference().get();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see #getData()
|
||||
*/
|
||||
@Override
|
||||
TileLogic get();
|
||||
|
||||
/*
|
||||
* Refer to #getDataReference() by default
|
||||
*/
|
||||
|
||||
@Override
|
||||
default int getIndex() {
|
||||
return getDataReference().getIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getTag() {
|
||||
return getDataReference().getTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isValid() {
|
||||
return getDataReference().isValid();
|
||||
}
|
||||
|
||||
}
|
@ -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.server.world;
|
||||
|
||||
import ru.windcorp.progressia.common.world.TileDataStack;
|
||||
|
||||
public interface TileLogicStack extends TileLogicStackRO {
|
||||
|
||||
/*
|
||||
* Override return types
|
||||
*/
|
||||
|
||||
@Override
|
||||
TileDataStack getData();
|
||||
|
||||
@Override
|
||||
ChunkLogic getChunk();
|
||||
|
||||
@Override
|
||||
TileLogicReference getReference(int index);
|
||||
|
||||
}
|
@ -16,19 +16,16 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ru.windcorp.progressia.server.world.tile;
|
||||
package ru.windcorp.progressia.server.world;
|
||||
|
||||
import java.util.AbstractList;
|
||||
|
||||
import ru.windcorp.progressia.common.world.TileDataStack;
|
||||
import ru.windcorp.progressia.common.world.TileDataStackRO;
|
||||
import ru.windcorp.progressia.common.world.generic.TileGenericStackRO;
|
||||
import ru.windcorp.progressia.server.world.ChunkLogic;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogic;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogic;
|
||||
|
||||
public abstract class TileLogicStack
|
||||
extends AbstractList<TileLogic>
|
||||
implements TileGenericStackRO<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
public interface TileLogicStackRO
|
||||
extends TileGenericStackRO<BlockLogic, TileLogic, TileLogicStackRO, TileLogicReferenceRO, ChunkLogicRO> {
|
||||
|
||||
public abstract TileDataStack getData();
|
||||
public abstract TileDataStackRO getData();
|
||||
|
||||
}
|
@ -15,140 +15,38 @@
|
||||
* 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.server.world;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
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.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.ChunkDataListeners;
|
||||
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.WorldGenericRO;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogic;
|
||||
import ru.windcorp.progressia.server.world.generation.WorldGenerator;
|
||||
import ru.windcorp.progressia.server.world.tasks.TickEntitiesTask;
|
||||
import ru.windcorp.progressia.server.world.ticking.Evaluation;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogic;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogicReference;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogicStack;
|
||||
import ru.windcorp.progressia.common.world.rels.BlockFace;
|
||||
|
||||
public class WorldLogic
|
||||
implements WorldGenericRO<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic, EntityData
|
||||
// not using EntityLogic because it is stateless
|
||||
> {
|
||||
public interface WorldLogic extends WorldLogicRO {
|
||||
|
||||
private final DefaultWorldData data;
|
||||
private final Server server;
|
||||
/*
|
||||
* Override return types
|
||||
*/
|
||||
|
||||
private final WorldGenerator generator;
|
||||
@Override
|
||||
ChunkLogic getChunk(Vec3i pos);
|
||||
|
||||
private final Map<DefaultChunkData, ChunkLogic> chunks = new HashMap<>();
|
||||
@Override
|
||||
Collection<? extends ChunkLogic> getChunks();
|
||||
|
||||
private final Evaluation tickEntitiesTask = new TickEntitiesTask();
|
||||
|
||||
public WorldLogic(DefaultWorldData data, Server server, WorldGenerator generator) {
|
||||
this.data = data;
|
||||
this.server = server;
|
||||
|
||||
this.generator = generator;
|
||||
data.setGravityModel(getGenerator().getGravityModel());
|
||||
|
||||
data.addListener(new WorldDataListener() {
|
||||
@Override
|
||||
public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) {
|
||||
chunks.put(chunk, new ChunkLogic(WorldLogic.this, chunk));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) {
|
||||
chunks.remove(chunk);
|
||||
}
|
||||
});
|
||||
|
||||
data.addListener(ChunkDataListeners.createAdder(new UpdateTriggerer(server)));
|
||||
@Override
|
||||
default ChunkLogic getChunkByBlock(Vec3i blockInWorld) {
|
||||
return (ChunkLogic) WorldLogicRO.super.getChunkByBlock(blockInWorld);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkLogic getChunk(Vec3i pos) {
|
||||
return chunks.get(getData().getChunk(pos));
|
||||
default TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face) {
|
||||
return (TileLogicStack) WorldLogicRO.super.getTiles(blockInWorld, face);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ChunkLogic> getChunks() {
|
||||
return chunks.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EntityData> getEntities() {
|
||||
return getData().getEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityData getEntity(long entityId) {
|
||||
return getData().getEntity(entityId);
|
||||
}
|
||||
|
||||
public Evaluation getTickEntitiesTask() {
|
||||
return tickEntitiesTask;
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public DefaultWorldData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public WorldGenerator getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
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)",
|
||||
getGenerator(),
|
||||
chunk.getX(), chunk.getY(), chunk.getZ(),
|
||||
chunkPos.x, chunkPos.y, chunkPos.z
|
||||
);
|
||||
}
|
||||
|
||||
if (getData().getChunk(chunk.getPosition()) != chunk) {
|
||||
if (isChunkLoaded(chunkPos)) {
|
||||
throw CrashReports.report(null, "Generator %s has returned a chunk different to the chunk that is located at (%d; %d; %d)",
|
||||
getGenerator(),
|
||||
chunkPos.x, chunkPos.y, chunkPos.z
|
||||
);
|
||||
} else {
|
||||
throw CrashReports.report(null, "Generator %s has returned a chunk that is not loaded when requested to generate a chunk at (%d; %d; %d)",
|
||||
getGenerator(),
|
||||
chunkPos.x, chunkPos.y, chunkPos.z
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!getChunk(chunk).isReady()) {
|
||||
throw CrashReports.report(null, "Generator %s has returned a chunk that is not ready when requested to generate a chunk at (%d; %d; %d)",
|
||||
getGenerator(),
|
||||
chunkPos.x, chunkPos.y, chunkPos.z
|
||||
);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public ChunkLogic getChunk(DefaultChunkData chunkData) {
|
||||
return chunks.get(chunkData);
|
||||
default TileLogicStack getTilesOrNull(Vec3i blockInWorld, BlockFace face) {
|
||||
return (TileLogicStack) WorldLogicRO.super.getTilesOrNull(blockInWorld, face);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,13 +15,14 @@
|
||||
* 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.server.world.tile;
|
||||
package ru.windcorp.progressia.server.world;
|
||||
|
||||
import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO;
|
||||
import ru.windcorp.progressia.server.world.ChunkLogic;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||
import ru.windcorp.progressia.common.world.generic.WorldGenericRO;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogic;
|
||||
import ru.windcorp.progressia.server.world.tile.TileLogic;
|
||||
|
||||
public interface TileLogicReference
|
||||
extends TileGenericReferenceRO<BlockLogic, TileLogic, TileLogicStack, TileLogicReference, ChunkLogic> {
|
||||
public interface WorldLogicRO
|
||||
extends WorldGenericRO<BlockLogic, TileLogic, TileLogicStackRO, TileLogicReferenceRO, ChunkLogicRO, EntityData> {
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.server.world.context;
|
||||
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
import ru.windcorp.progressia.server.world.WorldLogic;
|
||||
|
||||
public interface ServerWorldContext extends WorldData, ServerWorldContextRO {
|
||||
|
||||
public interface Logic extends ServerWorldContextRO.Logic, WorldLogic {
|
||||
|
||||
@Override
|
||||
ServerWorldContext data();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
ServerWorldContext.Logic logic();
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package ru.windcorp.progressia.server.world.context;
|
||||
|
||||
import ru.windcorp.progressia.common.world.WorldDataRO;
|
||||
import ru.windcorp.progressia.server.world.WorldLogicRO;
|
||||
|
||||
public interface ServerWorldContextRO extends WorldDataRO, ServerContext {
|
||||
|
||||
public interface Logic extends WorldLogicRO {
|
||||
|
||||
ServerWorldContextRO data();
|
||||
|
||||
}
|
||||
|
||||
ServerWorldContextRO.Logic logic();
|
||||
|
||||
}
|
@ -29,7 +29,7 @@ import ru.windcorp.progressia.common.world.GravityModel;
|
||||
import ru.windcorp.progressia.common.world.GravityModelRegistry;
|
||||
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.world.WorldLogic;
|
||||
import ru.windcorp.progressia.server.world.DefaultWorldLogic;
|
||||
|
||||
public abstract class AbstractWorldGenerator<H> extends WorldGenerator {
|
||||
|
||||
@ -90,7 +90,7 @@ public abstract class AbstractWorldGenerator<H> extends WorldGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldLogic getWorldLogic() {
|
||||
public DefaultWorldLogic getWorldLogic() {
|
||||
return server.getWorld();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.GravityModel;
|
||||
import ru.windcorp.progressia.common.world.DefaultWorldData;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.world.WorldLogic;
|
||||
import ru.windcorp.progressia.server.world.DefaultWorldLogic;
|
||||
|
||||
public abstract class WorldGenerator extends Namespaced {
|
||||
|
||||
@ -52,7 +52,7 @@ public abstract class WorldGenerator extends Namespaced {
|
||||
public abstract Vec3 suggestSpawnLocation();
|
||||
|
||||
public abstract Server getServer();
|
||||
public abstract WorldLogic getWorldLogic();
|
||||
public abstract DefaultWorldLogic getWorldLogic();
|
||||
public abstract DefaultWorldData getWorldData();
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import ru.windcorp.progressia.common.world.Coordinates;
|
||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.world.TickAndUpdateUtil;
|
||||
import ru.windcorp.progressia.server.world.WorldLogic;
|
||||
import ru.windcorp.progressia.server.world.DefaultWorldLogic;
|
||||
|
||||
class BlockTriggeredUpdate extends CachedEvaluation {
|
||||
|
||||
@ -39,7 +39,7 @@ class BlockTriggeredUpdate extends CachedEvaluation {
|
||||
public void evaluate(Server server) {
|
||||
Vec3i cursor = new Vec3i(blockInWorld.x, blockInWorld.y, blockInWorld.z);
|
||||
|
||||
WorldLogic world = server.getWorld();
|
||||
DefaultWorldLogic world = server.getWorld();
|
||||
|
||||
for (AbsFace face : AbsFace.getFaces()) {
|
||||
TickAndUpdateUtil.updateTiles(world, cursor, face);
|
||||
|
@ -31,7 +31,7 @@ import ru.windcorp.progressia.common.world.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||
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.DefaultChunkLogic;
|
||||
import ru.windcorp.progressia.server.world.TickContextMutable;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogic;
|
||||
import ru.windcorp.progressia.server.world.block.TickableBlock;
|
||||
@ -61,9 +61,9 @@ public class TickChunk extends Evaluation {
|
||||
this.randomTickMethods = ImmutableList.copyOf(randomTickMethods);
|
||||
}
|
||||
|
||||
private final ChunkLogic chunk;
|
||||
private final DefaultChunkLogic chunk;
|
||||
|
||||
public TickChunk(ChunkLogic chunk) {
|
||||
public TickChunk(DefaultChunkLogic chunk) {
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ import ru.windcorp.progressia.common.world.Coordinates;
|
||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.world.TickAndUpdateUtil;
|
||||
import ru.windcorp.progressia.server.world.WorldLogic;
|
||||
import ru.windcorp.progressia.server.world.DefaultWorldLogic;
|
||||
|
||||
class TileTriggeredUpdate extends CachedEvaluation {
|
||||
|
||||
@ -40,7 +40,7 @@ class TileTriggeredUpdate extends CachedEvaluation {
|
||||
public void evaluate(Server server) {
|
||||
Vec3i cursor = new Vec3i(blockInWorld.x, blockInWorld.y, blockInWorld.z);
|
||||
|
||||
WorldLogic world = server.getWorld();
|
||||
DefaultWorldLogic world = server.getWorld();
|
||||
|
||||
TickAndUpdateUtil.updateTiles(world, cursor, face); // Update facemates
|
||||
// (also self)
|
||||
|
@ -25,8 +25,9 @@ import java.util.function.Function;
|
||||
import ru.windcorp.progressia.common.world.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.common.world.TileDataStack;
|
||||
import ru.windcorp.progressia.server.world.ChunkLogic;
|
||||
import ru.windcorp.progressia.server.world.DefaultChunkLogic;
|
||||
import ru.windcorp.progressia.server.world.TickContextMutable;
|
||||
import ru.windcorp.progressia.server.world.TileLogicStackRO;
|
||||
import ru.windcorp.progressia.server.world.block.BlockTickContext;
|
||||
|
||||
public interface TSTickContext extends BlockTickContext {
|
||||
@ -41,15 +42,15 @@ public interface TSTickContext extends BlockTickContext {
|
||||
* Getters
|
||||
*/
|
||||
|
||||
default TileLogicStack getTLSOrNull() {
|
||||
ChunkLogic chunkLogic = getChunkLogic();
|
||||
default TileLogicStackRO getTLSOrNull() {
|
||||
DefaultChunkLogic chunkLogic = getChunkLogic();
|
||||
if (chunkLogic == null)
|
||||
return null;
|
||||
|
||||
return chunkLogic.getTilesOrNull(getBlockInChunk(), getFace());
|
||||
}
|
||||
|
||||
default TileLogicStack getTLS() {
|
||||
default TileLogicStackRO getTLS() {
|
||||
return getChunkLogic().getTiles(getBlockInChunk(), getFace());
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
package ru.windcorp.progressia.server.world.tile;
|
||||
|
||||
import ru.windcorp.progressia.common.world.tile.TileData;
|
||||
import ru.windcorp.progressia.server.world.TileLogicStackRO;
|
||||
import ru.windcorp.progressia.common.world.TileDataStack;
|
||||
import ru.windcorp.progressia.common.world.TileDataReference;
|
||||
|
||||
@ -40,7 +41,7 @@ public interface TileTickContext extends TSTickContext {
|
||||
*/
|
||||
|
||||
default TileLogic getTile() {
|
||||
TileLogicStack stack = getTLSOrNull();
|
||||
TileLogicStackRO stack = getTLSOrNull();
|
||||
if (stack == null)
|
||||
return null;
|
||||
return stack.get(getLayer());
|
||||
|
@ -19,7 +19,7 @@
|
||||
package ru.windcorp.progressia.test.gen;
|
||||
|
||||
import kdotjpg.opensimplex2.areagen.OpenSimplex2S;
|
||||
import ru.windcorp.progressia.server.world.WorldLogic;
|
||||
import ru.windcorp.progressia.server.world.DefaultWorldLogic;
|
||||
|
||||
class TestTerrainGenerator {
|
||||
|
||||
@ -31,7 +31,7 @@ class TestTerrainGenerator {
|
||||
private final OpenSimplex2S noise;
|
||||
private final Func2D shape;
|
||||
|
||||
public TestTerrainGenerator(TestWorldGenerator testWorldGenerator, WorldLogic world) {
|
||||
public TestTerrainGenerator(TestWorldGenerator testWorldGenerator, DefaultWorldLogic world) {
|
||||
this.noise = new OpenSimplex2S("We're getting somewhere".hashCode());
|
||||
|
||||
Func2D plainsHeight = tweak(
|
||||
|
Reference in New Issue
Block a user