--- net/minecraft/src/ItemBlock.java
+++ net/minecraft/src/ItemBlock.java
@@ -43,14 +43,47 @@
 		} else {
 			if(var3.canBlockBePlacedAt(this.blockID, var4, var5, var6, false)) {
 				Block var8 = Block.blocksList[this.blockID];
-				if(var3.setBlockWithNotify(var4, var5, var6, this.blockID)) {
+				if(var3.setBlockAndMetadataWithNotify(var4, var5, var6, this.blockID, var1.getItemDamageForDisplay())) {
 					Block.blocksList[this.blockID].onBlockPlaced(var3, var4, var5, var6, var7);
 					var3.playSoundEffect((double)((float)var4 + 0.5F), (double)((float)var5 + 0.5F), (double)((float)var6 + 0.5F), var8.stepSound.getStepSound(), (var8.stepSound.getVolume() + 1.0F) / 2.0F, var8.stepSound.getPitch() * 0.8F);
+					
 					--var1.stackSize;
 				}
 			}
 
 			return true;
 		}
+	}
+	
+	public boolean onPlace(ItemStack var1, EntityPlayer var2, World var3, int var4, int var5, int var6, int var7) {
+		if(var3.getBlockId(var4, var5, var6) == Block.snow.blockID) {
+			var7 = 0;
+		} else {
+			if(var7 == 0) {
+				--var5;
+			}
+
+			if(var7 == 1) {
+				++var5;
+			}
+
+			if(var7 == 2) {
+				--var6;
+			}
+
+			if(var7 == 3) {
+				++var6;
+			}
+
+			if(var7 == 4) {
+				--var4;
+			}
+
+			if(var7 == 5) {
+				++var4;
+			}
+		}
+
+		return var3.canBlockBePlacedAt(this.blockID, var4, var5, var6, false);
 	}
 }
--- net/minecraft/src/Packet31RelEntityMove.java
+++ net/minecraft/src/Packet31RelEntityMove.java
@@ -12,8 +12,8 @@
 		this.zPosition = var1.readByte();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		super.writePacket(var1);
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		super.writePacketData(var1);
 		var1.writeByte(this.xPosition);
 		var1.writeByte(this.yPosition);
 		var1.writeByte(this.zPosition);
--- net/minecraft/src/EntityItem.java
+++ net/minecraft/src/EntityItem.java
@@ -27,6 +27,9 @@
 		this.yOffset = this.height / 2.0F;
 	}
 
+	protected void entityInit() {
+	}
+
 	public void onUpdate() {
 		super.onUpdate();
 		if(this.delayBeforeCanPickup > 0) {
--- net/minecraft/src/SlotInventory.java
+++ /dev/null
@@ -1,22 +1,0 @@
-package net.minecraft.src;
-
-public class SlotInventory extends Slot {
-	private final GuiContainer guiContainer;
-	public final int xDisplayPosition;
-	public final int yDisplayPosition;
-
-	public SlotInventory(GuiContainer var1, IInventory var2, int var3, int var4, int var5) {
-		super(var2, var3);
-		this.guiContainer = var1;
-		this.xDisplayPosition = var4;
-		this.yDisplayPosition = var5;
-	}
-
-	public boolean getIsMouseOverSlot(int var1, int var2) {
-		int var3 = (this.guiContainer.width - this.guiContainer.xSize) / 2;
-		int var4 = (this.guiContainer.height - this.guiContainer.ySize) / 2;
-		var1 -= var3;
-		var2 -= var4;
-		return var1 >= this.xDisplayPosition - 1 && var1 < this.xDisplayPosition + 16 + 1 && var2 >= this.yDisplayPosition - 1 && var2 < this.yDisplayPosition + 16 + 1;
-	}
-}
--- net/minecraft/src/Packet13PlayerLookMove.java
+++ net/minecraft/src/Packet13PlayerLookMove.java
@@ -32,14 +32,14 @@
 		super.readPacketData(var1);
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeDouble(this.xPosition);
 		var1.writeDouble(this.yPosition);
 		var1.writeDouble(this.stance);
 		var1.writeDouble(this.zPosition);
 		var1.writeFloat(this.yaw);
 		var1.writeFloat(this.pitch);
-		super.writePacket(var1);
+		super.writePacketData(var1);
 	}
 
 	public int getPacketSize() {
--- /dev/null
+++ net/minecraft/src/ICrafting.java
@@ -1,0 +1,7 @@
+package net.minecraft.src;
+
+public interface ICrafting {
+	void func_20159_a(Container var1, int var2, ItemStack var3);
+
+	void func_20158_a(Container var1, int var2, int var3);
+}
--- net/minecraft/src/RenderBlocks.java
+++ net/minecraft/src/RenderBlocks.java
@@ -1322,7 +1322,7 @@
 		}
 
 		var1.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
-		return var5;
+		return true;
 	}
 
 	public boolean renderBlockStairs(Block var1, int var2, int var3, int var4) {
@@ -1719,7 +1719,7 @@
 
 	}
 
-	public void renderBlockOnInventory(Block var1) {
+	public void renderBlockOnInventory(Block var1, int metadata) {
 		byte var2 = -1;
 		Tessellator var3 = Tessellator.instance;
 		int var4 = var1.getRenderType();
@@ -1728,27 +1728,27 @@
 			GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
 			var3.startDrawingQuads();
 			var3.setNormal(0.0F, -1.0F, 0.0F);
-			this.renderBottomFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSide(0));
+			this.renderBottomFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSideAndMetadata(0, metadata));
 			var3.draw();
 			var3.startDrawingQuads();
 			var3.setNormal(0.0F, 1.0F, 0.0F);
-			this.renderTopFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSide(1));
+			this.renderTopFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSideAndMetadata(1, metadata));
 			var3.draw();
 			var3.startDrawingQuads();
 			var3.setNormal(0.0F, 0.0F, -1.0F);
-			this.renderEastFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSide(2));
+			this.renderEastFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSideAndMetadata(2, metadata));
 			var3.draw();
 			var3.startDrawingQuads();
 			var3.setNormal(0.0F, 0.0F, 1.0F);
-			this.renderWestFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSide(3));
+			this.renderWestFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSideAndMetadata(3, metadata));
 			var3.draw();
 			var3.startDrawingQuads();
 			var3.setNormal(-1.0F, 0.0F, 0.0F);
-			this.renderNorthFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSide(4));
+			this.renderNorthFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSideAndMetadata(4, metadata));
 			var3.draw();
 			var3.startDrawingQuads();
 			var3.setNormal(1.0F, 0.0F, 0.0F);
-			this.renderSouthFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSide(5));
+			this.renderSouthFace(var1, 0.0D, 0.0D, 0.0D, var1.getBlockTextureFromSideAndMetadata(5, metadata));
 			var3.draw();
 			GL11.glTranslatef(0.5F, 0.5F, 0.5F);
 		} else if(var4 == 1) {
--- net/minecraft/src/World.java
+++ net/minecraft/src/World.java
@@ -890,12 +890,29 @@
 	}
 
 	public void setEntityDead(Entity var1) {
+		if (var1.riddenByEntity != null) {
+			var1.riddenByEntity.mountEntity(null);
+		}
+
+		if (var1.ridingEntity != null) {
+			var1.mountEntity(null);
+		}
+		
 		var1.setEntityDead();
 		if(var1 instanceof EntityPlayer) {
 			this.playerEntities.remove((EntityPlayer)var1);
 			System.out.println("Player count: " + this.playerEntities.size());
 		}
 
+//		int i = var1.chunkCoordX;
+//		int j = var1.chunkCoordZ;
+//		if (var1.addedToChunk && this.chunkExists(i, j)) {
+//			this.getChunkFromChunkCoords(i, j).removeEntity(var1);
+//		}
+//
+//		this.loadedEntityList.remove(var1);
+//		this.releaseEntitySkin(var1);
+
 	}
 
 	public void addWorldAccess(IWorldAccess var1) {
@@ -1363,8 +1380,16 @@
 		return false;
 	}
 
-	public void createExplosion(Entity var1, double var2, double var4, double var6, float var8) {
-		(new Explosion()).doExplosion(this, var1, var2, var4, var6, var8);
+	public Explosion createExplosion(Entity var1, double var2, double var4, double var6, float var8) {
+		return this.newExplosion(var1, var2, var4, var6, var8, false);
+	}
+
+	public Explosion newExplosion(Entity var1, double var2, double var4, double var6, float var8, boolean var9) {
+		Explosion var10 = new Explosion(this, var1, var2, var4, var6, var8);
+		var10.isFlaming = var9;
+		var10.doExplosionA();
+		var10.doExplosionB(true);
+		return var10;
 	}
 
 	public float getBlockDensity(Vec3D var1, AxisAlignedBB var2) {
@@ -1392,7 +1417,7 @@
 		return (float)var9 / (float)var10;
 	}
 
-	public void extinguishFire(int var1, int var2, int var3, int var4) {
+	public boolean extinguishFire(EntityPlayer player, int var1, int var2, int var3, int var4) {
 		if(var4 == 0) {
 			--var2;
 		}
@@ -1418,9 +1443,13 @@
 		}
 
 		if(this.getBlockId(var1, var2, var3) == Block.fire.blockID) {
-			this.playSoundEffect((double)((float)var1 + 0.5F), (double)((float)var2 + 0.5F), (double)((float)var3 + 0.5F), "random.fizz", 0.5F, 2.6F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.8F);
+			if (!this.multiplayerWorld)
+				this.func_28107_a(player, 1004, var2, var3, var4, 0);
+			
 			this.setBlockWithNotify(var1, var2, var3, 0);
+	         return true;
 		}
+        return false;
 
 	}
 
@@ -1920,6 +1949,17 @@
 		if(!this.loadedEntityList.contains(var1)) {
 			System.out.println("REINSERTING PLAYER!");
 			this.loadedEntityList.add(var1);
+		}
+
+	}
+	
+	public void func_28106_e(int var1, int var2, int var3, int var4, int var5) {
+		this.func_28107_a((EntityPlayer)null, var1, var2, var3, var4, var5);
+	}
+
+	public void func_28107_a(EntityPlayer var1, int var2, int var3, int var4, int var5, int var6) {
+		for(int var7 = 0; var7 < this.worldAccesses.size(); ++var7) {
+			((IWorldAccess)this.worldAccesses.get(var7)).func_28136_a(var1, var2, var3, var4, var5, var6);
 		}
 
 	}
--- net/minecraft/src/TextureCompassFX.java
+++ net/minecraft/src/TextureCompassFX.java
@@ -14,7 +14,7 @@
 	private double angleDelta;
 
 	public TextureCompassFX(Minecraft var1) {
-		super(Item.compass.getIconIndex((ItemStack)null));
+		super(Item.compass.getSprite(0));
 		this.mc = var1;
 		this.tileImage = 1;
 
--- net/minecraft/src/ItemSign.java
+++ net/minecraft/src/ItemSign.java
@@ -43,7 +43,10 @@
 				}
 
 				--var1.stackSize;
-				var2.displayGUIEditSign((TileEntitySign)var3.getBlockTileEntity(var4, var5, var6));
+				TileEntitySign var8 = (TileEntitySign)var3.getBlockTileEntity(var4, var5, var6);
+				if(var8 != null) {
+					var2.displayGUIEditSign(var8);
+				}
 				return true;
 			}
 		}
--- /dev/null
+++ net/minecraft/src/Packet200Statistic.java
@@ -1,0 +1,28 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet200Statistic extends Packet {
+	public int field_27052_a;
+	public int field_27051_b;
+
+	public void processPacket(NetHandler var1) {
+		var1.func_27245_a(this);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.field_27052_a = var1.readInt();
+		this.field_27051_b = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.field_27052_a);
+		var1.writeByte(this.field_27051_b);
+	}
+
+	public int getPacketSize() {
+		return 6;
+	}
+}
--- net/minecraft/src/EntityPig.java
+++ net/minecraft/src/EntityPig.java
@@ -1,23 +1,25 @@
 package net.minecraft.src;
 
 public class EntityPig extends EntityAnimal {
-	public boolean saddled = false;
 
 	public EntityPig(World var1) {
 		super(var1);
 		this.texture = "/mob/pig.png";
 		this.setSize(0.9F, 0.9F);
-		this.saddled = false;
+	}
+
+	protected void entityInit() {
+		this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
 	}
 
 	public void writeEntityToNBT(NBTTagCompound var1) {
 		super.writeEntityToNBT(var1);
-		var1.setBoolean("Saddle", this.saddled);
+		var1.setBoolean("Saddle", this.getSaddled());
 	}
 
 	public void readEntityFromNBT(NBTTagCompound var1) {
 		super.readEntityFromNBT(var1);
-		this.saddled = var1.getBoolean("Saddle");
+		this.setSaddled(var1.getBoolean("Saddle"));
 	}
 
 	protected String getLivingSound() {
@@ -33,15 +35,28 @@
 	}
 
 	public boolean interact(EntityPlayer var1) {
-		if(this.saddled) {
+		if(!this.getSaddled() || this.worldObj.multiplayerWorld || this.riddenByEntity != null && this.riddenByEntity != var1) {
+			return false;
+		} else {
 			var1.mountEntity(this);
 			return true;
-		} else {
-			return false;
 		}
 	}
 
 	protected int getDropItemId() {
 		return Item.porkRaw.shiftedIndex;
+	}
+	
+	public boolean getSaddled() {
+		return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
+	}
+
+	public void setSaddled(boolean var1) {
+		if(var1) {
+			this.dataWatcher.updateObject(16, Byte.valueOf((byte)1));
+		} else {
+			this.dataWatcher.updateObject(16, Byte.valueOf((byte)0));
+		}
+
 	}
 }
--- net/minecraft/src/RenderSnowball.java
+++ net/minecraft/src/RenderSnowball.java
@@ -9,7 +9,7 @@
 		GL11.glTranslatef((float)var2, (float)var4, (float)var6);
 		GL11.glEnable(GL12.GL_RESCALE_NORMAL);
 		GL11.glScalef(0.5F, 0.5F, 0.5F);
-		int var10 = Item.snowball.getIconIndex((ItemStack)null);
+		int var10 = Item.snowball.getSprite(0);
 		this.loadTexture("/gui/items.png");
 		Tessellator var11 = Tessellator.instance;
 		float var12 = (float)(var10 % 16 * 16 + 0) / 256.0F;
--- net/minecraft/src/BlockSnow.java
+++ net/minecraft/src/BlockSnow.java
@@ -46,7 +46,7 @@
 		double var8 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.5D;
 		double var10 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.5D;
 		double var12 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.5D;
-		EntityItem var14 = new EntityItem(var1, (double)var2 + var8, (double)var3 + var10, (double)var4 + var12, new ItemStack(var6));
+		EntityItem var14 = new EntityItem(var1, (double)var2 + var8, (double)var3 + var10, (double)var4 + var12, new ItemStack(var6, 1, 0));
 		var14.delayBeforeCanPickup = 10;
 		var1.spawnEntityInWorld(var14);
 		var1.setBlockWithNotify(var2, var3, var4, 0);
--- net/minecraft/src/EntityRenderer.java
+++ net/minecraft/src/EntityRenderer.java
@@ -1,9 +1,11 @@
 package net.minecraft.src;
 
 import java.nio.FloatBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Random;
-import net.minecraft.client.Minecraft;
+
 import org.lwjgl.input.Mouse;
 import org.lwjgl.opengl.Display;
 import org.lwjgl.opengl.GL11;
@@ -11,6 +13,8 @@
 import org.lwjgl.opengl.NVFogDistance;
 import org.lwjgl.util.glu.GLU;
 
+import net.minecraft.client.Minecraft;
+
 public class EntityRenderer {
 	private Minecraft mc;
 	private float farPlaneDistance = 0.0F;
@@ -376,6 +380,13 @@
 				GL11.glEnable(GL11.GL_ALPHA_TEST);
 			}
 
+			// uberbukkit start
+			GL11.glEnable(GL11.GL_BLEND);
+			GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
+			var3.drawBlockBreaking(var2, var1);
+			GL11.glDisable(GL11.GL_BLEND);
+			// uberbukkit end
+			
 			GL11.glDisable(GL11.GL_FOG);
 			if(this.mc.theWorld.snowCovered) {
 				this.renderSnow(var1);
--- net/minecraft/src/Packet32EntityLook.java
+++ net/minecraft/src/Packet32EntityLook.java
@@ -15,8 +15,8 @@
 		this.pitch = var1.readByte();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		super.writePacket(var1);
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		super.writePacketData(var1);
 		var1.writeByte(this.yaw);
 		var1.writeByte(this.pitch);
 	}
--- net/minecraft/src/PlayerControllerCreative.java
+++ net/minecraft/src/PlayerControllerCreative.java
@@ -11,7 +11,7 @@
 	public void onRespawn(EntityPlayer var1) {
 		for(int var2 = 0; var2 < 9; ++var2) {
 			if(var1.inventory.mainInventory[var2] == null) {
-				this.mc.thePlayer.inventory.mainInventory[var2] = new ItemStack(((Block)Session.registeredBlocksList.get(var2)).blockID);
+				this.mc.thePlayer.inventory.mainInventory[var2] = new ItemStack(((Block)Session.registeredBlocksList.get(var2)));
 			} else {
 				this.mc.thePlayer.inventory.mainInventory[var2].stackSize = 1;
 			}
--- net/minecraft/src/BlockLever.java
+++ net/minecraft/src/BlockLever.java
@@ -133,12 +133,16 @@
 	}
 
 	public boolean blockActivated(World var1, int var2, int var3, int var4, EntityPlayer var5) {
+		if (var1.multiplayerWorld) {
+			return true;
+		}
 		int var6 = var1.getBlockMetadata(var2, var3, var4);
 		int var7 = var6 & 7;
 		int var8 = 8 - (var6 & 8);
 		var1.setBlockMetadataWithNotify(var2, var3, var4, var7 + var8);
 		var1.markBlocksDirty(var2, var3, var4, var2, var3, var4);
 		var1.playSoundEffect((double)var2 + 0.5D, (double)var3 + 0.5D, (double)var4 + 0.5D, "random.click", 0.3F, var8 > 0 ? 0.6F : 0.5F);
+		
 		var1.notifyBlocksOfNeighborChange(var2, var3, var4, this.blockID);
 		if(var7 == 1) {
 			var1.notifyBlocksOfNeighborChange(var2 - 1, var3, var4, this.blockID);
--- net/minecraft/src/EntityArrow.java
+++ net/minecraft/src/EntityArrow.java
@@ -9,7 +9,7 @@
 	private int inTile = 0;
 	private boolean inData = false;
 	public int arrowShake = 0;
-	private EntityLiving shootingEntity;
+	public EntityLiving shootingEntity;
 	private int ticksInGround;
 	private int ticksInAir = 0;
 
@@ -17,6 +17,13 @@
 		super(var1);
 		this.setSize(0.5F, 0.5F);
 	}
+	
+	public EntityArrow(World var1, double var2, double var4, double var6) {
+		super(var1);
+		this.setSize(0.5F, 0.5F);
+		this.setPosition(var2, var4, var6);
+		this.yOffset = 0.0F;
+	}
 
 	public EntityArrow(World var1, EntityLiving var2) {
 		super(var1);
@@ -34,6 +41,9 @@
 		this.setArrowHeading(this.motionX, this.motionY, this.motionZ, 1.5F, 1.0F);
 	}
 
+	protected void entityInit() {
+	}
+
 	public void setArrowHeading(double var1, double var3, double var5, float var7, float var8) {
 		float var9 = MathHelper.sqrt_double(var1 * var1 + var3 * var3 + var5 * var5);
 		var1 /= (double)var9;
@@ -54,8 +64,39 @@
 		this.ticksInGround = 0;
 	}
 
+	@Override
+	public void setVelocity(double velocityX, double velocityY, double velocityZ) {
+		this.motionX = velocityX;
+		this.motionY = velocityY;
+		this.motionZ = velocityZ;
+		if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) {
+			float f = MathHelper.sqrt_double(velocityX * velocityX + velocityZ * velocityZ);
+			this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(velocityX, velocityZ) * 180.0 / (float) Math.PI);
+			this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(velocityY, f) * 180.0 / (float) Math.PI);
+			this.prevRotationPitch = this.rotationPitch;
+			this.prevRotationYaw = this.rotationYaw;
+			this.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch);
+			this.ticksInGround = 0;
+		}
+	}
+
 	public void onUpdate() {
 		super.onUpdate();
+		if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) {
+			float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
+			this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0 / (float) Math.PI);
+			this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(this.motionY, f) * 180.0 / (float) Math.PI);
+		}
+
+		int i = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile);
+		if (i > 0) {
+			Block.blocksList[i].setBlockBoundsBasedOnState(this.worldObj, this.xTile, this.yTile, this.zTile);
+			AxisAlignedBB box = Block.blocksList[i].getCollisionBoundingBoxFromPool(this.worldObj, this.xTile, this.yTile, this.zTile);
+			if (box != null && box.contains(Vec3D.createVector(this.posX, this.posY, this.posZ))) {
+				this.inData = true;
+			}
+		}
+
 		if(this.arrowShake > 0) {
 			--this.arrowShake;
 		}
@@ -119,7 +160,9 @@
 		if(var3 != null) {
 			if(var3.entityHit != null) {
 				if(var3.entityHit.attackEntityFrom(this.shootingEntity, 4)) {
-					this.worldObj.playSoundAtEntity(this, "random.drr", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
+					if (!this.worldObj.multiplayerWorld)
+						this.worldObj.playSoundAtEntity(this, "random.drr", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
+					
 					this.setEntityDead();
 				} else {
 					this.motionX *= (double)-0.1F;
@@ -141,7 +184,9 @@
 				this.posX -= this.motionX / (double)var16 * (double)0.05F;
 				this.posY -= this.motionY / (double)var16 * (double)0.05F;
 				this.posZ -= this.motionZ / (double)var16 * (double)0.05F;
-				this.worldObj.playSoundAtEntity(this, "random.drr", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
+				if (!this.worldObj.multiplayerWorld)
+					this.worldObj.playSoundAtEntity(this, "random.drr", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
+				
 				this.inData = true;
 				this.arrowShake = 7;
 			}
@@ -207,7 +252,10 @@
 	}
 
 	public void onCollideWithPlayer(EntityPlayer var1) {
-		if(this.inData && this.shootingEntity == var1 && this.arrowShake <= 0 && var1.inventory.addItemStackToInventory(new ItemStack(Item.arrow.shiftedIndex, 1))) {
+		if (this.worldObj.multiplayerWorld)
+			return;
+		
+		if(this.inData && this.shootingEntity == var1 && this.arrowShake <= 0 && var1.inventory.addItemStackToInventory(new ItemStack(Item.arrow.shiftedIndex, 1, 0))) {
 			this.worldObj.playSoundAtEntity(this, "random.pop", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F);
 			var1.onItemPickup(this, 1);
 			this.setEntityDead();
--- /dev/null
+++ net/minecraft/src/IRecipe.java
@@ -1,0 +1,11 @@
+package net.minecraft.src;
+
+public interface IRecipe {
+	boolean matches(InventoryCrafting var1);
+
+	ItemStack getCraftingResult(InventoryCrafting var1);
+
+	int getRecipeSize();
+
+	ItemStack getRecipeOutput();
+}
--- net/minecraft/src/GuiInventory.java
+++ net/minecraft/src/GuiInventory.java
@@ -4,37 +4,17 @@
 import org.lwjgl.opengl.GL12;
 
 public class GuiInventory extends GuiContainer {
-	private CraftingInventoryPlayerCB craftingInventory;
 	private float xSize_lo;
 	private float ySize_lo;
 
-	public GuiInventory(IInventory var1, ItemStack[] var2) {
+	public GuiInventory(EntityPlayer var1) {
+		super(var1.inventorySlots);
 		this.allowUserInput = true;
-		this.craftingInventory = new CraftingInventoryPlayerCB(var2);
-		this.inventorySlots.add(new SlotCrafting(this, this.craftingInventory.craftMatrix, this.craftingInventory.craftResult, 0, 144, 36));
-
-		int var3;
-		int var4;
-		for(var3 = 0; var3 < 2; ++var3) {
-			for(var4 = 0; var4 < 2; ++var4) {
-				this.inventorySlots.add(new SlotInventory(this, this.craftingInventory.craftMatrix, var4 + var3 * 2, 88 + var4 * 18, 26 + var3 * 18));
-			}
-		}
-
-		for(var3 = 0; var3 < 4; ++var3) {
-			this.inventorySlots.add(new SlotArmor(this, this, var1, var1.getSizeInventory() - 1 - var3, 8, 8 + var3 * 18, var3));
-		}
-
-		for(var3 = 0; var3 < 3; ++var3) {
-			for(var4 = 0; var4 < 9; ++var4) {
-				this.inventorySlots.add(new SlotInventory(this, var1, var4 + (var3 + 1) * 9, 8 + var4 * 18, 84 + var3 * 18));
-			}
-		}
-
-		for(var3 = 0; var3 < 9; ++var3) {
-			this.inventorySlots.add(new SlotInventory(this, var1, var3, 8 + var3 * 18, 142));
-		}
-
+
+	}
+	
+	public void initGui() {
+		this.controlList.clear();
 	}
 
 	protected void drawGuiContainerForegroundLayer() {
--- net/minecraft/src/Packet3Chat.java
+++ net/minecraft/src/Packet3Chat.java
@@ -11,15 +11,19 @@
 	}
 
 	public Packet3Chat(String var1) {
+		if(var1.length() > 119) {
+			var1 = var1.substring(0, 119);
+		}
+
 		this.message = var1;
 	}
 
 	public void readPacketData(DataInputStream var1) throws IOException {
-		this.message = var1.readUTF();
+		this.message = readString(var1, 119);
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeUTF(this.message);
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		writeString(this.message, var1);
 	}
 
 	public void processPacket(NetHandler var1) {
--- /dev/null
+++ net/minecraft/src/WatchableObject.java
@@ -1,0 +1,35 @@
+package net.minecraft.src;
+
+public class WatchableObject {
+	private final int objectType;
+	private final int dataValueId;
+	private Object watchedObject;
+	private boolean isWatching;
+
+	public WatchableObject(int var1, int var2, Object var3) {
+		this.dataValueId = var2;
+		this.watchedObject = var3;
+		this.objectType = var1;
+		this.isWatching = true;
+	}
+
+	public int getDataValueId() {
+		return this.dataValueId;
+	}
+
+	public void setObject(Object var1) {
+		this.watchedObject = var1;
+	}
+
+	public Object getObject() {
+		return this.watchedObject;
+	}
+
+	public int getObjectType() {
+		return this.objectType;
+	}
+
+	public void setWatching(boolean var1) {
+		this.isWatching = var1;
+	}
+}
--- net/minecraft/src/Packet255KickDisconnect.java
+++ net/minecraft/src/Packet255KickDisconnect.java
@@ -15,11 +15,11 @@
 	}
 
 	public void readPacketData(DataInputStream var1) throws IOException {
-		this.reason = var1.readUTF();
+		this.reason = readString(var1, 100);
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeUTF(this.reason);
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		writeString(this.reason, var1);
 	}
 
 	public void processPacket(NetHandler var1) {
--- net/minecraft/src/Packet1Login.java
+++ net/minecraft/src/Packet1Login.java
@@ -7,27 +7,29 @@
 public class Packet1Login extends Packet {
 	public int protocolVersion;
 	public String username;
-	public String password;
+	public long mapSeed;
+	public byte dimension;
 
 	public Packet1Login() {
 	}
 
-	public Packet1Login(String var1, String var2, int var3) {
+	public Packet1Login(String var1, int var2) {
 		this.username = var1;
-		this.password = var2;
-		this.protocolVersion = var3;
+		this.protocolVersion = var2;
 	}
 
 	public void readPacketData(DataInputStream var1) throws IOException {
 		this.protocolVersion = var1.readInt();
-		this.username = var1.readUTF();
-		this.password = var1.readUTF();
+		this.username = readString(var1, 16);
+		this.mapSeed = var1.readLong();
+		this.dimension = var1.readByte();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.protocolVersion);
-		var1.writeUTF(this.username);
-		var1.writeUTF(this.password);
+		writeString(this.username, var1);
+		var1.writeLong(this.mapSeed);
+		var1.writeByte(this.dimension);
 	}
 
 	public void processPacket(NetHandler var1) {
@@ -35,6 +37,6 @@
 	}
 
 	public int getPacketSize() {
-		return 4 + this.username.length() + this.password.length() + 4;
+		return 4 + this.username.length() + 4 + 5;
 	}
 }
--- net/minecraft/src/IWorldAccess.java
+++ net/minecraft/src/IWorldAccess.java
@@ -18,4 +18,8 @@
 	void playRecord(String var1, int var2, int var3, int var4);
 
 	void doNothingWithTileEntity(int var1, int var2, int var3, TileEntity var4);
+
+	void func_28136_a(EntityPlayer var1, int var2, int var3, int var4, int var5, int var6);
+
+	void updateBlockMiningProgress(int id, int x, int y, int z, int progress);
 }
--- net/minecraft/src/RenderSlime.java
+++ net/minecraft/src/RenderSlime.java
@@ -28,9 +28,9 @@
 	}
 
 	protected void squishSlime(EntitySlime var1, float var2) {
-		float var3 = (var1.prevSquishFactor + (var1.squishFactor - var1.prevSquishFactor) * var2) / ((float)var1.size * 0.5F + 1.0F);
+		float var3 = (var1.prevSquishFactor + (var1.squishFactor - var1.prevSquishFactor) * var2) / ((float)var1.getSlimeSize() * 0.5F + 1.0F);
 		float var4 = 1.0F / (var3 + 1.0F);
-		float var5 = (float)var1.size;
+		float var5 = (float)var1.getSlimeSize();
 		GL11.glScalef(var4 * var5, 1.0F / var4 * var5, var4 * var5);
 	}
 
--- /dev/null
+++ net/minecraft/src/BlockWool.java
@@ -1,0 +1,30 @@
+package net.minecraft.src;
+
+public class BlockWool extends Block {
+	public BlockWool() {
+		super(35, 64, Material.cloth);
+	}
+
+	@Override
+	public int getBlockTextureFromSideAndMetadata(int face, int metadata) {
+		if (metadata == 0) {
+			return this.blockIndexInTexture;
+		} else {
+			metadata = ~(metadata & 15);
+			return 113 + ((metadata & 8) >> 3) + (metadata & 7) * 16;
+		}
+	}
+
+	@Override
+	protected int damageDropped(int metadata) {
+		return metadata;
+	}
+
+	public static int getBlockMetadataForItemMetadata(int metadata) {
+		return ~metadata & 15;
+	}
+
+	public static int getItemMetadataForBlockMetadata(int metadata) {
+		return ~metadata & 15;
+	}
+}
--- /dev/null
+++ net/minecraft/src/Packet103SetSlot.java
@@ -1,0 +1,46 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet103SetSlot extends Packet {
+	public int windowId;
+	public int itemSlot;
+	public ItemStack myItemStack;
+
+	public void processPacket(NetHandler var1) {
+		var1.func_20088_a(this);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.windowId = var1.readByte();
+		this.itemSlot = var1.readShort();
+		short var2 = var1.readShort();
+		if(var2 >= 0) {
+			byte var3 = var1.readByte();
+			short var4 = var1.readShort();
+			this.myItemStack = new ItemStack(var2, var3, var4);
+		} else {
+			this.myItemStack = null;
+		}
+
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.windowId);
+		var1.writeShort(this.itemSlot);
+		if(this.myItemStack == null) {
+			var1.writeShort(-1);
+		} else {
+			var1.writeShort(this.myItemStack.itemID);
+			var1.writeByte(this.myItemStack.stackSize);
+			var1.writeShort(this.myItemStack.getItemDamage());
+		}
+
+	}
+
+	public int getPacketSize() {
+		return 8;
+	}
+}
--- net/minecraft/src/EntityCreature.java
+++ net/minecraft/src/EntityCreature.java
@@ -23,6 +23,8 @@
 			float var2 = this.entityToAttack.getDistanceToEntity(this);
 			if(this.canEntityBeSeen(this.entityToAttack)) {
 				this.attackEntity(this.entityToAttack, var2);
+			} else {
+				this.attackBlockedEntity(this.entityToAttack, var2);
 			}
 		}
 
@@ -133,6 +135,9 @@
 
 	protected void attackEntity(Entity var1, float var2) {
 	}
+	
+	protected void attackBlockedEntity(Entity var1, float var2) {
+	}
 
 	protected float getBlockPathWeight(int var1, int var2, int var3) {
 		return 0.0F;
@@ -147,5 +152,21 @@
 		int var2 = MathHelper.floor_double(this.boundingBox.minY);
 		int var3 = MathHelper.floor_double(this.posZ);
 		return super.getCanSpawnHere() && this.getBlockPathWeight(var1, var2, var3) >= 0.0F;
+	}
+	
+	public boolean hasPath() {
+		return this.pathToEntity != null;
+	}
+
+	public void setPathToEntity(PathEntity var1) {
+		this.pathToEntity = var1;
+	}
+
+	public Entity getTarget() {
+		return this.entityToAttack;
+	}
+
+	public void setTarget(Entity var1) {
+		this.entityToAttack = var1;
 	}
 }
--- /dev/null
+++ net/minecraft/src/Packet54PlayNoteBlock.java
@@ -1,0 +1,37 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet54PlayNoteBlock extends Packet {
+	public int xLocation;
+	public int yLocation;
+	public int zLocation;
+	public int instrumentType;
+	public int pitch;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.xLocation = var1.readInt();
+		this.yLocation = var1.readShort();
+		this.zLocation = var1.readInt();
+		this.instrumentType = var1.read();
+		this.pitch = var1.read();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.xLocation);
+		var1.writeShort(this.yLocation);
+		var1.writeInt(this.zLocation);
+		var1.write(this.instrumentType);
+		var1.write(this.pitch);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.handleNotePlay(this);
+	}
+
+	public int getPacketSize() {
+		return 12;
+	}
+}
--- net/minecraft/src/Packet10Flying.java
+++ net/minecraft/src/Packet10Flying.java
@@ -30,7 +30,7 @@
 		this.onGround = var1.read() != 0;
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.write(this.onGround ? 1 : 0);
 	}
 
--- /dev/null
+++ net/minecraft/src/Packet62Sound.java
@@ -1,0 +1,36 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet62Sound extends Packet {
+	public String sound;
+	public double locX;
+	public double locY;
+	public double locZ;
+	public float f;
+	public float f1;
+
+	public Packet62Sound() {}
+
+	public void readPacketData(DataInputStream datainputstream) throws IOException {
+		this.sound = datainputstream.readUTF();
+		this.locX = datainputstream.readDouble();
+		this.locY = datainputstream.readDouble();
+		this.locZ = datainputstream.readDouble();
+		this.f = datainputstream.readFloat();
+		this.f1 = datainputstream.readFloat();
+	}
+
+	public void writePacketData(DataOutputStream dataoutputstream) throws IOException {
+	}
+
+	public void processPacket(NetHandler nethandler) {
+		nethandler.handle62Sound(this);
+	}
+
+	public int getPacketSize() {
+		return this.sound.length() + 8 * 3 + 4 * 2;
+	}
+}
--- net/minecraft/src/BlockRedstoneOre.java
+++ net/minecraft/src/BlockRedstoneOre.java
@@ -34,6 +34,9 @@
 	}
 
 	private void glow(World var1, int var2, int var3, int var4) {
+		if (var1.multiplayerWorld) {
+			return;
+		}
 		this.sparkle(var1, var2, var3, var4);
 		if(this.blockID == Block.oreRedstone.blockID) {
 			var1.setBlockWithNotify(var2, var3, var4, Block.oreRedstoneGlowing.blockID);
--- net/minecraft/src/ItemPainting.java
+++ net/minecraft/src/ItemPainting.java
@@ -27,7 +27,9 @@
 
 			EntityPainting var9 = new EntityPainting(var3, var4, var5, var6, var8);
 			if(var9.onValidSurface()) {
-				var3.spawnEntityInWorld(var9);
+				if(!var3.multiplayerWorld) {
+					var3.spawnEntityInWorld(var9);
+				}
 				--var1.stackSize;
 			}
 
--- /dev/null
+++ net/minecraft/src/Packet70Bed.java
@@ -1,0 +1,26 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet70Bed extends Packet {
+	public static final String[] field_25020_a = new String[]{"tile.bed.notValid", null, null};
+	public int field_25019_b;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.field_25019_b = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.field_25019_b);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_25118_a(this);
+	}
+
+	public int getPacketSize() {
+		return 1;
+	}
+}
--- net/minecraft/src/EntityCreeper.java
+++ net/minecraft/src/EntityCreeper.java
@@ -4,13 +4,17 @@
 	int timeSinceIgnited;
 	int lastActiveTime;
 	int fuseDuration = 30;
-	int creeperState = -1;
 
 	public EntityCreeper(World var1) {
 		super(var1);
 		this.texture = "/mob/creeper.png";
 	}
 
+	protected void entityInit() {
+		super.entityInit();
+		this.dataWatcher.addObject(16, Byte.valueOf((byte)-1));
+	}
+
 	public void writeEntityToNBT(NBTTagCompound var1) {
 		super.writeEntityToNBT(var1);
 	}
@@ -18,20 +22,45 @@
 	public void readEntityFromNBT(NBTTagCompound var1) {
 		super.readEntityFromNBT(var1);
 	}
-
-	protected void updateEntityActionState() {
+	
+	protected void attackBlockedEntity(Entity var1, float var2) {
+		if(!this.worldObj.multiplayerWorld) {
+			if(this.timeSinceIgnited > 0) {
+				this.setCreeperState(-1);
+				--this.timeSinceIgnited;
+				if(this.timeSinceIgnited < 0) {
+					this.timeSinceIgnited = 0;
+				}
+			}
+
+		}
+	}
+
+	public void onUpdate() {
 		this.lastActiveTime = this.timeSinceIgnited;
-		if(this.timeSinceIgnited > 0 && this.creeperState < 0) {
+		if(this.worldObj.multiplayerWorld) {
+			int var1 = this.getCreeperState();
+			if(var1 > 0 && this.timeSinceIgnited == 0) {
+				//this.worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 0.5F);
+			}
+
+			this.timeSinceIgnited += var1;
+			if(this.timeSinceIgnited < 0) {
+				this.timeSinceIgnited = 0;
+			}
+
+			if(this.timeSinceIgnited >= 30) {
+				this.timeSinceIgnited = 30;
+			}
+		}
+
+		super.onUpdate();
+		if(this.entityToAttack == null && this.timeSinceIgnited > 0) {
+			this.setCreeperState(-1);
 			--this.timeSinceIgnited;
-		}
-
-		if(this.creeperState >= 0) {
-			this.creeperState = 2;
-		}
-
-		super.updateEntityActionState();
-		if(this.creeperState != 1) {
-			this.creeperState = -1;
+			if(this.timeSinceIgnited < 0) {
+				this.timeSinceIgnited = 0;
+			}
 		}
 
 	}
@@ -53,12 +82,16 @@
 	}
 
 	protected void attackEntity(Entity var1, float var2) {
-		if(this.creeperState <= 0 && var2 < 3.0F || this.creeperState > 0 && var2 < 7.0F) {
+		if(this.worldObj.multiplayerWorld)
+			return;
+
+		int creeperState = this.getCreeperState();
+		if(creeperState <= 0 && var2 < 3.0F || creeperState > 0 && var2 < 7.0F) {
 			if(this.timeSinceIgnited == 0) {
 				this.worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 0.5F);
 			}
 
-			this.creeperState = 1;
+			this.setCreeperState(1);
 			++this.timeSinceIgnited;
 			if(this.timeSinceIgnited == this.fuseDuration) {
 				this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 3.0F);
@@ -66,6 +99,12 @@
 			}
 
 			this.hasAttacked = true;
+		} else {
+			this.setCreeperState(-1);
+			--this.timeSinceIgnited;
+			if(this.timeSinceIgnited < 0) {
+				this.timeSinceIgnited = 0;
+			}
 		}
 
 	}
@@ -76,5 +115,13 @@
 
 	protected int getDropItemId() {
 		return Item.gunpowder.shiftedIndex;
+	}
+	
+	private int getCreeperState() {
+		return this.dataWatcher.getWatchableObjectByte(16);
+	}
+
+	private void setCreeperState(int var1) {
+		this.dataWatcher.updateObject(16, Byte.valueOf((byte)var1));
 	}
 }
--- net/minecraft/src/GuiIngame.java
+++ net/minecraft/src/GuiIngame.java
@@ -286,6 +286,10 @@
 
 	}
 
+	public void clearChatMessages() {
+		this.chatMessageList.clear();
+	}
+
 	public void addChatMessage(String var1) {
 		while(this.mc.fontRenderer.getStringWidth(var1) > 320) {
 			int var2;
--- net/minecraft/src/ItemHoe.java
+++ net/minecraft/src/ItemHoe.java
@@ -16,7 +16,10 @@
 			Block var10 = Block.tilledField;
 			var3.playSoundEffect((double)((float)var4 + 0.5F), (double)((float)var5 + 0.5F), (double)((float)var6 + 0.5F), var10.stepSound.getStepSound(), (var10.stepSound.getVolume() + 1.0F) / 2.0F, var10.stepSound.getPitch() * 0.8F);
 			var3.setBlockWithNotify(var4, var5, var6, var10.blockID);
-			var1.damageItem(1);
+			if(var3.multiplayerWorld) {
+				return true;
+			}
+			var1.damageItem(1, var2);
 			if(var3.rand.nextInt(8) == 0 && var8 == Block.grass.blockID) {
 				byte var11 = 1;
 
--- /dev/null
+++ net/minecraft/src/Packet104WindowItems.java
@@ -1,0 +1,50 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet104WindowItems extends Packet {
+	public int windowId;
+	public ItemStack[] itemStack;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.windowId = var1.readByte();
+		short var2 = var1.readShort();
+		this.itemStack = new ItemStack[var2];
+
+		for(int var3 = 0; var3 < var2; ++var3) {
+			short var4 = var1.readShort();
+			if(var4 >= 0) {
+				byte var5 = var1.readByte();
+				short var6 = var1.readShort();
+				this.itemStack[var3] = new ItemStack(var4, var5, var6);
+			}
+		}
+
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.windowId);
+		var1.writeShort(this.itemStack.length);
+
+		for(int var2 = 0; var2 < this.itemStack.length; ++var2) {
+			if(this.itemStack[var2] == null) {
+				var1.writeShort(-1);
+			} else {
+				var1.writeShort((short)this.itemStack[var2].itemID);
+				var1.writeByte((byte)this.itemStack[var2].stackSize);
+				var1.writeShort((short)this.itemStack[var2].getItemDamage());
+			}
+		}
+
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_20094_a(this);
+	}
+
+	public int getPacketSize() {
+		return 3 + this.itemStack.length * 5;
+	}
+}
--- /dev/null
+++ net/minecraft/src/ShapedRecipes.java
@@ -1,0 +1,75 @@
+package net.minecraft.src;
+
+public class ShapedRecipes implements IRecipe {
+	private int recipeWidth;
+	private int recipeHeight;
+	private int[] recipeItems;
+	private ItemStack recipeOutput;
+	public final int recipeOutputItemID;
+
+	public ShapedRecipes(int var1, int var2, int[] var3, ItemStack var4) {
+		this.recipeOutputItemID = var4.itemID;
+		this.recipeWidth = var1;
+		this.recipeHeight = var2;
+		this.recipeItems = var3;
+		this.recipeOutput = var4;
+	}
+
+	public ItemStack getRecipeOutput() {
+		return this.recipeOutput;
+	}
+
+	public boolean matches(InventoryCrafting var1) {
+		for(int var2 = 0; var2 <= 3 - this.recipeWidth; ++var2) {
+			for(int var3 = 0; var3 <= 3 - this.recipeHeight; ++var3) {
+				if(this.func_21137_a(var1, var2, var3, true)) {
+					return true;
+				}
+
+				if(this.func_21137_a(var1, var2, var3, false)) {
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+
+	private boolean func_21137_a(InventoryCrafting var1, int var2, int var3, boolean var4) {
+		for(int var5 = 0; var5 < 3; ++var5) {
+			for(int var6 = 0; var6 < 3; ++var6) {
+				int var7 = var5 - var2;
+				int var8 = var6 - var3;
+				int var9 = -1;
+				if(var7 >= 0 && var8 >= 0 && var7 < this.recipeWidth && var8 < this.recipeHeight) {
+					if(var4) {
+						var9 = this.recipeItems[this.recipeWidth - var7 - 1 + var8 * this.recipeWidth];
+					} else {
+						var9 = this.recipeItems[var7 + var8 * this.recipeWidth];
+					}
+				}
+
+				ItemStack var10 = var1.func_21103_b(var5, var6);
+				if(var10 != null || var9 != -1) {
+					if(var10 == null && var9 != -1 || var10 != null && var9 == -1) {
+						return false;
+					}
+
+					if(var9 != var10.itemID) {
+						return false;
+					}
+				}
+			}
+		}
+
+		return true;
+	}
+
+	public ItemStack getCraftingResult(InventoryCrafting var1) {
+		return new ItemStack(this.recipeOutput.itemID, this.recipeOutput.stackSize, this.recipeOutput.getItemDamage());
+	}
+
+	public int getRecipeSize() {
+		return this.recipeWidth * this.recipeHeight;
+	}
+}
--- net/minecraft/src/Packet14BlockDig.java
+++ net/minecraft/src/Packet14BlockDig.java
@@ -30,7 +30,7 @@
 		this.face = var1.read();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.write(this.status);
 		var1.writeInt(this.xPosition);
 		var1.write(this.yPosition);
--- net/minecraft/src/BlockJukeBox.java
+++ net/minecraft/src/BlockJukeBox.java
@@ -20,16 +20,18 @@
 	}
 
 	public void ejectRecord(World var1, int var2, int var3, int var4, int var5) {
-		var1.playRecord((String)null, var2, var3, var4);
-		var1.setBlockMetadataWithNotify(var2, var3, var4, 0);
-		int var6 = Item.record13.shiftedIndex + var5 - 1;
-		float var7 = 0.7F;
-		double var8 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.5D;
-		double var10 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.2D + 0.6D;
-		double var12 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.5D;
-		EntityItem var14 = new EntityItem(var1, (double)var2 + var8, (double)var3 + var10, (double)var4 + var12, new ItemStack(var6));
-		var14.delayBeforeCanPickup = 10;
-		var1.spawnEntityInWorld(var14);
+		if(!var1.multiplayerWorld) {
+			var1.playRecord((String)null, var2, var3, var4);
+			var1.setBlockMetadataWithNotify(var2, var3, var4, 0);
+			int var6 = Item.record13.shiftedIndex + var5 - 1;
+			float var7 = 0.7F;
+			double var8 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.5D;
+			double var10 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.2D + 0.6D;
+			double var12 = (double)(var1.rand.nextFloat() * var7) + (double)(1.0F - var7) * 0.5D;
+			EntityItem var14 = new EntityItem(var1, (double)var2 + var8, (double)var3 + var10, (double)var4 + var12, new ItemStack(var6, 1, 0));
+			var14.delayBeforeCanPickup = 10;
+			var1.spawnEntityInWorld(var14);
+		}
 	}
 
 	public void dropBlockAsItemWithChance(World var1, int var2, int var3, int var4, int var5, float var6) {
--- net/minecraft/src/Packet21PickupSpawn.java
+++ net/minecraft/src/Packet21PickupSpawn.java
@@ -14,6 +14,7 @@
 	public byte roll;
 	public int itemID;
 	public int count;
+	public int itemDamage;
 
 	public Packet21PickupSpawn() {
 	}
@@ -22,6 +23,7 @@
 		this.entityId = var1.entityID;
 		this.itemID = var1.item.itemID;
 		this.count = var1.item.stackSize;
+		this.itemDamage = var1.item.getItemDamage();
 		this.xPosition = MathHelper.floor_double(var1.posX * 32.0D);
 		this.yPosition = MathHelper.floor_double(var1.posY * 32.0D);
 		this.zPosition = MathHelper.floor_double(var1.posZ * 32.0D);
@@ -34,6 +36,7 @@
 		this.entityId = var1.readInt();
 		this.itemID = var1.readShort();
 		this.count = var1.readByte();
+		this.itemDamage = var1.readShort();
 		this.xPosition = var1.readInt();
 		this.yPosition = var1.readInt();
 		this.zPosition = var1.readInt();
@@ -42,10 +45,11 @@
 		this.roll = var1.readByte();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.entityId);
 		var1.writeShort(this.itemID);
 		var1.writeByte(this.count);
+		var1.writeShort(this.itemDamage);
 		var1.writeInt(this.xPosition);
 		var1.writeInt(this.yPosition);
 		var1.writeInt(this.zPosition);
@@ -59,6 +63,6 @@
 	}
 
 	public int getPacketSize() {
-		return 22;
+		return 24;
 	}
 }
--- net/minecraft/src/NetworkManager.java
+++ net/minecraft/src/NetworkManager.java
@@ -1,11 +1,14 @@
 package net.minecraft.src;
 
+import java.io.BufferedOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 
 public class NetworkManager {
@@ -14,28 +17,42 @@
 	public static int numWriteThreads;
 	private Object sendQueueLock = new Object();
 	private Socket networkSocket;
+	private final SocketAddress remoteSocketAddress;
 	private DataInputStream socketInputStream;
 	private DataOutputStream socketOutputStream;
 	private boolean isRunning = true;
-	private List readPackets = Collections.synchronizedList(new LinkedList());
-	private List dataPackets = Collections.synchronizedList(new LinkedList());
-	private List chunkDataPackets = Collections.synchronizedList(new LinkedList());
+	private List readPackets = Collections.synchronizedList(new ArrayList());
+	private List dataPackets = Collections.synchronizedList(new ArrayList());
+	private List chunkDataPackets = Collections.synchronizedList(new ArrayList());
 	private NetHandler netHandler;
 	private boolean isServerTerminating = false;
 	private Thread writeThread;
 	private Thread readThread;
 	private boolean isTerminating = false;
 	private String terminationReason = "";
+	private Object[] field_20101_t;
 	private int timeSinceLastRead = 0;
 	private int sendQueueByteLength = 0;
-	private int chunkDataSendCounter = 0;
+	public static int[] field_28145_d = new int[256];
+	public static int[] field_28144_e = new int[256];
+	public int chunkDataSendCounter = 0;
+	private int field_20100_w = 50;
 
 	public NetworkManager(Socket var1, String var2, NetHandler var3) throws IOException {
 		this.networkSocket = var1;
+		this.remoteSocketAddress = var1.getRemoteSocketAddress();
 		this.netHandler = var3;
-		var1.setTrafficClass(24);
+
+		try {
+			var1.setSoTimeout(30000);
+			var1.setTcpNoDelay(true);
+			var1.setTrafficClass(24);
+		} catch (SocketException var5) {
+			System.err.println(var5.getMessage());
+		}
+
 		this.socketInputStream = new DataInputStream(var1.getInputStream());
-		this.socketOutputStream = new DataOutputStream(var1.getOutputStream());
+		this.socketOutputStream = new DataOutputStream(new BufferedOutputStream(var1.getOutputStream(), 5120));
 		this.readThread = new NetworkReaderThread(this, var2 + " read thread");
 		this.writeThread = new NetworkWriterThread(this, var2 + " write thread");
 		this.readThread.start();
@@ -57,13 +74,15 @@
 		}
 	}
 
-	private void sendPacket() {
+	private boolean sendPacket() {
+		boolean var1 = false;
+
 		try {
-			boolean var1 = true;
+			int[] var10000;
+			int var10001;
 			Packet var2;
 			Object var3;
-			if(!this.dataPackets.isEmpty()) {
-				var1 = false;
+			if(!this.dataPackets.isEmpty() && (this.chunkDataSendCounter == 0 || System.currentTimeMillis() - ((Packet)this.dataPackets.get(0)).creationTimeMillis >= (long)this.chunkDataSendCounter)) {
 				var3 = this.sendQueueLock;
 				synchronized(var3) {
 					var2 = (Packet)this.dataPackets.remove(0);
@@ -71,10 +90,13 @@
 				}
 
 				Packet.writePacket(var2, this.socketOutputStream);
+				var10000 = field_28144_e;
+				var10001 = var2.getPacketId();
+				var10000[var10001] += var2.getPacketSize() + 1;
+				var1 = true;
 			}
 
-			if((var1 || this.chunkDataSendCounter-- <= 0) && !this.chunkDataPackets.isEmpty()) {
-				var1 = false;
+			if(this.field_20100_w-- <= 0 && !this.chunkDataPackets.isEmpty() && (this.chunkDataSendCounter == 0 || System.currentTimeMillis() - ((Packet)this.chunkDataPackets.get(0)).creationTimeMillis >= (long)this.chunkDataSendCounter)) {
 				var3 = this.sendQueueLock;
 				synchronized(var3) {
 					var2 = (Packet)this.chunkDataPackets.remove(0);
@@ -82,35 +104,51 @@
 				}
 
 				Packet.writePacket(var2, this.socketOutputStream);
-				this.chunkDataSendCounter = 50;
+				var10000 = field_28144_e;
+				var10001 = var2.getPacketId();
+				var10000[var10001] += var2.getPacketSize() + 1;
+				this.field_20100_w = 0;
+				var1 = true;
 			}
 
-			if(var1) {
-				Thread.sleep(10L);
-			}
-		} catch (InterruptedException var8) {
-		} catch (Exception var9) {
+			return var1;
+		} catch (Exception var8) {
 			if(!this.isTerminating) {
-				this.onNetworkError(var9);
+				this.onNetworkError(var8);
 			}
+
+			return false;
 		}
-
-	}
-
-	private void readPacket() {
+	}
+
+	public void wakeThreads() {
+		this.readThread.interrupt();
+		this.writeThread.interrupt();
+	}
+
+	private boolean readPacket() {
+		boolean var1 = false;
+
 		try {
-			Packet var1 = Packet.readPacket(this.socketInputStream);
-			if(var1 != null) {
-				this.readPackets.add(var1);
+			Packet var2 = Packet.readPacket(this.socketInputStream, this.netHandler.isServerHandler());
+			if(var2 != null) {
+				int[] var10000 = field_28145_d;
+				int var10001 = var2.getPacketId();
+				var10000[var10001] += var2.getPacketSize() + 1;
+				this.readPackets.add(var2);
+				var1 = true;
 			} else {
-				this.networkShutdown("End of stream");
+				this.networkShutdown("End of stream", new Object[0]);
 			}
-		} catch (Exception var2) {
+
+			return var1;
+		} catch (Exception var3) {
 			if(!this.isTerminating) {
-				this.onNetworkError(var2);
+				this.onNetworkError(var3);
 			}
+
+			return false;
 		}
-
 	}
 
 	private void onNetworkError(Exception var1) {
@@ -118,26 +156,33 @@
 		this.networkShutdown("Internal exception: " + var1.toString());
 	}
 
-	public void networkShutdown(String var1) {
+	public void networkShutdown(String var1, Object... var2) {
 		if(this.isRunning) {
+			if (var2 == null) {
+				var2 = new Object[0];
+			}
 			this.isTerminating = true;
 			this.terminationReason = var1;
+			this.field_20101_t = var2;
 			(new NetworkMasterThread(this)).start();
 			this.isRunning = false;
 
 			try {
 				this.socketInputStream.close();
-			} catch (Throwable var5) {
+				this.socketInputStream = null;
+			} catch (Throwable var6) {
 			}
 
 			try {
 				this.socketOutputStream.close();
-			} catch (Throwable var4) {
+				this.socketOutputStream = null;
+			} catch (Throwable var5) {
 			}
 
 			try {
 				this.networkSocket.close();
-			} catch (Throwable var3) {
+				this.networkSocket = null;
+			} catch (Throwable var4) {
 			}
 
 		}
@@ -145,14 +190,15 @@
 
 	public void processReadPackets() {
 		if(this.sendQueueByteLength > 1048576) {
-			this.networkShutdown("Send buffer overflow");
+			this.networkShutdown("Send buffer overflow", new Object[0]);
 		}
 
 		if(this.readPackets.isEmpty()) {
 			if(this.timeSinceLastRead++ == 1200) {
-				this.networkShutdown("Timed out");
+				this.networkShutdown("Timed out", new Object[0]);
 			}
 		} else {
+			
 			this.timeSinceLastRead = 0;
 		}
 
@@ -163,10 +209,18 @@
 			var2.processPacket(this.netHandler);
 		}
 
+		this.wakeThreads();
 		if(this.isTerminating && this.readPackets.isEmpty()) {
-			this.netHandler.handleErrorMessage(this.terminationReason);
+			this.netHandler.handleErrorMessage(this.terminationReason, this.field_20101_t);
 		}
 
+	}
+
+	public void func_28142_c() {
+		this.wakeThreads();
+		this.isServerTerminating = true;
+		this.readThread.interrupt();
+		(new ThreadCloseConnection(this)).start();
 	}
 
 	static boolean isRunning(NetworkManager var0) {
@@ -177,12 +231,24 @@
 		return var0.isServerTerminating;
 	}
 
-	static void readNetworkPacket(NetworkManager var0) {
-		var0.readPacket();
-	}
-
-	static void sendNetworkPacket(NetworkManager var0) {
-		var0.sendPacket();
+	static boolean readNetworkPacket(NetworkManager var0) {
+		return var0.readPacket();
+	}
+
+	static boolean sendNetworkPacket(NetworkManager var0) {
+		return var0.sendPacket();
+	}
+
+	static DataOutputStream func_28140_f(NetworkManager var0) {
+		return var0.socketOutputStream;
+	}
+
+	static boolean func_28138_e(NetworkManager var0) {
+		return var0.isTerminating;
+	}
+
+	static void func_30005_a(NetworkManager var0, Exception var1) {
+		var0.onNetworkError(var1);
 	}
 
 	static Thread getReadThread(NetworkManager var0) {
--- net/minecraft/src/RenderMinecart.java
+++ net/minecraft/src/RenderMinecart.java
@@ -60,9 +60,9 @@
 			GL11.glTranslatef(0.0F, 5.0F / 16.0F, 0.0F);
 			GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F);
 			if(var1.minecartType == 1) {
-				(new RenderBlocks()).renderBlockOnInventory(Block.chest);
+				(new RenderBlocks()).renderBlockOnInventory(Block.chest, 0);
 			} else if(var1.minecartType == 2) {
-				(new RenderBlocks()).renderBlockOnInventory(Block.stoneOvenIdle);
+				(new RenderBlocks()).renderBlockOnInventory(Block.stoneOvenIdle, 0);
 			}
 
 			GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
--- net/minecraft/src/EntityFallingSand.java
+++ net/minecraft/src/EntityFallingSand.java
@@ -8,20 +8,23 @@
 		super(var1);
 	}
 
-	public EntityFallingSand(World var1, float var2, float var3, float var4, int var5) {
+	public EntityFallingSand(World var1, double var2, double var3, double var4, int var5) {
 		super(var1);
 		this.blockID = var5;
 		this.preventEntitySpawning = true;
 		this.setSize(0.98F, 0.98F);
 		this.yOffset = this.height / 2.0F;
-		this.setPosition((double)var2, (double)var3, (double)var4);
+		this.setPosition(var2, var3, var4);
 		this.motionX = 0.0D;
 		this.motionY = 0.0D;
 		this.motionZ = 0.0D;
 		this.canTriggerWalking = false;
-		this.prevPosX = (double)var2;
-		this.prevPosY = (double)var3;
-		this.prevPosZ = (double)var4;
+		this.prevPosX = var2;
+		this.prevPosY = var3;
+		this.prevPosZ = var4;
+	}
+
+	protected void entityInit() {
 	}
 
 	public boolean canBeCollidedWith() {
@@ -53,11 +56,13 @@
 				this.motionZ *= (double)0.7F;
 				this.motionY *= -0.5D;
 				this.setEntityDead();
-				if(!this.worldObj.canBlockBePlacedAt(this.blockID, var1, var2, var3, true) || !this.worldObj.setBlockWithNotify(var1, var2, var3, this.blockID)) {
+				if((!this.worldObj.canBlockBePlacedAt(this.blockID, var1, var2, var3, true) || !this.worldObj.setBlockWithNotify(var1, var2, var3, this.blockID)) && !this.worldObj.multiplayerWorld) {
 					this.dropItem(this.blockID, 1);
 				}
 			} else if(this.fallTime > 100) {
-				this.dropItem(this.blockID, 1);
+				if (!this.worldObj.multiplayerWorld)
+					this.dropItem(this.blockID, 1);
+				
 				this.setEntityDead();
 			}
 
--- net/minecraft/src/TileEntityFurnace.java
+++ net/minecraft/src/TileEntityFurnace.java
@@ -1,10 +1,10 @@
 package net.minecraft.src;
 
 public class TileEntityFurnace extends TileEntity implements IInventory {
-	private ItemStack[] furnaceItemStacks = new ItemStack[3];
-	private int furnaceBurnTime = 0;
-	private int currentItemBurnTime = 0;
-	private int furnaceCookTime = 0;
+	public ItemStack[] furnaceItemStacks = new ItemStack[3];
+	public int furnaceBurnTime = 0;
+	public int currentItemBurnTime = 0;
+	public int furnaceCookTime = 0;
 
 	public int getSizeInventory() {
 		return this.furnaceItemStacks.length;
@@ -159,7 +159,7 @@
 		if(this.canSmelt()) {
 			int var1 = this.getCookedItem(this.furnaceItemStacks[0].getItem().shiftedIndex);
 			if(this.furnaceItemStacks[2] == null) {
-				this.furnaceItemStacks[2] = new ItemStack(var1, 1);
+				this.furnaceItemStacks[2] = new ItemStack(var1, 1, 0);
 			} else if(this.furnaceItemStacks[2].itemID == var1) {
 				++this.furnaceItemStacks[2].stackSize;
 			}
@@ -183,5 +183,9 @@
 			int var2 = var1.getItem().shiftedIndex;
 			return var2 < 256 && Block.blocksList[var2].material == Material.wood ? 300 : (var2 == Item.stick.shiftedIndex ? 100 : (var2 == Item.coal.shiftedIndex ? 1600 : (var2 == Item.bucketLava.shiftedIndex ? 20000 : 0)));
 		}
+	}
+	
+	public boolean canInteractWith(EntityPlayer var1) {
+		return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : var1.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
 	}
 }
--- /dev/null
+++ net/minecraft/src/SlotFurnace.java
@@ -1,0 +1,20 @@
+package net.minecraft.src;
+
+public class SlotFurnace extends Slot {
+	private EntityPlayer thePlayer;
+
+	public SlotFurnace(EntityPlayer var1, IInventory var2, int var3, int var4, int var5) {
+		super(var2, var3, var4, var5);
+		this.thePlayer = var1;
+	}
+
+	public boolean isItemValid(ItemStack var1) {
+		return false;
+	}
+
+	public void onPickupFromSlot(ItemStack var1) {
+		var1.onCrafting(this.thePlayer.worldObj, this.thePlayer);
+
+		super.onPickupFromSlot(var1);
+	}
+}
--- net/minecraft/src/CraftingManager.java
+++ net/minecraft/src/CraftingManager.java
@@ -110,12 +110,35 @@
 			}
 		}
 
-		this.recipes.add(new CraftingRecipe(var5, var6, var14, var1));
-	}
-
-	public ItemStack findMatchingRecipe(int[] var1) {
+		this.recipes.add(new ShapedRecipes(var5, var6, var14, var1));
+	}
+	
+	void addShapelessRecipe(ItemStack var1, Object... var2) {
+		ArrayList var3 = new ArrayList();
+		Object[] var4 = var2;
+		int var5 = var2.length;
+
+		for(int var6 = 0; var6 < var5; ++var6) {
+			Object var7 = var4[var6];
+			if(var7 instanceof ItemStack) {
+				var3.add(((ItemStack)var7).copy());
+			} else if(var7 instanceof Item) {
+				var3.add(new ItemStack((Item)var7));
+			} else {
+				if(!(var7 instanceof Block)) {
+					throw new RuntimeException("Invalid shapeless recipy!");
+				}
+
+				var3.add(new ItemStack((Block)var7));
+			}
+		}
+
+		this.recipes.add(new ShapelessRecipes(var1, var3));
+	}
+
+	public ItemStack findMatchingRecipe(InventoryCrafting var1) {
 		for(int var2 = 0; var2 < this.recipes.size(); ++var2) {
-			CraftingRecipe var3 = (CraftingRecipe)this.recipes.get(var2);
+			IRecipe var3 = (IRecipe)this.recipes.get(var2);
 			if(var3.matches(var1)) {
 				return var3.getCraftingResult(var1);
 			}
--- /dev/null
+++ net/minecraft/src/Packet130UpdateSign.java
@@ -1,0 +1,61 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet130UpdateSign extends Packet {
+	public int xPosition;
+	public int yPosition;
+	public int zPosition;
+	public String[] signLines;
+
+	public Packet130UpdateSign() {
+		this.isChunkDataPacket = true;
+	}
+
+	public Packet130UpdateSign(int var1, int var2, int var3, String[] var4) {
+		this.isChunkDataPacket = true;
+		this.xPosition = var1;
+		this.yPosition = var2;
+		this.zPosition = var3;
+		this.signLines = var4;
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.xPosition = var1.readInt();
+		this.yPosition = var1.readShort();
+		this.zPosition = var1.readInt();
+		this.signLines = new String[4];
+
+		for(int var2 = 0; var2 < 4; ++var2) {
+			this.signLines[var2] = readString(var1, 15);
+		}
+
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.xPosition);
+		var1.writeShort(this.yPosition);
+		var1.writeInt(this.zPosition);
+
+		for(int var2 = 0; var2 < 4; ++var2) {
+			writeString(this.signLines[var2], var1);
+		}
+
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.handleSignUpdate(this);
+	}
+
+	public int getPacketSize() {
+		int var1 = 0;
+
+		for(int var2 = 0; var2 < 4; ++var2) {
+			var1 += this.signLines[var2].length();
+		}
+
+		return var1;
+	}
+}
--- /dev/null
+++ net/minecraft/src/DataWatcher.java
@@ -1,0 +1,179 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class DataWatcher {
+	private static final HashMap dataTypes = new HashMap();
+	private final Map watchedObjects = new HashMap();
+	private boolean objectChanged;
+
+	public void addObject(int var1, Object var2) {
+		Integer var3 = (Integer)dataTypes.get(var2.getClass());
+		if(var3 == null) {
+			throw new IllegalArgumentException("Unknown data type: " + var2.getClass());
+		} else if(var1 > 31) {
+			throw new IllegalArgumentException("Data value id is too big with " + var1 + "! (Max is " + 31 + ")");
+		} else if(this.watchedObjects.containsKey(Integer.valueOf(var1))) {
+			throw new IllegalArgumentException("Duplicate id value for " + var1 + "!");
+		} else {
+			WatchableObject var4 = new WatchableObject(var3.intValue(), var1, var2);
+			this.watchedObjects.put(Integer.valueOf(var1), var4);
+		}
+	}
+
+	public byte getWatchableObjectByte(int var1) {
+		return ((Byte)((WatchableObject)this.watchedObjects.get(Integer.valueOf(var1))).getObject()).byteValue();
+	}
+
+	public int getWatchableObjectInt(int var1) {
+		return ((Integer)((WatchableObject)this.watchedObjects.get(Integer.valueOf(var1))).getObject()).intValue();
+	}
+
+	public String getWatchableObjectString(int var1) {
+		return (String)((WatchableObject)this.watchedObjects.get(Integer.valueOf(var1))).getObject();
+	}
+
+	public void updateObject(int var1, Object var2) {
+		WatchableObject var3 = (WatchableObject)this.watchedObjects.get(Integer.valueOf(var1));
+		if(!var2.equals(var3.getObject())) {
+			var3.setObject(var2);
+			var3.setWatching(true);
+			this.objectChanged = true;
+		}
+
+	}
+
+	public static void writeObjectsInListToStream(List var0, DataOutputStream var1) throws IOException {
+		if(var0 != null) {
+			Iterator var2 = var0.iterator();
+
+			while(var2.hasNext()) {
+				WatchableObject var3 = (WatchableObject)var2.next();
+				writeWatchableObject(var1, var3);
+			}
+		}
+
+		var1.writeByte(127);
+	}
+
+	public void writeWatchableObjects(DataOutputStream var1) throws IOException {
+		Iterator var2 = this.watchedObjects.values().iterator();
+
+		while(var2.hasNext()) {
+			WatchableObject var3 = (WatchableObject)var2.next();
+			writeWatchableObject(var1, var3);
+		}
+
+		var1.writeByte(127);
+	}
+
+	private static void writeWatchableObject(DataOutputStream var0, WatchableObject var1) throws IOException {
+		int var2 = (var1.getObjectType() << 5 | var1.getDataValueId() & 31) & 255;
+		var0.writeByte(var2);
+		switch(var1.getObjectType()) {
+		case 0:
+			var0.writeByte(((Byte)var1.getObject()).byteValue());
+			break;
+		case 1:
+			var0.writeShort(((Short)var1.getObject()).shortValue());
+			break;
+		case 2:
+			var0.writeInt(((Integer)var1.getObject()).intValue());
+			break;
+		case 3:
+			var0.writeFloat(((Float)var1.getObject()).floatValue());
+			break;
+		case 4:
+			Packet.writeString((String)var1.getObject(), var0);
+			break;
+		case 5:
+			ItemStack var4 = (ItemStack)var1.getObject();
+			var0.writeShort(var4.getItem().shiftedIndex);
+			var0.writeByte(var4.stackSize);
+			var0.writeShort(var4.getItemDamage());
+			break;
+		case 6:
+			ChunkCoordinates var3 = (ChunkCoordinates)var1.getObject();
+			var0.writeInt(var3.x);
+			var0.writeInt(var3.y);
+			var0.writeInt(var3.z);
+		}
+
+	}
+
+	public static List readWatchableObjects(DataInputStream var0) throws IOException {
+		ArrayList var1 = null;
+
+		for(byte var2 = var0.readByte(); var2 != 127; var2 = var0.readByte()) {
+			if(var1 == null) {
+				var1 = new ArrayList();
+			}
+
+			int var3 = (var2 & 224) >> 5;
+			int var4 = var2 & 31;
+			WatchableObject var5 = null;
+			switch(var3) {
+			case 0:
+				var5 = new WatchableObject(var3, var4, Byte.valueOf(var0.readByte()));
+				break;
+			case 1:
+				var5 = new WatchableObject(var3, var4, Short.valueOf(var0.readShort()));
+				break;
+			case 2:
+				var5 = new WatchableObject(var3, var4, Integer.valueOf(var0.readInt()));
+				break;
+			case 3:
+				var5 = new WatchableObject(var3, var4, Float.valueOf(var0.readFloat()));
+				break;
+			case 4:
+				var5 = new WatchableObject(var3, var4, Packet.readString(var0, 64));
+				break;
+			case 5:
+				short var9 = var0.readShort();
+				byte var10 = var0.readByte();
+				short var11 = var0.readShort();
+				var5 = new WatchableObject(var3, var4, new ItemStack(var9, var10, var11));
+				break;
+			case 6:
+				int var6 = var0.readInt();
+				int var7 = var0.readInt();
+				int var8 = var0.readInt();
+				var5 = new WatchableObject(var3, var4, new ChunkCoordinates(var6, var7, var8));
+			}
+
+			var1.add(var5);
+		}
+
+		return var1;
+	}
+
+	public void updateWatchedObjectsFromList(List var1) {
+		Iterator var2 = var1.iterator();
+
+		while(var2.hasNext()) {
+			WatchableObject var3 = (WatchableObject)var2.next();
+			WatchableObject var4 = (WatchableObject)this.watchedObjects.get(Integer.valueOf(var3.getDataValueId()));
+			if(var4 != null) {
+				var4.setObject(var3.getObject());
+			}
+		}
+
+	}
+
+	static {
+		dataTypes.put(Byte.class, Integer.valueOf(0));
+		dataTypes.put(Short.class, Integer.valueOf(1));
+		dataTypes.put(Integer.class, Integer.valueOf(2));
+		dataTypes.put(Float.class, Integer.valueOf(3));
+		dataTypes.put(String.class, Integer.valueOf(4));
+		dataTypes.put(ItemStack.class, Integer.valueOf(5));
+		dataTypes.put(ChunkCoordinates.class, Integer.valueOf(6));
+	}
+}
--- /dev/null
+++ net/minecraft/src/Packet60Explosion.java
@@ -1,0 +1,67 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class Packet60Explosion extends Packet {
+	public double explosionX;
+	public double explosionY;
+	public double explosionZ;
+	public float explosionSize;
+	public Set destroyedBlockPositions;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.explosionX = var1.readDouble();
+		this.explosionY = var1.readDouble();
+		this.explosionZ = var1.readDouble();
+		this.explosionSize = var1.readFloat();
+		int var2 = var1.readInt();
+		this.destroyedBlockPositions = new HashSet();
+		int var3 = (int)this.explosionX;
+		int var4 = (int)this.explosionY;
+		int var5 = (int)this.explosionZ;
+
+		for(int var6 = 0; var6 < var2; ++var6) {
+			int var7 = var1.readByte() + var3;
+			int var8 = var1.readByte() + var4;
+			int var9 = var1.readByte() + var5;
+			this.destroyedBlockPositions.add(new ChunkPosition(var7, var8, var9));
+		}
+
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeDouble(this.explosionX);
+		var1.writeDouble(this.explosionY);
+		var1.writeDouble(this.explosionZ);
+		var1.writeFloat(this.explosionSize);
+		var1.writeInt(this.destroyedBlockPositions.size());
+		int var2 = (int)this.explosionX;
+		int var3 = (int)this.explosionY;
+		int var4 = (int)this.explosionZ;
+		Iterator var5 = this.destroyedBlockPositions.iterator();
+
+		while(var5.hasNext()) {
+			ChunkPosition var6 = (ChunkPosition)var5.next();
+			int var7 = var6.x - var2;
+			int var8 = var6.y - var3;
+			int var9 = var6.z - var4;
+			var1.writeByte(var7);
+			var1.writeByte(var8);
+			var1.writeByte(var9);
+		}
+
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_12245_a(this);
+	}
+
+	public int getPacketSize() {
+		return 32 + this.destroyedBlockPositions.size() * 3;
+	}
+}
--- /dev/null
+++ net/minecraft/src/IInvBasic.java
@@ -1,0 +1,5 @@
+package net.minecraft.src;
+
+public interface IInvBasic {
+	void func_20134_a(InventoryBasic var1);
+}
--- net/minecraft/src/EntityBoat.java
+++ net/minecraft/src/EntityBoat.java
@@ -6,6 +6,15 @@
 	public int damageTaken;
 	public int timeSinceHit;
 	public int forwardDirection;
+	private int lerpSteps;
+	private double lerpX;
+	private double lerpY;
+	private double lerpZ;
+	private double lerpYaw;
+	private double lerpPitch;
+	private double lerpVelocityX;
+	private double lerpVelocityY;
+	private double lerpVelocityZ;
 
 	public EntityBoat(World var1) {
 		super(var1);
@@ -41,11 +50,17 @@
 		this.prevPosZ = var6;
 	}
 
+	protected void entityInit() {
+	}
+
 	public double getMountedYOffset() {
 		return (double)this.height * 0.0D - (double)0.3F;
 	}
 
 	public boolean attackEntityFrom(Entity var1, int var2) {
+		if(var1.worldObj.multiplayerWorld)
+			return true;
+		
 		this.forwardDirection = -this.forwardDirection;
 		this.timeSinceHit = 10;
 		this.damageTaken += var2 * 10;
@@ -64,11 +79,37 @@
 
 		return true;
 	}
+	
+	public void performHurtAnimation() {
+		this.forwardDirection = -this.forwardDirection;
+		this.timeSinceHit = 10;
+		this.damageTaken += 10;
+	}
 
 	public boolean canBeCollidedWith() {
 		return !this.isDead;
 	}
 
+	@Override
+	public void setPositionAndRotation(double x, double y, double z, float yaw, float pitch, int steps) {
+		this.lerpX = x;
+		this.lerpY = y;
+		this.lerpZ = z;
+		this.lerpYaw = yaw;
+		this.lerpPitch = pitch;
+		this.lerpSteps = steps + 4;
+		this.motionX = this.lerpVelocityX;
+		this.motionY = this.lerpVelocityY;
+		this.motionZ = this.lerpVelocityZ;
+	}
+
+	@Override
+	public void setVelocity(double velocityX, double velocityY, double velocityZ) {
+		this.lerpVelocityX = this.motionX = velocityX;
+		this.lerpVelocityY = this.motionY = velocityY;
+		this.lerpVelocityZ = this.motionZ = velocityZ;
+	}
+
 	public void onUpdate() {
 		super.onUpdate();
 		if(this.timeSinceHit > 0) {
@@ -94,6 +135,44 @@
 			}
 		}
 
+		if (this.worldObj.multiplayerWorld) {
+			if (this.lerpSteps > 0) {
+				double e = this.posX + (this.lerpX - this.posX) / this.lerpSteps;
+				double m = this.posY + (this.lerpY - this.posY) / this.lerpSteps;
+				double q = this.posZ + (this.lerpZ - this.posZ) / this.lerpSteps;
+				double t = this.lerpYaw - this.rotationYaw;
+
+				while (t < -180.0) {
+					t += 360.0;
+				}
+
+				while (t >= 180.0) {
+					t -= 360.0;
+				}
+
+				this.rotationYaw = (float)(this.rotationYaw + t / this.lerpSteps);
+				this.rotationPitch = (float)(this.rotationPitch + (this.lerpPitch - this.rotationPitch) / this.lerpSteps);
+				this.lerpSteps--;
+				this.setPosition(e, m, q);
+				this.setRotation(this.rotationYaw, this.rotationPitch);
+			} else {
+				double f = this.posX + this.motionX;
+				double p = this.posY + this.motionY;
+				double t = this.posZ + this.motionZ;
+				this.setPosition(f, p, t);
+				if (this.onGround) {
+					this.motionX *= 0.5;
+					this.motionY *= 0.5;
+					this.motionZ *= 0.5;
+				}
+
+				this.motionX *= 0.99F;
+				this.motionY *= 0.95F;
+				this.motionZ *= 0.99F;
+			}
+
+			return;
+		}
 		double var23 = var2 * 2.0D - 1.0D;
 		this.motionY += (double)0.04F * var23;
 		if(this.riddenByEntity != null) {
@@ -149,7 +228,7 @@
 			}
 		}
 
-		if(this.isCollidedHorizontally && var8 > 0.15D) {
+		if(this.isCollidedHorizontally && var8 > 0.15D && !this.worldObj.multiplayerWorld) {
 			this.setEntityDead();
 
 			int var24;
@@ -225,6 +304,9 @@
 	}
 
 	public boolean interact(EntityPlayer var1) {
+		if(this.worldObj.multiplayerWorld)
+			return true;
+
 		var1.mountEntity(this);
 		return true;
 	}
--- net/minecraft/src/ItemFlintAndSteel.java
+++ net/minecraft/src/ItemFlintAndSteel.java
@@ -35,10 +35,11 @@
 		int var8 = var3.getBlockId(var4, var5, var6);
 		if(var8 == 0) {
 			var3.playSoundEffect((double)var4 + 0.5D, (double)var5 + 0.5D, (double)var6 + 0.5D, "fire.ignite", 1.0F, rand.nextFloat() * 0.4F + 0.8F);
+
 			var3.setBlockWithNotify(var4, var5, var6, Block.fire.blockID);
 		}
 
-		var1.damageItem(1);
+		var1.damageItem(1, var2);
 		return true;
 	}
 }
--- net/minecraft/src/EntitySnowball.java
+++ net/minecraft/src/EntitySnowball.java
@@ -18,6 +18,9 @@
 		this.setSize(0.25F, 0.25F);
 	}
 
+	protected void entityInit() {
+	}
+
 	public boolean isInRangeToRenderDist(double var1) {
 		double var3 = this.boundingBox.getAverageEdgeLength() * 4.0D;
 		var3 *= 64.0D;
@@ -40,6 +43,14 @@
 		this.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI) * var3);
 		this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, 1.5F, 1.0F);
 	}
+	
+	public EntitySnowball(World var1, double var2, double var4, double var6) {
+		super(var1);
+		this.ticksInGround = 0;
+		this.setSize(0.25F, 0.25F);
+		this.setPosition(var2, var4, var6);
+		this.yOffset = 0.0F;
+	}
 
 	public void setThrowableHeading(double var1, double var3, double var5, float var7, float var8) {
 		float var9 = MathHelper.sqrt_double(var1 * var1 + var3 * var3 + var5 * var5);
@@ -61,7 +72,22 @@
 		this.ticksInGround = 0;
 	}
 
+	@Override
+	public void setVelocity(double velocityX, double velocityY, double velocityZ) {
+		this.motionX = velocityX;
+		this.motionY = velocityY;
+		this.motionZ = velocityZ;
+		if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) {
+			float f = MathHelper.sqrt_double(velocityX * velocityX + velocityZ * velocityZ);
+			this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(velocityX, velocityZ) * 180.0 / (float) Math.PI);
+			this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(velocityY, f) * 180.0 / (float) Math.PI);
+		}
+	}
+
 	public void onUpdate() {
+		this.prevPosX = this.posX;
+		this.prevPosY = this.posY;
+		this.prevPosZ = this.posZ;
 		super.onUpdate();
 		if(this.throwableShake > 0) {
 			--this.throwableShake;
@@ -97,37 +123,39 @@
 			var2 = Vec3D.createVector(var3.hitVec.xCoord, var3.hitVec.yCoord, var3.hitVec.zCoord);
 		}
 
-		Entity var4 = null;
-		List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
-		double var6 = 0.0D;
+		if (!this.worldObj.multiplayerWorld) {
+			Entity var4 = null;
+			List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
+			double var6 = 0.0D;
 
-		int var8;
-		float var10;
-		for(var8 = 0; var8 < var5.size(); ++var8) {
-			Entity var9 = (Entity)var5.get(var8);
-			if(var9.canBeCollidedWith() && (var9 != this.thrower || this.ticksInAir >= 5)) {
-				var10 = 0.3F;
-				AxisAlignedBB var11 = var9.boundingBox.expand((double)var10, (double)var10, (double)var10);
-				MovingObjectPosition var12 = var11.calculateIntercept(var15, var2);
-				if(var12 != null) {
-					double var13 = var15.distanceTo(var12.hitVec);
-					if(var13 < var6 || var6 == 0.0D) {
-						var4 = var9;
-						var6 = var13;
+			int var8;
+			float var10;
+			for(var8 = 0; var8 < var5.size(); ++var8) {
+				Entity var9 = (Entity)var5.get(var8);
+				if(var9.canBeCollidedWith() && (var9 != this.thrower || this.ticksInAir >= 5)) {
+					var10 = 0.3F;
+					AxisAlignedBB var11 = var9.boundingBox.expand((double)var10, (double)var10, (double)var10);
+					MovingObjectPosition var12 = var11.calculateIntercept(var15, var2);
+					if(var12 != null) {
+						double var13 = var15.distanceTo(var12.hitVec);
+						if(var13 < var6 || var6 == 0.0D) {
+							var4 = var9;
+							var6 = var13;
+						}
 					}
 				}
 			}
-		}
 
-		if(var4 != null) {
-			var3 = new MovingObjectPosition(var4);
+			if(var4 != null) {
+				var3 = new MovingObjectPosition(var4);
+			}
 		}
 
 		if(var3 != null) {
 			if(var3.entityHit != null && var3.entityHit.attackEntityFrom(this.thrower, 0)) {
 			}
 
-			for(var8 = 0; var8 < 8; ++var8) {
+			for(int var8 = 0; var8 < 8; ++var8) {
 				this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
 			}
 
@@ -158,7 +186,7 @@
 		this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F;
 		this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F;
 		float var17 = 0.99F;
-		var10 = 0.03F;
+		float var10 = 0.03F;
 		if(this.handleWaterMovement()) {
 			for(int var18 = 0; var18 < 4; ++var18) {
 				float var19 = 0.25F;
@@ -194,7 +222,7 @@
 	}
 
 	public void onCollideWithPlayer(EntityPlayer var1) {
-		if(this.inGround && this.thrower == var1 && this.throwableShake <= 0 && var1.inventory.addItemStackToInventory(new ItemStack(Item.arrow.shiftedIndex, 1))) {
+		if(this.inGround && this.thrower == var1 && this.throwableShake <= 0 && var1.inventory.addItemStackToInventory(new ItemStack(Item.arrow.shiftedIndex, 1, 0))) {
 			this.worldObj.playSoundAtEntity(this, "random.pop", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F);
 			var1.onItemPickup(this, 1);
 			this.setEntityDead();
--- net/minecraft/src/TileEntity.java
+++ net/minecraft/src/TileEntity.java
@@ -67,7 +67,9 @@
 	}
 
 	public void onInventoryChanged() {
-		this.worldObj.updateTileEntityChunkAndDoNothing(this.xCoord, this.yCoord, this.zCoord, this);
+		if(this.worldObj != null) {
+			this.worldObj.updateTileEntityChunkAndDoNothing(this.xCoord, this.yCoord, this.zCoord, this);
+		}
 	}
 
 	public double getDistanceFrom(double var1, double var3, double var5) {
--- /dev/null
+++ net/minecraft/src/Packet18Animation.java
@@ -1,0 +1,36 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet18Animation extends Packet {
+	public int entityId;
+	public int animate;
+
+	public Packet18Animation() {
+	}
+
+	public Packet18Animation(Entity var1, int var2) {
+		this.entityId = var1.entityID;
+		this.animate = var2;
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.entityId = var1.readInt();
+		this.animate = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.entityId);
+		var1.writeByte(this.animate);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.handleArmAnimation(this);
+	}
+
+	public int getPacketSize() {
+		return 5;
+	}
+}
--- net/minecraft/src/EntityList.java
+++ net/minecraft/src/EntityList.java
@@ -94,8 +94,8 @@
 		addMapping(EntitySlime.class, "Slime", 55);
 		addMapping(EntityPig.class, "Pig", 90);
 		addMapping(EntitySheep.class, "Sheep", 91);
-		addMapping(EntityCow.class, "Cow", 91);
-		addMapping(EntityChicken.class, "Chicken", 91);
+		addMapping(EntityCow.class, "Cow", 92);
+		addMapping(EntityChicken.class, "Chicken", 93);
 		addMapping(EntityTNTPrimed.class, "PrimedTnt", 20);
 		addMapping(EntityFallingSand.class, "FallingSand", 21);
 		addMapping(EntityMinecart.class, "Minecart", 40);
--- net/minecraft/src/RecipeSorter.java
+++ net/minecraft/src/RecipeSorter.java
@@ -9,11 +9,11 @@
 		this.craftingManager = var1;
 	}
 
-	public int compareRecipes(CraftingRecipe var1, CraftingRecipe var2) {
-		return var2.getRecipeSize() < var1.getRecipeSize() ? -1 : (var2.getRecipeSize() > var1.getRecipeSize() ? 1 : 0);
+	public int compareRecipes(IRecipe var1, IRecipe var2) {
+		return var1 instanceof ShapelessRecipes && var2 instanceof ShapedRecipes ? 1 : (var2 instanceof ShapelessRecipes && var1 instanceof ShapedRecipes ? -1 : (var2.getRecipeSize() < var1.getRecipeSize() ? -1 : (var2.getRecipeSize() > var1.getRecipeSize() ? 1 : 0)));
 	}
 
 	public int compare(Object var1, Object var2) {
-		return this.compareRecipes((CraftingRecipe)var1, (CraftingRecipe)var2);
+		return this.compareRecipes((IRecipe)var1, (IRecipe)var2);
 	}
 }
--- net/minecraft/src/GuiContainer.java
+++ net/minecraft/src/GuiContainer.java
@@ -9,7 +9,16 @@
 	private static RenderItem itemRenderer = new RenderItem();
 	protected int xSize = 176;
 	protected int ySize = 166;
-	protected List inventorySlots = new ArrayList();
+	public Container inventorySlots;
+	
+	public GuiContainer(Container var1) {
+		this.inventorySlots = var1;
+	}
+
+	public void initGui() {
+		super.initGui();
+		this.mc.thePlayer.craftingInventory = this.inventorySlots;
+	}
 
 	public void drawScreen(int var1, int var2, float var3) {
 		this.drawDefaultBackground();
@@ -25,10 +34,10 @@
 		GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
 		GL11.glEnable(GL12.GL_RESCALE_NORMAL);
 
-		for(int var6 = 0; var6 < this.inventorySlots.size(); ++var6) {
-			SlotInventory var7 = (SlotInventory)this.inventorySlots.get(var6);
+		for(int var6 = 0; var6 < this.inventorySlots.slots.size(); ++var6) {
+			Slot var7 = (Slot)this.inventorySlots.slots.get(var6);
 			this.drawSlotInventory(var7);
-			if(var7.getIsMouseOverSlot(var1, var2)) {
+			if(this.getIsMouseOverSlot(var7, var1, var2)) {
 				GL11.glDisable(GL11.GL_LIGHTING);
 				GL11.glDisable(GL11.GL_DEPTH_TEST);
 				int var8 = var7.xDisplayPosition;
@@ -40,10 +49,10 @@
 		}
 
 		InventoryPlayer var10 = this.mc.thePlayer.inventory;
-		if(var10.draggedItemStack != null) {
+		if(var10.getItemStack() != null) {
 			GL11.glTranslatef(0.0F, 0.0F, 32.0F);
-			itemRenderer.renderItemIntoGUI(this.fontRenderer, this.mc.renderEngine, var10.draggedItemStack, var1 - var4 - 8, var2 - var5 - 8);
-			itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var10.draggedItemStack, var1 - var4 - 8, var2 - var5 - 8);
+			itemRenderer.renderItemIntoGUI(this.fontRenderer, this.mc.renderEngine, var10.getItemStack(), var1 - var4 - 8, var2 - var5 - 8);
+			itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var10.getItemStack(), var1 - var4 - 8, var2 - var5 - 8);
 		}
 
 		GL11.glDisable(GL12.GL_RESCALE_NORMAL);
@@ -61,12 +70,10 @@
 
 	protected abstract void drawGuiContainerBackgroundLayer(float var1);
 
-	private void drawSlotInventory(SlotInventory var1) {
-		IInventory var2 = var1.inventory;
-		int var3 = var1.slotIndex;
+	private void drawSlotInventory(Slot var1) {
 		int var4 = var1.xDisplayPosition;
 		int var5 = var1.yDisplayPosition;
-		ItemStack var6 = var2.getStackInSlot(var3);
+		ItemStack var6 = var1.getStack();
 		if(var6 == null) {
 			int var7 = var1.getBackgroundIconIndex();
 			if(var7 >= 0) {
@@ -83,9 +90,9 @@
 	}
 
 	private Slot getSlotAtPosition(int var1, int var2) {
-		for(int var3 = 0; var3 < this.inventorySlots.size(); ++var3) {
-			SlotInventory var4 = (SlotInventory)this.inventorySlots.get(var3);
-			if(var4.getIsMouseOverSlot(var1, var2)) {
+		for(int var3 = 0; var3 < this.inventorySlots.slots.size(); ++var3) {
+			Slot var4 = (Slot)this.inventorySlots.slots.get(var3);
+			if(this.getIsMouseOverSlot(var4, var1, var2)) {
 				return var4;
 			}
 		}
@@ -93,107 +100,31 @@
 		return null;
 	}
 
+	private boolean getIsMouseOverSlot(Slot var1, int var2, int var3) {
+		int var4 = (this.width - this.xSize) / 2;
+		int var5 = (this.height - this.ySize) / 2;
+		var2 -= var4;
+		var3 -= var5;
+		return var2 >= var1.xDisplayPosition - 1 && var2 < var1.xDisplayPosition + 16 + 1 && var3 >= var1.yDisplayPosition - 1 && var3 < var1.yDisplayPosition + 16 + 1;
+	}
+
 	protected void mouseClicked(int var1, int var2, int var3) {
 		if(var3 == 0 || var3 == 1) {
 			Slot var4 = this.getSlotAtPosition(var1, var2);
-			InventoryPlayer var5 = this.mc.thePlayer.inventory;
-			int var7;
+			int var5 = (this.width - this.xSize) / 2;
+			int var6 = (this.height - this.ySize) / 2;
+			boolean var7 = var1 < var5 || var2 < var6 || var1 >= var5 + this.xSize || var2 >= var6 + this.ySize;
+			int var8 = -1;
 			if(var4 != null) {
-				ItemStack var6 = var4.getStack();
-				if(var6 != null || var5.draggedItemStack != null) {
-					if(var6 != null && var5.draggedItemStack == null) {
-						var7 = var3 == 0 ? var6.stackSize : (var6.stackSize + 1) / 2;
-						var5.draggedItemStack = var4.inventory.decrStackSize(var4.slotIndex, var7);
-						if(var6.stackSize == 0) {
-							var4.putStack((ItemStack)null);
-						}
-
-						var4.onPickupFromSlot();
-					} else if(var6 == null && var5.draggedItemStack != null && var4.isItemValid(var5.draggedItemStack)) {
-						var7 = var3 == 0 ? var5.draggedItemStack.stackSize : 1;
-						if(var7 > var4.inventory.getInventoryStackLimit()) {
-							var7 = var4.inventory.getInventoryStackLimit();
-						}
-
-						var4.putStack(var5.draggedItemStack.splitStack(var7));
-						if(var5.draggedItemStack.stackSize == 0) {
-							var5.draggedItemStack = null;
-						}
-					} else if(var6 != null && var5.draggedItemStack != null) {
-						if(var4.isItemValid(var5.draggedItemStack)) {
-							if(var6.itemID != var5.draggedItemStack.itemID) {
-								if(var5.draggedItemStack.stackSize <= var4.inventory.getInventoryStackLimit()) {
-									var4.putStack(var5.draggedItemStack);
-									var5.draggedItemStack = var6;
-								}
-							} else if(var6.itemID == var5.draggedItemStack.itemID) {
-								if(var3 == 0) {
-									var7 = var5.draggedItemStack.stackSize;
-									if(var7 > var4.inventory.getInventoryStackLimit() - var6.stackSize) {
-										var7 = var4.inventory.getInventoryStackLimit() - var6.stackSize;
-									}
-
-									if(var7 > var5.draggedItemStack.getMaxStackSize() - var6.stackSize) {
-										var7 = var5.draggedItemStack.getMaxStackSize() - var6.stackSize;
-									}
-
-									var5.draggedItemStack.splitStack(var7);
-									if(var5.draggedItemStack.stackSize == 0) {
-										var5.draggedItemStack = null;
-									}
-
-									var6.stackSize += var7;
-								} else if(var3 == 1) {
-									var7 = 1;
-									if(var7 > var4.inventory.getInventoryStackLimit() - var6.stackSize) {
-										var7 = var4.inventory.getInventoryStackLimit() - var6.stackSize;
-									}
-
-									if(var7 > var5.draggedItemStack.getMaxStackSize() - var6.stackSize) {
-										var7 = var5.draggedItemStack.getMaxStackSize() - var6.stackSize;
-									}
-
-									var5.draggedItemStack.splitStack(var7);
-									if(var5.draggedItemStack.stackSize == 0) {
-										var5.draggedItemStack = null;
-									}
-
-									var6.stackSize += var7;
-								}
-							}
-						} else if(var6.itemID == var5.draggedItemStack.itemID && var5.draggedItemStack.getMaxStackSize() > 1) {
-							var7 = var6.stackSize;
-							if(var7 > 0 && var7 + var5.draggedItemStack.stackSize <= var5.draggedItemStack.getMaxStackSize()) {
-								var5.draggedItemStack.stackSize += var7;
-								var6.splitStack(var7);
-								if(var6.stackSize == 0) {
-									var4.putStack((ItemStack)null);
-								}
-
-								var4.onPickupFromSlot();
-							}
-						}
-					}
-				}
-
-				var4.onSlotChanged();
-			} else if(var5.draggedItemStack != null) {
-				int var9 = (this.width - this.xSize) / 2;
-				var7 = (this.height - this.ySize) / 2;
-				if(var1 < var9 || var2 < var7 || var1 >= var9 + this.xSize || var2 >= var7 + this.xSize) {
-					EntityPlayerSP var8 = this.mc.thePlayer;
-					if(var3 == 0) {
-						var8.dropPlayerItem(var5.draggedItemStack);
-						var5.draggedItemStack = null;
-					}
-
-					if(var3 == 1) {
-						var8.dropPlayerItem(var5.draggedItemStack.splitStack(1));
-						if(var5.draggedItemStack.stackSize == 0) {
-							var5.draggedItemStack = null;
-						}
-					}
-				}
+				var8 = var4.slotNumber;
+			}
+
+			if(var7) {
+				var8 = -999;
+			}
+
+			if(var8 != -1) {
+				this.mc.playerController.func_27174_a(this.inventorySlots.windowId, var8, var3, false, this.mc.thePlayer);
 			}
 		}
 
@@ -207,21 +138,27 @@
 
 	protected void keyTyped(char var1, int var2) {
 		if(var2 == 1 || var2 == this.mc.options.keyBindInventory.keyCode) {
-			this.mc.displayGuiScreen((GuiScreen)null);
+			this.mc.thePlayer.closeScreen();
 		}
 
 	}
 
 	public void onGuiClosed() {
-		InventoryPlayer var1 = this.mc.thePlayer.inventory;
-		if(var1.draggedItemStack != null) {
-			this.mc.thePlayer.dropPlayerItem(var1.draggedItemStack);
-			var1.draggedItemStack = null;
+		if(this.mc.thePlayer != null) {
+			this.mc.playerController.func_20086_a(this.inventorySlots.windowId, this.mc.thePlayer);
 		}
 
 	}
 
 	public boolean doesGuiPauseGame() {
 		return false;
+	}
+	
+	public void updateScreen() {
+		super.updateScreen();
+		if(!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead) {
+			this.mc.thePlayer.closeScreen();
+		}
+
 	}
 }
--- net/minecraft/src/Explosion.java
+++ net/minecraft/src/Explosion.java
@@ -3,126 +3,163 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Random;
+import java.util.Set;
 
 public class Explosion {
-	public void doExplosion(World var1, Entity var2, double var3, double var5, double var7, float var9) {
-		var1.playSoundEffect(var3, var5, var7, "random.explode", 4.0F, (1.0F + (var1.rand.nextFloat() - var1.rand.nextFloat()) * 0.2F) * 0.7F);
-		HashSet var10 = new HashSet();
-		float var11 = var9;
-		byte var12 = 16;
-
-		int var13;
-		int var14;
-		int var15;
-		double var25;
-		double var27;
-		double var29;
-		for(var13 = 0; var13 < var12; ++var13) {
-			for(var14 = 0; var14 < var12; ++var14) {
-				for(var15 = 0; var15 < var12; ++var15) {
-					if(var13 == 0 || var13 == var12 - 1 || var14 == 0 || var14 == var12 - 1 || var15 == 0 || var15 == var12 - 1) {
-						double var16 = (double)((float)var13 / ((float)var12 - 1.0F) * 2.0F - 1.0F);
-						double var18 = (double)((float)var14 / ((float)var12 - 1.0F) * 2.0F - 1.0F);
-						double var20 = (double)((float)var15 / ((float)var12 - 1.0F) * 2.0F - 1.0F);
-						double var22 = Math.sqrt(var16 * var16 + var18 * var18 + var20 * var20);
-						var16 /= var22;
-						var18 /= var22;
-						var20 /= var22;
-						float var24 = var9 * (0.7F + var1.rand.nextFloat() * 0.6F);
-						var25 = var3;
-						var27 = var5;
-						var29 = var7;
-
-						for(float var31 = 0.3F; var24 > 0.0F; var24 -= var31 * (12.0F / 16.0F)) {
-							int var32 = MathHelper.floor_double(var25);
-							int var33 = MathHelper.floor_double(var27);
-							int var34 = MathHelper.floor_double(var29);
-							int var35 = var1.getBlockId(var32, var33, var34);
-							if(var35 > 0) {
-								var24 -= (Block.blocksList[var35].getExplosionResistance(var2) + 0.3F) * var31;
-							}
-
-							if(var24 > 0.0F) {
-								var10.add(new ChunkPosition(var32, var33, var34));
-							}
-
-							var25 += var16 * (double)var31;
-							var27 += var18 * (double)var31;
-							var29 += var20 * (double)var31;
+	public boolean isFlaming = false;
+	private Random ExplosionRNG = new Random();
+	private World worldObj;
+	public double explosionX;
+	public double explosionY;
+	public double explosionZ;
+	public Entity exploder;
+	public float explosionSize;
+	public Set destroyedBlockPositions = new HashSet();
+	
+	public Explosion(World var1, Entity var2, double var3, double var5, double var7, float var9) {
+		this.worldObj = var1;
+		this.exploder = var2;
+		this.explosionSize = var9;
+		this.explosionX = var3;
+		this.explosionY = var5;
+		this.explosionZ = var7;
+	}
+
+	public void doExplosionA() {
+		float var1 = this.explosionSize;
+		byte var2 = 16;
+
+		int var3;
+		int var4;
+		int var5;
+		double var15;
+		double var17;
+		double var19;
+		for(var3 = 0; var3 < var2; ++var3) {
+			for(var4 = 0; var4 < var2; ++var4) {
+				for(var5 = 0; var5 < var2; ++var5) {
+					if(var3 == 0 || var3 == var2 - 1 || var4 == 0 || var4 == var2 - 1 || var5 == 0 || var5 == var2 - 1) {
+						double var6 = (double)((float)var3 / ((float)var2 - 1.0F) * 2.0F - 1.0F);
+						double var8 = (double)((float)var4 / ((float)var2 - 1.0F) * 2.0F - 1.0F);
+						double var10 = (double)((float)var5 / ((float)var2 - 1.0F) * 2.0F - 1.0F);
+						double var12 = Math.sqrt(var6 * var6 + var8 * var8 + var10 * var10);
+						var6 /= var12;
+						var8 /= var12;
+						var10 /= var12;
+						float var14 = this.explosionSize * (0.7F + this.worldObj.rand.nextFloat() * 0.6F);
+						var15 = this.explosionX;
+						var17 = this.explosionY;
+						var19 = this.explosionZ;
+
+						for(float var21 = 0.3F; var14 > 0.0F; var14 -= var21 * (12.0F / 16.0F)) {
+							int var22 = MathHelper.floor_double(var15);
+							int var23 = MathHelper.floor_double(var17);
+							int var24 = MathHelper.floor_double(var19);
+							int var25 = this.worldObj.getBlockId(var22, var23, var24);
+							if(var25 > 0) {
+								var14 -= (Block.blocksList[var25].getExplosionResistance(this.exploder) + 0.3F) * var21;
+							}
+
+							if(var14 > 0.0F) {
+								this.destroyedBlockPositions.add(new ChunkPosition(var22, var23, var24));
+							}
+
+							var15 += var6 * (double)var21;
+							var17 += var8 * (double)var21;
+							var19 += var10 * (double)var21;
 						}
 					}
 				}
 			}
 		}
 
-		var9 *= 2.0F;
-		var13 = MathHelper.floor_double(var3 - (double)var9 - 1.0D);
-		var14 = MathHelper.floor_double(var3 + (double)var9 + 1.0D);
-		var15 = MathHelper.floor_double(var5 - (double)var9 - 1.0D);
-		int var45 = MathHelper.floor_double(var5 + (double)var9 + 1.0D);
-		int var17 = MathHelper.floor_double(var7 - (double)var9 - 1.0D);
-		int var46 = MathHelper.floor_double(var7 + (double)var9 + 1.0D);
-		List var19 = var1.getEntitiesWithinAABBExcludingEntity(var2, AxisAlignedBB.getBoundingBoxFromPool((double)var13, (double)var15, (double)var17, (double)var14, (double)var45, (double)var46));
-		Vec3D var47 = Vec3D.createVector(var3, var5, var7);
-
-		double var55;
-		double var56;
-		double var57;
-		for(int var21 = 0; var21 < var19.size(); ++var21) {
-			Entity var49 = (Entity)var19.get(var21);
-			double var23 = var49.getDistance(var3, var5, var7) / (double)var9;
-			if(var23 <= 1.0D) {
-				var25 = var49.posX - var3;
-				var27 = var49.posY - var5;
-				var29 = var49.posZ - var7;
-				var55 = (double)MathHelper.sqrt_double(var25 * var25 + var27 * var27 + var29 * var29);
-				var25 /= var55;
-				var27 /= var55;
-				var29 /= var55;
-				var56 = (double)var1.getBlockDensity(var47, var49.boundingBox);
-				var57 = (1.0D - var23) * var56;
-				var49.attackEntityFrom(var2, (int)((var57 * var57 + var57) / 2.0D * 8.0D * (double)var9 + 1.0D));
-				var49.motionX += var25 * var57;
-				var49.motionY += var27 * var57;
-				var49.motionZ += var29 * var57;
-			}
-		}
-
-		var9 = var11;
-		ArrayList var48 = new ArrayList();
-		var48.addAll(var10);
-
-		for(int var50 = var48.size() - 1; var50 >= 0; --var50) {
-			ChunkPosition var51 = (ChunkPosition)var48.get(var50);
-			int var52 = var51.x;
-			int var53 = var51.y;
-			int var26 = var51.z;
-			int var54 = var1.getBlockId(var52, var53, var26);
-
-			for(int var28 = 0; var28 < 1; ++var28) {
-				var29 = (double)((float)var52 + var1.rand.nextFloat());
-				var55 = (double)((float)var53 + var1.rand.nextFloat());
-				var56 = (double)((float)var26 + var1.rand.nextFloat());
-				var57 = var29 - var3;
-				double var37 = var55 - var5;
-				double var39 = var56 - var7;
-				double var41 = (double)MathHelper.sqrt_double(var57 * var57 + var37 * var37 + var39 * var39);
-				var57 /= var41;
-				var37 /= var41;
-				var39 /= var41;
-				double var43 = 0.5D / (var41 / (double)var9 + 0.1D);
-				var43 *= (double)(var1.rand.nextFloat() * var1.rand.nextFloat() + 0.3F);
-				var57 *= var43;
-				var37 *= var43;
-				var39 *= var43;
-				var1.spawnParticle("explode", (var29 + var3 * 1.0D) / 2.0D, (var55 + var5 * 1.0D) / 2.0D, (var56 + var7 * 1.0D) / 2.0D, var57, var37, var39);
-				var1.spawnParticle("smoke", var29, var55, var56, var57, var37, var39);
-			}
-
-			if(var54 > 0) {
-				Block.blocksList[var54].dropBlockAsItemWithChance(var1, var52, var53, var26, var1.getBlockMetadata(var52, var53, var26), 0.3F);
-				var1.setBlockWithNotify(var52, var53, var26, 0);
-				Block.blocksList[var54].onBlockDestroyedByExplosion(var1, var52, var53, var26);
+		this.explosionSize *= 2.0F;
+		var3 = MathHelper.floor_double(this.explosionX - (double)this.explosionSize - 1.0D);
+		var4 = MathHelper.floor_double(this.explosionX + (double)this.explosionSize + 1.0D);
+		var5 = MathHelper.floor_double(this.explosionY - (double)this.explosionSize - 1.0D);
+		int var29 = MathHelper.floor_double(this.explosionY + (double)this.explosionSize + 1.0D);
+		int var7 = MathHelper.floor_double(this.explosionZ - (double)this.explosionSize - 1.0D);
+		int var30 = MathHelper.floor_double(this.explosionZ + (double)this.explosionSize + 1.0D);
+		List var9 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this.exploder, AxisAlignedBB.getBoundingBoxFromPool((double)var3, (double)var5, (double)var7, (double)var4, (double)var29, (double)var30));
+		Vec3D var31 = Vec3D.createVector(this.explosionX, this.explosionY, this.explosionZ);
+
+		for(int var11 = 0; var11 < var9.size(); ++var11) {
+			Entity var33 = (Entity)var9.get(var11);
+			double var13 = var33.getDistance(this.explosionX, this.explosionY, this.explosionZ) / (double)this.explosionSize;
+			if(var13 <= 1.0D) {
+				var15 = var33.posX - this.explosionX;
+				var17 = var33.posY - this.explosionY;
+				var19 = var33.posZ - this.explosionZ;
+				double var39 = (double)MathHelper.sqrt_double(var15 * var15 + var17 * var17 + var19 * var19);
+				var15 /= var39;
+				var17 /= var39;
+				var19 /= var39;
+				double var40 = (double)this.worldObj.getBlockDensity(var31, var33.boundingBox);
+				double var41 = (1.0D - var13) * var40;
+				var33.attackEntityFrom(this.exploder, (int)((var41 * var41 + var41) / 2.0D * 8.0D * (double)this.explosionSize + 1.0D));
+				var33.motionX += var15 * var41;
+				var33.motionY += var17 * var41;
+				var33.motionZ += var19 * var41;
+			}
+		}
+
+		this.explosionSize = var1;
+		ArrayList var32 = new ArrayList();
+		var32.addAll(this.destroyedBlockPositions);
+		if(this.isFlaming) {
+			for(int var34 = var32.size() - 1; var34 >= 0; --var34) {
+				ChunkPosition var35 = (ChunkPosition)var32.get(var34);
+				int var36 = var35.x;
+				int var37 = var35.y;
+				int var16 = var35.z;
+				int var38 = this.worldObj.getBlockId(var36, var37, var16);
+				int var18 = this.worldObj.getBlockId(var36, var37 - 1, var16);
+				if(var38 == 0 && Block.opaqueCubeLookup[var18] && this.ExplosionRNG.nextInt(3) == 0) {
+					this.worldObj.setBlockWithNotify(var36, var37, var16, Block.fire.blockID);
+				}
+			}
+		}
+
+	}
+
+	public void doExplosionB(boolean var1) {
+		if (!this.worldObj.multiplayerWorld)
+			this.worldObj.playSoundEffect(this.explosionX, this.explosionY, this.explosionZ, "random.explode", 4.0F, (1.0F + (this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.2F) * 0.7F);
+
+		ArrayList var2 = new ArrayList();
+		var2.addAll(this.destroyedBlockPositions);
+
+		for(int var3 = var2.size() - 1; var3 >= 0; --var3) {
+			ChunkPosition var4 = (ChunkPosition)var2.get(var3);
+			int var5 = var4.x;
+			int var6 = var4.y;
+			int var7 = var4.z;
+			int var8 = this.worldObj.getBlockId(var5, var6, var7);
+			if(var1) {
+				double var9 = (double)((float)var5 + this.worldObj.rand.nextFloat());
+				double var11 = (double)((float)var6 + this.worldObj.rand.nextFloat());
+				double var13 = (double)((float)var7 + this.worldObj.rand.nextFloat());
+				double var15 = var9 - this.explosionX;
+				double var17 = var11 - this.explosionY;
+				double var19 = var13 - this.explosionZ;
+				double var21 = (double)MathHelper.sqrt_double(var15 * var15 + var17 * var17 + var19 * var19);
+				var15 /= var21;
+				var17 /= var21;
+				var19 /= var21;
+				double var23 = 0.5D / (var21 / (double)this.explosionSize + 0.1D);
+				var23 *= (double)(this.worldObj.rand.nextFloat() * this.worldObj.rand.nextFloat() + 0.3F);
+				var15 *= var23;
+				var17 *= var23;
+				var19 *= var23;
+				this.worldObj.spawnParticle("explode", (var9 + this.explosionX * 1.0D) / 2.0D, (var11 + this.explosionY * 1.0D) / 2.0D, (var13 + this.explosionZ * 1.0D) / 2.0D, var15, var17, var19);
+				this.worldObj.spawnParticle("smoke", var9, var11, var13, var15, var17, var19);
+			}
+
+			if(var8 > 0) {
+				Block.blocksList[var8].dropBlockAsItemWithChance(this.worldObj, var5, var6, var7, this.worldObj.getBlockMetadata(var5, var6, var7), 0.3F);
+				this.worldObj.setBlockWithNotify(var5, var6, var7, 0);
+				Block.blocksList[var8].onBlockDestroyedByExplosion(this.worldObj, var5, var6, var7);
 			}
 		}
 
--- /dev/null
+++ net/minecraft/src/Packet71Weather.java
@@ -1,0 +1,40 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet71Weather extends Packet {
+	public int field_27054_a;
+	public int field_27053_b;
+	public int field_27057_c;
+	public int field_27056_d;
+	public int field_27055_e;
+
+	public Packet71Weather() {
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.field_27054_a = var1.readInt();
+		this.field_27055_e = var1.readByte();
+		this.field_27053_b = var1.readInt();
+		this.field_27057_c = var1.readInt();
+		this.field_27056_d = var1.readInt();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.field_27054_a);
+		var1.writeByte(this.field_27055_e);
+		var1.writeInt(this.field_27053_b);
+		var1.writeInt(this.field_27057_c);
+		var1.writeInt(this.field_27056_d);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.handleWeather(this);
+	}
+
+	public int getPacketSize() {
+		return 17;
+	}
+}
--- net/minecraft/src/BlockChest.java
+++ net/minecraft/src/BlockChest.java
@@ -143,7 +143,7 @@
 					}
 
 					var7.stackSize -= var11;
-					EntityItem var12 = new EntityItem(var1, (double)((float)var2 + var8), (double)((float)var3 + var9), (double)((float)var4 + var10), new ItemStack(var7.itemID, var11, var7.itemDmg));
+					EntityItem var12 = new EntityItem(var1, (double)((float)var2 + var8), (double)((float)var3 + var9), (double)((float)var4 + var10), new ItemStack(var7.itemID, var11, var7.getItemDamage()));
 					float var13 = 0.05F;
 					var12.motionX = (double)((float)this.random.nextGaussian() * var13);
 					var12.motionY = (double)((float)this.random.nextGaussian() * var13 + 0.2F);
@@ -185,6 +185,10 @@
 				var6 = new InventoryLargeChest("Large chest", (IInventory)var6, (TileEntityChest)var1.getBlockTileEntity(var2, var3, var4 + 1));
 			}
 
+
+			if (var1.multiplayerWorld)
+				return true;
+			
 			var5.displayGUIChest((IInventory)var6);
 			return true;
 		}
--- /dev/null
+++ net/minecraft/src/Packet131MapData.java
@@ -1,0 +1,37 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet131MapData extends Packet {
+	public short field_28055_a;
+	public short field_28054_b;
+	public byte[] field_28056_c;
+
+	public Packet131MapData() {
+		this.isChunkDataPacket = true;
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.field_28055_a = var1.readShort();
+		this.field_28054_b = var1.readShort();
+		this.field_28056_c = new byte[var1.readByte() & 255];
+		var1.readFully(this.field_28056_c);
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeShort(this.field_28055_a);
+		var1.writeShort(this.field_28054_b);
+		var1.writeByte(this.field_28056_c.length);
+		var1.write(this.field_28056_c);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_28116_a(this);
+	}
+
+	public int getPacketSize() {
+		return 4 + this.field_28056_c.length;
+	}
+}
--- net/minecraft/src/Packet18ArmAnimation.java
+++ /dev/null
@@ -1,36 +1,0 @@
-package net.minecraft.src;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-public class Packet18ArmAnimation extends Packet {
-	public int entityId;
-	public int animate;
-
-	public Packet18ArmAnimation() {
-	}
-
-	public Packet18ArmAnimation(Entity var1, int var2) {
-		this.entityId = var1.entityID;
-		this.animate = var2;
-	}
-
-	public void readPacketData(DataInputStream var1) throws IOException {
-		this.entityId = var1.readInt();
-		this.animate = var1.readByte();
-	}
-
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeInt(this.entityId);
-		var1.writeByte(this.animate);
-	}
-
-	public void processPacket(NetHandler var1) {
-		var1.handleArmAnimation(this);
-	}
-
-	public int getPacketSize() {
-		return 5;
-	}
-}
--- net/minecraft/src/EntityFX.java
+++ net/minecraft/src/EntityFX.java
@@ -50,6 +50,9 @@
 		return this;
 	}
 
+	protected void entityInit() {
+	}
+
 	public void onUpdate() {
 		this.prevPosX = this.posX;
 		this.prevPosY = this.posY;
--- net/minecraft/src/WorldClient.java
+++ net/minecraft/src/WorldClient.java
@@ -130,7 +130,13 @@
 	}
 
 	public void addEntityToWorld(int var1, Entity var2) {
+		Entity var3 = this.getEntityByID(var1);
+		if(var3 != null) {
+			this.setEntityDead(var3);
+		}
+		
 		this.entityList.add(var2);
+		var2.entityID = var1;
 		if(!this.spawnEntityInWorld(var2)) {
 			this.entitySpawnQueue.add(var2);
 		}
@@ -202,6 +208,6 @@
 	}
 
 	public void sendQuittingDisconnectingPacket() {
-		this.sendQueue.addToSendQueue(new Packet255KickDisconnect("Quitting"));
+		this.sendQueue.func_28117_a(new Packet255KickDisconnect("Quitting"));
 	}
 }
--- net/minecraft/src/EntityOtherPlayerMP.java
+++ net/minecraft/src/EntityOtherPlayerMP.java
@@ -95,4 +95,18 @@
 		this.cameraYaw += (var9 - this.cameraYaw) * 0.4F;
 		this.cameraPitch += (var2 - this.cameraPitch) * 0.8F;
 	}
+
+	public void outfitWithItem(int var1, int var2, int var3) {
+		ItemStack var4 = null;
+		if(var2 >= 0) {
+			var4 = new ItemStack(var2, 1, var3);
+		}
+
+		if(var1 == 0) {
+			this.inventory.mainInventory[this.inventory.currentItem] = var4;
+		} else {
+			this.inventory.armorInventory[var1 - 1] = var4;
+		}
+
+	}
 }
--- net/minecraft/src/EntityDiggingFX.java
+++ net/minecraft/src/EntityDiggingFX.java
@@ -1,9 +1,9 @@
 package net.minecraft.src;
 
 public class EntityDiggingFX extends EntityFX {
-	public EntityDiggingFX(World var1, double var2, double var4, double var6, double var8, double var10, double var12, Block var14) {
+	public EntityDiggingFX(World var1, double var2, double var4, double var6, double var8, double var10, double var12, Block var14, int metadata) {
 		super(var1, var2, var4, var6, var8, var10, var12);
-		this.particleTextureIndex = var14.blockIndexInTexture;
+		this.particleTextureIndex = var14.getBlockTextureFromSideAndMetadata(2, metadata);
 		this.particleGravity = var14.blockParticleGravity;
 		this.particleRed = this.particleGreen = this.particleBlue = 0.6F;
 		this.particleScale /= 2.0F;
--- /dev/null
+++ net/minecraft/src/Packet106Transaction.java
@@ -1,0 +1,40 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet106Transaction extends Packet {
+	public int windowId;
+	public short field_20028_b;
+	public boolean field_20030_c;
+
+	public Packet106Transaction() {
+	}
+
+	public Packet106Transaction(int var1, short var2, boolean var3) {
+		this.windowId = var1;
+		this.field_20028_b = var2;
+		this.field_20030_c = var3;
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_20089_a(this);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.windowId = var1.readByte();
+		this.field_20028_b = var1.readShort();
+		this.field_20030_c = var1.readByte() != 0;
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.windowId);
+		var1.writeShort(this.field_20028_b);
+		var1.writeByte(this.field_20030_c ? 1 : 0);
+	}
+
+	public int getPacketSize() {
+		return 4;
+	}
+}
--- net/minecraft/src/PlayerControllerSP.java
+++ net/minecraft/src/PlayerControllerSP.java
@@ -28,9 +28,9 @@
 		ItemStack var8 = this.mc.thePlayer.getCurrentEquippedItem();
 		boolean var9 = this.mc.thePlayer.canHarvestBlock(Block.blocksList[var5]);
 		if(var8 != null) {
-			var8.onDestroyBlock(var5, var1, var2, var3);
+			var8.onDestroyBlock(var5, var1, var2, var3, this.mc.thePlayer);
 			if(var8.stackSize == 0) {
-				var8.onItemDestroyedByUse(this.mc.thePlayer);
+				var8.func_1097_a(this.mc.thePlayer);
 				this.mc.thePlayer.destroyCurrentEquippedItem();
 			}
 		}
@@ -43,6 +43,7 @@
 	}
 
 	public void clickBlock(int var1, int var2, int var3, int var4) {
+		this.mc.theWorld.extinguishFire(this.mc.thePlayer, var1, var2, var3, var4);
 		int var5 = this.mc.theWorld.getBlockId(var1, var2, var3);
 		if(var5 > 0 && this.curBlockDamage == 0.0F) {
 			Block.blocksList[var5].onBlockClicked(this.mc.theWorld, var1, var2, var3, this.mc.thePlayer);
@@ -72,7 +73,7 @@
 				Block var6 = Block.blocksList[var5];
 				this.curBlockDamage += var6.blockStrength(this.mc.thePlayer);
 				if(this.blockDestroySoundCounter % 4.0F == 0.0F && var6 != null) {
-					this.mc.sndManager.playSound(var6.stepSound.getStepSound(), (float)var1 + 0.5F, (float)var2 + 0.5F, (float)var3 + 0.5F, (var6.stepSound.getVolume() + 1.0F) / 8.0F, var6.stepSound.getPitch() * 0.5F);
+					this.mc.sndManager.playSound(var6.stepSound.getBreakSound(), (float)var1 + 0.5F, (float)var2 + 0.5F, (float)var3 + 0.5F, (var6.stepSound.getVolume() + 1.0F) / 8.0F, var6.stepSound.getPitch() * 0.5F);
 				}
 
 				++this.blockDestroySoundCounter;
@@ -98,11 +99,11 @@
 	public void setPartialTime(float var1) {
 		if(this.curBlockDamage <= 0.0F) {
 			this.mc.ingameGUI.damageGuiPartialTime = 0.0F;
-			this.mc.renderGlobal.damagePartialTime = 0.0F;
+			//this.mc.renderGlobal.damagePartialTime = 0.0F;
 		} else {
 			float var2 = this.prevBlockDamage + (this.curBlockDamage - this.prevBlockDamage) * var1;
 			this.mc.ingameGUI.damageGuiPartialTime = var2;
-			this.mc.renderGlobal.damagePartialTime = var2;
+			//this.mc.renderGlobal.damagePartialTime = var2;
 		}
 
 	}
--- net/minecraft/src/TileEntityMobSpawner.java
+++ net/minecraft/src/TileEntityMobSpawner.java
@@ -26,52 +26,55 @@
 			for(this.yaw += (double)(1000.0F / ((float)this.delay + 200.0F)); this.yaw > 360.0D; this.prevYaw -= 360.0D) {
 				this.yaw -= 360.0D;
 			}
-
-			if(this.delay == -1) {
-				this.updateDelay();
-			}
-
-			if(this.delay > 0) {
-				--this.delay;
-			} else {
-				byte var7 = 4;
-
-				for(int var8 = 0; var8 < var7; ++var8) {
-					EntityLiving var9 = (EntityLiving)((EntityLiving)EntityList.createEntityByName(this.mobID, this.worldObj));
-					if(var9 == null) {
-						return;
-					}
-
-					int var10 = this.worldObj.getEntitiesWithinAABB(var9.getClass(), AxisAlignedBB.getBoundingBoxFromPool((double)this.xCoord, (double)this.yCoord, (double)this.zCoord, (double)(this.xCoord + 1), (double)(this.yCoord + 1), (double)(this.zCoord + 1)).expand(8.0D, 4.0D, 8.0D)).size();
-					if(var10 >= 6) {
-						this.updateDelay();
-						return;
-					}
-
-					if(var9 != null) {
-						double var11 = (double)this.xCoord + (this.worldObj.rand.nextDouble() - this.worldObj.rand.nextDouble()) * 4.0D;
-						double var13 = (double)(this.yCoord + this.worldObj.rand.nextInt(3) - 1);
-						double var15 = (double)this.zCoord + (this.worldObj.rand.nextDouble() - this.worldObj.rand.nextDouble()) * 4.0D;
-						var9.setLocationAndAngles(var11, var13, var15, this.worldObj.rand.nextFloat() * 360.0F, 0.0F);
-						if(var9.getCanSpawnHere()) {
-							this.worldObj.spawnEntityInWorld(var9);
-
-							for(int var17 = 0; var17 < 20; ++var17) {
-								var1 = (double)this.xCoord + 0.5D + ((double)this.worldObj.rand.nextFloat() - 0.5D) * 2.0D;
-								var3 = (double)this.yCoord + 0.5D + ((double)this.worldObj.rand.nextFloat() - 0.5D) * 2.0D;
-								var5 = (double)this.zCoord + 0.5D + ((double)this.worldObj.rand.nextFloat() - 0.5D) * 2.0D;
-								this.worldObj.spawnParticle("smoke", var1, var3, var5, 0.0D, 0.0D, 0.0D);
-								this.worldObj.spawnParticle("flame", var1, var3, var5, 0.0D, 0.0D, 0.0D);
-							}
-
-							var9.spawnExplosionParticle();
+			
+
+			if(!this.worldObj.multiplayerWorld) {
+				if(this.delay == -1) {
+					this.updateDelay();
+				}
+
+				if(this.delay > 0) {
+					--this.delay;
+				} else {
+					byte var7 = 4;
+
+					for(int var8 = 0; var8 < var7; ++var8) {
+						EntityLiving var9 = (EntityLiving)((EntityLiving)EntityList.createEntityByName(this.mobID, this.worldObj));
+						if(var9 == null) {
+							return;
+						}
+
+						int var10 = this.worldObj.getEntitiesWithinAABB(var9.getClass(), AxisAlignedBB.getBoundingBoxFromPool((double)this.xCoord, (double)this.yCoord, (double)this.zCoord, (double)(this.xCoord + 1), (double)(this.yCoord + 1), (double)(this.zCoord + 1)).expand(8.0D, 4.0D, 8.0D)).size();
+						if(var10 >= 6) {
 							this.updateDelay();
+							return;
+						}
+
+						if(var9 != null) {
+							double var11 = (double)this.xCoord + (this.worldObj.rand.nextDouble() - this.worldObj.rand.nextDouble()) * 4.0D;
+							double var13 = (double)(this.yCoord + this.worldObj.rand.nextInt(3) - 1);
+							double var15 = (double)this.zCoord + (this.worldObj.rand.nextDouble() - this.worldObj.rand.nextDouble()) * 4.0D;
+							var9.setLocationAndAngles(var11, var13, var15, this.worldObj.rand.nextFloat() * 360.0F, 0.0F);
+							if(var9.getCanSpawnHere()) {
+								this.worldObj.spawnEntityInWorld(var9);
+
+								for(int var17 = 0; var17 < 20; ++var17) {
+									var1 = (double)this.xCoord + 0.5D + ((double)this.worldObj.rand.nextFloat() - 0.5D) * 2.0D;
+									var3 = (double)this.yCoord + 0.5D + ((double)this.worldObj.rand.nextFloat() - 0.5D) * 2.0D;
+									var5 = (double)this.zCoord + 0.5D + ((double)this.worldObj.rand.nextFloat() - 0.5D) * 2.0D;
+									this.worldObj.spawnParticle("smoke", var1, var3, var5, 0.0D, 0.0D, 0.0D);
+									this.worldObj.spawnParticle("flame", var1, var3, var5, 0.0D, 0.0D, 0.0D);
+								}
+
+								var9.spawnExplosionParticle();
+								this.updateDelay();
+							}
 						}
 					}
 				}
-
-				super.updateEntity();
 			}
+
+			super.updateEntity();
 		}
 	}
 
--- /dev/null
+++ net/minecraft/src/Packet101CloseWindow.java
@@ -1,0 +1,32 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet101CloseWindow extends Packet {
+	public int windowId;
+
+	public Packet101CloseWindow() {
+	}
+
+	public Packet101CloseWindow(int var1) {
+		this.windowId = var1;
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_20092_a(this);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.windowId = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.windowId);
+	}
+
+	public int getPacketSize() {
+		return 1;
+	}
+}
--- net/minecraft/src/ItemRecord.java
+++ net/minecraft/src/ItemRecord.java
@@ -1,7 +1,7 @@
 package net.minecraft.src;
 
 public class ItemRecord extends Item {
-	private String recordName;
+	public final String recordName;
 
 	protected ItemRecord(int var1, String var2) {
 		super(var1);
@@ -11,6 +11,9 @@
 
 	public boolean onItemUse(ItemStack var1, EntityPlayer var2, World var3, int var4, int var5, int var6, int var7) {
 		if(var3.getBlockId(var4, var5, var6) == Block.jukebox.blockID && var3.getBlockMetadata(var4, var5, var6) == 0) {
+			if(var3.multiplayerWorld)
+				return true;
+
 			var3.setBlockMetadataWithNotify(var4, var5, var6, this.shiftedIndex - Item.record13.shiftedIndex + 1);
 			var3.playRecord(this.recordName, var4, var5, var6);
 			--var1.stackSize;
--- net/minecraft/src/AxisAlignedBB.java
+++ net/minecraft/src/AxisAlignedBB.java
@@ -191,11 +191,29 @@
 		return this;
 	}
 
+	public boolean contains(Vec3D vec) {
+		if (vec.xCoord <= this.minX || vec.xCoord >= this.maxX) {
+			return false;
+		} else {
+			return vec.yCoord <= this.minY || vec.yCoord >= this.maxY ? false : !(vec.zCoord <= this.minZ) && !(vec.zCoord >= this.maxZ);
+		}
+	}
+
 	public double getAverageEdgeLength() {
 		double var1 = this.maxX - this.minX;
 		double var3 = this.maxY - this.minY;
 		double var5 = this.maxZ - this.minZ;
 		return (var1 + var3 + var5) / 3.0D;
+	}
+
+	public AxisAlignedBB contract(double dx, double dy, double dz) {
+		double d = this.minX + dx;
+		double e = this.minY + dy;
+		double f = this.minZ + dz;
+		double g = this.maxX - dx;
+		double h = this.maxY - dy;
+		double i = this.maxZ - dz;
+		return getBoundingBoxFromPool(d, e, f, g, h, i);
 	}
 
 	public AxisAlignedBB copy() {
--- /dev/null
+++ net/minecraft/src/ContainerWorkbench.java
@@ -1,0 +1,91 @@
+package net.minecraft.src;
+
+public class ContainerWorkbench extends Container {
+	public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3);
+	public IInventory craftResult = new InventoryCraftResult();
+	private World field_20133_c;
+	private int field_20132_h;
+	private int field_20131_i;
+	private int field_20130_j;
+
+	public ContainerWorkbench(InventoryPlayer var1, World var2, int var3, int var4, int var5) {
+		this.field_20133_c = var2;
+		this.field_20132_h = var3;
+		this.field_20131_i = var4;
+		this.field_20130_j = var5;
+		this.addSlot(new SlotCrafting(var1.player, this.craftMatrix, this.craftResult, 0, 124, 35));
+
+		int var6;
+		int var7;
+		for(var6 = 0; var6 < 3; ++var6) {
+			for(var7 = 0; var7 < 3; ++var7) {
+				this.addSlot(new Slot(this.craftMatrix, var7 + var6 * 3, 30 + var7 * 18, 17 + var6 * 18));
+			}
+		}
+
+		for(var6 = 0; var6 < 3; ++var6) {
+			for(var7 = 0; var7 < 9; ++var7) {
+				this.addSlot(new Slot(var1, var7 + var6 * 9 + 9, 8 + var7 * 18, 84 + var6 * 18));
+			}
+		}
+
+		for(var6 = 0; var6 < 9; ++var6) {
+			this.addSlot(new Slot(var1, var6, 8 + var6 * 18, 142));
+		}
+
+		this.onCraftMatrixChanged(this.craftMatrix);
+	}
+
+	public void onCraftMatrixChanged(IInventory var1) {
+		this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix));
+	}
+
+	public void onCraftGuiClosed(EntityPlayer var1) {
+		super.onCraftGuiClosed(var1);
+		if(!this.field_20133_c.multiplayerWorld) {
+			for(int var2 = 0; var2 < 9; ++var2) {
+				ItemStack var3 = this.craftMatrix.getStackInSlot(var2);
+				if(var3 != null) {
+					var1.dropPlayerItem(var3);
+				}
+			}
+
+		}
+	}
+
+	public boolean isUsableByPlayer(EntityPlayer var1) {
+		return this.field_20133_c.getBlockId(this.field_20132_h, this.field_20131_i, this.field_20130_j) != Block.workbench.blockID ? false : var1.getDistanceSq((double)this.field_20132_h + 0.5D, (double)this.field_20131_i + 0.5D, (double)this.field_20130_j + 0.5D) <= 64.0D;
+	}
+
+	public ItemStack getStackInSlot(int var1) {
+		ItemStack var2 = null;
+		Slot var3 = (Slot)this.slots.get(var1);
+		if(var3 != null && var3.getHasStack()) {
+			ItemStack var4 = var3.getStack();
+			var2 = var4.copy();
+			if(var1 == 0) {
+				this.func_28125_a(var4, 10, 46, true);
+			} else if(var1 >= 10 && var1 < 37) {
+				this.func_28125_a(var4, 37, 46, false);
+			} else if(var1 >= 37 && var1 < 46) {
+				this.func_28125_a(var4, 10, 37, false);
+			} else {
+				this.func_28125_a(var4, 10, 46, false);
+			}
+
+			if(var4.stackSize == 0) {
+				var3.putStack((ItemStack)null);
+			} else {
+				var3.onSlotChanged();
+			}
+
+			if(var4.stackSize == var2.stackSize) {
+				return null;
+			}
+
+			var3.onPickupFromSlot(var4);
+		}
+
+		return var2;
+	}
+}
--- net/minecraft/src/Packet34EntityTeleport.java
+++ net/minecraft/src/Packet34EntityTeleport.java
@@ -33,7 +33,7 @@
 		this.pitch = (byte)var1.read();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.entityId);
 		var1.writeInt(this.xPosition);
 		var1.writeInt(this.yPosition);
--- /dev/null
+++ net/minecraft/src/ContainerPlayer.java
@@ -1,0 +1,96 @@
+package net.minecraft.src;
+
+public class ContainerPlayer extends Container {
+	public InventoryCrafting craftMatrix;
+	public IInventory craftResult;
+	public boolean isSinglePlayer;
+
+	public ContainerPlayer(InventoryPlayer var1) {
+		this(var1, true);
+	}
+
+	public ContainerPlayer(InventoryPlayer var1, boolean var2) {
+		this.craftMatrix = new InventoryCrafting(this, 2, 2);
+		this.craftResult = new InventoryCraftResult();
+		this.isSinglePlayer = false;
+		this.isSinglePlayer = var2;
+		this.addSlot(new SlotCrafting(var1.player, this.craftMatrix, this.craftResult, 0, 144, 36));
+
+		int var3;
+		int var4;
+		for(var3 = 0; var3 < 2; ++var3) {
+			for(var4 = 0; var4 < 2; ++var4) {
+				this.addSlot(new Slot(this.craftMatrix, var4 + var3 * 2, 88 + var4 * 18, 26 + var3 * 18));
+			}
+		}
+
+		for(var3 = 0; var3 < 4; ++var3) {
+			this.addSlot(new SlotArmor(this, var1, var1.getSizeInventory() - 1 - var3, 8, 8 + var3 * 18, var3));
+		}
+
+		for(var3 = 0; var3 < 3; ++var3) {
+			for(var4 = 0; var4 < 9; ++var4) {
+				this.addSlot(new Slot(var1, var4 + (var3 + 1) * 9, 8 + var4 * 18, 84 + var3 * 18));
+			}
+		}
+
+		for(var3 = 0; var3 < 9; ++var3) {
+			this.addSlot(new Slot(var1, var3, 8 + var3 * 18, 142));
+		}
+
+		this.onCraftMatrixChanged(this.craftMatrix);
+	}
+
+	public void onCraftMatrixChanged(IInventory var1) {
+		this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix));
+	}
+
+	public void onCraftGuiClosed(EntityPlayer var1) {
+		super.onCraftGuiClosed(var1);
+
+		for(int var2 = 0; var2 < 4; ++var2) {
+			ItemStack var3 = this.craftMatrix.getStackInSlot(var2);
+			if(var3 != null) {
+				var1.dropPlayerItem(var3);
+				this.craftMatrix.setInventorySlotContents(var2, (ItemStack)null);
+			}
+		}
+
+	}
+
+	public boolean isUsableByPlayer(EntityPlayer var1) {
+		return true;
+	}
+
+	public ItemStack getStackInSlot(int var1) {
+		ItemStack var2 = null;
+		Slot var3 = (Slot)this.slots.get(var1);
+		if(var3 != null && var3.getHasStack()) {
+			ItemStack var4 = var3.getStack();
+			var2 = var4.copy();
+			if(var1 == 0) {
+				this.func_28125_a(var4, 9, 45, true);
+			} else if(var1 >= 9 && var1 < 36) {
+				this.func_28125_a(var4, 36, 45, false);
+			} else if(var1 >= 36 && var1 < 45) {
+				this.func_28125_a(var4, 9, 36, false);
+			} else {
+				this.func_28125_a(var4, 9, 45, false);
+			}
+
+			if(var4.stackSize == 0) {
+				var3.putStack((ItemStack)null);
+			} else {
+				var3.onSlotChanged();
+			}
+
+			if(var4.stackSize == var2.stackSize) {
+				return null;
+			}
+
+			var3.onPickupFromSlot(var4);
+		}
+
+		return var2;
+	}
+}
--- net/minecraft/src/Packet6SpawnPosition.java
+++ net/minecraft/src/Packet6SpawnPosition.java
@@ -15,7 +15,7 @@
 		this.zPosition = var1.readInt();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.xPosition);
 		var1.writeInt(this.yPosition);
 		var1.writeInt(this.zPosition);
--- net/minecraft/src/Packet12PlayerLook.java
+++ net/minecraft/src/Packet12PlayerLook.java
@@ -22,10 +22,10 @@
 		super.readPacketData(var1);
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeFloat(this.yaw);
 		var1.writeFloat(this.pitch);
-		super.writePacket(var1);
+		super.writePacketData(var1);
 	}
 
 	public int getPacketSize() {
--- net/minecraft/client/Minecraft.java
+++ net/minecraft/client/Minecraft.java
@@ -8,6 +8,16 @@
 import java.awt.Frame;
 import java.awt.Graphics;
 import java.io.File;
+
+import org.lwjgl.LWJGLException;
+import org.lwjgl.input.Controllers;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.DisplayMode;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.util.glu.GLU;
+
 import net.minecraft.src.AxisAlignedBB;
 import net.minecraft.src.Block;
 import net.minecraft.src.EffectRenderer;
@@ -28,6 +38,7 @@
 import net.minecraft.src.GuiInventory;
 import net.minecraft.src.GuiMainMenu;
 import net.minecraft.src.GuiScreen;
+import net.minecraft.src.ItemBlock;
 import net.minecraft.src.ItemRenderer;
 import net.minecraft.src.ItemStack;
 import net.minecraft.src.LoadingScreenRenderer;
@@ -63,14 +74,6 @@
 import net.minecraft.src.Vec3D;
 import net.minecraft.src.World;
 import net.minecraft.src.WorldRenderer;
-import org.lwjgl.LWJGLException;
-import org.lwjgl.input.Controllers;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.input.Mouse;
-import org.lwjgl.opengl.Display;
-import org.lwjgl.opengl.DisplayMode;
-import org.lwjgl.opengl.GL11;
-import org.lwjgl.util.glu.GLU;
 
 public abstract class Minecraft implements Runnable {
 	public PlayerController playerController;
@@ -346,6 +349,10 @@
 				var1 = new GuiGameOver();
 			}
 
+			if(var1 instanceof GuiMainMenu) {
+				this.ingameGUI.clearChatMessages();
+			}
+
 			this.currentScreen = (GuiScreen)var1;
 			if(var1 != null) {
 				this.setIngameNotInFocus();
@@ -608,13 +615,18 @@
 	}
 
 	private void sendClickBlockToController(int var1, boolean var2) {
+		if (!var2) {
+			this.leftClickCounter = 0;
+		}
+		
 		if(!this.playerController.isInTestMode) {
 			if(var1 != 0 || this.leftClickCounter <= 0) {
 				if(var2 && this.objectMouseOver != null && this.objectMouseOver.typeOfHit == 0 && var1 == 0) {
 					int var3 = this.objectMouseOver.blockX;
 					int var4 = this.objectMouseOver.blockY;
 					int var5 = this.objectMouseOver.blockZ;
-					this.playerController.sendBlockRemoving(var3, var4, var5, this.objectMouseOver.sideHit);
+		            this.playerController.clickBlock(var3, var4, var5, this.objectMouseOver.sideHit);
+					//this.playerController.sendBlockRemoving(var3, var4, var5, this.objectMouseOver.sideHit);
 					this.effectRenderer.addBlockHitEffects(var3, var4, var5, this.objectMouseOver.sideHit);
 				} else {
 					this.playerController.resetBlockRemoving();
@@ -630,35 +642,42 @@
 				this.thePlayer.swingItem();
 			}
 
-			int var3;
+			boolean send = true;
 			if(this.objectMouseOver == null) {
 				if(var1 == 0 && !(this.playerController instanceof PlayerControllerCreative)) {
 					this.leftClickCounter = 10;
 				}
 			} else if(this.objectMouseOver.typeOfHit == 1) {
 				if(var1 == 0) {
-					this.thePlayer.attackEntity(this.objectMouseOver.entityHit);
+					this.playerController.attackEntity(this.thePlayer, this.objectMouseOver.entityHit);
 				}
 
 				if(var1 == 1) {
-					this.thePlayer.interactWithEntity(this.objectMouseOver.entityHit);
+					this.playerController.interactWithEntity(this.thePlayer, this.objectMouseOver.entityHit);
 				}
 			} else if(this.objectMouseOver.typeOfHit == 0) {
 				int var2 = this.objectMouseOver.blockX;
-				var3 = this.objectMouseOver.blockY;
+				int var3 = this.objectMouseOver.blockY;
 				int var4 = this.objectMouseOver.blockZ;
 				int var5 = this.objectMouseOver.sideHit;
-				Block var6 = Block.blocksList[this.theWorld.getBlockId(var2, var3, var4)];
+
+				Block var6 = Block.blocksList[this.theWorld.getBlockId(var3, var4, var5)];
 				if(var1 == 0) {
-					this.theWorld.extinguishFire(var2, var3, var4, this.objectMouseOver.sideHit);
+					this.theWorld.extinguishFire(this.thePlayer, var2, var3, var4, this.objectMouseOver.sideHit);
 					if(var6 != Block.bedrock || this.thePlayer.unusedMiningCooldown >= 100) {
-						this.playerController.clickBlock(var2, var3, var4, this.objectMouseOver.sideHit);
+						this.playerController.sendBlockRemoving(var2, var3, var4, this.objectMouseOver.sideHit);
 					}
+					
 				} else {
 					ItemStack var7 = this.thePlayer.inventory.getCurrentItem();
 					int var8 = var7 != null ? var7.stackSize : 0;
-					if(this.playerController.onPlayerRightClick(this.thePlayer, this.theWorld, var7, var2, var3, var4, var5)) {
-						this.thePlayer.swingItem();
+					
+					if(this.playerController.sendPlaceBlock(this.thePlayer, this.theWorld, var7, var2, var3, var4, var5)) {
+						send = false;
+					}
+					
+					if (!send || var7 != null && var7.getItem() instanceof ItemBlock) {
+						this.thePlayer.swingItem(); // TODO: swing
 					}
 
 					if(var7 == null) {
@@ -673,18 +692,10 @@
 				}
 			}
 
-			if(var1 == 1) {
+			if(send && var1 == 1) {
 				ItemStack var9 = this.thePlayer.inventory.getCurrentItem();
-				if(var9 != null) {
-					var3 = var9.stackSize;
-					ItemStack var10 = var9.useItemRightClick(this.theWorld, this.thePlayer);
-					if(var10 != var9 || var10 != null && var10.stackSize != var3) {
-						this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.currentItem] = var10;
-						this.entityRenderer.itemRenderer.resetEquippedProgress2();
-						if(var10.stackSize == 0) {
-							this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.currentItem] = null;
-						}
-					}
+				if(var9 != null && this.playerController.sendUseItem(this.thePlayer, this.theWorld, var9)) {
+					this.entityRenderer.itemRenderer.resetEquippedProgress2();
 				}
 			}
 
@@ -789,9 +800,9 @@
 	public void runTick() {
 		this.ingameGUI.updateTick();
 		this.entityRenderer.getMouseOver(1.0F);
-		if(this.thePlayer != null) {
-			this.thePlayer.onPlayerUpdate();
-		}
+//		if(this.thePlayer != null) {
+//			this.thePlayer.onUpdate();
+//		}
 
 		if(!this.isGamePaused && this.theWorld != null) {
 			this.playerController.onUpdate();
@@ -869,13 +880,18 @@
 												if(Keyboard.getEventKey() == Keyboard.KEY_F5) {
 													this.options.thirdPersonView = !this.options.thirdPersonView;
 												}
+												
+												if(Keyboard.getEventKey() == Keyboard.KEY_J) {
+													this.options.accept62 = !this.options.accept62;
+													System.out.println("TOGGLED 62! " + this.options.accept62);
+												}
 
 												if(Keyboard.getEventKey() == this.options.keyBindInventory.keyCode) {
-													this.displayGuiScreen(new GuiInventory(this.thePlayer.inventory, this.thePlayer.inventory.craftingInventory));
+													this.displayGuiScreen(new GuiInventory(this.thePlayer));
 												}
 
 												if(Keyboard.getEventKey() == this.options.keyBindDrop.keyCode) {
-													this.thePlayer.dropPlayerItemWithRandomChoice(this.thePlayer.inventory.decrStackSize(this.thePlayer.inventory.currentItem, 1), false);
+													this.thePlayer.dropCurrentItem();
 												}
 
 												if(this.isMultiplayerWorld() && Keyboard.getEventKey() == this.options.keyBindChat.keyCode) {
@@ -1113,7 +1129,9 @@
 
 	public void respawn() {
 		this.theWorld.setSpawnLocation();
+		int var8 = 0;
 		if(this.thePlayer != null) {
+			var8 = this.thePlayer.entityID;
 			this.theWorld.setEntityDead(this.thePlayer);
 		}
 
@@ -1122,8 +1140,12 @@
 		this.playerController.flipPlayer(this.thePlayer);
 		this.theWorld.spawnPlayerWithLoadedChunks(this.thePlayer);
 		this.thePlayer.movementInput = new MovementInputFromOptions(this.options);
+		this.thePlayer.entityID = var8;
 		this.playerController.onRespawn(this.thePlayer);
 		this.preloadWorld("Respawning");
+		if(this.currentScreen instanceof GuiGameOver) {
+			this.displayGuiScreen((GuiScreen)null);
+		}
 	}
 
 	public static void startMainThread(String var0, String var1) {
--- /dev/null
+++ net/minecraft/src/Packet55BlockBreakAnimation.java
@@ -1,0 +1,72 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet55BlockBreakAnimation extends Packet {
+   private int id;
+   private int x;
+   private int y;
+   private int z;
+   private int progress;
+
+   public Packet55BlockBreakAnimation() {
+   }
+
+   public Packet55BlockBreakAnimation(int id, int x, int y, int z, int progress) {
+      this.id = id;
+      this.x = x;
+      this.y = y;
+      this.z = z;
+      this.progress = progress;
+   }
+
+   @Override
+   public void readPacketData(DataInputStream input) throws IOException {
+      this.id = input.readInt();
+      this.x = input.readInt();
+      this.y = input.readInt();
+      this.z = input.readInt();
+      this.progress = input.read();
+   }
+
+   @Override
+   public void writePacketData(DataOutputStream output) throws IOException {
+      output.writeInt(this.id);
+      output.writeInt(this.x);
+      output.writeInt(this.y);
+      output.writeInt(this.z);
+      output.write(this.progress);
+   }
+
+   @Override
+   public void processPacket(NetHandler handler) {
+      handler.handle55BlockBreakAnimation(this);
+   }
+
+   @Override
+   public int getPacketSize() {
+      return 13;
+   }
+
+   public int getPlayerId() {
+      return this.id;
+   }
+
+   public int getX() {
+      return this.x;
+   }
+
+   public int getY() {
+      return this.y;
+   }
+
+   public int getZ() {
+      return this.z;
+   }
+
+   public int getProgress() {
+      return this.progress;
+   }
+}
--- net/minecraft/src/Packet4UpdateTime.java
+++ net/minecraft/src/Packet4UpdateTime.java
@@ -11,7 +11,7 @@
 		this.time = var1.readLong();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeLong(this.time);
 	}
 
--- net/minecraft/src/CraftingInventoryWorkbenchCB.java
+++ /dev/null
@@ -1,36 +1,0 @@
-package net.minecraft.src;
-
-public class CraftingInventoryWorkbenchCB extends CraftingInventoryCB {
-	public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3);
-	public IInventory craftResult = new InventoryCraftResult();
-
-	public void onCraftMatrixChanged(IInventory var1) {
-		int[] var2 = new int[9];
-
-		for(int var3 = 0; var3 < 3; ++var3) {
-			for(int var4 = 0; var4 < 3; ++var4) {
-				int var5 = var3 + var4 * 3;
-				ItemStack var6 = this.craftMatrix.getStackInSlot(var5);
-				if(var6 == null) {
-					var2[var5] = -1;
-				} else {
-					var2[var5] = var6.itemID;
-				}
-			}
-		}
-
-		this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(var2));
-	}
-
-	public void onCraftGuiClosed(EntityPlayer var1) {
-		super.onCraftGuiClosed(var1);
-
-		for(int var2 = 0; var2 < 9; ++var2) {
-			ItemStack var3 = this.craftMatrix.getStackInSlot(var2);
-			if(var3 != null) {
-				var1.dropPlayerItem(var3);
-			}
-		}
-
-	}
-}
--- net/minecraft/src/Packet50PreChunk.java
+++ net/minecraft/src/Packet50PreChunk.java
@@ -9,13 +9,17 @@
 	public int yPosition;
 	public boolean mode;
 
+	public Packet50PreChunk() {
+		this.isChunkDataPacket = false;
+	}
+
 	public void readPacketData(DataInputStream var1) throws IOException {
 		this.xPosition = var1.readInt();
 		this.yPosition = var1.readInt();
 		this.mode = var1.read() != 0;
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.xPosition);
 		var1.writeInt(this.yPosition);
 		var1.write(this.mode ? 1 : 0);
--- /dev/null
+++ net/minecraft/src/Packet100OpenWindow.java
@@ -1,0 +1,34 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet100OpenWindow extends Packet {
+	public int windowId;
+	public int inventoryType;
+	public String windowTitle;
+	public int slotsCount;
+
+	public void processPacket(NetHandler var1) {
+		var1.func_20087_a(this);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.windowId = var1.readByte();
+		this.inventoryType = var1.readByte();
+		this.windowTitle = var1.readUTF();
+		this.slotsCount = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.windowId);
+		var1.writeByte(this.inventoryType);
+		var1.writeUTF(this.windowTitle);
+		var1.writeByte(this.slotsCount);
+	}
+
+	public int getPacketSize() {
+		return 3 + this.windowTitle.length();
+	}
+}
--- net/minecraft/src/InventoryPlayer.java
+++ net/minecraft/src/InventoryPlayer.java
@@ -1,12 +1,11 @@
 package net.minecraft.src;
 
 public class InventoryPlayer implements IInventory {
-	public ItemStack[] mainInventory = new ItemStack[37];
+	public ItemStack[] mainInventory = new ItemStack[36];
 	public ItemStack[] armorInventory = new ItemStack[4];
-	public ItemStack[] craftingInventory = new ItemStack[4];
 	public int currentItem = 0;
-	private EntityPlayer player;
-	public ItemStack draggedItemStack;
+	public EntityPlayer player;
+	private ItemStack itemStack;
 	public boolean inventoryChanged = false;
 
 	public InventoryPlayer(EntityPlayer var1) {
@@ -14,7 +13,7 @@
 	}
 
 	public ItemStack getCurrentItem() {
-		return this.mainInventory[this.currentItem];
+		return this.currentItem < 9 && this.currentItem >= 0 ? this.mainInventory[this.currentItem] : null;
 	}
 
 	private int getInventorySlotContainItem(int var1) {
@@ -27,9 +26,9 @@
 		return -1;
 	}
 
-	private int storeItemStack(int var1) {
+	private int storeItemStack(ItemStack var1) {
 		for(int var2 = 0; var2 < this.mainInventory.length; ++var2) {
-			if(this.mainInventory[var2] != null && this.mainInventory[var2].itemID == var1 && this.mainInventory[var2].stackSize < this.mainInventory[var2].getMaxStackSize() && this.mainInventory[var2].stackSize < this.getInventoryStackLimit()) {
+			if(this.mainInventory[var2] != null && this.mainInventory[var2].itemID == var1.itemID && this.mainInventory[var2].isStackable() && this.mainInventory[var2].stackSize < this.mainInventory[var2].getMaxStackSize() && this.mainInventory[var2].stackSize < this.getInventoryStackLimit() && (!this.mainInventory[var2].getHasSubtypes() || this.mainInventory[var2].getItemDamage() == var1.getItemDamage())) {
 				return var2;
 			}
 		}
@@ -72,43 +71,45 @@
 
 	}
 
-	private int storePartialItemStack(int var1, int var2) {
-		int var3 = this.storeItemStack(var1);
-		if(var3 < 0) {
-			var3 = this.getFirstEmptyStack();
+	private int storePartialItemStack(ItemStack var1) {
+		int var2 = var1.itemID;
+		int var3 = var1.stackSize;
+		int var4 = this.storeItemStack(var1);
+		if(var4 < 0) {
+			var4 = this.getFirstEmptyStack();
 		}
 
-		if(var3 < 0) {
-			return var2;
+		if(var4 < 0) {
+			return var3;
 		} else {
-			if(this.mainInventory[var3] == null) {
-				this.mainInventory[var3] = new ItemStack(var1, 0);
-			}
-
-			int var4 = var2;
-			if(var2 > this.mainInventory[var3].getMaxStackSize() - this.mainInventory[var3].stackSize) {
-				var4 = this.mainInventory[var3].getMaxStackSize() - this.mainInventory[var3].stackSize;
-			}
-
-			if(var4 > this.getInventoryStackLimit() - this.mainInventory[var3].stackSize) {
-				var4 = this.getInventoryStackLimit() - this.mainInventory[var3].stackSize;
-			}
-
-			if(var4 == 0) {
-				return var2;
+			if(this.mainInventory[var4] == null) {
+				this.mainInventory[var4] = new ItemStack(var2, 0, var1.getItemDamage());
+			}
+
+			int var5 = var3;
+			if(var3 > this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize) {
+				var5 = this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize;
+			}
+
+			if(var5 > this.getInventoryStackLimit() - this.mainInventory[var4].stackSize) {
+				var5 = this.getInventoryStackLimit() - this.mainInventory[var4].stackSize;
+			}
+
+			if(var5 == 0) {
+				return var3;
 			} else {
-				var2 -= var4;
-				this.mainInventory[var3].stackSize += var4;
-				this.mainInventory[var3].animationsToGo = 5;
-				return var2;
+				var3 -= var5;
+				this.mainInventory[var4].stackSize += var5;
+				this.mainInventory[var4].animationsToGo = 5;
+				return var3;
 			}
 		}
 	}
 
 	public void decrementAnimations() {
 		for(int var1 = 0; var1 < this.mainInventory.length; ++var1) {
-			if(this.mainInventory[var1] != null && this.mainInventory[var1].animationsToGo > 0) {
-				--this.mainInventory[var1].animationsToGo;
+			if(this.mainInventory[var1] != null) {
+				this.mainInventory[var1].updateAnimation(this.player.worldObj, this.player, var1, this.currentItem == var1);
 			}
 		}
 
@@ -128,20 +129,24 @@
 	}
 
 	public boolean addItemStackToInventory(ItemStack var1) {
-		if(var1.itemDmg == 0) {
-			var1.stackSize = this.storePartialItemStack(var1.itemID, var1.stackSize);
-			if(var1.stackSize == 0) {
+		int var2;
+		if(var1.isItemDamaged()) {
+			var2 = this.getFirstEmptyStack();
+			if(var2 >= 0) {
+				this.mainInventory[var2] = ItemStack.copyItemStack(var1);
+				this.mainInventory[var2].animationsToGo = 5;
+				var1.stackSize = 0;
 				return true;
+			} else {
+				return false;
 			}
-		}
-
-		int var2 = this.getFirstEmptyStack();
-		if(var2 >= 0) {
-			this.mainInventory[var2] = var1;
-			this.mainInventory[var2].animationsToGo = 5;
-			return true;
 		} else {
-			return false;
+			do {
+				var2 = var1.stackSize;
+				var1.stackSize = this.storePartialItemStack(var1);
+			} while(var1.stackSize > 0 && var1.stackSize < var2);
+
+			return var1.stackSize < var2;
 		}
 	}
 
@@ -178,11 +183,6 @@
 			var3 = this.armorInventory;
 		}
 
-		if(var1 >= var3.length) {
-			var1 -= var3.length;
-			var3 = this.craftingInventory;
-		}
-
 		var3[var1] = var2;
 	}
 
@@ -216,36 +216,25 @@
 			}
 		}
 
-		for(var2 = 0; var2 < this.craftingInventory.length; ++var2) {
-			if(this.craftingInventory[var2] != null) {
-				var3 = new NBTTagCompound();
-				var3.setByte("Slot", (byte)(var2 + 80));
-				this.craftingInventory[var2].writeToNBT(var3);
-				var1.setTag(var3);
-			}
-		}
-
 		return var1;
 	}
 
 	public void readFromNBT(NBTTagList var1) {
 		this.mainInventory = new ItemStack[36];
 		this.armorInventory = new ItemStack[4];
-		this.craftingInventory = new ItemStack[4];
 
 		for(int var2 = 0; var2 < var1.tagCount(); ++var2) {
 			NBTTagCompound var3 = (NBTTagCompound)var1.tagAt(var2);
 			int var4 = var3.getByte("Slot") & 255;
-			if(var4 >= 0 && var4 < this.mainInventory.length) {
-				this.mainInventory[var4] = new ItemStack(var3);
-			}
-
-			if(var4 >= 80 && var4 < this.craftingInventory.length + 80) {
-				this.craftingInventory[var4 - 80] = new ItemStack(var3);
-			}
-
-			if(var4 >= 100 && var4 < this.armorInventory.length + 100) {
-				this.armorInventory[var4 - 100] = new ItemStack(var3);
+			ItemStack var5 = new ItemStack(var3);
+			if(var5.getItem() != null) {
+				if(var4 >= 0 && var4 < this.mainInventory.length) {
+					this.mainInventory[var4] = var5;
+				}
+
+				if(var4 >= 100 && var4 < this.armorInventory.length + 100) {
+					this.armorInventory[var4 - 100] = var5;
+				}
 			}
 		}
 
@@ -262,11 +251,6 @@
 			var2 = this.armorInventory;
 		}
 
-		if(var1 >= var2.length) {
-			var1 -= var2.length;
-			var2 = this.craftingInventory;
-		}
-
 		return var2[var1];
 	}
 
@@ -284,7 +268,7 @@
 	}
 
 	public boolean canHarvestBlock(Block var1) {
-		if(var1.material != Material.rock && var1.material != Material.iron && var1.material != Material.craftedSnow && var1.material != Material.snow) {
+		if(var1.material.getIsHarvestable()) {
 			return true;
 		} else {
 			ItemStack var2 = this.getStackInSlot(this.currentItem);
@@ -304,7 +288,7 @@
 		for(int var4 = 0; var4 < this.armorInventory.length; ++var4) {
 			if(this.armorInventory[var4] != null && this.armorInventory[var4].getItem() instanceof ItemArmor) {
 				int var5 = this.armorInventory[var4].getMaxDamage();
-				int var6 = this.armorInventory[var4].itemDmg;
+				int var6 = this.armorInventory[var4].getItemDamageForDisplay();
 				int var7 = var5 - var6;
 				var2 += var7;
 				var3 += var5;
@@ -323,9 +307,9 @@
 	public void damageArmor(int var1) {
 		for(int var2 = 0; var2 < this.armorInventory.length; ++var2) {
 			if(this.armorInventory[var2] != null && this.armorInventory[var2].getItem() instanceof ItemArmor) {
-				this.armorInventory[var2].damageItem(var1);
+				this.armorInventory[var2].damageItem(var1, this.player);
 				if(this.armorInventory[var2].stackSize == 0) {
-					this.armorInventory[var2].onItemDestroyedByUse(this.player);
+					this.armorInventory[var2].func_1097_a(this.player);
 					this.armorInventory[var2] = null;
 				}
 			}
@@ -355,49 +339,33 @@
 		this.inventoryChanged = true;
 	}
 
-	public boolean getInventoryEqual(InventoryPlayer var1) {
-		int var2;
-		for(var2 = 0; var2 < this.mainInventory.length; ++var2) {
-			if(!this.getItemStacksEqual(var1.mainInventory[var2], this.mainInventory[var2])) {
-				return false;
-			}
-		}
-
-		for(var2 = 0; var2 < this.armorInventory.length; ++var2) {
-			if(!this.getItemStacksEqual(var1.armorInventory[var2], this.armorInventory[var2])) {
-				return false;
-			}
-		}
-
-		for(var2 = 0; var2 < this.craftingInventory.length; ++var2) {
-			if(!this.getItemStacksEqual(var1.craftingInventory[var2], this.craftingInventory[var2])) {
-				return false;
-			}
-		}
-
-		return true;
-	}
-
-	private boolean getItemStacksEqual(ItemStack var1, ItemStack var2) {
-		return var1 == null && var2 == null ? true : (var1 != null && var2 != null ? var1.itemID == var2.itemID && var1.stackSize == var2.stackSize && var1.itemDmg == var2.itemDmg : false);
-	}
-
-	public InventoryPlayer copyInventory() {
-		InventoryPlayer var1 = new InventoryPlayer((EntityPlayer)null);
-
-		int var2;
-		for(var2 = 0; var2 < this.mainInventory.length; ++var2) {
-			var1.mainInventory[var2] = this.mainInventory[var2] != null ? this.mainInventory[var2].copy() : null;
-		}
-
-		for(var2 = 0; var2 < this.armorInventory.length; ++var2) {
-			var1.armorInventory[var2] = this.armorInventory[var2] != null ? this.armorInventory[var2].copy() : null;
-		}
-
-		for(var2 = 0; var2 < this.craftingInventory.length; ++var2) {
-			var1.craftingInventory[var2] = this.craftingInventory[var2] != null ? this.craftingInventory[var2].copy() : null;
-		}
-
-		return var1;
+	public void setItemStack(ItemStack var1) {
+		this.itemStack = var1;
+		this.player.onItemStackChanged(var1);
+	}
+
+	public ItemStack getItemStack() {
+		return this.itemStack;
+	}
+
+	public boolean canInteractWith(EntityPlayer var1) {
+		return this.player.isDead ? false : var1.getDistanceSqToEntity(this.player) <= 64.0D;
+	}
+
+	public boolean func_28018_c(ItemStack var1) {
+		int var2;
+		for(var2 = 0; var2 < this.armorInventory.length; ++var2) {
+			if(this.armorInventory[var2] != null && this.armorInventory[var2].isStackEqual(var1)) {
+				return true;
+			}
+		}
+
+		for(var2 = 0; var2 < this.mainInventory.length; ++var2) {
+			if(this.mainInventory[var2] != null && this.mainInventory[var2].isStackEqual(var1)) {
+				return true;
+			}
+		}
+
+		return false;
 	}
 }
--- net/minecraft/src/EntityPlayerSP.java
+++ net/minecraft/src/EntityPlayerSP.java
@@ -50,6 +50,11 @@
 		super.readEntityFromNBT(var1);
 		this.score = var1.getInteger("Score");
 	}
+	
+	public void closeScreen() {
+		super.closeScreen();
+		this.mc.displayGuiScreen((GuiScreen)null);
+	}
 
 	public void displayGUIChest(IInventory var1) {
 		this.mc.displayGuiScreen(new GuiChest(this.inventory, var1));
@@ -59,30 +64,14 @@
 		this.mc.displayGuiScreen(new GuiEditSign(var1));
 	}
 
-	public void displayWorkbenchGUI() {
-		this.mc.displayGuiScreen(new GuiCrafting(this.inventory));
+	public void displayWorkbenchGUI(int var1, int var2, int var3) {
+		this.mc.displayGuiScreen(new GuiCrafting(this.inventory, this.worldObj, var1, var2, var3));
 	}
 
 	public void displayGUIFurnace(TileEntityFurnace var1) {
 		this.mc.displayGuiScreen(new GuiFurnace(this.inventory, var1));
 	}
 
-	public void attackEntity(Entity var1) {
-		int var2 = this.inventory.getDamageVsEntity(var1);
-		if(var2 > 0) {
-			var1.attackEntityFrom(this, var2);
-			ItemStack var3 = this.getCurrentEquippedItem();
-			if(var3 != null && var1 instanceof EntityLiving) {
-				var3.hitEntity((EntityLiving)var1);
-				if(var3.stackSize <= 0) {
-					var3.onItemDestroyedByUse(this);
-					this.destroyCurrentEquippedItem();
-				}
-			}
-		}
-
-	}
-
 	public void onItemPickup(Entity var1, int var2) {
 		this.mc.effectRenderer.addEffect(new EntityPickupFX(this.mc.theWorld, var1, this, -0.5F));
 	}
@@ -91,20 +80,6 @@
 		return this.inventory.getTotalArmorValue();
 	}
 
-	public void interactWithEntity(Entity var1) {
-		if(!var1.interact(this)) {
-			ItemStack var2 = this.getCurrentEquippedItem();
-			if(var2 != null && var1 instanceof EntityLiving) {
-				var2.useItemOnEntity((EntityLiving)var1);
-				if(var2.stackSize <= 0) {
-					var2.onItemDestroyedByUse(this);
-					this.destroyCurrentEquippedItem();
-				}
-			}
-
-		}
-	}
-
 	public void sendChatMessage(String var1) {
 	}
 
@@ -113,5 +88,26 @@
 
 	public boolean isSneaking() {
 		return this.movementInput.sneak;
+	}
+	
+	public void setHealth(int var1) {
+		int var2 = this.health - var1;
+		if(var2 <= 0) {
+			this.health = var1;
+			if(var2 < 0) {
+				this.heartsLife = this.heartsHalvesLife / 2;
+			}
+		} else {
+			this.somethingHealth = var2;
+			this.prevHealth = this.health;
+			this.heartsLife = this.heartsHalvesLife;
+			this.damageEntity(var2);
+			this.hurtTime = this.maxHurtTime = 10;
+		}
+
+	}
+	
+	public void respawnPlayer() {
+		this.mc.respawn();
 	}
 }
--- /dev/null
+++ net/minecraft/src/Packet39AttachEntity.java
@@ -1,0 +1,28 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet39AttachEntity extends Packet {
+	public int entityId;
+	public int vehicleEntityId;
+
+	public int getPacketSize() {
+		return 8;
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.entityId = var1.readInt();
+		this.vehicleEntityId = var1.readInt();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.entityId);
+		var1.writeInt(this.vehicleEntityId);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_6497_a(this);
+	}
+}
--- net/minecraft/src/Packet52MultiBlockChange.java
+++ net/minecraft/src/Packet52MultiBlockChange.java
@@ -32,7 +32,7 @@
 		var1.readFully(this.metadataArray);
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.xPosition);
 		var1.writeInt(this.zPosition);
 		var1.writeShort((short)this.size);
--- /dev/null
+++ net/minecraft/src/Packet61DoorChange.java
@@ -1,0 +1,37 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet61DoorChange extends Packet {
+	public int field_28050_a;
+	public int field_28049_b;
+	public int field_28053_c;
+	public int field_28052_d;
+	public int field_28051_e;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.field_28050_a = var1.readInt();
+		this.field_28053_c = var1.readInt();
+		this.field_28052_d = var1.readByte();
+		this.field_28051_e = var1.readInt();
+		this.field_28049_b = var1.readInt();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.field_28050_a);
+		var1.writeInt(this.field_28053_c);
+		var1.writeByte(this.field_28052_d);
+		var1.writeInt(this.field_28051_e);
+		var1.writeInt(this.field_28049_b);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_28115_a(this);
+	}
+
+	public int getPacketSize() {
+		return 20;
+	}
+}
--- net/minecraft/src/EntityPlayer.java
+++ net/minecraft/src/EntityPlayer.java
@@ -4,6 +4,8 @@
 
 public class EntityPlayer extends EntityLiving {
 	public InventoryPlayer inventory = new InventoryPlayer(this);
+	public Container inventorySlots;
+	public Container craftingInventory;
 	public byte unusedMiningCooldown = 0;
 	public int score = 0;
 	public float prevCameraYaw;
@@ -15,6 +17,8 @@
 
 	public EntityPlayer(World var1) {
 		super(var1);
+		this.inventorySlots = new ContainerPlayer(this.inventory, !var1.multiplayerWorld);
+		this.craftingInventory = this.inventorySlots;
 		this.yOffset = 1.62F;
 		this.setLocationAndAngles((double)var1.spawnX + 0.5D, (double)(var1.spawnY + 1), (double)var1.spawnZ + 0.5D, 0.0F, 0.0F);
 		this.health = 20;
@@ -24,6 +28,25 @@
 		this.texture = "/char.png";
 	}
 
+	protected void entityInit() {
+		super.entityInit();
+		this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
+	}
+	
+	public void onUpdate() {
+
+		super.onUpdate();
+		if(!this.worldObj.multiplayerWorld && this.craftingInventory != null && !this.craftingInventory.isUsableByPlayer(this)) {
+			this.closeScreen();
+			this.craftingInventory = this.inventorySlots;
+		}
+
+	}
+	
+	protected void closeScreen() {
+		this.craftingInventory = this.inventorySlots;
+	}
+
 	public void updateRidden() {
 		super.updateRidden();
 		this.prevCameraYaw = this.cameraYaw;
@@ -117,6 +140,10 @@
 	public void addToPlayerScore(Entity var1, int var2) {
 		this.score += var2;
 	}
+	
+	public void dropCurrentItem() {
+		this.dropPlayerItemWithRandomChoice(this.inventory.decrStackSize(this.inventory.currentItem, 1), false);
+	}
 
 	public void dropPlayerItem(ItemStack var1) {
 		this.dropPlayerItemWithRandomChoice(var1, false);
@@ -188,6 +215,20 @@
 
 	public void displayWorkbenchGUI() {
 	}
+	
+	public void useCurrentItemOnEntity(Entity var1) {
+		if(!var1.interact(this)) {
+			ItemStack var2 = this.getCurrentEquippedItem();
+			if(var2 != null && var1 instanceof EntityLiving) {
+				var2.useItemOnEntity((EntityLiving)var1);
+				if(var2.stackSize <= 0) {
+					var2.func_1097_a(this);
+					this.destroyCurrentEquippedItem();
+				}
+			}
+
+		}
+	}
 
 	public void onItemPickup(Entity var1, int var2) {
 	}
@@ -225,6 +266,15 @@
 			return var2 == 0 ? false : super.attackEntityFrom(var1, var2);
 		}
 	}
+	
+	protected void damageEntity(int var1) {
+		int var2 = 25 - this.inventory.getTotalArmorValue();
+		int var3 = var1 * var2 + this.damageRemainder;
+		this.inventory.damageArmor(var1);
+		var1 = var3 / 25;
+		this.damageRemainder = var3 % 25;
+		super.damageEntity(var1);
+	}
 
 	public void displayGUIFurnace(TileEntityFurnace var1) {
 	}
@@ -250,5 +300,40 @@
 	public void swingItem() {
 		this.swingProgressInt = -1;
 		this.isSwinging = true;
+	}
+	
+	public void attackTargetEntityWithCurrentItem(Entity var1) {
+		int var2 = this.inventory.getDamageVsEntity(var1);
+		if(var2 > 0) {
+			if(this.motionY < 0.0D) {
+				++var2;
+			}
+
+			var1.attackEntityFrom(this, var2);
+			ItemStack var3 = this.getCurrentEquippedItem();
+			if(var3 != null && var1 instanceof EntityLiving) {
+				var3.hitEntity((EntityLiving)var1, this);
+				if(var3.stackSize <= 0) {
+					var3.func_1097_a(this);
+					this.destroyCurrentEquippedItem();
+				}
+			}
+		}
+
+	}
+	
+	public void setEntityDead() {
+		super.setEntityDead();
+		this.inventorySlots.onCraftGuiClosed(this);
+		if(this.craftingInventory != null) {
+			this.craftingInventory.onCraftGuiClosed(this);
+		}
+
+	}
+	
+	public void respawnPlayer() {
+	}
+	
+	public void onItemStackChanged(ItemStack var1) {
 	}
 }
--- net/minecraft/src/BlockPressurePlate.java
+++ net/minecraft/src/BlockPressurePlate.java
@@ -88,7 +88,8 @@
 			var1.notifyBlocksOfNeighborChange(var2, var3, var4, this.blockID);
 			var1.notifyBlocksOfNeighborChange(var2, var3 - 1, var4, this.blockID);
 			var1.markBlocksDirty(var2, var3, var4, var2, var3, var4);
-			var1.playSoundEffect((double)var2 + 0.5D, (double)var3 + 0.1D, (double)var4 + 0.5D, "random.click", 0.3F, 0.6F);
+			if (!var1.multiplayerWorld)
+				var1.playSoundEffect((double)var2 + 0.5D, (double)var3 + 0.1D, (double)var4 + 0.5D, "random.click", 0.3F, 0.6F);
 		}
 
 		if(!var6 && var5) {
@@ -96,7 +97,8 @@
 			var1.notifyBlocksOfNeighborChange(var2, var3, var4, this.blockID);
 			var1.notifyBlocksOfNeighborChange(var2, var3 - 1, var4, this.blockID);
 			var1.markBlocksDirty(var2, var3, var4, var2, var3, var4);
-			var1.playSoundEffect((double)var2 + 0.5D, (double)var3 + 0.1D, (double)var4 + 0.5D, "random.click", 0.3F, 0.5F);
+			if (!var1.multiplayerWorld)
+				var1.playSoundEffect((double)var2 + 0.5D, (double)var3 + 0.1D, (double)var4 + 0.5D, "random.click", 0.3F, 0.5F);
 		}
 
 		if(var6) {
--- net/minecraft/src/Packet11PlayerPosition.java
+++ net/minecraft/src/Packet11PlayerPosition.java
@@ -26,12 +26,12 @@
 		super.readPacketData(var1);
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeDouble(this.xPosition);
 		var1.writeDouble(this.yPosition);
 		var1.writeDouble(this.stance);
 		var1.writeDouble(this.zPosition);
-		super.writePacket(var1);
+		super.writePacketData(var1);
 	}
 
 	public int getPacketSize() {
--- net/minecraft/src/Packet.java
+++ net/minecraft/src/Packet.java
@@ -2,23 +2,39 @@
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.io.EOFException;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 public abstract class Packet {
 	private static Map packetIdToClassMap = new HashMap();
 	private static Map packetClassToIdMap = new HashMap();
+	private static Set clientPacketIdList = new HashSet();
+	private static Set serverPacketIdList = new HashSet();
+	public final long creationTimeMillis = System.currentTimeMillis();
 	public boolean isChunkDataPacket = false;
+	private static HashMap packetStats;
+	private static int totalPacketsCount;
 
-	static void addIdClassMapping(int var0, Class var1) {
+	static void addIdClassMapping(int var0, boolean var1, boolean var2, Class var3) {
 		if(packetIdToClassMap.containsKey(Integer.valueOf(var0))) {
 			throw new IllegalArgumentException("Duplicate packet id:" + var0);
-		} else if(packetClassToIdMap.containsKey(var1)) {
-			throw new IllegalArgumentException("Duplicate packet class:" + var1);
+		} else if(packetClassToIdMap.containsKey(var3)) {
+			throw new IllegalArgumentException("Duplicate packet class:" + var3);
 		} else {
-			packetIdToClassMap.put(Integer.valueOf(var0), var1);
-			packetClassToIdMap.put(var1, Integer.valueOf(var0));
+			packetIdToClassMap.put(Integer.valueOf(var0), var3);
+			packetClassToIdMap.put(var3, Integer.valueOf(var0));
+			if(var1) {
+				clientPacketIdList.add(Integer.valueOf(var0));
+			}
+
+			if(var2) {
+				serverPacketIdList.add(Integer.valueOf(var0));
+			}
+
 		}
 	}
 
@@ -33,71 +49,151 @@
 		}
 	}
 
-	public final int getPacketId() throws IOException {
+	public final int getPacketId() {
 		return ((Integer)packetClassToIdMap.get(this.getClass())).intValue();
 	}
 
-	public static Packet readPacket(DataInputStream var0) throws IOException {
-		int var1 = var0.read();
-		if(var1 == -1) {
+	public static Packet readPacket(DataInputStream var0, boolean var1) throws IOException {
+		boolean var2 = false;
+		Packet var3 = null;
+
+		int var6;
+		try {
+			var6 = var0.read();
+			if(var6 == -1) {
+				return null;
+			}
+
+			if(var1 && !serverPacketIdList.contains(Integer.valueOf(var6)) || !var1 && !clientPacketIdList.contains(Integer.valueOf(var6))) {
+				throw new IOException("Bad packet id " + var6);
+			}
+
+			var3 = getNewPacket(var6);
+			if(var3 == null) {
+				throw new IOException("Bad packet id " + var6);
+			}
+
+			var3.readPacketData(var0);
+		} catch (EOFException var5) {
+			System.out.println("Reached end of stream");
 			return null;
-		} else {
-			Packet var2 = getNewPacket(var1);
-			if(var2 == null) {
-				throw new IOException("Bad packet id " + var1);
-			} else {
-				var2.readPacketData(var0);
-				return var2;
-			}
-		}
+		}
+
+		PacketCounter var4 = (PacketCounter)packetStats.get(Integer.valueOf(var6));
+		if(var4 == null) {
+			var4 = new PacketCounter((Empty1)null);
+			packetStats.put(Integer.valueOf(var6), var4);
+		}
+
+		var4.addPacket(var3.getPacketSize());
+		++totalPacketsCount;
+		if(totalPacketsCount % 1000 == 0) {
+		}
+
+		return var3;
 	}
 
 	public static void writePacket(Packet var0, DataOutputStream var1) throws IOException {
 		var1.write(var0.getPacketId());
-		var0.writePacket(var1);
+		var0.writePacketData(var1);
+	}
+
+	public static void writeString(String var0, DataOutputStream var1) throws IOException {
+		if(var0.length() > Short.MAX_VALUE) {
+			throw new IOException("String too big");
+		} else {
+			var1.writeShort(var0.length());
+			var1.writeChars(var0);
+		}
+	}
+
+	public static String readString(DataInputStream var0, int var1) throws IOException {
+		short var2 = var0.readShort();
+		if(var2 > var1) {
+			throw new IOException("Received string length longer than maximum allowed (" + var2 + " > " + var1 + ")");
+		} else if(var2 < 0) {
+			throw new IOException("Received string length is less than zero! Weird string!");
+		} else {
+			StringBuilder var3 = new StringBuilder();
+
+			for(int var4 = 0; var4 < var2; ++var4) {
+				var3.append(var0.readChar());
+			}
+
+			return var3.toString();
+		}
 	}
 
 	public abstract void readPacketData(DataInputStream var1) throws IOException;
 
-	public abstract void writePacket(DataOutputStream var1) throws IOException;
+	public abstract void writePacketData(DataOutputStream var1) throws IOException;
 
 	public abstract void processPacket(NetHandler var1);
 
 	public abstract int getPacketSize();
 
 	static {
-		addIdClassMapping(0, Packet0KeepAlive.class);
-		addIdClassMapping(1, Packet1Login.class);
-		addIdClassMapping(2, Packet2Handshake.class);
-		addIdClassMapping(3, Packet3Chat.class);
-		addIdClassMapping(4, Packet4UpdateTime.class);
-		addIdClassMapping(5, Packet5PlayerInventory.class);
-		addIdClassMapping(6, Packet6SpawnPosition.class);
-		addIdClassMapping(10, Packet10Flying.class);
-		addIdClassMapping(11, Packet11PlayerPosition.class);
-		addIdClassMapping(12, Packet12PlayerLook.class);
-		addIdClassMapping(13, Packet13PlayerLookMove.class);
-		addIdClassMapping(14, Packet14BlockDig.class);
-		addIdClassMapping(15, Packet15Place.class);
-		addIdClassMapping(16, Packet16BlockItemSwitch.class);
-		addIdClassMapping(17, Packet17AddToInventory.class);
-		addIdClassMapping(18, Packet18ArmAnimation.class);
-		addIdClassMapping(20, Packet20NamedEntitySpawn.class);
-		addIdClassMapping(21, Packet21PickupSpawn.class);
-		addIdClassMapping(22, Packet22Collect.class);
-		addIdClassMapping(23, Packet23VehicleSpawn.class);
-		addIdClassMapping(24, Packet24MobSpawn.class);
-		addIdClassMapping(29, Packet29DestroyEntity.class);
-		addIdClassMapping(30, Packet30Entity.class);
-		addIdClassMapping(31, Packet31RelEntityMove.class);
-		addIdClassMapping(32, Packet32EntityLook.class);
-		addIdClassMapping(33, Packet33RelEntityMoveLook.class);
-		addIdClassMapping(34, Packet34EntityTeleport.class);
-		addIdClassMapping(50, Packet50PreChunk.class);
-		addIdClassMapping(51, Packet51MapChunk.class);
-		addIdClassMapping(52, Packet52MultiBlockChange.class);
-		addIdClassMapping(53, Packet53BlockChange.class);
-		addIdClassMapping(59, Packet59ComplexEntity.class);
-		addIdClassMapping(255, Packet255KickDisconnect.class);
+		addIdClassMapping(0, true, true, Packet0KeepAlive.class);
+		addIdClassMapping(1, true, true, Packet1Login.class);
+		addIdClassMapping(2, true, true, Packet2Handshake.class);
+		addIdClassMapping(3, true, true, Packet3Chat.class);
+		addIdClassMapping(4, true, false, Packet4UpdateTime.class);
+		addIdClassMapping(5, true, false, Packet5PlayerInventory.class);
+		addIdClassMapping(6, true, false, Packet6SpawnPosition.class);
+		addIdClassMapping(7, false, true, Packet7UseEntity.class);
+		addIdClassMapping(8, true, false, Packet8UpdateHealth.class);
+		addIdClassMapping(9, true, true, Packet9Respawn.class);
+		addIdClassMapping(10, true, true, Packet10Flying.class);
+		addIdClassMapping(11, true, true, Packet11PlayerPosition.class);
+		addIdClassMapping(12, true, true, Packet12PlayerLook.class);
+		addIdClassMapping(13, true, true, Packet13PlayerLookMove.class);
+		addIdClassMapping(14, false, true, Packet14BlockDig.class);
+		addIdClassMapping(15, false, true, Packet15Place.class);
+		addIdClassMapping(16, false, true, Packet16BlockItemSwitch.class);
+		addIdClassMapping(17, true, false, Packet17Sleep.class);
+		addIdClassMapping(18, true, true, Packet18Animation.class);
+		addIdClassMapping(19, false, true, Packet19EntityAction.class);
+		addIdClassMapping(20, true, false, Packet20NamedEntitySpawn.class);
+		addIdClassMapping(21, true, false, Packet21PickupSpawn.class);
+		addIdClassMapping(22, true, false, Packet22Collect.class);
+		addIdClassMapping(23, true, false, Packet23VehicleSpawn.class);
+		addIdClassMapping(24, true, false, Packet24MobSpawn.class);
+		addIdClassMapping(25, true, false, Packet25EntityPainting.class);
+		addIdClassMapping(27, false, true, Packet27Position.class);
+		addIdClassMapping(28, true, false, Packet28EntityVelocity.class);
+		addIdClassMapping(29, true, false, Packet29DestroyEntity.class);
+		addIdClassMapping(30, true, false, Packet30Entity.class);
+		addIdClassMapping(31, true, false, Packet31RelEntityMove.class);
+		addIdClassMapping(32, true, false, Packet32EntityLook.class);
+		addIdClassMapping(33, true, false, Packet33RelEntityMoveLook.class);
+		addIdClassMapping(34, true, false, Packet34EntityTeleport.class);
+		addIdClassMapping(38, true, false, Packet38EntityStatus.class);
+		addIdClassMapping(39, true, false, Packet39AttachEntity.class);
+		addIdClassMapping(40, true, false, Packet40EntityMetadata.class);
+		addIdClassMapping(50, true, false, Packet50PreChunk.class);
+		addIdClassMapping(51, true, false, Packet51MapChunk.class);
+		addIdClassMapping(52, true, false, Packet52MultiBlockChange.class);
+		addIdClassMapping(53, true, false, Packet53BlockChange.class);
+		addIdClassMapping(54, true, false, Packet54PlayNoteBlock.class);
+		addIdClassMapping(55, true, false, Packet55BlockBreakAnimation.class);
+		addIdClassMapping(60, true, false, Packet60Explosion.class);
+		addIdClassMapping(61, true, false, Packet61DoorChange.class);
+		addIdClassMapping(62, true, false, Packet62Sound.class);
+		addIdClassMapping(63, true, false, Packet63WorldParticles.class);
+		addIdClassMapping(70, true, false, Packet70Bed.class);
+		addIdClassMapping(71, true, false, Packet71Weather.class);
+		addIdClassMapping(100, true, false, Packet100OpenWindow.class);
+		addIdClassMapping(101, true, true, Packet101CloseWindow.class);
+		addIdClassMapping(102, false, true, Packet102WindowClick.class);
+		addIdClassMapping(103, true, false, Packet103SetSlot.class);
+		addIdClassMapping(104, true, false, Packet104WindowItems.class);
+		addIdClassMapping(105, true, false, Packet105UpdateProgressbar.class);
+		addIdClassMapping(106, true, true, Packet106Transaction.class);
+		addIdClassMapping(130, true, true, Packet130UpdateSign.class);
+		addIdClassMapping(131, true, false, Packet131MapData.class);
+		addIdClassMapping(200, true, false, Packet200Statistic.class);
+		addIdClassMapping(255, true, true, Packet255KickDisconnect.class);
+		packetStats = new HashMap();
+		totalPacketsCount = 0;
 	}
 }
--- net/minecraft/src/RenderGlobal.java
+++ net/minecraft/src/RenderGlobal.java
@@ -4,13 +4,18 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
-import net.minecraft.client.Minecraft;
+
 import org.lwjgl.opengl.ARBOcclusionQuery;
 import org.lwjgl.opengl.GL11;
 import org.lwjgl.opengl.GL15;
 
+import net.minecraft.client.Minecraft;
+
 public class RenderGlobal implements IWorldAccess {
 	public List tileEntities = new ArrayList();
 	private World theWorld;
@@ -36,6 +41,7 @@
 	private int maxBlockX;
 	private int maxBlockY;
 	private int maxBlockZ;
+	private Map<Integer, BlockMiningProgress> miningProgress = new HashMap<>();
 	private int renderDistance = -1;
 	private int renderEntitiesStartupCounter = 2;
 	private int countEntitiesTotal;
@@ -55,7 +61,7 @@
 	double prevSortX = -9999.0D;
 	double prevSortY = -9999.0D;
 	double prevSortZ = -9999.0D;
-	public float damagePartialTime;
+	//public float damagePartialTime;
 	int frustumCheckOffset = 0;
 
 	public RenderGlobal(Minecraft var1, RenderEngine var2) {
@@ -553,8 +559,19 @@
 
 	}
 
-	public void updateClouds() {
+	public void updateClouds() { // tick()
 		++this.cloudTickCounter;
+		if (this.cloudTickCounter % 20 == 0) {
+			Iterator iterator = this.miningProgress.values().iterator();
+
+			while (iterator.hasNext()) {
+				BlockMiningProgress blockMiningProgress = (BlockMiningProgress)iterator.next();
+				int i = blockMiningProgress.getLastUpdateTick();
+				if (this.cloudTickCounter - i > 400) {
+					iterator.remove();
+				}
+			}
+		}
 	}
 
 	public void renderSky(float var1) {
@@ -845,80 +862,78 @@
 		return this.worldRenderersToUpdate.size() == 0;
 	}
 
-	public void drawBlockBreaking(EntityPlayer var1, MovingObjectPosition var2, int var3, ItemStack var4, float var5) {
-		Tessellator var6 = Tessellator.instance;
+	public void drawBlockBreaking(EntityPlayer camera, MovingObjectPosition hit, int i, ItemStack itemInHand, float tickDelta) {
+		Tessellator tesselator = Tessellator.instance;
 		GL11.glEnable(GL11.GL_BLEND);
 		GL11.glEnable(GL11.GL_ALPHA_TEST);
 		GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
 		GL11.glColor4f(1.0F, 1.0F, 1.0F, (MathHelper.sin((float)System.currentTimeMillis() / 100.0F) * 0.2F + 0.4F) * 0.5F);
-		int var8;
-		if(var3 == 0) {
-			if(this.damagePartialTime > 0.0F) {
-				GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_SRC_COLOR);
-				int var7 = this.renderEngine.getTexture("/terrain.png");
-				GL11.glBindTexture(GL11.GL_TEXTURE_2D, var7);
-				GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F);
-				GL11.glPushMatrix();
-				var8 = this.theWorld.getBlockId(var2.blockX, var2.blockY, var2.blockZ);
-				Block var9 = var8 > 0 ? Block.blocksList[var8] : null;
-				GL11.glDisable(GL11.GL_ALPHA_TEST);
-				GL11.glPolygonOffset(-3.0F, -3.0F);
-				GL11.glEnable(GL11.GL_POLYGON_OFFSET_FILL);
-				var6.startDrawingQuads();
-				double var10 = var1.lastTickPosX + (var1.posX - var1.lastTickPosX) * (double)var5;
-				double var12 = var1.lastTickPosY + (var1.posY - var1.lastTickPosY) * (double)var5;
-				double var14 = var1.lastTickPosZ + (var1.posZ - var1.lastTickPosZ) * (double)var5;
-				var6.setTranslationD(-var10, -var12, -var14);
-				var6.disableColor();
-				if(var9 == null) {
-					var9 = Block.stone;
-				}
-
-				this.globalRenderBlocks.renderBlockUsingTexture(var9, var2.blockX, var2.blockY, var2.blockZ, 240 + (int)(this.damagePartialTime * 10.0F));
-				var6.draw();
-				var6.setTranslationD(0.0D, 0.0D, 0.0D);
-				GL11.glPolygonOffset(0.0F, 0.0F);
-				GL11.glDisable(GL11.GL_POLYGON_OFFSET_FILL);
-				GL11.glEnable(GL11.GL_ALPHA_TEST);
-				GL11.glDepthMask(true);
-				GL11.glPopMatrix();
-			}
-		} else if(var4 != null) {
+		if (i != 0 && itemInHand != null) {
 			GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
-			float var16 = MathHelper.sin((float)System.currentTimeMillis() / 100.0F) * 0.2F + 0.8F;
-			GL11.glColor4f(var16, var16, var16, MathHelper.sin((float)System.currentTimeMillis() / 200.0F) * 0.2F + 0.5F);
-			var8 = this.renderEngine.getTexture("/terrain.png");
-			GL11.glBindTexture(GL11.GL_TEXTURE_2D, var8);
-			int var17 = var2.blockX;
-			int var18 = var2.blockY;
-			int var11 = var2.blockZ;
-			if(var2.sideHit == 0) {
-				--var18;
-			}
-
-			if(var2.sideHit == 1) {
-				++var18;
-			}
-
-			if(var2.sideHit == 2) {
-				--var11;
-			}
-
-			if(var2.sideHit == 3) {
-				++var11;
-			}
-
-			if(var2.sideHit == 4) {
-				--var17;
-			}
-
-			if(var2.sideHit == 5) {
-				++var17;
-			}
+			float f = MathHelper.sin((float)System.currentTimeMillis() / 100.0F) * 0.2F + 0.8F;
+			GL11.glColor4f(f, f, f, MathHelper.sin((float)System.currentTimeMillis() / 200.0F) * 0.2F + 0.5F);
+			int var7 = this.renderEngine.getTexture("/terrain.png");
+			GL11.glBindTexture(GL11.GL_TEXTURE_2D, var7);
 		}
 
 		GL11.glDisable(GL11.GL_BLEND);
 		GL11.glDisable(GL11.GL_ALPHA_TEST);
+	}
+
+	public void drawBlockBreaking(EntityPlayer var1, float var5) {
+		Tessellator var6 = Tessellator.instance;
+		double var10 = var1.lastTickPosX + (var1.posX - var1.lastTickPosX) * (double)var5;
+		double var12 = var1.lastTickPosY + (var1.posY - var1.lastTickPosY) * (double)var5;
+		double var14 = var1.lastTickPosZ + (var1.posZ - var1.lastTickPosZ) * (double)var5;
+		if(!this.miningProgress.isEmpty()) {
+			GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_SRC_COLOR);
+			int var7 = this.renderEngine.getTexture("/terrain.png");
+			GL11.glBindTexture(GL11.GL_TEXTURE_2D, var7);
+			GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F);
+			GL11.glPushMatrix();
+			GL11.glDisable(GL11.GL_ALPHA_TEST);
+			GL11.glPolygonOffset(-3.0F, -3.0F);
+			GL11.glEnable(GL11.GL_POLYGON_OFFSET_FILL);
+			var6.startDrawingQuads();
+			var6.setTranslationD(-var10, -var12, -var14);
+			var6.disableColor();
+
+			Iterator<BlockMiningProgress> iterator = this.miningProgress.values().iterator();
+
+			while (iterator.hasNext()) {
+				BlockMiningProgress blockMiningProgress = iterator.next();
+				double g = blockMiningProgress.getX() - var10;
+				double h = blockMiningProgress.getY() - var12;
+				double i = blockMiningProgress.getZ() - var14;
+				if (g * g + h * h + i * i > 1024.0) {
+					iterator.remove();
+				} else {
+					int j = this.theWorld.getBlockId(blockMiningProgress.getX(), blockMiningProgress.getY(), blockMiningProgress.getZ());
+					Block block = j > 0 ? Block.blocksList[j] : null;
+					if (block == null) {
+						block = Block.stone;
+					}
+
+					this.globalRenderBlocks
+					.renderBlockUsingTexture(
+							block,
+							blockMiningProgress.getX(),
+							blockMiningProgress.getY(),
+							blockMiningProgress.getZ(),
+							240 + (int)(blockMiningProgress.getProgress())
+					);
+				}
+			}
+
+			//this.globalRenderBlocks.renderBlockUsingTexture(var9, var2.blockX, var2.blockY, var2.blockZ, 240 + (int)(progress * 10.0F));
+			var6.draw();
+			var6.setTranslationD(0.0D, 0.0D, 0.0D);
+			GL11.glPolygonOffset(0.0F, 0.0F);
+			GL11.glDisable(GL11.GL_POLYGON_OFFSET_FILL);
+			GL11.glEnable(GL11.GL_ALPHA_TEST);
+			GL11.glDepthMask(true);
+			GL11.glPopMatrix();
+		}
 	}
 
 	public void drawSelectionBox(EntityPlayer var1, MovingObjectPosition var2, int var3, ItemStack var4, float var5) {
@@ -1056,25 +1071,25 @@
 		double var16 = this.mc.thePlayer.posY - var4;
 		double var18 = this.mc.thePlayer.posZ - var6;
 		if(var14 * var14 + var16 * var16 + var18 * var18 <= 256.0D) {
-			if(var1 == "bubble") {
+			if(var1.equals("bubble")) {
 				this.mc.effectRenderer.addEffect(new EntityBubbleFX(this.theWorld, var2, var4, var6, var8, var10, var12));
-			} else if(var1 == "smoke") {
+			} else if(var1.equals("smoke")) {
 				this.mc.effectRenderer.addEffect(new EntitySmokeFX(this.theWorld, var2, var4, var6));
-			} else if(var1 == "explode") {
+			} else if(var1.equals("explode")) {
 				this.mc.effectRenderer.addEffect(new EntityExplodeFX(this.theWorld, var2, var4, var6, var8, var10, var12));
-			} else if(var1 == "flame") {
+			} else if(var1.equals("flame")) {
 				this.mc.effectRenderer.addEffect(new EntityFlameFX(this.theWorld, var2, var4, var6, var8, var10, var12));
-			} else if(var1 == "lava") {
+			} else if(var1.equals("lava")) {
 				this.mc.effectRenderer.addEffect(new EntityLavaFX(this.theWorld, var2, var4, var6));
-			} else if(var1 == "splash") {
+			} else if(var1.equals("splash")) {
 				this.mc.effectRenderer.addEffect(new EntitySplashFX(this.theWorld, var2, var4, var6, var8, var10, var12));
-			} else if(var1 == "largesmoke") {
+			} else if(var1.equals("largesmoke")) {
 				this.mc.effectRenderer.addEffect(new EntitySmokeFX(this.theWorld, var2, var4, var6, 2.5F));
-			} else if(var1 == "reddust") {
+			} else if(var1.equals("reddust")) {
 				this.mc.effectRenderer.addEffect(new EntityReddustFX(this.theWorld, var2, var4, var6));
-			} else if(var1 == "snowballpoof") {
+			} else if(var1.equals("snowballpoof")) {
 				this.mc.effectRenderer.addEffect(new EntitySlimeFX(this.theWorld, var2, var4, var6, Item.snowball));
-			} else if(var1 == "slime") {
+			} else if(var1.equals("slime")) {
 				this.mc.effectRenderer.addEffect(new EntitySlimeFX(this.theWorld, var2, var4, var6, Item.slimeBall));
 			}
 
@@ -1109,5 +1124,82 @@
 	}
 
 	public void doNothingWithTileEntity(int var1, int var2, int var3, TileEntity var4) {
+	}
+	
+	public void func_28136_a(EntityPlayer var1, int var2, int var3, int var4, int var5, int var6) {
+		Random var7 = this.theWorld.rand;
+		int var16;
+		switch(var2) {
+		case 1000:
+			this.theWorld.playSoundEffect((double)var3, (double)var4, (double)var5, "random.click", 1.0F, 1.0F);
+			break;
+		case 1001:
+			this.theWorld.playSoundEffect((double)var3, (double)var4, (double)var5, "random.click", 1.0F, 1.2F);
+			break;
+		case 1002:
+			this.theWorld.playSoundEffect((double)var3, (double)var4, (double)var5, "random.bow", 1.0F, 1.2F);
+			break;
+		case 1003:
+			if(Math.random() < 0.5D) {
+				this.theWorld.playSoundEffect((double)var3 + 0.5D, (double)var4 + 0.5D, (double)var5 + 0.5D, "random.door_open", 1.0F, this.theWorld.rand.nextFloat() * 0.1F + 0.9F);
+			} else {
+				this.theWorld.playSoundEffect((double)var3 + 0.5D, (double)var4 + 0.5D, (double)var5 + 0.5D, "random.door_close", 1.0F, this.theWorld.rand.nextFloat() * 0.1F + 0.9F);
+			}
+			break;
+		case 1004:
+			this.theWorld.playSoundEffect((double)((float)var3 + 0.5F), (double)((float)var4 + 0.5F), (double)((float)var5 + 0.5F), "random.fizz", 0.5F, 2.6F + (var7.nextFloat() - var7.nextFloat()) * 0.8F);
+			break;
+		case 1005:
+			if(Item.itemsList[var6] instanceof ItemRecord) {
+				this.theWorld.playRecord(((ItemRecord)Item.itemsList[var6]).recordName, var3, var4, var5);
+			} else {
+				this.theWorld.playRecord((String)null, var3, var4, var5);
+			}
+			break;
+		case 2000:
+			int var8 = var6 % 3 - 1;
+			int var9 = var6 / 3 % 3 - 1;
+			double var10 = (double)var3 + (double)var8 * 0.6D + 0.5D;
+			double var12 = (double)var4 + 0.5D;
+			double var14 = (double)var5 + (double)var9 * 0.6D + 0.5D;
+
+			for(var16 = 0; var16 < 10; ++var16) {
+				double var31 = var7.nextDouble() * 0.2D + 0.01D;
+				double var19 = var10 + (double)var8 * 0.01D + (var7.nextDouble() - 0.5D) * (double)var9 * 0.5D;
+				double var21 = var12 + (var7.nextDouble() - 0.5D) * 0.5D;
+				double var23 = var14 + (double)var9 * 0.01D + (var7.nextDouble() - 0.5D) * (double)var8 * 0.5D;
+				double var25 = (double)var8 * var31 + var7.nextGaussian() * 0.01D;
+				double var27 = -0.03D + var7.nextGaussian() * 0.01D;
+				double var29 = (double)var9 * var31 + var7.nextGaussian() * 0.01D;
+				this.spawnParticle("smoke", var19, var21, var23, var25, var27, var29);
+			}
+
+			return;
+		case 2001:
+			var16 = var6 & 255;
+			if(var16 > 0) {
+				Block var17 = Block.blocksList[var16];
+				this.mc.sndManager.playSound(var17.stepSound.getBreakSound(), (float)var3 + 0.5F, (float)var4 + 0.5F, (float)var5 + 0.5F, (var17.stepSound.getVolume() + 1.0F) / 2.0F, var17.stepSound.getPitch() * 0.8F);
+			}
+
+			this.mc.effectRenderer.addBlockDestroyEffects(var3, var4, var5);
+		}
+
+	}
+
+	@Override
+	public void updateBlockMiningProgress(int id, int x, int y, int z, int progress) {
+		if (progress >= 0 && progress < 10) {
+			BlockMiningProgress blockMiningProgress = (BlockMiningProgress)this.miningProgress.get(id);
+			if (blockMiningProgress == null || blockMiningProgress.getX() != x || blockMiningProgress.getY() != y || blockMiningProgress.getZ() != z) {
+				blockMiningProgress = new BlockMiningProgress(id, x, y, z);
+				this.miningProgress.put(id, blockMiningProgress);
+			}
+
+			blockMiningProgress.setProgress(progress);
+			blockMiningProgress.setLastUpdateTick(this.cloudTickCounter);
+		} else {
+			this.miningProgress.remove(id);
+		}
 	}
 }
--- net/minecraft/src/BlockWorkbench.java
+++ net/minecraft/src/BlockWorkbench.java
@@ -11,6 +11,9 @@
 	}
 
 	public boolean blockActivated(World var1, int var2, int var3, int var4, EntityPlayer var5) {
+		if (var1.multiplayerWorld)
+			return true;
+		
 		var5.displayWorkbenchGUI();
 		return true;
 	}
--- /dev/null
+++ net/minecraft/src/PacketCounter.java
@@ -1,0 +1,18 @@
+package net.minecraft.src;
+
+class PacketCounter {
+	private int totalPackets;
+	private long totalBytes;
+
+	private PacketCounter() {
+	}
+
+	public void addPacket(int var1) {
+		++this.totalPackets;
+		this.totalBytes += (long)var1;
+	}
+
+	PacketCounter(Empty1 var1) {
+		this();
+	}
+}
--- net/minecraft/src/ChunkProviderClient.java
+++ net/minecraft/src/ChunkProviderClient.java
@@ -20,7 +20,7 @@
 	}
 
 	public boolean chunkExists(int var1, int var2) {
-		ChunkCoordinates var3 = new ChunkCoordinates(var1, var2);
+		ChunkCoordIntPair var3 = new ChunkCoordIntPair(var1, var2);
 		return this.chunkMapping.containsKey(var3);
 	}
 
@@ -30,12 +30,12 @@
 			var3.onChunkUnload();
 		}
 
-		this.chunkMapping.remove(new ChunkCoordinates(var1, var2));
+		this.chunkMapping.remove(new ChunkCoordIntPair(var1, var2));
 		this.chunkListing.remove(var3);
 	}
 
 	public Chunk loadChunk(int var1, int var2) {
-		ChunkCoordinates var3 = new ChunkCoordinates(var1, var2);
+		ChunkCoordIntPair var3 = new ChunkCoordIntPair(var1, var2);
 		byte[] var4 = new byte[-Short.MIN_VALUE];
 		Chunk var5 = new Chunk(this.worldObj, var4, var1, var2);
 		Arrays.fill(var5.skylightMap.data, (byte)-1);
@@ -45,7 +45,7 @@
 	}
 
 	public Chunk provideChunk(int var1, int var2) {
-		ChunkCoordinates var3 = new ChunkCoordinates(var1, var2);
+		ChunkCoordIntPair var3 = new ChunkCoordIntPair(var1, var2);
 		Chunk var4 = (Chunk)this.chunkMapping.get(var3);
 		return var4 == null ? this.blankChunk : var4;
 	}
--- net/minecraft/src/Packet33RelEntityMoveLook.java
+++ net/minecraft/src/Packet33RelEntityMoveLook.java
@@ -18,8 +18,8 @@
 		this.pitch = var1.readByte();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		super.writePacket(var1);
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		super.writePacketData(var1);
 		var1.writeByte(this.xPosition);
 		var1.writeByte(this.yPosition);
 		var1.writeByte(this.zPosition);
--- net/minecraft/src/Material.java
+++ net/minecraft/src/Material.java
@@ -4,8 +4,8 @@
 	public static final Material air = new MaterialTransparent();
 	public static final Material grass = new Material();
 	public static final Material wood = (new Material()).setBurning();
-	public static final Material rock = new Material();
-	public static final Material iron = new Material();
+	public static final Material rock = new Material().setNoHarvest();
+	public static final Material iron = new Material().setNoHarvest();
 	public static final Material water = new MaterialLiquid();
 	public static final Material lava = new MaterialLiquid();
 	public static final Material leaves = (new Material()).setBurning();
@@ -19,11 +19,12 @@
 	public static final Material tnt = (new Material()).setBurning();
 	public static final Material unused = new Material();
 	public static final Material ice = new Material();
-	public static final Material snow = new MaterialLogic();
-	public static final Material craftedSnow = new Material();
+	public static final Material snow = new MaterialLogic().setNoHarvest();
+	public static final Material craftedSnow = new Material().setNoHarvest();
 	public static final Material cactus = new Material();
 	public static final Material clay = new Material();
 	private boolean canBurn;
+	private boolean canHarvest = true;
 
 	public boolean getIsLiquid() {
 		return false;
@@ -46,7 +47,16 @@
 		return this;
 	}
 
+	protected Material setNoHarvest() {
+		this.canHarvest = false;
+		return this;
+	}
+
 	public boolean getCanBurn() {
 		return this.canBurn;
+	}
+
+	public boolean getIsHarvestable() {
+		return this.canHarvest;
 	}
 }
--- net/minecraft/src/EntitySkeleton.java
+++ net/minecraft/src/EntitySkeleton.java
@@ -15,7 +15,7 @@
 	}
 
 	protected String getDeathSound() {
-		return "mob.skeletonhurt";
+		return "mob.skeletondeath";
 	}
 
 	public void onLivingUpdate() {
--- /dev/null
+++ net/minecraft/src/Packet9Respawn.java
@@ -1,0 +1,32 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet9Respawn extends Packet {
+	public byte field_28048_a;
+
+	public Packet9Respawn() {
+	}
+
+	public Packet9Respawn(byte var1) {
+		this.field_28048_a = var1;
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_9448_a(this);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.field_28048_a = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.field_28048_a);
+	}
+
+	public int getPacketSize() {
+		return 1;
+	}
+}
--- net/minecraft/src/InventoryCrafting.java
+++ net/minecraft/src/InventoryCrafting.java
@@ -2,27 +2,31 @@
 
 public class InventoryCrafting implements IInventory {
 	private ItemStack[] stackList;
-	private int gridSize;
-	private CraftingInventoryCB craftingInventory;
-
-	public InventoryCrafting(CraftingInventoryCB var1, int var2, int var3) {
-		this.gridSize = var2 * var3;
-		this.stackList = new ItemStack[this.gridSize];
-		this.craftingInventory = var1;
-	}
-
-	public InventoryCrafting(CraftingInventoryCB var1, ItemStack[] var2) {
-		this.gridSize = var2.length;
-		this.stackList = var2;
-		this.craftingInventory = var1;
+	private int field_21104_b;
+	private Container eventHandler;
+
+	public InventoryCrafting(Container var1, int var2, int var3) {
+		int var4 = var2 * var3;
+		this.stackList = new ItemStack[var4];
+		this.eventHandler = var1;
+		this.field_21104_b = var2;
 	}
 
 	public int getSizeInventory() {
-		return this.gridSize;
+		return this.stackList.length;
 	}
 
 	public ItemStack getStackInSlot(int var1) {
-		return this.stackList[var1];
+		return var1 >= this.getSizeInventory() ? null : this.stackList[var1];
+	}
+
+	public ItemStack func_21103_b(int var1, int var2) {
+		if(var1 >= 0 && var1 < this.field_21104_b) {
+			int var3 = var1 + var2 * this.field_21104_b;
+			return this.getStackInSlot(var3);
+		} else {
+			return null;
+		}
 	}
 
 	public String getInvName() {
@@ -35,7 +39,7 @@
 			if(this.stackList[var1].stackSize <= var2) {
 				var3 = this.stackList[var1];
 				this.stackList[var1] = null;
-				this.craftingInventory.onCraftMatrixChanged(this);
+				this.eventHandler.onCraftMatrixChanged(this);
 				return var3;
 			} else {
 				var3 = this.stackList[var1].splitStack(var2);
@@ -43,7 +47,7 @@
 					this.stackList[var1] = null;
 				}
 
-				this.craftingInventory.onCraftMatrixChanged(this);
+				this.eventHandler.onCraftMatrixChanged(this);
 				return var3;
 			}
 		} else {
@@ -53,7 +57,7 @@
 
 	public void setInventorySlotContents(int var1, ItemStack var2) {
 		this.stackList[var1] = var2;
-		this.craftingInventory.onCraftMatrixChanged(this);
+		this.eventHandler.onCraftMatrixChanged(this);
 	}
 
 	public int getInventoryStackLimit() {
@@ -61,5 +65,9 @@
 	}
 
 	public void onInventoryChanged() {
+	}
+
+	public boolean canInteractWith(EntityPlayer var1) {
+		return true;
 	}
 }
--- /dev/null
+++ net/minecraft/src/InventoryBasic.java
@@ -1,0 +1,76 @@
+package net.minecraft.src;
+
+import java.util.List;
+
+public class InventoryBasic implements IInventory {
+	private String inventoryTitle;
+	private int slotsCount;
+	private ItemStack[] inventoryContents;
+	private List field_20073_d;
+
+	public InventoryBasic(String var1, int var2) {
+		this.inventoryTitle = var1;
+		this.slotsCount = var2;
+		this.inventoryContents = new ItemStack[var2];
+	}
+
+	public ItemStack getStackInSlot(int var1) {
+		return this.inventoryContents[var1];
+	}
+
+	public ItemStack decrStackSize(int var1, int var2) {
+		if(this.inventoryContents[var1] != null) {
+			ItemStack var3;
+			if(this.inventoryContents[var1].stackSize <= var2) {
+				var3 = this.inventoryContents[var1];
+				this.inventoryContents[var1] = null;
+				this.onInventoryChanged();
+				return var3;
+			} else {
+				var3 = this.inventoryContents[var1].splitStack(var2);
+				if(this.inventoryContents[var1].stackSize == 0) {
+					this.inventoryContents[var1] = null;
+				}
+
+				this.onInventoryChanged();
+				return var3;
+			}
+		} else {
+			return null;
+		}
+	}
+
+	public void setInventorySlotContents(int var1, ItemStack var2) {
+		this.inventoryContents[var1] = var2;
+		if(var2 != null && var2.stackSize > this.getInventoryStackLimit()) {
+			var2.stackSize = this.getInventoryStackLimit();
+		}
+
+		this.onInventoryChanged();
+	}
+
+	public int getSizeInventory() {
+		return this.slotsCount;
+	}
+
+	public String getInvName() {
+		return this.inventoryTitle;
+	}
+
+	public int getInventoryStackLimit() {
+		return 64;
+	}
+
+	public void onInventoryChanged() {
+		if(this.field_20073_d != null) {
+			for(int var1 = 0; var1 < this.field_20073_d.size(); ++var1) {
+				((IInvBasic)this.field_20073_d.get(var1)).func_20134_a(this);
+			}
+		}
+
+	}
+
+	public boolean canInteractWith(EntityPlayer var1) {
+		return true;
+	}
+}
--- /dev/null
+++ net/minecraft/src/Packet17Sleep.java
@@ -1,0 +1,37 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet17Sleep extends Packet {
+	public int field_22045_a;
+	public int field_22044_b;
+	public int field_22048_c;
+	public int field_22047_d;
+	public int field_22046_e;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.field_22045_a = var1.readInt();
+		this.field_22046_e = var1.readByte();
+		this.field_22044_b = var1.readInt();
+		this.field_22048_c = var1.readByte();
+		this.field_22047_d = var1.readInt();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.field_22045_a);
+		var1.writeByte(this.field_22046_e);
+		var1.writeInt(this.field_22044_b);
+		var1.writeByte(this.field_22048_c);
+		var1.writeInt(this.field_22047_d);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_22186_a(this);
+	}
+
+	public int getPacketSize() {
+		return 14;
+	}
+}
--- net/minecraft/src/EffectRenderer.java
+++ net/minecraft/src/EffectRenderer.java
@@ -107,6 +107,7 @@
 	public void addBlockDestroyEffects(int var1, int var2, int var3) {
 		int var4 = this.worldObj.getBlockId(var1, var2, var3);
 		if(var4 != 0) {
+			int metadata = this.worldObj.getBlockMetadata(var1, var2, var3);
 			Block var5 = Block.blocksList[var4];
 			byte var6 = 4;
 
@@ -116,7 +117,7 @@
 						double var10 = (double)var1 + ((double)var7 + 0.5D) / (double)var6;
 						double var12 = (double)var2 + ((double)var8 + 0.5D) / (double)var6;
 						double var14 = (double)var3 + ((double)var9 + 0.5D) / (double)var6;
-						this.addEffect(new EntityDiggingFX(this.worldObj, var10, var12, var14, var10 - (double)var1 - 0.5D, var12 - (double)var2 - 0.5D, var14 - (double)var3 - 0.5D, var5));
+						this.addEffect(new EntityDiggingFX(this.worldObj, var10, var12, var14, var10 - (double)var1 - 0.5D, var12 - (double)var2 - 0.5D, var14 - (double)var3 - 0.5D, var5, metadata));
 					}
 				}
 			}
@@ -127,6 +128,7 @@
 	public void addBlockHitEffects(int var1, int var2, int var3, int var4) {
 		int var5 = this.worldObj.getBlockId(var1, var2, var3);
 		if(var5 != 0) {
+			int metadata = this.worldObj.getBlockMetadata(var1, var2, var3);
 			Block var6 = Block.blocksList[var5];
 			float var7 = 0.1F;
 			double var8 = (double)var1 + this.rand.nextDouble() * (var6.maxX - var6.minX - (double)(var7 * 2.0F)) + (double)var7 + var6.minX;
@@ -156,7 +158,7 @@
 				var8 = (double)var1 + var6.maxX + (double)var7;
 			}
 
-			this.addEffect((new EntityDiggingFX(this.worldObj, var8, var10, var12, 0.0D, 0.0D, 0.0D, var6)).multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F));
+			this.addEffect((new EntityDiggingFX(this.worldObj, var8, var10, var12, 0.0D, 0.0D, 0.0D, var6, metadata)).multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F));
 		}
 	}
 
--- net/minecraft/src/ItemStack.java
+++ net/minecraft/src/ItemStack.java
@@ -4,39 +4,37 @@
 	public int stackSize;
 	public int animationsToGo;
 	public int itemID;
-	public int itemDmg;
+	private int itemDamage;
 
 	public ItemStack(Block var1) {
 		this((Block)var1, 1);
 	}
 
 	public ItemStack(Block var1, int var2) {
-		this(var1.blockID, var2);
+		this(var1.blockID, var2, 0);
+	}
+
+	public ItemStack(Block var1, int var2, int var3) {
+		this(var1.blockID, var2, var3);
 	}
 
 	public ItemStack(Item var1) {
-		this((Item)var1, 1);
+		this(var1.shiftedIndex, 1, 0);
 	}
 
 	public ItemStack(Item var1, int var2) {
-		this(var1.shiftedIndex, var2);
-	}
-
-	public ItemStack(int var1) {
-		this(var1, 1);
-	}
-
-	public ItemStack(int var1, int var2) {
-		this.stackSize = 0;
-		this.itemID = var1;
-		this.stackSize = var2;
+		this(var1.shiftedIndex, var2, 0);
+	}
+
+	public ItemStack(Item var1, int var2, int var3) {
+		this(var1.shiftedIndex, var2, var3);
 	}
 
 	public ItemStack(int var1, int var2, int var3) {
 		this.stackSize = 0;
 		this.itemID = var1;
 		this.stackSize = var2;
-		this.itemDmg = var3;
+		this.itemDamage = var3;
 	}
 
 	public ItemStack(NBTTagCompound var1) {
@@ -46,7 +44,7 @@
 
 	public ItemStack splitStack(int var1) {
 		this.stackSize -= var1;
-		return new ItemStack(this.itemID, var1, this.itemDmg);
+		return new ItemStack(this.itemID, var1, this.itemDamage);
 	}
 
 	public Item getItem() {
@@ -58,7 +56,9 @@
 	}
 
 	public boolean useItem(EntityPlayer var1, World var2, int var3, int var4, int var5, int var6) {
-		return this.getItem().onItemUse(this, var1, var2, var3, var4, var5, var6);
+		boolean var7 = this.getItem().onItemUse(this, var1, var2, var3, var4, var5, var6);
+
+		return var7;
 	}
 
 	public float getStrVsBlock(Block var1) {
@@ -72,43 +72,74 @@
 	public NBTTagCompound writeToNBT(NBTTagCompound var1) {
 		var1.setShort("id", (short)this.itemID);
 		var1.setByte("Count", (byte)this.stackSize);
-		var1.setShort("Damage", (short)this.itemDmg);
+		var1.setShort("Damage", (short)this.itemDamage);
 		return var1;
 	}
 
 	public void readFromNBT(NBTTagCompound var1) {
 		this.itemID = var1.getShort("id");
 		this.stackSize = var1.getByte("Count");
-		this.itemDmg = var1.getShort("Damage");
+		this.itemDamage = var1.getShort("Damage");
 	}
 
 	public int getMaxStackSize() {
 		return this.getItem().getItemStackLimit();
 	}
 
+	public boolean isStackable() {
+		return this.getMaxStackSize() > 1 && (!this.isItemStackDamageable() || !this.isItemDamaged());
+	}
+
+	public boolean isItemStackDamageable() {
+		return Item.itemsList[this.itemID].getMaxDamage() > 0;
+	}
+
+	public boolean getHasSubtypes() {
+		return Item.itemsList[this.itemID].getHasSubtypes();
+	}
+
+	public boolean isItemDamaged() {
+		return this.isItemStackDamageable() && this.itemDamage > 0;
+	}
+
+	public int getItemDamageForDisplay() {
+		return this.itemDamage;
+	}
+
+	public int getItemDamage() {
+		return this.itemDamage;
+	}
+
+	public void setItemDamage(int var1) {
+		this.itemDamage = var1;
+	}
+
 	public int getMaxDamage() {
 		return Item.itemsList[this.itemID].getMaxDamage();
 	}
 
-	public void damageItem(int var1) {
-		this.itemDmg += var1;
-		if(this.itemDmg > this.getMaxDamage()) {
-			--this.stackSize;
-			if(this.stackSize < 0) {
-				this.stackSize = 0;
+	public void damageItem(int var1, Entity var2) {
+		if(this.isItemStackDamageable()) {
+			this.itemDamage += var1;
+			if(this.itemDamage > this.getMaxDamage()) {
+
+				--this.stackSize;
+				if(this.stackSize < 0) {
+					this.stackSize = 0;
+				}
+
+				this.itemDamage = 0;
 			}
 
-			this.itemDmg = 0;
 		}
-
-	}
-
-	public void hitEntity(EntityLiving var1) {
-		Item.itemsList[this.itemID].hitEntity(this, var1);
-	}
-
-	public void onDestroyBlock(int var1, int var2, int var3, int var4) {
-		Item.itemsList[this.itemID].onBlockDestroyed(this, var1, var2, var3, var4);
+	}
+
+	public void hitEntity(EntityLiving var1, EntityPlayer var2) {
+		Item.itemsList[this.itemID].hitEntity(this, var1, var2);
+	}
+
+	public void onDestroyBlock(int var1, int var2, int var3, int var4, EntityPlayer var5) {
+		Item.itemsList[this.itemID].onBlockDestroyed(this, var1, var2, var3, var4, var5);
 	}
 
 	public int getDamageVsEntity(Entity var1) {
@@ -119,7 +150,7 @@
 		return Item.itemsList[this.itemID].canHarvestBlock(var1);
 	}
 
-	public void onItemDestroyedByUse(EntityPlayer var1) {
+	public void func_1097_a(EntityPlayer var1) {
 	}
 
 	public void useItemOnEntity(EntityLiving var1) {
@@ -127,6 +158,46 @@
 	}
 
 	public ItemStack copy() {
-		return new ItemStack(this.itemID, this.stackSize, this.itemDmg);
+		return new ItemStack(this.itemID, this.stackSize, this.itemDamage);
+	}
+
+	public static boolean areItemStacksEqual(ItemStack var0, ItemStack var1) {
+		return var0 == null && var1 == null ? true : (var0 != null && var1 != null ? var0.isItemStackEqual(var1) : false);
+	}
+
+	private boolean isItemStackEqual(ItemStack var1) {
+		return this.stackSize != var1.stackSize ? false : (this.itemID != var1.itemID ? false : this.itemDamage == var1.itemDamage);
+	}
+
+	public boolean isItemEqual(ItemStack var1) {
+		return this.itemID == var1.itemID && this.itemDamage == var1.itemDamage;
+	}
+
+	public String getItemName() {
+		return "";
+	}
+
+	public static ItemStack copyItemStack(ItemStack var0) {
+		return var0 == null ? null : var0.copy();
+	}
+
+	public String toString() {
+		return this.stackSize + "x" + Item.itemsList[this.itemID].shiftedIndex + "@" + this.itemDamage;
+	}
+
+	public void updateAnimation(World var1, Entity var2, int var3, boolean var4) {
+		if(this.animationsToGo > 0) {
+			--this.animationsToGo;
+		}
+
+		Item.itemsList[this.itemID].onUpdate(this, var1, var2, var3, var4);
+	}
+
+	public void onCrafting(World var1, EntityPlayer var2) {
+		Item.itemsList[this.itemID].onCreated(this, var1, var2);
+	}
+
+	public boolean isStackEqual(ItemStack var1) {
+		return this.itemID == var1.itemID && this.stackSize == var1.stackSize && this.itemDamage == var1.itemDamage;
 	}
 }
--- net/minecraft/src/Entity.java
+++ net/minecraft/src/Entity.java
@@ -57,6 +57,7 @@
 	public int air = 300;
 	private boolean firstUpdate = true;
 	public String skinUrl;
+	protected DataWatcher dataWatcher = new DataWatcher();
 	private double entityRiderPitchDelta;
 	private double entityRiderYawDelta;
 	public boolean addedToChunk = false;
@@ -70,6 +71,14 @@
 	public Entity(World var1) {
 		this.worldObj = var1;
 		this.setPosition(0.0D, 0.0D, 0.0D);
+		this.dataWatcher.addObject(0, Byte.valueOf((byte)0));
+		this.entityInit();
+	}
+	
+	protected abstract void entityInit();
+
+	public DataWatcher getDataWatcher() {
+		return this.dataWatcher;
 	}
 
 	public boolean equals(Object var1) {
@@ -159,7 +168,9 @@
 					var1 = 1.0F;
 				}
 
-				this.worldObj.playSoundAtEntity(this, "random.splash", var1, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
+				if (!this.worldObj.multiplayerWorld)
+					this.worldObj.playSoundAtEntity(this, "random.splash", var1, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
+				
 				float var2 = (float)MathHelper.floor_double(this.boundingBox.minY);
 
 				int var3;
@@ -389,12 +400,16 @@
 				if(this.distanceWalkedModified > (float)this.nextStepDistance && var28 > 0) {
 					++this.nextStepDistance;
 					StepSound var29 = Block.blocksList[var28].stepSound;
-					if(this.worldObj.getBlockId(var38, var26 + 1, var40) == Block.snow.blockID) {
-						var29 = Block.snow.stepSound;
-						this.worldObj.playSoundAtEntity(this, var29.getStepSound(), var29.getVolume() * 0.15F, var29.getPitch());
-					} else if(!Block.blocksList[var28].material.getIsLiquid()) {
-						this.worldObj.playSoundAtEntity(this, var29.getStepSound(), var29.getVolume() * 0.15F, var29.getPitch());
+					
+					if (!this.worldObj.multiplayerWorld) {
+						if(this.worldObj.getBlockId(var38, var26 + 1, var40) == Block.snow.blockID) {
+							var29 = Block.snow.stepSound;
+							this.worldObj.playSoundAtEntity(this, var29.getStepSound(), var29.getVolume() * 0.15F, var29.getPitch());
+						} else if(!Block.blocksList[var28].material.getIsLiquid()) {
+							this.worldObj.playSoundAtEntity(this, var29.getStepSound(), var29.getVolume() * 0.15F, var29.getPitch());
+						}
 					}
+					
 
 					Block.blocksList[var28].onEntityWalking(this.worldObj, var38, var26, var40, this);
 				}
@@ -440,10 +455,6 @@
 		}
 	}
 
-	public boolean isSneaking() {
-		return false;
-	}
-
 	public AxisAlignedBB getBoundingBox() {
 		return null;
 	}
@@ -720,9 +731,13 @@
 	public EntityItem dropItem(int var1, int var2) {
 		return this.entityDropItem(var1, var2, 0.0F);
 	}
-
+	
 	public EntityItem entityDropItem(int var1, int var2, float var3) {
-		EntityItem var4 = new EntityItem(this.worldObj, this.posX, this.posY + (double)var3, this.posZ, new ItemStack(var1, var2));
+		return this.entityDropItem(new ItemStack(var1, var2, 0), var3);
+	}
+
+	public EntityItem entityDropItem(ItemStack var1, float var3) {
+		EntityItem var4 = new EntityItem(this.worldObj, this.posX, this.posY + (double)var3, this.posZ, var1);
 		var4.delayBeforeCanPickup = 10;
 		this.worldObj.spawnEntityInWorld(var4);
 		return var4;
@@ -814,7 +829,14 @@
 	public void mountEntity(Entity var1) {
 		this.entityRiderPitchDelta = 0.0D;
 		this.entityRiderYawDelta = 0.0D;
-		if(this.ridingEntity == var1) {
+		if (var1 == null) {
+			if (this.ridingEntity != null) {
+				this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch);
+				this.ridingEntity.riddenByEntity = null;
+			}
+
+			this.ridingEntity = null;
+		} else if(this.ridingEntity == var1) {
 			this.ridingEntity.riddenByEntity = null;
 			this.ridingEntity = null;
 			this.setLocationAndAngles(var1.posX, var1.boundingBox.minY + (double)var1.height, var1.posZ, this.rotationYaw, this.rotationPitch);
@@ -835,5 +857,85 @@
 	public void setPositionAndRotation(double var1, double var3, double var5, float var7, float var8, int var9) {
 		this.setPosition(var1, var3, var5);
 		this.setRotation(var7, var8);
-	}
+		List list = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.contract(0.03125, 0.0, 0.03125));
+		if (list.size() > 0) {
+			double d = 0.0;
+
+			for (int i = 0; i < list.size(); i++) {
+				AxisAlignedBB box = (AxisAlignedBB)list.get(i);
+				if (box.maxY > d) {
+					d = box.maxY;
+				}
+			}
+
+			var3 += d - this.boundingBox.minY;
+			this.setPosition(var1, var3, var5);
+		}
+	}
+	
+	public void setVelocity(double var1, double var3, double var5) {
+		this.motionX = var1;
+		this.motionY = var3;
+		this.motionZ = var5;
+	}
+	
+	public void handleHealthUpdate(byte var1) {
+	}
+	
+	public void performHurtAnimation() {
+	}
+	
+	public void outfitWithItem(int var1, int var2, int var3) {
+	}
+
+	public boolean isBurning() {
+		return this.fire > 0 || this.getEntityFlag(0);
+	}
+
+	public boolean isRiding() {
+		return this.ridingEntity != null || this.getEntityFlag(2);
+	}
+
+	public boolean isSneaking() {
+		return this.getEntityFlag(1);
+	}
+
+	protected boolean getEntityFlag(int var1) {
+		return (this.dataWatcher.getWatchableObjectByte(0) & 1 << var1) != 0;
+	}
+
+	protected void setEntityFlag(int var1, boolean var2) {
+		byte var3 = this.dataWatcher.getWatchableObjectByte(0);
+		if(var2) {
+			this.dataWatcher.updateObject(0, Byte.valueOf((byte)(var3 | 1 << var1)));
+		} else {
+			this.dataWatcher.updateObject(0, Byte.valueOf((byte)(var3 & ~(1 << var1))));
+		}
+
+	}
+
+//	public void lerpVelocity(double velocityX, double velocityY, double velocityZ) {
+//		this.motionX = velocityX;
+//		this.motionY = velocityY;
+//		this.motionZ = velocityZ;
+//	}
+//
+//	public void lerpPositionAndAngles(double x, double y, double z, float yaw, float pitch, int steps) {
+//		this.setPosition(x, y, z);
+//		this.setRotation(yaw, pitch);
+//		List list = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.contract(0.03125, 0.0, 0.03125));
+//		if (list.size() > 0) {
+//			double d = 0.0;
+//
+//			for (int i = 0; i < list.size(); i++) {
+//				AxisAlignedBB box = (AxisAlignedBB)list.get(i);
+//				if (box.maxY > d) {
+//					d = box.maxY;
+//				}
+//			}
+//
+//			y += d - this.boundingBox.minY;
+//			this.setPosition(x, y, z);
+//		}
+//	}
 }
--- net/minecraft/src/IInventory.java
+++ net/minecraft/src/IInventory.java
@@ -14,4 +14,6 @@
 	int getInventoryStackLimit();
 
 	void onInventoryChanged();
+
+	boolean canInteractWith(EntityPlayer var1);
 }
--- net/minecraft/src/NetClientHandler.java
+++ net/minecraft/src/NetClientHandler.java
@@ -6,7 +6,11 @@
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Random;
+
 import net.minecraft.client.Minecraft;
 
 public class NetClientHandler extends NetHandler {
@@ -28,6 +32,8 @@
 		if(!this.disconnected) {
 			this.netManager.processReadPackets();
 		}
+
+		this.netManager.wakeThreads();
 	}
 
 	public void handleLogin(Packet1Login var1) {
@@ -36,19 +42,21 @@
 		this.worldClient.multiplayerWorld = true;
 		this.mc.changeWorld1(this.worldClient);
 		this.mc.displayGuiScreen(new GuiDownloadTerrain(this));
+		this.mc.thePlayer.entityID = var1.protocolVersion;
 	}
 
 	public void handlePickupSpawn(Packet21PickupSpawn var1) {
 		double var2 = (double)var1.xPosition / 32.0D;
 		double var4 = (double)var1.yPosition / 32.0D;
 		double var6 = (double)var1.zPosition / 32.0D;
-		EntityItem var8 = new EntityItem(this.worldClient, var2, var4, var6, new ItemStack(var1.itemID, var1.count));
+		EntityItem var8 = new EntityItem(this.worldClient, var2, var4, var6, new ItemStack(var1.itemID, var1.count, var1.itemDamage));
 		var8.motionX = (double)var1.rotation / 128.0D;
 		var8.motionY = (double)var1.pitch / 128.0D;
 		var8.motionZ = (double)var1.roll / 128.0D;
 		var8.serverPosX = var1.xPosition;
 		var8.serverPosY = var1.yPosition;
 		var8.serverPosZ = var1.zPosition;
+		var8.entityID = var1.entityId;
 		this.worldClient.addEntityToWorld(var1.entityId, var8);
 	}
 
@@ -57,20 +65,35 @@
 		double var4 = (double)var1.yPosition / 32.0D;
 		double var6 = (double)var1.zPosition / 32.0D;
 		Object var8 = null;
-		if(var1.type == 10) {
+		
+		switch (var1.type) {
+		case 10:
 			var8 = new EntityMinecart(this.worldClient, var2, var4, var6, 0);
-		}
-
-		if(var1.type == 11) {
+			break;
+		case 11:
 			var8 = new EntityMinecart(this.worldClient, var2, var4, var6, 1);
-		}
-
-		if(var1.type == 12) {
+			break;
+		case 12:
 			var8 = new EntityMinecart(this.worldClient, var2, var4, var6, 2);
-		}
-
-		if(var1.type == 1) {
+			break;
+		case 60:
+			var8 = new EntityArrow(this.worldClient, var2, var4, var6);
+			break;
+		case 61:
+			var8 = new EntitySnowball(this.worldClient, var2, var4, var6);
+			break;
+		case 1:
 			var8 = new EntityBoat(this.worldClient, var2, var4, var6);
+			break;
+		case 50:
+			var8 = new EntityTNTPrimed(this.worldClient, var2, var4, var6);
+			break;
+		case 70:
+			var8 = new EntityFallingSand(this.worldClient, var2, var4, var6, Block.sand.blockID);
+			break;
+		case 71:
+			var8 = new EntityFallingSand(this.worldClient, var2, var4, var6, Block.gravel.blockID);
+			break;
 		}
 
 		if(var8 != null) {
@@ -81,6 +104,36 @@
 			((Entity)var8).rotationPitch = 0.0F;
 			((Entity)var8).entityID = var1.entityId;
 			this.worldClient.addEntityToWorld(var1.entityId, (Entity)var8);
+			
+			if (var1.field_28044_i > 0) {
+				if(var1.type == 60) {
+					Entity var9 = this.getEntityByID(var1.field_28044_i);
+					if(var9 instanceof EntityLiving) {
+						((EntityArrow)var8).shootingEntity = (EntityLiving)var9;
+					}
+				}
+				
+				((Entity)var8).setVelocity((double)var1.field_28047_e / 8000.0D, (double)var1.field_28046_f / 8000.0D, (double)var1.field_28045_g / 8000.0D);
+			}
+		}
+	}
+
+	public void func_21146_a(Packet25EntityPainting var1) {
+		EntityPainting var2 = new EntityPainting(this.worldClient, var1.xPosition, var1.yPosition, var1.zPosition, var1.direction, var1.title);
+		this.worldClient.addEntityToWorld(var1.entityId, var2);
+	}
+	
+	public void func_6498_a(Packet28EntityVelocity var1) {
+		Entity var2 = this.getEntityByID(var1.entityId);
+		if(var2 != null) {
+			var2.setVelocity((double)var1.motionX / 8000.0D, (double)var1.motionY / 8000.0D, (double)var1.motionZ / 8000.0D);
+		}
+	}
+
+	public void func_21148_a(Packet40EntityMetadata var1) {
+		Entity var2 = this.getEntityByID(var1.entityId);
+		if(var2 != null && var1.func_21047_b() != null) {
+			var2.getDataWatcher().updateWatchedObjectsFromList(var1.func_21047_b());
 		}
 
 	}
@@ -92,14 +145,14 @@
 		float var8 = (float)(var1.rotation * 360) / 256.0F;
 		float var9 = (float)(var1.pitch * 360) / 256.0F;
 		EntityOtherPlayerMP var10 = new EntityOtherPlayerMP(this.mc.theWorld, var1.name);
-		var10.serverPosX = var1.xPosition;
-		var10.serverPosY = var1.yPosition;
-		var10.serverPosZ = var1.zPosition;
+		var10.prevPosX = var10.lastTickPosX = (double)(var10.serverPosX = var1.xPosition);
+		var10.prevPosY = var10.lastTickPosY = (double)(var10.serverPosY = var1.yPosition);
+		var10.prevPosZ = var10.lastTickPosZ = (double)(var10.serverPosZ = var1.zPosition);
 		int var11 = var1.currentItem;
 		if(var11 == 0) {
 			var10.inventory.mainInventory[var10.inventory.currentItem] = null;
 		} else {
-			var10.inventory.mainInventory[var10.inventory.currentItem] = new ItemStack(var11);
+			var10.inventory.mainInventory[var10.inventory.currentItem] = new ItemStack(var11, 1, 0);
 		}
 
 		var10.setPositionAndRotation(var2, var4, var6, var8, var9);
@@ -113,7 +166,7 @@
 			var2.serverPosY = var1.yPosition;
 			var2.serverPosZ = var1.zPosition;
 			double var3 = (double)var2.serverPosX / 32.0D;
-			double var5 = (double)var2.serverPosY / 32.0D;
+			double var5 = (double)var2.serverPosY / 32.0D + 1.0D / 64.0D;
 			double var7 = (double)var2.serverPosZ / 32.0D;
 			float var9 = (float)(var1.yaw * 360) / 256.0F;
 			float var10 = (float)(var1.pitch * 360) / 256.0F;
@@ -201,7 +254,7 @@
 
 	public void handleMapChunk(Packet51MapChunk var1) {
 		this.worldClient.invalidateBlockReceiveRegion(var1.xPosition, var1.yPosition, var1.zPosition, var1.xPosition + var1.xSize - 1, var1.yPosition + var1.ySize - 1, var1.zPosition + var1.zSize - 1);
-		this.worldClient.setChunkData(var1.xPosition, var1.yPosition, var1.zPosition, var1.xSize, var1.ySize, var1.zSize, var1.chunkData);
+		this.worldClient.setChunkData(var1.xPosition, var1.yPosition, var1.zPosition, var1.xSize, var1.ySize, var1.zSize, var1.chunk);
 	}
 
 	public void handleBlockChange(Packet53BlockChange var1) {
@@ -215,13 +268,20 @@
 		this.mc.displayGuiScreen(new GuiConnectFailed("Disconnected by server", var1.reason));
 	}
 
-	public void handleErrorMessage(String var1) {
+	public void handleErrorMessage(String var1, Object[] var2) {
 		if(!this.disconnected) {
 			this.disconnected = true;
 			this.mc.changeWorld1((World)null);
 			this.mc.displayGuiScreen(new GuiConnectFailed("Connection lost", var1));
 		}
 	}
+	
+	public void func_28117_a(Packet var1) {
+		if(!this.disconnected) {
+			this.netManager.addToSendQueue(var1);
+			this.netManager.func_28142_c();
+		}
+	}
 
 	public void addToSendQueue(Packet var1) {
 		if(!this.disconnected) {
@@ -230,7 +290,7 @@
 	}
 
 	public void handleCollect(Packet22Collect var1) {
-		EntityItem var2 = (EntityItem)this.worldClient.getEntityByID(var1.collectedEntityId);
+		Entity var2 = this.worldClient.getEntityByID(var1.collectedEntityId);
 		Object var3 = (EntityLiving)this.worldClient.getEntityByID(var1.collectorEntityId);
 		if(var3 == null) {
 			var3 = this.mc.thePlayer;
@@ -244,47 +304,34 @@
 
 	}
 
-	public void handleBlockItemSwitch(Packet16BlockItemSwitch var1) {
-		Entity var2 = this.worldClient.getEntityByID(var1.entityId);
-		if(var2 != null) {
-			EntityPlayer var3 = (EntityPlayer)var2;
-			int var4 = var1.id;
-			if(var4 == 0) {
-				var3.inventory.mainInventory[var3.inventory.currentItem] = null;
-			} else {
-				var3.inventory.mainInventory[var3.inventory.currentItem] = new ItemStack(var4);
-			}
-
-		}
-	}
-
 	public void handleChat(Packet3Chat var1) {
 		this.mc.ingameGUI.addChatMessage(var1.message);
 	}
 
-	public void handleArmAnimation(Packet18ArmAnimation var1) {
+	public void handleArmAnimation(Packet18Animation var1) {
 		Entity var2 = this.worldClient.getEntityByID(var1.entityId);
 		if(var2 != null) {
-			EntityPlayer var3 = (EntityPlayer)var2;
-			var3.swingItem();
+			EntityPlayer var3;
+			if(var1.animate == 1) {
+				var3 = (EntityPlayer)var2;
+				var3.swingItem();
+			} else if(var1.animate == 2) {
+				var2.performHurtAnimation();
+			}
 		}
-	}
-
-	public void handleAddToInventory(Packet17AddToInventory var1) {
-		this.mc.thePlayer.inventory.addItemStackToInventory(new ItemStack(var1.itemID, var1.count, var1.itemDamage));
 	}
 
 	public void handleHandshake(Packet2Handshake var1) {
 		if(var1.username.equals("-")) {
-			this.addToSendQueue(new Packet1Login(this.mc.session.username, "Password", 2));
+			this.addToSendQueue(new Packet1Login(this.mc.session.username, 1984));
 		} else {
 			try {
-				URL var2 = new URL("http://www.minecraft.net/game/joinserver.jsp?user=" + this.mc.session.username + "&sessionId=" + this.mc.session.sessionId + "&serverId=" + var1.username);
+				URL var2 = new URL("https://session.minecraft.net/game/joinserver.jsp?user=" + this.mc.session.username + "&sessionId=" + this.mc.session.sessionId + "&serverId=" + var1.username);
 				BufferedReader var3 = new BufferedReader(new InputStreamReader(var2.openStream()));
 				String var4 = var3.readLine();
 				var3.close();
 				if(var4.equalsIgnoreCase("ok")) {
-					this.addToSendQueue(new Packet1Login(this.mc.session.username, "Password", 2));
+					this.addToSendQueue(new Packet1Login(this.mc.session.username, 1984));
 				} else {
 					this.netManager.networkShutdown("Failed to login: " + var4);
 				}
@@ -298,6 +345,7 @@
 
 	public void disconnect() {
 		this.disconnected = true;
+		this.netManager.wakeThreads();
 		this.netManager.networkShutdown("Closed");
 	}
 
@@ -311,43 +359,215 @@
 		var10.serverPosX = var1.xPosition;
 		var10.serverPosY = var1.yPosition;
 		var10.serverPosZ = var1.zPosition;
+		var10.entityID = var1.entityId;
 		var10.setPositionAndRotation(var2, var4, var6, var8, var9);
 		var10.isAIEnabled = true;
 		this.worldClient.addEntityToWorld(var1.entityId, var10);
+		List var11 = var1.getMetadata();
+		if(var11 != null) {
+			var10.getDataWatcher().updateWatchedObjectsFromList(var11);
+		}
 	}
 
 	public void handleUpdateTime(Packet4UpdateTime var1) {
 		this.mc.theWorld.setWorldTime(var1.time);
 	}
 
-	public void handlePlayerInventory(Packet5PlayerInventory var1) {
-		EntityPlayerSP var2 = this.mc.thePlayer;
-		if(var1.inventoryType == -1) {
-			var2.inventory.mainInventory = var1.inventory;
-		}
-
-		if(var1.inventoryType == -2) {
-			var2.inventory.craftingInventory = var1.inventory;
-		}
-
-		if(var1.inventoryType == -3) {
-			var2.inventory.armorInventory = var1.inventory;
-		}
-
-	}
-
-	public void handleComplexEntity(Packet59ComplexEntity var1) {
-		TileEntity var2 = this.worldClient.getBlockTileEntity(var1.xCoord, var1.yCoord, var1.zCoord);
-		if(var2 != null) {
-			var2.readFromNBT(var1.tileEntityNBT);
-			this.worldClient.markBlocksDirty(var1.xCoord, var1.yCoord, var1.zCoord, var1.xCoord, var1.yCoord, var1.zCoord);
-		}
-
-	}
-
 	public void handleSpawnPosition(Packet6SpawnPosition var1) {
 		this.worldClient.spawnX = var1.xPosition;
 		this.worldClient.spawnY = var1.yPosition;
 		this.worldClient.spawnZ = var1.zPosition;
+	}
+	
+	public void func_6497_a(Packet39AttachEntity var1) {
+		Object var2 = this.getEntityByID(var1.entityId);
+		Entity var3 = this.getEntityByID(var1.vehicleEntityId);
+		if(var1.entityId == this.mc.thePlayer.entityID) {
+			var2 = this.mc.thePlayer;
+		}
+
+		if(var2 != null) {
+			((Entity)var2).mountEntity(var3);
+		}
+	}
+
+	public void func_9447_a(Packet38EntityStatus var1) {
+		Entity var2 = this.getEntityByID(var1.entityId);
+		if(var2 != null) {
+			var2.handleHealthUpdate(var1.entityStatus);
+		}
+
+	}
+
+	private Entity getEntityByID(int var1) {
+		return (Entity)(var1 == this.mc.thePlayer.entityID ? this.mc.thePlayer : this.worldClient.getEntityByID(var1));
+	}
+
+	public void handleHealth(Packet8UpdateHealth var1) {
+		this.mc.thePlayer.setHealth(var1.healthMP);
+	}
+
+	public void func_9448_a(Packet9Respawn var1) {
+		this.posUpdated = false;
+		this.worldClient = new WorldClient(this);
+		this.worldClient.multiplayerWorld = true;
+		this.mc.changeWorld1(this.worldClient);
+		this.mc.displayGuiScreen(new GuiDownloadTerrain(this));
+
+		this.mc.respawn();
+	}
+
+	public void func_12245_a(Packet60Explosion var1) {
+		Explosion var2 = new Explosion(this.mc.theWorld, (Entity)null, var1.explosionX, var1.explosionY, var1.explosionZ, var1.explosionSize);
+		var2.destroyedBlockPositions = var1.destroyedBlockPositions;
+		var2.doExplosionB(true);
+	}
+
+	public void func_20087_a(Packet100OpenWindow var1) {
+		if(var1.inventoryType == 0) {
+			InventoryBasic var2 = new InventoryBasic(var1.windowTitle, var1.slotsCount);
+			this.mc.thePlayer.displayGUIChest(var2);
+			this.mc.thePlayer.craftingInventory.windowId = var1.windowId;
+		} else if(var1.inventoryType == 2) {
+			TileEntityFurnace var3 = new TileEntityFurnace();
+			this.mc.thePlayer.displayGUIFurnace(var3);
+			this.mc.thePlayer.craftingInventory.windowId = var1.windowId;
+		} else if(var1.inventoryType == 1) {
+			EntityPlayerSP var5 = this.mc.thePlayer;
+			this.mc.thePlayer.displayWorkbenchGUI(MathHelper.floor_double(var5.posX), MathHelper.floor_double(var5.posY), MathHelper.floor_double(var5.posZ));
+			this.mc.thePlayer.craftingInventory.windowId = var1.windowId;
+		}
+
+	}
+
+	public void func_20088_a(Packet103SetSlot var1) {
+		if(var1.windowId == -1) {
+			this.mc.thePlayer.inventory.setItemStack(var1.myItemStack);
+		} else if(var1.windowId == 0 && var1.itemSlot >= 36 && var1.itemSlot < 45) {
+			ItemStack var2 = this.mc.thePlayer.inventorySlots.getSlot(var1.itemSlot).getStack();
+			if(var1.myItemStack != null && (var2 == null || var2.stackSize < var1.myItemStack.stackSize)) {
+				var1.myItemStack.animationsToGo = 5;
+			}
+
+			this.mc.thePlayer.inventorySlots.putStackInSlot(var1.itemSlot, var1.myItemStack);
+		} else if(var1.windowId == this.mc.thePlayer.craftingInventory.windowId) {
+			this.mc.thePlayer.craftingInventory.putStackInSlot(var1.itemSlot, var1.myItemStack);
+		}
+
+	}
+
+	public void func_20089_a(Packet106Transaction var1) {
+		Container var2 = null;
+		if(var1.windowId == 0) {
+			var2 = this.mc.thePlayer.inventorySlots;
+		} else if(var1.windowId == this.mc.thePlayer.craftingInventory.windowId) {
+			var2 = this.mc.thePlayer.craftingInventory;
+		}
+
+		if(var2 != null) {
+			if(var1.field_20030_c) {
+				var2.func_20113_a(var1.field_20028_b);
+			} else {
+				var2.func_20110_b(var1.field_20028_b);
+				this.addToSendQueue(new Packet106Transaction(var1.windowId, var1.field_20028_b, true));
+			}
+		}
+
+	}
+
+	public void func_20094_a(Packet104WindowItems var1) {
+		if(var1.windowId == 0) {
+			this.mc.thePlayer.inventorySlots.putStacksInSlots(var1.itemStack);
+		} else if(var1.windowId == this.mc.thePlayer.craftingInventory.windowId) {
+			this.mc.thePlayer.craftingInventory.putStacksInSlots(var1.itemStack);
+		}
+
+	}
+
+	public void handleSignUpdate(Packet130UpdateSign var1) {
+		if(this.mc.theWorld.blockExists(var1.xPosition, var1.yPosition, var1.zPosition)) {
+			TileEntity var2 = this.mc.theWorld.getBlockTileEntity(var1.xPosition, var1.yPosition, var1.zPosition);
+			if(var2 instanceof TileEntitySign) {
+				TileEntitySign var3 = (TileEntitySign)var2;
+
+				for(int var4 = 0; var4 < 4; ++var4) {
+					var3.signText[var4] = var1.signLines[var4];
+				}
+
+				var3.onInventoryChanged();
+			}
+		}
+
+	}
+
+	public void func_20090_a(Packet105UpdateProgressbar var1) {
+		this.registerPacket(var1);
+		if(this.mc.thePlayer.craftingInventory != null && this.mc.thePlayer.craftingInventory.windowId == var1.windowId) {
+			this.mc.thePlayer.craftingInventory.func_20112_a(var1.progressBar, var1.progressBarValue);
+		}
+
+	}
+
+	public void handlePlayerInventory(Packet5PlayerInventory var1) {
+		Entity var2 = this.getEntityByID(var1.entityID);
+		if(var2 != null) {
+			var2.outfitWithItem(var1.slot, var1.itemID, var1.itemDamage);
+		}
+
+	}
+
+	public void func_20092_a(Packet101CloseWindow var1) {
+		this.mc.thePlayer.closeScreen();
+	}
+	
+	public void func_28115_a(Packet61DoorChange var1) {
+		this.mc.theWorld.func_28106_e(var1.field_28050_a, var1.field_28053_c, var1.field_28052_d, var1.field_28051_e, var1.field_28049_b);
+	}
+	
+	public void handle62Sound(Packet62Sound packet) {
+		if (!this.mc.options.accept62) return;
+		this.mc.renderGlobal.playSound(packet.sound, packet.locX, packet.locY, packet.locZ, packet.f, packet.f1);
+	}
+
+	@Override
+	public void handleParticle(Packet63WorldParticles packet) {
+		//System.out.println("Particle !!!! " + packet.getType() + ", " + packet.getCount() + ", " + packet.getX() + ", " + packet.getY() + ", " + packet.getZ());
+		for (int i = 0; i < packet.getCount(); i++) {
+			double d = this.rand.nextGaussian() * packet.getVelocityX();
+			double e = this.rand.nextGaussian() * packet.getVelocityY();
+			double f = this.rand.nextGaussian() * packet.getVelocityZ();
+			double g = this.rand.nextGaussian() * packet.getVelocityScale();
+			double h = this.rand.nextGaussian() * packet.getVelocityScale();
+			double j = this.rand.nextGaussian() * packet.getVelocityScale();
+			this.mc.renderGlobal.spawnParticle(packet.getType(), packet.getX() + d, packet.getY() + e, packet.getZ() + f, g, h, j);
+		}
+	}
+
+	private Map<Integer, Integer> miningSoundTimer = new HashMap<>();
+	@Override
+	public void handle55BlockBreakAnimation(Packet55BlockBreakAnimation packet) {
+		int x = packet.getX();
+		int y = packet.getY();
+		int z = packet.getZ();
+		this.mc.renderGlobal.updateBlockMiningProgress(packet.getPlayerId(), x, y, z, packet.getProgress());
+
+		int timer = this.miningSoundTimer.getOrDefault(packet.getPlayerId(), 0);
+		
+		Block block = Block.blocksList[this.worldClient.getBlockId(x, y, z)];
+		if (block != null && packet.getProgress() >= 0 && y >= 0 && timer % 3 == 0) {
+			this.mc.sndManager.playSound(block.stepSound.getStepSound(), x + 0.5F, y + 0.5F, z + 0.5F, (block.stepSound.getVolume() + 1.0F) / 8.0F, block.stepSound.getPitch() * 0.5F);
+		}
+		
+		if (packet.getProgress() != 255) {
+			this.miningSoundTimer.put(packet.getPlayerId(), ++timer);
+		} else {
+			this.miningSoundTimer.remove(packet.getPlayerId());
+		}
+		
+		
+	}
+
+	public boolean isServerHandler() {
+		return false;
 	}
 }
--- /dev/null
+++ net/minecraft/src/ItemWool.java
@@ -1,0 +1,20 @@
+package net.minecraft.src;
+
+public class ItemWool extends ItemBlock {
+
+	public ItemWool(int i) {
+		super(i);
+		this.setMaxDamage(0);
+		this.setHasSubtypes(true);
+	}
+
+	@Override
+	public int getSprite(int metadata) {
+		return Block.cloth.getBlockTextureFromSideAndMetadata(2, BlockWool.getBlockMetadataForItemMetadata(metadata));
+	}
+
+	@Override
+	public int getPlacedBlockMetadata(int metadata) {
+		return metadata;
+	}
+}
--- net/minecraft/src/ItemBow.java
+++ net/minecraft/src/ItemBow.java
@@ -9,7 +9,9 @@
 	public ItemStack onItemRightClick(ItemStack var1, World var2, EntityPlayer var3) {
 		if(var3.inventory.consumeInventoryItem(Item.arrow.shiftedIndex)) {
 			var2.playSoundAtEntity(var3, "random.bow", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F));
-			var2.spawnEntityInWorld(new EntityArrow(var2, var3));
+			if (!var2.multiplayerWorld) {
+			    var2.spawnEntityInWorld(new EntityArrow(var2, var3));
+			}
 		}
 
 		return var1;
--- net/minecraft/src/PlayerControllerMP.java
+++ net/minecraft/src/PlayerControllerMP.java
@@ -3,155 +3,421 @@
 import net.minecraft.client.Minecraft;
 
 public class PlayerControllerMP extends PlayerController {
-	private int currentBlockX = -1;
-	private int currentBlockY = -1;
-	private int currentBlockZ = -1;
-	private float curBlockDamageMP = 0.0F;
-	private float prevBlockDamageMP = 0.0F;
-	private float stepSoundTickCounter = 0.0F;
-	private int blockHitDelay = 0;
-	private boolean isHittingBlock = false;
+//	private int currentBlockX = -1;
+//	private int currentBlockY = -1;
+//	private int currentBlockZ = -1;
+//	private float curBlockDamageMP = 0.0F;
+//	private float prevBlockDamageMP = 0.0F;
+//	private float stepSoundTickCounter = 0.0F;
+//	private int blockHitDelay = 0;
+//	private boolean isHittingBlock = false;
+//	private int currentPlayerItem = 0;
 	private NetClientHandler netClientHandler;
-	private int currentPlayerItem = 0;
 
 	public PlayerControllerMP(Minecraft var1, NetClientHandler var2) {
 		super(var1);
 		this.netClientHandler = var2;
 	}
 
-	public void flipPlayer(EntityPlayer var1) {
-		var1.rotationYaw = -180.0F;
-	}
-
-	public boolean sendBlockRemoved(int var1, int var2, int var3, int var4) {
-		this.netClientHandler.addToSendQueue(new Packet14BlockDig(3, var1, var2, var3, var4));
-		int var5 = this.mc.theWorld.getBlockId(var1, var2, var3);
-		int var6 = this.mc.theWorld.getBlockMetadata(var1, var2, var3);
-		boolean var7 = super.sendBlockRemoved(var1, var2, var3, var4);
-		ItemStack var8 = this.mc.thePlayer.getCurrentEquippedItem();
-		if(var8 != null) {
-			var8.onDestroyBlock(var5, var1, var2, var3);
-			if(var8.stackSize == 0) {
-				var8.onItemDestroyedByUse(this.mc.thePlayer);
-				this.mc.thePlayer.destroyCurrentEquippedItem();
-			}
-		}
-
-		if(var7 && this.mc.thePlayer.canHarvestBlock(Block.blocksList[var5])) {
-			Block.blocksList[var5].dropBlockAsItem(this.mc.theWorld, var1, var2, var3, var6);
-		}
-
-		return var7;
-	}
-
-	public void clickBlock(int var1, int var2, int var3, int var4) {
-		this.isHittingBlock = true;
-		this.netClientHandler.addToSendQueue(new Packet14BlockDig(0, var1, var2, var3, var4));
-		int var5 = this.mc.theWorld.getBlockId(var1, var2, var3);
-		if(var5 > 0 && this.curBlockDamageMP == 0.0F) {
-			Block.blocksList[var5].onBlockClicked(this.mc.theWorld, var1, var2, var3, this.mc.thePlayer);
-		}
-
-		if(var5 > 0 && Block.blocksList[var5].blockStrength(this.mc.thePlayer) >= 1.0F) {
-			this.sendBlockRemoved(var1, var2, var3, var4);
-		}
-
-	}
-
-	public void resetBlockRemoving() {
-		if(this.isHittingBlock) {
-			this.isHittingBlock = false;
-			this.netClientHandler.addToSendQueue(new Packet14BlockDig(2, 0, 0, 0, 0));
-			this.curBlockDamageMP = 0.0F;
-			this.blockHitDelay = 0;
-		}
-	}
-
-	public void sendBlockRemoving(int var1, int var2, int var3, int var4) {
-		this.isHittingBlock = true;
-		this.syncCurrentPlayItem();
-		this.netClientHandler.addToSendQueue(new Packet14BlockDig(1, var1, var2, var3, var4));
-		if(this.blockHitDelay > 0) {
-			--this.blockHitDelay;
-		} else {
-			if(var1 == this.currentBlockX && var2 == this.currentBlockY && var3 == this.currentBlockZ) {
-				int var5 = this.mc.theWorld.getBlockId(var1, var2, var3);
-				if(var5 == 0) {
-					return;
-				}
-
-				Block var6 = Block.blocksList[var5];
-				this.curBlockDamageMP += var6.blockStrength(this.mc.thePlayer);
-				if(this.stepSoundTickCounter % 4.0F == 0.0F && var6 != null) {
-					this.mc.sndManager.playSound(var6.stepSound.getStepSound(), (float)var1 + 0.5F, (float)var2 + 0.5F, (float)var3 + 0.5F, (var6.stepSound.getVolume() + 1.0F) / 8.0F, var6.stepSound.getPitch() * 0.5F);
-				}
-
-				++this.stepSoundTickCounter;
-				if(this.curBlockDamageMP >= 1.0F) {
-					this.sendBlockRemoved(var1, var2, var3, var4);
-					this.curBlockDamageMP = 0.0F;
-					this.prevBlockDamageMP = 0.0F;
-					this.stepSoundTickCounter = 0.0F;
-					this.blockHitDelay = 5;
-				}
-			} else {
-				this.curBlockDamageMP = 0.0F;
-				this.prevBlockDamageMP = 0.0F;
-				this.stepSoundTickCounter = 0.0F;
-				this.currentBlockX = var1;
-				this.currentBlockY = var2;
-				this.currentBlockZ = var3;
-			}
-
-		}
-	}
-
-	public void setPartialTime(float var1) {
-		if(this.curBlockDamageMP <= 0.0F) {
-			this.mc.ingameGUI.damageGuiPartialTime = 0.0F;
-			this.mc.renderGlobal.damagePartialTime = 0.0F;
-		} else {
-			float var2 = this.prevBlockDamageMP + (this.curBlockDamageMP - this.prevBlockDamageMP) * var1;
-			this.mc.ingameGUI.damageGuiPartialTime = var2;
-			this.mc.renderGlobal.damagePartialTime = var2;
-		}
-
-	}
-
-	public float getBlockReachDistance() {
-		return 4.0F;
-	}
-
-	public void onWorldChange(World var1) {
-		super.onWorldChange(var1);
-	}
-
-	public void onUpdate() {
-		this.syncCurrentPlayItem();
-		this.prevBlockDamageMP = this.curBlockDamageMP;
-	}
-
-	private void syncCurrentPlayItem() {
-		ItemStack var1 = this.mc.thePlayer.inventory.getCurrentItem();
-		int var2 = 0;
-		if(var1 != null) {
-			var2 = var1.itemID;
-		}
-
-		if(var2 != this.currentPlayerItem) {
-			this.currentPlayerItem = var2;
-			this.netClientHandler.addToSendQueue(new Packet16BlockItemSwitch(0, this.currentPlayerItem));
-		}
-
-	}
-
-	public boolean onPlayerRightClick(EntityPlayer var1, World var2, ItemStack var3, int var4, int var5, int var6, int var7) {
-		this.syncCurrentPlayItem();
-		this.netClientHandler.addToSendQueue(new Packet15Place(var3 != null ? var3.itemID : -1, var4, var5, var6, var7));
-		return super.onPlayerRightClick(var1, var2, var3, var4, var5, var6, var7);
-	}
-
-	public EntityPlayer createPlayer(World var1) {
-		return new EntityClientPlayerMP(this.mc, var1, this.mc.session, this.netClientHandler);
-	}
+//	public void flipPlayer(EntityPlayer var1) {
+//		var1.rotationYaw = -180.0F;
+//	}
+//
+//	public boolean sendBlockRemoved(int var1, int var2, int var3, int var4) {
+//		int var5 = this.mc.theWorld.getBlockId(var1, var2, var3);
+//		boolean var6 = super.sendBlockRemoved(var1, var2, var3, var4);
+//		ItemStack var7 = this.mc.thePlayer.getCurrentEquippedItem();
+//		if(var7 != null) {
+//			var7.onDestroyBlock(var5, var1, var2, var3, this.mc.thePlayer);
+//			if(var7.stackSize == 0) {
+//				var7.func_1097_a(this.mc.thePlayer);
+//				this.mc.thePlayer.destroyCurrentEquippedItem();
+//			}
+//		}
+//
+//		return var6;
+//	}
+//
+//	public void clickBlock(int var1, int var2, int var3, int var4) {
+//		if(!this.isHittingBlock || var1 != this.currentBlockX || var2 != this.currentBlockY || var3 != this.currentBlockZ) {
+//			this.netClientHandler.addToSendQueue(new Packet14BlockDig(0, var1, var2, var3, var4));
+//			int var5 = this.mc.theWorld.getBlockId(var1, var2, var3);
+//			if(var5 > 0 && this.curBlockDamageMP == 0.0F) {
+//				Block.blocksList[var5].onBlockClicked(this.mc.theWorld, var1, var2, var3, this.mc.thePlayer);
+//			}
+//
+//			float strength = Block.blocksList[var5].blockStrength(this.mc.thePlayer);
+//			if(var5 > 0 && strength >= 1.0F) {
+//				this.sendBlockRemoved(var1, var2, var3, var4);
+//			} else {
+//				this.isHittingBlock = true;
+//				this.currentBlockX = var1;
+//				this.currentBlockY = var2;
+//				this.currentBlockZ = var3;
+//				int j = (int)(strength * 10.0F);
+//				this.mc.renderGlobal.updateBlockMiningProgress(this.mc.thePlayer.entityID, var1, var2, var3, j);
+//				this.prevBlockDamageMP = j;
+//				this.curBlockDamageMP = 0.0F;
+//				this.prevBlockDamageMP = 0.0F;
+//				this.stepSoundTickCounter = 0.0F;
+//			}
+//		}
+//
+//	}
+//
+//	public void resetBlockRemoving() {
+//		this.curBlockDamageMP = 0.0F;
+//		this.isHittingBlock = false;
+//		this.mc.renderGlobal.updateBlockMiningProgress(this.mc.thePlayer.entityID, this.currentBlockX, this.currentBlockY, this.currentBlockZ, -1);
+//	}
+//
+//	public void sendBlockRemoving(int var1, int var2, int var3, int var4) {
+//		if(this.isHittingBlock) {
+//			this.syncCurrentPlayItem();
+//			if(this.blockHitDelay > 0) {
+//				--this.blockHitDelay;
+//			} else {
+//				if(var1 == this.currentBlockX && var2 == this.currentBlockY && var3 == this.currentBlockZ) {
+//					int var5 = this.mc.theWorld.getBlockId(var1, var2, var3);
+//					if(var5 == 0) {
+//						this.isHittingBlock = false;
+//						return;
+//					}
+//
+//					Block var6 = Block.blocksList[var5];
+//					this.curBlockDamageMP += var6.blockStrength(this.mc.thePlayer);
+//					if(this.stepSoundTickCounter % 4.0F == 0.0F && var6 != null) {
+//						this.mc.sndManager.playSound(var6.stepSound.getBreakSound(), (float)var1 + 0.5F, (float)var2 + 0.5F, (float)var3 + 0.5F, (var6.stepSound.getVolume() + 1.0F) / 8.0F, var6.stepSound.getPitch() * 0.5F);
+//					}
+//
+//					++this.stepSoundTickCounter;
+//					if(this.curBlockDamageMP >= 1.0F) {
+//						this.isHittingBlock = false;
+//						this.netClientHandler.addToSendQueue(new Packet14BlockDig(2, var1, var2, var3, var4));
+//						this.sendBlockRemoved(var1, var2, var3, var4);
+//						this.curBlockDamageMP = 0.0F;
+//						this.prevBlockDamageMP = 0.0F;
+//						this.stepSoundTickCounter = 0.0F;
+//						this.blockHitDelay = 5;
+//					}
+//				} else {
+//					this.clickBlock(var1, var2, var3, var4);
+//				}
+//
+//			}
+//		}
+//	}
+//
+//	public void setPartialTime(float var1) {
+//		if(this.curBlockDamageMP <= 0.0F) {
+//			this.mc.ingameGUI.damageGuiPartialTime = 0.0F;
+//			//this.mc.renderGlobal.damagePartialTime = 0.0F;
+//            this.mc.renderGlobal.updateBlockMiningProgress(this.mc.thePlayer.entityID, this.currentBlockX, this.currentBlockY, this.currentBlockZ, -1);
+//		} else {
+//			float var2 = this.prevBlockDamageMP + (this.curBlockDamageMP - this.prevBlockDamageMP) * var1;
+//			this.mc.ingameGUI.damageGuiPartialTime = var2;
+//			//this.mc.renderGlobal.damagePartialTime = var2;
+//            this.mc.renderGlobal.updateBlockMiningProgress(this.mc.thePlayer.entityID, this.currentBlockX, this.currentBlockY, this.currentBlockZ, (int)curBlockDamageMP);
+//		}
+//
+//	}
+//
+//	public float getBlockReachDistance() {
+//		return 4.0F;
+//	}
+//
+//	public void onWorldChange(World var1) {
+//		super.onWorldChange(var1);
+//	}
+//
+//	public void onUpdate() {
+//		this.syncCurrentPlayItem();
+//		this.prevBlockDamageMP = this.curBlockDamageMP;
+//		this.mc.sndManager.playRandomMusicIfReady();
+//	}
+//
+//	private void syncCurrentPlayItem() {
+//		int var1 = this.mc.thePlayer.inventory.currentItem;
+//		if(var1 != this.currentPlayerItem) {
+//			this.currentPlayerItem = var1;
+//			this.netClientHandler.addToSendQueue(new Packet16BlockItemSwitch(this.currentPlayerItem));
+//		}
+//
+//	}
+//	
+//	public boolean sendPlaceBlock(EntityPlayer var1, World var2, ItemStack var3, int var4, int var5, int var6, int var7) {
+//		this.syncCurrentPlayItem();
+//		this.netClientHandler.addToSendQueue(new Packet15Place(var4, var5, var6, var7, var1.inventory.getCurrentItem()));
+//		boolean var8 = super.sendPlaceBlock(var1, var2, var3, var4, var5, var6, var7);
+//		return var8;
+//	}
+//
+//	public boolean sendUseItem(EntityPlayer var1, World var2, ItemStack var3) {
+//		this.syncCurrentPlayItem();
+//		this.netClientHandler.addToSendQueue(new Packet15Place(-1, -1, -1, 255, var1.inventory.getCurrentItem()));
+//		boolean var4 = super.sendUseItem(var1, var2, var3);
+//		return var4;
+//	}
+//
+//	public EntityPlayer createPlayer(World var1) {
+//		return new EntityClientPlayerMP(this.mc, var1, this.mc.session, this.netClientHandler);
+//	}
+//
+//	public void attackEntity(EntityPlayer var1, Entity var2) {
+//		this.syncCurrentPlayItem();
+//		this.netClientHandler.addToSendQueue(new Packet7UseEntity(var1.entityID, var2.entityID, 1));
+//		var1.attackTargetEntityWithCurrentItem(var2);
+//	}
+//
+//	public void interactWithEntity(EntityPlayer var1, Entity var2) {
+//		this.syncCurrentPlayItem();
+//		this.netClientHandler.addToSendQueue(new Packet7UseEntity(var1.entityID, var2.entityID, 0));
+//		var1.useCurrentItemOnEntity(var2);
+//	}
+//
+//	public ItemStack func_27174_a(int var1, int var2, int var3, boolean var4, EntityPlayer var5) {
+//		short var6 = var5.craftingInventory.func_20111_a(var5.inventory);
+//		ItemStack var7 = super.func_27174_a(var1, var2, var3, var4, var5);
+//		this.netClientHandler.addToSendQueue(new Packet102WindowClick(var1, var2, var3, var4, var7, var6));
+//		return var7;
+//	}
+//
+	public void func_20086_a(int var1, EntityPlayer var2) {
+		if(var1 != -9999) {
+		}
+	}
+	   private int targetBlockX;
+	   private int targetBlockY;
+	   private int targetBlockZ;
+	   private ItemStack miningTool = null;
+	   private float miningProgress = 0.0F;
+	   private float miningSoundTimer = 0.0F;
+	   private int miningCooldown = 0;
+	   private boolean isMiningBlock = false;
+	   private int selectedHotbarSlot = 0;
+
+	   @Override
+	   public void sendBlockRemoving(int x, int y, int z, int face) {
+		   if (this.isMiningBlock && this.isMiningBlock(x, y, z)) {
+			   return;
+		   }
+		   if (this.isMiningBlock) {
+			   this.netClientHandler.addToSendQueue(new Packet14BlockDig(1, this.targetBlockX, this.targetBlockY, this.targetBlockZ, face));
+		   }
+
+		   this.netClientHandler.addToSendQueue(new Packet14BlockDig(0, x, y, z, face));
+		   int i = this.mc.theWorld.getBlockId(x, y, z);
+		   if (i > 0 && this.miningProgress == 0.0F) {
+			   Block.blocksList[i].onBlockClicked(this.mc.theWorld, x, y, z, this.mc.thePlayer); // startMining
+		   }
+
+		   if (i > 0 && Block.blocksList[i].blockStrength(this.mc.thePlayer) >= 1.0F) {
+			   this.sendBlockRemoved(x, y, z, face);
+		   } else {
+			   this.isMiningBlock = true;
+			   this.targetBlockX = x;
+			   this.targetBlockY = y;
+			   this.targetBlockZ = z;
+			   this.miningTool = this.mc.thePlayer.getCurrentEquippedItem();
+			   this.miningProgress = 0.0F;
+			   this.miningSoundTimer = 0.0F;
+			   this.mc
+			   .renderGlobal
+			   .updateBlockMiningProgress(
+					   this.mc.thePlayer.entityID, this.targetBlockX, this.targetBlockY, this.targetBlockZ, (int)(this.miningProgress * 10.0F) - 1
+					   );
+		   }
+	   }
+
+	   @Override
+	   public boolean sendBlockRemoved(int x, int y, int z, int face) {
+		   Block block = Block.blocksList[this.mc.theWorld.getBlockId(x, y, z)];
+		   if (block == null) {
+			   return false;
+		   } else {
+			   //this.mc.sndManager.playSound(block.stepSound.getBreakSound(), (float)x + 0.5F, (float)y + 0.5F, (float)z + 0.5F, (block.stepSound.getVolume() + 1.0F) / 8.0F, block.stepSound.getPitch() * 0.5F);
+			   //this.mc.theWorld.doEvent(2001, x, y, z, block.blockID + (this.mc.theWorld.getBlockMetadata(x, y, z) << 12));
+			   // TODO: investigate block disintegrating particles
+			   this.mc.effectRenderer.addBlockDestroyEffects(x, y, z);
+			   int i = this.mc.theWorld.getBlockMetadata(x, y, z);
+			   boolean j = this.mc.theWorld.setBlockWithNotify(x, y, z, 0);
+			   if (j) {
+				   this.mc.sndManager.playSound(block.stepSound.getBreakSound(), (float)x + 0.5F, (float)y + 0.5F, (float)z + 0.5F, (block.stepSound.getVolume() + 1.0F) / 2.0F, block.stepSound.getPitch() * 0.8F);
+				   block.onBlockDestroyedByPlayer(this.mc.theWorld, x, y, z, i); // onBroken
+			   }
+
+			   this.targetBlockY = -1;
+			   ItemStack itemStack = this.mc.thePlayer.getCurrentEquippedItem();
+			   if (itemStack != null) {
+				   itemStack.onDestroyBlock(block.blockID, x, y, z, this.mc.thePlayer);
+				   if (itemStack.stackSize == 0) {
+					   this.mc.thePlayer.destroyCurrentEquippedItem();
+				   }
+			   }
+
+			   return (boolean)j;
+		   }
+	   }
+
+	   @Override
+	   public void resetBlockRemoving() {
+	      if (this.isMiningBlock) {
+	         this.netClientHandler.addToSendQueue(new Packet14BlockDig(1, this.targetBlockX, this.targetBlockY, this.targetBlockZ, -1));
+	      }
+
+	      this.isMiningBlock = false;
+	      this.miningProgress = 0.0F;
+	      this.mc.renderGlobal.updateBlockMiningProgress(this.mc.thePlayer.entityID, this.targetBlockX, this.targetBlockY, this.targetBlockZ, -1);
+	   }
+
+	   @Override
+	   public void clickBlock(int x, int y, int z, int face) {
+	      this.updateSelectedHotbarSlot();
+	      if (this.miningCooldown > 0) {
+	         this.miningCooldown--;
+	      } else {
+	         if (this.isMiningBlock(x, y, z)) {
+	            int i = this.mc.theWorld.getBlockId(x, y, z);
+	            if (i == 0) {
+	               this.isMiningBlock = false;
+	               return;
+	            }
+
+	            Block block = Block.blocksList[i];
+	            this.miningProgress = this.miningProgress + block.blockStrength(this.mc.thePlayer);
+	            if (this.miningSoundTimer % 4.0F == 0.0F && block != null) {
+	               this.mc
+	                  .sndManager
+	                  .playSound(block.stepSound.getStepSound(), x + 0.5F, y + 0.5F, z + 0.5F, (block.stepSound.getVolume() + 1.0F) / 8.0F, block.stepSound.getPitch() * 0.5F);
+	            }
+
+	            this.miningSoundTimer++;
+	            if (this.miningProgress >= 1.0F) {
+	               this.isMiningBlock = false;
+	               this.netClientHandler.addToSendQueue(new Packet14BlockDig(2, x, y, z, face));
+	               this.sendBlockRemoved(x, y, z, face);
+	               this.miningProgress = 0.0F;
+	               this.miningSoundTimer = 0.0F;
+	               this.miningCooldown = 5;
+	            }
+
+	            this.mc
+	               .renderGlobal
+	               .updateBlockMiningProgress(
+	                  this.mc.thePlayer.entityID, this.targetBlockX, this.targetBlockY, this.targetBlockZ, (int)(this.miningProgress * 10.0F) - 1
+	               );
+	         } else {
+	            this.sendBlockRemoving(x, y, z, face);
+	         }
+	      }
+	   }
+
+	   @Override
+	   public float getBlockReachDistance() {
+	      return 4.0F;
+	   }
+
+	   @Override
+	   public void onUpdate() {
+	      this.updateSelectedHotbarSlot();
+	      this.mc.sndManager.playRandomMusicIfReady();
+	   }
+
+	   private boolean isMiningBlock(int x, int y, int z) {
+	      ItemStack itemStack = this.mc.thePlayer.getCurrentEquippedItem();
+	      int i = this.miningTool == null && itemStack == null ? 1 : 0;
+	      if (this.miningTool != null && itemStack != null) {
+	         i = itemStack.itemID != this.miningTool.itemID
+	               || !itemStack.isItemStackDamageable() && itemStack.getItemDamage() != this.miningTool.getItemDamage()
+	            ? 0
+	            : 1;
+	      }
+
+	      return x == this.targetBlockX && y == this.targetBlockY && z == this.targetBlockZ && i != 0;
+	   }
+
+	   private void updateSelectedHotbarSlot() {
+	      int i = this.mc.thePlayer.inventory.currentItem;
+	      if (i != this.selectedHotbarSlot) {
+	         this.selectedHotbarSlot = i;
+	         this.netClientHandler.addToSendQueue(new Packet16BlockItemSwitch(this.selectedHotbarSlot));
+	      }
+	   }
+
+	   @Override
+	   public boolean sendPlaceBlock(EntityPlayer player, World world, ItemStack item, int x, int y, int z, int face) {
+	      this.updateSelectedHotbarSlot();
+	      int i = 0;
+	      int j = world.getBlockId(x, y, z);
+	      if (j > 0 && Block.blocksList[j].blockActivated(world, x, y, z, player)) { // use
+	    	  i = 1;
+	      }
+
+	      if (i == 0 && item != null && item.getItem() instanceof ItemBlock) {
+	    	  ItemBlock blockItem = (ItemBlock)item.getItem();
+	         if (!blockItem.onPlace(item, player, world, x, y, z, face)) {
+	            return false;
+	         }
+	      }
+
+	      this.netClientHandler.addToSendQueue(new Packet15Place(x, y, z, face, player.inventory.getCurrentItem()));
+	      if (i != 0) {
+	         return true;
+	      } else if (item == null) {
+	         return false;
+	      } else {
+	         return item.useItem(player, world, x, y, z, face); // useOn
+	      }
+	   }
+
+	   @Override
+	   public boolean sendUseItem(EntityPlayer player, World world, ItemStack itemInHand) {
+	      this.updateSelectedHotbarSlot();
+	      this.netClientHandler.addToSendQueue(new Packet15Place(-1, -1, -1, 255, player.inventory.getCurrentItem()));
+	      int i = itemInHand.stackSize;
+	      ItemStack itemStack = itemInHand.useItemRightClick(world, player);
+	      if (itemStack != itemInHand || itemStack != null && itemStack.stackSize != i) {
+	         player.inventory.mainInventory[player.inventory.currentItem] = itemStack;
+	         if (itemStack.stackSize == 0) {
+	            player.inventory.mainInventory[player.inventory.currentItem] = null;
+	         }
+
+	         return true;
+	      } else {
+	         return false;
+	      }
+	   }
+
+	   @Override
+	   public EntityPlayer createPlayer(World var1) {
+			return new EntityClientPlayerMP(this.mc, var1, this.mc.session, this.netClientHandler);
+		}
+
+	   @Override
+	   public void attackEntity(EntityPlayer player, Entity target) {
+	      this.updateSelectedHotbarSlot();
+	      this.netClientHandler.addToSendQueue(new Packet7UseEntity(player.entityID, target.entityID, 1));
+	      player.attackTargetEntityWithCurrentItem(target);
+	   }
+
+	   @Override
+	   public void interactWithEntity(EntityPlayer player, Entity target) {
+	      this.updateSelectedHotbarSlot();
+	      this.netClientHandler.addToSendQueue(new Packet7UseEntity(player.entityID, target.entityID, 0));
+	      player.useCurrentItemOnEntity(target);
+	   }
+
+	   @Override
+	   public ItemStack func_27174_a(int syncId, int slotId, int clickData, boolean actionType, EntityPlayer player) {
+	      int i = player.craftingInventory.func_20111_a(player.inventory);
+	      ItemStack itemStack = super.func_27174_a(syncId, slotId, clickData, actionType, player);
+	      this.netClientHandler.addToSendQueue(new Packet102WindowClick(syncId, slotId, clickData, actionType, itemStack, (short)i));
+	      return itemStack;
+	   }
+
+	   public void stopUsingHand(EntityPlayer player) {
+	      this.updateSelectedHotbarSlot();
+	      this.netClientHandler.addToSendQueue(new Packet14BlockDig(5, 0, 0, 0, 255));
+	      //player.stopUsingItem();
+	   }
 }
--- net/minecraft/src/SlotArmor.java
+++ net/minecraft/src/SlotArmor.java
@@ -1,13 +1,17 @@
 package net.minecraft.src;
 
-class SlotArmor extends SlotInventory {
+class SlotArmor extends Slot {
 	final int armorType;
-	final GuiInventory guiInventory;
-
-	SlotArmor(GuiInventory var1, GuiContainer var2, IInventory var3, int var4, int var5, int var6, int var7) {
-		super(var2, var3, var4, var5, var6);
-		this.guiInventory = var1;
-		this.armorType = var7;
+	final ContainerPlayer inventory;
+
+	SlotArmor(ContainerPlayer var1, IInventory var2, int var3, int var4, int var5, int var6) {
+		super(var2, var3, var4, var5);
+		this.inventory = var1;
+		this.armorType = var6;
+	}
+
+	public int getSlotStackLimit() {
+		return 1;
 	}
 
 	public boolean isItemValid(ItemStack var1) {
--- net/minecraft/src/EntityClientPlayerMP.java
+++ net/minecraft/src/EntityClientPlayerMP.java
@@ -3,7 +3,7 @@
 import net.minecraft.client.Minecraft;
 
 public class EntityClientPlayerMP extends EntityPlayerSP {
-	private NetClientHandler sendQueue;
+	public NetClientHandler sendQueue;
 	private int motionUpdateCounter = 0;
 	private double oldPosX;
 	private double oldBasePos;
@@ -11,33 +11,47 @@
 	private double oldPosZ;
 	private float oldRotationYaw;
 	private float oldRotationPitch;
-	private InventoryPlayer serverSideInventory = new InventoryPlayer((EntityPlayer)null);
+	private boolean field_9382_bF = false;
+	private boolean wasSneaking = false;
+	private int field_12242_bI = 0;
 
 	public EntityClientPlayerMP(Minecraft var1, World var2, Session var3, NetClientHandler var4) {
 		super(var1, var2, var3);
 		this.sendQueue = var4;
 	}
+	
+	public boolean attackEntityFrom(Entity var1, int var2) {
+		return false;
+	}
+
+	public void heal(int var1) {
+	}
 
 	public void onUpdate() {
-		super.onUpdate();
-		this.sendMotionUpdates();
-	}
-
-	public void onPlayerUpdate() {
-		this.sendMotionUpdates();
+		if(this.worldObj.blockExists(MathHelper.floor_double(this.posX), 64, MathHelper.floor_double(this.posZ))) {
+			super.onUpdate();
+			this.sendMotionUpdates();
+		}
+		
 	}
 
 	public void sendMotionUpdates() {
 		if(this.motionUpdateCounter++ == 20) {
-			if(!this.inventory.getInventoryEqual(this.serverSideInventory)) {
-				this.sendQueue.addToSendQueue(new Packet5PlayerInventory(-1, this.inventory.mainInventory));
-				this.sendQueue.addToSendQueue(new Packet5PlayerInventory(-2, this.inventory.craftingInventory));
-				this.sendQueue.addToSendQueue(new Packet5PlayerInventory(-3, this.inventory.armorInventory));
-				this.serverSideInventory = this.inventory.copyInventory();
-			}
+			this.sendInventoryChanged();
 
 			this.motionUpdateCounter = 0;
 		}
+		
+		boolean sneak = this.isSneaking();
+		if(sneak != this.wasSneaking) {
+			if(sneak) {
+				this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 1));
+			} else {
+				this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 2));
+			}
+
+			this.wasSneaking = sneak;
+		}
 
 		double var1 = this.posX - this.oldPosX;
 		double var3 = this.boundingBox.minY - this.oldBasePos;
@@ -47,16 +61,33 @@
 		double var11 = (double)(this.rotationPitch - this.oldRotationPitch);
 		boolean var13 = var3 != 0.0D || var5 != 0.0D || var1 != 0.0D || var7 != 0.0D;
 		boolean var14 = var9 != 0.0D || var11 != 0.0D;
-		if(var13 && var14) {
+		if(this.ridingEntity != null) {
+			if(var14) {
+				this.sendQueue.addToSendQueue(new Packet11PlayerPosition(this.motionX, -999.0D, -999.0D, this.motionZ, this.onGround));
+			} else {
+				this.sendQueue.addToSendQueue(new Packet13PlayerLookMove(this.motionX, -999.0D, -999.0D, this.motionZ, this.rotationYaw, this.rotationPitch, this.onGround));
+			}
+
+			var13 = false;
+		} else if(var13 && var14) {
 			this.sendQueue.addToSendQueue(new Packet13PlayerLookMove(this.posX, this.boundingBox.minY, this.posY, this.posZ, this.rotationYaw, this.rotationPitch, this.onGround));
+			this.field_12242_bI = 0;
 		} else if(var13) {
 			this.sendQueue.addToSendQueue(new Packet11PlayerPosition(this.posX, this.boundingBox.minY, this.posY, this.posZ, this.onGround));
+			this.field_12242_bI = 0;
 		} else if(var14) {
 			this.sendQueue.addToSendQueue(new Packet12PlayerLook(this.rotationYaw, this.rotationPitch, this.onGround));
+			this.field_12242_bI = 0;
 		} else {
 			this.sendQueue.addToSendQueue(new Packet10Flying(this.onGround));
+			if(this.field_9382_bF == this.onGround && this.field_12242_bI <= 200) {
+				++this.field_12242_bI;
+			} else {
+				this.field_12242_bI = 0;
+			}
 		}
 
+		this.field_9382_bF = this.onGround;
 		if(var13) {
 			this.oldPosX = this.posX;
 			this.oldBasePos = this.boundingBox.minY;
@@ -71,24 +102,35 @@
 
 	}
 
-	protected void joinEntityItemWithWorld(EntityItem var1) {
-		System.out.println("Dropping?");
-		Packet21PickupSpawn var2 = new Packet21PickupSpawn(var1);
-		this.sendQueue.addToSendQueue(var2);
-		var1.posX = (double)var2.xPosition / 32.0D;
-		var1.posY = (double)var2.yPosition / 32.0D;
-		var1.posZ = (double)var2.zPosition / 32.0D;
-		var1.motionX = (double)var2.rotation / 128.0D;
-		var1.motionY = (double)var2.pitch / 128.0D;
-		var1.motionZ = (double)var2.roll / 128.0D;
-	}
-
 	public void sendChatMessage(String var1) {
 		this.sendQueue.addToSendQueue(new Packet3Chat(var1));
 	}
 
 	public void swingItem() {
 		super.swingItem();
-		this.sendQueue.addToSendQueue(new Packet18ArmAnimation(this, 1));
+		this.sendQueue.addToSendQueue(new Packet18Animation(this, 1));
+	}
+	
+	protected void damageEntity(int var1) {
+		this.health -= var1;
+	}
+	
+	public void respawnPlayer() {
+		this.sendInventoryChanged();
+		this.sendQueue.addToSendQueue(new Packet9Respawn((byte)0));
+	}
+	
+	@Override
+	public void dropCurrentItem() {
+		this.sendQueue.addToSendQueue(new Packet14BlockDig(4, 0, 0, 0, 0));
+	}
+
+	private void sendInventoryChanged() {
+	}
+	
+	public void closeScreen() {
+		this.sendQueue.addToSendQueue(new Packet101CloseWindow(this.craftingInventory.windowId));
+		this.inventory.setItemStack((ItemStack)null);
+		super.closeScreen();
 	}
 }
--- /dev/null
+++ net/minecraft/src/Packet28EntityVelocity.java
@@ -1,0 +1,73 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet28EntityVelocity extends Packet {
+	public int entityId;
+	public int motionX;
+	public int motionY;
+	public int motionZ;
+
+	public Packet28EntityVelocity() {
+	}
+
+	public Packet28EntityVelocity(Entity var1) {
+		this(var1.entityID, var1.motionX, var1.motionY, var1.motionZ);
+	}
+
+	public Packet28EntityVelocity(int var1, double var2, double var4, double var6) {
+		this.entityId = var1;
+		double var8 = 3.9D;
+		if(var2 < -var8) {
+			var2 = -var8;
+		}
+
+		if(var4 < -var8) {
+			var4 = -var8;
+		}
+
+		if(var6 < -var8) {
+			var6 = -var8;
+		}
+
+		if(var2 > var8) {
+			var2 = var8;
+		}
+
+		if(var4 > var8) {
+			var4 = var8;
+		}
+
+		if(var6 > var8) {
+			var6 = var8;
+		}
+
+		this.motionX = (int)(var2 * 8000.0D);
+		this.motionY = (int)(var4 * 8000.0D);
+		this.motionZ = (int)(var6 * 8000.0D);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.entityId = var1.readInt();
+		this.motionX = var1.readShort();
+		this.motionY = var1.readShort();
+		this.motionZ = var1.readShort();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.entityId);
+		var1.writeShort(this.motionX);
+		var1.writeShort(this.motionY);
+		var1.writeShort(this.motionZ);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_6498_a(this);
+	}
+
+	public int getPacketSize() {
+		return 10;
+	}
+}
--- net/minecraft/src/NetHandler.java
+++ net/minecraft/src/NetHandler.java
@@ -1,13 +1,15 @@
 package net.minecraft.src;
 
-public class NetHandler {
+public abstract class NetHandler {
+	public abstract boolean isServerHandler();
+
 	public void handleMapChunk(Packet51MapChunk var1) {
 	}
 
 	public void registerPacket(Packet var1) {
 	}
 
-	public void handleErrorMessage(String var1) {
+	public void handleErrorMessage(String var1, Object[] var2) {
 	}
 
 	public void handleKickDisconnect(Packet255KickDisconnect var1) {
@@ -74,15 +76,15 @@
 		this.registerPacket(var1);
 	}
 
-	public void handleAddToInventory(Packet17AddToInventory var1) {
-		this.registerPacket(var1);
-	}
-
 	public void handleVehicleSpawn(Packet23VehicleSpawn var1) {
 		this.registerPacket(var1);
 	}
 
-	public void handleArmAnimation(Packet18ArmAnimation var1) {
+	public void handleArmAnimation(Packet18Animation var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_21147_a(Packet19EntityAction var1) {
 		this.registerPacket(var1);
 	}
 
@@ -98,15 +100,123 @@
 		this.registerPacket(var1);
 	}
 
-	public void handlePlayerInventory(Packet5PlayerInventory var1) {
-		this.registerPacket(var1);
-	}
-
-	public void handleComplexEntity(Packet59ComplexEntity var1) {
-		this.registerPacket(var1);
-	}
-
 	public void handleSpawnPosition(Packet6SpawnPosition var1) {
 		this.registerPacket(var1);
+	}
+
+	public void func_6498_a(Packet28EntityVelocity var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_21148_a(Packet40EntityMetadata var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_6497_a(Packet39AttachEntity var1) {
+		this.registerPacket(var1);
+	}
+
+	public void handleUseEntity(Packet7UseEntity var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_9447_a(Packet38EntityStatus var1) {
+		this.registerPacket(var1);
+	}
+
+	public void handleHealth(Packet8UpdateHealth var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_9448_a(Packet9Respawn var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_12245_a(Packet60Explosion var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_20087_a(Packet100OpenWindow var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_20092_a(Packet101CloseWindow var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_20091_a(Packet102WindowClick var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_20088_a(Packet103SetSlot var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_20094_a(Packet104WindowItems var1) {
+		this.registerPacket(var1);
+	}
+
+	public void handleSignUpdate(Packet130UpdateSign var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_20090_a(Packet105UpdateProgressbar var1) {
+		this.registerPacket(var1);
+	}
+
+	public void handlePlayerInventory(Packet5PlayerInventory var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_20089_a(Packet106Transaction var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_21146_a(Packet25EntityPainting var1) {
+		this.registerPacket(var1);
+	}
+
+	public void handleNotePlay(Packet54PlayNoteBlock var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_27245_a(Packet200Statistic var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_22186_a(Packet17Sleep var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_22185_a(Packet27Position var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_25118_a(Packet70Bed var1) {
+		this.registerPacket(var1);
+	}
+
+	public void handleWeather(Packet71Weather var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_28116_a(Packet131MapData var1) {
+		this.registerPacket(var1);
+	}
+
+	public void func_28115_a(Packet61DoorChange var1) {
+		this.registerPacket(var1);
+	}
+	
+	public void handle62Sound(Packet62Sound var1) {
+		this.registerPacket(var1);
+	}
+	
+	public void handle55BlockBreakAnimation(Packet55BlockBreakAnimation p) {
+		this.registerPacket(p);
+	}
+
+	public void handleParticle(Packet63WorldParticles packet) {
+		this.registerPacket(packet);
 	}
 }
--- net/minecraft/src/ItemSnowball.java
+++ net/minecraft/src/ItemSnowball.java
@@ -9,7 +9,9 @@
 	public ItemStack onItemRightClick(ItemStack var1, World var2, EntityPlayer var3) {
 		--var1.stackSize;
 		var2.playSoundAtEntity(var3, "random.bow", 0.5F, 0.4F / (rand.nextFloat() * 0.4F + 0.8F));
-		var2.spawnEntityInWorld(new EntitySnowball(var2, var3));
+		if(!var2.multiplayerWorld) {
+			var2.spawnEntityInWorld(new EntitySnowball(var2, var3));
+		}
 		return var1;
 	}
 }
--- /dev/null
+++ net/minecraft/src/Packet40EntityMetadata.java
@@ -1,0 +1,33 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+public class Packet40EntityMetadata extends Packet {
+	public int entityId;
+	private List field_21048_b;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.entityId = var1.readInt();
+		this.field_21048_b = DataWatcher.readWatchableObjects(var1);
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.entityId);
+		DataWatcher.writeObjectsInListToStream(this.field_21048_b, var1);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_21148_a(this);
+	}
+
+	public int getPacketSize() {
+		return 5;
+	}
+
+	public List func_21047_b() {
+		return this.field_21048_b;
+	}
+}
--- net/minecraft/src/ItemBoat.java
+++ net/minecraft/src/ItemBoat.java
@@ -30,7 +30,9 @@
 				int var25 = var24.blockX;
 				int var26 = var24.blockY;
 				int var27 = var24.blockZ;
-				var2.spawnEntityInWorld(new EntityBoat(var2, (double)((float)var25 + 0.5F), (double)((float)var26 + 1.5F), (double)((float)var27 + 0.5F)));
+				if(!var2.multiplayerWorld) {
+					var2.spawnEntityInWorld(new EntityBoat(var2, (double)((float)var25 + 0.5F), (double)((float)var26 + 1.5F), (double)((float)var27 + 0.5F)));
+				}
 				--var1.stackSize;
 			}
 
--- net/minecraft/src/InventoryLargeChest.java
+++ net/minecraft/src/InventoryLargeChest.java
@@ -44,4 +44,8 @@
 		this.upperChest.onInventoryChanged();
 		this.lowerChest.onInventoryChanged();
 	}
+
+	public boolean canInteractWith(EntityPlayer var1) {
+		return this.upperChest.canInteractWith(var1) && this.lowerChest.canInteractWith(var1);
+	}
 }
--- net/minecraft/src/NetworkWriterThread.java
+++ net/minecraft/src/NetworkWriterThread.java
@@ -1,5 +1,7 @@
 package net.minecraft.src;
 
+import java.io.IOException;
+
 class NetworkWriterThread extends Thread {
 	final NetworkManager netManager;
 
@@ -15,18 +17,36 @@
 		}
 
 		while(true) {
-			boolean var11 = false;
+			boolean var13 = false;
 
 			try {
-				var11 = true;
+				var13 = true;
 				if(!NetworkManager.isRunning(this.netManager)) {
-					var11 = false;
+					var13 = false;
 					break;
 				}
 
-				NetworkManager.sendNetworkPacket(this.netManager);
+				while(NetworkManager.sendNetworkPacket(this.netManager)) {
+				}
+
+				try {
+					sleep(2L);
+				} catch (InterruptedException var16) {
+				}
+
+				try {
+					if(NetworkManager.func_28140_f(this.netManager) != null) {
+						NetworkManager.func_28140_f(this.netManager).flush();
+					}
+				} catch (IOException var18) {
+					if(!NetworkManager.func_28138_e(this.netManager)) {
+						NetworkManager.func_30005_a(this.netManager, var18);
+					}
+
+					var18.printStackTrace();
+				}
 			} finally {
-				if(var11) {
+				if(var13) {
 					Object var5 = NetworkManager.threadSyncObject;
 					synchronized(var5) {
 						--NetworkManager.numWriteThreads;
--- net/minecraft/src/Packet2Handshake.java
+++ net/minecraft/src/Packet2Handshake.java
@@ -15,11 +15,11 @@
 	}
 
 	public void readPacketData(DataInputStream var1) throws IOException {
-		this.username = var1.readUTF();
+		this.username = readString(var1, 32);
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeUTF(this.username);
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		writeString(this.username, var1);
 	}
 
 	public void processPacket(NetHandler var1) {
--- net/minecraft/src/RenderTNTPrimed.java
+++ net/minecraft/src/RenderTNTPrimed.java
@@ -31,14 +31,14 @@
 
 		var10 = (1.0F - ((float)var1.fuse - var9 + 1.0F) / 100.0F) * 0.8F;
 		this.loadTexture("/terrain.png");
-		this.blockRenderer.renderBlockOnInventory(Block.tnt);
+		this.blockRenderer.renderBlockOnInventory(Block.tnt, 0);
 		if(var1.fuse / 5 % 2 == 0) {
 			GL11.glDisable(GL11.GL_TEXTURE_2D);
 			GL11.glDisable(GL11.GL_LIGHTING);
 			GL11.glEnable(GL11.GL_BLEND);
 			GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA);
 			GL11.glColor4f(1.0F, 1.0F, 1.0F, var10);
-			this.blockRenderer.renderBlockOnInventory(Block.tnt);
+			this.blockRenderer.renderBlockOnInventory(Block.tnt, 0);
 			GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
 			GL11.glDisable(GL11.GL_BLEND);
 			GL11.glEnable(GL11.GL_LIGHTING);
--- net/minecraft/src/Packet16BlockItemSwitch.java
+++ net/minecraft/src/Packet16BlockItemSwitch.java
@@ -5,24 +5,20 @@
 import java.io.IOException;
 
 public class Packet16BlockItemSwitch extends Packet {
-	public int entityId;
 	public int id;
 
 	public Packet16BlockItemSwitch() {
 	}
 
-	public Packet16BlockItemSwitch(int var1, int var2) {
-		this.entityId = var1;
-		this.id = var2;
+	public Packet16BlockItemSwitch(int var1) {
+		this.id = var1;
 	}
 
 	public void readPacketData(DataInputStream var1) throws IOException {
-		this.entityId = var1.readInt();
 		this.id = var1.readShort();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeInt(this.entityId);
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeShort(this.id);
 	}
 
@@ -31,6 +27,6 @@
 	}
 
 	public int getPacketSize() {
-		return 6;
+		return 2;
 	}
 }
--- net/minecraft/src/RenderSheep.java
+++ net/minecraft/src/RenderSheep.java
@@ -8,7 +8,7 @@
 
 	protected boolean renderFur(EntitySheep var1, int var2) {
 		this.loadTexture("/mob/sheep_fur.png");
-		return var2 == 0 && !var1.sheared;
+		return var2 == 0 && !var1.getSheared();
 	}
 
 	protected boolean shouldRenderPass(EntityLiving var1, int var2) {
--- net/minecraft/src/Packet30Entity.java
+++ net/minecraft/src/Packet30Entity.java
@@ -17,7 +17,7 @@
 		this.entityId = var1.readInt();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.entityId);
 	}
 
--- net/minecraft/src/Block.java
+++ net/minecraft/src/Block.java
@@ -54,7 +54,7 @@
 	public static final Block clothMagenta = null;
 	public static final Block clothRose = null;
 	public static final Block clothDarkGray = null;
-	public static final Block cloth = (new Block(35, 64, Material.cloth)).setHardness(0.8F).setStepSound(soundClothFootstep);
+	public static final Block cloth = (new BlockWool()).setHardness(0.8F).setStepSound(soundClothFootstep);
 	public static final Block clothWhite = null;
 	public static final BlockFlower plantYellow = (BlockFlower)(new BlockFlower(37, 13)).setHardness(0.0F).setStepSound(soundGrassFootstep);
 	public static final BlockFlower plantRed = (BlockFlower)(new BlockFlower(38, 12)).setHardness(0.0F).setStepSound(soundGrassFootstep);
@@ -295,7 +295,7 @@
 						double var11 = (double)(var1.rand.nextFloat() * var10) + (double)(1.0F - var10) * 0.5D;
 						double var13 = (double)(var1.rand.nextFloat() * var10) + (double)(1.0F - var10) * 0.5D;
 						double var15 = (double)(var1.rand.nextFloat() * var10) + (double)(1.0F - var10) * 0.5D;
-						EntityItem var17 = new EntityItem(var1, (double)var2 + var11, (double)var3 + var13, (double)var4 + var15, new ItemStack(var9));
+						EntityItem var17 = new EntityItem(var1, (double)var2 + var11, (double)var3 + var13, (double)var4 + var15, new ItemStack(var9, 1, this.damageDropped(var5)));
 						var17.delayBeforeCanPickup = 10;
 						var1.spawnEntityInWorld(var17);
 					}
@@ -472,10 +472,16 @@
 	public boolean canBlockStay(World var1, int var2, int var3, int var4) {
 		return true;
 	}
+	
+	protected int damageDropped(int var1) {
+		return 0;
+	}
 
 	static {
+		Item.itemsList[cloth.blockID] = new ItemWool(cloth.blockID - 256);
+		
 		for(int var0 = 0; var0 < 256; ++var0) {
-			if(blocksList[var0] != null) {
+			if(blocksList[var0] != null && Item.itemsList[var0] == null) {
 				Item.itemsList[var0] = new ItemBlock(var0 - 256);
 			}
 		}
--- net/minecraft/src/CraftingInventoryPlayerCB.java
+++ /dev/null
@@ -1,43 +1,0 @@
-package net.minecraft.src;
-
-public class CraftingInventoryPlayerCB extends CraftingInventoryCB {
-	public InventoryCrafting craftMatrix;
-	public IInventory craftResult = new InventoryCraftResult();
-
-	public CraftingInventoryPlayerCB(ItemStack[] var1) {
-		this.craftMatrix = new InventoryCrafting(this, var1);
-		this.onCraftMatrixChanged(this.craftMatrix);
-	}
-
-	public void onCraftMatrixChanged(IInventory var1) {
-		int[] var2 = new int[9];
-
-		for(int var3 = 0; var3 < 3; ++var3) {
-			for(int var4 = 0; var4 < 3; ++var4) {
-				int var5 = -1;
-				if(var3 < 2 && var4 < 2) {
-					ItemStack var6 = this.craftMatrix.getStackInSlot(var3 + var4 * 2);
-					if(var6 != null) {
-						var5 = var6.itemID;
-					}
-				}
-
-				var2[var3 + var4 * 3] = var5;
-			}
-		}
-
-		this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(var2));
-	}
-
-	public void onCraftGuiClosed(EntityPlayer var1) {
-		super.onCraftGuiClosed(var1);
-
-		for(int var2 = 0; var2 < 9; ++var2) {
-			ItemStack var3 = this.craftMatrix.getStackInSlot(var2);
-			if(var3 != null) {
-				var1.dropPlayerItem(var3);
-			}
-		}
-
-	}
-}
--- net/minecraft/src/CraftingInventoryCB.java
+++ /dev/null
@@ -1,19 +1,0 @@
-package net.minecraft.src;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class CraftingInventoryCB {
-	protected List list = new ArrayList();
-
-	public void onCraftGuiClosed(EntityPlayer var1) {
-		InventoryPlayer var2 = var1.inventory;
-		if(var2.draggedItemStack != null) {
-			var1.dropPlayerItem(var2.draggedItemStack);
-		}
-
-	}
-
-	public void onCraftMatrixChanged(IInventory var1) {
-	}
-}
--- net/minecraft/src/InventoryCraftResult.java
+++ net/minecraft/src/InventoryCraftResult.java
@@ -35,4 +35,8 @@
 
 	public void onInventoryChanged() {
 	}
+
+	public boolean canInteractWith(EntityPlayer var1) {
+		return true;
+	}
 }
--- net/minecraft/src/Packet20NamedEntitySpawn.java
+++ net/minecraft/src/Packet20NamedEntitySpawn.java
@@ -31,7 +31,7 @@
 
 	public void readPacketData(DataInputStream var1) throws IOException {
 		this.entityId = var1.readInt();
-		this.name = var1.readUTF();
+		this.name = readString(var1, 16);
 		this.xPosition = var1.readInt();
 		this.yPosition = var1.readInt();
 		this.zPosition = var1.readInt();
@@ -40,9 +40,9 @@
 		this.currentItem = var1.readShort();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.entityId);
-		var1.writeUTF(this.name);
+		writeString(this.name, var1);
 		var1.writeInt(this.xPosition);
 		var1.writeInt(this.yPosition);
 		var1.writeInt(this.zPosition);
--- net/minecraft/src/Item.java
+++ net/minecraft/src/Item.java
@@ -75,8 +75,8 @@
 	public static Item sign = (new ItemSign(67)).setIconIndex(42);
 	public static Item doorWood = (new ItemDoor(68, Material.wood)).setIconIndex(43);
 	public static Item bucketEmpty = (new ItemBucket(69, 0)).setIconIndex(74);
-	public static Item bucketWater = (new ItemBucket(70, Block.waterMoving.blockID)).setIconIndex(75);
-	public static Item bucketLava = (new ItemBucket(71, Block.lavaMoving.blockID)).setIconIndex(76);
+	public static Item bucketWater = (new ItemBucket(70, Block.waterMoving.blockID)).setIconIndex(75).setContainerItem(bucketEmpty);
+	public static Item bucketLava = (new ItemBucket(71, Block.lavaMoving.blockID)).setIconIndex(76).setContainerItem(bucketEmpty);
 	public static Item minecartEmpty = (new ItemMinecart(72, 0)).setIconIndex(135);
 	public static Item saddle = (new ItemSaddle(73)).setIconIndex(104);
 	public static Item doorSteel = (new ItemDoor(74, Material.iron)).setIconIndex(44);
@@ -84,7 +84,7 @@
 	public static Item snowball = (new ItemSnowball(76)).setIconIndex(14);
 	public static Item boat = (new ItemBoat(77)).setIconIndex(136);
 	public static Item leather = (new Item(78)).setIconIndex(103);
-	public static Item bucketMilk = (new ItemBucket(79, -1)).setIconIndex(77);
+	public static Item bucketMilk = (new ItemBucket(79, -1)).setIconIndex(77).setContainerItem(bucketEmpty);
 	public static Item brick = (new Item(80)).setIconIndex(22);
 	public static Item clay = (new Item(81)).setIconIndex(57);
 	public static Item reed = (new ItemReed(82, Block.reed)).setIconIndex(27);
@@ -103,6 +103,8 @@
 	protected int maxDamage = 32;
 	protected int iconIndex;
 	protected boolean bFull3D = false;
+	protected boolean hasSubtypes = false;
+	private Item containerItem = null;
 
 	protected Item(int var1) {
 		this.shiftedIndex = 256 + var1;
@@ -117,9 +119,18 @@
 		this.iconIndex = var1;
 		return this;
 	}
+	
+	public Item setMaxStackSize(int var1) {
+		this.maxStackSize = var1;
+		return this;
+	}
+	
+	public int getSprite(int metadata) {
+	      return this.iconIndex;
+	   }
 
 	public int getIconIndex(ItemStack var1) {
-		return this.iconIndex;
+		return this.getSprite(var1.getItemDamageForDisplay());
 	}
 
 	public boolean onItemUse(ItemStack var1, EntityPlayer var2, World var3, int var4, int var5, int var6, int var7) {
@@ -137,15 +148,37 @@
 	public int getItemStackLimit() {
 		return this.maxStackSize;
 	}
+	
+	public int getPlacedBlockMetadata(int var1) {
+		return 0;
+	}
+
+	public boolean getHasSubtypes() {
+		return this.hasSubtypes;
+	}
+
+	protected Item setHasSubtypes(boolean var1) {
+		this.hasSubtypes = var1;
+		return this;
+	}
 
 	public int getMaxDamage() {
 		return this.maxDamage;
 	}
-
-	public void hitEntity(ItemStack var1, EntityLiving var2) {
-	}
-
-	public void onBlockDestroyed(ItemStack var1, int var2, int var3, int var4, int var5) {
+	
+	protected Item setMaxDamage(int var1) {
+		this.maxDamage = var1;
+		return this;
+	}
+
+	public boolean isDamagable() {
+		return this.maxDamage > 0 && !this.hasSubtypes;
+	}
+
+	public void hitEntity(ItemStack var1, EntityLiving var2, EntityLiving var3) {
+	}
+
+	public void onBlockDestroyed(ItemStack var1, int var2, int var3, int var4, int var5, EntityLiving var6) {
 	}
 
 	public int getDamageVsEntity(Entity var1) {
@@ -166,5 +199,32 @@
 
 	public boolean isFull3D() {
 		return this.bFull3D;
+	}
+	
+	public boolean shouldRotateAroundWhenRendering() {
+		return false;
+	}
+	
+	public Item setContainerItem(Item var1) {
+		if(this.maxStackSize > 1) {
+			throw new IllegalArgumentException("Max stack size must be 1 for items with crafting results");
+		} else {
+			this.containerItem = var1;
+			return this;
+		}
+	}
+
+	public Item getContainerItem() {
+		return this.containerItem;
+	}
+	
+	public boolean hasContainerItem() {
+		return this.containerItem != null;
+	}
+	
+	public void onUpdate(ItemStack var1, World var2, Entity var3, int var4, boolean var5) {
+	}
+
+	public void onCreated(ItemStack var1, World var2, EntityPlayer var3) {
 	}
 }
--- net/minecraft/src/BlockRedstoneWire.java
+++ net/minecraft/src/BlockRedstoneWire.java
@@ -149,6 +149,9 @@
 
 	public void onBlockAdded(World var1, int var2, int var3, int var4) {
 		super.onBlockAdded(var1, var2, var3, var4);
+		if (var1.multiplayerWorld) {
+			return;
+		}
 		this.updateAndPropagateCurrentStrength(var1, var2, var3, var4);
 		var1.notifyBlocksOfNeighborChange(var2, var3 + 1, var4, this.blockID);
 		var1.notifyBlocksOfNeighborChange(var2, var3 - 1, var4, this.blockID);
@@ -184,6 +187,9 @@
 
 	public void onBlockRemoval(World var1, int var2, int var3, int var4) {
 		super.onBlockRemoval(var1, var2, var3, var4);
+		if (var1.multiplayerWorld) {
+			return;
+		}
 		var1.notifyBlocksOfNeighborChange(var2, var3 + 1, var4, this.blockID);
 		var1.notifyBlocksOfNeighborChange(var2, var3 - 1, var4, this.blockID);
 		this.updateAndPropagateCurrentStrength(var1, var2, var3, var4);
@@ -227,6 +233,9 @@
 	}
 
 	public void onNeighborBlockChange(World var1, int var2, int var3, int var4, int var5) {
+		if (var1.multiplayerWorld) {
+			return;
+		}
 		int var6 = var1.getBlockMetadata(var2, var3, var4);
 		boolean var7 = this.canPlaceBlockAt(var1, var2, var3, var4);
 		if(!var7) {
--- net/minecraft/src/Packet5PlayerInventory.java
+++ net/minecraft/src/Packet5PlayerInventory.java
@@ -5,52 +5,23 @@
 import java.io.IOException;
 
 public class Packet5PlayerInventory extends Packet {
-	public int inventoryType;
-	public ItemStack[] inventory;
-
-	public Packet5PlayerInventory() {
-	}
-
-	public Packet5PlayerInventory(int var1, ItemStack[] var2) {
-		this.inventoryType = var1;
-		this.inventory = new ItemStack[var2.length];
-
-		for(int var3 = 0; var3 < this.inventory.length; ++var3) {
-			this.inventory[var3] = var2[var3] == null ? null : var2[var3].copy();
-		}
-
-	}
+	public int entityID;
+	public int slot;
+	public int itemID;
+	public int itemDamage;
 
 	public void readPacketData(DataInputStream var1) throws IOException {
-		this.inventoryType = var1.readInt();
-		short var2 = var1.readShort();
-		this.inventory = new ItemStack[var2];
-
-		for(int var3 = 0; var3 < var2; ++var3) {
-			short var4 = var1.readShort();
-			if(var4 >= 0) {
-				byte var5 = var1.readByte();
-				short var6 = var1.readShort();
-				this.inventory[var3] = new ItemStack(var4, var5, var6);
-			}
-		}
-
+		this.entityID = var1.readInt();
+		this.slot = var1.readShort();
+		this.itemID = var1.readShort();
+		this.itemDamage = var1.readShort();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeInt(this.inventoryType);
-		var1.writeShort(this.inventory.length);
-
-		for(int var2 = 0; var2 < this.inventory.length; ++var2) {
-			if(this.inventory[var2] == null) {
-				var1.writeShort(-1);
-			} else {
-				var1.writeShort((short)this.inventory[var2].itemID);
-				var1.writeByte((byte)this.inventory[var2].stackSize);
-				var1.writeShort((short)this.inventory[var2].itemDmg);
-			}
-		}
-
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.entityID);
+		var1.writeShort(this.slot);
+		var1.writeShort(this.itemID);
+		var1.writeShort(this.itemDamage);
 	}
 
 	public void processPacket(NetHandler var1) {
@@ -58,6 +29,6 @@
 	}
 
 	public int getPacketSize() {
-		return 6 + this.inventory.length * 5;
+		return 8;
 	}
 }
--- net/minecraft/src/GuiCrafting.java
+++ net/minecraft/src/GuiCrafting.java
@@ -3,34 +3,13 @@
 import org.lwjgl.opengl.GL11;
 
 public class GuiCrafting extends GuiContainer {
-	public CraftingInventoryWorkbenchCB craftingInventory = new CraftingInventoryWorkbenchCB();
-
-	public GuiCrafting(InventoryPlayer var1) {
-		this.inventorySlots.add(new SlotCrafting(this, this.craftingInventory.craftMatrix, this.craftingInventory.craftResult, 0, 124, 35));
-
-		int var2;
-		int var3;
-		for(var2 = 0; var2 < 3; ++var2) {
-			for(var3 = 0; var3 < 3; ++var3) {
-				this.inventorySlots.add(new SlotInventory(this, this.craftingInventory.craftMatrix, var3 + var2 * 3, 30 + var3 * 18, 17 + var2 * 18));
-			}
-		}
-
-		for(var2 = 0; var2 < 3; ++var2) {
-			for(var3 = 0; var3 < 9; ++var3) {
-				this.inventorySlots.add(new SlotInventory(this, var1, var3 + (var2 + 1) * 9, 8 + var3 * 18, 84 + var2 * 18));
-			}
-		}
-
-		for(var2 = 0; var2 < 9; ++var2) {
-			this.inventorySlots.add(new SlotInventory(this, var1, var2, 8 + var2 * 18, 142));
-		}
-
+	public GuiCrafting(InventoryPlayer var1, World var2, int var3, int var4, int var5) {
+		super(new ContainerWorkbench(var1, var2, var3, var4, var5));
 	}
 
 	public void onGuiClosed() {
 		super.onGuiClosed();
-		this.craftingInventory.onCraftGuiClosed(this.mc.thePlayer);
+		this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer);
 	}
 
 	protected void drawGuiContainerForegroundLayer() {
--- net/minecraft/src/EntitySheep.java
+++ net/minecraft/src/EntitySheep.java
@@ -1,7 +1,6 @@
 package net.minecraft.src;
 
 public class EntitySheep extends EntityAnimal {
-	public boolean sheared = false;
 
 	public EntitySheep(World var1) {
 		super(var1);
@@ -9,9 +8,17 @@
 		this.setSize(0.9F, 1.3F);
 	}
 
+	protected void entityInit() {
+		super.entityInit();
+		this.dataWatcher.addObject(16, new Byte((byte)0));
+	}
+
 	public boolean attackEntityFrom(Entity var1, int var2) {
-		if(!this.sheared && var1 instanceof EntityLiving) {
-			this.sheared = true;
+		if(!this.getSheared() && var1 instanceof EntityLiving) {
+			if(this.worldObj.multiplayerWorld)
+				return false;
+			
+			this.setSheared(true);
 			int var3 = 1 + this.rand.nextInt(3);
 
 			for(int var4 = 0; var4 < var3; ++var4) {
@@ -27,12 +34,12 @@
 
 	public void writeEntityToNBT(NBTTagCompound var1) {
 		super.writeEntityToNBT(var1);
-		var1.setBoolean("Sheared", this.sheared);
+		var1.setBoolean("Sheared", this.getSheared());
 	}
 
 	public void readEntityFromNBT(NBTTagCompound var1) {
 		super.readEntityFromNBT(var1);
-		this.sheared = var1.getBoolean("Sheared");
+		this.setSheared(var1.getBoolean("Sheared"));
 	}
 
 	protected String getLivingSound() {
@@ -45,5 +52,19 @@
 
 	protected String getDeathSound() {
 		return "mob.sheep";
+	}
+	
+	public boolean getSheared() {
+		return (this.dataWatcher.getWatchableObjectByte(16) & 16) != 0;
+	}
+
+	public void setSheared(boolean var1) {
+		byte var2 = this.dataWatcher.getWatchableObjectByte(16);
+		if(var1) {
+			this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 16)));
+		} else {
+			this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -17)));
+		}
+
 	}
 }
--- /dev/null
+++ net/minecraft/src/Packet105UpdateProgressbar.java
@@ -1,0 +1,31 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet105UpdateProgressbar extends Packet {
+	public int windowId;
+	public int progressBar;
+	public int progressBarValue;
+
+	public void processPacket(NetHandler var1) {
+		var1.func_20090_a(this);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.windowId = var1.readByte();
+		this.progressBar = var1.readShort();
+		this.progressBarValue = var1.readShort();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.windowId);
+		var1.writeShort(this.progressBar);
+		var1.writeShort(this.progressBarValue);
+	}
+
+	public int getPacketSize() {
+		return 5;
+	}
+}
--- /dev/null
+++ net/minecraft/src/Packet102WindowClick.java
@@ -1,0 +1,67 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet102WindowClick extends Packet {
+	public int window_Id;
+	public int inventorySlot;
+	public int mouseClick;
+	public short action;
+	public ItemStack itemStack;
+	public boolean field_27050_f;
+
+	public Packet102WindowClick() {
+	}
+
+	public Packet102WindowClick(int var1, int var2, int var3, boolean var4, ItemStack var5, short var6) {
+		this.window_Id = var1;
+		this.inventorySlot = var2;
+		this.mouseClick = var3;
+		this.itemStack = var5;
+		this.action = var6;
+		this.field_27050_f = var4;
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_20091_a(this);
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.window_Id = var1.readByte();
+		this.inventorySlot = var1.readShort();
+		this.mouseClick = var1.readByte();
+		this.action = var1.readShort();
+		this.field_27050_f = var1.readBoolean();
+		short var2 = var1.readShort();
+		if(var2 >= 0) {
+			byte var3 = var1.readByte();
+			short var4 = var1.readShort();
+			this.itemStack = new ItemStack(var2, var3, var4);
+		} else {
+			this.itemStack = null;
+		}
+
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeByte(this.window_Id);
+		var1.writeShort(this.inventorySlot);
+		var1.writeByte(this.mouseClick);
+		var1.writeShort(this.action);
+		var1.writeBoolean(this.field_27050_f);
+		if(this.itemStack == null) {
+			var1.writeShort(-1);
+		} else {
+			var1.writeShort(this.itemStack.itemID);
+			var1.writeByte(this.itemStack.stackSize);
+			var1.writeShort(this.itemStack.getItemDamage());
+		}
+
+	}
+
+	public int getPacketSize() {
+		return 11;
+	}
+}
--- net/minecraft/src/BlockButton.java
+++ net/minecraft/src/BlockButton.java
@@ -132,6 +132,9 @@
 	}
 
 	public boolean blockActivated(World var1, int var2, int var3, int var4, EntityPlayer var5) {
+		if (var1.multiplayerWorld) {
+			return true;
+		}
 		int var6 = var1.getBlockMetadata(var2, var3, var4);
 		int var7 = var6 & 7;
 		int var8 = 8 - (var6 & 8);
@@ -141,6 +144,7 @@
 			var1.setBlockMetadataWithNotify(var2, var3, var4, var7 + var8);
 			var1.markBlocksDirty(var2, var3, var4, var2, var3, var4);
 			var1.playSoundEffect((double)var2 + 0.5D, (double)var3 + 0.5D, (double)var4 + 0.5D, "random.click", 0.3F, 0.6F);
+			
 			var1.notifyBlocksOfNeighborChange(var2, var3, var4, this.blockID);
 			if(var7 == 1) {
 				var1.notifyBlocksOfNeighborChange(var2 - 1, var3, var4, this.blockID);
@@ -199,6 +203,9 @@
 	}
 
 	public void updateTick(World var1, int var2, int var3, int var4, Random var5) {
+		if(var1.multiplayerWorld)
+			return;
+		
 		int var6 = var1.getBlockMetadata(var2, var3, var4);
 		if((var6 & 8) != 0) {
 			var1.setBlockMetadataWithNotify(var2, var3, var4, var6 & 7);
--- net/minecraft/src/BlockTNT.java
+++ net/minecraft/src/BlockTNT.java
@@ -24,12 +24,18 @@
 	}
 
 	public void onBlockDestroyedByExplosion(World var1, int var2, int var3, int var4) {
+		if(var1.multiplayerWorld)
+			return;
+		
 		EntityTNTPrimed var5 = new EntityTNTPrimed(var1, (float)var2 + 0.5F, (float)var3 + 0.5F, (float)var4 + 0.5F);
 		var5.fuse = var1.rand.nextInt(var5.fuse / 4) + var5.fuse / 8;
 		var1.spawnEntityInWorld(var5);
 	}
 
 	public void onBlockDestroyedByPlayer(World var1, int var2, int var3, int var4, int var5) {
+		if(var1.multiplayerWorld)
+			return;
+		
 		EntityTNTPrimed var6 = new EntityTNTPrimed(var1, (float)var2 + 0.5F, (float)var3 + 0.5F, (float)var4 + 0.5F);
 		var1.spawnEntityInWorld(var6);
 		var1.playSoundAtEntity(var6, "random.fuse", 1.0F, 1.0F);
--- /dev/null
+++ net/minecraft/src/ThreadCloseConnection.java
@@ -1,0 +1,22 @@
+package net.minecraft.src;
+
+class ThreadCloseConnection extends Thread {
+	final NetworkManager field_28109_a;
+
+	ThreadCloseConnection(NetworkManager var1) {
+		this.field_28109_a = var1;
+	}
+
+	public void run() {
+		try {
+			Thread.sleep(2000L);
+			if(NetworkManager.isRunning(this.field_28109_a)) {
+				NetworkManager.getWriteThread(this.field_28109_a).interrupt();
+				this.field_28109_a.networkShutdown("Connection closed", new Object[0]);
+			}
+		} catch (Exception var2) {
+			var2.printStackTrace();
+		}
+
+	}
+}
--- /dev/null
+++ net/minecraft/src/Packet25EntityPainting.java
@@ -1,0 +1,52 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet25EntityPainting extends Packet {
+	public int entityId;
+	public int xPosition;
+	public int yPosition;
+	public int zPosition;
+	public int direction;
+	public String title;
+
+	public Packet25EntityPainting() {
+	}
+
+	public Packet25EntityPainting(EntityPainting var1) {
+		this.entityId = var1.entityID;
+		this.xPosition = var1.xPosition;
+		this.yPosition = var1.yPosition;
+		this.zPosition = var1.zPosition;
+		this.direction = var1.direction;
+		this.title = var1.art.title;
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.entityId = var1.readInt();
+		this.title = readString(var1, EnumArt.maxArtTitleLength);
+		this.xPosition = var1.readInt();
+		this.yPosition = var1.readInt();
+		this.zPosition = var1.readInt();
+		this.direction = var1.readInt();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.entityId);
+		writeString(this.title, var1);
+		var1.writeInt(this.xPosition);
+		var1.writeInt(this.yPosition);
+		var1.writeInt(this.zPosition);
+		var1.writeInt(this.direction);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_21146_a(this);
+	}
+
+	public int getPacketSize() {
+		return 24;
+	}
+}
--- /dev/null
+++ net/minecraft/src/Empty1.java
@@ -1,0 +1,4 @@
+package net.minecraft.src;
+
+class Empty1 {
+}
--- net/minecraft/src/EntityTNTPrimed.java
+++ net/minecraft/src/EntityTNTPrimed.java
@@ -11,18 +11,21 @@
 		this.yOffset = this.height / 2.0F;
 	}
 
-	public EntityTNTPrimed(World var1, float var2, float var3, float var4) {
+	public EntityTNTPrimed(World var1, double var2, double var3, double var4) {
 		this(var1);
-		this.setPosition((double)var2, (double)var3, (double)var4);
+		this.setPosition(var2, var3, var4);
 		float var5 = (float)(Math.random() * (double)((float)Math.PI) * 2.0D);
 		this.motionX = (double)(-MathHelper.sin(var5 * (float)Math.PI / 180.0F) * 0.02F);
 		this.motionY = (double)0.2F;
 		this.motionZ = (double)(-MathHelper.cos(var5 * (float)Math.PI / 180.0F) * 0.02F);
 		this.canTriggerWalking = false;
 		this.fuse = 80;
-		this.prevPosX = (double)var2;
-		this.prevPosY = (double)var3;
-		this.prevPosZ = (double)var4;
+		this.prevPosX = var2;
+		this.prevPosY = var3;
+		this.prevPosZ = var4;
+	}
+
+	protected void entityInit() {
 	}
 
 	public boolean canBeCollidedWith() {
--- net/minecraft/src/GuiChest.java
+++ net/minecraft/src/GuiChest.java
@@ -8,6 +8,7 @@
 	private int inventoryRows = 0;
 
 	public GuiChest(IInventory var1, IInventory var2) {
+		super(new ContainerChest(var1, var2));
 		this.upperChestInventory = var1;
 		this.lowerChestInventory = var2;
 		this.allowUserInput = false;
@@ -15,25 +16,6 @@
 		int var4 = var3 - 108;
 		this.inventoryRows = var2.getSizeInventory() / 9;
 		this.ySize = var4 + this.inventoryRows * 18;
-		int var5 = (this.inventoryRows - 4) * 18;
-
-		int var6;
-		int var7;
-		for(var6 = 0; var6 < this.inventoryRows; ++var6) {
-			for(var7 = 0; var7 < 9; ++var7) {
-				this.inventorySlots.add(new SlotInventory(this, var2, var7 + var6 * 9, 8 + var7 * 18, 18 + var6 * 18));
-			}
-		}
-
-		for(var6 = 0; var6 < 3; ++var6) {
-			for(var7 = 0; var7 < 9; ++var7) {
-				this.inventorySlots.add(new SlotInventory(this, var1, var7 + (var6 + 1) * 9, 8 + var7 * 18, 103 + var6 * 18 + var5));
-			}
-		}
-
-		for(var6 = 0; var6 < 9; ++var6) {
-			this.inventorySlots.add(new SlotInventory(this, var1, var6, 8 + var6 * 18, 161 + var5));
-		}
 
 	}
 
--- net/minecraft/src/Packet15Place.java
+++ net/minecraft/src/Packet15Place.java
@@ -5,37 +5,52 @@
 import java.io.IOException;
 
 public class Packet15Place extends Packet {
-	public int id;
 	public int xPosition;
 	public int yPosition;
 	public int zPosition;
 	public int direction;
+	public ItemStack itemStack;
 
 	public Packet15Place() {
 	}
 
-	public Packet15Place(int var1, int var2, int var3, int var4, int var5) {
-		this.id = var1;
-		this.xPosition = var2;
-		this.yPosition = var3;
-		this.zPosition = var4;
-		this.direction = var5;
+	public Packet15Place(int var1, int var2, int var3, int var4, ItemStack var5) {
+		this.xPosition = var1;
+		this.yPosition = var2;
+		this.zPosition = var3;
+		this.direction = var4;
+		this.itemStack = var5;
 	}
 
 	public void readPacketData(DataInputStream var1) throws IOException {
-		this.id = var1.readShort();
 		this.xPosition = var1.readInt();
 		this.yPosition = var1.read();
 		this.zPosition = var1.readInt();
 		this.direction = var1.read();
+		short var2 = var1.readShort();
+		if(var2 >= 0) {
+			byte var3 = var1.readByte();
+			short var4 = var1.readShort();
+			this.itemStack = new ItemStack(var2, var3, var4);
+		} else {
+			this.itemStack = null;
+		}
+
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeShort(this.id);
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.xPosition);
 		var1.write(this.yPosition);
 		var1.writeInt(this.zPosition);
 		var1.write(this.direction);
+		if(this.itemStack == null) {
+			var1.writeShort(-1);
+		} else {
+			var1.writeShort(this.itemStack.itemID);
+			var1.writeByte(this.itemStack.stackSize);
+			var1.writeShort(this.itemStack.getItemDamage());
+		}
+
 	}
 
 	public void processPacket(NetHandler var1) {
@@ -43,6 +58,6 @@
 	}
 
 	public int getPacketSize() {
-		return 12;
+		return 15;
 	}
 }
--- net/minecraft/src/PlayerController.java
+++ net/minecraft/src/PlayerController.java
@@ -43,6 +43,21 @@
 	public float getBlockReachDistance() {
 		return 5.0F;
 	}
+	
+	public boolean sendUseItem(EntityPlayer var1, World var2, ItemStack var3) {
+		int var4 = var3.stackSize;
+		ItemStack var5 = var3.useItemRightClick(var2, var1);
+		if(var5 != var3 || var5 != null && var5.stackSize != var4) {
+			var1.inventory.mainInventory[var1.inventory.currentItem] = var5;
+			if(var5.stackSize == 0) {
+				var1.inventory.mainInventory[var1.inventory.currentItem] = null;
+			}
+
+			return true;
+		} else {
+			return false;
+		}
+	}
 
 	public void flipPlayer(EntityPlayer var1) {
 	}
@@ -56,13 +71,30 @@
 
 	public void onRespawn(EntityPlayer var1) {
 	}
-
-	public boolean onPlayerRightClick(EntityPlayer var1, World var2, ItemStack var3, int var4, int var5, int var6, int var7) {
+	
+	public boolean sendPlaceBlock(EntityPlayer var1, World var2, ItemStack var3, int var4, int var5, int var6, int var7) {
 		int var8 = var2.getBlockId(var4, var5, var6);
 		return var8 > 0 && Block.blocksList[var8].blockActivated(var2, var4, var5, var6, var1) ? true : (var3 == null ? false : var3.useItem(var1, var2, var4, var5, var6, var7));
 	}
 
 	public EntityPlayer createPlayer(World var1) {
 		return new EntityPlayerSP(this.mc, var1, this.mc.session);
+	}
+	
+	public void interactWithEntity(EntityPlayer var1, Entity var2) {
+		var1.useCurrentItemOnEntity(var2);
+	}
+
+	public void attackEntity(EntityPlayer var1, Entity var2) {
+		var1.attackTargetEntityWithCurrentItem(var2);
+	}
+
+	public ItemStack func_27174_a(int var1, int var2, int var3, boolean var4, EntityPlayer var5) {
+		return var5.craftingInventory.func_27280_a(var2, var3, var4, var5);
+	}
+
+	public void func_20086_a(int var1, EntityPlayer var2) {
+		var2.craftingInventory.onCraftGuiClosed(var2);
+		var2.craftingInventory = var2.inventorySlots;
 	}
 }
--- net/minecraft/src/ItemSaddle.java
+++ net/minecraft/src/ItemSaddle.java
@@ -10,8 +10,8 @@
 	public void saddleEntity(ItemStack var1, EntityLiving var2) {
 		if(var2 instanceof EntityPig) {
 			EntityPig var3 = (EntityPig)var2;
-			if(!var3.saddled) {
-				var3.saddled = true;
+			if(!var3.getSaddled()) {
+				var3.setSaddled(true);
 				--var1.stackSize;
 			}
 		}
--- net/minecraft/src/ItemSword.java
+++ net/minecraft/src/ItemSword.java
@@ -18,12 +18,12 @@
 		return 1.5F;
 	}
 
-	public void hitEntity(ItemStack var1, EntityLiving var2) {
-		var1.damageItem(1);
+	public void hitEntity(ItemStack var1, EntityLiving var2, EntityLiving var3) {
+		var1.damageItem(1, var3);
 	}
 
-	public void onBlockDestroyed(ItemStack var1, int var2, int var3, int var4, int var5) {
-		var1.damageItem(2);
+	public void onBlockDestroyed(ItemStack var1, int var2, int var3, int var4, int var5, EntityLiving var6) {
+		var1.damageItem(2, var6);
 	}
 
 	public int getDamageVsEntity(Entity var1) {
--- net/minecraft/src/Packet17AddToInventory.java
+++ /dev/null
@@ -1,31 +1,0 @@
-package net.minecraft.src;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-public class Packet17AddToInventory extends Packet {
-	public int itemID;
-	public int count;
-	public int itemDamage;
-
-	public void readPacketData(DataInputStream var1) throws IOException {
-		this.itemID = var1.readShort();
-		this.count = var1.readByte();
-		this.itemDamage = var1.readShort();
-	}
-
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeShort(this.itemID);
-		var1.writeByte(this.count);
-		var1.writeShort(this.itemDamage);
-	}
-
-	public void processPacket(NetHandler var1) {
-		var1.handleAddToInventory(this);
-	}
-
-	public int getPacketSize() {
-		return 5;
-	}
-}
--- net/minecraft/src/TileEntityChest.java
+++ net/minecraft/src/TileEntityChest.java
@@ -80,4 +80,8 @@
 	public int getInventoryStackLimit() {
 		return 64;
 	}
+	
+	public boolean canInteractWith(EntityPlayer var1) {
+		return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : var1.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
+	}
 }
--- net/minecraft/src/EntitySlime.java
+++ net/minecraft/src/EntitySlime.java
@@ -4,32 +4,40 @@
 	public float squishFactor;
 	public float prevSquishFactor;
 	private int slimeJumpDelay = 0;
-	public int size = 1;
 
 	public EntitySlime(World var1) {
 		super(var1);
 		this.texture = "/mob/slime.png";
-		this.size = 1 << this.rand.nextInt(3);
+		int var2 = 1 << this.rand.nextInt(3);
 		this.yOffset = 0.0F;
 		this.slimeJumpDelay = this.rand.nextInt(20) + 10;
-		this.setSlimeSize(this.size);
+		this.setSlimeSize(var2);
+	}
+
+	protected void entityInit() {
+		super.entityInit();
+		this.dataWatcher.addObject(16, new Byte((byte)1));
 	}
 
 	public void setSlimeSize(int var1) {
-		this.size = var1;
+		this.dataWatcher.updateObject(16, new Byte((byte)var1));
 		this.setSize(0.6F * (float)var1, 0.6F * (float)var1);
 		this.health = var1 * var1;
 		this.setPosition(this.posX, this.posY, this.posZ);
 	}
+	
+	public int getSlimeSize() {
+		return this.dataWatcher.getWatchableObjectByte(16);
+	}
 
 	public void writeEntityToNBT(NBTTagCompound var1) {
 		super.writeEntityToNBT(var1);
-		var1.setInteger("Size", this.size - 1);
+		var1.setInteger("Size", this.getSlimeSize() - 1);
 	}
 
 	public void readEntityFromNBT(NBTTagCompound var1) {
 		super.readEntityFromNBT(var1);
-		this.size = var1.getInteger("Size") + 1;
+		this.setSlimeSize(var1.getInteger("Size") + 1);
 	}
 
 	public void onUpdate() {
@@ -37,15 +45,17 @@
 		boolean var1 = this.onGround;
 		super.onUpdate();
 		if(this.onGround && !var1) {
-			for(int var2 = 0; var2 < this.size * 8; ++var2) {
+			int size = this.getSlimeSize();
+			
+			for(int var2 = 0; var2 < size * 8; ++var2) {
 				float var3 = this.rand.nextFloat() * (float)Math.PI * 2.0F;
 				float var4 = this.rand.nextFloat() * 0.5F + 0.5F;
-				float var5 = MathHelper.sin(var3) * (float)this.size * 0.5F * var4;
-				float var6 = MathHelper.cos(var3) * (float)this.size * 0.5F * var4;
+				float var5 = MathHelper.sin(var3) * (float)size * 0.5F * var4;
+				float var6 = MathHelper.cos(var3) * (float)size * 0.5F * var4;
 				this.worldObj.spawnParticle("slime", this.posX + (double)var5, this.boundingBox.minY, this.posZ + (double)var6, 0.0D, 0.0D, 0.0D);
 			}
 
-			if(this.size > 2) {
+			if(size > 2) {
 				this.worldObj.playSoundAtEntity(this, "mob.slime", this.getSoundVolume(), ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) / 0.8F);
 			}
 
@@ -68,13 +78,13 @@
 			}
 
 			this.isJumping = true;
-			if(this.size > 1) {
+			if(this.getSlimeSize() > 1) {
 				this.worldObj.playSoundAtEntity(this, "mob.slime", this.getSoundVolume(), ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) * 0.8F);
 			}
 
 			this.squishFactor = 1.0F;
 			this.moveStrafing = 1.0F - this.rand.nextFloat() * 2.0F;
-			this.moveForward = (float)(1 * this.size);
+			this.moveForward = (float)(1 * this.getSlimeSize());
 		} else {
 			this.isJumping = false;
 			if(this.onGround) {
@@ -85,12 +95,13 @@
 	}
 
 	public void setEntityDead() {
-		if(this.size > 1 && this.health == 0) {
+		int size = this.getSlimeSize();
+		if(!this.worldObj.multiplayerWorld && size > 1 && this.health == 0) {
 			for(int var1 = 0; var1 < 4; ++var1) {
-				float var2 = ((float)(var1 % 2) - 0.5F) * (float)this.size / 4.0F;
-				float var3 = ((float)(var1 / 2) - 0.5F) * (float)this.size / 4.0F;
+				float var2 = ((float)(var1 % 2) - 0.5F) * (float)size / 4.0F;
+				float var3 = ((float)(var1 / 2) - 0.5F) * (float)size / 4.0F;
 				EntitySlime var4 = new EntitySlime(this.worldObj);
-				var4.setSlimeSize(this.size / 2);
+				var4.setSlimeSize(size / 2);
 				var4.setLocationAndAngles(this.posX + (double)var2, this.posY + 0.5D, this.posZ + (double)var3, this.rand.nextFloat() * 360.0F, 0.0F);
 				this.worldObj.spawnEntityInWorld(var4);
 			}
@@ -100,7 +111,8 @@
 	}
 
 	public void onCollideWithPlayer(EntityPlayer var1) {
-		if(this.size > 1 && this.canEntityBeSeen(var1) && (double)this.getDistanceToEntity(var1) < 0.6D * (double)this.size && var1.attackEntityFrom(this, this.size)) {
+		int size = this.getSlimeSize();
+		if(size > 1 && this.canEntityBeSeen(var1) && (double)this.getDistanceToEntity(var1) < 0.6D * (double)size && var1.attackEntityFrom(this, size)) {
 			this.worldObj.playSoundAtEntity(this, "mob.slimeattack", 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
 		}
 
@@ -115,12 +127,12 @@
 	}
 
 	protected int getDropItemId() {
-		return this.size == 1 ? Item.slimeBall.shiftedIndex : 0;
+		return this.getSlimeSize() == 1 ? Item.slimeBall.shiftedIndex : 0;
 	}
 
 	public boolean getCanSpawnHere() {
 		Chunk var1 = this.worldObj.getChunkFromBlockCoords(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY));
-		return (this.size == 1 || this.worldObj.difficultySetting > 0) && this.rand.nextInt(10) == 0 && var1.getRandomWithSeed(987234911L).nextInt(10) == 0 && this.posY < 16.0D;
+		return (this.getSlimeSize() == 1 || this.worldObj.difficultySetting > 0) && this.rand.nextInt(10) == 0 && var1.getRandomWithSeed(987234911L).nextInt(10) == 0 && this.posY < 16.0D;
 	}
 
 	protected float getSoundVolume() {
--- net/minecraft/src/ItemRenderer.java
+++ net/minecraft/src/ItemRenderer.java
@@ -10,6 +10,7 @@
 	private float equippedProgress = 0.0F;
 	private float prevEquippedProgress = 0.0F;
 	private RenderBlocks renderBlocksInstance = new RenderBlocks();
+	private int field_20099_f = -1;
 
 	public ItemRenderer(Minecraft var1) {
 		this.mc = var1;
@@ -19,7 +20,7 @@
 		GL11.glPushMatrix();
 		if(var1.itemID < 256 && RenderBlocks.renderItemIn3d(Block.blocksList[var1.itemID].getRenderType())) {
 			GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.mc.renderEngine.getTexture("/terrain.png"));
-			this.renderBlocksInstance.renderBlockOnInventory(Block.blocksList[var1.itemID]);
+			this.renderBlocksInstance.renderBlockOnInventory(Block.blocksList[var1.itemID], var1.getItemDamageForDisplay());
 		} else {
 			if(var1.itemID < 256) {
 				GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.mc.renderEngine.getTexture("/terrain.png"));
@@ -194,7 +195,7 @@
 	public void renderOverlays(float var1) {
 		GL11.glDisable(GL11.GL_ALPHA_TEST);
 		int var2;
-		if(this.mc.thePlayer.fire > 0) {
+		if(this.mc.thePlayer.isBurning()) {
 			var2 = this.mc.renderEngine.getTexture("/terrain.png");
 			GL11.glBindTexture(GL11.GL_TEXTURE_2D, var2);
 			this.renderFireInFirstPerson(var1);
@@ -313,8 +314,18 @@
 		this.prevEquippedProgress = this.equippedProgress;
 		EntityPlayerSP var1 = this.mc.thePlayer;
 		ItemStack var2 = var1.inventory.getCurrentItem();
+		boolean bool = this.field_20099_f == var1.inventory.currentItem && var2 == this.itemToRender;
+		if(this.itemToRender == null && var2 == null) {
+			bool = true;
+		}
+
+		if(var2 != null && this.itemToRender != null && var2 != this.itemToRender && var2.itemID == this.itemToRender.itemID && var2.getItemDamage() == this.itemToRender.getItemDamage()) {
+			this.itemToRender = var2;
+			bool = true;
+		}
+		
 		float var4 = 0.4F;
-		float var5 = var2 == this.itemToRender ? 1.0F : 0.0F;
+		float var5 = bool ? 1.0F : 0.0F;
 		float var6 = var5 - this.equippedProgress;
 		if(var6 < -var4) {
 			var6 = -var4;
@@ -327,6 +338,7 @@
 		this.equippedProgress += var6;
 		if(this.equippedProgress < 0.1F) {
 			this.itemToRender = var2;
+			this.field_20099_f = var1.inventory.currentItem;
 		}
 
 	}
--- net/minecraft/src/BlockGrass.java
+++ net/minecraft/src/BlockGrass.java
@@ -21,6 +21,9 @@
 	}
 
 	public void updateTick(World var1, int var2, int var3, int var4, Random var5) {
+		if(var1.multiplayerWorld)
+			return;
+
 		if(var1.getBlockLightValue(var2, var3 + 1, var4) < 4 && var1.getBlockMaterial(var2, var3 + 1, var4).getCanBlockGrass()) {
 			if(var5.nextInt(4) != 0) {
 				return;
--- net/minecraft/src/Packet29DestroyEntity.java
+++ net/minecraft/src/Packet29DestroyEntity.java
@@ -11,7 +11,7 @@
 		this.entityId = var1.readInt();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.entityId);
 	}
 
--- net/minecraft/src/Packet59ComplexEntity.java
+++ /dev/null
@@ -1,59 +1,0 @@
-package net.minecraft.src;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-public class Packet59ComplexEntity extends Packet {
-	public int xCoord;
-	public int yCoord;
-	public int zCoord;
-	public byte[] compressedNBT;
-	public NBTTagCompound tileEntityNBT;
-
-	public Packet59ComplexEntity() {
-		this.isChunkDataPacket = true;
-	}
-
-	public Packet59ComplexEntity(int var1, int var2, int var3, TileEntity var4) {
-		this.isChunkDataPacket = true;
-		this.xCoord = var1;
-		this.yCoord = var2;
-		this.zCoord = var3;
-		this.tileEntityNBT = new NBTTagCompound();
-		var4.writeToNBT(this.tileEntityNBT);
-
-		try {
-			this.compressedNBT = CompressedStreamTools.compress(this.tileEntityNBT);
-		} catch (IOException var6) {
-			var6.printStackTrace();
-		}
-
-	}
-
-	public void readPacketData(DataInputStream var1) throws IOException {
-		this.xCoord = var1.readInt();
-		this.yCoord = var1.readShort();
-		this.zCoord = var1.readInt();
-		int var2 = var1.readShort() & '\uffff';
-		this.compressedNBT = new byte[var2];
-		var1.readFully(this.compressedNBT);
-		this.tileEntityNBT = CompressedStreamTools.decompress(this.compressedNBT);
-	}
-
-	public void writePacket(DataOutputStream var1) throws IOException {
-		var1.writeInt(this.xCoord);
-		var1.writeShort(this.yCoord);
-		var1.writeInt(this.zCoord);
-		var1.writeShort((short)this.compressedNBT.length);
-		var1.write(this.compressedNBT);
-	}
-
-	public void processPacket(NetHandler var1) {
-		var1.handleComplexEntity(this);
-	}
-
-	public int getPacketSize() {
-		return this.compressedNBT.length + 2 + 10;
-	}
-}
--- net/minecraft/src/CraftingRecipe.java
+++ /dev/null
@@ -1,64 +1,0 @@
-package net.minecraft.src;
-
-public class CraftingRecipe {
-	private int width;
-	private int height;
-	private int[] ingredientMap;
-	private ItemStack resultStack;
-	public final int resultId;
-
-	public CraftingRecipe(int var1, int var2, int[] var3, ItemStack var4) {
-		this.resultId = var4.itemID;
-		this.width = var1;
-		this.height = var2;
-		this.ingredientMap = var3;
-		this.resultStack = var4;
-	}
-
-	public boolean matches(int[] var1) {
-		for(int var2 = 0; var2 <= 3 - this.width; ++var2) {
-			for(int var3 = 0; var3 <= 3 - this.height; ++var3) {
-				if(this.checkMatch(var1, var2, var3, true)) {
-					return true;
-				}
-
-				if(this.checkMatch(var1, var2, var3, false)) {
-					return true;
-				}
-			}
-		}
-
-		return false;
-	}
-
-	private boolean checkMatch(int[] var1, int var2, int var3, boolean var4) {
-		for(int var5 = 0; var5 < 3; ++var5) {
-			for(int var6 = 0; var6 < 3; ++var6) {
-				int var7 = var5 - var2;
-				int var8 = var6 - var3;
-				int var9 = -1;
-				if(var7 >= 0 && var8 >= 0 && var7 < this.width && var8 < this.height) {
-					if(var4) {
-						var9 = this.ingredientMap[this.width - var7 - 1 + var8 * this.width];
-					} else {
-						var9 = this.ingredientMap[var7 + var8 * this.width];
-					}
-				}
-
-				if(var1[var5 + var6 * 3] != var9) {
-					return false;
-				}
-			}
-		}
-
-		return true;
-	}
-
-	public ItemStack getCraftingResult(int[] var1) {
-		return new ItemStack(this.resultStack.itemID, this.resultStack.stackSize);
-	}
-
-	public int getRecipeSize() {
-		return this.width * this.height;
-	}
-}
--- /dev/null
+++ net/minecraft/src/Packet63WorldParticles.java
@@ -1,0 +1,88 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet63WorldParticles extends Packet {
+
+    private String a;
+    private float b;
+    private float c;
+    private float d;
+    private float e;
+    private float f;
+    private float g;
+    private float h;
+    private int i;
+
+    public Packet63WorldParticles() {}
+
+    public void readPacketData(DataInputStream datainputstream) throws IOException {
+        this.a = readString(datainputstream, 64);
+        this.b = datainputstream.readFloat();
+        this.c = datainputstream.readFloat();
+        this.d = datainputstream.readFloat();
+        this.e = datainputstream.readFloat();
+        this.f = datainputstream.readFloat();
+        this.g = datainputstream.readFloat();
+        this.h = datainputstream.readFloat();
+        this.i = datainputstream.readInt();
+    }
+
+    public void writePacketData(DataOutputStream dataoutputstream) throws IOException {
+        writeString(this.a, dataoutputstream);
+        dataoutputstream.writeFloat(this.b);
+        dataoutputstream.writeFloat(this.c);
+        dataoutputstream.writeFloat(this.d);
+        dataoutputstream.writeFloat(this.e);
+        dataoutputstream.writeFloat(this.f);
+        dataoutputstream.writeFloat(this.g);
+        dataoutputstream.writeFloat(this.h);
+        dataoutputstream.writeInt(this.i);
+    }
+
+    public String getType() {
+       return this.a;
+    }
+
+    public double getX() {
+       return this.b;
+    }
+
+    public double getY() {
+       return this.c;
+    }
+
+    public double getZ() {
+       return this.d;
+    }
+
+    public float getVelocityX() {
+       return this.e;
+    }
+
+    public float getVelocityY() {
+       return this.f;
+    }
+
+    public float getVelocityZ() {
+       return this.g;
+    }
+
+    public float getVelocityScale() {
+       return this.h;
+    }
+
+    public int getCount() {
+       return this.i;
+    }
+
+    public void processPacket(NetHandler connection) {
+        connection.handleParticle(this);
+    }
+
+    public int getPacketSize() {
+        return 64;
+    }
+}
--- net/minecraft/src/Packet0KeepAlive.java
+++ net/minecraft/src/Packet0KeepAlive.java
@@ -2,15 +2,16 @@
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.io.IOException;
 
 public class Packet0KeepAlive extends Packet {
 	public void processPacket(NetHandler var1) {
 	}
 
-	public void readPacketData(DataInputStream var1) {
+	public void readPacketData(DataInputStream var1) throws IOException {
 	}
 
-	public void writePacket(DataOutputStream var1) {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 	}
 
 	public int getPacketSize() {
--- net/minecraft/src/Slot.java
+++ net/minecraft/src/Slot.java
@@ -1,15 +1,20 @@
 package net.minecraft.src;
 
 public class Slot {
-	public final int slotIndex;
-	public final IInventory inventory;
+	private final int slotIndex;
+	private final IInventory inventory;
+	public int slotNumber;
+	public int xDisplayPosition;
+	public int yDisplayPosition;
 
-	public Slot(IInventory var1, int var2) {
+	public Slot(IInventory var1, int var2, int var3, int var4) {
 		this.inventory = var1;
 		this.slotIndex = var2;
+		this.xDisplayPosition = var3;
+		this.yDisplayPosition = var4;
 	}
 
-	public void onPickupFromSlot() {
+	public void onPickupFromSlot(ItemStack var1) {
 		this.onSlotChanged();
 	}
 
@@ -21,16 +26,28 @@
 		return this.inventory.getStackInSlot(this.slotIndex);
 	}
 
+	public boolean getHasStack() {
+		return this.getStack() != null;
+	}
+
 	public void putStack(ItemStack var1) {
 		this.inventory.setInventorySlotContents(this.slotIndex, var1);
 		this.onSlotChanged();
 	}
 
-	public int getBackgroundIconIndex() {
-		return -1;
-	}
-
 	public void onSlotChanged() {
 		this.inventory.onInventoryChanged();
+	}
+
+	public int getSlotStackLimit() {
+		return this.inventory.getInventoryStackLimit();
+	}
+
+	public int getBackgroundIconIndex() {
+		return -1;
+	}
+
+	public ItemStack decrStackSize(int var1) {
+		return this.inventory.decrStackSize(this.slotIndex, var1);
 	}
 }
--- /dev/null
+++ net/minecraft/src/Packet27Position.java
@@ -1,0 +1,40 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet27Position extends Packet {
+	private float field_22039_a;
+	private float field_22038_b;
+	private boolean field_22043_c;
+	private boolean field_22042_d;
+	private float field_22041_e;
+	private float field_22040_f;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.field_22039_a = var1.readFloat();
+		this.field_22038_b = var1.readFloat();
+		this.field_22041_e = var1.readFloat();
+		this.field_22040_f = var1.readFloat();
+		this.field_22043_c = var1.readBoolean();
+		this.field_22042_d = var1.readBoolean();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeFloat(this.field_22039_a);
+		var1.writeFloat(this.field_22038_b);
+		var1.writeFloat(this.field_22041_e);
+		var1.writeFloat(this.field_22040_f);
+		var1.writeBoolean(this.field_22043_c);
+		var1.writeBoolean(this.field_22042_d);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_22185_a(this);
+	}
+
+	public int getPacketSize() {
+		return 18;
+	}
+}
--- net/minecraft/src/BlockFurnace.java
+++ net/minecraft/src/BlockFurnace.java
@@ -86,6 +86,9 @@
 	}
 
 	public boolean blockActivated(World var1, int var2, int var3, int var4, EntityPlayer var5) {
+		if(var1.multiplayerWorld) {
+			return true;
+		}
 		TileEntityFurnace var6 = (TileEntityFurnace)var1.getBlockTileEntity(var2, var3, var4);
 		var5.displayGUIFurnace(var6);
 		return true;
--- /dev/null
+++ net/minecraft/src/ShapelessRecipes.java
@@ -1,0 +1,56 @@
+package net.minecraft.src;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ShapelessRecipes implements IRecipe {
+	private final ItemStack recipeOutput;
+	private final List recipeItems;
+
+	public ShapelessRecipes(ItemStack var1, List var2) {
+		this.recipeOutput = var1;
+		this.recipeItems = var2;
+	}
+
+	public ItemStack getRecipeOutput() {
+		return this.recipeOutput;
+	}
+
+	public boolean matches(InventoryCrafting var1) {
+		ArrayList var2 = new ArrayList(this.recipeItems);
+
+		for(int var3 = 0; var3 < 3; ++var3) {
+			for(int var4 = 0; var4 < 3; ++var4) {
+				ItemStack var5 = var1.func_21103_b(var4, var3);
+				if(var5 != null) {
+					boolean var6 = false;
+					Iterator var7 = var2.iterator();
+
+					while(var7.hasNext()) {
+						ItemStack var8 = (ItemStack)var7.next();
+						if(var5.itemID == var8.itemID && (var8.getItemDamage() == -1 || var5.getItemDamage() == var8.getItemDamage())) {
+							var6 = true;
+							var2.remove(var8);
+							break;
+						}
+					}
+
+					if(!var6) {
+						return false;
+					}
+				}
+			}
+		}
+
+		return var2.isEmpty();
+	}
+
+	public ItemStack getCraftingResult(InventoryCrafting var1) {
+		return this.recipeOutput.copy();
+	}
+
+	public int getRecipeSize() {
+		return this.recipeItems.size();
+	}
+}
--- /dev/null
+++ net/minecraft/src/Container.java
@@ -1,0 +1,253 @@
+package net.minecraft.src;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public abstract class Container {
+	public List field_20123_d = new ArrayList();
+	public List slots = new ArrayList();
+	public int windowId = 0;
+	private short field_20917_a = 0;
+	protected List field_20121_g = new ArrayList();
+	private Set field_20918_b = new HashSet();
+
+	protected void addSlot(Slot var1) {
+		var1.slotNumber = this.slots.size();
+		this.slots.add(var1);
+		this.field_20123_d.add((Object)null);
+	}
+
+	public void updateCraftingResults() {
+		for(int var1 = 0; var1 < this.slots.size(); ++var1) {
+			ItemStack var2 = ((Slot)this.slots.get(var1)).getStack();
+			ItemStack var3 = (ItemStack)this.field_20123_d.get(var1);
+			if(!ItemStack.areItemStacksEqual(var3, var2)) {
+				var3 = var2 == null ? null : var2.copy();
+				this.field_20123_d.set(var1, var3);
+
+				for(int var4 = 0; var4 < this.field_20121_g.size(); ++var4) {
+					((ICrafting)this.field_20121_g.get(var4)).func_20159_a(this, var1, var3);
+				}
+			}
+		}
+
+	}
+
+	public Slot getSlot(int var1) {
+		return (Slot)this.slots.get(var1);
+	}
+
+	public ItemStack getStackInSlot(int var1) {
+		Slot var2 = (Slot)this.slots.get(var1);
+		return var2 != null ? var2.getStack() : null;
+	}
+
+	public ItemStack func_27280_a(int var1, int var2, boolean var3, EntityPlayer var4) {
+		ItemStack var5 = null;
+		if(var2 == 0 || var2 == 1) {
+			InventoryPlayer var6 = var4.inventory;
+			if(var1 == -999) {
+				if(var6.getItemStack() != null && var1 == -999) {
+					if(var2 == 0) {
+						var4.dropPlayerItem(var6.getItemStack());
+						var6.setItemStack((ItemStack)null);
+					}
+
+					if(var2 == 1) {
+						var4.dropPlayerItem(var6.getItemStack().splitStack(1));
+						if(var6.getItemStack().stackSize == 0) {
+							var6.setItemStack((ItemStack)null);
+						}
+					}
+				}
+			} else {
+				int var10;
+				if(var3) {
+					ItemStack var7 = this.getStackInSlot(var1);
+					if(var7 != null) {
+						int var8 = var7.stackSize;
+						var5 = var7.copy();
+						Slot var9 = (Slot)this.slots.get(var1);
+						if(var9 != null && var9.getStack() != null) {
+							var10 = var9.getStack().stackSize;
+							if(var10 < var8) {
+								this.func_27280_a(var1, var2, var3, var4);
+							}
+						}
+					}
+				} else {
+					Slot var12 = (Slot)this.slots.get(var1);
+					if(var12 != null) {
+						var12.onSlotChanged();
+						ItemStack var13 = var12.getStack();
+						ItemStack var14 = var6.getItemStack();
+						if(var13 != null) {
+							var5 = var13.copy();
+						}
+
+						if(var13 == null) {
+							if(var14 != null && var12.isItemValid(var14)) {
+								var10 = var2 == 0 ? var14.stackSize : 1;
+								if(var10 > var12.getSlotStackLimit()) {
+									var10 = var12.getSlotStackLimit();
+								}
+
+								var12.putStack(var14.splitStack(var10));
+								if(var14.stackSize == 0) {
+									var6.setItemStack((ItemStack)null);
+								}
+							}
+						} else if(var14 == null) {
+							var10 = var2 == 0 ? var13.stackSize : (var13.stackSize + 1) / 2;
+							ItemStack var11 = var12.decrStackSize(var10);
+							var6.setItemStack(var11);
+							if(var13.stackSize == 0) {
+								var12.putStack((ItemStack)null);
+							}
+
+							var12.onPickupFromSlot(var6.getItemStack());
+						} else if(var12.isItemValid(var14)) {
+							if(var13.itemID != var14.itemID || var13.getHasSubtypes() && var13.getItemDamage() != var14.getItemDamage()) {
+								if(var14.stackSize <= var12.getSlotStackLimit()) {
+									var12.putStack(var14);
+									var6.setItemStack(var13);
+								}
+							} else {
+								var10 = var2 == 0 ? var14.stackSize : 1;
+								if(var10 > var12.getSlotStackLimit() - var13.stackSize) {
+									var10 = var12.getSlotStackLimit() - var13.stackSize;
+								}
+
+								if(var10 > var14.getMaxStackSize() - var13.stackSize) {
+									var10 = var14.getMaxStackSize() - var13.stackSize;
+								}
+
+								var14.splitStack(var10);
+								if(var14.stackSize == 0) {
+									var6.setItemStack((ItemStack)null);
+								}
+
+								var13.stackSize += var10;
+							}
+						} else if(var13.itemID == var14.itemID && var14.getMaxStackSize() > 1 && (!var13.getHasSubtypes() || var13.getItemDamage() == var14.getItemDamage())) {
+							var10 = var13.stackSize;
+							if(var10 > 0 && var10 + var14.stackSize <= var14.getMaxStackSize()) {
+								var14.stackSize += var10;
+								var13.splitStack(var10);
+								if(var13.stackSize == 0) {
+									var12.putStack((ItemStack)null);
+								}
+
+								var12.onPickupFromSlot(var6.getItemStack());
+							}
+						}
+					}
+				}
+			}
+		}
+
+		return var5;
+	}
+
+	public void onCraftGuiClosed(EntityPlayer var1) {
+		InventoryPlayer var2 = var1.inventory;
+		if(var2.getItemStack() != null) {
+			var1.dropPlayerItem(var2.getItemStack());
+			var2.setItemStack((ItemStack)null);
+		}
+
+	}
+
+	public void onCraftMatrixChanged(IInventory var1) {
+		this.updateCraftingResults();
+	}
+
+	public void putStackInSlot(int var1, ItemStack var2) {
+		this.getSlot(var1).putStack(var2);
+	}
+
+	public void putStacksInSlots(ItemStack[] var1) {
+		for(int var2 = 0; var2 < var1.length; ++var2) {
+			this.getSlot(var2).putStack(var1[var2]);
+		}
+
+	}
+
+	public void func_20112_a(int var1, int var2) {
+	}
+
+	public short func_20111_a(InventoryPlayer var1) {
+		++this.field_20917_a;
+		return this.field_20917_a;
+	}
+
+	public void func_20113_a(short var1) {
+	}
+
+	public void func_20110_b(short var1) {
+	}
+
+	public abstract boolean isUsableByPlayer(EntityPlayer var1);
+
+	protected void func_28125_a(ItemStack var1, int var2, int var3, boolean var4) {
+		int var5 = var2;
+		if(var4) {
+			var5 = var3 - 1;
+		}
+
+		Slot var6;
+		ItemStack var7;
+		if(var1.isStackable()) {
+			while(var1.stackSize > 0 && (!var4 && var5 < var3 || var4 && var5 >= var2)) {
+				var6 = (Slot)this.slots.get(var5);
+				var7 = var6.getStack();
+				if(var7 != null && var7.itemID == var1.itemID && (!var1.getHasSubtypes() || var1.getItemDamage() == var7.getItemDamage())) {
+					int var8 = var7.stackSize + var1.stackSize;
+					if(var8 <= var1.getMaxStackSize()) {
+						var1.stackSize = 0;
+						var7.stackSize = var8;
+						var6.onSlotChanged();
+					} else if(var7.stackSize < var1.getMaxStackSize()) {
+						var1.stackSize -= var1.getMaxStackSize() - var7.stackSize;
+						var7.stackSize = var1.getMaxStackSize();
+						var6.onSlotChanged();
+					}
+				}
+
+				if(var4) {
+					--var5;
+				} else {
+					++var5;
+				}
+			}
+		}
+
+		if(var1.stackSize > 0) {
+			if(var4) {
+				var5 = var3 - 1;
+			} else {
+				var5 = var2;
+			}
+
+			while(!var4 && var5 < var3 || var4 && var5 >= var2) {
+				var6 = (Slot)this.slots.get(var5);
+				var7 = var6.getStack();
+				if(var7 == null) {
+					var6.putStack(var1.copy());
+					var6.onSlotChanged();
+					var1.stackSize = 0;
+					break;
+				}
+
+				if(var4) {
+					--var5;
+				} else {
+					++var5;
+				}
+			}
+		}
+
+	}
+}
--- net/minecraft/src/Packet22Collect.java
+++ net/minecraft/src/Packet22Collect.java
@@ -13,7 +13,7 @@
 		this.collectorEntityId = var1.readInt();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.collectedEntityId);
 		var1.writeInt(this.collectorEntityId);
 	}
--- net/minecraft/src/SlotCrafting.java
+++ net/minecraft/src/SlotCrafting.java
@@ -1,10 +1,12 @@
 package net.minecraft.src;
 
-public class SlotCrafting extends SlotInventory {
+public class SlotCrafting extends Slot {
 	private final IInventory craftMatrix;
+	private EntityPlayer thePlayer;
 
-	public SlotCrafting(GuiContainer var1, IInventory var2, IInventory var3, int var4, int var5, int var6) {
-		super(var1, var3, var4, var5, var6);
+	public SlotCrafting(EntityPlayer var1, IInventory var2, IInventory var3, int var4, int var5, int var6) {
+		super(var3, var4, var5, var6);
+		this.thePlayer = var1;
 		this.craftMatrix = var2;
 	}
 
@@ -12,10 +14,16 @@
 		return false;
 	}
 
-	public void onPickupFromSlot() {
-		for(int var1 = 0; var1 < this.craftMatrix.getSizeInventory(); ++var1) {
-			if(this.craftMatrix.getStackInSlot(var1) != null) {
-				this.craftMatrix.decrStackSize(var1, 1);
+	public void onPickupFromSlot(ItemStack var1) {
+		var1.onCrafting(this.thePlayer.worldObj, this.thePlayer);
+
+		for(int var2 = 0; var2 < this.craftMatrix.getSizeInventory(); ++var2) {
+			ItemStack var3 = this.craftMatrix.getStackInSlot(var2);
+			if(var3 != null) {
+				this.craftMatrix.decrStackSize(var2, 1);
+				if(var3.getItem().hasContainerItem()) {
+					this.craftMatrix.setInventorySlotContents(var2, new ItemStack(var3.getItem().getContainerItem()));
+				}
 			}
 		}
 
--- net/minecraft/src/GuiFurnace.java
+++ net/minecraft/src/GuiFurnace.java
@@ -6,21 +6,8 @@
 	private TileEntityFurnace furnaceInventory;
 
 	public GuiFurnace(InventoryPlayer var1, TileEntityFurnace var2) {
+		super(new ContainerFurnace(var1, var2));
 		this.furnaceInventory = var2;
-		this.inventorySlots.add(new SlotInventory(this, var2, 0, 56, 17));
-		this.inventorySlots.add(new SlotInventory(this, var2, 1, 56, 53));
-		this.inventorySlots.add(new SlotInventory(this, var2, 2, 116, 35));
-
-		int var3;
-		for(var3 = 0; var3 < 3; ++var3) {
-			for(int var4 = 0; var4 < 9; ++var4) {
-				this.inventorySlots.add(new SlotInventory(this, var1, var4 + (var3 + 1) * 9, 8 + var4 * 18, 84 + var3 * 18));
-			}
-		}
-
-		for(var3 = 0; var3 < 9; ++var3) {
-			this.inventorySlots.add(new SlotInventory(this, var1, var3, 8 + var3 * 18, 142));
-		}
 
 	}
 
--- /dev/null
+++ net/minecraft/src/ContainerChest.java
@@ -1,0 +1,57 @@
+package net.minecraft.src;
+
+public class ContainerChest extends Container {
+	private IInventory field_20125_a;
+	private int field_27282_b;
+
+	public ContainerChest(IInventory var1, IInventory var2) {
+		this.field_20125_a = var2;
+		this.field_27282_b = var2.getSizeInventory() / 9;
+		int var3 = (this.field_27282_b - 4) * 18;
+
+		int var4;
+		int var5;
+		for(var4 = 0; var4 < this.field_27282_b; ++var4) {
+			for(var5 = 0; var5 < 9; ++var5) {
+				this.addSlot(new Slot(var2, var5 + var4 * 9, 8 + var5 * 18, 18 + var4 * 18));
+			}
+		}
+
+		for(var4 = 0; var4 < 3; ++var4) {
+			for(var5 = 0; var5 < 9; ++var5) {
+				this.addSlot(new Slot(var1, var5 + var4 * 9 + 9, 8 + var5 * 18, 103 + var4 * 18 + var3));
+			}
+		}
+
+		for(var4 = 0; var4 < 9; ++var4) {
+			this.addSlot(new Slot(var1, var4, 8 + var4 * 18, 161 + var3));
+		}
+
+	}
+
+	public boolean isUsableByPlayer(EntityPlayer var1) {
+		return this.field_20125_a.canInteractWith(var1);
+	}
+
+	public ItemStack getStackInSlot(int var1) {
+		ItemStack var2 = null;
+		Slot var3 = (Slot)this.slots.get(var1);
+		if(var3 != null && var3.getHasStack()) {
+			ItemStack var4 = var3.getStack();
+			var2 = var4.copy();
+			if(var1 < this.field_27282_b * 9) {
+				this.func_28125_a(var4, this.field_27282_b * 9, this.slots.size(), true);
+			} else {
+				this.func_28125_a(var4, 0, this.field_27282_b * 9, false);
+			}
+
+			if(var4.stackSize == 0) {
+				var3.putStack((ItemStack)null);
+			} else {
+				var3.onSlotChanged();
+			}
+		}
+
+		return var2;
+	}
+}
--- net/minecraft/src/Packet53BlockChange.java
+++ net/minecraft/src/Packet53BlockChange.java
@@ -23,7 +23,7 @@
 		this.metadata = var1.read();
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.xPosition);
 		var1.write(this.yPosition);
 		var1.writeInt(this.zPosition);
--- net/minecraft/src/Packet51MapChunk.java
+++ net/minecraft/src/Packet51MapChunk.java
@@ -13,8 +13,8 @@
 	public int xSize;
 	public int ySize;
 	public int zSize;
-	public byte[] chunkData;
-	private int tempLength;
+	public byte[] chunk;
+	private int chunkSize;
 
 	public Packet51MapChunk() {
 		this.isChunkDataPacket = true;
@@ -27,32 +27,32 @@
 		this.xSize = var1.read() + 1;
 		this.ySize = var1.read() + 1;
 		this.zSize = var1.read() + 1;
-		int var2 = var1.readInt();
-		byte[] var3 = new byte[var2];
-		var1.readFully(var3);
-		this.chunkData = new byte[this.xSize * this.ySize * this.zSize * 5 / 2];
-		Inflater var4 = new Inflater();
-		var4.setInput(var3);
+		this.chunkSize = var1.readInt();
+		byte[] var2 = new byte[this.chunkSize];
+		var1.readFully(var2);
+		this.chunk = new byte[this.xSize * this.ySize * this.zSize * 5 / 2];
+		Inflater var3 = new Inflater();
+		var3.setInput(var2);
 
 		try {
-			var4.inflate(this.chunkData);
-		} catch (DataFormatException var9) {
+			var3.inflate(this.chunk);
+		} catch (DataFormatException var8) {
 			throw new IOException("Bad compressed data format");
 		} finally {
-			var4.end();
+			var3.end();
 		}
 
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.xPosition);
 		var1.writeShort(this.yPosition);
 		var1.writeInt(this.zPosition);
 		var1.write(this.xSize - 1);
 		var1.write(this.ySize - 1);
 		var1.write(this.zSize - 1);
-		var1.writeInt(this.tempLength);
-		var1.write(this.chunkData, 0, this.tempLength);
+		var1.writeInt(this.chunkSize);
+		var1.write(this.chunk, 0, this.chunkSize);
 	}
 
 	public void processPacket(NetHandler var1) {
@@ -60,6 +60,6 @@
 	}
 
 	public int getPacketSize() {
-		return 17 + this.tempLength;
+		return 17 + this.chunkSize;
 	}
 }
--- net/minecraft/src/GuiGameOver.java
+++ net/minecraft/src/GuiGameOver.java
@@ -21,11 +21,15 @@
 		}
 
 		if(var1.id == 1) {
-			this.mc.respawn();
+			this.mc.thePlayer.respawnPlayer();
 			this.mc.displayGuiScreen((GuiScreen)null);
 		}
 
 		if(var1.id == 2) {
+			if (this.mc.isMultiplayerWorld()) {
+				((EntityClientPlayerMP)this.mc.thePlayer).sendQueue.disconnect();
+			}
+			
 			this.mc.changeWorld1((World)null);
 			this.mc.displayGuiScreen(new GuiMainMenu());
 		}
--- /dev/null
+++ net/minecraft/src/Packet8UpdateHealth.java
@@ -1,0 +1,25 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet8UpdateHealth extends Packet {
+	public int healthMP;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.healthMP = var1.readShort();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeShort(this.healthMP);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.handleHealth(this);
+	}
+
+	public int getPacketSize() {
+		return 2;
+	}
+}
--- /dev/null
+++ net/minecraft/src/BlockMiningProgress.java
@@ -1,0 +1,49 @@
+package net.minecraft.src;
+
+public class BlockMiningProgress {
+	   private final int id;
+	   private final int x;
+	   private final int y;
+	   private final int z;
+	   private int progress;
+	   private int lastUpdateTick;
+
+	   public BlockMiningProgress(int entityId, int x, int y, int z) {
+	      this.id = entityId;
+	      this.x = x;
+	      this.y = y;
+	      this.z = z;
+	   }
+
+	   public int getX() {
+	      return this.x;
+	   }
+
+	   public int getY() {
+	      return this.y;
+	   }
+
+	   public int getZ() {
+	      return this.z;
+	   }
+
+	   public void setProgress(int progress) {
+	      if (progress > 10) {
+	         progress = 10;
+	      }
+
+	      this.progress = progress;
+	   }
+
+	   public int getProgress() {
+	      return this.progress;
+	   }
+
+	   public void setLastUpdateTick(int lastUpdateTick) {
+	      this.lastUpdateTick = lastUpdateTick;
+	   }
+
+	   public int getLastUpdateTick() {
+	      return this.lastUpdateTick;
+	   }
+	}
--- net/minecraft/src/ItemTool.java
+++ net/minecraft/src/ItemTool.java
@@ -30,12 +30,12 @@
 		return 1.0F;
 	}
 
-	public void hitEntity(ItemStack var1, EntityLiving var2) {
-		var1.damageItem(2);
+	public void hitEntity(ItemStack var1, EntityLiving var2, EntityLiving var3) {
+		var1.damageItem(2, var3);
 	}
 
-	public void onBlockDestroyed(ItemStack var1, int var2, int var3, int var4, int var5) {
-		var1.damageItem(1);
+	public void onBlockDestroyed(ItemStack var1, int var2, int var3, int var4, int var5, EntityLiving var6) {
+		var1.damageItem(1, var6);
 	}
 
 	public int getDamageVsEntity(Entity var1) {
--- net/minecraft/src/EntityLiving.java
+++ net/minecraft/src/EntityLiving.java
@@ -26,6 +26,7 @@
 	public float swingProgress;
 	public int health = 10;
 	public int prevHealth;
+	public int somethingHealth = 0;
 	private int livingSoundTime;
 	public int hurtTime;
 	public int maxHurtTime;
@@ -67,6 +68,9 @@
 		this.unusedFloat = 1.0F;
 		this.stepHeight = 0.5F;
 	}
+	
+	protected void entityInit() {
+	}
 
 	protected boolean canEntityBeSeen(Entity var1) {
 		return this.worldObj.rayTraceBlocks(Vec3D.createVector(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ), Vec3D.createVector(var1.posX, var1.posY + (double)var1.getEyeHeight(), var1.posZ)) == null;
@@ -98,7 +102,7 @@
 		if(this.rand.nextInt(1000) < this.livingSoundTime++) {
 			this.livingSoundTime = -this.getTalkInterval();
 			String var1 = this.getLivingSound();
-			if(var1 != null) {
+			if(var1 != null && !this.worldObj.multiplayerWorld) {
 				this.worldObj.playSoundAtEntity(this, var1, this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
 			}
 		}
@@ -295,7 +299,7 @@
 
 	public boolean attackEntityFrom(Entity var1, int var2) {
 		if(this.worldObj.multiplayerWorld) {
-			var2 = 0;
+			return false;
 		}
 
 		this.entityAge = 0;
@@ -303,44 +307,62 @@
 			return false;
 		} else {
 			this.limbYaw = 1.5F;
+			boolean bool = true;
 			if((float)this.heartsLife > (float)this.heartsHalvesLife / 2.0F) {
-				if(this.prevHealth - var2 >= this.health) {
+				if(var2 <= this.somethingHealth) {
 					return false;
 				}
 
-				this.health = this.prevHealth - var2;
+				this.damageEntity(var2 - this.somethingHealth);
+				this.somethingHealth = var2;
+				bool = false;
 			} else {
+				this.somethingHealth = var2;
 				this.prevHealth = this.health;
 				this.heartsLife = this.heartsHalvesLife;
-				this.health -= var2;
+				this.damageEntity(var2);
 				this.hurtTime = this.maxHurtTime = 10;
 			}
 
 			this.attackedAtYaw = 0.0F;
-			if(var1 != null) {
-				double var3 = var1.posX - this.posX;
-
-				double var5;
-				for(var5 = var1.posZ - this.posZ; var3 * var3 + var5 * var5 < 1.0E-4D; var5 = (Math.random() - Math.random()) * 0.01D) {
-					var3 = (Math.random() - Math.random()) * 0.01D;
+			if(bool) {
+				if(var1 != null) {
+					double var3 = var1.posX - this.posX;
+
+					double var5;
+					for(var5 = var1.posZ - this.posZ; var3 * var3 + var5 * var5 < 1.0E-4D; var5 = (Math.random() - Math.random()) * 0.01D) {
+						var3 = (Math.random() - Math.random()) * 0.01D;
+					}
+
+					this.attackedAtYaw = (float)(Math.atan2(var5, var3) * 180.0D / (double)((float)Math.PI)) - this.rotationYaw;
+					this.knockBack(var1, var2, var3, var5);
+				} else {
+					this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
 				}
-
-				this.attackedAtYaw = (float)(Math.atan2(var5, var3) * 180.0D / (double)((float)Math.PI)) - this.rotationYaw;
-				this.knockBack(var1, var2, var3, var5);
-			} else {
-				this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
 			}
+			
 
 			if(this.health <= 0) {
-				this.worldObj.playSoundAtEntity(this, this.getDeathSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
+				if (bool && !this.worldObj.multiplayerWorld)
+					this.worldObj.playSoundAtEntity(this, this.getDeathSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
+
 				this.onDeath(var1);
-			} else {
+			} else if (bool && !this.worldObj.multiplayerWorld) {
 				this.worldObj.playSoundAtEntity(this, this.getHurtSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
 			}
 
 			return true;
 		}
 	}
+	
+	public void performHurtAnimation() {
+		this.hurtTime = this.maxHurtTime = 10;
+		this.attackedAtYaw = 0.0F;
+	}
+
+	protected void damageEntity(int var1) {
+		this.health -= var1;
+	}
 
 	protected float getSoundVolume() {
 		return 1.0F;
@@ -379,12 +401,14 @@
 		}
 
 		this.dead = true;
-		int var2 = this.getDropItemId();
-		if(var2 > 0) {
-			int var3 = this.rand.nextInt(3);
+		if(!this.worldObj.multiplayerWorld) {
+			int var2 = this.getDropItemId();
+			if(var2 > 0) {
+				int var3 = this.rand.nextInt(3);
 
-			for(int var4 = 0; var4 < var3; ++var4) {
-				this.dropItem(var2, 1);
+				for(int var4 = 0; var4 < var3; ++var4) {
+					this.dropItem(var2, 1);
+				}
 			}
 		}
 
@@ -399,7 +423,7 @@
 		if(var2 > 0) {
 			this.attackEntityFrom((Entity)null, var2);
 			int var3 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY - (double)0.2F - (double)this.yOffset), MathHelper.floor_double(this.posZ));
-			if(var3 > 0) {
+			if(var3 > 0 && !this.worldObj.multiplayerWorld) {
 				StepSound var4 = Block.blocksList[var3].stepSound;
 				this.worldObj.playSoundAtEntity(this, var4.getStepSound(), var4.getVolume() * 0.5F, var4.getPitch() * (12.0F / 16.0F));
 			}
@@ -725,5 +749,25 @@
 		Vec3D var5 = this.getLook(var3);
 		Vec3D var6 = var4.addVector(var5.xCoord * var1, var5.yCoord * var1, var5.zCoord * var1);
 		return this.worldObj.rayTraceBlocks(var4, var6);
+	}
+	
+	public void handleHealthUpdate(byte var1) {
+		if(var1 == 2) {
+			this.limbYaw = 1.5F;
+			this.heartsLife = this.heartsHalvesLife;
+			this.hurtTime = this.maxHurtTime = 10;
+			this.attackedAtYaw = 0.0F;
+			if (!this.worldObj.multiplayerWorld)
+				this.worldObj.playSoundAtEntity(this, this.getHurtSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
+			this.attackEntityFrom((Entity)null, 0);
+		} else if(var1 == 3) {
+			if (!this.worldObj.multiplayerWorld)
+				this.worldObj.playSoundAtEntity(this, this.getDeathSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
+			this.health = 0;
+			this.onDeath((Entity)null);
+		} else {
+			super.handleHealthUpdate(var1);
+		}
+
 	}
 }
--- net/minecraft/src/ItemMinecart.java
+++ net/minecraft/src/ItemMinecart.java
@@ -12,7 +12,9 @@
 	public boolean onItemUse(ItemStack var1, EntityPlayer var2, World var3, int var4, int var5, int var6, int var7) {
 		int var8 = var3.getBlockId(var4, var5, var6);
 		if(var8 == Block.minecartTrack.blockID) {
-			var3.spawnEntityInWorld(new EntityMinecart(var3, (double)((float)var4 + 0.5F), (double)((float)var5 + 0.5F), (double)((float)var6 + 0.5F), this.minecartType));
+			if(!var3.multiplayerWorld) {
+				var3.spawnEntityInWorld(new EntityMinecart(var3, (double)((float)var4 + 0.5F), (double)((float)var5 + 0.5F), (double)((float)var6 + 0.5F), this.minecartType));
+			}
 			--var1.stackSize;
 			return true;
 		} else {
--- net/minecraft/src/NetworkReaderThread.java
+++ net/minecraft/src/NetworkReaderThread.java
@@ -15,24 +15,29 @@
 		}
 
 		while(true) {
-			boolean var11 = false;
+			boolean var12 = false;
 
 			try {
-				var11 = true;
-				if(NetworkManager.isRunning(this.netManager)) {
-					if(!NetworkManager.isServerTerminating(this.netManager)) {
-						NetworkManager.readNetworkPacket(this.netManager);
-						continue;
-					}
-
-					var11 = false;
-					break;
-				}
-
-				var11 = false;
-				break;
+				var12 = true;
+				if(!NetworkManager.isRunning(this.netManager)) {
+					var12 = false;
+					break;
+				}
+
+				if(NetworkManager.isServerTerminating(this.netManager)) {
+					var12 = false;
+					break;
+				}
+
+				while(NetworkManager.readNetworkPacket(this.netManager)) {
+				}
+
+				try {
+					sleep(2L);
+				} catch (InterruptedException var15) {
+				}
 			} finally {
-				if(var11) {
+				if(var12) {
 					Object var5 = NetworkManager.threadSyncObject;
 					synchronized(var5) {
 						--NetworkManager.numReadThreads;
--- net/minecraft/src/EnumArt.java
+++ net/minecraft/src/EnumArt.java
@@ -26,6 +26,7 @@
 	Skeleton("Skeleton", 64, 48, 192, 64),
 	DonkeyKong("DonkeyKong", 64, 48, 192, 112);
 
+	public static final int maxArtTitleLength = "SkullAndRoses".length();
 	public final String title;
 	public final int sizeX;
 	public final int sizeY;
--- /dev/null
+++ net/minecraft/src/Packet7UseEntity.java
@@ -1,0 +1,40 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet7UseEntity extends Packet {
+	public int playerEntityId;
+	public int targetEntity;
+	public int isLeftClick;
+
+	public Packet7UseEntity() {
+	}
+
+	public Packet7UseEntity(int var1, int var2, int var3) {
+		this.playerEntityId = var1;
+		this.targetEntity = var2;
+		this.isLeftClick = var3;
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.playerEntityId = var1.readInt();
+		this.targetEntity = var1.readInt();
+		this.isLeftClick = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.playerEntityId);
+		var1.writeInt(this.targetEntity);
+		var1.writeByte(this.isLeftClick);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.handleUseEntity(this);
+	}
+
+	public int getPacketSize() {
+		return 9;
+	}
+}
--- net/minecraft/src/RenderPig.java
+++ net/minecraft/src/RenderPig.java
@@ -8,7 +8,7 @@
 
 	protected boolean renderSaddledPig(EntityPig var1, int var2) {
 		this.loadTexture("/mob/saddle.png");
-		return var2 == 0 && var1.saddled;
+		return var2 == 0 && var1.getSaddled();
 	}
 
 	protected boolean shouldRenderPass(EntityLiving var1, int var2) {
--- /dev/null
+++ net/minecraft/src/Packet38EntityStatus.java
@@ -1,0 +1,28 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet38EntityStatus extends Packet {
+	public int entityId;
+	public byte entityStatus;
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.entityId = var1.readInt();
+		this.entityStatus = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.entityId);
+		var1.writeByte(this.entityStatus);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_9447_a(this);
+	}
+
+	public int getPacketSize() {
+		return 5;
+	}
+}
--- net/minecraft/src/Packet24MobSpawn.java
+++ net/minecraft/src/Packet24MobSpawn.java
@@ -3,6 +3,7 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.List;
 
 public class Packet24MobSpawn extends Packet {
 	public int entityId;
@@ -12,6 +13,8 @@
 	public int zPosition;
 	public byte yaw;
 	public byte pitch;
+	private DataWatcher metaData;
+	private List receivedMetadata;
 
 	public Packet24MobSpawn() {
 	}
@@ -24,6 +27,7 @@
 		this.zPosition = MathHelper.floor_double(var1.posZ * 32.0D);
 		this.yaw = (byte)((int)(var1.rotationYaw * 256.0F / 360.0F));
 		this.pitch = (byte)((int)(var1.rotationPitch * 256.0F / 360.0F));
+		this.metaData = var1.getDataWatcher();
 	}
 
 	public void readPacketData(DataInputStream var1) throws IOException {
@@ -34,9 +38,10 @@
 		this.zPosition = var1.readInt();
 		this.yaw = var1.readByte();
 		this.pitch = var1.readByte();
+		this.receivedMetadata = DataWatcher.readWatchableObjects(var1);
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.entityId);
 		var1.writeByte(this.type);
 		var1.writeInt(this.xPosition);
@@ -44,6 +49,7 @@
 		var1.writeInt(this.zPosition);
 		var1.writeByte(this.yaw);
 		var1.writeByte(this.pitch);
+		this.metaData.writeWatchableObjects(var1);
 	}
 
 	public void processPacket(NetHandler var1) {
@@ -51,6 +57,10 @@
 	}
 
 	public int getPacketSize() {
-		return 19;
+		return 20;
+	}
+
+	public List getMetadata() {
+		return this.receivedMetadata;
 	}
 }
--- net/minecraft/src/RenderItem.java
+++ net/minecraft/src/RenderItem.java
@@ -56,7 +56,7 @@
 					GL11.glTranslatef(var16, var17, var18);
 				}
 
-				this.itemRenderBlocks.renderBlockOnInventory(Block.blocksList[var10.itemID]);
+				this.itemRenderBlocks.renderBlockOnInventory(Block.blocksList[var10.itemID], var10.getItemDamageForDisplay());
 				GL11.glPopMatrix();
 			}
 		} else {
@@ -116,7 +116,7 @@
 				GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
 				GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
 				GL11.glScalef(1.0F, 1.0F, 1.0F);
-				this.itemRenderBlocks.renderBlockOnInventory(var7);
+				this.itemRenderBlocks.renderBlockOnInventory(var7, var3.getItemDamageForDisplay());
 				GL11.glPopMatrix();
 			} else if(var3.getIconIndex() >= 0) {
 				GL11.glDisable(GL11.GL_LIGHTING);
@@ -145,9 +145,9 @@
 				GL11.glEnable(GL11.GL_DEPTH_TEST);
 			}
 
-			if(var3.itemDmg > 0) {
-				int var11 = 13 - var3.itemDmg * 13 / var3.getMaxDamage();
-				int var7 = 255 - var3.itemDmg * 255 / var3.getMaxDamage();
+			if(var3.getItemDamage() > 0 && var3.isItemStackDamageable()) {
+				int var11 = 13 - var3.getItemDamage() * 13 / var3.getMaxDamage();
+				int var7 = 255 - var3.getItemDamage() * 255 / var3.getMaxDamage();
 				GL11.glDisable(GL11.GL_LIGHTING);
 				GL11.glDisable(GL11.GL_DEPTH_TEST);
 				GL11.glDisable(GL11.GL_TEXTURE_2D);
--- net/minecraft/src/EntityMinecart.java
+++ net/minecraft/src/EntityMinecart.java
@@ -19,6 +19,9 @@
 	private double minecartZ;
 	private double minecartYaw;
 	private double minecartPitch;
+	private double lerpVelocityX;
+	private double lerpVelocityY;
+	private double lerpVelocityZ;
 
 	public EntityMinecart(World var1) {
 		super(var1);
@@ -33,6 +36,9 @@
 		this.canTriggerWalking = false;
 	}
 
+	protected void entityInit() {
+	}
+
 	public AxisAlignedBB getCollisionBox(Entity var1) {
 		return var1.boundingBox;
 	}
@@ -62,6 +68,9 @@
 	}
 
 	public boolean attackEntityFrom(Entity var1, int var2) {
+		if (this.worldObj.multiplayerWorld || this.isDead)
+			return true;
+		
 		this.forwardDirection = -this.forwardDirection;
 		this.timeSinceHit = 10;
 		this.damageTaken += var2 * 10;
@@ -78,6 +87,12 @@
 
 		return true;
 	}
+	
+	public void performHurtAnimation() {
+		this.forwardDirection = -this.forwardDirection;
+		this.timeSinceHit = 10;
+		this.damageTaken += 10;
+	}
 
 	public boolean canBeCollidedWith() {
 		return !this.isDead;
@@ -98,12 +113,15 @@
 					}
 
 					var2.stackSize -= var6;
-					EntityItem var7 = new EntityItem(this.worldObj, this.posX + (double)var3, this.posY + (double)var4, this.posZ + (double)var5, new ItemStack(var2.itemID, var6, var2.itemDmg));
-					float var8 = 0.05F;
-					var7.motionX = (double)((float)this.rand.nextGaussian() * var8);
-					var7.motionY = (double)((float)this.rand.nextGaussian() * var8 + 0.2F);
-					var7.motionZ = (double)((float)this.rand.nextGaussian() * var8);
-					this.worldObj.spawnEntityInWorld(var7);
+					if (!this.worldObj.multiplayerWorld) {
+						EntityItem var7 = new EntityItem(this.worldObj, this.posX + (double)var3, this.posY + (double)var4, this.posZ + (double)var5, new ItemStack(var2.itemID, var6, var2.getItemDamage()));
+						float var8 = 0.05F;
+						var7.motionX = (double)((float)this.rand.nextGaussian() * var8);
+						var7.motionY = (double)((float)this.rand.nextGaussian() * var8 + 0.2F);
+						var7.motionZ = (double)((float)this.rand.nextGaussian() * var8);
+						this.worldObj.spawnEntityInWorld(var7);
+					}
+					
 				}
 			}
 		}
@@ -113,6 +131,14 @@
 
 	public void onUpdate() {
 		double var7;
+		if(this.timeSinceHit > 0) {
+			--this.timeSinceHit;
+		}
+
+		if(this.damageTaken > 0) {
+			--this.damageTaken;
+		}
+		
 		if(this.worldObj.multiplayerWorld) {
 			if(this.turnProgress > 0) {
 				double var41 = this.posX + (this.minecartX - this.posX) / (double)this.turnProgress;
@@ -137,13 +163,6 @@
 			}
 
 		} else {
-			if(this.timeSinceHit > 0) {
-				--this.timeSinceHit;
-			}
-
-			if(this.damageTaken > 0) {
-				--this.damageTaken;
-			}
 
 			this.prevPosX = this.posX;
 			this.prevPosY = this.posY;
@@ -536,6 +555,9 @@
 	}
 
 	public void applyEntityCollision(Entity var1) {
+		if (this.worldObj.multiplayerWorld)
+			return;
+		
 		if(var1 != this.riddenByEntity) {
 			if(var1 instanceof EntityLiving && !(var1 instanceof EntityPlayer) && this.minecartType == 0 && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01D && this.riddenByEntity == null && var1.ridingEntity == null) {
 				var1.mountEntity(this);
@@ -643,6 +665,9 @@
 	}
 
 	public boolean interact(EntityPlayer var1) {
+		if (this.worldObj.multiplayerWorld)
+			return true;
+		
 		if(this.minecartType == 0) {
 			var1.mountEntity(this);
 		} else if(this.minecartType == 1) {
@@ -664,12 +689,27 @@
 		return true;
 	}
 
+	@Override
 	public void setPositionAndRotation(double var1, double var3, double var5, float var7, float var8, int var9) {
 		this.minecartX = var1;
 		this.minecartY = var3;
 		this.minecartZ = var5;
 		this.minecartYaw = (double)var7;
 		this.minecartPitch = (double)var8;
-		this.turnProgress = var9;
+		this.turnProgress = var9 + 2; // TODO: +2?
+		this.motionX = this.lerpVelocityX;
+		this.motionY = this.lerpVelocityY;
+		this.motionZ = this.lerpVelocityZ;
+	}
+
+	@Override
+	public void setVelocity(double velocityX, double velocityY, double velocityZ) {
+		this.lerpVelocityX = this.motionX = velocityX;
+		this.lerpVelocityY = this.motionY = velocityY;
+		this.lerpVelocityZ = this.motionZ = velocityZ;
+	}
+	
+	public boolean canInteractWith(EntityPlayer var1) {
+		return this.isDead ? false : var1.getDistanceSqToEntity(this) <= 64.0D;
 	}
 }
--- net/minecraft/src/EntitySlimeFX.java
+++ net/minecraft/src/EntitySlimeFX.java
@@ -3,7 +3,7 @@
 public class EntitySlimeFX extends EntityFX {
 	public EntitySlimeFX(World var1, double var2, double var4, double var6, Item var8) {
 		super(var1, var2, var4, var6, 0.0D, 0.0D, 0.0D);
-		this.particleTextureIndex = var8.getIconIndex((ItemStack)null);
+		this.particleTextureIndex = var8.getSprite(0);
 		this.particleRed = this.particleGreen = this.particleBlue = 1.0F;
 		this.particleGravity = Block.blockSnow.blockParticleGravity;
 		this.particleScale /= 2.0F;
--- net/minecraft/src/EntityPainting.java
+++ net/minecraft/src/EntityPainting.java
@@ -6,9 +6,9 @@
 public class EntityPainting extends Entity {
 	private int tickCounter;
 	public int direction;
-	private int xPosition;
-	private int yPosition;
-	private int zPosition;
+	public int xPosition;
+	public int yPosition;
+	public int zPosition;
 	public EnumArt art;
 
 	public EntityPainting(World var1) {
@@ -43,6 +43,28 @@
 
 		this.setDirection(var5);
 	}
+	
+	public EntityPainting(World var1, int var2, int var3, int var4, int var5, String var6) {
+		this(var1);
+		this.xPosition = var2;
+		this.yPosition = var3;
+		this.zPosition = var4;
+		EnumArt[] var7 = EnumArt.values();
+		int var8 = var7.length;
+
+		for(int var9 = 0; var9 < var8; ++var9) {
+			EnumArt var10 = var7[var9];
+			if(var10.title.equals(var6)) {
+				this.art = var10;
+				break;
+			}
+		}
+
+		this.setDirection(var5);
+	}
+	
+	protected void entityInit() {
+	}
 
 	public void setDirection(int var1) {
 		this.direction = var1;
@@ -106,7 +128,7 @@
 	}
 
 	public void onUpdate() {
-		if(this.tickCounter++ == 100 && !this.onValidSurface()) {
+		if(this.tickCounter++ == 100 && !this.onValidSurface() && !this.worldObj.multiplayerWorld) {
 			this.tickCounter = 0;
 			this.setEntityDead();
 			this.worldObj.spawnEntityInWorld(new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, new ItemStack(Item.painting)));
@@ -174,6 +196,9 @@
 	}
 
 	public boolean attackEntityFrom(Entity var1, int var2) {
+		if (this.worldObj.multiplayerWorld)
+			return true;
+		
 		this.setEntityDead();
 		this.worldObj.spawnEntityInWorld(new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, new ItemStack(Item.painting)));
 		return true;
--- /dev/null
+++ net/minecraft/src/ContainerFurnace.java
@@ -1,0 +1,101 @@
+package net.minecraft.src;
+
+public class ContainerFurnace extends Container {
+	private TileEntityFurnace furnace;
+	private int cookTime = 0;
+	private int burnTime = 0;
+	private int itemBurnTime = 0;
+
+	public ContainerFurnace(InventoryPlayer var1, TileEntityFurnace var2) {
+		this.furnace = var2;
+		this.addSlot(new Slot(var2, 0, 56, 17));
+		this.addSlot(new Slot(var2, 1, 56, 53));
+		this.addSlot(new SlotFurnace(var1.player, var2, 2, 116, 35));
+
+		int var3;
+		for(var3 = 0; var3 < 3; ++var3) {
+			for(int var4 = 0; var4 < 9; ++var4) {
+				this.addSlot(new Slot(var1, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18));
+			}
+		}
+
+		for(var3 = 0; var3 < 9; ++var3) {
+			this.addSlot(new Slot(var1, var3, 8 + var3 * 18, 142));
+		}
+
+	}
+
+	public void updateCraftingResults() {
+		super.updateCraftingResults();
+
+		for(int var1 = 0; var1 < this.field_20121_g.size(); ++var1) {
+			ICrafting var2 = (ICrafting)this.field_20121_g.get(var1);
+			if(this.cookTime != this.furnace.furnaceCookTime) {
+				var2.func_20158_a(this, 0, this.furnace.furnaceCookTime);
+			}
+
+			if(this.burnTime != this.furnace.furnaceBurnTime) {
+				var2.func_20158_a(this, 1, this.furnace.furnaceBurnTime);
+			}
+
+			if(this.itemBurnTime != this.furnace.currentItemBurnTime) {
+				var2.func_20158_a(this, 2, this.furnace.currentItemBurnTime);
+			}
+		}
+
+		this.cookTime = this.furnace.furnaceCookTime;
+		this.burnTime = this.furnace.furnaceBurnTime;
+		this.itemBurnTime = this.furnace.currentItemBurnTime;
+	}
+
+	public void func_20112_a(int var1, int var2) {
+		if(var1 == 0) {
+			this.furnace.furnaceCookTime = var2;
+		}
+
+		if(var1 == 1) {
+			this.furnace.furnaceBurnTime = var2;
+		}
+
+		if(var1 == 2) {
+			this.furnace.currentItemBurnTime = var2;
+		}
+
+	}
+
+	public boolean isUsableByPlayer(EntityPlayer var1) {
+		return this.furnace.canInteractWith(var1);
+	}
+
+	public ItemStack getStackInSlot(int var1) {
+		ItemStack var2 = null;
+		Slot var3 = (Slot)this.slots.get(var1);
+		if(var3 != null && var3.getHasStack()) {
+			ItemStack var4 = var3.getStack();
+			var2 = var4.copy();
+			if(var1 == 2) {
+				this.func_28125_a(var4, 3, 39, true);
+			} else if(var1 >= 3 && var1 < 30) {
+				this.func_28125_a(var4, 30, 39, false);
+			} else if(var1 >= 30 && var1 < 39) {
+				this.func_28125_a(var4, 3, 30, false);
+			} else {
+				this.func_28125_a(var4, 3, 39, false);
+			}
+
+			if(var4.stackSize == 0) {
+				var3.putStack((ItemStack)null);
+			} else {
+				var3.onSlotChanged();
+			}
+
+			if(var4.stackSize == var2.stackSize) {
+				return null;
+			}
+
+			var3.onPickupFromSlot(var4);
+		}
+
+		return var2;
+	}
+}
--- /dev/null
+++ net/minecraft/src/Packet19EntityAction.java
@@ -1,0 +1,36 @@
+package net.minecraft.src;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class Packet19EntityAction extends Packet {
+	public int entityId;
+	public int state;
+
+	public Packet19EntityAction() {
+	}
+
+	public Packet19EntityAction(Entity var1, int var2) {
+		this.entityId = var1.entityID;
+		this.state = var2;
+	}
+
+	public void readPacketData(DataInputStream var1) throws IOException {
+		this.entityId = var1.readInt();
+		this.state = var1.readByte();
+	}
+
+	public void writePacketData(DataOutputStream var1) throws IOException {
+		var1.writeInt(this.entityId);
+		var1.writeByte(this.state);
+	}
+
+	public void processPacket(NetHandler var1) {
+		var1.func_21147_a(this);
+	}
+
+	public int getPacketSize() {
+		return 5;
+	}
+}
--- net/minecraft/src/GameSettings.java
+++ net/minecraft/src/GameSettings.java
@@ -36,6 +36,8 @@
 	public int numberOfOptions = 10;
 	public int difficulty = 2;
 	public boolean thirdPersonView = false;
+	
+	public boolean accept62 = true;
 
 	public GameSettings(Minecraft var1, File var2) {
 		this.mc = var1;
--- net/minecraft/src/BlockCrops.java
+++ net/minecraft/src/BlockCrops.java
@@ -100,7 +100,6 @@
 	}
 
 	public int idDropped(int var1, Random var2) {
-		System.out.println("Get resource: " + var1);
 		return var1 == 7 ? Item.wheat.shiftedIndex : -1;
 	}
 
--- net/minecraft/src/Packet23VehicleSpawn.java
+++ net/minecraft/src/Packet23VehicleSpawn.java
@@ -9,7 +9,11 @@
 	public int xPosition;
 	public int yPosition;
 	public int zPosition;
+	public int field_28047_e;
+	public int field_28046_f;
+	public int field_28045_g;
 	public int type;
+	public int field_28044_i;
 
 	public void readPacketData(DataInputStream var1) throws IOException {
 		this.entityId = var1.readInt();
@@ -17,14 +21,28 @@
 		this.xPosition = var1.readInt();
 		this.yPosition = var1.readInt();
 		this.zPosition = var1.readInt();
+		this.field_28044_i = var1.readInt();
+		if(this.field_28044_i > 0) {
+			this.field_28047_e = var1.readShort();
+			this.field_28046_f = var1.readShort();
+			this.field_28045_g = var1.readShort();
+		}
+
 	}
 
-	public void writePacket(DataOutputStream var1) throws IOException {
+	public void writePacketData(DataOutputStream var1) throws IOException {
 		var1.writeInt(this.entityId);
 		var1.writeByte(this.type);
 		var1.writeInt(this.xPosition);
 		var1.writeInt(this.yPosition);
 		var1.writeInt(this.zPosition);
+		var1.writeInt(this.field_28044_i);
+		if(this.field_28044_i > 0) {
+			var1.writeShort(this.field_28047_e);
+			var1.writeShort(this.field_28046_f);
+			var1.writeShort(this.field_28045_g);
+		}
+
 	}
 
 	public void processPacket(NetHandler var1) {
@@ -32,6 +50,6 @@
 	}
 
 	public int getPacketSize() {
-		return 17;
+		return 21 + this.field_28044_i > 0 ? 6 : 0;
 	}
 }
--- net/minecraft/src/ChunkCoordinates.java
+++ net/minecraft/src/ChunkCoordinates.java
@@ -1,12 +1,23 @@
 package net.minecraft.src;
 
-final class ChunkCoordinates {
-	public final int posX;
-	public final int posZ;
-
-	public ChunkCoordinates(int var1, int var2) {
-		this.posX = var1;
-		this.posZ = var2;
+public class ChunkCoordinates implements Comparable {
+	public int x;
+	public int y;
+	public int z;
+
+	public ChunkCoordinates() {
+	}
+
+	public ChunkCoordinates(int var1, int var2, int var3) {
+		this.x = var1;
+		this.y = var2;
+		this.z = var3;
+	}
+
+	public ChunkCoordinates(ChunkCoordinates var1) {
+		this.x = var1.x;
+		this.y = var1.y;
+		this.z = var1.z;
 	}
 
 	public boolean equals(Object var1) {
@@ -14,11 +25,26 @@
 			return false;
 		} else {
 			ChunkCoordinates var2 = (ChunkCoordinates)var1;
-			return this.posX == var2.posX && this.posZ == var2.posZ;
+			return this.x == var2.x && this.y == var2.y && this.z == var2.z;
 		}
 	}
 
 	public int hashCode() {
-		return this.posX << 16 ^ this.posZ;
+		return this.x + this.z << 8 + this.y << 16;
+	}
+
+	public int compareChunkCoordinate(ChunkCoordinates var1) {
+		return this.y == var1.y ? (this.z == var1.z ? this.x - var1.x : this.z - var1.z) : this.y - var1.y;
+	}
+
+	public double getSqDistanceTo(int var1, int var2, int var3) {
+		int var4 = this.x - var1;
+		int var5 = this.y - var2;
+		int var6 = this.z - var3;
+		return Math.sqrt((double)(var4 * var4 + var5 * var5 + var6 * var6));
+	}
+
+	public int compareTo(Object var1) {
+		return this.compareChunkCoordinate((ChunkCoordinates)var1);
 	}
 }
