Minestom/src/main/java/net/minestom/server/instance/light/Light.java

109 lines
3.6 KiB
Java

package net.minestom.server.instance.light;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.palette.Palette;
import net.minestom.server.utils.Direction;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import static net.minestom.server.instance.light.LightCompute.SECTION_SIZE;
import static net.minestom.server.instance.light.LightCompute.getLight;
public interface Light {
static Light sky(@NotNull Palette blockPalette) {
return new SkyLight(blockPalette);
}
static Light block(@NotNull Palette blockPalette) {
return new BlockLight(blockPalette);
}
boolean requiresSend();
@ApiStatus.Internal
byte[] array();
Set<Point> flip();
@ApiStatus.Internal
Light calculateExternal(Instance instance, Chunk chunk, int sectionY);
@ApiStatus.Internal
void invalidatePropagation();
int getLevel(int x, int y, int z);
@ApiStatus.Internal
Light calculateInternal(Instance instance, int chunkX, int chunkY, int chunkZ);
void invalidate();
boolean requiresUpdate();
void set(byte[] copyArray);
@ApiStatus.Internal
static Point[] getNeighbors(Chunk chunk, int sectionY) {
int chunkX = chunk.getChunkX();
int chunkZ = chunk.getChunkZ();
Point[] links = new Vec[BlockFace.values().length];
for (BlockFace face : BlockFace.values()) {
Direction direction = face.toDirection();
int x = chunkX + direction.normalX();
int z = chunkZ + direction.normalZ();
int y = sectionY + direction.normalY();
Chunk foundChunk = chunk.getInstance().getChunk(x, z);
if (foundChunk == null) continue;
if (y - foundChunk.getMinSection() > foundChunk.getMaxSection() || y - foundChunk.getMinSection() < 0) continue;
links[face.ordinal()] = new Vec(foundChunk.getChunkX(), y, foundChunk.getChunkZ());
}
return links;
}
@ApiStatus.Internal
static boolean compareBorders(byte[] content, byte[] contentPropagation, byte[] contentPropagationTemp, BlockFace face) {
if (content == null && contentPropagation == null && contentPropagationTemp == null) return true;
final int k = switch (face) {
case WEST, BOTTOM, NORTH -> 0;
case EAST, TOP, SOUTH -> 15;
};
for (int bx = 0; bx < SECTION_SIZE; bx++) {
for (int by = 0; by < SECTION_SIZE; by++) {
final int posFrom = switch (face) {
case NORTH, SOUTH -> bx | (k << 4) | (by << 8);
case WEST, EAST -> k | (by << 4) | (bx << 8);
default -> bx | (by << 4) | (k << 8);
};
int valueFrom;
if (content == null && contentPropagation == null) valueFrom = 0;
else if (content != null && contentPropagation == null) valueFrom = getLight(content, posFrom);
else if (content == null && contentPropagation != null) valueFrom = getLight(contentPropagation, posFrom);
else valueFrom = Math.max(getLight(content, posFrom), getLight(contentPropagation, posFrom));
int valueTo = getLight(contentPropagationTemp, posFrom);
if (valueFrom < valueTo) return false;
}
}
return true;
}
}