Some more refactoring of generic world-related classes. May not compile.
- Added GenericWritableWorld - Moved static methods from GenericChunk to GenericChunks - GenericEntity now declares getEntityId() - GenericWorld now declares getEntity(long) - Added a lambda-based mapToFaces variations for AbsFace and RelFace
This commit is contained in:
		@@ -36,7 +36,7 @@ import ru.windcorp.progressia.client.world.tile.TileRender;
 | 
			
		||||
import ru.windcorp.progressia.client.world.tile.TileRenderNone;
 | 
			
		||||
import ru.windcorp.progressia.client.world.tile.TileRenderStack;
 | 
			
		||||
import ru.windcorp.progressia.common.world.ChunkData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunk;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunks;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.AxisRotations;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.RelFace;
 | 
			
		||||
 | 
			
		||||
@@ -77,7 +77,7 @@ public class ChunkRenderModel implements Renderable {
 | 
			
		||||
		
 | 
			
		||||
		optimizers.forEach(ChunkRenderOptimizer::startRender);
 | 
			
		||||
		
 | 
			
		||||
		GenericChunk.forEachBiC(relBlockInChunk -> {
 | 
			
		||||
		GenericChunks.forEachBiC(relBlockInChunk -> {
 | 
			
		||||
			processBlockAndTiles(relBlockInChunk, sink);
 | 
			
		||||
		});
 | 
			
		||||
		
 | 
			
		||||
 
 | 
			
		||||
@@ -112,6 +112,13 @@ public class WorldRender
 | 
			
		||||
		return entityModels.values();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public EntityRenderable getEntity(long entityId) {
 | 
			
		||||
		EntityData entityData = getData().getEntity(entityId);
 | 
			
		||||
		if (entityData == null) return null;
 | 
			
		||||
		return getEntityRenderable(entityData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void render(ShapeRenderHelper renderer) {
 | 
			
		||||
		updateChunks();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ import ru.windcorp.progressia.client.world.block.BlockRender;
 | 
			
		||||
import ru.windcorp.progressia.client.world.tile.TileRender;
 | 
			
		||||
import ru.windcorp.progressia.common.util.Vectors;
 | 
			
		||||
import ru.windcorp.progressia.common.world.ChunkData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunk;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunks;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.RelFace;
 | 
			
		||||
 | 
			
		||||
public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer {
 | 
			
		||||
@@ -217,7 +217,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer {
 | 
			
		||||
 | 
			
		||||
		Consumer<ShapePart> consumer = shapeParts::add;
 | 
			
		||||
 | 
			
		||||
		GenericChunk.forEachBiC(relBlockInChunk -> {
 | 
			
		||||
		GenericChunks.forEachBiC(relBlockInChunk -> {
 | 
			
		||||
			processInnerFaces(relBlockInChunk, consumer);
 | 
			
		||||
			processOuterFaces(relBlockInChunk, consumer);
 | 
			
		||||
		});
 | 
			
		||||
@@ -316,7 +316,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean shouldRenderWhenFacing(Vec3i relBlockInChunk, RelFace face) {
 | 
			
		||||
		if (GenericChunk.containsBiC(relBlockInChunk)) {
 | 
			
		||||
		if (GenericChunks.containsBiC(relBlockInChunk)) {
 | 
			
		||||
			return shouldRenderWhenFacingLocal(relBlockInChunk, face);
 | 
			
		||||
		} else {
 | 
			
		||||
			return shouldRenderWhenFacingNeighbor(relBlockInChunk, face);
 | 
			
		||||
 
 | 
			
		||||
@@ -72,6 +72,11 @@ public abstract class EntityRenderable implements Renderable, GenericEntity {
 | 
			
		||||
		return getData().getId();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public long getEntityId() {
 | 
			
		||||
		return getData().getEntityId();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final Vec3 getLookingAt(Vec3 output) {
 | 
			
		||||
		if (output == null) output = new Vec3();
 | 
			
		||||
		updateIfNecessary();
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ import java.util.Objects;
 | 
			
		||||
import glm.vec._3.i.Vec3i;
 | 
			
		||||
 | 
			
		||||
import ru.windcorp.progressia.common.world.block.BlockData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunk;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunks;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericWritableChunk;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.BlockFace;
 | 
			
		||||
@@ -160,7 +160,7 @@ public class ChunkData
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static void checkLocalCoordinates(Vec3i posInChunk) {
 | 
			
		||||
		if (!GenericChunk.containsBiC(posInChunk)) {
 | 
			
		||||
		if (!GenericChunks.containsBiC(posInChunk)) {
 | 
			
		||||
			throw new IllegalCoordinatesException(
 | 
			
		||||
				"Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") "
 | 
			
		||||
					+ "are not legal chunk coordinates"
 | 
			
		||||
 
 | 
			
		||||
@@ -34,14 +34,14 @@ import ru.windcorp.progressia.common.world.block.BlockData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.entity.EntityData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.ChunkMap;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.ChunkSet;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericWorld;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericWritableWorld;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.LongBasedChunkMap;
 | 
			
		||||
import ru.windcorp.progressia.common.world.tile.TileData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.tile.TileDataStack;
 | 
			
		||||
import ru.windcorp.progressia.common.world.tile.TileDataReference;
 | 
			
		||||
 | 
			
		||||
public class WorldData
 | 
			
		||||
	implements GenericWorld<BlockData, TileData, TileDataStack, TileDataReference, ChunkData, EntityData> {
 | 
			
		||||
	implements GenericWritableWorld<BlockData, TileData, TileDataStack, TileDataReference, ChunkData, EntityData> {
 | 
			
		||||
 | 
			
		||||
	private final ChunkMap<ChunkData> chunksByPos = new LongBasedChunkMap<>(
 | 
			
		||||
		TCollections.synchronizedMap(new TLongObjectHashMap<>())
 | 
			
		||||
@@ -128,6 +128,7 @@ public class WorldData
 | 
			
		||||
		chunksByPos.remove(chunk);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) {
 | 
			
		||||
		ChunkData chunk = getChunkByBlock(blockInWorld);
 | 
			
		||||
		if (chunk == null)
 | 
			
		||||
@@ -140,10 +141,12 @@ public class WorldData
 | 
			
		||||
		chunk.setBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null), block, notify);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public EntityData getEntity(long entityId) {
 | 
			
		||||
		return entitiesById.get(entityId);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void addEntity(EntityData entity) {
 | 
			
		||||
		Objects.requireNonNull(entity, "entity");
 | 
			
		||||
 | 
			
		||||
@@ -164,6 +167,7 @@ public class WorldData
 | 
			
		||||
		getListeners().forEach(l -> l.onEntityAdded(this, entity));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void removeEntity(long entityId) {
 | 
			
		||||
		synchronized (entitiesById) {
 | 
			
		||||
			EntityData entity = entitiesById.get(entityId);
 | 
			
		||||
@@ -178,6 +182,7 @@ public class WorldData
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void removeEntity(EntityData entity) {
 | 
			
		||||
		Objects.requireNonNull(entity, "entity");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -85,6 +85,7 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn
 | 
			
		||||
		this.velocity.set(velocity);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public long getEntityId() {
 | 
			
		||||
		return entityId;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -106,20 +106,7 @@ public interface GenericChunk<
 | 
			
		||||
	boolean hasTiles(Vec3i blockInChunk, BlockFace face);
 | 
			
		||||
 | 
			
		||||
	default Vec3i resolve(Vec3i relativeCoords, Vec3i output) {
 | 
			
		||||
		if (output == null) {
 | 
			
		||||
			output = new Vec3i();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		final int offset = BLOCKS_PER_CHUNK - 1;
 | 
			
		||||
 | 
			
		||||
		output.set(relativeCoords.x, relativeCoords.y, relativeCoords.z);
 | 
			
		||||
		output.mul(2).sub(offset);
 | 
			
		||||
 | 
			
		||||
		AxisRotations.resolve(output, getUp(), output);
 | 
			
		||||
 | 
			
		||||
		output.add(offset).div(2);
 | 
			
		||||
 | 
			
		||||
		return output;
 | 
			
		||||
		return GenericChunks.resolve(relativeCoords, output, getUp());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	default B getBlockRel(Vec3i relativeBlockInChunk) {
 | 
			
		||||
@@ -240,50 +227,20 @@ public interface GenericChunk<
 | 
			
		||||
		return output;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean containsBiC(Vec3i blockInChunk) {
 | 
			
		||||
		return blockInChunk.x >= 0 && blockInChunk.x < BLOCKS_PER_CHUNK &&
 | 
			
		||||
			blockInChunk.y >= 0 && blockInChunk.y < BLOCKS_PER_CHUNK &&
 | 
			
		||||
			blockInChunk.z >= 0 && blockInChunk.z < BLOCKS_PER_CHUNK;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean isSurfaceBiC(Vec3i blockInChunk) {
 | 
			
		||||
		return Util.getBorderHits(blockInChunk) >= 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean isEdgeBiC(Vec3i blockInChunk) {
 | 
			
		||||
		return Util.getBorderHits(blockInChunk) >= 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean isVertexBiC(Vec3i blockInChunk) {
 | 
			
		||||
		return Util.getBorderHits(blockInChunk) == 3;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	default boolean containsBiW(Vec3i blockInWorld) {
 | 
			
		||||
		return Util.testBiC(blockInWorld, this, GenericChunk::containsBiC);
 | 
			
		||||
		return GenericChunks.testBiC(blockInWorld, this, GenericChunks::containsBiC);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	default boolean isSurfaceBiW(Vec3i blockInWorld) {
 | 
			
		||||
		return Util.testBiC(blockInWorld, this, GenericChunk::isSurfaceBiC);
 | 
			
		||||
		return GenericChunks.testBiC(blockInWorld, this, GenericChunks::isSurfaceBiC);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	default boolean isEdgeBiW(Vec3i blockInWorld) {
 | 
			
		||||
		return Util.testBiC(blockInWorld, this, GenericChunk::isEdgeBiC);
 | 
			
		||||
		return GenericChunks.testBiC(blockInWorld, this, GenericChunks::isEdgeBiC);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	default boolean isVertexBiW(Vec3i blockInWorld) {
 | 
			
		||||
		return Util.testBiC(blockInWorld, this, GenericChunk::isVertexBiC);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static void forEachBiC(Consumer<? super Vec3i> action) {
 | 
			
		||||
		VectorUtil.iterateCuboid(
 | 
			
		||||
			0,
 | 
			
		||||
			0,
 | 
			
		||||
			0,
 | 
			
		||||
			BLOCKS_PER_CHUNK,
 | 
			
		||||
			BLOCKS_PER_CHUNK,
 | 
			
		||||
			BLOCKS_PER_CHUNK,
 | 
			
		||||
			action
 | 
			
		||||
		);
 | 
			
		||||
		return GenericChunks.testBiC(blockInWorld, this, GenericChunks::isVertexBiC);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	default void forEachBiW(Consumer<? super Vec3i> action) {
 | 
			
		||||
@@ -324,7 +281,7 @@ public interface GenericChunk<
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	default void forEachTileStack(Consumer<TS> action) {
 | 
			
		||||
		forEachBiC(blockInChunk -> {
 | 
			
		||||
		GenericChunks.forEachBiC(blockInChunk -> {
 | 
			
		||||
			for (AbsFace face : AbsFace.getFaces()) {
 | 
			
		||||
				TS stack = getTilesOrNull(blockInChunk, face);
 | 
			
		||||
				if (stack == null)
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,102 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Progressia
 | 
			
		||||
 * Copyright (C)  2020-2021  Wind Corporation and contributors
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
package ru.windcorp.progressia.common.world.generic;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Consumer;
 | 
			
		||||
import java.util.function.Predicate;
 | 
			
		||||
 | 
			
		||||
import glm.vec._3.i.Vec3i;
 | 
			
		||||
import ru.windcorp.progressia.common.util.VectorUtil;
 | 
			
		||||
import ru.windcorp.progressia.common.util.Vectors;
 | 
			
		||||
import ru.windcorp.progressia.common.world.Coordinates;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.AxisRotations;
 | 
			
		||||
 | 
			
		||||
public class GenericChunks {
 | 
			
		||||
	
 | 
			
		||||
	public static Vec3i resolve(Vec3i relativeCoords, Vec3i output, AbsFace up) {
 | 
			
		||||
		if (output == null) {
 | 
			
		||||
			output = new Vec3i();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		final int offset = GenericChunk.BLOCKS_PER_CHUNK - 1;
 | 
			
		||||
 | 
			
		||||
		output.set(relativeCoords.x, relativeCoords.y, relativeCoords.z);
 | 
			
		||||
		output.mul(2).sub(offset);
 | 
			
		||||
 | 
			
		||||
		AxisRotations.resolve(output, up, output);
 | 
			
		||||
 | 
			
		||||
		output.add(offset).div(2);
 | 
			
		||||
 | 
			
		||||
		return output;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static int getBorderHits(Vec3i blockInChunk) {
 | 
			
		||||
		int hits = 0;
 | 
			
		||||
		
 | 
			
		||||
		if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++;
 | 
			
		||||
		if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++;
 | 
			
		||||
		if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++;
 | 
			
		||||
		
 | 
			
		||||
		return hits;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static boolean testBiC(Vec3i blockInWorld, GenericChunk<?, ?, ?, ?, ?> chunk, Predicate<Vec3i> test) {
 | 
			
		||||
		Vec3i v = Vectors.grab3i();
 | 
			
		||||
 | 
			
		||||
		v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v);
 | 
			
		||||
		v = blockInWorld.sub(v, v);
 | 
			
		||||
 | 
			
		||||
		boolean result = test.test(v);
 | 
			
		||||
 | 
			
		||||
		Vectors.release(v);
 | 
			
		||||
		
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean containsBiC(Vec3i blockInChunk) {
 | 
			
		||||
		return blockInChunk.x >= 0 && blockInChunk.x < GenericChunk.BLOCKS_PER_CHUNK &&
 | 
			
		||||
			blockInChunk.y >= 0 && blockInChunk.y < GenericChunk.BLOCKS_PER_CHUNK &&
 | 
			
		||||
			blockInChunk.z >= 0 && blockInChunk.z < GenericChunk.BLOCKS_PER_CHUNK;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean isSurfaceBiC(Vec3i blockInChunk) {
 | 
			
		||||
		return GenericChunks.getBorderHits(blockInChunk) >= 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean isEdgeBiC(Vec3i blockInChunk) {
 | 
			
		||||
		return GenericChunks.getBorderHits(blockInChunk) >= 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean isVertexBiC(Vec3i blockInChunk) {
 | 
			
		||||
		return GenericChunks.getBorderHits(blockInChunk) == 3;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static void forEachBiC(Consumer<? super Vec3i> action) {
 | 
			
		||||
		VectorUtil.iterateCuboid(
 | 
			
		||||
			0,
 | 
			
		||||
			0,
 | 
			
		||||
			0,
 | 
			
		||||
			GenericChunk.BLOCKS_PER_CHUNK,
 | 
			
		||||
			GenericChunk.BLOCKS_PER_CHUNK,
 | 
			
		||||
			GenericChunk.BLOCKS_PER_CHUNK,
 | 
			
		||||
			action
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -26,6 +26,8 @@ public interface GenericEntity {
 | 
			
		||||
 | 
			
		||||
	String getId();
 | 
			
		||||
	
 | 
			
		||||
	long getEntityId();
 | 
			
		||||
 | 
			
		||||
	Vec3 getPosition();
 | 
			
		||||
 | 
			
		||||
	default Vec3i getBlockInWorld(Vec3i output) {
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,8 @@ public interface GenericWorld<
 | 
			
		||||
 | 
			
		||||
	Collection<E> getEntities();
 | 
			
		||||
 | 
			
		||||
	E getEntity(long entityId);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Chunks
 | 
			
		||||
	 */
 | 
			
		||||
 
 | 
			
		||||
@@ -17,37 +17,29 @@
 | 
			
		||||
 */
 | 
			
		||||
package ru.windcorp.progressia.common.world.generic;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Predicate;
 | 
			
		||||
 | 
			
		||||
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.block.BlockData;
 | 
			
		||||
 | 
			
		||||
class Util {
 | 
			
		||||
//@formatter:off
 | 
			
		||||
public interface GenericWritableWorld<
 | 
			
		||||
	B  extends GenericBlock,
 | 
			
		||||
	T  extends GenericTile,
 | 
			
		||||
	TS extends GenericWritableTileStack <B, T, TS, TR, C>,
 | 
			
		||||
	TR extends GenericTileReference     <B, T, TS, TR, C>,
 | 
			
		||||
	C  extends GenericWritableChunk     <B, T, TS, TR, C>,
 | 
			
		||||
	E  extends GenericEntity
 | 
			
		||||
>
 | 
			
		||||
	extends GenericWorld<B, T, TS, TR, C, E> {
 | 
			
		||||
//@formatter:on
 | 
			
		||||
 | 
			
		||||
	public static int getBorderHits(Vec3i blockInChunk) {
 | 
			
		||||
		int hits = 0;
 | 
			
		||||
	void setBlock(Vec3i blockInWorld, BlockData block, boolean notify);
 | 
			
		||||
 | 
			
		||||
		if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++;
 | 
			
		||||
		if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++;
 | 
			
		||||
		if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++;
 | 
			
		||||
	void addEntity(E entity);
 | 
			
		||||
 | 
			
		||||
		return hits;
 | 
			
		||||
	void removeEntity(long entityId);
 | 
			
		||||
 | 
			
		||||
	default void removeEntity(E entity) {
 | 
			
		||||
		removeEntity(entity.getEntityId());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean testBiC(Vec3i blockInWorld, GenericChunk<?, ?, ?, ?, ?> chunk, Predicate<Vec3i> test) {
 | 
			
		||||
		Vec3i v = Vectors.grab3i();
 | 
			
		||||
 | 
			
		||||
		v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v);
 | 
			
		||||
		v = blockInWorld.sub(v, v);
 | 
			
		||||
 | 
			
		||||
		boolean result = test.test(v);
 | 
			
		||||
 | 
			
		||||
		Vectors.release(v);
 | 
			
		||||
		
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
package ru.windcorp.progressia.common.world.rels;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
@@ -90,6 +91,17 @@ public final class AbsFace extends AbsRelation implements BlockFace {
 | 
			
		||||
			.build();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static <E> ImmutableMap<AbsFace, E> mapToFaces(Function<AbsFace, E> generator) {
 | 
			
		||||
		return mapToFaces(
 | 
			
		||||
			generator.apply(POS_Z),
 | 
			
		||||
			generator.apply(NEG_Z),
 | 
			
		||||
			generator.apply(POS_X),
 | 
			
		||||
			generator.apply(NEG_X),
 | 
			
		||||
			generator.apply(NEG_Y),
 | 
			
		||||
			generator.apply(POS_Y)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Rounds the provided vector to one of {@link AbsFace}s. The returned face
 | 
			
		||||
	 * is pointing in the same general direction as the provided vector. The
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,8 @@
 | 
			
		||||
 */
 | 
			
		||||
package ru.windcorp.progressia.common.world.rels;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
 | 
			
		||||
@@ -69,6 +71,17 @@ public class RelFace extends RelRelation implements BlockFace {
 | 
			
		||||
			.build();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static <E> ImmutableMap<RelFace, E> mapToFaces(Function<RelFace, E> generator) {
 | 
			
		||||
		return mapToFaces(
 | 
			
		||||
			generator.apply(UP),
 | 
			
		||||
			generator.apply(DOWN),
 | 
			
		||||
			generator.apply(NORTH),
 | 
			
		||||
			generator.apply(SOUTH),
 | 
			
		||||
			generator.apply(WEST),
 | 
			
		||||
			generator.apply(EAST)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static int nextId = 0;
 | 
			
		||||
 | 
			
		||||
	private final int id;
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ import java.util.function.Consumer;
 | 
			
		||||
 | 
			
		||||
import glm.vec._3.i.Vec3i;
 | 
			
		||||
import ru.windcorp.progressia.common.world.ChunkData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunk;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunks;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
 | 
			
		||||
import ru.windcorp.progressia.server.world.block.BlockTickContext;
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +46,7 @@ public interface ChunkTickContext extends TickContext {
 | 
			
		||||
	default void forEachBlock(Consumer<BlockTickContext> action) {
 | 
			
		||||
		TickContextMutable context = TickContextMutable.uninitialized();
 | 
			
		||||
 | 
			
		||||
		GenericChunk.forEachBiC(blockInChunk -> {
 | 
			
		||||
		GenericChunks.forEachBiC(blockInChunk -> {
 | 
			
		||||
			context.rebuild().withServer(getServer()).withChunk(getChunk()).withBlockInChunk(blockInChunk).build();
 | 
			
		||||
			action.accept(context);
 | 
			
		||||
		});
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,11 @@ public class WorldLogic
 | 
			
		||||
		return getData().getEntities();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public EntityData getEntity(long entityId) {
 | 
			
		||||
		return getData().getEntity(entityId);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Evaluation getTickEntitiesTask() {
 | 
			
		||||
		return tickEntitiesTask;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ import ru.windcorp.progressia.common.world.DecodingException;
 | 
			
		||||
import ru.windcorp.progressia.common.world.WorldData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.block.BlockData;
 | 
			
		||||
import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunk;
 | 
			
		||||
import ru.windcorp.progressia.common.world.generic.GenericChunks;
 | 
			
		||||
import ru.windcorp.progressia.common.world.io.ChunkCodec;
 | 
			
		||||
import ru.windcorp.progressia.common.world.rels.RelFace;
 | 
			
		||||
import ru.windcorp.progressia.common.world.tile.TileData;
 | 
			
		||||
@@ -125,7 +125,7 @@ public class TestChunkCodec extends ChunkCodec {
 | 
			
		||||
 | 
			
		||||
	private void readBlocks(DataInput input, BlockData[] blockPalette, ChunkData chunk) throws IOException {
 | 
			
		||||
		try {
 | 
			
		||||
			GenericChunk.forEachBiC(guard(v -> {
 | 
			
		||||
			GenericChunks.forEachBiC(guard(v -> {
 | 
			
		||||
				chunk.setBlock(v, blockPalette[input.readInt()], false);
 | 
			
		||||
			}));
 | 
			
		||||
		} catch (UncheckedIOException e) {
 | 
			
		||||
@@ -172,7 +172,7 @@ public class TestChunkCodec extends ChunkCodec {
 | 
			
		||||
 | 
			
		||||
	private Palette<BlockData> createBlockPalette(ChunkData chunk) {
 | 
			
		||||
		Palette<BlockData> blockPalette = new Palette<>();
 | 
			
		||||
		GenericChunk.forEachBiC(v -> blockPalette.add(chunk.getBlock(v)));
 | 
			
		||||
		GenericChunks.forEachBiC(v -> blockPalette.add(chunk.getBlock(v)));
 | 
			
		||||
		return blockPalette;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -200,7 +200,7 @@ public class TestChunkCodec extends ChunkCodec {
 | 
			
		||||
 | 
			
		||||
	private void writeBlocks(ChunkData chunk, Palette<BlockData> blockPalette, DataOutput output) throws IOException {
 | 
			
		||||
		try {
 | 
			
		||||
			GenericChunk.forEachBiC(guard(v -> {
 | 
			
		||||
			GenericChunks.forEachBiC(guard(v -> {
 | 
			
		||||
				output.writeInt(blockPalette.getNid(chunk.getBlock(v)));
 | 
			
		||||
			}));
 | 
			
		||||
		} catch (UncheckedIOException e) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user