From 36a0759426050336602e3495938b275ab59ce6fd Mon Sep 17 00:00:00 2001
From: Joseph Hirschfeld <joe@ibj.io>
Date: Thu, 3 Mar 2016 02:39:54 -0600
Subject: [PATCH] Change implementation of (tile)entity removal list


diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 9ee8c40a5..438624dd7 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -122,7 +122,7 @@ public abstract class Entity implements ICommandListener {
     private static final DataWatcherObject<Boolean> aC = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
     private static final DataWatcherObject<Boolean> aD = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
     private static final DataWatcherObject<Boolean> aE = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
-    public boolean aa;
+    public boolean aa; public boolean isAddedToChunk() { return aa; } // Paper - OBFHELPER
     public int ab; public int getChunkX() { return ab; } // Paper - OBFHELPER
     public int ac; public int getChunkY() { return ac; } // Paper - OBFHELPER
     public int ad; public int getChunkZ() { return ad; } // Paper - OBFHELPER
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 6d200b809..b814d965e 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -31,6 +31,11 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
 import org.bukkit.generator.ChunkGenerator;
 // CraftBukkit end
 
+// Paper start
+import java.util.Set;
+import com.google.common.collect.Sets;
+// Paper end
+
 public abstract class World implements IBlockAccess {
 
     private int a = 63;
@@ -61,11 +66,11 @@ public abstract class World implements IBlockAccess {
         }
     };
     // Spigot end
-    protected final List<Entity> f = Lists.newArrayList();
+    protected final Set<Entity> f = Sets.newHashSet(); // Paper
     public final List<TileEntity> tileEntityList = Lists.newArrayList();
     public final List<TileEntity> tileEntityListTick = Lists.newArrayList();
     private final List<TileEntity> b = Lists.newArrayList();
-    private final List<TileEntity> tileEntityListUnload = Lists.newArrayList();
+    private final Set<TileEntity> tileEntityListUnload = Sets.newHashSet(); // Paper
     public final List<EntityHuman> players = Lists.newArrayList();
     public final List<Entity> j = Lists.newArrayList();
     protected final IntHashMap<Entity> entitiesById = new IntHashMap();
@@ -1397,20 +1402,20 @@ public abstract class World implements IBlockAccess {
         this.entityList.removeAll(this.f);
 
         int j;
+        // Paper start - Set based removal lists
+        for (Entity e : this.f) {
+            j = e.getChunkZ();
+            int k = e.getChunkX();
 
-        for (i = 0; i < this.f.size(); ++i) {
-            entity = (Entity) this.f.get(i);
-            int k = entity.ab;
-
-            j = entity.ad;
-            if (entity.aa && this.isChunkLoaded(k, j, true)) {
-                this.getChunkAt(k, j).b(entity);
+            if (e.isAddedToChunk() && this.isChunkLoaded(k, j, true)) {
+                this.getChunkAt(k, j).b(e);
             }
         }
 
-        for (i = 0; i < this.f.size(); ++i) {
-            this.c((Entity) this.f.get(i));
+        for (Entity e : this.f) {
+            this.c(e);
         }
+        // Paper end
 
         this.f.clear();
         this.l();
-- 
2.15.1