diff --git a/.gitignore b/.gitignore
index 3827bdefa8..6785057323 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,3 +48,4 @@ CraftBukkit
Paperclip
Paperclip.jar
paperclip.jar
+paperclip-*.jar
diff --git a/BuildData b/BuildData
index 29cbded5ff..46d0be39f2 160000
--- a/BuildData
+++ b/BuildData
@@ -1 +1 @@
-Subproject commit 29cbded5ff05b66a9af3ac22efe07031d5fb5742
+Subproject commit 46d0be39f2fae4732ebe544dfada3949a18e2092
diff --git a/Bukkit b/Bukkit
index 56605a05f6..8ce4d2f45f 160000
--- a/Bukkit
+++ b/Bukkit
@@ -1 +1 @@
-Subproject commit 56605a05f6c85762d46b0b76b9eb20cfc7991e7e
+Subproject commit 8ce4d2f45fbdb7cd85346b220f6a9d34f2000910
diff --git a/CraftBukkit b/CraftBukkit
index 7fc5cd856e..8b61cc5208 160000
--- a/CraftBukkit
+++ b/CraftBukkit
@@ -1 +1 @@
-Subproject commit 7fc5cd856e46182e727f383a911ffa46326611f1
+Subproject commit 8b61cc52088ccb9220970740a4905baf3781a680
diff --git a/Paperclip b/Paperclip
index 1d8ff24ec3..9bb246f7f1 160000
--- a/Paperclip
+++ b/Paperclip
@@ -1 +1 @@
-Subproject commit 1d8ff24ec3fff88334498bfb4071b6b6c834cc07
+Subproject commit 9bb246f7f19963ef91e22af3e05a315ee5e5e746
diff --git a/Spigot b/Spigot
index d20369fcad..1480adb827 160000
--- a/Spigot
+++ b/Spigot
@@ -1 +1 @@
-Subproject commit d20369fcad255c6ab18fab8180fac63ff4cedec3
+Subproject commit 1480adb82751e38cca5bcc75202ece68277b0113
diff --git a/Spigot-API-Patches/POM-changes.patch b/Spigot-API-Patches/POM-changes.patch
index 9ff814de3f..b377935509 100644
--- a/Spigot-API-Patches/POM-changes.patch
+++ b/Spigot-API-Patches/POM-changes.patch
@@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- spigot-api
+ com.destroystokyo.paper
+ paper-api
- 1.9-R0.1-SNAPSHOT
+ 1.9.2-R0.1-SNAPSHOT
jar
- Spigot-API
diff --git a/Spigot-Server-Patches/Configurable-TNT-cannon-fix.patch b/Spigot-Server-Patches/Configurable-TNT-cannon-fix.patch
index f4c04a40d3..c5c7025b51 100644
--- a/Spigot-Server-Patches/Configurable-TNT-cannon-fix.patch
+++ b/Spigot-Server-Patches/Configurable-TNT-cannon-fix.patch
@@ -168,7 +168,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
world.addEntity(entitytntprimed);
- world.a((EntityHuman) null, entitytntprimed.locX, entitytntprimed.locY, entitytntprimed.locZ, SoundEffects.gj, SoundCategory.BLOCKS, 1.0F, 1.0F);
+ world.a((EntityHuman) null, entitytntprimed.locX, entitytntprimed.locY, entitytntprimed.locZ, SoundEffects.gk, SoundCategory.BLOCKS, 1.0F, 1.0F);
diff --git a/src/main/java/net/minecraft/server/DispenserRegistry.java b/src/main/java/net/minecraft/server/DispenserRegistry.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/DispenserRegistry.java
diff --git a/Spigot-Server-Patches/Fix-redstone-lag-issues.patch b/Spigot-Server-Patches/Fix-redstone-lag-issues.patch
deleted file mode 100644
index 07d6899f6c..0000000000
--- a/Spigot-Server-Patches/Fix-redstone-lag-issues.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Zach Brown <1254957+zachbr@users.noreply.github.com>
-Date: Wed, 2 Mar 2016 00:21:24 -0600
-Subject: [PATCH] Fix redstone lag issues
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -0,0 +0,0 @@ public class PaperWorldConfig {
- netherVoidTopDamage = getBoolean( "nether-ceiling-void-damage", false );
- log("Top of the nether void damage: " + netherVoidTopDamage);
- }
-+
-+ public int tickNextTickCap;
-+ public boolean tickNextTickListCapIgnoresRedstone;
-+ private void tickNextTickCap() {
-+ tickNextTickCap = getInt("tick-next-tick-list-cap", 1000); // Higher values will be friendlier to vanilla style mechanics (to a point) but may hurt performance
-+ tickNextTickListCapIgnoresRedstone = getBoolean("tick-next-tick-list-cap-ignores-redstone", false); // Redstone TickNextTicks will always bypass the preceding cap
-+ log("WorldServer TickNextTick cap set at " + tickNextTickCap);
-+ log("WorldServer TickNextTickList cap always processes redstone: " + tickNextTickListCapIgnoresRedstone);
-+
-+ }
-+
- }
-diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/WorldServer.java
-+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
- if (false) { // CraftBukkit
- throw new IllegalStateException("TickNextTick list out of synch");
- } else {
-+ // Paper start - No, stop doing this, it affects things like redstone
-+ /*
- if (i > 1000) {
- // CraftBukkit start - If the server has too much to process over time, try to alleviate that
- if (i > 20 * 1000) {
-@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
- }
- // CraftBukkit end
- }
-+ */
-+ if (i > paperConfig.tickNextTickCap) {
-+ i = paperConfig.tickNextTickCap;
-+ }
-+ // Paper end
-
- this.methodProfiler.a("cleaning");
-
-@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
- }
- timings.scheduledBlocksCleanup.stopTiming(); // Paper
-
-+ // Paper start - Allow redstone ticks to bypass the tickNextTickListCap
-+ if (paperConfig.tickNextTickListCapIgnoresRedstone) {
-+ Iterator iterator = this.nextTickList.iterator();
-+ while (iterator.hasNext()) {
-+ NextTickListEntry next = iterator.next();
-+ if (!flag && next.b > this.worldData.getTime()) {
-+ break;
-+ }
-+
-+ IBlockData data = next.a().getBlockData();
-+ if (next.a().isPowerSource(data) || next.a() instanceof IInventory) {
-+ iterator.remove();
-+ this.U.add(next);
-+ }
-+ }
-+ }
-+ // Paper end
-+
- this.methodProfiler.b();
- this.methodProfiler.a("ticking");
- timings.scheduledBlocksTicking.startTiming(); // Paper
---
\ No newline at end of file
diff --git a/Spigot-Server-Patches/Lighting-Queue.patch b/Spigot-Server-Patches/Lighting-Queue.patch
index 62df13fc4d..e745354d36 100644
--- a/Spigot-Server-Patches/Lighting-Queue.patch
+++ b/Spigot-Server-Patches/Lighting-Queue.patch
@@ -21,9 +21,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
-
+ netherVoidTopDamage = getBoolean( "nether-ceiling-void-damage", false );
+ log("Top of the nether void damage: " + netherVoidTopDamage);
}
-
++
++ public int tickNextTickCap;
++ public boolean tickNextTickListCapIgnoresRedstone;
++ private void tickNextTickCap() {
++ tickNextTickCap = getInt("tick-next-tick-list-cap", 1000); // Higher values will be friendlier to vanilla style mechanics (to a point) but may hurt performance
++ tickNextTickListCapIgnoresRedstone = getBoolean("tick-next-tick-list-cap-ignores-redstone", false); // Redstone TickNextTicks will always bypass the preceding cap
++ log("WorldServer TickNextTick cap set at " + tickNextTickCap);
++ log("WorldServer TickNextTickList cap always processes redstone: " + tickNextTickListCapIgnoresRedstone);
++
++ }
++
+ public boolean queueLightUpdates;
+ private void queueLightUpdates() {
+ queueLightUpdates = getBoolean("queue-light-updates", false);
diff --git a/Spigot-Server-Patches/MC-Dev-fixes.patch b/Spigot-Server-Patches/MC-Dev-fixes.patch
new file mode 100644
index 0000000000..990c7f7a69
--- /dev/null
+++ b/Spigot-Server-Patches/MC-Dev-fixes.patch
@@ -0,0 +1,86 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar
+Date: Wed, 30 Mar 2016 19:36:20 -0400
+Subject: [PATCH] MC Dev fixes
+
+
+diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/BaseBlockPosition.java
++++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java
+@@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable {
+ return Objects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString();
+ }
+
+- public int compareTo(Object object) {
++ public int compareTo(BaseBlockPosition object) { // Paper - decompile fix
+ return this.i((BaseBlockPosition) object);
+ }
+ }
+diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/BiomeBase.java
++++ b/src/main/java/net/minecraft/server/BiomeBase.java
+@@ -0,0 +0,0 @@ public abstract class BiomeBase {
+ protected List x;
+
+ public static int a(BiomeBase biomebase) {
+- return BiomeBase.REGISTRY_ID.a((Object) biomebase);
++ return BiomeBase.REGISTRY_ID.a(biomebase); // Paper - decompile fix
+ }
+
+ public static BiomeBase a(int i) {
+diff --git a/src/main/java/net/minecraft/server/BlockStateList.java b/src/main/java/net/minecraft/server/BlockStateList.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/BlockStateList.java
++++ b/src/main/java/net/minecraft/server/BlockStateList.java
+@@ -0,0 +0,0 @@ public class BlockStateList {
+ if (!BlockStateList.a.matcher(s).matches()) {
+ throw new IllegalArgumentException("Block: " + block.getClass() + " has invalidly named property: " + s);
+ } else {
+- Iterator iterator = iblockstate.c().iterator();
++ Iterator iterator = iblockstate.c().iterator(); // Paper - decompile fix
+
+ String s1;
+
+@@ -0,0 +0,0 @@ public class BlockStateList {
+ return s;
+ }
+
+- Comparable comparable = (Comparable) iterator.next();
++ T comparable = iterator.next(); // Paper - decompile fix
+
+ s1 = iblockstate.a(comparable);
+ } while (BlockStateList.a.matcher(s1).matches());
+@@ -0,0 +0,0 @@ public class BlockStateList {
+ if (!this.b.containsKey(iblockstate)) {
+ throw new IllegalArgumentException("Cannot get property " + iblockstate + " as it does not exist in " + this.a.t());
+ } else {
+- return (Comparable) iblockstate.b().cast(this.b.get(iblockstate));
++ return iblockstate.b().cast(this.b.get(iblockstate)); // Paper - decompile fix
+ }
+ }
+
+diff --git a/src/main/java/net/minecraft/server/CommandAbstract.java b/src/main/java/net/minecraft/server/CommandAbstract.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/CommandAbstract.java
++++ b/src/main/java/net/minecraft/server/CommandAbstract.java
+@@ -0,0 +0,0 @@ public abstract class CommandAbstract implements ICommand {
+ }
+
+ if (object != null && oclass.isAssignableFrom(object.getClass())) {
+- return (Entity) object;
++ return (T) object; // Paper - fix decompile error
+ } else {
+ throw new ExceptionEntityNotFound();
+ }
+@@ -0,0 +0,0 @@ public abstract class CommandAbstract implements ICommand {
+ return this.getCommand().compareTo(icommand.getCommand());
+ }
+
+- public int compareTo(Object object) {
++ public int compareTo(ICommand object) { // Paper - fix decompile error
+ return this.a((ICommand) object);
+ }
+
+--
\ No newline at end of file
diff --git a/Spigot-Server-Patches/Optimize-BlockStateList-BlockData.patch b/Spigot-Server-Patches/Optimize-BlockStateList-BlockData.patch
index 64bcada64f..c236c0366f 100644
--- a/Spigot-Server-Patches/Optimize-BlockStateList-BlockData.patch
+++ b/Spigot-Server-Patches/Optimize-BlockStateList-BlockData.patch
@@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- if (!this.b.containsKey(iblockstate)) {
- throw new IllegalArgumentException("Cannot get property " + iblockstate + " as it does not exist in " + this.a.t());
- } else {
-- return iblockstate.b().cast(this.b.get(iblockstate));
+- return iblockstate.b().cast(this.b.get(iblockstate)); // Paper - decompile fix
- }
+ return iblockstate.b().cast(this.b.get(iblockstate)); // Paper
}
diff --git a/Spigot-Server-Patches/POM-Changes.patch b/Spigot-Server-Patches/POM-Changes.patch
index 02a4d367a6..1b8c680251 100644
--- a/Spigot-Server-Patches/POM-Changes.patch
+++ b/Spigot-Server-Patches/POM-Changes.patch
@@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ com.destroystokyo.paper
+ paper
jar
- 1.9-R0.1-SNAPSHOT
+ 1.9.2-R0.1-SNAPSHOT
- Spigot
- http://www.spigotmc.org
+ Paper
diff --git a/Spigot-Server-Patches/Player-Tab-List-and-Title-APIs.patch b/Spigot-Server-Patches/Player-Tab-List-and-Title-APIs.patch
index 89c05eec25..5eda2c4371 100644
--- a/Spigot-Server-Patches/Player-Tab-List-and-Title-APIs.patch
+++ b/Spigot-Server-Patches/Player-Tab-List-and-Title-APIs.patch
@@ -8,15 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/PacketPlayOutPlayerListHeaderFoo
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutPlayerListHeaderFooter.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutPlayerListHeaderFooter.java
-@@ -0,0 +0,0 @@
- package net.minecraft.server;
-
--import net.minecraft.server.IChatBaseComponent;
--import net.minecraft.server.Packet;
--import net.minecraft.server.PacketDataSerializer;
--import net.minecraft.server.PacketListenerPlayOut;
--
- import java.io.IOException;
+@@ -0,0 +0,0 @@ import java.io.IOException;
public class PacketPlayOutPlayerListHeaderFooter implements Packet {
diff --git a/Spigot-Server-Patches/Support-offline-mode-in-whitelist-command-as-well.patch b/Spigot-Server-Patches/Support-offline-mode-in-whitelist-command-as-well.patch
index 67bda86c37..e3a03a04a1 100644
--- a/Spigot-Server-Patches/Support-offline-mode-in-whitelist-command-as-well.patch
+++ b/Spigot-Server-Patches/Support-offline-mode-in-whitelist-command-as-well.patch
@@ -45,12 +45,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else if (astring[0].equals("reload")) {
minecraftserver.getPlayerList().reloadWhitelist();
@@ -0,0 +0,0 @@ public class CommandWhitelist extends CommandAbstract {
- return a((ICommand) o);
+ return Collections.emptyList();
+ }
}
- // Paper end
+
++ // Paper start
+ /**
-+ * Paper - Adds or removes a player from the game whitelist
++ * Adds or removes a player from the game whitelist
+ *
+ * @param mcserver running instance of MinecraftServer
+ * @param playerName the player we're going to be whitelisting
@@ -85,5 +86,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+ }
++ // Paper end
}
--
\ No newline at end of file
diff --git a/Spigot-Server-Patches/mc-dev-imports.patch b/Spigot-Server-Patches/mc-dev-imports.patch
deleted file mode 100644
index 2b50ffa56e..0000000000
--- a/Spigot-Server-Patches/mc-dev-imports.patch
+++ /dev/null
@@ -1,5977 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Zach Brown <1254957+zachbr@users.noreply.github.com>
-Date: Mon, 29 Feb 2016 21:09:10 -0600
-Subject: [PATCH] mc-dev imports
-
-
-diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java
-@@ -0,0 +0,0 @@
-+package net.minecraft.server;
-+
-+import com.google.common.base.Objects;
-+
-+public class BaseBlockPosition implements Comparable {
-+
-+ public static final BaseBlockPosition ZERO = new BaseBlockPosition(0, 0, 0);
-+ private final int a;
-+ private final int c;
-+ private final int d;
-+
-+ public BaseBlockPosition(int i, int j, int k) {
-+ this.a = i;
-+ this.c = j;
-+ this.d = k;
-+ }
-+
-+ public BaseBlockPosition(double d0, double d1, double d2) {
-+ this(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
-+ }
-+
-+ public boolean equals(Object object) {
-+ if (this == object) {
-+ return true;
-+ } else if (!(object instanceof BaseBlockPosition)) {
-+ return false;
-+ } else {
-+ BaseBlockPosition baseblockposition = (BaseBlockPosition) object;
-+
-+ return this.getX() != baseblockposition.getX() ? false : (this.getY() != baseblockposition.getY() ? false : this.getZ() == baseblockposition.getZ());
-+ }
-+ }
-+
-+ public int hashCode() {
-+ return (this.getY() + this.getZ() * 31) * 31 + this.getX();
-+ }
-+
-+ public int i(BaseBlockPosition baseblockposition) {
-+ return this.getY() == baseblockposition.getY() ? (this.getZ() == baseblockposition.getZ() ? this.getX() - baseblockposition.getX() : this.getZ() - baseblockposition.getZ()) : this.getY() - baseblockposition.getY();
-+ }
-+
-+ public int getX() {
-+ return this.a;
-+ }
-+
-+ public int getY() {
-+ return this.c;
-+ }
-+
-+ public int getZ() {
-+ return this.d;
-+ }
-+
-+ public BaseBlockPosition d(BaseBlockPosition baseblockposition) {
-+ return new BaseBlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX());
-+ }
-+
-+ public double f(int i, int j, int k) {
-+ double d0 = (double) (this.getX() - i);
-+ double d1 = (double) (this.getY() - j);
-+ double d2 = (double) (this.getZ() - k);
-+
-+ return Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
-+ }
-+
-+ public double distanceSquared(double d0, double d1, double d2) {
-+ double d3 = (double) this.getX() - d0;
-+ double d4 = (double) this.getY() - d1;
-+ double d5 = (double) this.getZ() - d2;
-+
-+ return d3 * d3 + d4 * d4 + d5 * d5;
-+ }
-+
-+ public double f(double d0, double d1, double d2) {
-+ double d3 = (double) this.getX() + 0.5D - d0;
-+ double d4 = (double) this.getY() + 0.5D - d1;
-+ double d5 = (double) this.getZ() + 0.5D - d2;
-+
-+ return d3 * d3 + d4 * d4 + d5 * d5;
-+ }
-+
-+ public double k(BaseBlockPosition baseblockposition) {
-+ return this.distanceSquared((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ());
-+ }
-+
-+ public String toString() {
-+ return Objects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString();
-+ }
-+
-+ public int compareTo(BaseBlockPosition object) { // Paper - correct decompile error
-+ return this.i((BaseBlockPosition) object);
-+ }
-+}
-diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/BiomeBase.java
-@@ -0,0 +0,0 @@
-+package net.minecraft.server;
-+
-+import com.google.common.collect.Lists;
-+import com.google.common.collect.Sets;
-+import java.util.Collections;
-+import java.util.List;
-+import java.util.Random;
-+import java.util.Set;
-+import org.apache.logging.log4j.LogManager;
-+import org.apache.logging.log4j.Logger;
-+
-+public abstract class BiomeBase {
-+
-+ private static final Logger y = LogManager.getLogger();
-+ protected static final IBlockData a = Blocks.STONE.getBlockData();
-+ protected static final IBlockData b = Blocks.AIR.getBlockData();
-+ protected static final IBlockData c = Blocks.BEDROCK.getBlockData();
-+ protected static final IBlockData d = Blocks.GRAVEL.getBlockData();
-+ protected static final IBlockData e = Blocks.RED_SANDSTONE.getBlockData();
-+ protected static final IBlockData f = Blocks.SANDSTONE.getBlockData();
-+ protected static final IBlockData g = Blocks.ICE.getBlockData();
-+ protected static final IBlockData h = Blocks.WATER.getBlockData();
-+ public static final Set i = Sets.newHashSet();
-+ public static final RegistryBlockID j = new RegistryBlockID();
-+ protected static final NoiseGenerator3 k = new NoiseGenerator3(new Random(1234L), 1);
-+ protected static final NoiseGenerator3 l = new NoiseGenerator3(new Random(2345L), 1);
-+ protected static final WorldGenTallPlant m = new WorldGenTallPlant();
-+ protected static final WorldGenTrees n = new WorldGenTrees(false);
-+ protected static final WorldGenBigTree o = new WorldGenBigTree(false);
-+ protected static final WorldGenSwampTree p = new WorldGenSwampTree();
-+ public static final RegistryMaterials REGISTRY_ID = new RegistryMaterials();
-+ private final String z;
-+ private final float A;
-+ private final float B;
-+ private final float C;
-+ private final float D;
-+ private final int E;
-+ private final boolean F;
-+ private final boolean G;
-+ private final String H;
-+ public IBlockData r;
-+ public IBlockData s;
-+ public BiomeDecorator t;
-+ protected List u;
-+ protected List v;
-+ protected List w;
-+ protected List x;
-+
-+ public static int a(BiomeBase biomebase) {
-+ return BiomeBase.REGISTRY_ID.a(biomebase); // Paper - Fix compile
-+ }
-+
-+ public static BiomeBase a(int i) {
-+ return (BiomeBase) BiomeBase.REGISTRY_ID.getId(i);
-+ }
-+
-+ public static BiomeBase b(BiomeBase biomebase) {
-+ return (BiomeBase) BiomeBase.j.fromId(a(biomebase));
-+ }
-+
-+ protected BiomeBase(BiomeBase.a biomebase_a) {
-+ this.r = Blocks.GRASS.getBlockData();
-+ this.s = Blocks.DIRT.getBlockData();
-+ this.u = Lists.newArrayList();
-+ this.v = Lists.newArrayList();
-+ this.w = Lists.newArrayList();
-+ this.x = Lists.newArrayList();
-+ this.z = biomebase_a.a;
-+ this.A = biomebase_a.b;
-+ this.B = biomebase_a.c;
-+ this.C = biomebase_a.d;
-+ this.D = biomebase_a.e;
-+ this.E = biomebase_a.f;
-+ this.F = biomebase_a.g;
-+ this.G = biomebase_a.h;
-+ this.H = biomebase_a.i;
-+ this.t = this.a();
-+ this.v.add(new BiomeBase.BiomeMeta(EntitySheep.class, 12, 4, 4));
-+ this.v.add(new BiomeBase.BiomeMeta(EntityPig.class, 10, 4, 4));
-+ this.v.add(new BiomeBase.BiomeMeta(EntityChicken.class, 10, 4, 4));
-+ this.v.add(new BiomeBase.BiomeMeta(EntityCow.class, 8, 4, 4));
-+ this.u.add(new BiomeBase.BiomeMeta(EntitySpider.class, 100, 4, 4));
-+ this.u.add(new BiomeBase.BiomeMeta(EntityZombie.class, 100, 4, 4));
-+ this.u.add(new BiomeBase.BiomeMeta(EntitySkeleton.class, 100, 4, 4));
-+ this.u.add(new BiomeBase.BiomeMeta(EntityCreeper.class, 100, 4, 4));
-+ this.u.add(new BiomeBase.BiomeMeta(EntitySlime.class, 100, 4, 4));
-+ this.u.add(new BiomeBase.BiomeMeta(EntityEnderman.class, 10, 1, 4));
-+ this.u.add(new BiomeBase.BiomeMeta(EntityWitch.class, 5, 1, 1));
-+ this.w.add(new BiomeBase.BiomeMeta(EntitySquid.class, 10, 4, 4));
-+ this.x.add(new BiomeBase.BiomeMeta(EntityBat.class, 10, 8, 8));
-+ }
-+
-+ protected BiomeDecorator a() {
-+ return new BiomeDecorator();
-+ }
-+
-+ public boolean b() {
-+ return this.H != null;
-+ }
-+
-+ public WorldGenTreeAbstract a(Random random) {
-+ return (WorldGenTreeAbstract) (random.nextInt(10) == 0 ? BiomeBase.o : BiomeBase.n);
-+ }
-+
-+ public WorldGenerator b(Random random) {
-+ return new WorldGenGrass(BlockLongGrass.EnumTallGrassType.GRASS);
-+ }
-+
-+ public BlockFlowers.EnumFlowerVarient a(Random random, BlockPosition blockposition) {
-+ return random.nextInt(3) > 0 ? BlockFlowers.EnumFlowerVarient.DANDELION : BlockFlowers.EnumFlowerVarient.POPPY;
-+ }
-+
-+ public List getMobs(EnumCreatureType enumcreaturetype) {
-+ switch (BiomeBase.SyntheticClass_1.a[enumcreaturetype.ordinal()]) {
-+ case 1:
-+ return this.u;
-+
-+ case 2:
-+ return this.v;
-+
-+ case 3:
-+ return this.w;
-+
-+ case 4:
-+ return this.x;
-+
-+ default:
-+ return Collections.emptyList();
-+ }
-+ }
-+
-+ public boolean c() {
-+ return this.p();
-+ }
-+
-+ public boolean d() {
-+ return this.p() ? false : this.G;
-+ }
-+
-+ public boolean e() {
-+ return this.getHumidity() > 0.85F;
-+ }
-+
-+ public float f() {
-+ return 0.1F;
-+ }
-+
-+ public final float a(BlockPosition blockposition) {
-+ if (blockposition.getY() > 64) {
-+ float f = (float) (BiomeBase.k.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F)) * 4.0D);
-+
-+ return this.getTemperature() - (f + (float) blockposition.getY() - 64.0F) * 0.05F / 30.0F;
-+ } else {
-+ return this.getTemperature();
-+ }
-+ }
-+
-+ public void a(World world, Random random, BlockPosition blockposition) {
-+ this.t.a(world, random, this, blockposition);
-+ }
-+
-+ public void a(World world, Random random, ChunkSnapshot chunksnapshot, int i, int j, double d0) {
-+ this.b(world, random, chunksnapshot, i, j, d0);
-+ }
-+
-+ public final void b(World world, Random random, ChunkSnapshot chunksnapshot, int i, int j, double d0) {
-+ int k = world.K();
-+ IBlockData iblockdata = this.r;
-+ IBlockData iblockdata1 = this.s;
-+ int l = -1;
-+ int i1 = (int) (d0 / 3.0D + 3.0D + random.nextDouble() * 0.25D);
-+ int j1 = i & 15;
-+ int k1 = j & 15;
-+ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
-+
-+ for (int l1 = 255; l1 >= 0; --l1) {
-+ if (l1 <= random.nextInt(5)) {
-+ chunksnapshot.a(k1, l1, j1, BiomeBase.c);
-+ } else {
-+ IBlockData iblockdata2 = chunksnapshot.a(k1, l1, j1);
-+
-+ if (iblockdata2.getMaterial() == Material.AIR) {
-+ l = -1;
-+ } else if (iblockdata2.getBlock() == Blocks.STONE) {
-+ if (l == -1) {
-+ if (i1 <= 0) {
-+ iblockdata = BiomeBase.b;
-+ iblockdata1 = BiomeBase.a;
-+ } else if (l1 >= k - 4 && l1 <= k + 1) {
-+ iblockdata = this.r;
-+ iblockdata1 = this.s;
-+ }
-+
-+ if (l1 < k && (iblockdata == null || iblockdata.getMaterial() == Material.AIR)) {
-+ if (this.a((BlockPosition) blockposition_mutableblockposition.c(i, l1, j)) < 0.15F) {
-+ iblockdata = BiomeBase.g;
-+ } else {
-+ iblockdata = BiomeBase.h;
-+ }
-+ }
-+
-+ l = i1;
-+ if (l1 >= k - 1) {
-+ chunksnapshot.a(k1, l1, j1, iblockdata);
-+ } else if (l1 < k - 7 - i1) {
-+ iblockdata = BiomeBase.b;
-+ iblockdata1 = BiomeBase.a;
-+ chunksnapshot.a(k1, l1, j1, BiomeBase.d);
-+ } else {
-+ chunksnapshot.a(k1, l1, j1, iblockdata1);
-+ }
-+ } else if (l > 0) {
-+ --l;
-+ chunksnapshot.a(k1, l1, j1, iblockdata1);
-+ if (l == 0 && iblockdata1.getBlock() == Blocks.SAND) {
-+ l = random.nextInt(4) + Math.max(0, l1 - 63);
-+ iblockdata1 = iblockdata1.get(BlockSand.VARIANT) == BlockSand.EnumSandVariant.RED_SAND ? BiomeBase.e : BiomeBase.f;
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ }
-+
-+ public Class extends BiomeBase> g() {
-+ return this.getClass();
-+ }
-+
-+ public BiomeBase.EnumTemperature h() {
-+ return (double) this.getTemperature() < 0.2D ? BiomeBase.EnumTemperature.COLD : ((double) this.getTemperature() < 1.0D ? BiomeBase.EnumTemperature.MEDIUM : BiomeBase.EnumTemperature.WARM);
-+ }
-+
-+ public static BiomeBase getBiome(int i) {
-+ return getBiome(i, (BiomeBase) null);
-+ }
-+
-+ public static BiomeBase getBiome(int i, BiomeBase biomebase) {
-+ BiomeBase biomebase1 = a(i);
-+
-+ return biomebase1 == null ? biomebase : biomebase1;
-+ }
-+
-+ public boolean i() {
-+ return false;
-+ }
-+
-+ public final float j() {
-+ return this.A;
-+ }
-+
-+ public final float getHumidity() {
-+ return this.D;
-+ }
-+
-+ public final String l() {
-+ return this.z;
-+ }
-+
-+ public final float m() {
-+ return this.B;
-+ }
-+
-+ public final float getTemperature() {
-+ return this.C;
-+ }
-+
-+ public final boolean p() {
-+ return this.F;
-+ }
-+
-+ public static void q() {
-+ a(0, "ocean", new BiomeOcean((new BiomeBase.a("Ocean")).c(-1.0F).d(0.1F)));
-+ a(1, "plains", new BiomePlains(false, (new BiomeBase.a("Plains")).c(0.125F).d(0.05F).a(0.8F).b(0.4F)));
-+ a(2, "desert", new BiomeDesert((new BiomeBase.a("Desert")).c(0.125F).d(0.05F).a(2.0F).b(0.0F).a()));
-+ a(3, "extreme_hills", new BiomeBigHills(BiomeBigHills.Type.NORMAL, (new BiomeBase.a("Extreme Hills")).c(1.0F).d(0.5F).a(0.2F).b(0.3F)));
-+ a(4, "forest", new BiomeForest(BiomeForest.Type.NORMAL, (new BiomeBase.a("Forest")).a(0.7F).b(0.8F)));
-+ a(5, "taiga", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new BiomeBase.a("Taiga")).c(0.2F).d(0.2F).a(0.25F).b(0.8F)));
-+ a(6, "swampland", new BiomeSwamp((new BiomeBase.a("Swampland")).c(-0.2F).d(0.1F).a(0.8F).b(0.9F).a(14745518)));
-+ a(7, "river", new BiomeRiver((new BiomeBase.a("River")).c(-0.5F).d(0.0F)));
-+ a(8, "hell", new BiomeHell((new BiomeBase.a("Hell")).a(2.0F).b(0.0F).a()));
-+ a(9, "sky", new BiomeTheEnd((new BiomeBase.a("The End")).a()));
-+ a(10, "frozen_ocean", new BiomeOcean((new BiomeBase.a("FrozenOcean")).c(-1.0F).d(0.1F).a(0.0F).b(0.5F).b()));
-+ a(11, "frozen_river", new BiomeRiver((new BiomeBase.a("FrozenRiver")).c(-0.5F).d(0.0F).a(0.0F).b(0.5F).b()));
-+ a(12, "ice_flats", new BiomeIcePlains(false, (new BiomeBase.a("Ice Plains")).c(0.125F).d(0.05F).a(0.0F).b(0.5F).b()));
-+ a(13, "ice_mountains", new BiomeIcePlains(false, (new BiomeBase.a("Ice Mountains")).c(0.45F).d(0.3F).a(0.0F).b(0.5F).b()));
-+ a(14, "mushroom_island", new BiomeMushrooms((new BiomeBase.a("MushroomIsland")).c(0.2F).d(0.3F).a(0.9F).b(1.0F)));
-+ a(15, "mushroom_island_shore", new BiomeMushrooms((new BiomeBase.a("MushroomIslandShore")).c(0.0F).d(0.025F).a(0.9F).b(1.0F)));
-+ a(16, "beaches", new BiomeBeach((new BiomeBase.a("Beach")).c(0.0F).d(0.025F).a(0.8F).b(0.4F)));
-+ a(17, "desert_hills", new BiomeDesert((new BiomeBase.a("DesertHills")).c(0.45F).d(0.3F).a(2.0F).b(0.0F).a()));
-+ a(18, "forest_hills", new BiomeForest(BiomeForest.Type.NORMAL, (new BiomeBase.a("ForestHills")).c(0.45F).d(0.3F).a(0.7F).b(0.8F)));
-+ a(19, "taiga_hills", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new BiomeBase.a("TaigaHills")).a(0.25F).b(0.8F).c(0.45F).d(0.3F)));
-+ a(20, "smaller_extreme_hills", new BiomeBigHills(BiomeBigHills.Type.EXTRA_TREES, (new BiomeBase.a("Extreme Hills Edge")).c(0.8F).d(0.3F).a(0.2F).b(0.3F)));
-+ a(21, "jungle", new BiomeJungle(false, (new BiomeBase.a("Jungle")).a(0.95F).b(0.9F)));
-+ a(22, "jungle_hills", new BiomeJungle(false, (new BiomeBase.a("JungleHills")).c(0.45F).d(0.3F).a(0.95F).b(0.9F)));
-+ a(23, "jungle_edge", new BiomeJungle(true, (new BiomeBase.a("JungleEdge")).a(0.95F).b(0.8F)));
-+ a(24, "deep_ocean", new BiomeOcean((new BiomeBase.a("Deep Ocean")).c(-1.8F).d(0.1F)));
-+ a(25, "stone_beach", new BiomeStoneBeach((new BiomeBase.a("Stone Beach")).c(0.1F).d(0.8F).a(0.2F).b(0.3F)));
-+ a(26, "cold_beach", new BiomeBeach((new BiomeBase.a("Cold Beach")).c(0.0F).d(0.025F).a(0.05F).b(0.3F).b()));
-+ a(27, "birch_forest", new BiomeForest(BiomeForest.Type.BIRCH, (new BiomeBase.a("Birch Forest")).a(0.6F).b(0.6F)));
-+ a(28, "birch_forest_hills", new BiomeForest(BiomeForest.Type.BIRCH, (new BiomeBase.a("Birch Forest Hills")).c(0.45F).d(0.3F).a(0.6F).b(0.6F)));
-+ a(29, "roofed_forest", new BiomeForest(BiomeForest.Type.ROOFED, (new BiomeBase.a("Roofed Forest")).a(0.7F).b(0.8F)));
-+ a(30, "taiga_cold", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new BiomeBase.a("Cold Taiga")).c(0.2F).d(0.2F).a(-0.5F).b(0.4F).b()));
-+ a(31, "taiga_cold_hills", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new BiomeBase.a("Cold Taiga Hills")).c(0.45F).d(0.3F).a(-0.5F).b(0.4F).b()));
-+ a(32, "redwood_taiga", new BiomeTaiga(BiomeTaiga.Type.MEGA, (new BiomeBase.a("Mega Taiga")).a(0.3F).b(0.8F).c(0.2F).d(0.2F)));
-+ a(33, "redwood_taiga_hills", new BiomeTaiga(BiomeTaiga.Type.MEGA, (new BiomeBase.a("Mega Taiga Hills")).c(0.45F).d(0.3F).a(0.3F).b(0.8F)));
-+ a(34, "extreme_hills_with_trees", new BiomeBigHills(BiomeBigHills.Type.EXTRA_TREES, (new BiomeBase.a("Extreme Hills+")).c(1.0F).d(0.5F).a(0.2F).b(0.3F)));
-+ a(35, "savanna", new BiomeSavanna((new BiomeBase.a("Savanna")).c(0.125F).d(0.05F).a(1.2F).b(0.0F).a()));
-+ a(36, "savanna_rock", new BiomeSavanna((new BiomeBase.a("Savanna Plateau")).c(1.5F).d(0.025F).a(1.0F).b(0.0F).a()));
-+ a(37, "mesa", new BiomeMesa(false, false, (new BiomeBase.a("Mesa")).a(2.0F).b(0.0F).a()));
-+ a(38, "mesa_rock", new BiomeMesa(false, true, (new BiomeBase.a("Mesa Plateau F")).c(1.5F).d(0.025F).a(2.0F).b(0.0F).a()));
-+ a(39, "mesa_clear_rock", new BiomeMesa(false, false, (new BiomeBase.a("Mesa Plateau")).c(1.5F).d(0.025F).a(2.0F).b(0.0F).a()));
-+ a(127, "void", new BiomeVoid((new BiomeBase.a("The Void")).a()));
-+ a(129, "mutated_plains", new BiomePlains(true, (new BiomeBase.a("Sunflower Plains")).a("plains").c(0.125F).d(0.05F).a(0.8F).b(0.4F)));
-+ a(130, "mutated_desert", new BiomeDesert((new BiomeBase.a("Desert M")).a("desert").c(0.225F).d(0.25F).a(2.0F).b(0.0F).a()));
-+ a(131, "mutated_extreme_hills", new BiomeBigHills(BiomeBigHills.Type.MUTATED, (new BiomeBase.a("Extreme Hills M")).a("extreme_hills").c(1.0F).d(0.5F).a(0.2F).b(0.3F)));
-+ a(132, "mutated_forest", new BiomeForest(BiomeForest.Type.FLOWER, (new BiomeBase.a("Flower Forest")).a("forest").d(0.4F).a(0.7F).b(0.8F)));
-+ a(133, "mutated_taiga", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new BiomeBase.a("Taiga M")).a("taiga").c(0.3F).d(0.4F).a(0.25F).b(0.8F)));
-+ a(134, "mutated_swampland", new BiomeSwamp((new BiomeBase.a("Swampland M")).a("swampland").c(-0.1F).d(0.3F).a(0.8F).b(0.9F).a(14745518)));
-+ a(140, "mutated_ice_flats", new BiomeIcePlains(true, (new BiomeBase.a("Ice Plains Spikes")).a("ice_flats").c(0.425F).d(0.45000002F).a(0.0F).b(0.5F).b()));
-+ a(149, "mutated_jungle", new BiomeJungle(false, (new BiomeBase.a("Jungle M")).a("jungle").c(0.2F).d(0.4F).a(0.95F).b(0.9F)));
-+ a(151, "mutated_jungle_edge", new BiomeJungle(true, (new BiomeBase.a("JungleEdge M")).a("jungle_edge").c(0.2F).d(0.4F).a(0.95F).b(0.8F)));
-+ a(155, "mutated_birch_forest", new BiomeForestMutated((new BiomeBase.a("Birch Forest M")).a("birch_forest").c(0.2F).d(0.4F).a(0.6F).b(0.6F)));
-+ a(156, "mutated_birch_forest_hills", new BiomeForestMutated((new BiomeBase.a("Birch Forest Hills M")).a("birch_forest").c(0.55F).d(0.5F).a(0.6F).b(0.6F)));
-+ a(157, "mutated_roofed_forest", new BiomeForest(BiomeForest.Type.ROOFED, (new BiomeBase.a("Roofed Forest M")).a("roofed_forest").c(0.2F).d(0.4F).a(0.7F).b(0.8F)));
-+ a(158, "mutated_taiga_cold", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new BiomeBase.a("Cold Taiga M")).a("taiga_cold").c(0.3F).d(0.4F).a(-0.5F).b(0.4F).b()));
-+ a(160, "mutated_redwood_taiga", new BiomeTaiga(BiomeTaiga.Type.MEGA_SPRUCE, (new BiomeBase.a("Mega Spruce Taiga")).a("redwood_taiga").c(0.2F).d(0.2F).a(0.25F).b(0.8F)));
-+ a(161, "mutated_redwood_taiga_hills", new BiomeTaiga(BiomeTaiga.Type.MEGA_SPRUCE, (new BiomeBase.a("Redwood Taiga Hills M")).a("redwood_taiga_hills").c(0.2F).d(0.2F).a(0.25F).b(0.8F)));
-+ a(162, "mutated_extreme_hills_with_trees", new BiomeBigHills(BiomeBigHills.Type.MUTATED, (new BiomeBase.a("Extreme Hills+ M")).a("extreme_hills_with_trees").c(1.0F).d(0.5F).a(0.2F).b(0.3F)));
-+ a(163, "mutated_savanna", new BiomeSavannaMutated((new BiomeBase.a("Savanna M")).a("savanna").c(0.3625F).d(1.225F).a(1.1F).b(0.0F).a()));
-+ a(164, "mutated_savanna_rock", new BiomeSavannaMutated((new BiomeBase.a("Savanna Plateau M")).a("savanna_rock").c(1.05F).d(1.2125001F).a(1.0F).b(0.0F).a()));
-+ a(165, "mutated_mesa", new BiomeMesa(true, false, (new BiomeBase.a("Mesa (Bryce)")).a("mesa").a(2.0F).b(0.0F).a()));
-+ a(166, "mutated_mesa_rock", new BiomeMesa(false, true, (new BiomeBase.a("Mesa Plateau F M")).a("mesa_rock").c(0.45F).d(0.3F).a(2.0F).b(0.0F).a()));
-+ a(167, "mutated_mesa_clear_rock", new BiomeMesa(false, false, (new BiomeBase.a("Mesa Plateau M")).a("mesa_clear_rock").c(0.45F).d(0.3F).a(2.0F).b(0.0F).a()));
-+ Collections.addAll(BiomeBase.i, new BiomeBase[] { Biomes.a, Biomes.c, Biomes.d, Biomes.e, Biomes.f, Biomes.g, Biomes.h, Biomes.i, Biomes.m, Biomes.n, Biomes.o, Biomes.p, Biomes.q, Biomes.r, Biomes.s, Biomes.t, Biomes.u, Biomes.w, Biomes.x, Biomes.y, Biomes.z, Biomes.A, Biomes.B, Biomes.C, Biomes.D, Biomes.E, Biomes.F, Biomes.G, Biomes.H, Biomes.I, Biomes.J, Biomes.K, Biomes.L, Biomes.M, Biomes.N, Biomes.O});
-+ }
-+
-+ private static void a(int i, String s, BiomeBase biomebase) {
-+ BiomeBase.REGISTRY_ID.a(i, new MinecraftKey(s), biomebase);
-+ if (biomebase.b()) {
-+ BiomeBase.j.a(biomebase, a((BiomeBase) BiomeBase.REGISTRY_ID.get(new MinecraftKey(biomebase.H))));
-+ }
-+
-+ }
-+
-+ static class SyntheticClass_1 {
-+
-+ static final int[] a = new int[EnumCreatureType.values().length];
-+
-+ static {
-+ try {
-+ BiomeBase.SyntheticClass_1.a[EnumCreatureType.MONSTER.ordinal()] = 1;
-+ } catch (NoSuchFieldError nosuchfielderror) {
-+ ;
-+ }
-+
-+ try {
-+ BiomeBase.SyntheticClass_1.a[EnumCreatureType.CREATURE.ordinal()] = 2;
-+ } catch (NoSuchFieldError nosuchfielderror1) {
-+ ;
-+ }
-+
-+ try {
-+ BiomeBase.SyntheticClass_1.a[EnumCreatureType.WATER_CREATURE.ordinal()] = 3;
-+ } catch (NoSuchFieldError nosuchfielderror2) {
-+ ;
-+ }
-+
-+ try {
-+ BiomeBase.SyntheticClass_1.a[EnumCreatureType.AMBIENT.ordinal()] = 4;
-+ } catch (NoSuchFieldError nosuchfielderror3) {
-+ ;
-+ }
-+
-+ }
-+ }
-+
-+ public static class a {
-+
-+ private final String a;
-+ private float b = 0.1F;
-+ private float c = 0.2F;
-+ private float d = 0.5F;
-+ private float e = 0.5F;
-+ private int f = 16777215;
-+ private boolean g;
-+ private boolean h = true;
-+ private String i;
-+
-+ public a(String s) {
-+ this.a = s;
-+ }
-+
-+ protected BiomeBase.a a(float f) {
-+ if (f > 0.1F && f < 0.2F) {
-+ throw new IllegalArgumentException("Please avoid temperatures in the range 0.1 - 0.2 because of snow");
-+ } else {
-+ this.d = f;
-+ return this;
-+ }
-+ }
-+
-+ protected BiomeBase.a b(float f) {
-+ this.e = f;
-+ return this;
-+ }
-+
-+ protected BiomeBase.a c(float f) {
-+ this.b = f;
-+ return this;
-+ }
-+
-+ protected BiomeBase.a d(float f) {
-+ this.c = f;
-+ return this;
-+ }
-+
-+ protected BiomeBase.a a() {
-+ this.h = false;
-+ return this;
-+ }
-+
-+ protected BiomeBase.a b() {
-+ this.g = true;
-+ return this;
-+ }
-+
-+ protected BiomeBase.a a(int i) {
-+ this.f = i;
-+ return this;
-+ }
-+
-+ protected BiomeBase.a a(String s) {
-+ this.i = s;
-+ return this;
-+ }
-+ }
-+
-+ public static class BiomeMeta extends WeightedRandom.WeightedRandomChoice {
-+
-+ public Class extends EntityInsentient> b;
-+ public int c;
-+ public int d;
-+
-+ public BiomeMeta(Class extends EntityInsentient> oclass, int i, int j, int k) {
-+ super(i);
-+ this.b = oclass;
-+ this.c = j;
-+ this.d = k;
-+ }
-+
-+ public String toString() {
-+ return this.b.getSimpleName() + "*(" + this.c + "-" + this.d + "):" + this.a;
-+ }
-+ }
-+
-+ public static enum EnumTemperature {
-+
-+ OCEAN, COLD, MEDIUM, WARM;
-+
-+ private EnumTemperature() {}
-+ }
-+}
-diff --git a/src/main/java/net/minecraft/server/BiomeMesa.java b/src/main/java/net/minecraft/server/BiomeMesa.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/BiomeMesa.java
-@@ -0,0 +0,0 @@
-+package net.minecraft.server;
-+
-+import java.util.Arrays;
-+import java.util.Random;
-+
-+public class BiomeMesa extends BiomeBase {
-+
-+ protected static final IBlockData y = Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, BlockDirt.EnumDirtVariant.COARSE_DIRT);
-+ protected static final IBlockData z = Blocks.GRASS.getBlockData();
-+ protected static final IBlockData A = Blocks.HARDENED_CLAY.getBlockData();
-+ protected static final IBlockData B = Blocks.STAINED_HARDENED_CLAY.getBlockData();
-+ protected static final IBlockData C = BiomeMesa.B.set(BlockCloth.COLOR, EnumColor.ORANGE);
-+ protected static final IBlockData D = Blocks.SAND.getBlockData().set(BlockSand.VARIANT, BlockSand.EnumSandVariant.RED_SAND);
-+ private IBlockData[] E;
-+ private long F;
-+ private NoiseGenerator3 G;
-+ private NoiseGenerator3 H;
-+ private NoiseGenerator3 I;
-+ private boolean J;
-+ private boolean K;
-+
-+ public BiomeMesa(boolean flag, boolean flag1, BiomeBase.a biomebase_a) {
-+ super(biomebase_a);
-+ this.J = flag;
-+ this.K = flag1;
-+ this.v.clear();
-+ this.r = BiomeMesa.D;
-+ this.s = BiomeMesa.B;
-+ this.t.z = -999;
-+ this.t.C = 20;
-+ this.t.E = 3;
-+ this.t.F = 5;
-+ this.t.A = 0;
-+ this.v.clear();
-+ if (flag1) {
-+ this.t.z = 5;
-+ }
-+
-+ }
-+
-+ public WorldGenTreeAbstract a(Random random) {
-+ return BiomeMesa.n;
-+ }
-+
-+ public void a(World world, Random random, BlockPosition blockposition) {
-+ super.a(world, random, blockposition);
-+ }
-+
-+ public void a(World world, Random random, ChunkSnapshot chunksnapshot, int i, int j, double d0) {
-+ if (this.E == null || this.F != world.getSeed()) {
-+ this.a(world.getSeed());
-+ }
-+
-+ if (this.G == null || this.H == null || this.F != world.getSeed()) {
-+ Random random1 = new Random(this.F);
-+
-+ this.G = new NoiseGenerator3(random1, 4);
-+ this.H = new NoiseGenerator3(random1, 1);
-+ }
-+
-+ this.F = world.getSeed();
-+ double d1 = 0.0D;
-+ int k;
-+ int l;
-+
-+ if (this.J) {
-+ k = (i & -16) + (j & 15);
-+ l = (j & -16) + (i & 15);
-+ double d2 = Math.min(Math.abs(d0), this.G.a((double) k * 0.25D, (double) l * 0.25D));
-+
-+ if (d2 > 0.0D) {
-+ double d3 = 0.001953125D;
-+ double d4 = Math.abs(this.H.a((double) k * d3, (double) l * d3));
-+
-+ d1 = d2 * d2 * 2.5D;
-+ double d5 = Math.ceil(d4 * 50.0D) + 14.0D;
-+
-+ if (d1 > d5) {
-+ d1 = d5;
-+ }
-+
-+ d1 += 64.0D;
-+ }
-+ }
-+
-+ k = i & 15;
-+ l = j & 15;
-+ int i1 = world.K();
-+ IBlockData iblockdata = BiomeMesa.B;
-+ IBlockData iblockdata1 = this.s;
-+ int j1 = (int) (d0 / 3.0D + 3.0D + random.nextDouble() * 0.25D);
-+ boolean flag = Math.cos(d0 / 3.0D * 3.141592653589793D) > 0.0D;
-+ int k1 = -1;
-+ boolean flag1 = false;
-+
-+ for (int l1 = 255; l1 >= 0; --l1) {
-+ if (chunksnapshot.a(l, l1, k).getMaterial() == Material.AIR && l1 < (int) d1) {
-+ chunksnapshot.a(l, l1, k, BiomeMesa.a);
-+ }
-+
-+ if (l1 <= random.nextInt(5)) {
-+ chunksnapshot.a(l, l1, k, BiomeMesa.c);
-+ } else {
-+ IBlockData iblockdata2 = chunksnapshot.a(l, l1, k);
-+
-+ if (iblockdata2.getMaterial() == Material.AIR) {
-+ k1 = -1;
-+ } else if (iblockdata2.getBlock() == Blocks.STONE) {
-+ if (k1 == -1) {
-+ flag1 = false;
-+ if (j1 <= 0) {
-+ iblockdata = BiomeMesa.b;
-+ iblockdata1 = BiomeMesa.a;
-+ } else if (l1 >= i1 - 4 && l1 <= i1 + 1) {
-+ iblockdata = BiomeMesa.B;
-+ iblockdata1 = this.s;
-+ }
-+
-+ if (l1 < i1 && (iblockdata == null || iblockdata.getMaterial() == Material.AIR)) {
-+ iblockdata = BiomeMesa.h;
-+ }
-+
-+ k1 = j1 + Math.max(0, l1 - i1);
-+ if (l1 >= i1 - 1) {
-+ if (this.K && l1 > 86 + j1 * 2) {
-+ if (flag) {
-+ chunksnapshot.a(l, l1, k, BiomeMesa.y);
-+ } else {
-+ chunksnapshot.a(l, l1, k, BiomeMesa.z);
-+ }
-+ } else if (l1 > i1 + 3 + j1) {
-+ IBlockData iblockdata3;
-+
-+ if (l1 >= 64 && l1 <= 127) {
-+ if (flag) {
-+ iblockdata3 = BiomeMesa.A;
-+ } else {
-+ iblockdata3 = this.a(i, l1, j);
-+ }
-+ } else {
-+ iblockdata3 = BiomeMesa.C;
-+ }
-+
-+ chunksnapshot.a(l, l1, k, iblockdata3);
-+ } else {
-+ chunksnapshot.a(l, l1, k, this.r);
-+ flag1 = true;
-+ }
-+ } else {
-+ chunksnapshot.a(l, l1, k, iblockdata1);
-+ if (iblockdata1.getBlock() == Blocks.STAINED_HARDENED_CLAY) {
-+ chunksnapshot.a(l, l1, k, BiomeMesa.C);
-+ }
-+ }
-+ } else if (k1 > 0) {
-+ --k1;
-+ if (flag1) {
-+ chunksnapshot.a(l, l1, k, BiomeMesa.C);
-+ } else {
-+ chunksnapshot.a(l, l1, k, this.a(i, l1, j));
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ }
-+
-+ private void a(long i) {
-+ this.E = new IBlockData[64];
-+ Arrays.fill(this.E, BiomeMesa.A);
-+ Random random = new Random(i);
-+
-+ this.I = new NoiseGenerator3(random, 1);
-+
-+ int j;
-+
-+ for (j = 0; j < 64; ++j) {
-+ j += random.nextInt(5) + 1;
-+ if (j < 64) {
-+ this.E[j] = BiomeMesa.C;
-+ }
-+ }
-+
-+ j = random.nextInt(4) + 2;
-+
-+ int k;
-+ int l;
-+ int i1;
-+ int j1;
-+
-+ for (k = 0; k < j; ++k) {
-+ l = random.nextInt(3) + 1;
-+ i1 = random.nextInt(64);
-+
-+ for (j1 = 0; i1 + j1 < 64 && j1 < l; ++j1) {
-+ this.E[i1 + j1] = BiomeMesa.B.set(BlockCloth.COLOR, EnumColor.YELLOW);
-+ }
-+ }
-+
-+ k = random.nextInt(4) + 2;
-+
-+ int k1;
-+
-+ for (l = 0; l < k; ++l) {
-+ i1 = random.nextInt(3) + 2;
-+ j1 = random.nextInt(64);
-+
-+ for (k1 = 0; j1 + k1 < 64 && k1 < i1; ++k1) {
-+ this.E[j1 + k1] = BiomeMesa.B.set(BlockCloth.COLOR, EnumColor.BROWN);
-+ }
-+ }
-+
-+ l = random.nextInt(4) + 2;
-+
-+ for (i1 = 0; i1 < l; ++i1) {
-+ j1 = random.nextInt(3) + 1;
-+ k1 = random.nextInt(64);
-+
-+ for (int l1 = 0; k1 + l1 < 64 && l1 < j1; ++l1) {
-+ this.E[k1 + l1] = BiomeMesa.B.set(BlockCloth.COLOR, EnumColor.RED);
-+ }
-+ }
-+
-+ i1 = random.nextInt(3) + 3;
-+ j1 = 0;
-+
-+ for (k1 = 0; k1 < i1; ++k1) {
-+ byte b0 = 1;
-+
-+ j1 += random.nextInt(16) + 4;
-+
-+ for (int i2 = 0; j1 + i2 < 64 && i2 < b0; ++i2) {
-+ this.E[j1 + i2] = BiomeMesa.B.set(BlockCloth.COLOR, EnumColor.WHITE);
-+ if (j1 + i2 > 1 && random.nextBoolean()) {
-+ this.E[j1 + i2 - 1] = BiomeMesa.B.set(BlockCloth.COLOR, EnumColor.SILVER);
-+ }
-+
-+ if (j1 + i2 < 63 && random.nextBoolean()) {
-+ this.E[j1 + i2 + 1] = BiomeMesa.B.set(BlockCloth.COLOR, EnumColor.SILVER);
-+ }
-+ }
-+ }
-+
-+ }
-+
-+ private IBlockData a(int i, int j, int k) {
-+ int l = (int) Math.round(this.I.a((double) i / 512.0D, (double) i / 512.0D) * 2.0D);
-+
-+ return this.E[(j + l + 64) % 64];
-+ }
-+}
-diff --git a/src/main/java/net/minecraft/server/BlockChest.java b/src/main/java/net/minecraft/server/BlockChest.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/BlockChest.java
-@@ -0,0 +0,0 @@
-+package net.minecraft.server;
-+
-+import java.util.Iterator;
-+
-+public class BlockChest extends BlockTileEntity {
-+
-+ public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING;
-+ protected static final AxisAlignedBB b = new AxisAlignedBB(0.0625D, 0.0D, 0.0D, 0.9375D, 0.875D, 0.9375D);
-+ protected static final AxisAlignedBB c = new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 0.9375D, 0.875D, 1.0D);
-+ protected static final AxisAlignedBB d = new AxisAlignedBB(0.0D, 0.0D, 0.0625D, 0.9375D, 0.875D, 0.9375D);
-+ protected static final AxisAlignedBB e = new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 1.0D, 0.875D, 0.9375D);
-+ protected static final AxisAlignedBB f = new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 0.9375D, 0.875D, 0.9375D);
-+ public final Type g;
-+
-+ protected BlockChest(Type blockchest_type) {
-+ super(Material.WOOD);
-+ this.w(this.blockStateList.getBlockData().set(BlockChest.FACING, EnumDirection.NORTH));
-+ this.g = blockchest_type;
-+ this.a(blockchest_type == Type.TRAP ? CreativeModeTab.d : CreativeModeTab.c);
-+ }
-+
-+ public boolean b(IBlockData iblockdata) {
-+ return false;
-+ }
-+
-+ public boolean c(IBlockData iblockdata) {
-+ return false;
-+ }
-+
-+ public EnumRenderType a(IBlockData iblockdata) {
-+ return EnumRenderType.ENTITYBLOCK_ANIMATED;
-+ }
-+
-+ public AxisAlignedBB a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) {
-+ return iblockaccess.getType(blockposition.north()).getBlock() == this ? BlockChest.b : (iblockaccess.getType(blockposition.south()).getBlock() == this ? BlockChest.c : (iblockaccess.getType(blockposition.west()).getBlock() == this ? BlockChest.d : (iblockaccess.getType(blockposition.east()).getBlock() == this ? BlockChest.e : BlockChest.f)));
-+ }
-+
-+ public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
-+ this.e(world, blockposition, iblockdata);
-+ Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
-+
-+ while (iterator.hasNext()) {
-+ EnumDirection enumdirection = (EnumDirection) iterator.next();
-+ BlockPosition blockposition1 = blockposition.shift(enumdirection);
-+ IBlockData iblockdata1 = world.getType(blockposition1);
-+
-+ if (iblockdata1.getBlock() == this) {
-+ this.e(world, blockposition1, iblockdata1);
-+ }
-+ }
-+
-+ }
-+
-+ public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) {
-+ return this.getBlockData().set(BlockChest.FACING, entityliving.getDirection());
-+ }
-+
-+ public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) {
-+ EnumDirection enumdirection = EnumDirection.fromType2(MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3).opposite();
-+
-+ iblockdata = iblockdata.set(BlockChest.FACING, enumdirection);
-+ BlockPosition blockposition1 = blockposition.north();
-+ BlockPosition blockposition2 = blockposition.south();
-+ BlockPosition blockposition3 = blockposition.west();
-+ BlockPosition blockposition4 = blockposition.east();
-+ boolean flag = this == world.getType(blockposition1).getBlock();
-+ boolean flag1 = this == world.getType(blockposition2).getBlock();
-+ boolean flag2 = this == world.getType(blockposition3).getBlock();
-+ boolean flag3 = this == world.getType(blockposition4).getBlock();
-+
-+ if (!flag && !flag1 && !flag2 && !flag3) {
-+ world.setTypeAndData(blockposition, iblockdata, 3);
-+ } else if (enumdirection.k() == EnumDirection.EnumAxis.X && (flag || flag1)) {
-+ if (flag) {
-+ world.setTypeAndData(blockposition1, iblockdata, 3);
-+ } else {
-+ world.setTypeAndData(blockposition2, iblockdata, 3);
-+ }
-+
-+ world.setTypeAndData(blockposition, iblockdata, 3);
-+ } else if (enumdirection.k() == EnumDirection.EnumAxis.Z && (flag2 || flag3)) {
-+ if (flag2) {
-+ world.setTypeAndData(blockposition3, iblockdata, 3);
-+ } else {
-+ world.setTypeAndData(blockposition4, iblockdata, 3);
-+ }
-+
-+ world.setTypeAndData(blockposition, iblockdata, 3);
-+ }
-+
-+ if (itemstack.hasName()) {
-+ TileEntity tileentity = world.getTileEntity(blockposition);
-+
-+ if (tileentity instanceof TileEntityChest) {
-+ ((TileEntityChest) tileentity).a(itemstack.getName());
-+ }
-+ }
-+
-+ }
-+
-+ public IBlockData e(World world, BlockPosition blockposition, IBlockData iblockdata) {
-+ if (world.isClientSide) {
-+ return iblockdata;
-+ } else {
-+ IBlockData iblockdata1 = world.getType(blockposition.north());
-+ IBlockData iblockdata2 = world.getType(blockposition.south());
-+ IBlockData iblockdata3 = world.getType(blockposition.west());
-+ IBlockData iblockdata4 = world.getType(blockposition.east());
-+ EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockChest.FACING);
-+
-+ if (iblockdata1.getBlock() != this && iblockdata2.getBlock() != this) {
-+ boolean flag = iblockdata1.b();
-+ boolean flag1 = iblockdata2.b();
-+
-+ if (iblockdata3.getBlock() == this || iblockdata4.getBlock() == this) {
-+ BlockPosition blockposition1 = iblockdata3.getBlock() == this ? blockposition.west() : blockposition.east();
-+ IBlockData iblockdata5 = world.getType(blockposition1.north());
-+ IBlockData iblockdata6 = world.getType(blockposition1.south());
-+
-+ enumdirection = EnumDirection.SOUTH;
-+ EnumDirection enumdirection1;
-+
-+ if (iblockdata3.getBlock() == this) {
-+ enumdirection1 = (EnumDirection) iblockdata3.get(BlockChest.FACING);
-+ } else {
-+ enumdirection1 = (EnumDirection) iblockdata4.get(BlockChest.FACING);
-+ }
-+
-+ if (enumdirection1 == EnumDirection.NORTH) {
-+ enumdirection = EnumDirection.NORTH;
-+ }
-+
-+ if ((flag || iblockdata5.b()) && !flag1 && !iblockdata6.b()) {
-+ enumdirection = EnumDirection.SOUTH;
-+ }
-+
-+ if ((flag1 || iblockdata6.b()) && !flag && !iblockdata5.b()) {
-+ enumdirection = EnumDirection.NORTH;
-+ }
-+ }
-+ } else {
-+ BlockPosition blockposition2 = iblockdata1.getBlock() == this ? blockposition.north() : blockposition.south();
-+ IBlockData iblockdata7 = world.getType(blockposition2.west());
-+ IBlockData iblockdata8 = world.getType(blockposition2.east());
-+
-+ enumdirection = EnumDirection.EAST;
-+ EnumDirection enumdirection2;
-+
-+ if (iblockdata1.getBlock() == this) {
-+ enumdirection2 = (EnumDirection) iblockdata1.get(BlockChest.FACING);
-+ } else {
-+ enumdirection2 = (EnumDirection) iblockdata2.get(BlockChest.FACING);
-+ }
-+
-+ if (enumdirection2 == EnumDirection.WEST) {
-+ enumdirection = EnumDirection.WEST;
-+ }
-+
-+ if ((iblockdata3.b() || iblockdata7.b()) && !iblockdata4.b() && !iblockdata8.b()) {
-+ enumdirection = EnumDirection.EAST;
-+ }
-+
-+ if ((iblockdata4.b() || iblockdata8.b()) && !iblockdata3.b() && !iblockdata7.b()) {
-+ enumdirection = EnumDirection.WEST;
-+ }
-+ }
-+
-+ iblockdata = iblockdata.set(BlockChest.FACING, enumdirection);
-+ world.setTypeAndData(blockposition, iblockdata, 3);
-+ return iblockdata;
-+ }
-+ }
-+
-+ public IBlockData f(World world, BlockPosition blockposition, IBlockData iblockdata) {
-+ EnumDirection enumdirection = null;
-+ Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
-+
-+ while (iterator.hasNext()) {
-+ EnumDirection enumdirection1 = (EnumDirection) iterator.next();
-+ IBlockData iblockdata1 = world.getType(blockposition.shift(enumdirection1));
-+
-+ if (iblockdata1.getBlock() == this) {
-+ return iblockdata;
-+ }
-+
-+ if (iblockdata1.b()) {
-+ if (enumdirection != null) {
-+ enumdirection = null;
-+ break;
-+ }
-+
-+ enumdirection = enumdirection1;
-+ }
-+ }
-+
-+ if (enumdirection != null) {
-+ return iblockdata.set(BlockChest.FACING, enumdirection.opposite());
-+ } else {
-+ EnumDirection enumdirection2 = (EnumDirection) iblockdata.get(BlockChest.FACING);
-+
-+ if (world.getType(blockposition.shift(enumdirection2)).b()) {
-+ enumdirection2 = enumdirection2.opposite();
-+ }
-+
-+ if (world.getType(blockposition.shift(enumdirection2)).b()) {
-+ enumdirection2 = enumdirection2.e();
-+ }
-+
-+ if (world.getType(blockposition.shift(enumdirection2)).b()) {
-+ enumdirection2 = enumdirection2.opposite();
-+ }
-+
-+ return iblockdata.set(BlockChest.FACING, enumdirection2);
-+ }
-+ }
-+
-+ public boolean canPlace(World world, BlockPosition blockposition) {
-+ int i = 0;
-+ BlockPosition blockposition1 = blockposition.west();
-+ BlockPosition blockposition2 = blockposition.east();
-+ BlockPosition blockposition3 = blockposition.north();
-+ BlockPosition blockposition4 = blockposition.south();
-+
-+ if (world.getType(blockposition1).getBlock() == this) {
-+ if (this.d(world, blockposition1)) {
-+ return false;
-+ }
-+
-+ ++i;
-+ }
-+
-+ if (world.getType(blockposition2).getBlock() == this) {
-+ if (this.d(world, blockposition2)) {
-+ return false;
-+ }
-+
-+ ++i;
-+ }
-+
-+ if (world.getType(blockposition3).getBlock() == this) {
-+ if (this.d(world, blockposition3)) {
-+ return false;
-+ }
-+
-+ ++i;
-+ }
-+
-+ if (world.getType(blockposition4).getBlock() == this) {
-+ if (this.d(world, blockposition4)) {
-+ return false;
-+ }
-+
-+ ++i;
-+ }
-+
-+ return i <= 1;
-+ }
-+
-+ private boolean d(World world, BlockPosition blockposition) {
-+ if (world.getType(blockposition).getBlock() != this) {
-+ return false;
-+ } else {
-+ Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
-+
-+ EnumDirection enumdirection;
-+
-+ do {
-+ if (!iterator.hasNext()) {
-+ return false;
-+ }
-+
-+ enumdirection = (EnumDirection) iterator.next();
-+ } while (world.getType(blockposition.shift(enumdirection)).getBlock() != this);
-+
-+ return true;
-+ }
-+ }
-+
-+ public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {
-+ super.doPhysics(world, blockposition, iblockdata, block);
-+ TileEntity tileentity = world.getTileEntity(blockposition);
-+
-+ if (tileentity instanceof TileEntityChest) {
-+ tileentity.invalidateBlockCache();
-+ }
-+
-+ }
-+
-+ public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
-+ TileEntity tileentity = world.getTileEntity(blockposition);
-+
-+ if (tileentity instanceof IInventory) {
-+ InventoryUtils.dropInventory(world, blockposition, (IInventory) tileentity);
-+ world.updateAdjacentComparators(blockposition, this);
-+ }
-+
-+ super.remove(world, blockposition, iblockdata);
-+ }
-+
-+ public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumHand enumhand, ItemStack itemstack, EnumDirection enumdirection, float f, float f1, float f2) {
-+ if (world.isClientSide) {
-+ return true;
-+ } else {
-+ ITileInventory itileinventory = this.c(world, blockposition);
-+
-+ if (itileinventory != null) {
-+ entityhuman.openContainer(itileinventory);
-+ if (this.g == Type.BASIC) {
-+ entityhuman.b(StatisticList.ac);
-+ } else if (this.g == Type.TRAP) {
-+ entityhuman.b(StatisticList.W);
-+ }
-+ }
-+
-+ return true;
-+ }
-+ }
-+
-+ public ITileInventory c(World world, BlockPosition blockposition) {
-+ TileEntity tileentity = world.getTileEntity(blockposition);
-+
-+ if (!(tileentity instanceof TileEntityChest)) {
-+ return null;
-+ } else {
-+ Object object = (TileEntityChest) tileentity;
-+
-+ if (this.e(world, blockposition)) {
-+ return null;
-+ } else {
-+ Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
-+
-+ while (iterator.hasNext()) {
-+ EnumDirection enumdirection = (EnumDirection) iterator.next();
-+ BlockPosition blockposition1 = blockposition.shift(enumdirection);
-+ Block block = world.getType(blockposition1).getBlock();
-+
-+ if (block == this) {
-+ if (this.e(world, blockposition1)) {
-+ return null;
-+ }
-+
-+ TileEntity tileentity1 = world.getTileEntity(blockposition1);
-+
-+ if (tileentity1 instanceof TileEntityChest) {
-+ if (enumdirection != EnumDirection.WEST && enumdirection != EnumDirection.NORTH) {
-+ object = new InventoryLargeChest("container.chestDouble", (ITileInventory) object, (TileEntityChest) tileentity1);
-+ } else {
-+ object = new InventoryLargeChest("container.chestDouble", (TileEntityChest) tileentity1, (ITileInventory) object);
-+ }
-+ }
-+ }
-+ }
-+
-+ return (ITileInventory) object;
-+ }
-+ }
-+ }
-+
-+ public TileEntity a(World world, int i) {
-+ return new TileEntityChest();
-+ }
-+
-+ public boolean isPowerSource(IBlockData iblockdata) {
-+ return this.g == Type.TRAP;
-+ }
-+
-+ public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
-+ if (!iblockdata.m()) {
-+ return 0;
-+ } else {
-+ int i = 0;
-+ TileEntity tileentity = iblockaccess.getTileEntity(blockposition);
-+
-+ if (tileentity instanceof TileEntityChest) {
-+ i = ((TileEntityChest) tileentity).l;
-+ }
-+
-+ return MathHelper.clamp(i, 0, 15);
-+ }
-+ }
-+
-+ public int c(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
-+ return enumdirection == EnumDirection.UP ? iblockdata.a(iblockaccess, blockposition, enumdirection) : 0;
-+ }
-+
-+ private boolean e(World world, BlockPosition blockposition) {
-+ return this.i(world, blockposition) || this.j(world, blockposition);
-+ }
-+
-+ private boolean i(World world, BlockPosition blockposition) {
-+ return world.getType(blockposition.up()).l();
-+ }
-+
-+ private boolean j(World world, BlockPosition blockposition) {
-+ Iterator iterator = world.a(EntityOcelot.class, new AxisAlignedBB((double) blockposition.getX(), (double) (blockposition.getY() + 1), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 2), (double) (blockposition.getZ() + 1))).iterator();
-+
-+ EntityOcelot entityocelot;
-+
-+ do {
-+ if (!iterator.hasNext()) {
-+ return false;
-+ }
-+
-+ Entity entity = (Entity) iterator.next();
-+
-+ entityocelot = (EntityOcelot) entity;
-+ } while (!entityocelot.isSitting());
-+
-+ return true;
-+ }
-+
-+ public boolean isComplexRedstone(IBlockData iblockdata) {
-+ return true;
-+ }
-+
-+ public int d(IBlockData iblockdata, World world, BlockPosition blockposition) {
-+ return Container.b((IInventory) this.c(world, blockposition));
-+ }
-+
-+ public IBlockData fromLegacyData(int i) {
-+ EnumDirection enumdirection = EnumDirection.fromType1(i);
-+
-+ if (enumdirection.k() == EnumDirection.EnumAxis.Y) {
-+ enumdirection = EnumDirection.NORTH;
-+ }
-+
-+ return this.getBlockData().set(BlockChest.FACING, enumdirection);
-+ }
-+
-+ public int toLegacyData(IBlockData iblockdata) {
-+ return ((EnumDirection) iblockdata.get(BlockChest.FACING)).a();
-+ }
-+
-+ public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) {
-+ return iblockdata.set(BlockChest.FACING, enumblockrotation.a((EnumDirection) iblockdata.get(BlockChest.FACING)));
-+ }
-+
-+ public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) {
-+ return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockChest.FACING)));
-+ }
-+
-+ protected BlockStateList getStateList() {
-+ return new BlockStateList(this, new IBlockState[] { BlockChest.FACING});
-+ }
-+
-+ public static enum Type {
-+
-+ BASIC, TRAP;
-+
-+ private Type() {}
-+ }
-+}
-diff --git a/src/main/java/net/minecraft/server/BlockFalling.java b/src/main/java/net/minecraft/server/BlockFalling.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/BlockFalling.java
-@@ -0,0 +0,0 @@
-+package net.minecraft.server;
-+
-+import java.util.Random;
-+
-+public class BlockFalling extends Block {
-+
-+ public static boolean instaFall;
-+
-+ public BlockFalling() {
-+ super(Material.SAND);
-+ this.a(CreativeModeTab.b);
-+ }
-+
-+ public BlockFalling(Material material) {
-+ super(material);
-+ }
-+
-+ public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
-+ world.a(blockposition, (Block) this, this.a(world));
-+ }
-+
-+ public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {
-+ world.a(blockposition, (Block) this, this.a(world));
-+ }
-+
-+ public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
-+ if (!world.isClientSide) {
-+ this.b(world, blockposition);
-+ }
-+
-+ }
-+
-+ private void b(World world, BlockPosition blockposition) {
-+ if (i(world.getType(blockposition.down())) && blockposition.getY() >= 0) {
-+ byte b0 = 32;
-+
-+ if (!BlockFalling.instaFall && world.areChunksLoadedBetween(blockposition.a(-b0, -b0, -b0), blockposition.a(b0, b0, b0))) {
-+ if (!world.isClientSide) {
-+ EntityFallingBlock entityfallingblock = new EntityFallingBlock(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, world.getType(blockposition));
-+
-+ this.a(entityfallingblock);
-+ world.addEntity(entityfallingblock);
-+ }
-+ } else {
-+ world.setAir(blockposition);
-+
-+ BlockPosition blockposition1;
-+
-+ for (blockposition1 = blockposition.down(); i(world.getType(blockposition1)) && blockposition1.getY() > 0; blockposition1 = blockposition1.down()) {
-+ ;
-+ }
-+
-+ if (blockposition1.getY() > 0) {
-+ world.setTypeUpdate(blockposition1.up(), this.getBlockData());
-+ }
-+ }
-+
-+ }
-+ }
-+
-+ protected void a(EntityFallingBlock entityfallingblock) {}
-+
-+ public int a(World world) {
-+ return 2;
-+ }
-+
-+ public static boolean i(IBlockData iblockdata) {
-+ Block block = iblockdata.getBlock();
-+ Material material = iblockdata.getMaterial();
-+
-+ return block == Blocks.FIRE || material == Material.AIR || material == Material.WATER || material == Material.LAVA;
-+ }
-+
-+ public void a_(World world, BlockPosition blockposition) {}
-+}
-diff --git a/src/main/java/net/minecraft/server/BlockFluids.java b/src/main/java/net/minecraft/server/BlockFluids.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/BlockFluids.java
-@@ -0,0 +0,0 @@
-+package net.minecraft.server;
-+
-+import java.util.Iterator;
-+import java.util.Random;
-+
-+public abstract class BlockFluids extends Block {
-+
-+ public static final BlockStateInteger LEVEL = BlockStateInteger.of("level", 0, 15);
-+
-+ protected BlockFluids(Material material) {
-+ super(material);
-+ this.w(this.blockStateList.getBlockData().set(BlockFluids.LEVEL, Integer.valueOf(0)));
-+ this.a(true);
-+ }
-+
-+ public AxisAlignedBB a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) {
-+ return BlockFluids.j;
-+ }
-+
-+ public AxisAlignedBB a(IBlockData iblockdata, World world, BlockPosition blockposition) {
-+ return BlockFluids.k;
-+ }
-+
-+ public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition) {
-+ return this.material != Material.LAVA;
-+ }
-+
-+ public static float e(int i) {
-+ if (i >= 8) {
-+ i = 0;
-+ }
-+
-+ return (float) (i + 1) / 9.0F;
-+ }
-+
-+ protected int c(IBlockAccess iblockaccess, BlockPosition blockposition) {
-+ return iblockaccess.getType(blockposition).getMaterial() == this.material ? ((Integer) iblockaccess.getType(blockposition).get(BlockFluids.LEVEL)).intValue() : -1;
-+ }
-+
-+ protected int d(IBlockAccess iblockaccess, BlockPosition blockposition) {
-+ int i = this.c(iblockaccess, blockposition);
-+
-+ return i >= 8 ? 0 : i;
-+ }
-+
-+ public boolean c(IBlockData iblockdata) {
-+ return false;
-+ }
-+
-+ public boolean b(IBlockData iblockdata) {
-+ return false;
-+ }
-+
-+ public boolean a(IBlockData iblockdata, boolean flag) {
-+ return flag && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0;
-+ }
-+
-+ public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
-+ Material material = iblockaccess.getType(blockposition).getMaterial();
-+
-+ return material == this.material ? false : (enumdirection == EnumDirection.UP ? true : (material == Material.ICE ? false : super.a(iblockaccess, blockposition, enumdirection)));
-+ }
-+
-+ public EnumRenderType a(IBlockData iblockdata) {
-+ return EnumRenderType.LIQUID;
-+ }
-+
-+ public Item getDropType(IBlockData iblockdata, Random random, int i) {
-+ return null;
-+ }
-+
-+ public int a(Random random) {
-+ return 0;
-+ }
-+
-+ protected Vec3D f(IBlockAccess iblockaccess, BlockPosition blockposition) {
-+ double d0 = 0.0D;
-+ double d1 = 0.0D;
-+ double d2 = 0.0D;
-+ int i = this.d(iblockaccess, blockposition);
-+ BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.s();
-+ Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
-+
-+ while (iterator.hasNext()) {
-+ EnumDirection enumdirection = (EnumDirection) iterator.next();
-+
-+ blockposition_pooledblockposition.h(blockposition).c(enumdirection);
-+ int j = this.d(iblockaccess, blockposition_pooledblockposition);
-+ int k;
-+
-+ if (j < 0) {
-+ if (!iblockaccess.getType(blockposition_pooledblockposition).getMaterial().isSolid()) {
-+ j = this.d(iblockaccess, blockposition_pooledblockposition.down());
-+ if (j >= 0) {
-+ k = j - (i - 8);
-+ d0 += (double) (enumdirection.getAdjacentX() * k);
-+ d1 += (double) (enumdirection.getAdjacentY() * k);
-+ d2 += (double) (enumdirection.getAdjacentZ() * k);
-+ }
-+ }
-+ } else if (j >= 0) {
-+ k = j - i;
-+ d0 += (double) (enumdirection.getAdjacentX() * k);
-+ d1 += (double) (enumdirection.getAdjacentY() * k);
-+ d2 += (double) (enumdirection.getAdjacentZ() * k);
-+ }
-+ }
-+
-+ Vec3D vec3d = new Vec3D(d0, d1, d2);
-+
-+ if (((Integer) iblockaccess.getType(blockposition).get(BlockFluids.LEVEL)).intValue() >= 8) {
-+ Iterator iterator1 = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
-+
-+ while (iterator1.hasNext()) {
-+ EnumDirection enumdirection1 = (EnumDirection) iterator1.next();
-+
-+ blockposition_pooledblockposition.h(blockposition).c(enumdirection1);
-+ if (this.a(iblockaccess, (BlockPosition) blockposition_pooledblockposition, enumdirection1) || this.a(iblockaccess, blockposition_pooledblockposition.up(), enumdirection1)) {
-+ vec3d = vec3d.a().add(0.0D, -6.0D, 0.0D);
-+ break;
-+ }
-+ }
-+ }
-+
-+ blockposition_pooledblockposition.t();
-+ return vec3d.a();
-+ }
-+
-+ public Vec3D a(World world, BlockPosition blockposition, Entity entity, Vec3D vec3d) {
-+ return vec3d.e(this.f(world, blockposition));
-+ }
-+
-+ public int a(World world) {
-+ return this.material == Material.WATER ? 5 : (this.material == Material.LAVA ? (world.worldProvider.m() ? 10 : 30) : 0);
-+ }
-+
-+ public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
-+ this.e(world, blockposition, iblockdata);
-+ }
-+
-+ public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {
-+ this.e(world, blockposition, iblockdata);
-+ }
-+
-+ public boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) {
-+ if (this.material == Material.LAVA) {
-+ boolean flag = false;
-+ EnumDirection[] aenumdirection = EnumDirection.values();
-+ int i = aenumdirection.length;
-+
-+ for (int j = 0; j < i; ++j) {
-+ EnumDirection enumdirection = aenumdirection[j];
-+
-+ if (enumdirection != EnumDirection.DOWN && world.getType(blockposition.shift(enumdirection)).getMaterial() == Material.WATER) {
-+ flag = true;
-+ break;
-+ }
-+ }
-+
-+ if (flag) {
-+ Integer integer = (Integer) iblockdata.get(BlockFluids.LEVEL);
-+
-+ if (integer.intValue() == 0) {
-+ world.setTypeUpdate(blockposition, Blocks.OBSIDIAN.getBlockData());
-+ this.fizz(world, blockposition);
-+ return true;
-+ }
-+
-+ if (integer.intValue() <= 4) {
-+ world.setTypeUpdate(blockposition, Blocks.COBBLESTONE.getBlockData());
-+ this.fizz(world, blockposition);
-+ return true;
-+ }
-+ }
-+ }
-+
-+ return false;
-+ }
-+
-+ protected void fizz(World world, BlockPosition blockposition) {
-+ double d0 = (double) blockposition.getX();
-+ double d1 = (double) blockposition.getY();
-+ double d2 = (double) blockposition.getZ();
-+
-+ world.a((EntityHuman) null, blockposition, SoundEffects.db, SoundCategory.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F);
-+
-+ for (int i = 0; i < 8; ++i) {
-+ world.addParticle(EnumParticle.SMOKE_LARGE, d0 + Math.random(), d1 + 1.2D, d2 + Math.random(), 0.0D, 0.0D, 0.0D, new int[0]);
-+ }
-+
-+ }
-+
-+ public IBlockData fromLegacyData(int i) {
-+ return this.getBlockData().set(BlockFluids.LEVEL, Integer.valueOf(i));
-+ }
-+
-+ public int toLegacyData(IBlockData iblockdata) {
-+ return ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue();
-+ }
-+
-+ protected BlockStateList getStateList() {
-+ return new BlockStateList(this, new IBlockState[] { BlockFluids.LEVEL});
-+ }
-+
-+ public static BlockFlowing a(Material material) {
-+ if (material == Material.WATER) {
-+ return Blocks.FLOWING_WATER;
-+ } else if (material == Material.LAVA) {
-+ return Blocks.FLOWING_LAVA;
-+ } else {
-+ throw new IllegalArgumentException("Invalid material");
-+ }
-+ }
-+
-+ public static BlockStationary b(Material material) {
-+ if (material == Material.WATER) {
-+ return Blocks.WATER;
-+ } else if (material == Material.LAVA) {
-+ return Blocks.LAVA;
-+ } else {
-+ throw new IllegalArgumentException("Invalid material");
-+ }
-+ }
-+}
-diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/BlockPosition.java
-@@ -0,0 +0,0 @@
-+package net.minecraft.server;
-+
-+import com.google.common.collect.AbstractIterator;
-+import com.google.common.collect.Lists;
-+import java.util.Iterator;
-+import java.util.List;
-+import org.apache.logging.log4j.LogManager;
-+import org.apache.logging.log4j.Logger;
-+
-+public class BlockPosition extends BaseBlockPosition {
-+
-+ private static final Logger c = LogManager.getLogger();
-+ public static final BlockPosition ZERO = new BlockPosition(0, 0, 0);
-+ private static final int d = 1 + MathHelper.e(MathHelper.c(30000000));
-+ private static final int e = BlockPosition.d;
-+ private static final int f = 64 - BlockPosition.d - BlockPosition.e;
-+ private static final int g = 0 + BlockPosition.e;
-+ private static final int h = BlockPosition.g + BlockPosition.f;
-+ private static final long i = (1L << BlockPosition.d) - 1L;
-+ private static final long j = (1L << BlockPosition.f) - 1L;
-+ private static final long k = (1L << BlockPosition.e) - 1L;
-+
-+ public BlockPosition(int i, int j, int k) {
-+ super(i, j, k);
-+ }
-+
-+ public BlockPosition(double d0, double d1, double d2) {
-+ super(d0, d1, d2);
-+ }
-+
-+ public BlockPosition(Entity entity) {
-+ this(entity.locX, entity.locY, entity.locZ);
-+ }
-+
-+ public BlockPosition(Vec3D vec3d) {
-+ this(vec3d.x, vec3d.y, vec3d.z);
-+ }
-+
-+ public BlockPosition(BaseBlockPosition baseblockposition) {
-+ this(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
-+ }
-+
-+ public BlockPosition a(double d0, double d1, double d2) {
-+ return d0 == 0.0D && d1 == 0.0D && d2 == 0.0D ? this : new BlockPosition((double) this.getX() + d0, (double) this.getY() + d1, (double) this.getZ() + d2);
-+ }
-+
-+ public BlockPosition a(int i, int j, int k) {
-+ return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k);
-+ }
-+
-+ public BlockPosition a(BaseBlockPosition baseblockposition) {
-+ return baseblockposition.getX() == 0 && baseblockposition.getY() == 0 && baseblockposition.getZ() == 0 ? this : new BlockPosition(this.getX() + baseblockposition.getX(), this.getY() + baseblockposition.getY(), this.getZ() + baseblockposition.getZ());
-+ }
-+
-+ public BlockPosition b(BaseBlockPosition baseblockposition) {
-+ return baseblockposition.getX() == 0 && baseblockposition.getY() == 0 && baseblockposition.getZ() == 0 ? this : new BlockPosition(this.getX() - baseblockposition.getX(), this.getY() - baseblockposition.getY(), this.getZ() - baseblockposition.getZ());
-+ }
-+
-+ public BlockPosition up() {
-+ return this.up(1);
-+ }
-+
-+ public BlockPosition up(int i) {
-+ return this.shift(EnumDirection.UP, i);
-+ }
-+
-+ public BlockPosition down() {
-+ return this.down(1);
-+ }
-+
-+ public BlockPosition down(int i) {
-+ return this.shift(EnumDirection.DOWN, i);
-+ }
-+
-+ public BlockPosition north() {
-+ return this.north(1);
-+ }
-+
-+ public BlockPosition north(int i) {
-+ return this.shift(EnumDirection.NORTH, i);
-+ }
-+
-+ public BlockPosition south() {
-+ return this.south(1);
-+ }
-+
-+ public BlockPosition south(int i) {
-+ return this.shift(EnumDirection.SOUTH, i);
-+ }
-+
-+ public BlockPosition west() {
-+ return this.west(1);
-+ }
-+
-+ public BlockPosition west(int i) {
-+ return this.shift(EnumDirection.WEST, i);
-+ }
-+
-+ public BlockPosition east() {
-+ return this.east(1);
-+ }
-+
-+ public BlockPosition east(int i) {
-+ return this.shift(EnumDirection.EAST, i);
-+ }
-+
-+ public BlockPosition shift(EnumDirection enumdirection) {
-+ return this.shift(enumdirection, 1);
-+ }
-+
-+ public BlockPosition shift(EnumDirection enumdirection, int i) {
-+ return i == 0 ? this : new BlockPosition(this.getX() + enumdirection.getAdjacentX() * i, this.getY() + enumdirection.getAdjacentY() * i, this.getZ() + enumdirection.getAdjacentZ() * i);
-+ }
-+
-+ public BlockPosition c(BaseBlockPosition baseblockposition) {
-+ return new BlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX());
-+ }
-+
-+ public long asLong() {
-+ return ((long) this.getX() & BlockPosition.i) << BlockPosition.h | ((long) this.getY() & BlockPosition.j) << BlockPosition.g | ((long) this.getZ() & BlockPosition.k) << 0;
-+ }
-+
-+ public static BlockPosition fromLong(long i) {
-+ int j = (int) (i << 64 - BlockPosition.h - BlockPosition.d >> 64 - BlockPosition.d);
-+ int k = (int) (i << 64 - BlockPosition.g - BlockPosition.f >> 64 - BlockPosition.f);
-+ int l = (int) (i << 64 - BlockPosition.e >> 64 - BlockPosition.e);
-+
-+ return new BlockPosition(j, k, l);
-+ }
-+
-+ public static Iterable a(BlockPosition blockposition, BlockPosition blockposition1) {
-+ final BlockPosition blockposition2 = new BlockPosition(Math.min(blockposition.getX(), blockposition1.getX()), Math.min(blockposition.getY(), blockposition1.getY()), Math.min(blockposition.getZ(), blockposition1.getZ()));
-+ final BlockPosition blockposition3 = new BlockPosition(Math.max(blockposition.getX(), blockposition1.getX()), Math.max(blockposition.getY(), blockposition1.getY()), Math.max(blockposition.getZ(), blockposition1.getZ()));
-+
-+ return new Iterable() {
-+ public Iterator iterator() {
-+ return new AbstractIterator() {
-+ private BlockPosition b = null;
-+
-+ protected BlockPosition a() {
-+ if (this.b == null) {
-+ this.b = blockposition;
-+ return this.b;
-+ } else if (this.b.equals(blockposition1)) {
-+ return (BlockPosition) this.endOfData();
-+ } else {
-+ int i = this.b.getX();
-+ int j = this.b.getY();
-+ int k = this.b.getZ();
-+
-+ if (i < blockposition1.getX()) {
-+ ++i;
-+ } else if (j < blockposition1.getY()) {
-+ i = blockposition.getX();
-+ ++j;
-+ } else if (k < blockposition1.getZ()) {
-+ i = blockposition.getX();
-+ j = blockposition.getY();
-+ ++k;
-+ }
-+
-+ this.b = new BlockPosition(i, j, k);
-+ return this.b;
-+ }
-+ }
-+
-+ protected Object computeNext() {
-+ return this.a();
-+ }
-+ };
-+ }
-+ };
-+ }
-+
-+ public BlockPosition h() {
-+ return this;
-+ }
-+
-+ public static Iterable b(BlockPosition blockposition, BlockPosition blockposition1) {
-+ final BlockPosition blockposition2 = new BlockPosition(Math.min(blockposition.getX(), blockposition1.getX()), Math.min(blockposition.getY(), blockposition1.getY()), Math.min(blockposition.getZ(), blockposition1.getZ()));
-+ final BlockPosition blockposition3 = new BlockPosition(Math.max(blockposition.getX(), blockposition1.getX()), Math.max(blockposition.getY(), blockposition1.getY()), Math.max(blockposition.getZ(), blockposition1.getZ()));
-+
-+ return new Iterable() {
-+ public Iterator iterator() {
-+ return new AbstractIterator() {
-+ private BlockPosition.MutableBlockPosition b = null;
-+
-+ protected BlockPosition.MutableBlockPosition a() {
-+ if (this.b == null) {
-+ this.b = new BlockPosition.MutableBlockPosition(blockposition.getX(), blockposition.getY(), blockposition.getZ());
-+ return this.b;
-+ } else if (this.b.equals(blockposition1)) {
-+ return (BlockPosition.MutableBlockPosition) this.endOfData();
-+ } else {
-+ int i = this.b.getX();
-+ int j = this.b.getY();
-+ int k = this.b.getZ();
-+
-+ if (i < blockposition1.getX()) {
-+ ++i;
-+ } else if (j < blockposition1.getY()) {
-+ i = blockposition.getX();
-+ ++j;
-+ } else if (k < blockposition1.getZ()) {
-+ i = blockposition.getX();
-+ j = blockposition.getY();
-+ ++k;
-+ }
-+
-+ this.b.c = i;
-+ this.b.d = j;
-+ this.b.e = k;
-+ return this.b;
-+ }
-+ }
-+
-+ protected Object computeNext() {
-+ return this.a();
-+ }
-+ };
-+ }
-+ };
-+ }
-+
-+ public BaseBlockPosition d(BaseBlockPosition baseblockposition) {
-+ return this.c(baseblockposition);
-+ }
-+
-+ public static final class PooledBlockPosition extends BlockPosition {
-+
-+ private int c;
-+ private int d;
-+ private int e;
-+ private boolean f;
-+ private static final List g = Lists.newArrayList();
-+
-+ private PooledBlockPosition(int i, int j, int k) {
-+ super(0, 0, 0);
-+ this.c = i;
-+ this.d = j;
-+ this.e = k;
-+ }
-+
-+ public static BlockPosition.PooledBlockPosition s() {
-+ return c(0, 0, 0);
-+ }
-+
-+ public static BlockPosition.PooledBlockPosition c(double d0, double d1, double d2) {
-+ return c(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
-+ }
-+
-+ public static BlockPosition.PooledBlockPosition c(int i, int j, int k) {
-+ List list = BlockPosition.PooledBlockPosition.g;
-+
-+ synchronized (BlockPosition.PooledBlockPosition.g) {
-+ if (!BlockPosition.PooledBlockPosition.g.isEmpty()) {
-+ BlockPosition.PooledBlockPosition blockposition_pooledblockposition = (BlockPosition.PooledBlockPosition) BlockPosition.PooledBlockPosition.g.remove(BlockPosition.PooledBlockPosition.g.size() - 1);
-+
-+ if (blockposition_pooledblockposition != null && blockposition_pooledblockposition.f) {
-+ blockposition_pooledblockposition.f = false;
-+ blockposition_pooledblockposition.d(i, j, k);
-+ return blockposition_pooledblockposition;
-+ }
-+ }
-+ }
-+
-+ return new BlockPosition.PooledBlockPosition(i, j, k);
-+ }
-+
-+ public void t() {
-+ List list = BlockPosition.PooledBlockPosition.g;
-+
-+ synchronized (BlockPosition.PooledBlockPosition.g) {
-+ if (BlockPosition.PooledBlockPosition.g.size() < 100) {
-+ BlockPosition.PooledBlockPosition.g.add(this);
-+ }
-+
-+ this.f = true;
-+ }
-+ }
-+
-+ public int getX() {
-+ return this.c;
-+ }
-+
-+ public int getY() {
-+ return this.d;
-+ }
-+
-+ public int getZ() {
-+ return this.e;
-+ }
-+
-+ public BlockPosition.PooledBlockPosition d(int i, int j, int k) {
-+ if (this.f) {
-+ BlockPosition.c.error("PooledMutableBlockPosition modified after it was released.", new Throwable());
-+ this.f = false;
-+ }
-+
-+ this.c = i;
-+ this.d = j;
-+ this.e = k;
-+ return this;
-+ }
-+
-+ public BlockPosition.PooledBlockPosition d(double d0, double d1, double d2) {
-+ return this.d(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
-+ }
-+
-+ public BlockPosition.PooledBlockPosition h(BaseBlockPosition baseblockposition) {
-+ return this.d(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
-+ }
-+
-+ public BlockPosition.PooledBlockPosition c(EnumDirection enumdirection) {
-+ return this.d(this.c + enumdirection.getAdjacentX(), this.d + enumdirection.getAdjacentY(), this.e + enumdirection.getAdjacentZ());
-+ }
-+
-+ public BaseBlockPosition d(BaseBlockPosition baseblockposition) {
-+ return super.c(baseblockposition);
-+ }
-+ }
-+
-+ public static final class MutableBlockPosition extends BlockPosition {
-+
-+ private int c;
-+ private int d;
-+ private int e;
-+
-+ public MutableBlockPosition() {
-+ this(0, 0, 0);
-+ }
-+
-+ public MutableBlockPosition(BlockPosition blockposition) {
-+ this(blockposition.getX(), blockposition.getY(), blockposition.getZ());
-+ }
-+
-+ public MutableBlockPosition(int i, int j, int k) {
-+ super(0, 0, 0);
-+ this.c = i;
-+ this.d = j;
-+ this.e = k;
-+ }
-+
-+ public int getX() {
-+ return this.c;
-+ }
-+
-+ public int getY() {
-+ return this.d;
-+ }
-+
-+ public int getZ() {
-+ return this.e;
-+ }
-+
-+ public BlockPosition.MutableBlockPosition c(int i, int j, int k) {
-+ this.c = i;
-+ this.d = j;
-+ this.e = k;
-+ return this;
-+ }
-+
-+ public void c(EnumDirection enumdirection) {
-+ this.c += enumdirection.getAdjacentX();
-+ this.d += enumdirection.getAdjacentY();
-+ this.e += enumdirection.getAdjacentZ();
-+ }
-+
-+ public void p(int i) {
-+ this.d = i;
-+ }
-+
-+ public BlockPosition h() {
-+ return new BlockPosition(this);
-+ }
-+
-+ public BaseBlockPosition d(BaseBlockPosition baseblockposition) {
-+ return super.c(baseblockposition);
-+ }
-+ }
-+}
-diff --git a/src/main/java/net/minecraft/server/BlockStateList.java b/src/main/java/net/minecraft/server/BlockStateList.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/BlockStateList.java
-@@ -0,0 +0,0 @@
-+package net.minecraft.server;
-+
-+import com.google.common.base.Function;
-+import com.google.common.base.Objects;
-+import com.google.common.collect.HashBasedTable;
-+import com.google.common.collect.ImmutableCollection;
-+import com.google.common.collect.ImmutableList;
-+import com.google.common.collect.ImmutableMap;
-+import com.google.common.collect.ImmutableSortedMap;
-+import com.google.common.collect.ImmutableTable;
-+import com.google.common.collect.Iterables;
-+import com.google.common.collect.Lists;
-+import com.google.common.collect.Maps;
-+import java.util.ArrayList;
-+import java.util.Collection;
-+import java.util.Collections;
-+import java.util.HashMap;
-+import java.util.Iterator;
-+import java.util.LinkedHashMap;
-+import java.util.List;
-+import java.util.Map;
-+import java.util.Map.Entry;
-+import java.util.regex.Pattern;
-+
-+public class BlockStateList {
-+
-+ private static final Pattern a = Pattern.compile("^[a-z0-9_]+$");
-+ private static final Function, String> b = new Function() {
-+ public String a(IBlockState> iblockstate) {
-+ return iblockstate == null ? "" : iblockstate.a();
-+ }
-+
-+ public Object apply(Object object) {
-+ return this.a((IBlockState) object);
-+ }
-+ };
-+ private final Block c;
-+ private final ImmutableSortedMap> d;
-+ private final ImmutableList e;
-+
-+ public BlockStateList(Block block, IBlockState>... aiblockstate) {
-+ this.c = block;
-+ HashMap hashmap = Maps.newHashMap();
-+ IBlockState[] aiblockstate1 = aiblockstate;
-+ int i = aiblockstate.length;
-+
-+ for (int j = 0; j < i; ++j) {
-+ IBlockState iblockstate = aiblockstate1[j];
-+
-+ a(block, iblockstate);
-+ hashmap.put(iblockstate.a(), iblockstate);
-+ }
-+
-+ this.d = ImmutableSortedMap.copyOf(hashmap);
-+ LinkedHashMap linkedhashmap = Maps.newLinkedHashMap();
-+ ArrayList arraylist = Lists.newArrayList();
-+ Iterable iterable = IteratorUtils.a(this.e());
-+ Iterator iterator = iterable.iterator();
-+
-+ while (iterator.hasNext()) {
-+ List list = (List) iterator.next();
-+ Map map = MapGeneratorUtils.b(this.d.values(), list);
-+ BlockStateList.BlockData blockstatelist_blockdata = new BlockStateList.BlockData(block, ImmutableMap.copyOf(map), null);
-+
-+ linkedhashmap.put(map, blockstatelist_blockdata);
-+ arraylist.add(blockstatelist_blockdata);
-+ }
-+
-+ iterator = arraylist.iterator();
-+
-+ while (iterator.hasNext()) {
-+ BlockStateList.BlockData blockstatelist_blockdata1 = (BlockStateList.BlockData) iterator.next();
-+
-+ blockstatelist_blockdata1.a((Map) linkedhashmap);
-+ }
-+
-+ this.e = ImmutableList.copyOf(arraylist);
-+ }
-+
-+ public static > String a(Block block, IBlockState iblockstate) {
-+ String s = iblockstate.a();
-+
-+ if (!BlockStateList.a.matcher(s).matches()) {
-+ throw new IllegalArgumentException("Block: " + block.getClass() + " has invalidly named property: " + s);
-+ } else {
-+ for (T t : iblockstate.c()) {
-+ String s1 = iblockstate.a(t);
-+
-+ if (!a.matcher(s1).matches())
-+ {
-+ throw new IllegalArgumentException("Block: " + block.getClass() + " has property: " + s + " with invalidly named value: " + s1);
-+ }
-+ }
-+ }
-+ return s;
-+ }
-+
-+ public ImmutableList a() {
-+ return this.e;
-+ }
-+
-+ private List>> e() {
-+ ArrayList arraylist = Lists.newArrayList();
-+ ImmutableCollection immutablecollection = this.d.values();
-+ Iterator iterator = immutablecollection.iterator();
-+
-+ while (iterator.hasNext()) {
-+ IBlockState iblockstate = (IBlockState) iterator.next();
-+
-+ arraylist.add(iblockstate.c());
-+ }
-+
-+ return arraylist;
-+ }
-+
-+ public IBlockData getBlockData() {
-+ return (IBlockData) this.e.get(0);
-+ }
-+
-+ public Block getBlock() {
-+ return this.c;
-+ }
-+
-+ public Collection> d() {
-+ return this.d.values();
-+ }
-+
-+ public String toString() {
-+ return Objects.toStringHelper(this).add("block", Block.REGISTRY.b(this.c)).add("properties", Iterables.transform(this.d.values(), BlockStateList.b)).toString();
-+ }
-+
-+ static class BlockData extends BlockDataAbstract {
-+
-+ private final Block a;
-+ private final ImmutableMap, Comparable>> b;
-+ private ImmutableTable, Comparable>, IBlockData> c;
-+
-+ private BlockData(Block block, ImmutableMap, Comparable>> immutablemap) {
-+ this.a = block;
-+ this.b = immutablemap;
-+ }
-+
-+ public Collection> r() {
-+ return Collections.unmodifiableCollection(this.b.keySet());
-+ }
-+
-+ public > T get(IBlockState iblockstate) {
-+ if (!this.b.containsKey(iblockstate)) {
-+ throw new IllegalArgumentException("Cannot get property " + iblockstate + " as it does not exist in " + this.a.t());
-+ } else {
-+ return iblockstate.b().cast(this.b.get(iblockstate));
-+ }
-+ }
-+
-+ public , V extends T> IBlockData set(IBlockState iblockstate, V v0) {
-+ if (!this.b.containsKey(iblockstate)) {
-+ throw new IllegalArgumentException("Cannot set property " + iblockstate + " as it does not exist in " + this.a.t());
-+ } else if (!iblockstate.c().contains(v0)) {
-+ throw new IllegalArgumentException("Cannot set property " + iblockstate + " to " + v0 + " on block " + Block.REGISTRY.b(this.a) + ", it is not an allowed value");
-+ } else {
-+ return (IBlockData) (this.b.get(iblockstate) == v0 ? this : (IBlockData) this.c.get(iblockstate, v0));
-+ }
-+ }
-+
-+ public ImmutableMap, Comparable>> s() {
-+ return this.b;
-+ }
-+
-+ public Block getBlock() {
-+ return this.a;
-+ }
-+
-+ public boolean equals(Object object) {
-+ return this == object;
-+ }
-+
-+ public int hashCode() {
-+ return this.b.hashCode();
-+ }
-+
-+ public void a(Map