Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream Update 1.20.6 #66

Closed
wants to merge 8 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static PhysicsResult handlePhysics(@NotNull BoundingBox boundingBox,
static Entity canPlaceBlockAt(Instance instance, Point blockPos, Block b) {
for (Entity entity : instance.getNearbyEntities(blockPos, 3)) {
final EntityType type = entity.getEntityType();
if (type == EntityType.ITEM || type == EntityType.ARROW)
if (!entity.hasCollision() || type == EntityType.ITEM || type == EntityType.ARROW)
continue;
// Marker Armor Stands should not prevent block placement
if (entity.getEntityMeta() instanceof ArmorStandMeta armorStandMeta && armorStandMeta.isMarker())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package net.minestom.server.command.builder.condition;


import net.kyori.adventure.text.Component;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.ConsoleSender;
import net.minestom.server.entity.Player;
Expand All @@ -10,19 +8,47 @@
* Common command conditions
*/
public class Conditions {
public static boolean playerOnly(CommandSender sender, String commandString) {
if (!(sender instanceof Player)) {
sender.sendMessage(Component.text("The command is only available for players"));
/**
* Will only execute if all command conditions succeed.
*/
public static CommandCondition all(CommandCondition... conditions) {
return (sender, commandString) -> {
for (CommandCondition condition : conditions) {
if (!condition.canUse(sender, commandString)) {
return false;
}
}

return true;
};
}

/**
* Will execute if one or more command conditions succeed.
*/
public static CommandCondition any(CommandCondition... conditions) {
return (sender, commandString) -> {
for (CommandCondition condition : conditions) {
if (condition.canUse(sender, commandString)) {
return true;
}
}

return false;
}
return true;
};
}

/**
* Will succeed if the command sender is a player.
*/
public static boolean playerOnly(CommandSender sender, String commandString) {
return sender instanceof Player;
}

/**
* Will succeed if the command sender is the server console.
*/
public static boolean consoleOnly(CommandSender sender, String commandString) {
if (!(sender instanceof ConsoleSender)) {
sender.sendMessage(Component.text("The command is only available from the console"));
return false;
}
return true;
return sender instanceof ConsoleSender;
}
}
6 changes: 6 additions & 0 deletions src/main/java/net/minestom/server/coordinate/Vec.java
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,12 @@ public interface Operator {
Math.floor(z)
);

Operator SIGNUM = (x, y, z) -> new Vec(
Math.signum(x),
Math.signum(y),
Math.signum(z)
);

@NotNull Vec apply(double x, double y, double z);
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/minestom/server/entity/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -1453,11 +1453,11 @@ public boolean hasEffect(@NotNull PotionEffect effect) {
* Gets the level of the specified effect.
*
* @param effect the effect type
* @return the effect level, 0 if not found
* @return the effect level, -1 if not found
*/
public int getEffectLevel(@NotNull PotionEffect effect) {
TimedPotion timedPotion = getEffect(effect);
return timedPotion == null ? 0 : timedPotion.potion().amplifier();
return timedPotion == null ? -1 : timedPotion.potion().amplifier();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;

public class PlayerProjectile extends LivingEntity {
public class PlayerProjectile extends Entity {
private final Entity shooter;
private long cooldown = 0;

Expand Down
91 changes: 54 additions & 37 deletions src/main/java/net/minestom/server/instance/LightingChunk.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package net.minestom.server.instance;

import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import net.minestom.server.collision.Shape;
import net.minestom.server.coordinate.Point;
Expand Down Expand Up @@ -41,8 +40,8 @@ public class LightingChunk extends DynamicChunk {
final CachedPacket lightCache = new CachedPacket(this::createLightPacket);
private LightData lightData;

boolean chunkLoaded = false;
private int highestBlock;
private boolean freezeInvalidation = false;

private final ReentrantLock packetGenerationLock = new ReentrantLock();
private final AtomicInteger resendTimer = new AtomicInteger(-1);
Expand Down Expand Up @@ -107,7 +106,15 @@ private boolean checkSkyOcclusion(Block block) {
return occludesBottom || occludesTop;
}

private void invalidateSection(int coordinate) {
public void setFreezeInvalidation(boolean freezeInvalidation) {
this.freezeInvalidation = freezeInvalidation;
}

public void invalidateNeighborsSection(int coordinate) {
if (freezeInvalidation) {
return;
}

for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
Chunk neighborChunk = instance.getChunk(chunkX + i, chunkZ + j);
Expand All @@ -126,6 +133,21 @@ private void invalidateSection(int coordinate) {
}
}

public void invalidateResendDelay() {
if (!doneInit || freezeInvalidation) {
return;
}

for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
Chunk neighborChunk = instance.getChunk(chunkX + i, chunkZ + j);
if (neighborChunk instanceof LightingChunk light) {
light.resendTimer.set(resendDelay);
}
}
}
}

@Override
public void setBlock(int x, int y, int z, @NotNull Block block,
@Nullable BlockHandler.Placement placement,
Expand All @@ -135,22 +157,10 @@ public void setBlock(int x, int y, int z, @NotNull Block block,

// Invalidate neighbor chunks, since they can be updated by this block change
int coordinate = ChunkUtils.getChunkCoordinate(y);
if (chunkLoaded) {
invalidateSection(coordinate);
if (doneInit && !freezeInvalidation) {
invalidateNeighborsSection(coordinate);
invalidateResendDelay();
this.lightCache.invalidate();

if (doneInit) {
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
Chunk neighborChunk = instance.getChunk(chunkX + i, chunkZ + j);
if (neighborChunk == null) continue;

if (neighborChunk instanceof LightingChunk light) {
light.resendTimer.set(resendDelay);
}
}
}
}
}
}

Expand All @@ -161,7 +171,6 @@ public void sendLighting() {

@Override
protected void onLoad() {
chunkLoaded = true;
doneInit = true;
}

Expand All @@ -176,27 +185,24 @@ public void onGenerate() {

invalidate();

MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
Chunk neighborChunk = instance.getChunk(chunkX + i, chunkZ + j);
if (neighborChunk == null) continue;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
Chunk neighborChunk = instance.getChunk(chunkX + i, chunkZ + j);
if (neighborChunk == null) continue;

if (neighborChunk instanceof LightingChunk light) {
if (light.doneInit) {
light.resendTimer.set(20);
light.invalidate();

if (neighborChunk instanceof LightingChunk light) {
for (int section = light.minSection; section < light.maxSection; section++) {
for (int section = minSection; section < maxSection; section++) {
light.getSection(section).blockLight().invalidate();
light.getSection(section).skyLight().invalidate();
}

light.invalidate();

light.resendTimer.set(20);
}
}
}
});

doneInit = true;
}
}

// Lazy compute occlusion map
Expand Down Expand Up @@ -337,11 +343,16 @@ private static Set<Chunk> flushQueue(Instance instance, Set<Point> queue, LightT
var section = chunk.getSection(point.blockY());
responseChunks.add(chunk);

var light = type == LightType.BLOCK ? section.blockLight() : section.skyLight();
Light light = switch(type) {
case BLOCK -> section.blockLight();
case SKY -> section.skyLight();
};

CompletableFuture<Void> task = CompletableFuture.runAsync(() -> {
if (queueType == QueueType.INTERNAL) light.calculateInternal(instance, chunk.getChunkX(), point.blockY(), chunk.getChunkZ());
else light.calculateExternal(instance, chunk, point.blockY());
switch (queueType) {
case INTERNAL -> light.calculateInternal(instance, chunk.getChunkX(), point.blockY(), chunk.getChunkZ());
case EXTERNAL -> light.calculateExternal(instance, chunk, point.blockY());
}

sections.add(light);

Expand Down Expand Up @@ -449,7 +460,8 @@ private static Set<Point> getNearbyRequired(Instance instance, Point point, Ligh

if (sectionPosition.blockY() < chunkCheck.getMaxSection() && sectionPosition.blockY() >= chunkCheck.getMinSection()) {
Section s = chunkCheck.getSection(sectionPosition.blockY());
if (!s.blockLight().requiresUpdate() && !s.skyLight().requiresUpdate()) continue;
if (type == LightType.BLOCK && !s.blockLight().requiresUpdate()) continue;
if (type == LightType.SKY && !s.skyLight().requiresUpdate()) continue;

collected.add(sectionPosition);
}
Expand Down Expand Up @@ -509,4 +521,9 @@ private static Set<Chunk> relight(Instance instance, Set<Point> queue, LightType
lightingChunk.entries.putAll(entries);
return lightingChunk;
}

@Override
public boolean isLoaded() {
return super.isLoaded() && doneInit;
}
}
Loading
Loading