From d4d5552df0da25daefef7df6e3f363ca7374947c Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 2 Apr 2020 02:42:24 -0400
Subject: [PATCH] Optimize Collision Chunk lookup and avoid loading far chunks

Try to use a faster chunk lookup for collision detection, and only
fall back to the original for nearby chunks.

The collision code takes an AABB and generates a cuboid of checks rather
than a cylinder, so at high velocity this can generate a lot of chunk checks.
---
 ...on-Chunk-lookup-and-avoid-loading-fa.patch | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 Spigot-Server-Patches/Optimize-Collision-Chunk-lookup-and-avoid-loading-fa.patch

diff --git a/Spigot-Server-Patches/Optimize-Collision-Chunk-lookup-and-avoid-loading-fa.patch b/Spigot-Server-Patches/Optimize-Collision-Chunk-lookup-and-avoid-loading-fa.patch
new file mode 100644
index 0000000000..cc62591943
--- /dev/null
+++ b/Spigot-Server-Patches/Optimize-Collision-Chunk-lookup-and-avoid-loading-fa.patch
@@ -0,0 +1,40 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <aikar@aikar.co>
+Date: Thu, 2 Apr 2020 02:37:57 -0400
+Subject: [PATCH] Optimize Collision Chunk lookup and avoid loading far chunks
+
+Try to use a faster chunk lookup for collision detection, and only
+fall back to the original for nearby chunks.
+
+The collision code takes an AABB and generates a cuboid of checks rather
+than a cylinder, so at high velocity this can generate a lot of chunk checks.
+
+diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
+index f851ed11df..d154487294 100644
+--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
++++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
+@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
+                 }
+ 
+                 while (cursorposition.a()) {
+-                    int k1 = cursorposition.b();
+-                    int l1 = cursorposition.c();
+-                    int i2 = cursorposition.d();
++                    int k1 = cursorposition.b();int x = k1; // Paper
++                    int l1 = cursorposition.c();int y = l1; // Paper
++                    int i2 = cursorposition.d();int z = i2; // Paper
+                     int j2 = cursorposition.e();
+ 
+                     if (j2 != 3) {
+                         int k2 = k1 >> 4;
+                         int l2 = i2 >> 4;
+-                        IBlockAccess iblockaccess = ICollisionAccess.this.c(k2, l2);
++                        // Paper start - ensure we don't load chunks for far away chunks
++                        boolean far = entity != null && MCUtil.distance(entity.locX(), entity.locY(), entity.locZ(), x, y, z) > 32;
++                        IBlockAccess iblockaccess = ICollisionAccess.this instanceof WorldServer ? ((WorldServer) ICollisionAccess.this).getChunkProvider().getChunkAtIfLoadedMainThread(k2, l2) : null;
++                        if (!far && iblockaccess == null) iblockaccess = ICollisionAccess.this.c(k2, l2);
++                        // Paper end
+ 
+                         if (iblockaccess != null) {
+                             blockposition_mutableblockposition.d(k1, l1, i2);
+--
\ No newline at end of file