Added SurfaceContexts to replace SurfaceWorld+Request. WIP
There is a problem with features when up != POS_Z
This commit is contained in:
parent
a6fd81ba1e
commit
d33b48578d
@ -47,6 +47,7 @@ import ru.windcorp.progressia.server.world.context.impl.RotatingServerContext;
|
||||
import ru.windcorp.progressia.server.world.tasks.WorldAccessor;
|
||||
import ru.windcorp.progressia.server.world.ticking.Change;
|
||||
import ru.windcorp.progressia.server.world.ticking.Evaluation;
|
||||
import ru.windcorp.progressia.server.world.ticking.TickerCoordinator;
|
||||
import ru.windcorp.progressia.test.gen.planet.Planet;
|
||||
import ru.windcorp.progressia.test.gen.planet.TestPlanetGenerator;
|
||||
|
||||
@ -232,13 +233,41 @@ public class Server {
|
||||
schedule(() -> task.accept(this));
|
||||
}
|
||||
|
||||
public void requestChange(Change change) {
|
||||
/**
|
||||
* Delayed
|
||||
*/
|
||||
public void scheduleChange(Change change) {
|
||||
serverThread.getTicker().requestChange(change);
|
||||
}
|
||||
|
||||
public void requestEvaluation(Evaluation evaluation) {
|
||||
|
||||
/**
|
||||
* Delayed
|
||||
*/
|
||||
public void scheduleEvaluation(Evaluation evaluation) {
|
||||
serverThread.getTicker().requestEvaluation(evaluation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediate if possible, otherwise delayed
|
||||
*/
|
||||
public void requestChange(Change change) {
|
||||
if (serverThread.getTicker().getPhase() == TickerCoordinator.TickPhase.SYNCHRONOUS) {
|
||||
change.affect(this);
|
||||
} else {
|
||||
serverThread.getTicker().requestChange(change);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediate if possible, otherwise delayed
|
||||
*/
|
||||
public void requestEvaluation(Evaluation evaluation) {
|
||||
if (serverThread.getTicker().getPhase() == TickerCoordinator.TickPhase.SYNCHRONOUS) {
|
||||
evaluation.evaluate(this);
|
||||
} else {
|
||||
serverThread.getTicker().requestEvaluation(evaluation);
|
||||
}
|
||||
}
|
||||
|
||||
public void subscribe(Object object) {
|
||||
eventBus.register(object);
|
||||
@ -279,20 +308,7 @@ public class Server {
|
||||
public long getUptimeTicks() {
|
||||
return this.serverThread.getTicker().getUptimeTicks();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns the {@link WorldAccessor} object for this server. Use the
|
||||
// * provided accessor to request common {@link Evaluation}s and
|
||||
// * {@link Change}s.
|
||||
// *
|
||||
// * @return a {@link WorldAccessor}
|
||||
// * @see #requestChange(Change)
|
||||
// * @see #requestEvaluation(Evaluation)
|
||||
// */
|
||||
// public WorldAccessor getWorldAccessor() {
|
||||
// return worldAccessor;
|
||||
// }
|
||||
|
||||
|
||||
public WorldAccessor getWorldAccessor___really_bad_dont_use() {
|
||||
return worldAccessor;
|
||||
}
|
||||
@ -338,8 +354,8 @@ public class Server {
|
||||
}
|
||||
|
||||
private void scheduleWorldTicks(Server server) {
|
||||
server.getWorld().getChunks().forEach(chunk -> requestEvaluation(chunk.getTickTask()));
|
||||
requestEvaluation(server.getWorld().getTickEntitiesTask());
|
||||
server.getWorld().getChunks().forEach(chunk -> scheduleEvaluation(chunk.getTickTask()));
|
||||
scheduleEvaluation(server.getWorld().getTickEntitiesTask());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,8 +23,8 @@ import java.util.Collection;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@ -47,6 +47,12 @@ import ru.windcorp.progressia.server.Server;
|
||||
* @author javapony
|
||||
*/
|
||||
public class TickerCoordinator {
|
||||
|
||||
public enum TickPhase {
|
||||
SYNCHRONOUS,
|
||||
EVALUATION,
|
||||
CHANGE
|
||||
}
|
||||
|
||||
static final int INITIAL_QUEUE_SIZE = 1024;
|
||||
|
||||
@ -77,7 +83,7 @@ public class TickerCoordinator {
|
||||
|
||||
private final AtomicInteger workingTickers = new AtomicInteger();
|
||||
|
||||
private final AtomicBoolean canChange = new AtomicBoolean(true);
|
||||
private final AtomicReference<TickPhase> phase = new AtomicReference<>(TickPhase.SYNCHRONOUS);
|
||||
|
||||
private boolean isTickStartSet = false;
|
||||
private long tickStart = -1;
|
||||
@ -96,17 +102,14 @@ public class TickerCoordinator {
|
||||
}
|
||||
|
||||
this.tickers = ImmutableList.copyOf(tickerCollection);
|
||||
this.threads = Collections2.transform(this.tickers, Ticker::getThread); // Immutable
|
||||
// because
|
||||
// it
|
||||
// is
|
||||
// a
|
||||
// view
|
||||
|
||||
// Immutable because it is a view
|
||||
this.threads = Collections2.transform(this.tickers, Ticker::getThread);
|
||||
|
||||
server.getWorld().getData().addListener(ChunkDataListeners.createAdder(new ChunkDataListener() {
|
||||
@Override
|
||||
public void onChunkChanged(DefaultChunkData chunk) {
|
||||
if (!canChange.get()) {
|
||||
if (phase.get() == TickPhase.EVALUATION) {
|
||||
throw CrashReports.report(null, "A change has been detected during evaluation phase");
|
||||
}
|
||||
}
|
||||
@ -156,8 +159,14 @@ public class TickerCoordinator {
|
||||
public long getUptimeTicks() {
|
||||
return ticks;
|
||||
}
|
||||
|
||||
public TickPhase getPhase() {
|
||||
return phase.get();
|
||||
}
|
||||
|
||||
private void onTickStart() {
|
||||
phase.set(TickPhase.EVALUATION);
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
if (isTickStartSet) {
|
||||
@ -171,6 +180,7 @@ public class TickerCoordinator {
|
||||
|
||||
private void onTickEnd() {
|
||||
ticks++;
|
||||
phase.set(TickPhase.SYNCHRONOUS);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -212,9 +222,9 @@ public class TickerCoordinator {
|
||||
}
|
||||
|
||||
private synchronized void runOnePass() throws InterruptedException {
|
||||
canChange.set(false);
|
||||
phase.set(TickPhase.EVALUATION);
|
||||
runPassStage(pendingEvaluations, "EVALUATION");
|
||||
canChange.set(true);
|
||||
phase.set(TickPhase.CHANGE);
|
||||
runPassStage(pendingChanges, "CHANGE");
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,9 @@ import ru.windcorp.progressia.common.util.VectorUtil;
|
||||
import ru.windcorp.progressia.common.world.block.BlockData;
|
||||
import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogicRegistry;
|
||||
import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature;
|
||||
import ru.windcorp.progressia.test.gen.surface.SurfaceWorld;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext;
|
||||
|
||||
public class TestBushFeature extends SurfaceTopLayerFeature {
|
||||
|
||||
@ -32,35 +32,35 @@ public class TestBushFeature extends SurfaceTopLayerFeature {
|
||||
super(id);
|
||||
}
|
||||
|
||||
private void tryToSetLeaves(SurfaceWorld world, Vec3i posSfc, BlockData leaves) {
|
||||
if (world.getBlockSfc(posSfc).getId().equals("Test:Air")) {
|
||||
world.setBlockSfc(posSfc, leaves, false);
|
||||
private void tryToSetLeaves(SurfaceWorldContext context, Vec3i location, BlockData leaves) {
|
||||
if (context.getBlock(location).getId().equals("Test:Air")) {
|
||||
context.setBlock(location, leaves);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) {
|
||||
if (request.getRandom().nextInt(10*10) > 0) return;
|
||||
protected void processTopBlock(SurfaceBlockContext context) {
|
||||
if (context.getRandom().nextInt(10*10) > 0) return;
|
||||
|
||||
Vec3i center = topBlock.add_(0, 0, 1);
|
||||
Vec3i center = context.getLocation().add_(0, 0, 1);
|
||||
|
||||
BlockData log = BlockDataRegistry.getInstance().get("Test:Log");
|
||||
BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves");
|
||||
|
||||
world.setBlockSfc(center, log, false);
|
||||
context.setBlock(center, log);
|
||||
|
||||
VectorUtil.iterateCuboidAround(center.x, center.y, center.z, 3, 3, 3, p -> {
|
||||
tryToSetLeaves(world, p, leaves);
|
||||
tryToSetLeaves(context, p, leaves);
|
||||
});
|
||||
|
||||
VectorUtil.iterateCuboidAround(center.x, center.y, center.z, 5, 5, 1, p -> {
|
||||
tryToSetLeaves(world, p, leaves);
|
||||
tryToSetLeaves(context, p, leaves);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) {
|
||||
return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP);
|
||||
protected boolean isSolid(SurfaceBlockContext context) {
|
||||
return context.logic().getBlock().isSolid(RelFace.UP);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,13 +21,11 @@ import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.common.world.tile.TileData;
|
||||
import ru.windcorp.progressia.common.world.tile.TileDataRegistry;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogicRegistry;
|
||||
import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature;
|
||||
import ru.windcorp.progressia.test.gen.surface.SurfaceWorld;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext;
|
||||
|
||||
public class TestGrassFeature extends SurfaceTopLayerFeature {
|
||||
|
||||
@ -44,8 +42,8 @@ public class TestGrassFeature extends SurfaceTopLayerFeature {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) {
|
||||
if (!WHITELIST.contains(world.getBlockSfc(topBlock).getId())) {
|
||||
protected void processTopBlock(SurfaceBlockContext context) {
|
||||
if (!WHITELIST.contains(context.getBlock().getId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -54,15 +52,19 @@ public class TestGrassFeature extends SurfaceTopLayerFeature {
|
||||
for (RelFace face : RelFace.getFaces()) {
|
||||
if (face == RelFace.DOWN) continue;
|
||||
|
||||
if (BlockLogicRegistry.getInstance().get(world.getBlockSfc(topBlock.add_(face.getRelVector())).getId()).isTransparent()) {
|
||||
world.getTilesSfc(topBlock, face).addFarthest(grass);
|
||||
if (context.pushRelative(face).logic().getBlock().isTransparent()) {
|
||||
context.pop();
|
||||
context.addTile(face, grass);
|
||||
} else {
|
||||
context.pop();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) {
|
||||
return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP);
|
||||
protected boolean isSolid(SurfaceBlockContext context) {
|
||||
return context.logic().getBlock().isSolid(RelFace.UP);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,25 +24,27 @@ import ru.windcorp.progressia.common.util.VectorUtil;
|
||||
import ru.windcorp.progressia.common.world.block.BlockData;
|
||||
import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.server.world.block.BlockLogicRegistry;
|
||||
import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature;
|
||||
import ru.windcorp.progressia.test.gen.surface.SurfaceWorld;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext;
|
||||
|
||||
public class TestTreeFeature extends SurfaceTopLayerFeature {
|
||||
|
||||
public TestTreeFeature(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
private void tryToSetLeaves(SurfaceWorld world, Vec3i posSfc, BlockData leaves) {
|
||||
if (world.getBlockSfc(posSfc).getId().equals("Test:Air")) {
|
||||
world.setBlockSfc(posSfc, leaves, false);
|
||||
|
||||
private void tryToSetLeaves(SurfaceWorldContext context, Vec3i location, BlockData leaves) {
|
||||
if (context.getBlock(location).getId().equals("Test:Air")) {
|
||||
context.setBlock(location, leaves);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void iterateSpheroid(Vec3i center, double horDiameter, double vertDiameter, Consumer<Vec3i> action) {
|
||||
VectorUtil.iterateCuboidAround(
|
||||
center.x, center.y, center.z,
|
||||
center.x,
|
||||
center.y,
|
||||
center.z,
|
||||
(int) Math.ceil(horDiameter) / 2 * 2 + 5,
|
||||
(int) Math.ceil(horDiameter) / 2 * 2 + 5,
|
||||
(int) Math.ceil(vertDiameter) / 2 * 2 + 5,
|
||||
@ -50,54 +52,55 @@ public class TestTreeFeature extends SurfaceTopLayerFeature {
|
||||
double sx = (pos.x - center.x) / horDiameter;
|
||||
double sy = (pos.y - center.y) / horDiameter;
|
||||
double sz = (pos.z - center.z) / vertDiameter;
|
||||
|
||||
if (sx*sx + sy*sy + sz*sz <= 1) {
|
||||
|
||||
if (sx * sx + sy * sy + sz * sz <= 1) {
|
||||
action.accept(pos);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) {
|
||||
if (request.getRandom().nextInt(20*20) > 0) return;
|
||||
|
||||
Vec3i start = topBlock.add_(0, 0, 1);
|
||||
protected void processTopBlock(SurfaceBlockContext context) {
|
||||
if (context.getRandom().nextInt(20 * 20) > 0)
|
||||
return;
|
||||
|
||||
Vec3i start = context.getLocation().add_(0, 0, 1);
|
||||
|
||||
BlockData log = BlockDataRegistry.getInstance().get("Test:Log");
|
||||
BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves");
|
||||
|
||||
|
||||
Vec3i center = start.add_(0);
|
||||
|
||||
int height = request.getRandom().nextInt(3) + 5;
|
||||
|
||||
int height = context.getRandom().nextInt(3) + 5;
|
||||
for (; center.z < start.z + height; ++center.z) {
|
||||
world.setBlockSfc(center, log, false);
|
||||
context.setBlock(center, log);
|
||||
}
|
||||
|
||||
|
||||
double branchHorDistance = 0;
|
||||
|
||||
|
||||
do {
|
||||
double branchSize = 0.5 + 1 * request.getRandom().nextDouble();
|
||||
double branchHorAngle = 2 * Math.PI * request.getRandom().nextDouble();
|
||||
int branchVertOffset = -2 + request.getRandom().nextInt(3);
|
||||
|
||||
double branchSize = 0.5 + 1 * context.getRandom().nextDouble();
|
||||
double branchHorAngle = 2 * Math.PI * context.getRandom().nextDouble();
|
||||
int branchVertOffset = -2 + context.getRandom().nextInt(3);
|
||||
|
||||
Vec3i branchCenter = center.add_(
|
||||
(int) (Math.sin(branchHorAngle) * branchHorDistance),
|
||||
(int) (Math.cos(branchHorAngle) * branchHorDistance),
|
||||
branchVertOffset
|
||||
);
|
||||
|
||||
|
||||
iterateSpheroid(branchCenter, 1.75 * branchSize, 2.5 * branchSize, p -> {
|
||||
tryToSetLeaves(world, p, leaves);
|
||||
tryToSetLeaves(context, p, leaves);
|
||||
});
|
||||
|
||||
branchHorDistance = 1 + 2 * request.getRandom().nextDouble();
|
||||
} while (request.getRandom().nextInt(8) > 1);
|
||||
|
||||
branchHorDistance = 1 + 2 * context.getRandom().nextDouble();
|
||||
} while (context.getRandom().nextInt(8) > 1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) {
|
||||
return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP);
|
||||
protected boolean isSolid(SurfaceBlockContext context) {
|
||||
return context.logic().getBlock().isSolid(RelFace.UP);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.util.VectorUtil;
|
||||
import ru.windcorp.progressia.common.world.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.test.TestBushFeature;
|
||||
import ru.windcorp.progressia.test.TestGrassFeature;
|
||||
import ru.windcorp.progressia.test.TestTreeFeature;
|
||||
@ -57,11 +58,11 @@ public class PlanetFeatureGenerator {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void generateFeatures(DefaultChunkData chunk) {
|
||||
public void generateFeatures(Server server, DefaultChunkData chunk) {
|
||||
if (isOrdinaryChunk(chunk.getPosition())) {
|
||||
generateOrdinaryFeatures(chunk);
|
||||
generateOrdinaryFeatures(server, chunk);
|
||||
} else {
|
||||
generateBorderFeatures(chunk);
|
||||
generateBorderFeatures(server, chunk);
|
||||
}
|
||||
|
||||
chunk.setGenerationHint(true);
|
||||
@ -72,11 +73,11 @@ public class PlanetFeatureGenerator {
|
||||
return sorted.x != sorted.y;
|
||||
}
|
||||
|
||||
private void generateOrdinaryFeatures(DefaultChunkData chunk) {
|
||||
surfaceGenerators.get(chunk.getUp()).generateFeatures(chunk);
|
||||
private void generateOrdinaryFeatures(Server server, DefaultChunkData chunk) {
|
||||
surfaceGenerators.get(chunk.getUp()).generateFeatures(server, chunk);
|
||||
}
|
||||
|
||||
private void generateBorderFeatures(DefaultChunkData chunk) {
|
||||
private void generateBorderFeatures(Server server, DefaultChunkData chunk) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator<Boolean> {
|
||||
DefaultChunkData chunk = getWorldData().getChunk(chunkPos);
|
||||
|
||||
if (!isChunkReady(chunk.getGenerationHint())) {
|
||||
featureGenerator.generateFeatures(chunk);
|
||||
featureGenerator.generateFeatures(getServer(), chunk);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
|
@ -18,15 +18,13 @@
|
||||
package ru.windcorp.progressia.test.gen.surface;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import glm.Glm;
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.util.VectorUtil;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.common.world.DefaultChunkData;
|
||||
import ru.windcorp.progressia.common.world.generic.GenericChunks;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext;
|
||||
|
||||
public abstract class SurfaceFeature extends Namespaced {
|
||||
|
||||
@ -107,60 +105,6 @@ public abstract class SurfaceFeature extends Namespaced {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract void process(SurfaceWorld world, Request request);
|
||||
|
||||
/*
|
||||
* Utility methods
|
||||
*/
|
||||
|
||||
public boolean contains(Request request, Vec3i surfaceBlockInWorld) {
|
||||
Vec3i bic = Vectors.grab3i();
|
||||
bic.set(surfaceBlockInWorld.x, surfaceBlockInWorld.y, surfaceBlockInWorld.z);
|
||||
bic.sub(request.minSfc);
|
||||
boolean result = GenericChunks.containsBiC(bic);
|
||||
Vectors.release(bic);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void forEach(Request request, Consumer<? super Vec3i> action) {
|
||||
VectorUtil.iterateCuboid(
|
||||
request.minSfc.x,
|
||||
request.minSfc.y,
|
||||
request.minSfc.z,
|
||||
request.maxSfc.x + 1,
|
||||
request.maxSfc.y + 1,
|
||||
request.maxSfc.z + 1,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided vectors have z set to {@link #getMinZ()}.
|
||||
*/
|
||||
public void forEachOnFloor(Request request, Consumer<? super Vec3i> action) {
|
||||
forEachOnLayer(request, action, request.getMinZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided vectors have z set to {@link #getMaxZ()}.
|
||||
*/
|
||||
public void forEachOnCeiling(Request request, Consumer<? super Vec3i> action) {
|
||||
forEachOnLayer(request, action, request.getMaxZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided vectors have z set to layer.
|
||||
*/
|
||||
public void forEachOnLayer(Request request, Consumer<? super Vec3i> action, int layer) {
|
||||
VectorUtil.iterateCuboid(
|
||||
request.minSfc.x,
|
||||
request.minSfc.y,
|
||||
layer,
|
||||
request.maxSfc.x + 1,
|
||||
request.maxSfc.y + 1,
|
||||
layer + 1,
|
||||
action
|
||||
);
|
||||
}
|
||||
public abstract void process(SurfaceWorldContext context);
|
||||
|
||||
}
|
||||
|
@ -21,8 +21,13 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
|
||||
import glm.Glm;
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.util.CoordinatePacker;
|
||||
import ru.windcorp.progressia.common.world.DefaultChunkData;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.world.context.ServerTileContext;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceContextImpl;
|
||||
|
||||
public class SurfaceFeatureGenerator {
|
||||
|
||||
@ -42,14 +47,27 @@ public class SurfaceFeatureGenerator {
|
||||
return surface;
|
||||
}
|
||||
|
||||
public void generateFeatures(DefaultChunkData chunk) {
|
||||
SurfaceWorld world = new SurfaceWorld(surface, chunk.getWorld());
|
||||
public void generateFeatures(Server server, DefaultChunkData chunk) {
|
||||
|
||||
Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/);
|
||||
SurfaceFeature.Request request = new SurfaceFeature.Request(world, chunk, random);
|
||||
|
||||
SurfaceContextImpl context = new SurfaceContextImpl((ServerTileContext) server.createAbsoluteContext(), surface);
|
||||
context.setRandom(random);
|
||||
|
||||
Vec3i tmpA = new Vec3i();
|
||||
Vec3i tmpB = new Vec3i();
|
||||
|
||||
chunk.getMinBIW(tmpA);
|
||||
chunk.getMaxBIW(tmpB);
|
||||
|
||||
context.toContext(tmpA, tmpA);
|
||||
context.toContext(tmpB, tmpB);
|
||||
|
||||
Glm.min(tmpA, tmpB, context.getMin());
|
||||
Glm.max(tmpA, tmpB, context.getMax());
|
||||
|
||||
for (SurfaceFeature feature : features) {
|
||||
feature.process(world, request);
|
||||
feature.process(context);
|
||||
}
|
||||
|
||||
chunk.setGenerationHint(true);
|
||||
|
@ -18,41 +18,47 @@
|
||||
package ru.windcorp.progressia.test.gen.surface;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext;
|
||||
import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext;
|
||||
|
||||
public abstract class SurfaceTopLayerFeature extends SurfaceFeature {
|
||||
|
||||
|
||||
public SurfaceTopLayerFeature(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
protected abstract void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock);
|
||||
|
||||
protected abstract boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld);
|
||||
|
||||
protected abstract void processTopBlock(SurfaceBlockContext context);
|
||||
|
||||
protected abstract boolean isSolid(SurfaceBlockContext context);
|
||||
|
||||
@Override
|
||||
public void process(SurfaceWorld world, Request request) {
|
||||
Vec3i cursor = Vectors.grab3i();
|
||||
|
||||
forEachOnLayer(request, pos -> {
|
||||
|
||||
public void process(SurfaceWorldContext context) {
|
||||
Vec3i cursor = new Vec3i();
|
||||
|
||||
context.forEachOnFloor(pos -> {
|
||||
|
||||
cursor.set(pos.x, pos.y, pos.z);
|
||||
|
||||
if (!isSolid(world, cursor)) {
|
||||
|
||||
if (!isSolid(context.push(cursor))) {
|
||||
context.pop();
|
||||
return;
|
||||
}
|
||||
|
||||
for (cursor.z += 1; cursor.z <= request.getMaxZ() + 1; ++cursor.z) {
|
||||
if (!isSolid(world, cursor)) {
|
||||
cursor.z -= 1;
|
||||
processTopBlock(world, request, cursor);
|
||||
context.pop();
|
||||
|
||||
for (cursor.z += 1; cursor.z <= context.getMaxZ() + 1; ++cursor.z) {
|
||||
SurfaceBlockContext blockContext = context.push(cursor);
|
||||
|
||||
if (!isSolid(blockContext)) {
|
||||
processTopBlock(blockContext.pushRelative(0, 0, -1));
|
||||
context.pop();
|
||||
context.pop();
|
||||
return;
|
||||
}
|
||||
|
||||
context.pop();
|
||||
}
|
||||
|
||||
}, request.getMinZ());
|
||||
|
||||
Vectors.release(cursor);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.test.gen.surface.context;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.common.world.rels.RelRelation;
|
||||
import ru.windcorp.progressia.server.world.context.ServerBlockContext;
|
||||
|
||||
public interface SurfaceBlockContext extends ServerBlockContext, SurfaceWorldContext {
|
||||
|
||||
public interface Logic extends ServerBlockContext.Logic, SurfaceWorldContext.Logic {
|
||||
|
||||
@Override
|
||||
SurfaceBlockContext data();
|
||||
|
||||
@Override
|
||||
default SurfaceBlockContext.Logic pushRelative(int dx, int dy, int dz) {
|
||||
return push(getLocation().add_(dx, dy, dz));
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceBlockContext.Logic pushRelative(Vec3i direction) {
|
||||
return push(getLocation().add_(direction));
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceBlockContext.Logic pushRelative(RelRelation direction) {
|
||||
return push(getLocation().add_(direction.getRelVector()));
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileStackContext.Logic push(RelFace face) {
|
||||
return push(getLocation(), face);
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileContext.Logic push(RelFace face, int layer) {
|
||||
return push(getLocation(), face, layer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
SurfaceBlockContext.Logic logic();
|
||||
|
||||
@Override
|
||||
default SurfaceBlockContext pushRelative(int dx, int dy, int dz) {
|
||||
return push(getLocation().add_(dx, dy, dz));
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceBlockContext pushRelative(Vec3i direction) {
|
||||
return push(getLocation().add_(direction));
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceBlockContext pushRelative(RelRelation direction) {
|
||||
return push(getLocation().add_(direction.getRelVector()));
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileStackContext push(RelFace face) {
|
||||
return push(getLocation(), face);
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileContext push(RelFace face, int layer) {
|
||||
return push(getLocation(), face, layer);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.test.gen.surface.context;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.util.VectorUtil;
|
||||
import ru.windcorp.progressia.test.gen.surface.Surface;
|
||||
|
||||
public interface SurfaceContext {
|
||||
|
||||
/**
|
||||
* Returns the {@link Surface} object relevant to this context.
|
||||
*
|
||||
* @return the surface details
|
||||
*/
|
||||
Surface getSurface();
|
||||
|
||||
/**
|
||||
* Returns lower bounds (inclusive) on the coordinates of the requested
|
||||
* region.
|
||||
*
|
||||
* @return the coordinates of the minimum corner of the region that
|
||||
* should be processed
|
||||
*/
|
||||
Vec3i getMin();
|
||||
|
||||
/**
|
||||
* Returns upper bounds (inclusive) on the coordinates of the requested
|
||||
* region.
|
||||
*
|
||||
* @return the coordinates of the maximum corner of the region that
|
||||
* should be processed
|
||||
*/
|
||||
Vec3i getMax();
|
||||
|
||||
/*
|
||||
* Convenience methods
|
||||
*/
|
||||
|
||||
default int getMinX() {
|
||||
return getMin().x;
|
||||
}
|
||||
|
||||
default int getMinY() {
|
||||
return getMin().y;
|
||||
}
|
||||
|
||||
default int getMinZ() {
|
||||
return getMin().z;
|
||||
}
|
||||
|
||||
default int getMaxX() {
|
||||
return getMax().x;
|
||||
}
|
||||
|
||||
default int getMaxY() {
|
||||
return getMax().y;
|
||||
}
|
||||
|
||||
default int getMaxZ() {
|
||||
return getMax().z;
|
||||
}
|
||||
|
||||
default boolean isRequested(int x, int y, int z) {
|
||||
Vec3i min = getMin();
|
||||
Vec3i max = getMax();
|
||||
return (min.x <= x && x <= max.x) && (min.y <= y && y <= max.y) && (min.z <= z && z <= max.z);
|
||||
}
|
||||
|
||||
default boolean isRequested(Vec3i location) {
|
||||
return isRequested(location.x, location.y, location.z);
|
||||
}
|
||||
|
||||
default void forEachRequested(Consumer<? super Vec3i> action) {
|
||||
Vec3i min = getMin();
|
||||
Vec3i max = getMax();
|
||||
VectorUtil.iterateCuboid(
|
||||
min.x,
|
||||
min.y,
|
||||
min.z,
|
||||
max.x + 1,
|
||||
max.y + 1,
|
||||
max.z + 1,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided vectors have z set to {@link #getMinZ()}.
|
||||
*/
|
||||
default void forEachOnFloor(Consumer<? super Vec3i> action) {
|
||||
forEachOnLayer(action, getMinZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided vectors have z set to {@link #getMaxZ()}.
|
||||
*/
|
||||
default void forEachOnCeiling(Consumer<? super Vec3i> action) {
|
||||
forEachOnLayer(action, getMaxZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided vectors have z set to layer.
|
||||
*/
|
||||
default void forEachOnLayer(Consumer<? super Vec3i> action, int layer) {
|
||||
Vec3i min = getMin();
|
||||
Vec3i max = getMax();
|
||||
VectorUtil.iterateCuboid(
|
||||
min.x,
|
||||
min.y,
|
||||
layer,
|
||||
max.x + 1,
|
||||
max.y + 1,
|
||||
layer + 1,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.test.gen.surface.context;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.server.world.context.ServerTileContext;
|
||||
import ru.windcorp.progressia.server.world.context.impl.RotatingServerContext;
|
||||
import ru.windcorp.progressia.test.gen.surface.Surface;
|
||||
|
||||
public class SurfaceContextImpl extends RotatingServerContext implements SurfaceTileContext {
|
||||
|
||||
final Surface surface;
|
||||
final Vec3i min = new Vec3i();
|
||||
final Vec3i max = new Vec3i();
|
||||
private Random random;
|
||||
|
||||
private final SurfaceContextImplLogic logic;
|
||||
|
||||
public SurfaceContextImpl(ServerTileContext parent, Surface surface) {
|
||||
super(parent, surface.getUp());
|
||||
this.logic = new SurfaceContextImplLogic(this);
|
||||
|
||||
this.surface = surface;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transform(Vec3i userLocation, Vec3i output) {
|
||||
output.set(userLocation.x, userLocation.y, userLocation.z);
|
||||
output.z += surface.getSeaLevel();
|
||||
super.transform(output, output);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void untransform(Vec3i parentLocation, Vec3i output) {
|
||||
super.untransform(parentLocation, output);
|
||||
output.z -= surface.getSeaLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Surface getSurface() {
|
||||
return surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implNote can rw
|
||||
*/
|
||||
@Override
|
||||
public Vec3i getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implNote can rw
|
||||
*/
|
||||
@Override
|
||||
public Vec3i getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Random getRandom() {
|
||||
return random;
|
||||
}
|
||||
|
||||
public void setRandom(Random random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceContextImplLogic logic() {
|
||||
return logic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceTileContext push(Vec3i location) {
|
||||
super.push(location);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceTileContext push(Vec3i location, RelFace face) {
|
||||
super.push(location, face);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceTileContext push(Vec3i location, RelFace face, int layer) {
|
||||
super.push(location, face, layer);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.test.gen.surface.context;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.server.world.context.impl.DefaultServerContextLogic;
|
||||
import ru.windcorp.progressia.test.gen.surface.Surface;
|
||||
|
||||
public class SurfaceContextImplLogic extends DefaultServerContextLogic implements SurfaceTileContext.Logic {
|
||||
|
||||
private final SurfaceContextImpl surfaceParent;
|
||||
|
||||
public SurfaceContextImplLogic(SurfaceContextImpl surfaceParent) {
|
||||
super(surfaceParent);
|
||||
this.surfaceParent = surfaceParent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Surface getSurface() {
|
||||
return this.surfaceParent.surface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getMin() {
|
||||
return this.surfaceParent.min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getMax() {
|
||||
return this.surfaceParent.max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceContextImpl data() {
|
||||
return this.surfaceParent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceTileContext.Logic push(Vec3i location) {
|
||||
super.push(location);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceTileContext.Logic push(Vec3i location, RelFace face) {
|
||||
super.push(location, face);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceTileContext.Logic push(Vec3i location, RelFace face, int layer) {
|
||||
super.push(location, face, layer);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.test.gen.surface.context;
|
||||
|
||||
import ru.windcorp.progressia.server.world.context.ServerTileContext;
|
||||
|
||||
public interface SurfaceTileContext extends ServerTileContext, SurfaceTileStackContext {
|
||||
|
||||
public interface Logic extends ServerTileContext.Logic, SurfaceTileStackContext.Logic {
|
||||
|
||||
@Override
|
||||
SurfaceTileContext data();
|
||||
|
||||
@Override
|
||||
default SurfaceTileContext.Logic pushCloser() {
|
||||
return push(getLocation(), getFace(), getLayer() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileContext.Logic pushFarther() {
|
||||
return push(getLocation(), getFace(), getLayer() + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
SurfaceTileContext.Logic logic();
|
||||
|
||||
@Override
|
||||
default SurfaceTileContext pushCloser() {
|
||||
return push(getLocation(), getFace(), getLayer() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileContext pushFarther() {
|
||||
return push(getLocation(), getFace(), getLayer() + 1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.test.gen.surface.context;
|
||||
|
||||
import ru.windcorp.progressia.server.world.context.ServerTileStackContext;
|
||||
|
||||
public interface SurfaceTileStackContext extends ServerTileStackContext, SurfaceBlockContext {
|
||||
|
||||
public interface Logic extends ServerTileStackContext.Logic, SurfaceBlockContext.Logic {
|
||||
|
||||
@Override
|
||||
SurfaceTileStackContext data();
|
||||
|
||||
@Override
|
||||
default SurfaceTileContext.Logic push(int layer) {
|
||||
return push(getLocation(), getFace(), layer);
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileStackContext.Logic pushCounter() {
|
||||
return push(getFace().getCounter());
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileStackContext.Logic pushOpposite() {
|
||||
return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
SurfaceTileStackContext.Logic logic();
|
||||
|
||||
@Override
|
||||
default SurfaceTileContext push(int layer) {
|
||||
return push(getLocation(), getFace(), layer);
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileStackContext pushCounter() {
|
||||
return push(getFace().getCounter());
|
||||
}
|
||||
|
||||
@Override
|
||||
default SurfaceTileStackContext pushOpposite() {
|
||||
return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.test.gen.surface.context;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.rels.RelFace;
|
||||
import ru.windcorp.progressia.server.world.context.ServerWorldContext;
|
||||
|
||||
public interface SurfaceWorldContext extends ServerWorldContext, SurfaceContext {
|
||||
|
||||
public interface Logic extends ServerWorldContext.Logic, SurfaceContext {
|
||||
|
||||
@Override
|
||||
SurfaceWorldContext data();
|
||||
|
||||
@Override
|
||||
SurfaceBlockContext.Logic push(Vec3i location);
|
||||
|
||||
@Override
|
||||
SurfaceTileStackContext.Logic push(Vec3i location, RelFace face);
|
||||
|
||||
@Override
|
||||
SurfaceTileContext.Logic push(Vec3i location, RelFace face, int layer);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
SurfaceWorldContext.Logic logic();
|
||||
|
||||
@Override
|
||||
SurfaceBlockContext push(Vec3i location);
|
||||
|
||||
@Override
|
||||
SurfaceTileStackContext push(Vec3i location, RelFace face);
|
||||
|
||||
@Override
|
||||
SurfaceTileContext push(Vec3i location, RelFace face, int layer);
|
||||
|
||||
}
|
Reference in New Issue
Block a user