Skip to content

Commit

Permalink
feat: light system (#468)
Browse files Browse the repository at this point in the history
Co-authored-by: harryxi <[email protected]>
  • Loading branch information
smartcmd and harry-xi authored Nov 9, 2024
1 parent f7bb44f commit a755228
Show file tree
Hide file tree
Showing 60 changed files with 1,290 additions and 499 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,5 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
@ApiStatus.Internal
public @interface MinecraftVersionSensitive {
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,14 @@ public class BlockStateData {
@Builder.Default
protected float friction = DEFAULT_FRICTION;
/**
* The light level of the block state.
* The amount that light will be dampened when it passes through the block, in a range (0-15).
* Higher value means the light will be dampened more.
*/
@Builder.Default
protected int light = 15;
protected int lightDampening = 15;
/**
* The light emission of the block state.
* The amount of light this block will emit in a range (0-15).
* Higher value means more light will be emitted.
*/
@Builder.Default
protected int lightEmission = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import org.allaymc.api.math.location.Location3fc;
import org.allaymc.api.math.location.Location3ic;
import org.allaymc.api.math.position.Position3ic;
import org.allaymc.api.utils.MathUtils;
import org.allaymc.api.math.MathUtils;
import org.allaymc.api.world.Dimension;
import org.allaymc.api.world.World;
import org.allaymc.api.world.chunk.Chunk;
Expand Down Expand Up @@ -185,6 +185,17 @@ default boolean isAlive() {
*/
void teleport(Location3fc location);

/**
* Teleport the entity to the specified location asynchronously.
* <p>
* This method is safe to be used in world thread.
*
* @param location the location to teleport the entity to.
*/
default void teleportAsync(Location3fc location) {
Thread.ofVirtual().start(() -> teleport(location));
}

/**
* Teleport the entity to the specified location.
*
Expand All @@ -194,6 +205,17 @@ default void teleport(Location3ic location) {
teleport(new Location3f(location));
}

/**
* Teleport the entity to the specified location asynchronously.
* <p>
* This method is safe to be used in world thread.
*
* @param location the location to teleport the entity to.
*/
default void teleportAsync(Location3ic location) {
teleportAsync(new Location3f(location));
}

/**
* Get the runtime id of this entity.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.allaymc.api.entity.initinfo.EntityInitInfo;
import org.allaymc.api.entity.type.EntityTypes;
import org.allaymc.api.utils.Identifier;
import org.allaymc.api.utils.MathUtils;
import org.allaymc.api.math.MathUtils;

import java.util.concurrent.ThreadLocalRandom;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import org.allaymc.api.eventbus.event.player.PlayerDropItemEvent;
import org.allaymc.api.item.ItemStack;
import org.allaymc.api.item.interfaces.ItemAirStack;
import org.allaymc.api.utils.MathUtils;
import org.allaymc.api.math.MathUtils;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.allaymc.api.utils;
package org.allaymc.api.math;

import lombok.experimental.UtilityClass;
import org.joml.*;

import java.lang.Math;
Expand All @@ -12,46 +11,55 @@
*
* @author Cool_Loong | daoge_cmd
*/
@UtilityClass
public class MathUtils {
public final class MathUtils {

public Vector3ic CBVecToJOMLVec(org.cloudburstmc.math.vector.Vector3i cbVec) {
private static final float[] SIN_LOOK_UP_TABLE = new float[65536];

static {
for (int i = 0; i < 65536; i++) {
SIN_LOOK_UP_TABLE[i] = (float) Math.sin(i * Math.PI * 2.0D / 65536.0d);
}
}

private MathUtils() {throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");}

public static Vector3ic CBVecToJOMLVec(org.cloudburstmc.math.vector.Vector3i cbVec) {
return new Vector3i(cbVec.getX(), cbVec.getY(), cbVec.getZ());
}

public org.cloudburstmc.math.vector.Vector3i JOMLVecToCBVec(Vector3ic JOMLVec) {
public static org.cloudburstmc.math.vector.Vector3i JOMLVecToCBVec(Vector3ic JOMLVec) {
return org.cloudburstmc.math.vector.Vector3i.from(JOMLVec.x(), JOMLVec.y(), JOMLVec.z());
}

public Vector3dc CBVecToJOMLVec(org.cloudburstmc.math.vector.Vector3d cbVec) {
public static Vector3dc CBVecToJOMLVec(org.cloudburstmc.math.vector.Vector3d cbVec) {
return new Vector3d(cbVec.getX(), cbVec.getY(), cbVec.getZ());
}

public org.cloudburstmc.math.vector.Vector3d JOMLVecToCBVec(Vector3dc JOMLVec) {
public static org.cloudburstmc.math.vector.Vector3d JOMLVecToCBVec(Vector3dc JOMLVec) {
return org.cloudburstmc.math.vector.Vector3d.from(JOMLVec.x(), JOMLVec.y(), JOMLVec.z());
}

public Vector3fc CBVecToJOMLVec(org.cloudburstmc.math.vector.Vector3f cbVec) {
public static Vector3fc CBVecToJOMLVec(org.cloudburstmc.math.vector.Vector3f cbVec) {
return new Vector3f(cbVec.getX(), cbVec.getY(), cbVec.getZ());
}

public org.cloudburstmc.math.vector.Vector3f JOMLVecToCBVec(Vector3fc JOMLVec) {
public static org.cloudburstmc.math.vector.Vector3f JOMLVecToCBVec(Vector3fc JOMLVec) {
return org.cloudburstmc.math.vector.Vector3f.from(JOMLVec.x(), JOMLVec.y(), JOMLVec.z());
}

public Vector3i floor(Vector3dc vector3d) {
public static Vector3i floor(Vector3dc vector3d) {
return new Vector3i((int) Math.floor(vector3d.x()), (int) Math.floor(vector3d.y()), (int) Math.floor(vector3d.z()));
}

public Vector3i floor(Vector3fc vector3f) {
public static Vector3i floor(Vector3fc vector3f) {
return new Vector3i((int) Math.floor(vector3f.x()), (int) Math.floor(vector3f.y()), (int) Math.floor(vector3f.z()));
}

public Vector3i ceil(Vector3dc vector3d) {
public static Vector3i ceil(Vector3dc vector3d) {
return new Vector3i((int) Math.ceil(vector3d.x()), (int) Math.ceil(vector3d.y()), (int) Math.ceil(vector3d.z()));
}

public Vector3i ceil(Vector3fc vector3f) {
public static Vector3i ceil(Vector3fc vector3f) {
return new Vector3i((int) Math.ceil(vector3f.x()), (int) Math.ceil(vector3f.y()), (int) Math.ceil(vector3f.z()));
}

Expand All @@ -67,7 +75,7 @@ public static double round(double d, int precision) {
*
* @return result.
*/
public float fastFloatInverseSqrt(float x) {
public static float fastFloatInverseSqrt(float x) {
float xHalf = 0.5f * x;
int reEncode = Float.floatToIntBits(x);
reEncode = 0x5f3759df - (reEncode >> 1);
Expand All @@ -83,7 +91,7 @@ public float fastFloatInverseSqrt(float x) {
*
* @return result.
*/
public double fastDoubleInverseSqrt(double x) {
public static double fastDoubleInverseSqrt(double x) {
double xHalf = 0.5d * x;
long reEncode = Double.doubleToLongBits(x);
reEncode = 0x5fe6ec85e7de30daL - (reEncode >> 1);
Expand All @@ -101,7 +109,7 @@ public double fastDoubleInverseSqrt(double x) {
*
* @return {@code true} if the value is in the range, otherwise {@code false}.
*/
public boolean isInRange(float l, float value, float r) {
public static boolean isInRange(float l, float value, float r) {
return l <= value && value <= r;
}

Expand All @@ -113,7 +121,7 @@ public boolean isInRange(float l, float value, float r) {
*
* @return direction vector.
*/
public Vector3f getDirectionVector(double yaw, double pitch) {
public static Vector3f getDirectionVector(double yaw, double pitch) {
var pitch0 = toRadians(pitch + 90);
var yaw0 = toRadians(yaw + 90);
var x = sin(pitch0) * cos(yaw0);
Expand All @@ -129,7 +137,7 @@ public Vector3f getDirectionVector(double yaw, double pitch) {
*
* @return yaw.
*/
public double getYawFromVector(Vector3fc vector) {
public static double getYawFromVector(Vector3fc vector) {
double length = vector.x() * vector.x() + vector.z() * vector.z();
// Prevent NAN
if (length == 0) {
Expand All @@ -146,7 +154,7 @@ public double getYawFromVector(Vector3fc vector) {
*
* @return pitch.
*/
public double getPitchFromVector(Vector3fc vector) {
public static double getPitchFromVector(Vector3fc vector) {
double length =
vector.x() * vector.x() +
vector.z() * vector.z() +
Expand All @@ -158,4 +166,20 @@ public double getPitchFromVector(Vector3fc vector) {
var pitch = toDegrees(asin(-vector.y() / sqrt(length)));
return StrictMath.abs(pitch) < 1E-10 ? 0 : pitch;
}

public static float fastSin(float p) {
return SIN_LOOK_UP_TABLE[((int) (p * 10430.378F) & 0xFFFF)];
}

public static float fastSin(double p) {
return SIN_LOOK_UP_TABLE[((int) (p * 10430.378F) & 0xFFFF)];
}

public static float fastCos(float p) {
return SIN_LOOK_UP_TABLE[((int) (p * 10430.378F + 16384.0F) & 0xFFFF)];
}

public static float fastCos(double p) {
return SIN_LOOK_UP_TABLE[((int) (p * 10430.378F + 16384.0F) & 0xFFFF)];
}
}
7 changes: 7 additions & 0 deletions api/src/main/java/org/allaymc/api/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ default void disconnectAllPlayers(@MayContainTrKey String reason) {
*/
boolean isRunning();

/**
* Check if the server is starting.
*
* @return {@code true} if the server is starting, otherwise {@code false}.
*/
boolean isStarting();

/**
* Get the player storage.
*
Expand Down
13 changes: 12 additions & 1 deletion api/src/main/java/org/allaymc/api/server/ServerSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public static class WorldConfig extends OkaeriConfig {
@CustomKey("chunk-sending-strategy")
private ChunkSendingStrategy chunkSendingStrategy = ChunkSendingStrategy.ASYNC;

@Comment("Determines the minimum number of chunks that must to be sent to the client which is joining the server")
@Comment("Determines the minimum number of chunks that must be sent to the client which is joining the server")
@Comment("Decrease this value may reduce the time on joining server. However, client may see a lot of unloaded chunks if the value is too low")
@CustomKey("fully-join-chunk-threshold")
private int fullyJoinChunkThreshold = 30;
Expand All @@ -161,6 +161,17 @@ public static class WorldConfig extends OkaeriConfig {
@CustomKey("spawn-point-chunk-radius")
private int spawnPointChunkRadius = 3;

@Comment("Whether to use independent light thread for light calculation")
@Comment("If set to true, the light calculation will be done in a separate thread")
@Comment("And each dimension will have a light thread")
@CustomKey("enable-independent-light-thread")
private boolean enableIndependentLightThread = true;

@Comment("Determines the maximum number of light updates that can be processed per tick")
@Comment("This only be effective when independent light thread is disabled")
@CustomKey("max-light-update-count-per-tick")
private int maxLightUpdateCountPerTick = 128;

public enum ChunkSendingStrategy {
ASYNC,
SYNC
Expand Down
25 changes: 14 additions & 11 deletions api/src/main/java/org/allaymc/api/world/Dimension.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,9 @@
import org.allaymc.api.item.ItemStack;
import org.allaymc.api.math.position.Position3i;
import org.allaymc.api.math.position.Position3ic;
import org.allaymc.api.utils.MathUtils;
import org.allaymc.api.math.MathUtils;
import org.allaymc.api.utils.Utils;
import org.allaymc.api.world.generator.WorldGenerator;
import org.allaymc.api.world.service.BlockUpdateService;
import org.allaymc.api.world.service.ChunkService;
import org.allaymc.api.world.service.EntityPhysicsService;
import org.allaymc.api.world.service.EntityService;
import org.allaymc.api.world.service.*;
import org.apache.commons.lang3.function.TriFunction;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i;
Expand Down Expand Up @@ -98,6 +94,13 @@ static UpdateBlockPacket createUpdateBlockPacket(BlockState newBlockState, int x
*/
EntityService getEntityService();

/**
* Get the light service of this dimension.
*
* @return the light service.
*/
LightService getLightService();

/**
* Get the dimension info of this dimension.
*
Expand Down Expand Up @@ -460,12 +463,12 @@ default <DATATYPE> void updateBlockProperty(BlockPropertyType<DATATYPE> property
chunk.sendChunkPacket(createUpdateBlockPacket(newBlockState, x, y, z, layer));
}

default BlockState[][][] getCollidingBlocks(AABBfc aabb) {
return getCollidingBlocks(aabb, 0);
default BlockState[][][] getCollidingBlockStates(AABBfc aabb) {
return getCollidingBlockStates(aabb, 0);
}

default BlockState[][][] getCollidingBlocks(AABBfc aabb, int layer) {
return getCollidingBlocks(aabb, layer, false);
default BlockState[][][] getCollidingBlockStates(AABBfc aabb, int layer) {
return getCollidingBlockStates(aabb, layer, false);
}

/**
Expand All @@ -477,7 +480,7 @@ default BlockState[][][] getCollidingBlocks(AABBfc aabb, int layer) {
*
* @return the block states that collide with the specified AABB.
*/
default BlockState[][][] getCollidingBlocks(AABBfc aabb, int layer, boolean ignoreCollision) {
default BlockState[][][] getCollidingBlockStates(AABBfc aabb, int layer, boolean ignoreCollision) {
var maxX = (int) Math.ceil(aabb.maxX());
var maxY = (int) Math.ceil(aabb.maxY());
var maxZ = (int) Math.ceil(aabb.maxZ());
Expand Down
13 changes: 7 additions & 6 deletions api/src/main/java/org/allaymc/api/world/DimensionInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ public record DimensionInfo(
int dimensionId,
int minHeight,
int maxHeight,
int chunkSectionSize
int chunkSectionCount,
boolean hasSkyLight
) {

public static final DimensionInfo OVERWORLD = new DimensionInfo(0, -64, 319, 24);
public static final DimensionInfo NETHER = new DimensionInfo(1, 0, 127, 8);
public static final DimensionInfo THE_END = new DimensionInfo(2, 0, 255, 16);
public static final DimensionInfo OVERWORLD = new DimensionInfo(0, -64, 319, 24, true);
public static final DimensionInfo NETHER = new DimensionInfo(1, 0, 127, 8, false);
public static final DimensionInfo THE_END = new DimensionInfo(2, 0, 255, 16, false);

public DimensionInfo(int dimensionId, int minHeight, int maxHeight) {
this(dimensionId, minHeight, maxHeight, (maxHeight - minHeight + 1) / 16);
public DimensionInfo(int dimensionId, int minHeight, int maxHeight, boolean hasSkyLight) {
this(dimensionId, minHeight, maxHeight, (maxHeight - minHeight + 1) / 16, hasSkyLight);
Preconditions.checkArgument(minHeight >= -512 && minHeight <= 512);
Preconditions.checkArgument(maxHeight >= -512 && maxHeight <= 512);
}
Expand Down
22 changes: 0 additions & 22 deletions api/src/main/java/org/allaymc/api/world/chunk/Chunk.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,28 +131,6 @@ default Set<EntityPlayer> getPlayerChunkLoaders() {
*/
void compareAndSetBiome(int x, int y, int z, BiomeType expectedValue, BiomeType newValue);

/**
* Compare and set block light at the specified position.
*
* @param x the x coordinate.
* @param y the y coordinate.
* @param z the z coordinate.
* @param expectedValue the expected block light level.
* @param newValue the new block light level.
*/
void compareAndSetBlockLight(int x, int y, int z, int expectedValue, int newValue);

/**
* Compare and set skylight at the specified position.
*
* @param x the x coordinate.
* @param y the y coordinate.
* @param z the z coordinate.
* @param expectedValue the expected skylight level.
* @param newValue the new skylight level.
*/
void compareAndSetSkyLight(int x, int y, int z, int expectedValue, int newValue);

/**
* Compare and set height at the specified position.
*
Expand Down
Loading

0 comments on commit a755228

Please sign in to comment.