From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik Date: Sat, 11 Sep 2021 19:19:41 +0100 Subject: [PATCH] Load Chunks on Movement diff --git a/src/main/java/io/papermc/paper/util/CollisionUtil.java b/src/main/java/io/papermc/paper/util/CollisionUtil.java index a87f6380b2c387fb0cdd40d5087b5c93492e3c88..4db0a1b1270e2ff1ea1a4723b3dd28860f4c2087 100644 --- a/src/main/java/io/papermc/paper/util/CollisionUtil.java +++ b/src/main/java/io/papermc/paper/util/CollisionUtil.java @@ -403,9 +403,17 @@ public final class CollisionUtil { return boxMinX < borderMinX || boxMaxX > borderMaxX || boxMinZ < borderMinZ || boxMaxZ > borderMaxZ; } + // Sakura start - load chunks on movement public static boolean getCollisionsForBlocksOrWorldBorder(final CollisionGetter getter, final Entity entity, final AABB aabb, - final List into, final boolean loadChunks, final boolean collidesWithUnloaded, - final boolean checkBorder, final boolean checkOnly, final BiPredicate predicate) { + final List into, final boolean loadChunks, final boolean collidesWithUnloaded, + final boolean checkBorder, final boolean checkOnly, final BiPredicate predicate) { + return getCollisionsForBlocksOrWorldBorder(getter, entity, aabb, into, loadChunks, collidesWithUnloaded, checkBorder, false, checkOnly, predicate); + } + public static boolean getCollisionsForBlocksOrWorldBorder(final CollisionGetter getter, final Entity entity, final AABB aabb, + final List into, final boolean loadChunks, final boolean collidesWithUnloaded, + final boolean checkBorder, final boolean addTicket, final boolean checkOnly, + final BiPredicate predicate) { + // Sakura end - load chunks on movement boolean ret = false; if (checkBorder) { @@ -479,8 +487,17 @@ public final class CollisionUtil { final ChunkAccess chunk; if (chunkProvider == null) { chunk = (ChunkAccess)getter.getChunkForCollisions(currChunkX, currChunkZ); + // Sakura start - load chunks on movement + } else if (loadChunks) { + chunk = chunkProvider.getChunk(currChunkX, currChunkZ, true); + if (addTicket && chunk instanceof net.minecraft.world.level.chunk.LevelChunk levelChunk && levelChunk.movementLoadTicketRequiresUpdate()) { + net.minecraft.world.level.ChunkPos chunkPos = new net.minecraft.world.level.ChunkPos(currChunkX, currChunkZ); + chunkProvider.addTicketAtLevel(net.minecraft.server.level.TicketType.ENTITY_MOVEMENT, chunkPos, 33, chunkPos.toLong()); + levelChunk.updatedMovementLoadTicket(); + } } else { - chunk = loadChunks ? chunkProvider.getChunk(currChunkX, currChunkZ, true) : chunkProvider.getChunkAtIfLoadedImmediately(currChunkX, currChunkZ); + chunk = chunkProvider.getChunkAtIfLoadedImmediately(currChunkX, currChunkZ); + // Sakura end - load chunks on movement } if (chunk == null) { @@ -846,16 +863,24 @@ public final class CollisionUtil { return ret; } + // Sakura start - load chunks on movement public static boolean getCollisions(final CollisionGetter view, final Entity entity, final AABB aabb, final List into, final boolean loadChunks, final boolean collidesWithUnloadedChunks, final boolean checkBorder, final boolean checkOnly, final BiPredicate blockPredicate, final Predicate entityPredicate) { + return getCollisions(view, entity, aabb, into, loadChunks, collidesWithUnloadedChunks, checkBorder, false, checkOnly, blockPredicate, entityPredicate); + } + public static boolean getCollisions(final CollisionGetter view, final Entity entity, final AABB aabb, + final List into, final boolean loadChunks, final boolean collidesWithUnloadedChunks, + final boolean checkBorder, final boolean addTicket, final boolean checkOnly, + final BiPredicate blockPredicate, final Predicate entityPredicate) { if (checkOnly) { - return getCollisionsForBlocksOrWorldBorder(view, entity, aabb, into, loadChunks, collidesWithUnloadedChunks, checkBorder, checkOnly, blockPredicate) + return getCollisionsForBlocksOrWorldBorder(view, entity, aabb, into, loadChunks, collidesWithUnloadedChunks, checkBorder, addTicket, checkOnly, blockPredicate) || getEntityHardCollisions(view, entity, aabb, into, checkOnly, entityPredicate); } else { - return getCollisionsForBlocksOrWorldBorder(view, entity, aabb, into, loadChunks, collidesWithUnloadedChunks, checkBorder, checkOnly, blockPredicate) + return getCollisionsForBlocksOrWorldBorder(view, entity, aabb, into, loadChunks, collidesWithUnloadedChunks, checkBorder, addTicket, checkOnly, blockPredicate) | getEntityHardCollisions(view, entity, aabb, into, checkOnly, entityPredicate); + // Sakura end - load chunks on movement } } diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java index 97d1ff2af23bac14e67bca5896843325aaa5bfc1..c90b265a9cd92d40960d5513d9585e47d93fed3c 100644 --- a/src/main/java/net/minecraft/server/level/TicketType.java +++ b/src/main/java/net/minecraft/server/level/TicketType.java @@ -35,6 +35,7 @@ public class TicketType { public static final TicketType POI_LOAD = create("poi_load", Long::compareTo); public static final TicketType UNLOAD_COOLDOWN = create("unload_cooldown", (u1, u2) -> 0, 5 * 20); // Paper end - rewrite chunk system + public static final TicketType ENTITY_MOVEMENT = create("entity_movement", Long::compareTo, 10 * 20); // Sakura public static TicketType create(String name, Comparator argumentComparator) { return new TicketType<>(name, argumentComparator, 0L); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 3b6efce07745df062d5d3ef60011718842217336..0025d08527f41c0d19f4a713ef072fae008cec25 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -545,6 +545,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public boolean isPrimedTNT; public boolean isFallingBlock; // Sakura end - visibility api and command + public boolean loadChunks = false; // Sakura - load chunks on cannon entity movement public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); @@ -1393,8 +1394,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } } - io.papermc.paper.util.CollisionUtil.getCollisions(world, this, collisionBox, potentialCollisions, false, this.level.paperConfig().chunks.preventMovingIntoUnloadedChunks, - false, false, null, null); + io.papermc.paper.util.CollisionUtil.getCollisions(world, this, collisionBox, potentialCollisions, this.loadChunks, this.level.paperConfig().chunks.preventMovingIntoUnloadedChunks, // Sakura - load chunks on movement + false, this.loadChunks, false, null, null); // Sakura - load chunks on movement if (collidingWithWorldBorder = io.papermc.paper.util.CollisionUtil.isCollidingWithBorderEdge(world.getWorldBorder(), collisionBox)) { // Paper - this line *is* correct, ignore the IDE warning about assignments being used as a condition io.papermc.paper.util.CollisionUtil.addBoxesToIfIntersects(world.getWorldBorder().getCollisionShape(), collisionBox, potentialCollisions); @@ -4532,12 +4533,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @Override public boolean shouldBeSaved() { - return this.removalReason != null && !this.removalReason.shouldSave() ? false : (this.isPassenger() ? false : !this.isVehicle() || !this.hasAnyPlayerPassengers()); // Paper - rewrite chunk system - it should check if the entity has ANY player passengers + return this.removalReason != null && !this.removalReason.shouldSave() ? false : (this.loadChunks || this.isPassenger() ? false : !this.isVehicle() || !this.hasAnyPlayerPassengers()); // Sakura - used to determine whether a chunk should unload // Paper - rewrite chunk system - it should check if the entity has ANY player passengers } @Override public boolean isAlwaysTicking() { - return false; + return this.loadChunks; // Sakura - always tick in chunks } public boolean mayInteract(Level world, BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java index 1a83f88e7759b168d6f3c2f6ed4532d65a7cf437..3559457024f5c9bef4c44a27514e338c7d2b4172 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -71,6 +71,7 @@ public class FallingBlockEntity extends Entity { this.dropItem = true; this.fallDamageMax = 40; this.isFallingBlock = true; // Sakura + this.loadChunks = world.sakuraConfig().cannons.loadChunks; // Sakura - falling blocks load chunks } public FallingBlockEntity(Level world, double x, double y, double z, BlockState block) { diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java index 7d2a2d69241344593b691321ba859e5ba246d15d..5761b786f036df1516189edd67ea4439d64c6ea8 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -28,6 +28,7 @@ public class PrimedTnt extends Entity { super(type, world); this.blocksBuilding = true; this.isPrimedTNT = true; // Sakura + this.loadChunks = world.sakuraConfig().cannons.loadChunks; // Sakura - tnt load chunks } public PrimedTnt(Level world, double x, double y, double z, @Nullable LivingEntity igniter) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java index 28e4b302284f955a73e75d0f4276d55fb51826f5..2bb7195bdb977de6b899cade0847cd6414f3eae2 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -361,6 +361,17 @@ public class LevelChunk extends ChunkAccess { } } // Paper end - optimise checkDespawn + // Sakura start + private long lastMovementLoadTicket = 0; + + public boolean movementLoadTicketRequiresUpdate() { + return net.minecraft.server.MinecraftServer.currentTickLong - this.lastMovementLoadTicket >= 100; + } + + public void updatedMovementLoadTicket() { + this.lastMovementLoadTicket = net.minecraft.server.MinecraftServer.currentTickLong; + } + // Sakura end public LevelChunk(ServerLevel world, ProtoChunk protoChunk, @Nullable LevelChunk.PostLoadProcessor entityLoader) { this(world, protoChunk.getPos(), protoChunk.getUpgradeData(), protoChunk.unpackBlockTicks(), protoChunk.unpackFluidTicks(), protoChunk.getInhabitedTime(), protoChunk.getSections(), entityLoader, protoChunk.getBlendingData());