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 bfb1de19f53d5d7c7b65e25a606fabfa416706b3..ae2eede559bd9fe7e500ce180f2ac102a95d3856 100644 --- a/src/main/java/io/papermc/paper/util/CollisionUtil.java +++ b/src/main/java/io/papermc/paper/util/CollisionUtil.java @@ -1595,6 +1595,7 @@ public final class CollisionUtil { public static final int COLLISION_FLAG_COLLIDE_WITH_UNLOADED_CHUNKS = 1 << 1; public static final int COLLISION_FLAG_CHECK_BORDER = 1 << 2; public static final int COLLISION_FLAG_CHECK_ONLY = 1 << 3; + public static final int COLLISION_FLAG_ADD_TICKET = 1 << 4; // Sakura public static boolean getCollisionsForBlocksOrWorldBorder(final Level world, final Entity entity, final AABB aabb, final List intoVoxel, final List intoAABB, @@ -1644,11 +1645,20 @@ public final class CollisionUtil { final int maxChunkZ = maxBlockZ >> 4; final boolean loadChunks = (collisionFlags & COLLISION_FLAG_LOAD_CHUNKS) != 0; + final boolean addTicket = (collisionFlags & COLLISION_FLAG_ADD_TICKET) != 0; // Sakura final ServerChunkCache chunkSource = (ServerChunkCache)world.getChunkSource(); for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { final ChunkAccess chunk = loadChunks ? chunkSource.getChunk(currChunkX, currChunkZ, ChunkStatus.FULL, true) : chunkSource.getChunkAtIfLoadedImmediately(currChunkX, currChunkZ); + // Sakura start - keep chunks loaded on movement + if (addTicket) { + chunkSource.chunkMap.getDistanceManager().getChunkHolderManager().addTicketAtLevel(net.minecraft.server.level.TicketType.ENTITY_MOVEMENT, currChunkX, currChunkZ, 33, CoordinateUtils.getChunkKey(currChunkX, currChunkZ)); + // This is known to work, uncomment if any issues + // var pos = new net.minecraft.world.level.ChunkPos(currChunkX, currChunkZ); + // chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.ENTITY_MOVEMENT, pos, 33, pos.toLong()); + } + // Sakura end if (chunk == null) { if ((collisionFlags & COLLISION_FLAG_COLLIDE_WITH_UNLOADED_CHUNKS) != 0) { diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java index 658e63ebde81dc14c8ab5850fb246dc0aab25dea..f1ff1a67fee37ee7b241ceaa164fa4ee64d3767b 100644 --- a/src/main/java/net/minecraft/server/level/TicketType.java +++ b/src/main/java/net/minecraft/server/level/TicketType.java @@ -37,6 +37,7 @@ public class TicketType { public static final TicketType NON_FULL_SYNC_LOAD = create("non_full_sync_load", Long::compareTo); public static final TicketType DELAY_UNLOAD = create("delay_unload", Comparator.comparingLong(ChunkPos::toLong), 1); // 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 a52530dbcd8a3e48a26f13fb246e8183ee560b07..1297012df74a2c955c4f0c87697f802a70ad16f3 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -398,6 +398,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled public boolean persistentInvisibility = false; + public boolean loadChunks = false; // Sakura - load chunks public BlockPos lastLavaContact; // Spigot start public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); @@ -1490,7 +1491,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { io.papermc.paper.util.CollisionUtil.getCollisions( world, this, collisionBox, potentialCollisionsVoxel, potentialCollisionsBB, - (0), + (loadChunks ? io.papermc.paper.util.CollisionUtil.COLLISION_FLAG_LOAD_CHUNKS | io.papermc.paper.util.CollisionUtil.COLLISION_FLAG_ADD_TICKET : 0), // Sakura null, null ); @@ -4812,7 +4813,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @Override public boolean isAlwaysTicking() { - return false; + return 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 e2f34595a535582d2722f68dc88b777704ef641a..354e210a52e5ce7b1b8cf75ce132e59c02f664ab 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -74,6 +74,7 @@ public class FallingBlockEntity extends Entity { this.dropItem = true; this.fallDamageMax = 40; this.isFallingBlock = true; // Sakura + this.loadChunks = world.sakuraConfig().cannons.sand.loadsChunks; // Sakura - 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 5b4e1d56f63935c5b6506dc94d174e8efebd260f..4c328a511ff6c0e6b73ef9701c82373e02c12830 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -32,6 +32,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { super(type, world); this.blocksBuilding = true; this.isPrimedTNT = true; // Sakura + this.loadChunks = world.sakuraConfig().cannons.tnt.loadsChunks; // Sakura - load chunks } public PrimedTnt(Level world, double x, double y, double z, @Nullable LivingEntity igniter) {