diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java
index 30b85ce..5cf9f44 100644
--- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java
+++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java
@@ -20,7 +20,9 @@ package ru.windcorp.progressia.common.world.generic.context;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.context.Context;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
import ru.windcorp.progressia.common.world.rels.AbsRelation;
+import ru.windcorp.progressia.common.world.rels.BlockFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
/**
@@ -81,6 +83,80 @@ class WorldContexts {
*/
Tile push(Vec3i location, RelFace face, int layer);
+ /**
+ * Converts the provided location given in the context's coordinate
+ * space to the underlying absolute coordinate space.
+ *
+ * The definition of "absolute coordinate space" for contexts that are
+ * not {@linkplain #isReal() real} may be arbitrary, but methods
+ * {@link #toAbsolute(Vec3i, Vec3i)}, {@link #toAbsolute(BlockFace)},
+ * {@link #toContext(Vec3i, Vec3i)} and {@link #toContext(AbsFace)} are
+ * guaranteed to be consistent for all contexts.
+ *
+ * @param contextLocation the location expressed in context coordinate
+ * system
+ * @param output the {@link Vec3i} object to output the result
+ * into, or {@code null}
+ * @return The location expressed in absolute coordinate system. If
+ * {@code output} is not {@code null}, {@code output} is
+ * returned; otherwise, a new {@link Vec3i} is instantiated and
+ * returned
+ */
+ Vec3i toAbsolute(Vec3i contextLocation, Vec3i output);
+
+ /**
+ * Converts the provided location given in the absolute coordinate
+ * space to the context coordinate space.
+ *
+ * The definition of "absolute coordinate space" for contexts that are
+ * not {@linkplain #isReal() real} may be arbitrary, but methods
+ * {@link #toAbsolute(Vec3i, Vec3i)}, {@link #toAbsolute(BlockFace)},
+ * {@link #toContext(Vec3i, Vec3i)} and {@link #toContext(AbsFace)} are
+ * guaranteed to be consistent for all contexts.
+ *
+ * @param contextLocation the location expressed in absolute coordinate
+ * system
+ * @param output the {@link Vec3i} object to output the result
+ * into, or {@code null}
+ * @return The location expressed in context coordinate system. If
+ * {@code output} is not {@code null}, {@code output} is
+ * returned; otherwise, a new {@link Vec3i} is instantiated and
+ * returned
+ */
+ Vec3i toContext(Vec3i absoluteLocation, Vec3i output);
+
+ /**
+ * Converts the provided face given in the context's coordinate
+ * space to the underlying absolute coordinate space.
+ *
+ * The definition of "absolute coordinate space" for contexts that are
+ * not {@linkplain #isReal() real} may be arbitrary, but methods
+ * {@link #toAbsolute(Vec3i, Vec3i)}, {@link #toAbsolute(BlockFace)},
+ * {@link #toContext(Vec3i, Vec3i)} and {@link #toContext(AbsFace)} are
+ * guaranteed to be consistent for all contexts.
+ *
+ * @param contextLocation the face expressed in context coordinate
+ * system
+ * @return the face expressed in absolute coordinate system
+ */
+ AbsFace toAbsolute(BlockFace contextFace);
+
+ /**
+ * Converts the provided face given in the absolute coordinate
+ * space to the context coordinate space.
+ *
+ * The definition of "absolute coordinate space" for contexts that are
+ * not {@linkplain #isReal() real} may be arbitrary, but methods
+ * {@link #toAbsolute(Vec3i, Vec3i)}, {@link #toAbsolute(BlockFace)},
+ * {@link #toContext(Vec3i, Vec3i)} and {@link #toContext(AbsFace)} are
+ * guaranteed to be consistent for all contexts.
+ *
+ * @param contextLocation the face expressed in absolute coordinate
+ * system
+ * @return the face expressed in context coordinate system
+ */
+ RelFace toContext(AbsFace absoluteFace);
+
}
/**
diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java
index 9be01e2..41cffef 100644
--- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java
+++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java
@@ -51,6 +51,10 @@ public abstract class PacketAffectTile extends PacketAffectChunk {
}
public void set(Vec3i blockInWorld, AbsFace face, int tag) {
+ if (tag < 0) {
+ throw new IllegalArgumentException("Cannot affect tile with tag -1");
+ }
+
this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
this.face = face;
this.tag = tag;
diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java
index 0efc551..915c262 100644
--- a/src/main/java/ru/windcorp/progressia/server/Server.java
+++ b/src/main/java/ru/windcorp/progressia/server/Server.java
@@ -24,20 +24,26 @@ import org.apache.logging.log4j.LogManager;
import com.google.common.eventbus.EventBus;
+import glm.vec._3.i.Vec3i;
import ru.windcorp.jputil.functions.ThrowingRunnable;
import ru.windcorp.progressia.common.Units;
import ru.windcorp.progressia.common.util.TaskQueue;
import ru.windcorp.progressia.common.util.crash.ReportingEventBus;
import ru.windcorp.progressia.common.world.DefaultWorldData;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
+import ru.windcorp.progressia.common.world.rels.AxisRotations;
import ru.windcorp.progressia.server.comms.ClientManager;
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.DefaultWorldLogic;
+import ru.windcorp.progressia.server.world.context.ServerBlockContext;
+import ru.windcorp.progressia.server.world.context.ServerTileContext;
import ru.windcorp.progressia.server.world.context.ServerWorldContext;
import ru.windcorp.progressia.server.world.context.impl.DefaultServerContext;
import ru.windcorp.progressia.server.world.context.impl.ReportingServerContext;
+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;
@@ -102,15 +108,54 @@ public class Server {
/**
* Instantiates and returns an new {@link ServerWorldContext} instance
- * suitable for read and write access to the server's world. This is the
- * preferred way to query or change the world.
+ * suitable for read and write access to the server's world. This context
+ * uses the absolute coordinate space (not rotated to match positive Z =
+ * up).
*
* @return the context
+ * @see #createContext(AbsFace)
*/
- public ServerWorldContext createContext() {
+ public ServerWorldContext createAbsoluteContext() {
+ return doCreateAbsoluteContext();
+ }
- return new ReportingServerContext(DefaultServerContext.empty().inRealWorldOf(this).build()).withListener(worldAccessor).setPassToParent(false);
-
+ private ServerTileContext doCreateAbsoluteContext() {
+ return new ReportingServerContext(DefaultServerContext.empty().inRealWorldOf(this).build())
+ .withListener(worldAccessor).setPassToParent(false);
+ }
+
+ /**
+ * Instantiates and returns an new {@link ServerWorldContext} instance
+ * suitable for read and write access to the server's world. This is the
+ * preferred way to query or change the world. This context uses the
+ * coordinate space in which positive Z = {@code up}.
+ *
+ * @param up the desired up direction
+ * @return the context
+ * @see #createContext(Vec3i)
+ * @see #createAbsoluteContext()
+ */
+ public ServerWorldContext createContext(AbsFace up) {
+ return new RotatingServerContext(doCreateAbsoluteContext(), up);
+ }
+
+ /**
+ * Instantiates and returns an new {@link ServerBlockContext} instance
+ * suitable for read and write access to the server's world. The context is
+ * initialized to point to the provided block. This is the preferred way to
+ * query or change the world. This context uses the coordinate space in
+ * which positive Z matches the discrete up direction of the provided
+ * location.
+ *
+ * @param up the desired up direction
+ * @return the context
+ * @see #createContext(AbsFace)
+ * @see #createAbsoluteContext()
+ */
+ public ServerBlockContext createContext(Vec3i blockInWorld) {
+ AbsFace up = getWorld().getUp(blockInWorld);
+ Vec3i relativeBlockInWorld = AxisRotations.relativize(blockInWorld, up, null);
+ return new RotatingServerContext(doCreateAbsoluteContext(), up).push(relativeBlockInWorld);
}
/**
@@ -247,7 +292,7 @@ public class Server {
// public WorldAccessor getWorldAccessor() {
// return worldAccessor;
// }
-
+
public WorldAccessor getWorldAccessor___really_bad_dont_use() {
return worldAccessor;
}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java
index 978fae3..d18ff11 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java
@@ -28,17 +28,18 @@ 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.generic.GenericChunks;
import ru.windcorp.progressia.common.world.TileDataReference;
import ru.windcorp.progressia.server.Server;
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.context.ServerBlockContextRO;
+import ru.windcorp.progressia.server.world.context.ServerContexts;
import ru.windcorp.progressia.server.world.context.ServerTileContextRO;
import ru.windcorp.progressia.server.world.context.ServerWorldContextRO;
import ru.windcorp.progressia.server.world.tasks.TickChunk;
@@ -225,15 +226,12 @@ public class DefaultChunkLogic implements ChunkLogic {
}
private void tmp_generateTickLists() {
- ServerWorldContextRO context = Server.getCurrentServer().createContext();
- Vec3i blockInChunk = new Vec3i();
+ ServerWorldContextRO context = Server.getCurrentServer().createContext(getUp());
- forEachBiW(location -> {
+ GenericChunks.forEachBiC(blockInChunk -> {
- ServerBlockContextRO blockContext = context.push(location);
-
- BlockLogic block = blockContext.logic().getBlock();
- Coordinates.convertInWorldToInChunk(location, blockInChunk);
+ ServerBlockContextRO blockContext = ServerContexts.pushAbs(context, this, blockInChunk);
+ BlockLogic block = getBlock(blockInChunk);
if (!(block instanceof TickableBlock)) {
blockContext.pop();
@@ -241,7 +239,7 @@ public class DefaultChunkLogic implements ChunkLogic {
}
if (((TickableBlock) block).getTickingPolicy(blockContext) == TickingPolicy.REGULAR) {
- tickingBlocks.add(blockInChunk);
+ tickingBlocks.add(blockInChunk.add_(0));
}
for (RelFace face : RelFace.getFaces()) {
@@ -249,16 +247,14 @@ public class DefaultChunkLogic implements ChunkLogic {
if (stack == null || stack.isEmpty()) continue;
for (int i = 0; i < stack.size(); ++i) {
- ServerTileContextRO tileContext = blockContext.push(face, i);
+ ServerTileContextRO tileContext = blockContext.push(context.toContext(face.resolve(getUp())), i);
TileLogic tile = stack.get(i);
- if (!(tile instanceof TickableTile)) {
- tileContext.pop();
- continue;
- }
-
- if (((TickableTile) tile).getTickingPolicy(tileContext) == TickingPolicy.REGULAR) {
- tickingTiles.add(stack.getData().getReference(i));
+ if (tile instanceof TickableTile) {
+ TickingPolicy policy = ((TickableTile) tile).getTickingPolicy(tileContext);
+ if (policy == TickingPolicy.REGULAR) {
+ tickingTiles.add(stack.getData().getReference(i));
+ }
}
tileContext.pop();
diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java
index 286a557..9e21c63 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java
@@ -21,12 +21,13 @@ package ru.windcorp.progressia.server.world;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.world.entity.EntityData;
-import ru.windcorp.progressia.common.world.rels.BlockFace;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.block.BlockLogic;
import ru.windcorp.progressia.server.world.block.TickableBlock;
import ru.windcorp.progressia.server.world.block.UpdateableBlock;
import ru.windcorp.progressia.server.world.context.ServerBlockContext;
+import ru.windcorp.progressia.server.world.context.ServerContexts;
import ru.windcorp.progressia.server.world.context.ServerTileContext;
import ru.windcorp.progressia.server.world.context.ServerTileStackContext;
import ru.windcorp.progressia.server.world.context.ServerWorldContext;
@@ -56,7 +57,7 @@ public class TickAndUpdateUtil {
if (!(block instanceof TickableBlock)) {
return;
}
- ServerBlockContext context = server.createContext().push(blockInWorld);
+ ServerBlockContext context = server.createContext(blockInWorld);
tickBlock(context);
}
@@ -73,23 +74,22 @@ public class TickAndUpdateUtil {
}
}
- public static void tickTile(Server server, Vec3i blockInWorld, BlockFace face, int layer) {
+ public static void tickTile(Server server, Vec3i blockInWorld, AbsFace face, int layer) {
TileLogic tile = server.getWorld().getTile(blockInWorld, face, layer);
if (!(tile instanceof TickableTile)) {
return;
}
- ServerTileContext context = server.createContext()
- .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld)), layer);
+ ServerTileContext context = ServerContexts.pushAbs(server.createContext(blockInWorld), blockInWorld, face)
+ .push(layer);
tickTile(context);
}
- public static void tickTiles(Server server, Vec3i blockInWorld, BlockFace face) {
+ public static void tickTiles(Server server, Vec3i blockInWorld, AbsFace face) {
if (!server.getWorld().hasTiles(blockInWorld, face)) {
return;
}
- ServerTileStackContext context = server.createContext()
- .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld)));
+ ServerTileStackContext context = ServerContexts.pushAbs(server.createContext(blockInWorld), blockInWorld, face);
for (int i = 0; i < context.getTileCount(); ++i) {
tickTile(context.push(i));
context.pop();
@@ -114,7 +114,7 @@ public class TickAndUpdateUtil {
if (!(block instanceof UpdateableBlock)) {
return;
}
- ServerBlockContext context = server.createContext().push(blockInWorld);
+ ServerBlockContext context = server.createContext(blockInWorld);
updateBlock(context);
}
@@ -131,23 +131,22 @@ public class TickAndUpdateUtil {
}
}
- public static void updateTile(Server server, Vec3i blockInWorld, BlockFace face, int layer) {
+ public static void updateTile(Server server, Vec3i blockInWorld, AbsFace face, int layer) {
TileLogic tile = server.getWorld().getTile(blockInWorld, face, layer);
if (!(tile instanceof UpdateableTile)) {
return;
}
- ServerTileContext context = server.createContext()
- .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld)), layer);
+ ServerTileContext context = ServerContexts.pushAbs(server.createContext(blockInWorld), blockInWorld, face)
+ .push(layer);
updateTile(context);
}
- public static void updateTiles(Server server, Vec3i blockInWorld, BlockFace face) {
+ public static void updateTiles(Server server, Vec3i blockInWorld, AbsFace face) {
if (!server.getWorld().hasTiles(blockInWorld, face)) {
return;
}
- ServerTileStackContext context = server.createContext()
- .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld)));
+ ServerTileStackContext context = ServerContexts.pushAbs(server.createContext(blockInWorld), blockInWorld, face);
for (int i = 0; i < context.getTileCount(); ++i) {
updateTile(context.push(i));
context.pop();
@@ -166,7 +165,7 @@ public class TickAndUpdateUtil {
tickEntity(
EntityLogicRegistry.getInstance().get(data.getId()),
data,
- server.createContext()
+ server.createContext(data.getUpFace())
);
}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerContexts.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContexts.java
new file mode 100644
index 0000000..b0cf996
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContexts.java
@@ -0,0 +1,141 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.server.world.context;
+
+import glm.vec._3.i.Vec3i;
+import ru.windcorp.progressia.common.util.Vectors;
+import ru.windcorp.progressia.common.world.Coordinates;
+import ru.windcorp.progressia.common.world.generic.ChunkGenericRO;
+import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
+import ru.windcorp.progressia.common.world.rels.RelFace;
+
+public class ServerContexts {
+
+ /*
+ * RW
+ */
+
+ public static ServerBlockContext pushAbs(ServerWorldContext context, Vec3i blockInWorld) {
+ Vec3i contextLocation = Vectors.grab3i();
+ context.toContext(blockInWorld, contextLocation);
+ ServerBlockContext blockContext = context.push(contextLocation);
+ Vectors.release(contextLocation);
+ return blockContext;
+ }
+
+ public static ServerBlockContext pushAbs(ServerWorldContext context, ChunkGenericRO, ?, ?, ?, ?> chunk, Vec3i blockInChunk) {
+ Vec3i contextLocation = Vectors.grab3i();
+ Coordinates.getInWorld(chunk.getPosition(), blockInChunk, contextLocation);
+ context.toContext(contextLocation, contextLocation);
+ ServerBlockContext blockContext = context.push(contextLocation);
+ Vectors.release(contextLocation);
+ return blockContext;
+ }
+
+ public static ServerTileStackContext pushAbs(ServerWorldContext context, Vec3i blockInWorld, AbsFace face) {
+ Vec3i contextLocation = Vectors.grab3i();
+ context.toContext(blockInWorld, contextLocation);
+ RelFace contextFace = context.toContext(face);
+ ServerTileStackContext tileStackContext = context.push(contextLocation, contextFace);
+ Vectors.release(contextLocation);
+ return tileStackContext;
+ }
+
+ public static ServerTileStackContext pushAbs(ServerWorldContext context, ChunkGenericRO, ?, ?, ?, ?> chunk, Vec3i blockInChunk, AbsFace face) {
+ Vec3i contextLocation = Vectors.grab3i();
+ Coordinates.getInWorld(chunk.getPosition(), blockInChunk, contextLocation);
+ context.toContext(contextLocation, contextLocation);
+ RelFace contextFace = context.toContext(face);
+ ServerTileStackContext tileStackContext = context.push(contextLocation, contextFace);
+ Vectors.release(contextLocation);
+ return tileStackContext;
+ }
+
+ public static ServerTileStackContext pushAbs(ServerBlockContext context, AbsFace face) {
+ return context.push(context.toContext(face));
+ }
+
+ public static ServerTileContext pushAbs(ServerWorldContext context, AbsFace up, TileGenericReferenceRO, ?, ?, ?, ?> ref) {
+ Vec3i contextLocation = Vectors.grab3i();
+ ref.getStack().getBlockInWorld(contextLocation);
+ context.toContext(contextLocation, contextLocation);
+ RelFace contextFace = context.toContext(ref.getStack().getFace().resolve(up));
+ ServerTileContext tileContext = context.push(contextLocation, contextFace, ref.getIndex());
+ Vectors.release(contextLocation);
+ return tileContext;
+ }
+
+ /*
+ * RO
+ */
+
+ public static ServerBlockContextRO pushAbs(ServerWorldContextRO context, Vec3i blockInWorld) {
+ Vec3i contextLocation = Vectors.grab3i();
+ context.toContext(blockInWorld, contextLocation);
+ ServerBlockContextRO blockContextRO = context.push(contextLocation);
+ Vectors.release(contextLocation);
+ return blockContextRO;
+ }
+
+ public static ServerBlockContextRO pushAbs(ServerWorldContextRO context, ChunkGenericRO, ?, ?, ?, ?> chunk, Vec3i blockInChunk) {
+ Vec3i contextLocation = Vectors.grab3i();
+ Coordinates.getInWorld(chunk.getPosition(), blockInChunk, contextLocation);
+ context.toContext(contextLocation, contextLocation);
+ ServerBlockContextRO blockContextRO = context.push(contextLocation);
+ Vectors.release(contextLocation);
+ return blockContextRO;
+ }
+
+ public static ServerTileStackContextRO pushAbs(ServerWorldContextRO context, Vec3i blockInWorld, AbsFace face) {
+ Vec3i contextLocation = Vectors.grab3i();
+ context.toContext(blockInWorld, contextLocation);
+ RelFace contextFace = context.toContext(face);
+ ServerTileStackContextRO tileStackContextRO = context.push(contextLocation, contextFace);
+ Vectors.release(contextLocation);
+ return tileStackContextRO;
+ }
+
+ public static ServerTileStackContextRO pushAbs(ServerWorldContextRO context, ChunkGenericRO, ?, ?, ?, ?> chunk, Vec3i blockInChunk, AbsFace face) {
+ Vec3i contextLocation = Vectors.grab3i();
+ Coordinates.getInWorld(chunk.getPosition(), blockInChunk, contextLocation);
+ context.toContext(contextLocation, contextLocation);
+ RelFace contextFace = context.toContext(face);
+ ServerTileStackContextRO tileStackContextRO = context.push(contextLocation, contextFace);
+ Vectors.release(contextLocation);
+ return tileStackContextRO;
+ }
+
+ public static ServerTileStackContextRO pushAbs(ServerBlockContextRO context, AbsFace face) {
+ return context.push(context.toContext(face));
+ }
+
+ public static ServerTileContextRO pushAbs(ServerWorldContextRO context, AbsFace up, TileGenericReferenceRO, ?, ?, ?, ?> ref) {
+ Vec3i contextLocation = Vectors.grab3i();
+ ref.getStack().getBlockInWorld(contextLocation);
+ context.toContext(contextLocation, contextLocation);
+ RelFace contextFace = context.toContext(ref.getStack().getFace().resolve(up));
+ ServerTileContextRO tileContextRO = context.push(contextLocation, contextFace, ref.getIndex());
+ Vectors.release(contextLocation);
+ return tileContextRO;
+ }
+
+ private ServerContexts() {
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java
index ec89e47..aeda6e8 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java
@@ -29,6 +29,7 @@ import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.EntityGeneric;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
import ru.windcorp.progressia.common.world.rels.BlockFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
import ru.windcorp.progressia.common.world.tile.TileData;
@@ -290,6 +291,41 @@ class DefaultServerContextImpl extends DefaultServerContext
assert requireContextRole(Role.TILE);
return frame.layer;
}
+
+ /*
+ * ABSOLUTE COORDINATE CONVERSIONS
+ * (or lack thereof)
+ */
+
+ @Override
+ public Vec3i toAbsolute(Vec3i contextLocation, Vec3i output) {
+ if (output == null) {
+ output = new Vec3i();
+ }
+
+ output.set(contextLocation.x, contextLocation.y, contextLocation.z);
+ return output;
+ }
+
+ @Override
+ public Vec3i toContext(Vec3i absoluteLocation, Vec3i output) {
+ if (output == null) {
+ output = new Vec3i();
+ }
+
+ output.set(absoluteLocation.x, absoluteLocation.y, absoluteLocation.z);
+ return output;
+ }
+
+ @Override
+ public AbsFace toAbsolute(BlockFace contextFace) {
+ return contextFace.resolve(AbsFace.POS_Z);
+ }
+
+ @Override
+ public RelFace toContext(AbsFace absoluteFace) {
+ return absoluteFace.relativize(AbsFace.POS_Z);
+ }
/*
* RO CONTEXT INTERFACE
diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java
index 4461d23..640a475 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java
@@ -23,6 +23,7 @@ import java.util.Random;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
import ru.windcorp.progressia.common.world.rels.BlockFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
import ru.windcorp.progressia.common.world.tile.TileData;
@@ -84,6 +85,26 @@ public class DefaultServerContextLogic implements ServerTileContext.Logic {
parent.push(location, face, layer);
return this;
}
+
+ @Override
+ public Vec3i toAbsolute(Vec3i contextLocation, Vec3i output) {
+ return parent.toAbsolute(contextLocation, output);
+ }
+
+ @Override
+ public Vec3i toContext(Vec3i absoluteLocation, Vec3i output) {
+ return parent.toContext(absoluteLocation, output);
+ }
+
+ @Override
+ public AbsFace toAbsolute(BlockFace contextFace) {
+ return parent.toAbsolute(contextFace);
+ }
+
+ @Override
+ public RelFace toContext(AbsFace absoluteFace) {
+ return parent.toContext(absoluteFace);
+ }
@Override
public double getTickLength() {
diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java
index b7b5ff5..677f9d3 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java
@@ -27,6 +27,7 @@ import ru.windcorp.progressia.common.world.GravityModel;
import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.EntityGeneric;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
import ru.windcorp.progressia.common.world.rels.BlockFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
import ru.windcorp.progressia.common.world.tile.TileData;
@@ -199,6 +200,26 @@ public abstract class FilterServerContext implements ServerTileContext {
parent.push(location, face, layer);
return this;
}
+
+ @Override
+ public Vec3i toAbsolute(Vec3i contextLocation, Vec3i output) {
+ return parent.toAbsolute(contextLocation, output);
+ }
+
+ @Override
+ public Vec3i toContext(Vec3i absoluteLocation, Vec3i output) {
+ return parent.toContext(absoluteLocation, output);
+ }
+
+ @Override
+ public AbsFace toAbsolute(BlockFace contextFace) {
+ return parent.toAbsolute(contextFace);
+ }
+
+ @Override
+ public RelFace toContext(AbsFace absoluteFace) {
+ return parent.toContext(absoluteFace);
+ }
@Override
public Server getServer() {
diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java
new file mode 100644
index 0000000..2ccc86c
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java
@@ -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 .
+ */
+package ru.windcorp.progressia.server.world.context.impl;
+
+import glm.vec._3.i.Vec3i;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
+import ru.windcorp.progressia.common.world.rels.RelFace;
+import ru.windcorp.progressia.server.world.context.ServerTileContext;
+
+public class RotatingServerContext extends TransformingServerContext {
+
+ private final AbsFace up;
+
+ public RotatingServerContext(ServerTileContext parent, AbsFace up) {
+ super(parent);
+ this.up = up;
+ }
+
+ @Override
+ protected void transform(Vec3i userLocation, Vec3i output) {
+ output.set(userLocation.x, userLocation.y, userLocation.z);
+ }
+
+ @Override
+ protected void untransform(Vec3i parentLocation, Vec3i output) {
+ output.set(parentLocation.x, parentLocation.y, parentLocation.z);
+ }
+
+ @Override
+ protected RelFace transform(RelFace userFace) {
+ return userFace.resolve(up).relativize(AbsFace.POS_Z);
+ }
+
+ @Override
+ protected RelFace untransform(RelFace parentFace) {
+ return parentFace.resolve(AbsFace.POS_Z).relativize(up);
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java
new file mode 100644
index 0000000..7305876
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java
@@ -0,0 +1,273 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.server.world.context.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import glm.vec._3.i.Vec3i;
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
+import ru.windcorp.progressia.common.world.rels.BlockFace;
+import ru.windcorp.progressia.common.world.rels.RelFace;
+import ru.windcorp.progressia.common.world.tile.TileData;
+import ru.windcorp.progressia.server.world.context.ServerBlockContext;
+import ru.windcorp.progressia.server.world.context.ServerTileContext;
+import ru.windcorp.progressia.server.world.context.ServerTileStackContext;
+
+public abstract class TransformingServerContext extends FilterServerContext {
+
+ private final Vec3i location = new Vec3i();
+ private boolean isLocationValid = false;
+
+ private RelFace face;
+
+ private final List vectorCache = new ArrayList<>(1);
+
+ public TransformingServerContext(ServerTileContext parent) {
+ super(parent);
+ }
+
+ protected abstract void transform(Vec3i userLocation, Vec3i output);
+
+ protected abstract void untransform(Vec3i parentLocation, Vec3i output);
+
+ protected abstract RelFace transform(RelFace userFace);
+
+ protected abstract RelFace untransform(RelFace parentFace);
+
+ protected void invalidateCache() {
+ isLocationValid = false;
+ face = null;
+ }
+
+ private Vec3i grabVector(Vec3i userVector) {
+ Vec3i parentVector;
+
+ if (vectorCache.isEmpty()) {
+ parentVector = new Vec3i();
+ } else {
+ parentVector = vectorCache.remove(vectorCache.size() - 1);
+ }
+
+ transform(userVector, parentVector);
+
+ return parentVector;
+ }
+
+ private void releaseVector(Vec3i parentVector) {
+ vectorCache.add(parentVector);
+ }
+
+ @Override
+ public Vec3i getLocation() {
+ // Always invoke parent method to allow parent to determine validity
+ Vec3i parentLocation = super.getLocation();
+
+ if (!isLocationValid) {
+ untransform(parentLocation, location);
+ isLocationValid = true;
+ }
+
+ return location;
+ }
+
+ @Override
+ public RelFace getFace() {
+ // Always invoke parent method to allow parent to determine validity
+ RelFace parentFace = super.getFace();
+
+ if (face == null) {
+ face = untransform(parentFace);
+ }
+
+ return face;
+ }
+
+ @Override
+ public void pop() {
+ super.pop();
+ invalidateCache();
+ }
+
+ @Override
+ public ServerBlockContext push(Vec3i userLocation) {
+ transform(userLocation, location);
+ isLocationValid = true;
+ super.push(location);
+ face = null;
+ return this;
+ }
+
+ @Override
+ public ServerTileStackContext push(Vec3i userLocation, RelFace userFace) {
+ transform(userLocation, location);
+ isLocationValid = true;
+ face = transform(userFace);
+ super.push(location, face);
+ return this;
+ }
+
+ @Override
+ public ServerTileContext push(Vec3i userLocation, RelFace userFace, int layer) {
+ transform(userLocation, location);
+ isLocationValid = true;
+ face = transform(userFace);
+ super.push(location, face, layer);
+ return this;
+ }
+
+ @Override
+ public Vec3i toAbsolute(Vec3i contextLocation, Vec3i output) {
+ if (output == null) {
+ output = new Vec3i();
+ }
+
+ transform(contextLocation, output);
+
+ return super.toAbsolute(output, output);
+ }
+
+ @Override
+ public Vec3i toContext(Vec3i absoluteLocation, Vec3i output) {
+ output = super.toContext(absoluteLocation, output);
+ untransform(output, output);
+ return output;
+ }
+
+ @Override
+ public AbsFace toAbsolute(BlockFace contextFace) {
+ return super.toAbsolute(transform(contextFace.relativize(AbsFace.POS_Z)));
+ }
+
+ @Override
+ public RelFace toContext(AbsFace absoluteFace) {
+ return untransform(super.toContext(absoluteFace));
+ }
+
+ @Override
+ public boolean isLocationLoaded(Vec3i userLocation) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ return super.isLocationLoaded(parentLocation);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public BlockData getBlock(Vec3i userLocation) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ return super.getBlock(parentLocation);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public void setBlock(Vec3i userLocation, BlockData block) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ super.setBlock(parentLocation, block);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public boolean hasTile(Vec3i userLocation, BlockFace userFace, int layer) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ return super.hasTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), layer);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public TileData getTile(Vec3i userLocation, BlockFace userFace, int layer) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ return super.getTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), layer);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public boolean isTagValid(Vec3i userLocation, BlockFace userFace, int tag) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ return super.isTagValid(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public TileData getTileByTag(Vec3i userLocation, BlockFace userFace, int tag) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ return super.getTileByTag(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public int getTileCount(Vec3i userLocation, BlockFace userFace) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ return super.getTileCount(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)));
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public void addTile(Vec3i userLocation, BlockFace userFace, TileData tile) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ super.addTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tile);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+ @Override
+ public void removeTile(Vec3i userLocation, BlockFace userFace, int tag) {
+ Vec3i parentLocation = grabVector(userLocation);
+
+ try {
+ super.removeTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag);
+ } finally {
+ releaseVector(parentLocation);
+ }
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java
index 4ed21f1..a2a59f9 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java
@@ -27,17 +27,15 @@ import com.google.common.collect.ImmutableList;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.util.FloatMathUtil;
-import ru.windcorp.progressia.common.util.Vectors;
-import ru.windcorp.progressia.common.world.Coordinates;
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.common.world.generic.ChunkGenericRO;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.DefaultChunkLogic;
import ru.windcorp.progressia.server.world.block.BlockLogic;
import ru.windcorp.progressia.server.world.block.TickableBlock;
import ru.windcorp.progressia.server.world.context.ServerBlockContext;
+import ru.windcorp.progressia.server.world.context.ServerContexts;
import ru.windcorp.progressia.server.world.context.ServerTileContext;
import ru.windcorp.progressia.server.world.context.ServerTileStackContext;
import ru.windcorp.progressia.server.world.context.ServerWorldContext;
@@ -53,20 +51,21 @@ public class TickChunk extends Evaluation {
DefaultChunkData.BLOCKS_PER_CHUNK *
DefaultChunkData.BLOCKS_PER_CHUNK;
- private final List> randomTickMethods;
+ private final List> randomTickMethods;
{
- List> randomTickMethods = new ArrayList<>();
+ List> randomTickMethods = new ArrayList<>();
randomTickMethods.add(this::tickRandomBlock);
for (AbsFace face : AbsFace.getFaces()) {
- randomTickMethods.add(s -> this.tickRandomTile(s, face));
+ randomTickMethods.add(context -> this.tickRandomTile(face, context));
}
this.randomTickMethods = ImmutableList.copyOf(randomTickMethods);
}
private final DefaultChunkLogic chunk;
+ private ServerWorldContext context;
public TickChunk(DefaultChunkLogic chunk) {
this.chunk = chunk;
@@ -74,44 +73,41 @@ public class TickChunk extends Evaluation {
@Override
public void evaluate(Server server) {
- tickRegulars(server);
- tickRandom(server);
+ if (context == null || context.getServer() != server) {
+ context = server.createContext(chunk.getUp());
+ }
+
+ tickRegulars(context);
+ tickRandom(context);
}
- private void tickRegulars(Server server) {
- tickRegularBlocks(server);
- tickRegularTiles(server);
+ private void tickRegulars(ServerWorldContext context) {
+ tickRegularBlocks(context);
+ tickRegularTiles(context);
}
- private void tickRegularBlocks(Server server) {
+ private void tickRegularBlocks(ServerWorldContext context) {
if (!chunk.hasTickingBlocks())
return;
- ServerWorldContext context = server.createContext();
-
chunk.forEachTickingBlock((blockInChunk, block) -> {
- ((TickableBlock) block).tick(contextPushBiC(context, chunk, blockInChunk));
+ ((TickableBlock) block).tick(ServerContexts.pushAbs(context, chunk, blockInChunk));
context.pop();
});
}
- private void tickRegularTiles(Server server) {
+ private void tickRegularTiles(ServerWorldContext context) {
if (!chunk.hasTickingTiles())
return;
- ServerWorldContext context = server.createContext();
- Vec3i blockInWorld = new Vec3i();
-
chunk.forEachTickingTile((ref, tile) -> {
- ((TickableTile) tile).tick(
- context.push(ref.getStack().getBlockInWorld(blockInWorld), ref.getStack().getFace(), ref.getIndex())
- );
+ ((TickableTile) tile).tick(ServerContexts.pushAbs(context, chunk.getUp(), ref));
context.pop();
});
}
- private void tickRandom(Server server) {
- float ticks = computeRandomTicks(server);
+ private void tickRandom(ServerWorldContext context) {
+ float ticks = computeRandomTicks(context.getServer());
/*
* If we are expected to run 3.25 random ticks per tick
@@ -122,23 +118,23 @@ public class TickChunk extends Evaluation {
float extraTickChance = ticks - unconditionalTicks;
for (int i = 0; i < unconditionalTicks; ++i) {
- tickRandomOnce(server);
+ tickRandomOnce(context);
}
- if (server.getAdHocRandom().nextFloat() < extraTickChance) {
- tickRandomOnce(server);
+ if (context.getRandom().nextFloat() < extraTickChance) {
+ tickRandomOnce(context);
}
}
- private void tickRandomOnce(Server server) {
+ private void tickRandomOnce(ServerWorldContext context) {
// Pick a target at random: a block or one of 3 primary block faces
randomTickMethods.get(
- server.getAdHocRandom().nextInt(randomTickMethods.size())
- ).accept(server);
+ context.getRandom().nextInt(randomTickMethods.size())
+ ).accept(context);
}
- private void tickRandomBlock(Server server) {
- Random random = server.getAdHocRandom();
+ private void tickRandomBlock(ServerWorldContext context) {
+ Random random = context.getRandom();
Vec3i blockInChunk = new Vec3i(
random.nextInt(BLOCKS_PER_CHUNK),
@@ -152,15 +148,17 @@ public class TickChunk extends Evaluation {
return;
TickableBlock tickable = (TickableBlock) block;
- ServerBlockContext context = contextPushBiC(server.createContext(), chunk, blockInChunk);
+ ServerBlockContext blockContext = ServerContexts.pushAbs(context, chunk, blockInChunk);
- if (tickable.getTickingPolicy(context) != TickingPolicy.RANDOM)
+ if (tickable.getTickingPolicy(blockContext) != TickingPolicy.RANDOM)
return;
- tickable.tick(context);
+ tickable.tick(blockContext);
+
+ blockContext.pop();
}
- private void tickRandomTile(Server server, AbsFace face) {
- Random random = server.getAdHocRandom();
+ private void tickRandomTile(AbsFace face, ServerWorldContext context) {
+ Random random = context.getRandom();
Vec3i blockInChunk = new Vec3i(
random.nextInt(BLOCKS_PER_CHUNK),
@@ -172,10 +170,10 @@ public class TickChunk extends Evaluation {
if (tiles == null || tiles.isEmpty())
return;
- ServerTileStackContext context = contextPushBiC(server.createContext(), chunk, blockInChunk).push(face.relativize(chunk.getUp()));
+ ServerTileStackContext tsContext = ServerContexts.pushAbs(context, chunk, blockInChunk, face);
for (int i = 0; i < tiles.size(); ++i) {
- ServerTileContext tileContext = context.push(i);
+ ServerTileContext tileContext = tsContext.push(i);
TileLogic logic = tileContext.logic().getTile();
if (!(logic instanceof TickableTile)) {
@@ -192,6 +190,8 @@ public class TickChunk extends Evaluation {
tileContext.pop();
}
+
+ tsContext.pop();
}
private float computeRandomTicks(Server server) {
@@ -200,18 +200,6 @@ public class TickChunk extends Evaluation {
server.getTickLength());
}
- private ServerBlockContext contextPushBiC(
- ServerWorldContext context,
- ChunkGenericRO, ?, ?, ?, ?> chunk,
- Vec3i blockInChunk
- ) {
- Vec3i blockInWorld = Vectors.grab3i();
- Coordinates.getInWorld(chunk.getPosition(), blockInChunk, blockInWorld);
- ServerBlockContext blockContext = context.push(blockInWorld);
- Vectors.release(blockInWorld);
- return blockContext;
- }
-
@Override
public void getRelevantChunk(Vec3i output) {
Vec3i p = chunk.getData().getPosition();
diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java
index 0ddc3e5..7b9122f 100644
--- a/src/main/java/ru/windcorp/progressia/test/TestContent.java
+++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java
@@ -383,7 +383,7 @@ public class TestContent {
ru.windcorp.progressia.server.comms.Client client
) {
Vec3i blockInWorld = ((ControlBreakBlockData) packet.getControl()).getBlockInWorld();
- server.createContext().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Air"));
+ server.createAbsoluteContext().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Air"));
}
private static void onBlockPlaceTrigger(ControlData control) {
@@ -403,7 +403,7 @@ public class TestContent {
Vec3i blockInWorld = controlData.getBlockInWorld();
if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null)
return;
- server.createContext().setBlock(blockInWorld, block);
+ server.createAbsoluteContext().setBlock(blockInWorld, block);
}
private static void onTilePlaceTrigger(ControlData control) {
@@ -428,7 +428,7 @@ public class TestContent {
return;
if (server.getWorld().getData().getTiles(blockInWorld, face).isFull())
return;
- server.createContext().addTile(blockInWorld, face, tile);
+ server.createAbsoluteContext().addTile(blockInWorld, face, tile);
}
private static void registerMisc() {
diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java
index bfe438f..c197ce1 100644
--- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java
+++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java
@@ -18,6 +18,7 @@
package ru.windcorp.progressia.test;
+import ru.windcorp.progressia.common.world.rels.AbsFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
import ru.windcorp.progressia.server.world.block.BlockLogic;
import ru.windcorp.progressia.server.world.context.ServerTileContext;
@@ -65,7 +66,7 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile
private boolean isBlockAboveTransparent(ServerTileContextRO context) {
// TODO rework
- context.pushRelative(RelFace.UP.resolve(context.getServer().getWorld().getUp(context.getLocation())));
+ context.pushRelative(RelFace.UP.resolve(AbsFace.POS_Z));
BlockLogic block = context.logic().getBlock();
return context.popAndReturn(block == null || block.isTransparent(context));
}