--- ../src-base/minecraft/net/minecraft/world/biome/BiomeDecorator.java
+++ ../src-work/minecraft/net/minecraft/world/biome/BiomeDecorator.java
@@ -24,6 +24,14 @@
 import net.minecraftforge.common.*;
 import net.minecraftforge.event.terraingen.*;
 
+// Spigot Start
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.minecraft.world.chunk.Chunk;
+// Spigot End
+
 public class BiomeDecorator
 {
     public World currentWorld;
@@ -61,6 +69,7 @@
     public int clayPerChunk;
     public int bigMushroomsPerChunk;
     public boolean generateLakes;
+    private final List<Chunk> chunksToUnload = new ArrayList<Chunk>(); // Spigot
     private static final String __OBFID = "CL_00000164";
 
     public BiomeDecorator()
@@ -194,7 +203,7 @@
         {
             k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-            i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
+            i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
             WorldGenerator worldgenerator = p_150513_1_.getRandomWorldGenForGrass(this.randomGenerator);
             worldgenerator.generate(this.currentWorld, this.randomGenerator, k, i1, l);
         }
@@ -204,7 +213,7 @@
         {
             k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-            i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
+            i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
             (new WorldGenDeadBush(Blocks.deadbush)).generate(this.currentWorld, this.randomGenerator, k, i1, l);
         }
 
@@ -214,7 +223,7 @@
             k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
 
-            for (i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); i1 > 0 && this.currentWorld.isAirBlock(k, i1 - 1, l); --i1)
+            for (i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); i1 > 0 && this.currentWorld.isAirBlock(k, i1 - 1, l); --i1)  // Spigot
             {
                 ;
             }
@@ -229,7 +238,7 @@
             {
                 k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
                 l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-                i1 = this.currentWorld.getHeightValue(k, l);
+                i1 = this.getHighestBlockYAt(k, l); // Spigot
                 this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
             }
 
@@ -237,7 +246,7 @@
             {
                 k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
                 l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-                i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
+                i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
                 this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
             }
         }
@@ -246,7 +255,7 @@
         {
             j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-            l = nextInt(this.currentWorld.getHeightValue(j, k) * 2);
+            l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
             this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, j, l, k);
         }
 
@@ -254,7 +263,7 @@
         {
             j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-            l = nextInt(this.currentWorld.getHeightValue(j, k) * 2);
+            l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
             this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, j, l, k);
         }
 
@@ -263,7 +272,7 @@
         {
             k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-            i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
+            i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
             this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
         }
 
@@ -271,7 +280,7 @@
         {
             k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-            i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
+            i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
             this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
         }
 
@@ -280,7 +289,7 @@
         {
             j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-            l = nextInt(this.currentWorld.getHeightValue(j, k) * 2);
+            l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
             (new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, j, l, k);
         }
 
@@ -289,7 +298,7 @@
         {
             k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
             l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
-            i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2);
+            i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
             this.cactusGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
         }
 
@@ -313,6 +322,7 @@
             }
         }
 
+        this.unloadChunks(); // Spigot - unload chunks we force loaded
         MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
     }
 
@@ -360,6 +370,31 @@
         MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
     }
 
+    // Spigot start - force load chunks
+    private int getHighestBlockYAt(int i, int j)
+    {
+        // Make sure the chunk is loaded
+        if (!this.currentWorld.chunkExists(i >> 4, j >> 4))
+        {
+            // If not, load it, then add it to our unload list
+            this.chunksToUnload.add(this.currentWorld.getChunkFromChunkCoords(i >> 4, j >> 4));
+        }
+
+        return this.currentWorld.getHeightValue(i, j);
+    }
+
+    private void unloadChunks()
+    {
+        Iterator<Chunk> iter = this.chunksToUnload.iterator();
+
+        while (iter.hasNext())
+        {
+            this.currentWorld.getWorld().unloadChunk(iter.next().bukkitChunk);
+            iter.remove();
+        }
+    }
+    // Spigot end
+
     private int nextInt(int i) {
         if (i <= 1)
             return 0;
