From cead4c266909b279e8eeeea1d021d1f647b150e5 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 1 Dec 2013 15:10:48 +1100
Subject: [PATCH] mc-dev imports


diff --git a/src/main/java/net/minecraft/server/BlockBrewingStand.java b/src/main/java/net/minecraft/server/BlockBrewingStand.java
new file mode 100644
index 0000000..3287d77
--- /dev/null
+++ b/src/main/java/net/minecraft/server/BlockBrewingStand.java
@@ -0,0 +1,109 @@
+package net.minecraft.server;
+
+import java.util.List;
+import java.util.Random;
+
+public class BlockBrewingStand extends BlockContainer {
+
+    private Random a = new Random();
+
+    public BlockBrewingStand() {
+        super(Material.ORE);
+    }
+
+    public boolean c() {
+        return false;
+    }
+
+    public int b() {
+        return 25;
+    }
+
+    public TileEntity a(World world, int i) {
+        return new TileEntityBrewingStand();
+    }
+
+    public boolean d() {
+        return false;
+    }
+
+    public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, List list, Entity entity) {
+        this.a(0.4375F, 0.0F, 0.4375F, 0.5625F, 0.875F, 0.5625F);
+        super.a(world, i, j, k, axisalignedbb, list, entity);
+        this.g();
+        super.a(world, i, j, k, axisalignedbb, list, entity);
+    }
+
+    public void g() {
+        this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
+    }
+
+    public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
+        if (world.isStatic) {
+            return true;
+        } else {
+            TileEntityBrewingStand tileentitybrewingstand = (TileEntityBrewingStand) world.getTileEntity(i, j, k);
+
+            if (tileentitybrewingstand != null) {
+                entityhuman.openBrewingStand(tileentitybrewingstand);
+            }
+
+            return true;
+        }
+    }
+
+    public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
+        if (itemstack.hasName()) {
+            ((TileEntityBrewingStand) world.getTileEntity(i, j, k)).a(itemstack.getName());
+        }
+    }
+
+    public void remove(World world, int i, int j, int k, Block block, int l) {
+        TileEntity tileentity = world.getTileEntity(i, j, k);
+
+        if (tileentity instanceof TileEntityBrewingStand) {
+            TileEntityBrewingStand tileentitybrewingstand = (TileEntityBrewingStand) tileentity;
+
+            for (int i1 = 0; i1 < tileentitybrewingstand.getSize(); ++i1) {
+                ItemStack itemstack = tileentitybrewingstand.getItem(i1);
+
+                if (itemstack != null) {
+                    float f = this.a.nextFloat() * 0.8F + 0.1F;
+                    float f1 = this.a.nextFloat() * 0.8F + 0.1F;
+                    float f2 = this.a.nextFloat() * 0.8F + 0.1F;
+
+                    while (itemstack.count > 0) {
+                        int j1 = this.a.nextInt(21) + 10;
+
+                        if (j1 > itemstack.count) {
+                            j1 = itemstack.count;
+                        }
+
+                        itemstack.count -= j1;
+                        EntityItem entityitem = new EntityItem(world, (double) ((float) i + f), (double) ((float) j + f1), (double) ((float) k + f2), new ItemStack(itemstack.getItem(), j1, itemstack.getData()));
+                        float f3 = 0.05F;
+
+                        entityitem.motX = (double) ((float) this.a.nextGaussian() * f3);
+                        entityitem.motY = (double) ((float) this.a.nextGaussian() * f3 + 0.2F);
+                        entityitem.motZ = (double) ((float) this.a.nextGaussian() * f3);
+                        world.addEntity(entityitem);
+                    }
+                }
+            }
+        }
+
+        super.remove(world, i, j, k, block, l);
+    }
+
+    public Item getDropType(int i, Random random, int j) {
+        return Items.BREWING_STAND;
+    }
+
+    public boolean M() {
+        return true;
+    }
+
+    public int g(World world, int i, int j, int k, int l) {
+        return Container.b((IInventory) world.getTileEntity(i, j, k));
+    }
+}
diff --git a/src/main/java/net/minecraft/server/BlockFlowerPot.java b/src/main/java/net/minecraft/server/BlockFlowerPot.java
new file mode 100644
index 0000000..ef909f7
--- /dev/null
+++ b/src/main/java/net/minecraft/server/BlockFlowerPot.java
@@ -0,0 +1,195 @@
+package net.minecraft.server;
+
+import java.util.Random;
+
+public class BlockFlowerPot extends BlockContainer {
+
+    public BlockFlowerPot() {
+        super(Material.ORIENTABLE);
+        this.g();
+    }
+
+    public void g() {
+        float f = 0.375F;
+        float f1 = f / 2.0F;
+
+        this.a(0.5F - f1, 0.0F, 0.5F - f1, 0.5F + f1, f, 0.5F + f1);
+    }
+
+    public boolean c() {
+        return false;
+    }
+
+    public int b() {
+        return 33;
+    }
+
+    public boolean d() {
+        return false;
+    }
+
+    public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
+        ItemStack itemstack = entityhuman.inventory.getItemInHand();
+
+        if (itemstack != null && itemstack.getItem() instanceof ItemBlock) {
+            if (world.getData(i, j, k) != 0) {
+                return false;
+            } else {
+                TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
+
+                if (tileentityflowerpot != null) {
+                    Block block = Block.a(itemstack.getItem());
+
+                    if (!this.a(block, itemstack.getData())) {
+                        return false;
+                    } else {
+                        tileentityflowerpot.a(itemstack.getItem(), itemstack.getData());
+                        tileentityflowerpot.update();
+                        if (!world.setData(i, j, k, itemstack.getData(), 2)) {
+                            world.notify(i, j, k);
+                        }
+
+                        if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count <= 0) {
+                            entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null);
+                        }
+
+                        return true;
+                    }
+                } else {
+                    return false;
+                }
+            }
+        } else {
+            return false;
+        }
+    }
+
+    private boolean a(Block block, int i) {
+        return block != Blocks.YELLOW_FLOWER && block != Blocks.RED_ROSE && block != Blocks.CACTUS && block != Blocks.BROWN_MUSHROOM && block != Blocks.RED_MUSHROOM && block != Blocks.SAPLING && block != Blocks.DEAD_BUSH ? block == Blocks.LONG_GRASS && i == 2 : true;
+    }
+
+    public int getDropData(World world, int i, int j, int k) {
+        TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
+
+        return tileentityflowerpot != null && tileentityflowerpot.a() != null ? tileentityflowerpot.b() : 0;
+    }
+
+    public boolean canPlace(World world, int i, int j, int k) {
+        return super.canPlace(world, i, j, k) && World.a((IBlockAccess) world, i, j - 1, k);
+    }
+
+    public void doPhysics(World world, int i, int j, int k, Block block) {
+        if (!World.a((IBlockAccess) world, i, j - 1, k)) {
+            this.b(world, i, j, k, world.getData(i, j, k), 0);
+            world.setAir(i, j, k);
+        }
+    }
+
+    public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
+        super.dropNaturally(world, i, j, k, l, f, i1);
+        TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
+
+        if (tileentityflowerpot != null && tileentityflowerpot.a() != null) {
+            this.a(world, i, j, k, new ItemStack(tileentityflowerpot.a(), 1, tileentityflowerpot.b()));
+        }
+    }
+
+    public void remove(World world, int i, int j, int k, Block block, int l) {
+        TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
+
+        if (tileentityflowerpot != null && tileentityflowerpot.a() != null) {
+            this.a(world, i, j, k, new ItemStack(tileentityflowerpot.a(), 1, tileentityflowerpot.b()));
+        }
+
+        super.remove(world, i, j, k, block, l);
+    }
+
+    public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
+        super.a(world, i, j, k, l, entityhuman);
+        if (entityhuman.abilities.canInstantlyBuild) {
+            TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
+
+            if (tileentityflowerpot != null) {
+                tileentityflowerpot.a(Item.d(0), 0);
+            }
+        }
+    }
+
+    public Item getDropType(int i, Random random, int j) {
+        return Items.FLOWER_POT;
+    }
+
+    private TileEntityFlowerPot e(World world, int i, int j, int k) {
+        TileEntity tileentity = world.getTileEntity(i, j, k);
+
+        return tileentity != null && tileentity instanceof TileEntityFlowerPot ? (TileEntityFlowerPot) tileentity : null;
+    }
+
+    public TileEntity a(World world, int i) {
+        Object object = null;
+        byte b0 = 0;
+
+        switch (i) {
+        case 1:
+            object = Blocks.RED_ROSE;
+            b0 = 0;
+            break;
+
+        case 2:
+            object = Blocks.YELLOW_FLOWER;
+            break;
+
+        case 3:
+            object = Blocks.SAPLING;
+            b0 = 0;
+            break;
+
+        case 4:
+            object = Blocks.SAPLING;
+            b0 = 1;
+            break;
+
+        case 5:
+            object = Blocks.SAPLING;
+            b0 = 2;
+            break;
+
+        case 6:
+            object = Blocks.SAPLING;
+            b0 = 3;
+            break;
+
+        case 7:
+            object = Blocks.RED_MUSHROOM;
+            break;
+
+        case 8:
+            object = Blocks.BROWN_MUSHROOM;
+            break;
+
+        case 9:
+            object = Blocks.CACTUS;
+            break;
+
+        case 10:
+            object = Blocks.DEAD_BUSH;
+            break;
+
+        case 11:
+            object = Blocks.LONG_GRASS;
+            b0 = 2;
+            break;
+
+        case 12:
+            object = Blocks.SAPLING;
+            b0 = 4;
+            break;
+
+        case 13:
+            object = Blocks.SAPLING;
+            b0 = 5;
+        }
+
+        return new TileEntityFlowerPot(Item.getItemOf((Block) object), b0);
+    }
+}
diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java
new file mode 100644
index 0000000..6d5090b
--- /dev/null
+++ b/src/main/java/net/minecraft/server/BlockTNT.java
@@ -0,0 +1,80 @@
+package net.minecraft.server;
+
+import java.util.Random;
+
+public class BlockTNT extends Block {
+
+    public BlockTNT() {
+        super(Material.TNT);
+        this.a(CreativeModeTab.d);
+    }
+
+    public void onPlace(World world, int i, int j, int k) {
+        super.onPlace(world, i, j, k);
+        if (world.isBlockIndirectlyPowered(i, j, k)) {
+            this.postBreak(world, i, j, k, 1);
+            world.setAir(i, j, k);
+        }
+    }
+
+    public void doPhysics(World world, int i, int j, int k, Block block) {
+        if (world.isBlockIndirectlyPowered(i, j, k)) {
+            this.postBreak(world, i, j, k, 1);
+            world.setAir(i, j, k);
+        }
+    }
+
+    public int a(Random random) {
+        return 1;
+    }
+
+    public void wasExploded(World world, int i, int j, int k, Explosion explosion) {
+        if (!world.isStatic) {
+            EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), explosion.c());
+
+            entitytntprimed.fuseTicks = world.random.nextInt(entitytntprimed.fuseTicks / 4) + entitytntprimed.fuseTicks / 8;
+            world.addEntity(entitytntprimed);
+        }
+    }
+
+    public void postBreak(World world, int i, int j, int k, int l) {
+        this.a(world, i, j, k, l, (EntityLiving) null);
+    }
+
+    public void a(World world, int i, int j, int k, int l, EntityLiving entityliving) {
+        if (!world.isStatic) {
+            if ((l & 1) == 1) {
+                EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), entityliving);
+
+                world.addEntity(entitytntprimed);
+                world.makeSound(entitytntprimed, "game.tnt.primed", 1.0F, 1.0F);
+            }
+        }
+    }
+
+    public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
+        if (entityhuman.bD() != null && entityhuman.bD().getItem() == Items.FLINT_AND_STEEL) {
+            this.a(world, i, j, k, 1, entityhuman);
+            world.setAir(i, j, k);
+            entityhuman.bD().damage(1, entityhuman);
+            return true;
+        } else {
+            return super.interact(world, i, j, k, entityhuman, l, f, f1, f2);
+        }
+    }
+
+    public void a(World world, int i, int j, int k, Entity entity) {
+        if (entity instanceof EntityArrow && !world.isStatic) {
+            EntityArrow entityarrow = (EntityArrow) entity;
+
+            if (entityarrow.isBurning()) {
+                this.a(world, i, j, k, 1, entityarrow.shooter instanceof EntityLiving ? (EntityLiving) entityarrow.shooter : null);
+                world.setAir(i, j, k);
+            }
+        }
+    }
+
+    public boolean a(Explosion explosion) {
+        return false;
+    }
+}
diff --git a/src/main/java/net/minecraft/server/EntityItemFrame.java b/src/main/java/net/minecraft/server/EntityItemFrame.java
new file mode 100644
index 0000000..261d0c1
--- /dev/null
+++ b/src/main/java/net/minecraft/server/EntityItemFrame.java
@@ -0,0 +1,146 @@
+package net.minecraft.server;
+
+public class EntityItemFrame extends EntityHanging {
+
+    private float e = 1.0F;
+
+    public EntityItemFrame(World world) {
+        super(world);
+    }
+
+    public EntityItemFrame(World world, int i, int j, int k, int l) {
+        super(world, i, j, k, l);
+        this.setDirection(l);
+    }
+
+    protected void c() {
+        this.getDataWatcher().a(2, 5);
+        this.getDataWatcher().a(3, Byte.valueOf((byte) 0));
+    }
+
+    public boolean damageEntity(DamageSource damagesource, float f) {
+        if (this.isInvulnerable()) {
+            return false;
+        } else if (this.getItem() != null) {
+            if (!this.world.isStatic) {
+                this.b(damagesource.getEntity(), false);
+                this.setItem((ItemStack) null);
+            }
+
+            return true;
+        } else {
+            return super.damageEntity(damagesource, f);
+        }
+    }
+
+    public int f() {
+        return 9;
+    }
+
+    public int i() {
+        return 9;
+    }
+
+    public void b(Entity entity) {
+        this.b(entity, true);
+    }
+
+    public void b(Entity entity, boolean flag) {
+        ItemStack itemstack = this.getItem();
+
+        if (entity instanceof EntityHuman) {
+            EntityHuman entityhuman = (EntityHuman) entity;
+
+            if (entityhuman.abilities.canInstantlyBuild) {
+                this.b(itemstack);
+                return;
+            }
+        }
+
+        if (flag) {
+            this.a(new ItemStack(Items.ITEM_FRAME), 0.0F);
+        }
+
+        if (itemstack != null && this.random.nextFloat() < this.e) {
+            itemstack = itemstack.cloneItemStack();
+            this.b(itemstack);
+            this.a(itemstack, 0.0F);
+        }
+    }
+
+    private void b(ItemStack itemstack) {
+        if (itemstack != null) {
+            if (itemstack.getItem() == Items.MAP) {
+                WorldMap worldmap = ((ItemWorldMap) itemstack.getItem()).getSavedMap(itemstack, this.world);
+
+                worldmap.g.remove("frame-" + this.getId());
+            }
+
+            itemstack.a((EntityItemFrame) null);
+        }
+    }
+
+    public ItemStack getItem() {
+        return this.getDataWatcher().getItemStack(2);
+    }
+
+    public void setItem(ItemStack itemstack) {
+        if (itemstack != null) {
+            itemstack = itemstack.cloneItemStack();
+            itemstack.count = 1;
+            itemstack.a(this);
+        }
+
+        this.getDataWatcher().watch(2, itemstack);
+        this.getDataWatcher().h(2);
+    }
+
+    public int getRotation() {
+        return this.getDataWatcher().getByte(3);
+    }
+
+    public void setRotation(int i) {
+        this.getDataWatcher().watch(3, Byte.valueOf((byte) (i % 4)));
+    }
+
+    public void b(NBTTagCompound nbttagcompound) {
+        if (this.getItem() != null) {
+            nbttagcompound.set("Item", this.getItem().save(new NBTTagCompound()));
+            nbttagcompound.setByte("ItemRotation", (byte) this.getRotation());
+            nbttagcompound.setFloat("ItemDropChance", this.e);
+        }
+
+        super.b(nbttagcompound);
+    }
+
+    public void a(NBTTagCompound nbttagcompound) {
+        NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Item");
+
+        if (nbttagcompound1 != null && !nbttagcompound1.isEmpty()) {
+            this.setItem(ItemStack.createStack(nbttagcompound1));
+            this.setRotation(nbttagcompound.getByte("ItemRotation"));
+            if (nbttagcompound.hasKeyOfType("ItemDropChance", 99)) {
+                this.e = nbttagcompound.getFloat("ItemDropChance");
+            }
+        }
+
+        super.a(nbttagcompound);
+    }
+
+    public boolean c(EntityHuman entityhuman) {
+        if (this.getItem() == null) {
+            ItemStack itemstack = entityhuman.be();
+
+            if (itemstack != null && !this.world.isStatic) {
+                this.setItem(itemstack);
+                if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count <= 0) {
+                    entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null);
+                }
+            }
+        } else if (!this.world.isStatic) {
+            this.setRotation(this.getRotation() + 1);
+        }
+
+        return true;
+    }
+}
diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
new file mode 100644
index 0000000..06934a1
--- /dev/null
+++ b/src/main/java/net/minecraft/server/NextTickListEntry.java
@@ -0,0 +1,60 @@
+package net.minecraft.server;
+
+public class NextTickListEntry implements Comparable {
+
+    private static long f;
+    private final Block g;
+    public int a;
+    public int b;
+    public int c;
+    public long d;
+    public int e;
+    private long h;
+
+    public NextTickListEntry(int i, int j, int k, Block block) {
+        this.h = (long) (f++);
+        this.a = i;
+        this.b = j;
+        this.c = k;
+        this.g = block;
+    }
+
+    public boolean equals(Object object) {
+        if (!(object instanceof NextTickListEntry)) {
+            return false;
+        } else {
+            NextTickListEntry nextticklistentry = (NextTickListEntry) object;
+
+            return this.a == nextticklistentry.a && this.b == nextticklistentry.b && this.c == nextticklistentry.c && Block.a(this.g, nextticklistentry.g);
+        }
+    }
+
+    public int hashCode() {
+        return (this.a * 1024 * 1024 + this.c * 1024 + this.b) * 256;
+    }
+
+    public NextTickListEntry a(long i) {
+        this.d = i;
+        return this;
+    }
+
+    public void a(int i) {
+        this.e = i;
+    }
+
+    public int compareTo(NextTickListEntry nextticklistentry) {
+        return this.d < nextticklistentry.d ? -1 : (this.d > nextticklistentry.d ? 1 : (this.e != nextticklistentry.e ? this.e - nextticklistentry.e : (this.h < nextticklistentry.h ? -1 : (this.h > nextticklistentry.h ? 1 : 0))));
+    }
+
+    public String toString() {
+        return Block.b(this.g) + ": (" + this.a + ", " + this.b + ", " + this.c + "), " + this.d + ", " + this.e + ", " + this.h;
+    }
+
+    public Block a() {
+        return this.g;
+    }
+
+    public int compareTo(Object object) {
+        return this.compareTo((NextTickListEntry) object);
+    }
+}
diff --git a/src/main/java/net/minecraft/server/NibbleArray.java b/src/main/java/net/minecraft/server/NibbleArray.java
new file mode 100644
index 0000000..5d75a54
--- /dev/null
+++ b/src/main/java/net/minecraft/server/NibbleArray.java
@@ -0,0 +1,40 @@
+package net.minecraft.server;
+
+public class NibbleArray {
+
+    public final byte[] a;
+    private final int b;
+    private final int c;
+
+    public NibbleArray(int i, int j) {
+        this.a = new byte[i >> 1];
+        this.b = j;
+        this.c = j + 4;
+    }
+
+    public NibbleArray(byte[] abyte, int i) {
+        this.a = abyte;
+        this.b = i;
+        this.c = i + 4;
+    }
+
+    public int a(int i, int j, int k) {
+        int l = j << this.c | k << this.b | i;
+        int i1 = l >> 1;
+        int j1 = l & 1;
+
+        return j1 == 0 ? this.a[i1] & 15 : this.a[i1] >> 4 & 15;
+    }
+
+    public void a(int i, int j, int k, int l) {
+        int i1 = j << this.c | k << this.b | i;
+        int j1 = i1 >> 1;
+        int k1 = i1 & 1;
+
+        if (k1 == 0) {
+            this.a[j1] = (byte) (this.a[j1] & 240 | l & 15);
+        } else {
+            this.a[j1] = (byte) (this.a[j1] & 15 | (l & 15) << 4);
+        }
+    }
+}
diff --git a/src/main/java/net/minecraft/server/OldChunkLoader.java b/src/main/java/net/minecraft/server/OldChunkLoader.java
new file mode 100644
index 0000000..fcb9912
--- /dev/null
+++ b/src/main/java/net/minecraft/server/OldChunkLoader.java
@@ -0,0 +1,120 @@
+package net.minecraft.server;
+
+public class OldChunkLoader {
+
+    public static OldChunk a(NBTTagCompound nbttagcompound) {
+        int i = nbttagcompound.getInt("xPos");
+        int j = nbttagcompound.getInt("zPos");
+        OldChunk oldchunk = new OldChunk(i, j);
+
+        oldchunk.g = nbttagcompound.getByteArray("Blocks");
+        oldchunk.f = new OldNibbleArray(nbttagcompound.getByteArray("Data"), 7);
+        oldchunk.e = new OldNibbleArray(nbttagcompound.getByteArray("SkyLight"), 7);
+        oldchunk.d = new OldNibbleArray(nbttagcompound.getByteArray("BlockLight"), 7);
+        oldchunk.c = nbttagcompound.getByteArray("HeightMap");
+        oldchunk.b = nbttagcompound.getBoolean("TerrainPopulated");
+        oldchunk.h = nbttagcompound.getList("Entities", 10);
+        oldchunk.i = nbttagcompound.getList("TileEntities", 10);
+        oldchunk.j = nbttagcompound.getList("TileTicks", 10);
+
+        try {
+            oldchunk.a = nbttagcompound.getLong("LastUpdate");
+        } catch (ClassCastException classcastexception) {
+            oldchunk.a = (long) nbttagcompound.getInt("LastUpdate");
+        }
+
+        return oldchunk;
+    }
+
+    public static void a(OldChunk oldchunk, NBTTagCompound nbttagcompound, WorldChunkManager worldchunkmanager) {
+        nbttagcompound.setInt("xPos", oldchunk.k);
+        nbttagcompound.setInt("zPos", oldchunk.l);
+        nbttagcompound.setLong("LastUpdate", oldchunk.a);
+        int[] aint = new int[oldchunk.c.length];
+
+        for (int i = 0; i < oldchunk.c.length; ++i) {
+            aint[i] = oldchunk.c[i];
+        }
+
+        nbttagcompound.setIntArray("HeightMap", aint);
+        nbttagcompound.setBoolean("TerrainPopulated", oldchunk.b);
+        NBTTagList nbttaglist = new NBTTagList();
+
+        int j;
+
+        for (int k = 0; k < 8; ++k) {
+            boolean flag = true;
+
+            for (j = 0; j < 16 && flag; ++j) {
+                int l = 0;
+
+                while (l < 16 && flag) {
+                    int i1 = 0;
+
+                    while (true) {
+                        if (i1 < 16) {
+                            int j1 = j << 11 | i1 << 7 | l + (k << 4);
+                            byte b0 = oldchunk.g[j1];
+
+                            if (b0 == 0) {
+                                ++i1;
+                                continue;
+                            }
+
+                            flag = false;
+                        }
+
+                        ++l;
+                        break;
+                    }
+                }
+            }
+
+            if (!flag) {
+                byte[] abyte = new byte[4096];
+                NibbleArray nibblearray = new NibbleArray(abyte.length, 4);
+                NibbleArray nibblearray1 = new NibbleArray(abyte.length, 4);
+                NibbleArray nibblearray2 = new NibbleArray(abyte.length, 4);
+
+                for (int k1 = 0; k1 < 16; ++k1) {
+                    for (int l1 = 0; l1 < 16; ++l1) {
+                        for (int i2 = 0; i2 < 16; ++i2) {
+                            int j2 = k1 << 11 | i2 << 7 | l1 + (k << 4);
+                            byte b1 = oldchunk.g[j2];
+
+                            abyte[l1 << 8 | i2 << 4 | k1] = (byte) (b1 & 255);
+                            nibblearray.a(k1, l1, i2, oldchunk.f.a(k1, l1 + (k << 4), i2));
+                            nibblearray1.a(k1, l1, i2, oldchunk.e.a(k1, l1 + (k << 4), i2));
+                            nibblearray2.a(k1, l1, i2, oldchunk.d.a(k1, l1 + (k << 4), i2));
+                        }
+                    }
+                }
+
+                NBTTagCompound nbttagcompound1 = new NBTTagCompound();
+
+                nbttagcompound1.setByte("Y", (byte) (k & 255));
+                nbttagcompound1.setByteArray("Blocks", abyte);
+                nbttagcompound1.setByteArray("Data", nibblearray.a);
+                nbttagcompound1.setByteArray("SkyLight", nibblearray1.a);
+                nbttagcompound1.setByteArray("BlockLight", nibblearray2.a);
+                nbttaglist.add(nbttagcompound1);
+            }
+        }
+
+        nbttagcompound.set("Sections", nbttaglist);
+        byte[] abyte1 = new byte[256];
+
+        for (int k2 = 0; k2 < 16; ++k2) {
+            for (j = 0; j < 16; ++j) {
+                abyte1[j << 4 | k2] = (byte) (worldchunkmanager.getBiome(oldchunk.k << 4 | k2, oldchunk.l << 4 | j).id & 255);
+            }
+        }
+
+        nbttagcompound.setByteArray("Biomes", abyte1);
+        nbttagcompound.set("Entities", oldchunk.h);
+        nbttagcompound.set("TileEntities", oldchunk.i);
+        if (oldchunk.j != null) {
+            nbttagcompound.set("TileTicks", oldchunk.j);
+        }
+    }
+}
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
new file mode 100644
index 0000000..c7b799a
--- /dev/null
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -0,0 +1,190 @@
+package net.minecraft.server;
+
+import java.io.IOException;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+public class PacketPlayOutMapChunk extends Packet {
+
+    private int a;
+    private int b;
+    private int c;
+    private int d;
+    private byte[] e;
+    private byte[] buffer;
+    private boolean inflatedBuffer;
+    private int size;
+    private static byte[] buildBuffer = new byte[196864];
+
+    public PacketPlayOutMapChunk() {}
+
+    public PacketPlayOutMapChunk(Chunk chunk, boolean flag, int i) {
+        this.a = chunk.locX;
+        this.b = chunk.locZ;
+        this.inflatedBuffer = flag;
+        ChunkMap chunkmap = a(chunk, flag, i);
+        Deflater deflater = new Deflater(-1);
+
+        this.d = chunkmap.c;
+        this.c = chunkmap.b;
+
+        try {
+            this.buffer = chunkmap.a;
+            deflater.setInput(chunkmap.a, 0, chunkmap.a.length);
+            deflater.finish();
+            this.e = new byte[chunkmap.a.length];
+            this.size = deflater.deflate(this.e);
+        } finally {
+            deflater.end();
+        }
+    }
+
+    public static int c() {
+        return 196864;
+    }
+
+    public void a(PacketDataSerializer packetdataserializer) throws IOException {
+        this.a = packetdataserializer.readInt();
+        this.b = packetdataserializer.readInt();
+        this.inflatedBuffer = packetdataserializer.readBoolean();
+        this.c = packetdataserializer.readShort();
+        this.d = packetdataserializer.readShort();
+        this.size = packetdataserializer.readInt();
+        if (buildBuffer.length < this.size) {
+            buildBuffer = new byte[this.size];
+        }
+
+        packetdataserializer.readBytes(buildBuffer, 0, this.size);
+        int i = 0;
+
+        int j;
+
+        for (j = 0; j < 16; ++j) {
+            i += this.c >> j & 1;
+        }
+
+        j = 12288 * i;
+        if (this.inflatedBuffer) {
+            j += 256;
+        }
+
+        this.buffer = new byte[j];
+        Inflater inflater = new Inflater();
+
+        inflater.setInput(buildBuffer, 0, this.size);
+
+        try {
+            inflater.inflate(this.buffer);
+        } catch (DataFormatException dataformatexception) {
+            throw new IOException("Bad compressed data format");
+        } finally {
+            inflater.end();
+        }
+    }
+
+    public void b(PacketDataSerializer packetdataserializer) {
+        packetdataserializer.writeInt(this.a);
+        packetdataserializer.writeInt(this.b);
+        packetdataserializer.writeBoolean(this.inflatedBuffer);
+        packetdataserializer.writeShort((short) (this.c & '\uffff'));
+        packetdataserializer.writeShort((short) (this.d & '\uffff'));
+        packetdataserializer.writeInt(this.size);
+        packetdataserializer.writeBytes(this.e, 0, this.size);
+    }
+
+    public void a(PacketPlayOutListener packetplayoutlistener) {
+        packetplayoutlistener.a(this);
+    }
+
+    public String b() {
+        return String.format("x=%d, z=%d, full=%b, sects=%d, add=%d, size=%d", new Object[] { Integer.valueOf(this.a), Integer.valueOf(this.b), Boolean.valueOf(this.inflatedBuffer), Integer.valueOf(this.c), Integer.valueOf(this.d), Integer.valueOf(this.size)});
+    }
+
+    public static ChunkMap a(Chunk chunk, boolean flag, int i) {
+        int j = 0;
+        ChunkSection[] achunksection = chunk.i();
+        int k = 0;
+        ChunkMap chunkmap = new ChunkMap();
+        byte[] abyte = buildBuffer;
+
+        if (flag) {
+            chunk.q = true;
+        }
+
+        int l;
+
+        for (l = 0; l < achunksection.length; ++l) {
+            if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
+                chunkmap.b |= 1 << l;
+                if (achunksection[l].getExtendedIdArray() != null) {
+                    chunkmap.c |= 1 << l;
+                    ++k;
+                }
+            }
+        }
+
+        for (l = 0; l < achunksection.length; ++l) {
+            if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
+                byte[] abyte1 = achunksection[l].getIdArray();
+
+                System.arraycopy(abyte1, 0, abyte, j, abyte1.length);
+                j += abyte1.length;
+            }
+        }
+
+        NibbleArray nibblearray;
+
+        for (l = 0; l < achunksection.length; ++l) {
+            if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
+                nibblearray = achunksection[l].getDataArray();
+                System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
+                j += nibblearray.a.length;
+            }
+        }
+
+        for (l = 0; l < achunksection.length; ++l) {
+            if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
+                nibblearray = achunksection[l].getEmittedLightArray();
+                System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
+                j += nibblearray.a.length;
+            }
+        }
+
+        if (!chunk.world.worldProvider.g) {
+            for (l = 0; l < achunksection.length; ++l) {
+                if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
+                    nibblearray = achunksection[l].getSkyLightArray();
+                    System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
+                    j += nibblearray.a.length;
+                }
+            }
+        }
+
+        if (k > 0) {
+            for (l = 0; l < achunksection.length; ++l) {
+                if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && achunksection[l].getExtendedIdArray() != null && (i & 1 << l) != 0) {
+                    nibblearray = achunksection[l].getExtendedIdArray();
+                    System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
+                    j += nibblearray.a.length;
+                }
+            }
+        }
+
+        if (flag) {
+            byte[] abyte2 = chunk.m();
+
+            System.arraycopy(abyte2, 0, abyte, j, abyte2.length);
+            j += abyte2.length;
+        }
+
+        chunkmap.a = new byte[j];
+        System.arraycopy(abyte, 0, chunkmap.a, 0, j);
+        return chunkmap;
+    }
+
+    @Override
+    public void handle(PacketListener packetlistener) {
+        this.a((PacketPlayOutListener) packetlistener);
+    }
+}
diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
new file mode 100644
index 0000000..900ed68
--- /dev/null
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
@@ -0,0 +1,67 @@
+package net.minecraft.server;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class RegionFileCache {
+
+    private static final Map a = new HashMap();
+
+    public static synchronized RegionFile a(File file1, int i, int j) {
+        File file2 = new File(file1, "region");
+        File file3 = new File(file2, "r." + (i >> 5) + "." + (j >> 5) + ".mca");
+        RegionFile regionfile = (RegionFile) a.get(file3);
+
+        if (regionfile != null) {
+            return regionfile;
+        } else {
+            if (!file2.exists()) {
+                file2.mkdirs();
+            }
+
+            if (a.size() >= 256) {
+                a();
+            }
+
+            RegionFile regionfile1 = new RegionFile(file3);
+
+            a.put(file3, regionfile1);
+            return regionfile1;
+        }
+    }
+
+    public static synchronized void a() {
+        Iterator iterator = a.values().iterator();
+
+        while (iterator.hasNext()) {
+            RegionFile regionfile = (RegionFile) iterator.next();
+
+            try {
+                if (regionfile != null) {
+                    regionfile.c();
+                }
+            } catch (IOException ioexception) {
+                ioexception.printStackTrace();
+            }
+        }
+
+        a.clear();
+    }
+
+    public static DataInputStream c(File file1, int i, int j) {
+        RegionFile regionfile = a(file1, i, j);
+
+        return regionfile.a(i & 31, j & 31);
+    }
+
+    public static DataOutputStream d(File file1, int i, int j) {
+        RegionFile regionfile = a(file1, i, j);
+
+        return regionfile.b(i & 31, j & 31);
+    }
+}
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
new file mode 100644
index 0000000..1eb87ae
--- /dev/null
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
@@ -0,0 +1,217 @@
+package net.minecraft.server;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.Callable;
+
+public abstract class StructureGenerator extends WorldGenBase {
+
+    private PersistentStructure e;
+    protected Map d = new HashMap();
+
+    public StructureGenerator() {}
+
+    public abstract String a();
+
+    protected final void a(World world, int i, int j, int k, int l, Block[] ablock) {
+        this.a(world);
+        if (!this.d.containsKey(Long.valueOf(ChunkCoordIntPair.a(i, j)))) {
+            this.b.nextInt();
+
+            try {
+                if (this.a(i, j)) {
+                    StructureStart structurestart = this.b(i, j);
+
+                    this.d.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart);
+                    this.a(i, j, structurestart);
+                }
+            } catch (Throwable throwable) {
+                CrashReport crashreport = CrashReport.a(throwable, "Exception preparing structure feature");
+                CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Feature being prepared");
+
+                crashreportsystemdetails.a("Is feature chunk", (Callable) (new CrashReportIsFeatureChunk(this, i, j)));
+                crashreportsystemdetails.a("Chunk location", String.format("%d,%d", new Object[] { Integer.valueOf(i), Integer.valueOf(j)}));
+                crashreportsystemdetails.a("Chunk pos hash", (Callable) (new CrashReportChunkPosHash(this, i, j)));
+                crashreportsystemdetails.a("Structure type", (Callable) (new CrashReportStructureType(this)));
+                throw new ReportedException(crashreport);
+            }
+        }
+    }
+
+    public boolean a(World world, Random random, int i, int j) {
+        this.a(world);
+        int k = (i << 4) + 8;
+        int l = (j << 4) + 8;
+        boolean flag = false;
+        Iterator iterator = this.d.values().iterator();
+
+        while (iterator.hasNext()) {
+            StructureStart structurestart = (StructureStart) iterator.next();
+
+            if (structurestart.d() && structurestart.a().a(k, l, k + 15, l + 15)) {
+                structurestart.a(world, random, new StructureBoundingBox(k, l, k + 15, l + 15));
+                flag = true;
+                this.a(structurestart.e(), structurestart.f(), structurestart);
+            }
+        }
+
+        return flag;
+    }
+
+    public boolean b(int i, int j, int k) {
+        this.a(this.c);
+        return this.c(i, j, k) != null;
+    }
+
+    protected StructureStart c(int i, int j, int k) {
+        Iterator iterator = this.d.values().iterator();
+
+        while (iterator.hasNext()) {
+            StructureStart structurestart = (StructureStart) iterator.next();
+
+            if (structurestart.d() && structurestart.a().a(i, k, i, k)) {
+                Iterator iterator1 = structurestart.b().iterator();
+
+                while (iterator1.hasNext()) {
+                    StructurePiece structurepiece = (StructurePiece) iterator1.next();
+
+                    if (structurepiece.c().b(i, j, k)) {
+                        return structurestart;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public boolean d(int i, int j, int k) {
+        this.a(this.c);
+        Iterator iterator = this.d.values().iterator();
+
+        StructureStart structurestart;
+
+        do {
+            if (!iterator.hasNext()) {
+                return false;
+            }
+
+            structurestart = (StructureStart) iterator.next();
+        } while (!structurestart.d());
+
+        return structurestart.a().a(i, k, i, k);
+    }
+
+    public ChunkPosition getNearestGeneratedFeature(World world, int i, int j, int k) {
+        this.c = world;
+        this.a(world);
+        this.b.setSeed(world.getSeed());
+        long l = this.b.nextLong();
+        long i1 = this.b.nextLong();
+        long j1 = (long) (i >> 4) * l;
+        long k1 = (long) (k >> 4) * i1;
+
+        this.b.setSeed(j1 ^ k1 ^ world.getSeed());
+        this.a(world, i >> 4, k >> 4, 0, 0, (Block[]) null);
+        double d0 = Double.MAX_VALUE;
+        ChunkPosition chunkposition = null;
+        Iterator iterator = this.d.values().iterator();
+
+        ChunkPosition chunkposition1;
+        int l1;
+        int i2;
+        double d1;
+        int j2;
+
+        while (iterator.hasNext()) {
+            StructureStart structurestart = (StructureStart) iterator.next();
+
+            if (structurestart.d()) {
+                StructurePiece structurepiece = (StructurePiece) structurestart.b().get(0);
+
+                chunkposition1 = structurepiece.a();
+                i2 = chunkposition1.x - i;
+                l1 = chunkposition1.y - j;
+                j2 = chunkposition1.z - k;
+                d1 = (double) (i2 * i2 + l1 * l1 + j2 * j2);
+                if (d1 < d0) {
+                    d0 = d1;
+                    chunkposition = chunkposition1;
+                }
+            }
+        }
+
+        if (chunkposition != null) {
+            return chunkposition;
+        } else {
+            List list = this.o_();
+
+            if (list != null) {
+                ChunkPosition chunkposition2 = null;
+                Iterator iterator1 = list.iterator();
+
+                while (iterator1.hasNext()) {
+                    chunkposition1 = (ChunkPosition) iterator1.next();
+                    i2 = chunkposition1.x - i;
+                    l1 = chunkposition1.y - j;
+                    j2 = chunkposition1.z - k;
+                    d1 = (double) (i2 * i2 + l1 * l1 + j2 * j2);
+                    if (d1 < d0) {
+                        d0 = d1;
+                        chunkposition2 = chunkposition1;
+                    }
+                }
+
+                return chunkposition2;
+            } else {
+                return null;
+            }
+        }
+    }
+
+    protected List o_() {
+        return null;
+    }
+
+    private void a(World world) {
+        if (this.e == null) {
+            this.e = (PersistentStructure) world.a(PersistentStructure.class, this.a());
+            if (this.e == null) {
+                this.e = new PersistentStructure(this.a());
+                world.a(this.a(), (PersistentBase) this.e);
+            } else {
+                NBTTagCompound nbttagcompound = this.e.a();
+                Iterator iterator = nbttagcompound.c().iterator();
+
+                while (iterator.hasNext()) {
+                    String s = (String) iterator.next();
+                    NBTBase nbtbase = nbttagcompound.get(s);
+
+                    if (nbtbase.getTypeId() == 10) {
+                        NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbtbase;
+
+                        if (nbttagcompound1.hasKey("ChunkX") && nbttagcompound1.hasKey("ChunkZ")) {
+                            int i = nbttagcompound1.getInt("ChunkX");
+                            int j = nbttagcompound1.getInt("ChunkZ");
+                            StructureStart structurestart = WorldGenFactory.a(nbttagcompound1, world);
+
+                            this.d.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void a(int i, int j, StructureStart structurestart) {
+        this.e.a(structurestart.a(i, j), i, j);
+        this.e.c();
+    }
+
+    protected abstract boolean a(int i, int j);
+
+    protected abstract StructureStart b(int i, int j);
+}
diff --git a/src/main/java/net/minecraft/server/WorldGenPackedIce2.java b/src/main/java/net/minecraft/server/WorldGenPackedIce2.java
new file mode 100644
index 0000000..c0db754
--- /dev/null
+++ b/src/main/java/net/minecraft/server/WorldGenPackedIce2.java
@@ -0,0 +1,101 @@
+package net.minecraft.server;
+
+import java.util.Random;
+
+public class WorldGenPackedIce2 extends WorldGenerator {
+
+    public WorldGenPackedIce2() {}
+
+    public boolean a(World world, Random random, int i, int j, int k) {
+        while (world.isEmpty(i, j, k) && j > 2) {
+            --j;
+        }
+
+        if (world.getType(i, j, k) != Blocks.SNOW_BLOCK) {
+            return false;
+        } else {
+            j += random.nextInt(4);
+            int l = random.nextInt(4) + 7;
+            int i1 = l / 4 + random.nextInt(2);
+
+            if (i1 > 1 && random.nextInt(60) == 0) {
+                j += 10 + random.nextInt(30);
+            }
+
+            int j1;
+            int k1;
+            int l1;
+
+            for (j1 = 0; j1 < l; ++j1) {
+                float f = (1.0F - (float) j1 / (float) l) * (float) i1;
+
+                k1 = MathHelper.f(f);
+
+                for (l1 = -k1; l1 <= k1; ++l1) {
+                    float f1 = (float) MathHelper.a(l1) - 0.25F;
+
+                    for (int i2 = -k1; i2 <= k1; ++i2) {
+                        float f2 = (float) MathHelper.a(i2) - 0.25F;
+
+                        if ((l1 == 0 && i2 == 0 || f1 * f1 + f2 * f2 <= f * f) && (l1 != -k1 && l1 != k1 && i2 != -k1 && i2 != k1 || random.nextFloat() <= 0.75F)) {
+                            Block block = world.getType(i + l1, j + j1, k + i2);
+
+                            if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW_BLOCK || block == Blocks.ICE) {
+                                this.setType(world, i + l1, j + j1, k + i2, Blocks.PACKED_ICE);
+                            }
+
+                            if (j1 != 0 && k1 > 1) {
+                                block = world.getType(i + l1, j - j1, k + i2);
+                                if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW_BLOCK || block == Blocks.ICE) {
+                                    this.setType(world, i + l1, j - j1, k + i2, Blocks.PACKED_ICE);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            j1 = i1 - 1;
+            if (j1 < 0) {
+                j1 = 0;
+            } else if (j1 > 1) {
+                j1 = 1;
+            }
+
+            for (int j2 = -j1; j2 <= j1; ++j2) {
+                k1 = -j1;
+
+                while (k1 <= j1) {
+                    l1 = j - 1;
+                    int k2 = 50;
+
+                    if (Math.abs(j2) == 1 && Math.abs(k1) == 1) {
+                        k2 = random.nextInt(5);
+                    }
+
+                    while (true) {
+                        if (l1 > 50) {
+                            Block block1 = world.getType(i + j2, l1, k + k1);
+
+                            if (block1.getMaterial() == Material.AIR || block1 == Blocks.DIRT || block1 == Blocks.SNOW_BLOCK || block1 == Blocks.ICE || block1 == Blocks.PACKED_ICE) {
+                                this.setType(world, i + j2, l1, k + k1, Blocks.PACKED_ICE);
+                                --l1;
+                                --k2;
+                                if (k2 <= 0) {
+                                    l1 -= random.nextInt(5) + 1;
+                                    k2 = random.nextInt(5);
+                                }
+                                continue;
+                            }
+                        }
+
+                        ++k1;
+                        break;
+                    }
+                }
+            }
+
+            return true;
+        }
+    }
+}
-- 
1.8.3.2