From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Sauve <paul@technove.co>
Date: Sun, 13 Dec 2020 17:52:35 -0600
Subject: [PATCH] Reduce projectile chunk loading

Airplane
Copyright (C) 2020 Technove LLC

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/EntityProjectile.java
index e55061b6c04b4bde92404a6ef58ba9a52cd99c1d..24d205dd1f31ece82d5cf516b8642eb0172e1a97 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityProjectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityProjectile.java
@@ -4,6 +4,8 @@ import net.minecraft.core.BlockPosition;
 import net.minecraft.core.particles.Particles;
 import net.minecraft.network.protocol.Packet;
 import net.minecraft.network.protocol.game.PacketPlayOutSpawnEntity;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.util.MathHelper;
 import net.minecraft.world.entity.Entity;
 import net.minecraft.world.entity.EntityLiving;
 import net.minecraft.world.entity.EntityTypes;
@@ -102,6 +104,37 @@ public abstract class EntityProjectile extends IProjectile {
         this.setPosition(d0, d1, d2);
     }
 
+    private static int loadedThisTick = 0;
+    private static int loadedTick;
+
+    private int buffered = 0;
+
+    // Airplane start
+    @Override
+    public void setPosition(double d0, double d1, double d2) {
+        if (loadedTick != MinecraftServer.currentTick) {
+            loadedTick = MinecraftServer.currentTick;
+            loadedThisTick = 0;
+        }
+        int previousX = MathHelper.floor(this.locX()) >> 4, previousZ = MathHelper.floor(this.locZ()) >> 4;
+        int newX = MathHelper.floor(d0) >> 4, newZ = MathHelper.floor(d2) >> 4;
+        if (previousX != newX || previousZ != newZ) {
+            boolean isLoaded = this.world.isChunkLoaded(newX, newZ);
+            if (!isLoaded) {
+                if (loadedThisTick > 10) { // Airplane 10 = max chunks to load from projectiles in a tick todo config
+                    if (++buffered > 20) { // Airplane 20 = max chunks  a single projectile loads overall todo config
+                        this.die();
+                    }
+                    return;
+                }
+                loadedThisTick++;
+            }
+            buffered = 0;
+        }
+        super.setPosition(d0, d1, d2);
+    }
+    // Airplane end
+
     protected float k() {
         return 0.03F;
     }
