diff --git a/src/common/resources/lang/en_US/options.lang b/src/common/resources/lang/en_US/options.lang
index 416cee6b3..32adcf2ad 100644
--- a/src/common/resources/lang/en_US/options.lang
+++ b/src/common/resources/lang/en_US/options.lang
@@ -220,3 +220,4 @@ key.toggleDebug=Toggle Debug
 key.toggleOverlay=Toggle Overlays
 key.sortInventory=Sort Inventory
 key.disabled=Disabled
+key.debug.textureAtlas=Show Texture Atlas
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java
index 899b5b561..612652f03 100644
--- a/src/main/java/net/minecraft/client/Minecraft.java
+++ b/src/main/java/net/minecraft/client/Minecraft.java
@@ -1,6 +1,20 @@
 package net.minecraft.client;
 
+import static net.minecraft.core.Global.*;
+import static org.lwjgl.opengl.GL11.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Random;
+
+import org.lwjgl.LWJGLException;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.Display;
+
 import com.mojang.nbt.CompoundTag;
+
 import net.minecraft.client.achievement.stat.StatStringFormatKeyInv;
 import net.minecraft.client.discord.RichPresenceHandlerThread;
 import net.minecraft.client.entity.ClientSkinVariantList;
@@ -30,6 +44,7 @@ import net.minecraft.client.gui.GuiSleepSP;
 import net.minecraft.client.gui.MainMenuBackground;
 import net.minecraft.client.gui.modelviewer.GuiModelViewer;
 import net.minecraft.client.gui.popup.GuiPopup;
+import net.minecraft.client.input.InputDevice;
 import net.minecraft.client.input.InputHandler;
 import net.minecraft.client.input.InputType;
 import net.minecraft.client.input.MouseInput;
@@ -41,7 +56,6 @@ import net.minecraft.client.net.thread.ThreadCheckHasPaid;
 import net.minecraft.client.net.thread.ThreadDownloadResources;
 import net.minecraft.client.net.thread.ThreadSleepForeverClient;
 import net.minecraft.client.option.GameSettings;
-import net.minecraft.client.option.InputDevice;
 import net.minecraft.client.option.KeyBinding;
 import net.minecraft.client.option.enums.LightmapStyle;
 import net.minecraft.client.player.controller.PlayerController;
@@ -130,35 +144,6 @@ import net.minecraft.core.world.save.LevelStorage;
 import net.minecraft.core.world.save.SaveConverters;
 import net.minecraft.core.world.save.SaveFormats;
 import net.minecraft.core.world.save.mcregion.SaveFormat19134;
-import org.lwjgl.LWJGLException;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.input.Mouse;
-import org.lwjgl.opengl.Display;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Random;
-
-import static net.minecraft.core.Global.CURRENT_SAVE_VERSION;
-import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
-import static org.lwjgl.opengl.GL11.glAlphaFunc;
-import static org.lwjgl.opengl.GL11.glBindTexture;
-import static org.lwjgl.opengl.GL11.glClear;
-import static org.lwjgl.opengl.GL11.glClearColor;
-import static org.lwjgl.opengl.GL11.glClearDepth;
-import static org.lwjgl.opengl.GL11.glColor4f;
-import static org.lwjgl.opengl.GL11.glCullFace;
-import static org.lwjgl.opengl.GL11.glDepthFunc;
-import static org.lwjgl.opengl.GL11.glDisable;
-import static org.lwjgl.opengl.GL11.glEnable;
-import static org.lwjgl.opengl.GL11.glLoadIdentity;
-import static org.lwjgl.opengl.GL11.glMatrixMode;
-import static org.lwjgl.opengl.GL11.glOrtho;
-import static org.lwjgl.opengl.GL11.glShadeModel;
-import static org.lwjgl.opengl.GL11.glTranslatef;
-import static org.lwjgl.opengl.GL11.glViewport;
 
 // Referenced classes of package net.minecraft.client:
 //            MinecraftApplet
@@ -1114,7 +1099,9 @@ public class Minecraft
             }
             if(clickType == 1)
             {
-                playerController.interact(thePlayer, objectMouseOver.entity);
+                if (playerController.interact(thePlayer, objectMouseOver.entity)){
+                    flag = false;
+                }
             }
         }
         else if(objectMouseOver.hitType == HitResult.HitType.TILE)
@@ -1207,8 +1194,10 @@ public class Minecraft
         {
             startCheckPaidThread();
         }
+        Debug.push("gui");
         statsCounter.func_27178_d();
         ingameGUI.updateTick();
+        Debug.change("misc");
         worldRenderer.getMouseOver(1.0F);
         if(thePlayer != null)
         {
@@ -1225,11 +1214,13 @@ public class Minecraft
         {
             playerController.tick();
         }
+        Debug.change("textureTick");
         TextureRegistry.blockAtlas.bindTexture();
         if(!isGamePaused)
         {
             renderEngine.updateDynamicTextures();
         }
+        Debug.change("misc");
         if(currentScreen == null && thePlayer != null)
         {
             if(thePlayer.getHealth() <= 0)
@@ -1253,6 +1244,7 @@ public class Minecraft
         {
             displayGuiScreen(null);
         }
+        Debug.change("input");
         if(currentScreen != null)
         {
             mouseTicksRan = ticksRan + 10000;
@@ -1309,7 +1301,7 @@ public class Minecraft
                     }
                     else
                     {
-                        if (checkBoundInputs(InputDevice.MOUSE)) {
+                        if (checkBoundInputs(InputDevice.mouse)) {
                             if (!Mouse.isGrabbed() && inputType == InputType.KEYBOARD && currentScreen == null) {
                                 mouseInput.grabCursor();
                             }
@@ -1338,10 +1330,10 @@ public class Minecraft
                 	thePlayer.input.keyEvent(Keyboard.getEventKey(), Keyboard.getEventKeyState());
                 }
                 
-                if(gameSettings.keyToggleDebug.isPressEvent(InputDevice.KEYBOARD)) {
+                if(gameSettings.keyToggleDebug.isPressEvent(InputDevice.keyboard)) {
                     f3Press = true;
                 }
-                if (gameSettings.keyToggleDebug.isReleaseEvent(InputDevice.KEYBOARD))
+                if (gameSettings.keyToggleDebug.isReleaseEvent(InputDevice.keyboard))
                 {
                     if(f3Press)
                     {
@@ -1479,7 +1471,7 @@ public class Minecraft
                                 gameSettings.ambientOcclusion.onUpdate();
                                 ingameGUI.guiHeldItemTooltip.setOptionNameAndValueString(gameSettings.ambientOcclusion);
                             }
-                            if(!gameSettings.keyToggleDebug.isPressEvent(InputDevice.KEYBOARD)) f3Press = false;
+                            if(!gameSettings.keyToggleDebug.isPressEvent(InputDevice.keyboard)) f3Press = false;
                         }
                         else if (Keyboard.getEventKey() == Keyboard.KEY_F12)
                         {
@@ -1498,11 +1490,11 @@ public class Minecraft
                         }
                         else
                         {
-                            checkBoundInputs(InputDevice.KEYBOARD);
+                            checkBoundInputs(InputDevice.keyboard);
                         }
                     }
                 }else {
-                	checkBoundInputs(InputDevice.KEYBOARD);
+                	checkBoundInputs(InputDevice.keyboard);
                 }
             }
 
@@ -1520,6 +1512,7 @@ public class Minecraft
         {
             handleControllerInput();
         }
+        Debug.change("misc");
         if(theWorld != null)
         {
             if(thePlayer != null)
@@ -1549,27 +1542,36 @@ public class Minecraft
             }
             if(!isGamePaused)
             {
+                Debug.change("entity");
                 if(theWorld.lightningFlicker > 0)
                 {
                     theWorld.lightningFlicker--;
                 }
                 theWorld.updateEntities();
+                Debug.change("misc");
             }
             if(!isGamePaused || isMultiplayerWorld())
             {
+                Debug.change("world");
                 theWorld.setAllowedMobSpawns(gameSettings.difficulty.value.canMobsSpawn(), true);
                 theWorld.tick();
+                Debug.change("misc");
             }
             if(!isGamePaused && theWorld != null)
             {
+                Debug.change("randomDisplayTick");
                 theWorld.randomDisplayUpdates(MathHelper.floor_double(thePlayer.x), MathHelper.floor_double(thePlayer.y), MathHelper.floor_double(thePlayer.z));
+                Debug.change("misc");
             }
             if(!isGamePaused)
             {
+                Debug.change("effects");
                 effectRenderer.updateEffects();
+                Debug.change("misc");
             }
         }
         systemTime = System.currentTimeMillis();
+        Debug.pop();
     }
 
     private boolean checkBoundInputs(InputDevice currentInputDevice) {
diff --git a/src/main/java/net/minecraft/client/entity/fx/EntityDiggingFX.java b/src/main/java/net/minecraft/client/entity/fx/EntityDiggingFX.java
index d6fb40119..076052cfb 100644
--- a/src/main/java/net/minecraft/client/entity/fx/EntityDiggingFX.java
+++ b/src/main/java/net/minecraft/client/entity/fx/EntityDiggingFX.java
@@ -14,14 +14,14 @@ import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
 
 public class EntityDiggingFX extends EntityFX
-{    public EntityDiggingFX(World world, double d, double d1, double d2,
-                           double d3, double d4, double d5, Block block,
-                           int i, int meta)
+{    public EntityDiggingFX(World world, double x, double y, double z,
+                           double motionX, double motionY, double motionZ, Block block,
+                           int side, int meta)
     {
-        super(world, d, d1, d2, d3, d4, d5);
-        this.side = Side.getSideById(i);
+        super(world, x, y, z, motionX, motionY, motionZ);
+        this.side = Side.getSideById(side);
         this.block = block;
-        particleTexture = BlockModelDispatcher.getInstance().getDispatch(block).getParticleTexture(side, meta);
+        particleTexture = BlockModelDispatcher.getInstance().getDispatch(block).getParticleTexture(this.side, meta);
         this.particleGravity = block != null ? block.blockParticleGravity : 0;
         this.particleRed = particleGreen = particleBlue = 0.6F;
         this.particleScale /= 2.0F;
diff --git a/src/main/java/net/minecraft/client/entity/fx/EntityReddustFX.java b/src/main/java/net/minecraft/client/entity/fx/EntityReddustFX.java
index b8b7026a5..f020e8094 100644
--- a/src/main/java/net/minecraft/client/entity/fx/EntityReddustFX.java
+++ b/src/main/java/net/minecraft/client/entity/fx/EntityReddustFX.java
@@ -1,21 +1,30 @@
 package net.minecraft.client.entity.fx;
 
 
+import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
+import net.minecraft.core.enums.LightLayer;
+import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
 
 public class EntityReddustFX extends EntityFX
 {
+    float originalScale;
+    private int brightness;
 
-    public EntityReddustFX(World world, double x, double y, double z, float red, float green, float blue)
+    public EntityReddustFX(World world, double x, double y, double z, float red, float green, float blue, int brightness)
     {
-        this(world, x, y, z, 1.0F, red, green, blue);
+        this(world, x, y, z, 1.0F, red, green, blue, brightness);
     }
 
-    public EntityReddustFX(World world, double x, double y, double z, float scale, float red, float green, float blue)
+    public EntityReddustFX(World world, double x, double y, double z, float scale, float red, float green, float blue, int brightness)
     {
         super(world, x, y, z, 0.0D, 0.0D, 0.0D);
+        this.brightness = -1;
+        if (brightness >= 0){
+            this.brightness = brightness;
+        }
         xd *= 0.1D;
         yd *= 0.1D;
         zd *= 0.1D;
@@ -25,7 +34,7 @@ public class EntityReddustFX extends EntityFX
         this.particleBlue = ((float)(Math.random() * 0.2D) + 0.8F) * blue * f4;
         particleScale *= 0.75F;
         particleScale *= scale;
-        field_673_a = particleScale;
+        this.originalScale = particleScale;
         particleMaxAge = (int)(8D / (Math.random() * 0.8D + 0.2D));
         particleMaxAge *= scale;
         noPhysics = false;
@@ -43,8 +52,40 @@ public class EntityReddustFX extends EntityFX
         {
             f6 = 1.0F;
         }
-        particleScale = field_673_a * f6;
-        super.renderParticle(t, partialTick, rotationX, rotationXZ, rotationZ, rotationYZ, rotationXY);
+        particleScale = originalScale * f6;
+        if (particleTexture == null) return;
+
+        float texMinU = (float) particleTexture.getIconUMin();
+        float texMaxU = (float) particleTexture.getSubIconU(1);
+        float texMinV = (float) particleTexture.getIconVMin();
+        float texMaxV = (float) particleTexture.getSubIconV(1);
+        float scale = 0.1F * particleScale;
+        float posX = (float)((xo + (this.x - xo) * (double)partialTick) - lerpPosX);
+        float posY = (float)((yo + (this.y - yo) * (double)partialTick) - lerpPosY);
+        float posZ = (float)((zo + (this.z - zo) * (double)partialTick) - lerpPosZ);
+        float brightness = 1f;
+        if(LightmapHelper.isLightmapEnabled()) {
+            int blockX = MathHelper.floor_double(x);
+            int blockY = MathHelper.floor_double(y);
+            int blockZ = MathHelper.floor_double(z);
+            int lmc;
+            if (this.brightness >= 0){
+                lmc =
+                    LightmapHelper.getLightmapCoord(
+                        world.getSavedLightValue(LightLayer.Sky, blockX, blockY, blockZ),
+                        Math.max(world.getSavedLightValue(LightLayer.Block, blockX, blockY, blockZ), this.brightness));
+            } else {
+                lmc = getLightmapCoord(partialTick);
+            }
+            t.setLightmapCoord(lmc);
+        }else {
+            brightness = Math.max(getBrightness(partialTick), this.brightness/15f);
+        }
+        t.setColorOpaque_F(particleRed * brightness, particleGreen * brightness, particleBlue * brightness);
+        t.addVertexWithUV(posX - rotationX * scale - rotationYZ * scale, posY - rotationXZ * scale, posZ - rotationZ * scale - rotationXY * scale, texMaxU, texMaxV);
+        t.addVertexWithUV((posX - rotationX * scale) + rotationYZ * scale, posY + rotationXZ * scale, (posZ - rotationZ * scale) + rotationXY * scale, texMaxU, texMinV);
+        t.addVertexWithUV(posX + rotationX * scale + rotationYZ * scale, posY + rotationXZ * scale, posZ + rotationZ * scale + rotationXY * scale, texMinU, texMinV);
+        t.addVertexWithUV((posX + rotationX * scale) - rotationYZ * scale, posY - rotationXZ * scale, (posZ + rotationZ * scale) - rotationXY * scale, texMinU, texMaxV);
     }
 
     @Override
@@ -78,6 +119,4 @@ public class EntityReddustFX extends EntityFX
             zd *= 0.7D;
         }
     }
-
-    float field_673_a;
 }
diff --git a/src/main/java/net/minecraft/client/entity/fx/ParticleDispatcher.java b/src/main/java/net/minecraft/client/entity/fx/ParticleDispatcher.java
index 4eae7cab1..847ef2194 100644
--- a/src/main/java/net/minecraft/client/entity/fx/ParticleDispatcher.java
+++ b/src/main/java/net/minecraft/client/entity/fx/ParticleDispatcher.java
@@ -39,7 +39,7 @@ public class ParticleDispatcher extends Dispatcher<String, ParticleLambda> {
         addDispatch("footstep", (world, x, y, z, motionX, motionY, motionZ, data) -> new EntityFootStepFX(mc.renderEngine, world, x, y, z));
         addDispatch("splash", (world1, d, d1, d2, d3, d4, d5, data) -> new EntitySplashFX(world1, d, d1, d2, d3, d4, d5));
         addDispatch("largesmoke", (world, x, y, z, motionX, motionY, motionZ, data) -> new EntitySmokeFX(world, x, y, z, motionX, motionY, motionX, 2.5f));
-        addDispatch("reddust", (world, x, y, z, motionX, motionY, motionZ, data) -> new EntityReddustFX(world, x, y, z, (float) motionX, (float) motionY, (float) motionZ));
+        addDispatch("reddust", (world, x, y, z, motionX, motionY, motionZ, data) -> new EntityReddustFX(world, x, y, z, (float) motionX, (float) motionY, (float) motionZ, data));
         addDispatch("item", (world, x, y, z, motionX, motionY, motionZ, data) -> new EntityItemFX(world, x, y, z, Item.itemsList[MathHelper.clamp(data, 0, Item.itemsList.length - 1)]));
         addDispatch("block", (world, x, y, z, motionX, motionY, motionZ, data) -> new EntityDiggingFX(world, x, y, z,motionX,motionY,motionZ, Block.blocksList[BlockParticleHelper.decodeBlockID(data)], BlockParticleHelper.decodeBlockSide(data), BlockParticleHelper.decodeBlockMeta(data)).setParticleColor((int) x, (int) y, (int) z));
         addDispatch("snowshovel", (world, x, y, z, motionX, motionY, motionZ, data) -> new EntitySnowShovelFX(world, x, y, z, motionX, motionY, motionX));
diff --git a/src/main/java/net/minecraft/client/entity/player/EntityOtherPlayerMP.java b/src/main/java/net/minecraft/client/entity/player/EntityOtherPlayerMP.java
index 6eb59bb5e..554049899 100644
--- a/src/main/java/net/minecraft/client/entity/player/EntityOtherPlayerMP.java
+++ b/src/main/java/net/minecraft/client/entity/player/EntityOtherPlayerMP.java
@@ -80,7 +80,7 @@ public class EntityOtherPlayerMP extends EntityPlayer
     }
     
     @Override
-	public void onDeath(Entity entity)
+	public void onDeath(Entity entityKilledBy)
     {
     }
 
diff --git a/src/main/java/net/minecraft/client/gui/GuiHeldItemTooltip.java b/src/main/java/net/minecraft/client/gui/GuiHeldItemTooltip.java
index 5d7a1e82a..4d4b2fbc7 100644
--- a/src/main/java/net/minecraft/client/gui/GuiHeldItemTooltip.java
+++ b/src/main/java/net/minecraft/client/gui/GuiHeldItemTooltip.java
@@ -28,7 +28,7 @@ public class GuiHeldItemTooltip extends Gui {
 		this.mc = mc;
 	}
 	
-	public void updateAndRender(Minecraft mc, int width, int height, int sp) {
+	public void updateAndRender(Minecraft mc, int width, int height, int screenPadding) {
 		if(mc.gameSettings.heldItemTooltips.value) {
 			ItemStack item = mc.thePlayer.getCurrentEquippedItem();
 			
@@ -45,7 +45,26 @@ public class GuiHeldItemTooltip extends Gui {
 			}
 		}
 		
-		render(mc, width, height, sp);
+		render(mc, width, height, screenPadding);
+	}
+	public void updateAndRender(Minecraft mc, int x, int y) {
+		if(mc.gameSettings.heldItemTooltips.value) {
+			ItemStack item = mc.thePlayer.getCurrentEquippedItem();
+
+			int id = getItemID(item);
+			int i = mc.thePlayer.inventory.currentItem;
+
+			if(id != lastItemID || i != lastSelectedItem) {
+				updateString(item);
+
+				time = displayTime;
+
+				lastItemID = id;
+				lastSelectedItem = i;
+			}
+		}
+
+		render(mc, x, y);
 	}
 	
 	private void updateString(ItemStack item) {
@@ -73,14 +92,17 @@ public class GuiHeldItemTooltip extends Gui {
 		this.time = displayTime;
 	}
 	
-	public void render(Minecraft mc, int width, int height, int sp) {
+	public void render(Minecraft mc, int width, int height, int screenPadding) {
+		render(mc, width/2, height - 50 - screenPadding);
+	}
+	public void render(Minecraft mc, int x, int y){
 		if(string == null) return;
 		if(time < 0.0) {
 			return;
 		}
-		
+
 		double alpha;
-		
+
 		if (time < fadeTime) {
 			alpha = time / fadeTime;
 		} else {
@@ -90,21 +112,21 @@ public class GuiHeldItemTooltip extends Gui {
 		if(!mc.isGamePaused) {
 			time -= Time.delta;
 		}
-		
+
 		int a = (int) (alpha * 255);
 		if(a < 1) {
 			return;
 		}
-		
+
 		int rgb = (color & 0x00FFFFFF) | (a << 24);
-		
+
 		if(a < 255) {
 			glEnable(GL_BLEND);
 			glDisable(GL_ALPHA_TEST);
-	        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 		}
-		
-		mc.fontRenderer.drawStringWithShadow(string, (width - mc.fontRenderer.getStringWidth(string)) / 2, height - 50 - sp, rgb);
+
+		mc.fontRenderer.drawStringWithShadow(string, x - (mc.fontRenderer.getStringWidth(string)) / 2, y, rgb);
 
 		glDisable(GL_BLEND);
 		glEnable(GL_ALPHA_TEST);
diff --git a/src/main/java/net/minecraft/client/gui/GuiIngame.java b/src/main/java/net/minecraft/client/gui/GuiIngame.java
index ab4d71d30..0d77bae83 100644
--- a/src/main/java/net/minecraft/client/gui/GuiIngame.java
+++ b/src/main/java/net/minecraft/client/gui/GuiIngame.java
@@ -9,7 +9,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.lwjgl.input.Keyboard;
 import org.lwjgl.opengl.GL11;
 
 import net.minecraft.client.Minecraft;
@@ -527,18 +526,13 @@ public class GuiIngame extends Gui
 
         }
 
-        if (mc.gameSettings.immersiveMode.drawHotbar())
-        {
-            guiHeldItemTooltip.updateAndRender(mc, width, height, sp);
-        }
-        
         if (mc.gameSettings.immersiveMode.drawChat())
         {
         	drawChat(width, height, sp);
         }
-
+        
         // Adding this mostly to see if the stitcher and dynamic textures are working properly
-        if (Keyboard.isKeyDown(Keyboard.KEY_F6) && mc.theWorld.getLevelData().getCheatsEnabled()){
+        if (mc.gameSettings.keyToggleTextureAtlas.isPressed()) {
             Tessellator tessellator = Tessellator.instance;
 
             TextureRegistry.blockAtlas.bindTexture();
diff --git a/src/main/java/net/minecraft/client/gui/hud/HotbarComponent.java b/src/main/java/net/minecraft/client/gui/hud/HotbarComponent.java
index 80e3509f4..96d56e2af 100644
--- a/src/main/java/net/minecraft/client/gui/hud/HotbarComponent.java
+++ b/src/main/java/net/minecraft/client/gui/hud/HotbarComponent.java
@@ -2,6 +2,7 @@ package net.minecraft.client.gui.hud;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.GuiHeldItemTooltip;
 import net.minecraft.client.gui.GuiIngame;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.Scissor;
@@ -123,6 +124,8 @@ public class HotbarComponent
 
         // Render selector
         gui.drawTexturedModalRect((x + 4) + (inv.currentItem % 9) * 20, y - 1, 0, 22, 24, 24);
+
+        gui.guiHeldItemTooltip.updateAndRender(mc, x + 187/2, y - 20);
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/gui/modelviewer/categories/entries/particle/RedDustFXEntry.java b/src/main/java/net/minecraft/client/gui/modelviewer/categories/entries/particle/RedDustFXEntry.java
index 896e066a2..e6f3b2790 100644
--- a/src/main/java/net/minecraft/client/gui/modelviewer/categories/entries/particle/RedDustFXEntry.java
+++ b/src/main/java/net/minecraft/client/gui/modelviewer/categories/entries/particle/RedDustFXEntry.java
@@ -71,7 +71,7 @@ public class RedDustFXEntry extends ParticleEntry{
 
     @Override
     public void spawnParticle(Minecraft mc, World world, double x, double y, double z) {
-        mc.effectRenderer.addEffect(new EntityReddustFX(world, x, y, z, red/255f, green/255f, blue/255f));
+        mc.effectRenderer.addEffect(new EntityReddustFX(world, x, y, z, red/255f, green/255f, blue/255f, 15));
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/gui/options/GuiOptions.java b/src/main/java/net/minecraft/client/gui/options/GuiOptions.java
index 787a0ef13..fb530fc7c 100644
--- a/src/main/java/net/minecraft/client/gui/options/GuiOptions.java
+++ b/src/main/java/net/minecraft/client/gui/options/GuiOptions.java
@@ -7,6 +7,7 @@ import net.minecraft.client.gui.options.components.KeyBindingComponent;
 import net.minecraft.client.gui.options.components.OptionsComponent;
 import net.minecraft.client.gui.options.data.OptionsPage;
 import net.minecraft.client.gui.options.data.OptionsPages;
+import net.minecraft.client.input.InputDevice;
 import net.minecraft.client.gui.options.data.OptionsPageRegistry;
 import net.minecraft.client.option.KeyBinding;
 import net.minecraft.client.render.Scissor;
@@ -84,7 +85,7 @@ public class GuiOptions
                 pickingKeyBindingComponent = null;
                 return;
             }
-            pickingKeyBinding.bindKeyboard(key);
+            pickingKeyBinding.bind(InputDevice.keyboard, key);
             pickingKeyBindingComponent.update();
             pickingKeyBinding = null;
             pickingKeyBindingComponent = null;
@@ -393,7 +394,7 @@ public class GuiOptions
     public void mouseClicked(int mouseX, int mouseY, int mouseButton)
     {
         if (pickingKeyBinding != null && pickingKeyBindingComponent != null) {
-            pickingKeyBinding.bindMouse(mouseButton);
+            pickingKeyBinding.bind(InputDevice.mouse, mouseButton);
             pickingKeyBindingComponent.update();
             pickingKeyBinding = null;
             pickingKeyBindingComponent = null;
diff --git a/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java b/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
index 60ed1402d..bcab897a5 100644
--- a/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
+++ b/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
@@ -216,6 +216,7 @@ public abstract class OptionsPages
         .withComponent(new SearchFieldComponent())
     );
     public static final OptionsPage DEBUG = new OptionsPage("gui.options.page.debug.title", Block.bedrock.getDefaultStack())
+    		.withComponent(new KeyBindingComponent(mc.gameSettings.keyToggleTextureAtlas))
             .withComponent(new ShortcutComponent("gui.options.page.debug.button.open.model_viewer", () -> {
                 mc.playerController = new PlayerControllerSP(mc);
                 mc.changeWorld(new World(), "Loading Model Viewer");
diff --git a/src/main/java/net/minecraft/client/input/InputDevice.java b/src/main/java/net/minecraft/client/input/InputDevice.java
new file mode 100644
index 000000000..9a1324a08
--- /dev/null
+++ b/src/main/java/net/minecraft/client/input/InputDevice.java
@@ -0,0 +1,18 @@
+package net.minecraft.client.input;
+
+public abstract class InputDevice {
+	
+	public static InputDevice mouse = new InputDeviceMouse();
+	public static InputDevice keyboard = new InputDeviceKeyboard();
+	
+	public abstract boolean isPressed(int keyCode);
+	
+	public abstract boolean isPressEvent(int keyCode);
+	
+	public abstract boolean isReleaseEvent(int keyCode);
+	
+	public abstract boolean isKeyCodeValid(int keyCode);
+	
+	public abstract String getKeyName(int keyCode);
+	
+}
diff --git a/src/main/java/net/minecraft/client/input/InputDeviceKeyboard.java b/src/main/java/net/minecraft/client/input/InputDeviceKeyboard.java
new file mode 100644
index 000000000..7b64cee80
--- /dev/null
+++ b/src/main/java/net/minecraft/client/input/InputDeviceKeyboard.java
@@ -0,0 +1,32 @@
+package net.minecraft.client.input;
+
+import org.lwjgl.input.Keyboard;
+
+public class InputDeviceKeyboard extends InputDevice {
+
+	@Override
+	public boolean isPressed(int keyCode) {
+		return Keyboard.isKeyDown(keyCode);
+	}
+
+	@Override
+	public boolean isPressEvent(int keyCode) {
+		return Keyboard.getEventKey() == keyCode && Keyboard.getEventKeyState();
+	}
+
+	@Override
+	public boolean isReleaseEvent(int keyCode) {
+		return Keyboard.getEventKey() == keyCode && !Keyboard.getEventKeyState();
+	}
+
+	@Override
+	public boolean isKeyCodeValid(int keyCode) {
+		return keyCode > 0;
+	}
+
+	@Override
+	public String getKeyName(int keyCode) {
+		return Keyboard.getKeyName(keyCode);
+	}
+
+}
diff --git a/src/main/java/net/minecraft/client/input/InputDeviceMouse.java b/src/main/java/net/minecraft/client/input/InputDeviceMouse.java
new file mode 100644
index 000000000..8a4864c19
--- /dev/null
+++ b/src/main/java/net/minecraft/client/input/InputDeviceMouse.java
@@ -0,0 +1,38 @@
+package net.minecraft.client.input;
+
+import org.lwjgl.input.Mouse;
+
+public class InputDeviceMouse extends InputDevice {
+	
+	private static final String[] MOUSE_BUTTON_NAMES = new String[] { "LEFT CLICK", "RIGHT CLICK", "MIDDLE CLICK" };
+
+	@Override
+	public boolean isPressed(int keyCode) {
+		return Mouse.isButtonDown(keyCode);
+	}
+
+	@Override
+	public boolean isPressEvent(int keyCode) {
+		return Mouse.getEventButton() == keyCode && Mouse.getEventButtonState();
+	}
+
+	@Override
+	public boolean isReleaseEvent(int keyCode) {
+		return Mouse.getEventButton() == keyCode && !Mouse.getEventButtonState();
+	}
+
+	@Override
+	public boolean isKeyCodeValid(int keyCode) {
+		return keyCode >= 0;
+	}
+
+	@Override
+	public String getKeyName(int keyCode) {
+		if (keyCode < MOUSE_BUTTON_NAMES.length) {
+			return MOUSE_BUTTON_NAMES[keyCode];
+		} else {
+			return "MOUSE " + (keyCode + 1);
+		}
+	}
+
+}
diff --git a/src/main/java/net/minecraft/client/net/handler/NetClientHandler.java b/src/main/java/net/minecraft/client/net/handler/NetClientHandler.java
index 563d0dd58..830b2423c 100644
--- a/src/main/java/net/minecraft/client/net/handler/NetClientHandler.java
+++ b/src/main/java/net/minecraft/client/net/handler/NetClientHandler.java
@@ -627,7 +627,7 @@ public class NetClientHandler extends NetHandler
     @Override
     public void handleBlockChange(Packet53BlockChange packet53blockchange)
     {
-        worldClient.func_714_c(packet53blockchange.xPosition, packet53blockchange.yPosition, packet53blockchange.zPosition, packet53blockchange.type, packet53blockchange.metadata);
+        worldClient.blockChange(packet53blockchange.xPosition, packet53blockchange.yPosition, packet53blockchange.zPosition, packet53blockchange.type, packet53blockchange.metadata);
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/option/GameSettings.java b/src/main/java/net/minecraft/client/option/GameSettings.java
index b059de517..a2cdfad31 100644
--- a/src/main/java/net/minecraft/client/option/GameSettings.java
+++ b/src/main/java/net/minecraft/client/option/GameSettings.java
@@ -15,6 +15,7 @@ import com.b100.utils.ReflectUtils;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.discord.RichPresenceHandlerThread;
 import net.minecraft.client.gui.hud.HudComponents;
+import net.minecraft.client.input.InputDevice;
 import net.minecraft.client.option.enums.Colorblindness;
 import net.minecraft.client.option.enums.Difficulty;
 import net.minecraft.client.option.enums.LightmapStyle;
@@ -31,7 +32,6 @@ import net.minecraft.core.util.helper.ITranslatable;
 
 public class GameSettings {
 
-	private static final String[] LIMIT_FRAMERATES = { "performance.max", "performance.balanced", "performance.powersaver", "performance.vsync" };
 	private static final String[] ANIMATIONS = { "options.animations.off", "options.animations.procedural", "options.animations.custom" };
 
 	public final Minecraft mc;
@@ -165,57 +165,58 @@ public class GameSettings {
 	public BooleanOption mobVariants = new BooleanOption(this, "mobVariants", true);
 	public EnumOption<Colorblindness> colorblindnessFix = new EnumOption<>(this, "colorblindnessFix", Colorblindness.class, Colorblindness.NONE);
 
-	public KeyBinding keyAttack = new KeyBinding("key.attack").bindMouse(0);
-	public KeyBinding keyInteract = new KeyBinding("key.interact").bindMouse(1);
-	public KeyBinding keyPickBlock = new KeyBinding("key.pickBlock").bindMouse(2);
-	public KeyBinding keySortInventory = new KeyBinding("key.sortInventory").bindMouse(2);
-	public KeyBinding keyForward = new KeyBinding("key.forward").bindKeyboard(KEY_W);
-	public KeyBinding keyLeft = new KeyBinding("key.left").bindKeyboard(KEY_A);
-	public KeyBinding keyBack = new KeyBinding("key.back").bindKeyboard(KEY_S);
-	public KeyBinding keyRight = new KeyBinding("key.right").bindKeyboard(KEY_D);
-	public KeyBinding keyJump = new KeyBinding("key.jump").bindKeyboard(KEY_SPACE);
-	public KeyBinding keyInventory = new KeyBinding("key.inventory").bindKeyboard(KEY_E);
-	public KeyBinding keyDrop = new KeyBinding("key.drop").bindKeyboard(KEY_Q);
-	public KeyBinding keyChat = new KeyBinding("key.chat").bindKeyboard(KEY_T);
-	public KeyBinding keyCommand = new KeyBinding("key.command").bindKeyboard(KEY_SLASH);
-	public KeyBinding keyToggleFog = new KeyBinding("key.fog").bindKeyboard(KEY_F);
-	public KeyBinding keyToggleGamma = new KeyBinding("key.gamma").bindKeyboard(KEY_G);
-	public KeyBinding keySneak = new KeyBinding("key.sneak").bindKeyboard(KEY_LSHIFT);
-	public KeyBinding keyFly = new KeyBinding("key.fly").bindKeyboard(KEY_LCONTROL);
-	public KeyBinding keyGuidebook = new KeyBinding("key.guidebook").bindKeyboard(KEY_R);
-	public KeyBinding keyShowRecipe = new KeyBinding("key.showRecipe").bindKeyboard(KEY_R);
-	public KeyBinding keyShowUsage = new KeyBinding("key.showUsage").bindKeyboard(KEY_U);
-	public KeyBinding keyHotBarLeft = new KeyBinding("key.hotbar.left").bindKeyboard(KEY_COMMA);
-	public KeyBinding keyHotBarRight = new KeyBinding("key.hotbar.right").bindKeyboard(KEY_PERIOD);
-	public KeyBinding keyHotBarSwitch = new KeyBinding("key.hotbar.switch").bindKeyboard(KEY_TAB);
+	public KeyBinding keyAttack = new KeyBinding("key.attack").setDefault(InputDevice.mouse, 0);
+	public KeyBinding keyInteract = new KeyBinding("key.interact").setDefault(InputDevice.mouse, 1);
+	public KeyBinding keyPickBlock = new KeyBinding("key.pickBlock").setDefault(InputDevice.mouse, 2);
+	public KeyBinding keySortInventory = new KeyBinding("key.sortInventory").setDefault(InputDevice.mouse, 2);
+	public KeyBinding keyForward = new KeyBinding("key.forward").setDefault(InputDevice.keyboard, KEY_W);
+	public KeyBinding keyLeft = new KeyBinding("key.left").setDefault(InputDevice.keyboard, KEY_A);
+	public KeyBinding keyBack = new KeyBinding("key.back").setDefault(InputDevice.keyboard, KEY_S);
+	public KeyBinding keyRight = new KeyBinding("key.right").setDefault(InputDevice.keyboard, KEY_D);
+	public KeyBinding keyJump = new KeyBinding("key.jump").setDefault(InputDevice.keyboard, KEY_SPACE);
+	public KeyBinding keyInventory = new KeyBinding("key.inventory").setDefault(InputDevice.keyboard, KEY_E);
+	public KeyBinding keyDrop = new KeyBinding("key.drop").setDefault(InputDevice.keyboard, KEY_Q);
+	public KeyBinding keyChat = new KeyBinding("key.chat").setDefault(InputDevice.keyboard, KEY_T);
+	public KeyBinding keyCommand = new KeyBinding("key.command").setDefault(InputDevice.keyboard, KEY_SLASH);
+	public KeyBinding keyToggleFog = new KeyBinding("key.fog").setDefault(InputDevice.keyboard, KEY_F);
+	public KeyBinding keyToggleGamma = new KeyBinding("key.gamma").setDefault(InputDevice.keyboard, KEY_G);
+	public KeyBinding keySneak = new KeyBinding("key.sneak").setDefault(InputDevice.keyboard, KEY_LSHIFT);
+	public KeyBinding keyFly = new KeyBinding("key.fly").setDefault(InputDevice.keyboard, KEY_LCONTROL);
+	public KeyBinding keyGuidebook = new KeyBinding("key.guidebook").setDefault(InputDevice.keyboard, KEY_R);
+	public KeyBinding keyShowRecipe = new KeyBinding("key.showRecipe").setDefault(InputDevice.keyboard, KEY_R);
+	public KeyBinding keyShowUsage = new KeyBinding("key.showUsage").setDefault(InputDevice.keyboard, KEY_U);
+	public KeyBinding keyHotBarLeft = new KeyBinding("key.hotbar.left").setDefault(InputDevice.keyboard, KEY_COMMA);
+	public KeyBinding keyHotBarRight = new KeyBinding("key.hotbar.right").setDefault(InputDevice.keyboard, KEY_PERIOD);
+	public KeyBinding keyHotBarSwitch = new KeyBinding("key.hotbar.switch").setDefault(InputDevice.keyboard, KEY_TAB);
 
-	public KeyBinding keyHotBarSlot1 = new KeyBinding("key.hotbar.1").bindKeyboard(KEY_1);
-	public KeyBinding keyHotBarSlot2 = new KeyBinding("key.hotbar.2").bindKeyboard(KEY_2);
-	public KeyBinding keyHotBarSlot3 = new KeyBinding("key.hotbar.3").bindKeyboard(KEY_3);
-	public KeyBinding keyHotBarSlot4 = new KeyBinding("key.hotbar.4").bindKeyboard(KEY_4);
-	public KeyBinding keyHotBarSlot5 = new KeyBinding("key.hotbar.5").bindKeyboard(KEY_5);
-	public KeyBinding keyHotBarSlot6 = new KeyBinding("key.hotbar.6").bindKeyboard(KEY_6);
-	public KeyBinding keyHotBarSlot7 = new KeyBinding("key.hotbar.7").bindKeyboard(KEY_7);
-	public KeyBinding keyHotBarSlot8 = new KeyBinding("key.hotbar.8").bindKeyboard(KEY_8);
-	public KeyBinding keyHotBarSlot9 = new KeyBinding("key.hotbar.9").bindKeyboard(KEY_9);
+	public KeyBinding keyHotBarSlot1 = new KeyBinding("key.hotbar.1").setDefault(InputDevice.keyboard, KEY_1);
+	public KeyBinding keyHotBarSlot2 = new KeyBinding("key.hotbar.2").setDefault(InputDevice.keyboard, KEY_2);
+	public KeyBinding keyHotBarSlot3 = new KeyBinding("key.hotbar.3").setDefault(InputDevice.keyboard, KEY_3);
+	public KeyBinding keyHotBarSlot4 = new KeyBinding("key.hotbar.4").setDefault(InputDevice.keyboard, KEY_4);
+	public KeyBinding keyHotBarSlot5 = new KeyBinding("key.hotbar.5").setDefault(InputDevice.keyboard, KEY_5);
+	public KeyBinding keyHotBarSlot6 = new KeyBinding("key.hotbar.6").setDefault(InputDevice.keyboard, KEY_6);
+	public KeyBinding keyHotBarSlot7 = new KeyBinding("key.hotbar.7").setDefault(InputDevice.keyboard, KEY_7);
+	public KeyBinding keyHotBarSlot8 = new KeyBinding("key.hotbar.8").setDefault(InputDevice.keyboard, KEY_8);
+	public KeyBinding keyHotBarSlot9 = new KeyBinding("key.hotbar.9").setDefault(InputDevice.keyboard, KEY_9);
 
-	public KeyBinding keyLookLeft = new KeyBinding("key.look.left").bindKeyboard(KEY_LEFT);
-	public KeyBinding keyLookRight = new KeyBinding("key.look.right").bindKeyboard(KEY_RIGHT);
-	public KeyBinding keyLookUp = new KeyBinding("key.look.up").bindKeyboard(KEY_UP);
-	public KeyBinding keyLookDown = new KeyBinding("key.look.down").bindKeyboard(KEY_DOWN);
-	public KeyBinding keyCenterView = new KeyBinding("key.look.center").bindKeyboard(KEY_END);
-	public KeyBinding keyZoom = new KeyBinding("key.zoom").bindKeyboard(KEY_C);
-	public KeyBinding keyPlayerList = new KeyBinding("key.playerList").bindKeyboard(KEY_L);
-	public KeyBinding keyPhotoMode = new KeyBinding("key.photoMode").bindKeyboard(KEY_P);
-	public KeyBinding keyLockRotation = new KeyBinding("key.lockRotation").bindKeyboard(KEY_Z);
-	public KeyBinding keyScreenshot = new KeyBinding("key.screenshot").bindKeyboard(KEY_F2);
-	public KeyBinding keyCinematicCamera = new KeyBinding("key.cinematicCamera").bindKeyboard(KEY_F8);
-	public KeyBinding keySwitchPerspective = new KeyBinding("key.switchPerspective").bindKeyboard(KEY_F5);
-	public KeyBinding keyHideGui = new KeyBinding("key.immersiveMode").bindKeyboard(KEY_F1);
-	public KeyBinding keyAutoWalk = new KeyBinding("key.autoWalk").bindKeyboard(KEY_NONE);
-	public KeyBinding keySprint = new KeyBinding("key.sprint").bindKeyboard(KEY_NONE);
-	public KeyBinding keyToggleDebug = new KeyBinding("key.toggleDebug").bindKeyboard(KEY_F3);
-	public KeyBinding keyToggleOverlay = new KeyBinding("key.toggleOverlay").bindKeyboard(KEY_F4);
+	public KeyBinding keyLookLeft = new KeyBinding("key.look.left").setDefault(InputDevice.keyboard, KEY_LEFT);
+	public KeyBinding keyLookRight = new KeyBinding("key.look.right").setDefault(InputDevice.keyboard, KEY_RIGHT);
+	public KeyBinding keyLookUp = new KeyBinding("key.look.up").setDefault(InputDevice.keyboard, KEY_UP);
+	public KeyBinding keyLookDown = new KeyBinding("key.look.down").setDefault(InputDevice.keyboard, KEY_DOWN);
+	public KeyBinding keyCenterView = new KeyBinding("key.look.center").setDefault(InputDevice.keyboard, KEY_END);
+	public KeyBinding keyZoom = new KeyBinding("key.zoom").setDefault(InputDevice.keyboard, KEY_C);
+	public KeyBinding keyPlayerList = new KeyBinding("key.playerList").setDefault(InputDevice.keyboard, KEY_L);
+	public KeyBinding keyPhotoMode = new KeyBinding("key.photoMode").setDefault(InputDevice.keyboard, KEY_P);
+	public KeyBinding keyLockRotation = new KeyBinding("key.lockRotation").setDefault(InputDevice.keyboard, KEY_Z);
+	public KeyBinding keyScreenshot = new KeyBinding("key.screenshot").setDefault(InputDevice.keyboard, KEY_F2);
+	public KeyBinding keyCinematicCamera = new KeyBinding("key.cinematicCamera").setDefault(InputDevice.keyboard, KEY_F8);
+	public KeyBinding keySwitchPerspective = new KeyBinding("key.switchPerspective").setDefault(InputDevice.keyboard, KEY_F5);
+	public KeyBinding keyHideGui = new KeyBinding("key.immersiveMode").setDefault(InputDevice.keyboard, KEY_F1);
+	public KeyBinding keyAutoWalk = new KeyBinding("key.autoWalk");
+	public KeyBinding keySprint = new KeyBinding("key.sprint");
+	public KeyBinding keyToggleDebug = new KeyBinding("key.toggleDebug").setDefault(InputDevice.keyboard, KEY_F3);
+	public KeyBinding keyToggleOverlay = new KeyBinding("key.toggleOverlay").setDefault(InputDevice.keyboard, KEY_F4);
+	public KeyBinding keyToggleTextureAtlas = new KeyBinding("key.debug.textureAtlas");
 
 	public KeyBinding[] keys = ReflectUtils.getAllObjects(GameSettings.class, KeyBinding.class, this);
 
@@ -316,8 +317,7 @@ public class GameSettings {
 			}
 		}
 		if(option == customFpsLimit){
-			Option<Integer> limit = (Option<Integer>) option;
-			int value = limit.value;
+			int value = customFpsLimit.value;
 			int maxValue = 240;
 			if (enableVsync.value){
 				if(mc.gameWindow instanceof GameWindowLWJGL2){
@@ -325,10 +325,10 @@ public class GameSettings {
 				}
 			}
 			if(value > maxValue){
-				limit.set(maxValue);
+				customFpsLimit.set(maxValue);
 			}
 			if(value < 15){
-				limit.set(0);
+				customFpsLimit.set(0);
 				return trans.translateKey("options.customFpsLimit.unlimited");
 			}
 		}
@@ -442,11 +442,10 @@ public class GameSettings {
 			
 line:		for (String line = ""; (line = br.readLine()) != null;) {
 				try {
-					String[] as = line.split(":");
-
-					String key = as[0];
-					String value = as[1];
-
+					int i = line.indexOf(':');
+					String key = line.substring(0, i);
+					String value = line.substring(i + 1);
+					
 					if (key.equals("hudLayout")) {
 						HudComponents.INSTANCE.fromSettingsString(value);
 						continue line;
@@ -465,15 +464,15 @@ line:		for (String line = ""; (line = br.readLine()) != null;) {
                             continue line;
                         }
                     }
-				} catch (Exception exception1) {
+				} catch (Exception e) {
 					System.out.println("Skipping bad option: "+line);
 				}
 			}
 
 			br.close();
-		} catch (Exception exception) {
+		} catch (Exception e) {
 			System.out.println("Failed to load options");
-			exception.printStackTrace();
+			e.printStackTrace();
 		}
 	}
 	
diff --git a/src/main/java/net/minecraft/client/option/InputDevice.java b/src/main/java/net/minecraft/client/option/InputDevice.java
deleted file mode 100644
index e5a3a9a22..000000000
--- a/src/main/java/net/minecraft/client/option/InputDevice.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.minecraft.client.option;
-
-public enum InputDevice {
-    KEYBOARD, MOUSE;
-}
diff --git a/src/main/java/net/minecraft/client/option/KeyBinding.java b/src/main/java/net/minecraft/client/option/KeyBinding.java
index debf10af3..8b6c8c33f 100644
--- a/src/main/java/net/minecraft/client/option/KeyBinding.java
+++ b/src/main/java/net/minecraft/client/option/KeyBinding.java
@@ -1,16 +1,36 @@
 package net.minecraft.client.option;
 
-import org.lwjgl.input.Keyboard;
+import java.util.HashMap;
+import java.util.Map;
 
+import net.minecraft.client.input.InputDevice;
 import net.minecraft.core.lang.I18n;
-import org.lwjgl.input.Mouse;
 
 public class KeyBinding {
-	private static String UNBOUND = "NONE";
-	private static final String[] MOUSE_BUTTON_NAMES = new String[] { "LEFT CLICK", "RIGHT CLICK", "MIDDLE CLICK" };
+	
+	private static Map<Character, InputDevice> charToInputDeviceMap = new HashMap<>();
+	private static Map<InputDevice, Character> inputDeviceToCharMap = new HashMap<>();
+	
+	public static void addInputDevice(char c, InputDevice inputDevice) {
+		if(charToInputDeviceMap.containsKey(c)) {
+			inputDeviceToCharMap.remove(charToInputDeviceMap.get(c));
+		}
+		if(inputDeviceToCharMap.containsKey(inputDevice)) {
+			charToInputDeviceMap.remove(inputDeviceToCharMap.get(inputDevice));
+		}
+		charToInputDeviceMap.put(c, inputDevice);
+		inputDeviceToCharMap.put(inputDevice, c);
+	}
+	
+	static {
+		addInputDevice('m', InputDevice.mouse);
+		addInputDevice('k', InputDevice.keyboard);
+	}
+	
 	private final String id;
-	private InputDevice inputDevice;
-	private int keyCode;
+	
+	private InputDevice inputDevice = null;
+	private int keyCode = -1;
 
 	private InputDevice defaultInputDevice = null;
 	private int defaultKeyCode = -1;
@@ -21,30 +41,27 @@ public class KeyBinding {
 		this.keyCode = -1;
 	}
 
-	public KeyBinding bindKeyboard(int keyCode) {
-		this.keyCode = keyCode;
-		this.inputDevice = InputDevice.KEYBOARD;
-
-		if (this.defaultInputDevice == null) {
-			this.defaultInputDevice = InputDevice.KEYBOARD;
-			this.defaultKeyCode = keyCode;
+	public KeyBinding setDefault(InputDevice device, int keyCode) {
+		if(device != null && !device.isKeyCodeValid(keyCode)) {
+			throw new RuntimeException("Key code " + keyCode + " is not valid for input device " + device);
 		}
-
-		return this;
+		
+		this.defaultInputDevice = device;
+		this.defaultKeyCode = keyCode;
+		
+		return bind(device, keyCode);
 	}
-
-	public KeyBinding bindMouse(int keyCode) {
-		this.keyCode = keyCode;
-		this.inputDevice = InputDevice.MOUSE;
-
-		if (this.defaultInputDevice == null) {
-			this.defaultInputDevice = InputDevice.MOUSE;
-			this.defaultKeyCode = keyCode;
+	
+	public KeyBinding bind(InputDevice device, int keyCode) {
+		if(device.isKeyCodeValid(keyCode)) {
+			this.keyCode = keyCode;
+			this.inputDevice = device;	
+		}else {
+			unbind();
 		}
-
 		return this;
 	}
-
+	
 	public KeyBinding unbind() {
 		this.keyCode = -1;
 		this.inputDevice = null;
@@ -74,96 +91,87 @@ public class KeyBinding {
 	}
 
 	public boolean isPressed() {
-		if (!isBound()) return false;
-		if(keyCode >= 0) {
-			switch (inputDevice) {
-				case KEYBOARD:
-					return Keyboard.isKeyDown(keyCode);
-				case MOUSE:
-					return Mouse.isButtonDown(keyCode);
-			}
+		if(inputDevice != null) {
+			return inputDevice.isPressed(keyCode);
 		}
 		return false;
 	}
 
 	public boolean isPressEvent(InputDevice eventInputDevice) {
-		if (!isBound() || eventInputDevice != inputDevice) return false;
-		switch (inputDevice) {
-			case KEYBOARD:
-				return Keyboard.getEventKey() == keyCode && Keyboard.getEventKeyState();
-			case MOUSE:
-				return Mouse.getEventButton() == keyCode && Mouse.getEventButtonState();
+		if(inputDevice == eventInputDevice) {
+			return inputDevice.isPressEvent(keyCode);
 		}
 		return false;
 	}
 
 	public boolean isReleaseEvent(InputDevice eventInputDevice) {
-		if (!isBound() || eventInputDevice != inputDevice) return false;
-		switch (inputDevice) {
-			case KEYBOARD:
-				return Keyboard.getEventKey() == keyCode && !Keyboard.getEventKeyState();
-			case MOUSE:
-				return Mouse.getEventButton() == keyCode && !Mouse.getEventButtonState();
+		if(inputDevice == eventInputDevice) {
+			return inputDevice.isReleaseEvent(keyCode);
 		}
 		return false;
 	}
 
 	public void fromOptionsString(String value) {
-		if (value.equals(UNBOUND)) {
-			this.unbind();
+		if(value.length() == 0) {
+			unbind();
 			return;
 		}
-
-		if (value.startsWith("m")) {
-			bindMouse(Integer.parseInt(value.substring(1)));
-		} else if (value.startsWith("k")) {
-			bindKeyboard(Integer.parseInt(value.substring(1)));
-		} else {
-			bindKeyboard(Integer.parseInt(value));
+		
+		char c = value.charAt(0);
+		
+		InputDevice inputDevice;
+		int code;
+		if(c >= '0' && c <= '9') {
+			inputDevice = InputDevice.keyboard;
+			code = Integer.parseInt(value);
+		}else {
+			inputDevice = charToInputDeviceMap.get(c);
+			code = Integer.parseInt(value.substring(1));
+		}
+		
+		if(inputDevice == null) {
+			unbind();
+			return;
 		}
+		
+		bind(inputDevice, code);
 	}
 
 	public String toOptionsString() {
-		if(!isBound()) {
-			return UNBOUND;
-		}
-		switch (inputDevice) {
-			case KEYBOARD:
-				return "k" + keyCode;
-			case MOUSE:
-				return "m" + keyCode;
+		Character c = inputDeviceToCharMap.get(inputDevice);
+		if(c != null) {
+			return String.valueOf(c) + keyCode;
 		}
 		return "";
 	}
 	
 	public boolean isKeyboardKey(int key) {
-		if(this.keyCode <= 0 || this.inputDevice != InputDevice.KEYBOARD) return false;
-		return this.keyCode == key;
+		if(inputDevice == InputDevice.keyboard) {
+			return keyCode == key;
+		}
+		return false;
 	}
 
 	public boolean isMouseButton(int button) {
-		if(this.keyCode < 0 || this.inputDevice != InputDevice.MOUSE) return false;
-		return this.keyCode == button;
+		if(inputDevice == InputDevice.mouse) {
+			return keyCode == button;
+		}
+		return false;
 	}
 	
 	public boolean isBound() {
-		return !(inputDevice == null || ((inputDevice == InputDevice.KEYBOARD && keyCode < 0) || (inputDevice == InputDevice.MOUSE && keyCode < 0)));
+		return inputDevice != null;
 	}
 	
 	public String getKeyName() {
-		if(!isBound()) {
+		if(inputDevice == null) {
 			return I18n.getInstance().translateKey("key.disabled");
 		}
-		switch (inputDevice) {
-			case KEYBOARD:
-				return Keyboard.getKeyName(keyCode);
-			case MOUSE:
-				if (keyCode < MOUSE_BUTTON_NAMES.length) {
-					return MOUSE_BUTTON_NAMES[keyCode];
-				} else {
-					return "MOUSE " + (keyCode + 1);
-				}
+		
+		String keyName = inputDevice.getKeyName(keyCode);
+		if(keyName == null) {
+			keyName = String.valueOf(keyCode);
 		}
-		return "";
+		return keyName;
 	}
 }
diff --git a/src/main/java/net/minecraft/client/player/controller/PlayerController.java b/src/main/java/net/minecraft/client/player/controller/PlayerController.java
index d03fcf2b3..1988619e3 100644
--- a/src/main/java/net/minecraft/client/player/controller/PlayerController.java
+++ b/src/main/java/net/minecraft/client/player/controller/PlayerController.java
@@ -265,8 +265,8 @@ public abstract class PlayerController {
 		return new EntityPlayerSP(mc, world, mc.session, world.dimension.id);
 	}
 
-	public void interact(EntityPlayer entityplayer, Entity entity) {
-		entityplayer.useCurrentItemOnEntity(entity);
+	public boolean interact(EntityPlayer entityplayer, Entity entity) {
+		return entityplayer.useCurrentItemOnEntity(entity);
 	}
 
 	public void attack(EntityPlayer entityplayer, Entity entity) {
diff --git a/src/main/java/net/minecraft/client/player/controller/PlayerControllerMP.java b/src/main/java/net/minecraft/client/player/controller/PlayerControllerMP.java
index eeff5f7c6..3d6540857 100644
--- a/src/main/java/net/minecraft/client/player/controller/PlayerControllerMP.java
+++ b/src/main/java/net/minecraft/client/player/controller/PlayerControllerMP.java
@@ -92,10 +92,10 @@ public class PlayerControllerMP extends PlayerController {
 	}
 
 	@Override
-	public void interact(EntityPlayer entityplayer, Entity entity) {
+	public boolean interact(EntityPlayer entityplayer, Entity entity) {
 		syncCurrentPlayItem();
 		netHandler.addToSendQueue(new Packet7UseEntity(entityplayer.id, entity.id, 0));
-		entityplayer.useCurrentItemOnEntity(entity);
+		return entityplayer.useCurrentItemOnEntity(entity);
 	}
 
 	@Override
diff --git a/src/main/java/net/minecraft/client/render/ChunkRenderer.java b/src/main/java/net/minecraft/client/render/ChunkRenderer.java
index 6fb1c0f7a..10fc0cc9a 100644
--- a/src/main/java/net/minecraft/client/render/ChunkRenderer.java
+++ b/src/main/java/net/minecraft/client/render/ChunkRenderer.java
@@ -19,6 +19,7 @@ import org.lwjgl.opengl.GL11;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 public class ChunkRenderer
 {
@@ -74,57 +75,48 @@ public class ChunkRenderer
 
     public void updateRenderer()
     {
-        if(!needsUpdate)
-        {
-            return;
-        }
+        if(!needsUpdate) { return; }
         chunksUpdated++;
-        int minX = posX;
-        int minY = posY;
-        int minZ = posZ;
-        int maxX = posX + sizeWidth;
-        int maxY = posY + sizeHeight;
-        int maxZ = posZ + sizeDepth;
-        for(int i = 0; i < MAX_RENDER_PASSES; i++)
-        {
-            skipRenderPass[i] = true;
-        }
+        final int minX = posX;
+        final int minY = posY;
+        final int minZ = posZ;
+        final int maxX = posX + sizeWidth;
+        final int maxY = posY + sizeHeight;
+        final int maxZ = posZ + sizeDepth;
+        for(int i = 0; i < MAX_RENDER_PASSES; i++) { skipRenderPass[i] = true; }
 
         Chunk.isLit = false;
-        HashSet<TileEntity> lastSpecialTileEntities = new HashSet<>(specialTileEntities);
+        final Set<TileEntity> lastSpecialTileEntities = new HashSet<>(specialTileEntities);
         specialTileEntities.clear();
-        int cacheRadius = 1;
-        ChunkCache chunkcache = new ChunkCache(worldObj, minX - cacheRadius, minY - cacheRadius, minZ - cacheRadius, maxX + cacheRadius, maxY + cacheRadius, maxZ + cacheRadius);
-        RenderBlocks renderblocks = new RenderBlocks(chunkcache);
+        final int cacheRadius = 1;
+        final ChunkCache chunkcache = new ChunkCache(worldObj, minX - cacheRadius, minY - cacheRadius, minZ - cacheRadius, maxX + cacheRadius, maxY + cacheRadius, maxZ + cacheRadius);
+        final RenderBlocks renderblocks = new RenderBlocks(chunkcache);
         BlockModel.setRenderBlocks(renderblocks);
         int renderPass = 0;
         do
         {
-            if(renderPass >= MAX_RENDER_PASSES)
-            {
-                break;
-            }
+            if(renderPass >= MAX_RENDER_PASSES) { break; }
+
             boolean needsMoreRenderPasses = false;
             boolean hasRenderedBlock = false;
             boolean hasStartedDrawing = false;
+
             for(int y = minY; y < maxY; y++)
             {
                 for(int z = minZ; z < maxZ; z++)
                 {
                     for(int x = minX; x < maxX; x++)
                     {
-                        int blockId = chunkcache.getBlockId(x, y, z);
-                        if(blockId <= 0)
-                        {
+                        final int blockId = chunkcache.getBlockId(x, y, z);
+                        if(blockId <= 0) {
                             continue;
                         }
-                        if(!hasStartedDrawing)
-                        {
+                        if(!hasStartedDrawing) {
                             hasStartedDrawing = true;
                             GL11.glNewList(glRenderList + renderPass, GL11.GL_COMPILE);
                             GL11.glPushMatrix();
                             setupGLTranslation();
-                            float scale = 1.000001F;
+                            final float scale = 1.000001F;
                             GL11.glTranslatef((float)(-sizeDepth) / 2.0F, (float)(-sizeHeight) / 2.0F, (float)(-sizeDepth) / 2.0F);
                             GL11.glScalef(scale, scale, scale);
                             GL11.glTranslatef((float)sizeDepth / 2.0F, (float)sizeHeight / 2.0F, (float)sizeDepth / 2.0F);
@@ -136,58 +128,47 @@ public class ChunkRenderer
                             	tessellator.setLightmapCoord(LightmapHelper.getLightmapCoord(15, 15));
                             }
                         }
-                        if(renderPass == 0 && Block.isEntityTile[blockId])
-                        {
-                            TileEntity tileentity = chunkcache.getBlockTileEntity(x, y, z);
-                            if(TileEntityRenderDispatcher.instance.hasRenderer(tileentity))
-                            {
+                        if(renderPass == 0 && Block.isEntityTile[blockId]) {
+                            final TileEntity tileentity = chunkcache.getBlockTileEntity(x, y, z);
+                            if(TileEntityRenderDispatcher.instance.hasRenderer(tileentity)) {
                                 specialTileEntities.add(tileentity);
                             }
                         }
-                        Block block = Block.blocksList[blockId];
-                        int blockRenderPass = block.getRenderBlockPass();
-                        if(blockRenderPass != renderPass)
-                        {
+                        final Block block = Block.blocksList[blockId];
+                        final int blockRenderPass = block.getRenderBlockPass();
+                        if(blockRenderPass != renderPass) {
                             needsMoreRenderPasses = true;
                         }
-                        else
-                        {
+                        else {
                         	if(LightmapHelper.isLightmapEnabled()) {
                         		// Can probably be removed once all block models support the lightmap
                         		tessellator.setLightmapCoord(LightmapHelper.getLightmapCoord(15, 0));	
                         	}
                             
-                            BlockModel<Block> model = BlockModelDispatcher.getInstance().getDispatch(block);
+                            final BlockModel<Block> model = BlockModelDispatcher.getInstance().getDispatch(block);
                             hasRenderedBlock |= model.render(tessellator, x, y, z);
-                            if (model.hasOverbright())
-                            {
+                            if (model.hasOverbright()) {
                             	renderblocks.overbright = true;
                                 hasRenderedBlock |= model.render(tessellator, x, y, z);
                                 renderblocks.overbright = false;
                             }
                         }
                     }
-
                 }
-
             }
-            if(hasStartedDrawing)
-            {
+            if(hasStartedDrawing) {
                 tessellator.draw();
                 GL11.glPopMatrix();
                 GL11.glEndList();
                 tessellator.setTranslation(0.0D, 0.0D, 0.0D);
-            } else
-            {
+            } else {
                 hasRenderedBlock = false;
             }
             
-            if(hasRenderedBlock)
-            {
+            if(hasRenderedBlock) {
                 skipRenderPass[renderPass] = false;
             }            
-            if(!needsMoreRenderPasses)
-            {
+            if(!needsMoreRenderPasses) {
                 break;
             }
             
diff --git a/src/main/java/net/minecraft/client/render/EffectRenderer.java b/src/main/java/net/minecraft/client/render/EffectRenderer.java
index 23d1ef3cb..527d5d8b7 100644
--- a/src/main/java/net/minecraft/client/render/EffectRenderer.java
+++ b/src/main/java/net/minecraft/client/render/EffectRenderer.java
@@ -135,27 +135,24 @@ public class EffectRenderer
 
     }
 
-    public void addBlockDestroyEffects(int i, int j, int k, int l, int i1)
+    public void addBlockDestroyEffects(int x, int y, int z, int blockId, int i1)
     {
-        if(l == 0)
-        {
-            return;
-        }
-        Block block = Block.blocksList[l];
-        int j1 = 4;
+        Block block = Block.blocksList[blockId];
+        if (block == null) return;
+        int amount = 4;
         if(block == Block.fire)
             return;
-        for(int k1 = 0; k1 < j1; k1++)
+        for(int _x = 0; _x < amount; _x++)
         {
-            for(int l1 = 0; l1 < j1; l1++)
+            for(int _y = 0; _y < amount; _y++)
             {
-                for(int i2 = 0; i2 < j1; i2++)
+                for(int _z = 0; _z < amount; _z++)
                 {
-                    double d = (double)i + ((double)k1 + 0.5D) / (double)j1;
-                    double d1 = (double)j + ((double)l1 + 0.5D) / (double)j1;
-                    double d2 = (double)k + ((double)i2 + 0.5D) / (double)j1;
-                    int j2 = rand.nextInt(6);
-                    addEffect((new EntityDiggingFX(worldObj, d, d1, d2, d - (double)i - 0.5D, d1 - (double)j - 0.5D, d2 - (double)k - 0.5D, block, j2, i1)).setParticleColor(i, j, k));
+                    double pX = (double)x + ((double)_x + 0.5D) / (double)amount;
+                    double pY = (double)y + ((double)_y + 0.5D) / (double)amount;
+                    double pZ = (double)z + ((double)_z + 0.5D) / (double)amount;
+                    int side = rand.nextInt(6);
+                    addEffect((new EntityDiggingFX(worldObj, pX, pY, pZ, pX - (double)x - 0.5D, pY - (double)y - 0.5D, pZ - (double)z - 0.5D, block, side, i1)).setParticleColor(x, y, z));
                 }
 
             }
diff --git a/src/main/java/net/minecraft/client/render/RenderGlobal.java b/src/main/java/net/minecraft/client/render/RenderGlobal.java
index 4c2f46948..be081a4dd 100644
--- a/src/main/java/net/minecraft/client/render/RenderGlobal.java
+++ b/src/main/java/net/minecraft/client/render/RenderGlobal.java
@@ -301,7 +301,7 @@ public class RenderGlobal
         double cameraY = camera.getY(partialTick);
         double cameraZ = camera.getZ(partialTick);
         double cameraYaw = camera.getYRot(partialTick);
-        float temperature = (float)worldObj.getBlockTemperature((int)cameraX, (int)cameraZ);
+        double temperature = worldObj.getBlockTemperature((int)cameraX, (int)cameraZ);
         float mult = 0.0f;
         if (temperature <= 0.4f || worldObj.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_WINTER_ENDLESS)
         {
@@ -313,7 +313,7 @@ public class RenderGlobal
             mult += temperature;
         }
 
-        float altitude = (float)worldObj.getWorldType().getYPercentage((int)cameraY);
+        double altitude = worldObj.getWorldType().getYPercentage((int)cameraY);
         if ((temperature <= 0.6f || worldObj.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_WINTER || worldObj.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_WINTER_ENDLESS) && altitude >= 0.8f)
         {
             // altitude from 0.8f to 1.0f
@@ -326,13 +326,13 @@ public class RenderGlobal
         if (mult < 0.0f) mult = 0.0f;
         if (mult > 1.0f) mult = 1.0f;
 
-        if (Float.isNaN(targetAuroraBrightness))
+        if (Double.isNaN(targetAuroraBrightness))
         {
             auroraBrightness = mult;
         }
 
         targetAuroraBrightness = mult;
-        float totalDelta = targetAuroraBrightness - auroraBrightness;
+        double totalDelta = targetAuroraBrightness - auroraBrightness;
         auroraBrightnessDelta = totalDelta / 100;
         auroraBrightness += auroraBrightnessDelta * partialTick;
 
@@ -344,44 +344,44 @@ public class RenderGlobal
         GL11.glDisable(GL11.GL_FOG);
         GL11.glDisable(GL11.GL_ALPHA_TEST);
 
-        float scale = 1f;
-        float auroraY = (worldObj.getWorldType().getMinY() + worldObj.getWorldType().getYRange() + 64f) * 2f;
+        final double scale = 1f;
+        double auroraY = (worldObj.getWorldType().getMinY() + worldObj.getWorldType().getYRange() + 64f) * 2f;
 
         // Draw pieces
-        float rotationX = MathHelper.cos((float) ((cameraYaw * Math.PI) / 180F));
-        float rotationZ = MathHelper.sin((float) ((cameraYaw * Math.PI) / 180F));
+        double rotationX = Math.cos(((cameraYaw * Math.PI) / 180D));
+        double rotationZ = Math.sin(((cameraYaw * Math.PI) / 180D));
 
         renderEngine.bindTexture(renderEngine.getTexture("%blur%/environment/aurora.png"));
-        float time = worldObj.getWorldTime() + partialTick;
+        double time = worldObj.getWorldTime() + partialTick;
         AuroraProvider aurora = worldObj.auroraProvider;
 
-        float radius = 512;
+        double radius = 512;
         long worldTime = worldObj.getWorldTime();
 
         Tessellator.instance.startDrawingQuads();
-        for (float x = -radius; x < radius; x += 8f)
+        for (double x = -radius; x < radius; x += 8f)
         {
-            for (float z = -radius; z < radius; z += 8f)
+            for (double z = -radius; z < radius; z += 8f)
             {
-                float posX = (float) cameraX + x;
-                float posZ = (float) cameraZ + z;
+                double posX = cameraX + x;
+                double posZ = cameraZ + z;
 
-                float distanceSq = x * x + z + z;
-                float distanceSqPercentage = distanceSq / (radius * radius + radius * radius);
+                double distanceSq = x * x + z + z;
+                double distanceSqPercentage = distanceSq / (radius * radius + radius * radius);
                 distanceSqPercentage = 1f - distanceSqPercentage;
 
-                float sample = aurora.getAuroraPresence(posX, posZ, worldTime, celestialAngle) * auroraBrightness;
+                double sample = aurora.getAuroraPresence(posX, posZ, worldTime, celestialAngle) * auroraBrightness;
                 if (sample * 0.3f * distanceSqPercentage < 0.01f) continue;
 
                 renderAuroraBeam(
                     x * scale,
-                    (float) (auroraY * scale - cameraY * scale) + aurora.getAuroraHeightOffset(posX, posZ, time),
+                    (auroraY * scale - cameraY * scale) + aurora.getAuroraHeightOffset(posX, posZ, time),
                     z * scale,
                     rotationX, rotationZ,
                     aurora.getAuroraRedOffset(posX, posZ, time),
                     aurora.getAuroraGreenOffset(posX, posZ, time),
                     aurora.getAuroraBlueOffset(posX, posZ, time),
-                    scale, sample * 0.3f * distanceSqPercentage
+                    scale, (float) (sample * 0.3f * distanceSqPercentage)
                 );
             }
         }
@@ -395,7 +395,7 @@ public class RenderGlobal
         GL11.glDisable(GL11.GL_LIGHTING);
     }
 
-    private void renderAuroraBeam(float x, float y, float z, float xOffset, float zOffset, float redOffset, float greenOffset, float blueOffset, float scale, float transparency)
+    private void renderAuroraBeam(double x, double y, double z, double xOffset, double zOffset, float redOffset, float greenOffset, float blueOffset, double scale, float transparency)
     {
         float width = 16f;
         Tessellator tessellator = Tessellator.instance;
@@ -1142,109 +1142,81 @@ public class RenderGlobal
     	mc.renderer.endRenderClouds(partialTick);
     }
 
-    public boolean updateRenderers(ICamera camera)
-    {
-        byte numLayers = 2;
-        ChunkRendererComparator comparator = new ChunkRendererComparator(camera);
-        ChunkRenderer[] chunkRenderers = new ChunkRenderer[numLayers];
-        ArrayList<ChunkRenderer> arraylist = null;
-        int numChunkRenderersToUpdate = chunkRenderersToUpdate.size();
-        int i1 = 0;
-        for(int i = 0; i < numChunkRenderersToUpdate; i++)
-        {
-            ChunkRenderer chunkRenderer = chunkRenderersToUpdate.get(i);
-            if(chunkRenderer.distanceToCameraSquared(camera) > 256F)
-            {
-                int k2;
-                for(k2 = 0; k2 < numLayers && (chunkRenderers[k2] == null || comparator.compare(chunkRenderers[k2], chunkRenderer) <= 0); k2++) { }
-                if(--k2 <= 0)
-                {
+    public boolean updateRenderers(ICamera camera) {
+        final byte numLayers = 2;
+        final ChunkRendererComparator comparator = new ChunkRendererComparator(camera);
+        final ChunkRenderer[] chunkRenderers = new ChunkRenderer[numLayers];
+        List<ChunkRenderer> rendererList = null;
+        final int numChunkRenderersToUpdate = chunkRenderersToUpdate.size();
+        int renderListSize = 0;
+        for(int i = 0; i < numChunkRenderersToUpdate; i++) {
+            final ChunkRenderer chunkRenderer = chunkRenderersToUpdate.get(i);
+            if(chunkRenderer.distanceToCameraSquared(camera) > 256F) {
+                int layer = 0;
+                while (layer < numLayers && (chunkRenderers[layer] == null || comparator.compare(chunkRenderers[layer], chunkRenderer) <= 0)) {
+                    layer++;
+                }
+                if(--layer <= 0) {
                     continue;
                 }
-                for(int i3 = k2; --i3 != 0;)
-                {
+                for(int i3 = layer; --i3 != 0;) {
                     chunkRenderers[i3 - 1] = chunkRenderers[i3];
                 }
 
-                chunkRenderers[k2] = chunkRenderer;
+                chunkRenderers[layer] = chunkRenderer;
                 continue;
             }
-            if(arraylist == null)
-            {
-                arraylist = new ArrayList<>();
+            if(rendererList == null) {
+                rendererList = new ArrayList<>();
             }
-            i1++;
-            arraylist.add(chunkRenderer);
+            renderListSize++;
+            rendererList.add(chunkRenderer);
             chunkRenderersToUpdate.set(i, null);
         }
 
-        if(arraylist != null)
-        {
-            if(arraylist.size() > 1)
-            {
-                arraylist.sort(comparator);
+        if(rendererList != null) {
+            if(rendererList.size() > 1) {
+                rendererList.sort(comparator);
             }
-            for(int k1 = arraylist.size() - 1; k1 >= 0; k1--)
-            {
-                ChunkRenderer worldrenderer2 = arraylist.get(k1);
-                worldrenderer2.updateRenderer();
-                worldrenderer2.needsUpdate = false;
+            for (ChunkRenderer renderer : rendererList){
+                renderer.updateRenderer();
+                renderer.needsUpdate = false;
             }
-
         }
-        int l1 = 0;
-        for(int i2 = numLayers - 1; i2 >= 0; i2--)
-        {
-            ChunkRenderer worldrenderer3 = chunkRenderers[i2];
-            if(worldrenderer3 == null)
-            {
-                continue;
-            }
-            if(!worldrenderer3.isInFrustum && i2 != numLayers - 1)
-            {
-                chunkRenderers[i2] = null;
-                chunkRenderers[0] = null;
+        int renderersUpdated = 0;
+        for(int layer = numLayers - 1; layer >= 0; layer--) {
+            ChunkRenderer renderer = chunkRenderers[layer];
+            if(renderer == null) { continue; }
+            if(!renderer.isInFrustum && layer != numLayers - 1) {
+                chunkRenderers[layer] = null;
                 break;
             }
-            chunkRenderers[i2].updateRenderer();
-            chunkRenderers[i2].needsUpdate = false;
-            l1++;
+            renderer.updateRenderer();
+            renderer.needsUpdate = false;
+            renderersUpdated++;
         }
 
-        int j2 = 0;
-        int l2 = 0;
-        for(int j3 = chunkRenderersToUpdate.size(); j2 != j3; j2++)
-        {
-            ChunkRenderer worldrenderer4 = chunkRenderersToUpdate.get(j2);
-            if(worldrenderer4 == null)
-            {
-                continue;
-            }
-            boolean flag2 = false;
-            for(int k3 = 0; k3 < numLayers && !flag2; k3++)
-            {
-                if(worldrenderer4 == chunkRenderers[k3])
-                {
-                    flag2 = true;
+        int renderIndex = 0;
+        int setRenders = 0;
+        label1: for (int size = chunkRenderersToUpdate.size(); renderIndex != size; renderIndex++) {
+            final ChunkRenderer renderer = chunkRenderersToUpdate.get(renderIndex);
+            if(renderer == null) { continue; }
+            for(int layer = 0; layer < numLayers; layer++) {
+                if (renderer == chunkRenderers[layer]) {
+                    continue label1;
                 }
             }
 
-            if(flag2)
-            {
-                continue;
+            if(setRenders != renderIndex) {
+                chunkRenderersToUpdate.set(setRenders, renderer);
             }
-            if(l2 != j2)
-            {
-                chunkRenderersToUpdate.set(l2, worldrenderer4);
-            }
-            l2++;
+            setRenders++;
         }
 
-        while(--j2 >= l2) 
-        {
-            chunkRenderersToUpdate.remove(j2);
+        while(--renderIndex >= setRenders) {
+            chunkRenderersToUpdate.remove(renderIndex);
         }
-        return numChunkRenderersToUpdate == i1 + l1;
+        return numChunkRenderersToUpdate == (renderListSize + renderersUpdated);
     }
 
     public void drawBlockBreaking(ICamera camera, HitResult hitResult, float partialTick)
@@ -1466,32 +1438,32 @@ public class RenderGlobal
 		glEnable(GL_FOG);
 	}
 
-    public void drawOutlinedBoundingBox(AABB axisalignedbb)
+    public void drawOutlinedBoundingBox(AABB aabb)
     {
         Tessellator tessellator = Tessellator.instance;
         tessellator.startDrawing(GL11.GL_LINE_STRIP);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ);
-        tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ);
-        tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ);
+        tessellator.addVertex(aabb.minX, aabb.minY, aabb.minZ);
+        tessellator.addVertex(aabb.maxX, aabb.minY, aabb.minZ);
+        tessellator.addVertex(aabb.maxX, aabb.minY, aabb.maxZ);
+        tessellator.addVertex(aabb.minX, aabb.minY, aabb.maxZ);
+        tessellator.addVertex(aabb.minX, aabb.minY, aabb.minZ);
         tessellator.draw();
         tessellator.startDrawing(GL11.GL_LINE_STRIP);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ);
-        tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ);
-        tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ);
+        tessellator.addVertex(aabb.minX, aabb.maxY, aabb.minZ);
+        tessellator.addVertex(aabb.maxX, aabb.maxY, aabb.minZ);
+        tessellator.addVertex(aabb.maxX, aabb.maxY, aabb.maxZ);
+        tessellator.addVertex(aabb.minX, aabb.maxY, aabb.maxZ);
+        tessellator.addVertex(aabb.minX, aabb.maxY, aabb.minZ);
         tessellator.draw();
         tessellator.startDrawing(GL11.GL_LINES);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ);
-        tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ);
-        tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ);
-        tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ);
-        tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ);
-        tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ);
+        tessellator.addVertex(aabb.minX, aabb.minY, aabb.minZ);
+        tessellator.addVertex(aabb.minX, aabb.maxY, aabb.minZ);
+        tessellator.addVertex(aabb.maxX, aabb.minY, aabb.minZ);
+        tessellator.addVertex(aabb.maxX, aabb.maxY, aabb.minZ);
+        tessellator.addVertex(aabb.maxX, aabb.minY, aabb.maxZ);
+        tessellator.addVertex(aabb.maxX, aabb.maxY, aabb.maxZ);
+        tessellator.addVertex(aabb.minX, aabb.minY, aabb.maxZ);
+        tessellator.addVertex(aabb.minX, aabb.maxY, aabb.maxZ);
         tessellator.draw();
     }
 
@@ -1753,8 +1725,8 @@ public class RenderGlobal
 
     public List<TileEntity> tileEntities;
     private World worldObj;
-    private RenderEngine renderEngine;
-    private List<ChunkRenderer> chunkRenderersToUpdate;
+    private final RenderEngine renderEngine;
+    private final List<ChunkRenderer> chunkRenderersToUpdate;
     private ChunkRenderer[] sortedChunkRenderers;
     private ChunkRenderer[] chunkRenderers;
     private int renderChunksWide;
@@ -1793,8 +1765,8 @@ public class RenderGlobal
     private int renderersBeingRendered;
     private int renderersSkippingRenderPass;
     private int worldRenderersCheckIndex;
-    private List<ChunkRenderer> glRenderLists;
-    private DisplayList allDisplayLists[] = {
+    private final List<ChunkRenderer> glRenderLists;
+    private final DisplayList[] allDisplayLists = {
         new DisplayList(), new DisplayList(), new DisplayList(), new DisplayList()
     };
     int dummyInt0;
@@ -1805,7 +1777,7 @@ public class RenderGlobal
     public float damagePartialTime;
     int frustumCheckOffset;
 
-    private float auroraBrightness = 0.0f;
-    private float targetAuroraBrightness = Float.NaN;
-    private float auroraBrightnessDelta = Float.NaN;
+    private double auroraBrightness = 0.0f;
+    private double targetAuroraBrightness = Double.NaN;
+    private double auroraBrightnessDelta = Double.NaN;
 }
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModel.java b/src/main/java/net/minecraft/client/render/block/model/BlockModel.java
index 17d3fca7e..b853530bc 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModel.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModel.java
@@ -6,6 +6,7 @@ import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
+import org.jetbrains.annotations.Nullable;
 
 public abstract class BlockModel<T extends Block>
 {
@@ -28,10 +29,10 @@ public abstract class BlockModel<T extends Block>
         renderBlocks.overrideBlockTexture = null;
         return result;
     }
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness){
-        renderBlockOnInventory(tessellator, metadata, brightness, 1f);
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, @Nullable Integer lightmapCoordinate){
+        renderBlockOnInventory(tessellator, metadata, brightness, 1f, lightmapCoordinate);
     }
-    public abstract void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha);
+    public abstract void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate);
     public abstract boolean shouldItemRender3d();
     public abstract float getItemRenderScale();
 
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java
index 5b78751a1..5c36b7387 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java
@@ -1,14 +1,13 @@
 package net.minecraft.client.render.block.model;
 
-import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockBrazier;
-import net.minecraft.core.block.BlockFire;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelBrazier<T extends BlockBrazier>
@@ -28,15 +27,19 @@ public class BlockModelBrazier<T extends BlockBrazier>
         renderBlocks.enableAO = true;
         renderBlocks.cache.setupCache(block, renderBlocks.blockAccess, x, y, z);
         renderSide(tessellator, block, x, y, z, Side.NORTH, 0);
-        renderSide(tessellator, block, x, y, z + 1, Side.NORTH, 0);
         renderSide(tessellator, block, x, y, z, Side.SOUTH, 0);
-        renderSide(tessellator, block, x, y, z - 1, Side.SOUTH, 0);
         renderSide(tessellator, block, x, y, z, Side.EAST, 0);
-        renderSide(tessellator, block, x - 1, y, z, Side.EAST, 0);
         renderSide(tessellator, block, x, y, z, Side.WEST, 0);
-        renderSide(tessellator, block, x + 1, y, z, Side.WEST, 0);
         renderSide(tessellator, block, x, y, z, Side.BOTTOM, 0);
+
+        final double zFightOffset = 0.005;
+        block.setBlockBounds(-zFightOffset, -zFightOffset, -zFightOffset, 1 + zFightOffset, 1 + zFightOffset, 1 + zFightOffset);
+        renderSide(tessellator, block, x, y, z + 1, Side.NORTH, 0);
+        renderSide(tessellator, block, x, y, z - 1, Side.SOUTH, 0);
+        renderSide(tessellator, block, x - 1, y, z, Side.EAST, 0);
+        renderSide(tessellator, block, x + 1, y, z, Side.WEST, 0);
         renderSide(tessellator, block, x, y - 1, z, Side.TOP, 0);
+        block.setBlockBounds(0, 0, 0, 1, 1, 1);
         renderBlocks.enableAO = false;
 
         if (block.isBurning()) {
@@ -47,7 +50,7 @@ public class BlockModelBrazier<T extends BlockBrazier>
     }
 
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
 
         GL11.glColor4f(brightness, brightness, brightness, alpha);
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelCacaoLeaves.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelCacaoLeaves.java
index eb08896bf..d962fb936 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelCacaoLeaves.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelCacaoLeaves.java
@@ -5,6 +5,7 @@ import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelCacaoLeaves<T extends Block> extends BlockModelLeaves<T>{
@@ -52,8 +53,8 @@ public class BlockModelCacaoLeaves<T extends Block> extends BlockModelLeaves<T>{
         return true;
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
-        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha);
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
+        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha, lightmapCoordinate);
         GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
 
         final IconCoordinate cacaoCoord = growthStages[3];
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelCactus.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelCactus.java
index bbe0fd74f..17b00a8bc 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelCactus.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelCactus.java
@@ -4,6 +4,7 @@ import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.util.helper.Side;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelCactus<T extends Block> extends BlockModelStandard<T> {
@@ -33,7 +34,7 @@ public class BlockModelCactus<T extends Block> extends BlockModelStandard<T> {
         return true;
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha){
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate){
         if(renderBlocks.useInventoryTint)
         {
             int color = BlockColorDispatcher.getInstance().getDispatch(block).getFallbackColor(metadata);
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelCherryLeavesBloom.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelCherryLeavesBloom.java
index 672c2bac6..b58434ea2 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelCherryLeavesBloom.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelCherryLeavesBloom.java
@@ -4,6 +4,7 @@ import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelCherryLeavesBloom<T extends Block> extends BlockModelLeaves<T> {
@@ -30,8 +31,8 @@ public class BlockModelCherryLeavesBloom<T extends Block> extends BlockModelLeav
         return true;
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
-        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha);
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
+        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha, lightmapCoordinate);
         GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
 
         IconCoordinate cherryCoord = grownCherryOverlay;
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelCrossedSquares.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelCrossedSquares.java
index ac52c4e53..7fe1d29b6 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelCrossedSquares.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelCrossedSquares.java
@@ -6,6 +6,7 @@ import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.util.helper.Side;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelCrossedSquares<T extends Block> extends BlockModelStandard<T> {
@@ -13,17 +14,21 @@ public class BlockModelCrossedSquares<T extends Block> extends BlockModelStandar
         super(block);
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
+        if (LightmapHelper.isLightmapEnabled()){
+            brightness = 1f;
+        }
+        float r = 1f;
+        float g = 1f;
+        float b = 1f;
         // Used for the rendering for the block inside the jar
+        GL11.glColor4f(1f, 1f, 1f,1f);
         if(renderBlocks.useInventoryTint)
         {
             int color = BlockColorDispatcher.getInstance().getDispatch(block).getFallbackColor(metadata);
-            float r = (float)(color >> 16 & 0xff) / 255F;
-            float g = (float)(color >> 8 & 0xff) / 255F;
-            float b = (float)(color & 0xff) / 255F;
-            GL11.glColor4f(r * brightness, g * brightness, b * brightness, alpha);
-        } else {
-            GL11.glColor4f(brightness, brightness, brightness, alpha);
+             r = (float)(color >> 16 & 0xff) / 255F;
+             g = (float)(color >> 8 & 0xff) / 255F;
+             b = (float)(color & 0xff) / 255F;
         }
         final float yOffset = 0.0F;
 
@@ -41,7 +46,11 @@ public class BlockModelCrossedSquares<T extends Block> extends BlockModelStandar
         final double maxV = texIndex.getIconVMax();
 
         tessellator.startDrawingQuads();
-        tessellator.setNormal(1.0F, 0.0F, 1.0F);
+        tessellator.setColorOpaque_F(r * brightness, g * brightness, b * brightness);
+        tessellator.setNormal(0.0F, 1.0F, 0.0F);
+        if (LightmapHelper.isLightmapEnabled() && lightmapCoordinate != null){
+            tessellator.setLightmapCoord(lightmapCoordinate);
+        }
 
         double xd = 0;
         double yd = 0;
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
index 8598ae8a2..6e4db5802 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
@@ -294,7 +294,7 @@ public class BlockModelDispatcher
         addDispatch(new BlockModelMotionSensor(Block.motionsensorActive).withTextures("minecraft:block/motionsensor_side", "minecraft:block/motionsensor_side", "minecraft:block/motionsensor_active_front", "minecraft:block/motionsensor_side", "minecraft:block/motionsensor_side", "minecraft:block/motionsensor_side"));
 
         addDispatch(new BlockModelRepeater(Block.repeaterIdle).withTextures("minecraft:block/repeater_idle_top", "minecraft:block/polished_stone_top"));
-        addDispatch(new BlockModelRepeater(Block.repeaterActive).withTextures("minecraft:block/repeater_active_top", "minecraft:block/polished_stone_top"));
+        addDispatch(new BlockModelRepeater(Block.repeaterActive).withTextures("minecraft:block/repeater_active_top", "minecraft:block/polished_stone_top").withOverbrightTexture("minecraft:block/repeater_active_overlay"));
 
         addDispatch(new BlockModelPiston<>(Block.pistonBase, TextureRegistry.getTexture("minecraft:block/piston_face")).withTextures("minecraft:block/piston_face").withCustomItemBounds(0,0,0,1,1,1));
         addDispatch(new BlockModelPiston<>(Block.pistonBaseSticky,TextureRegistry.getTexture("minecraft:block/piston_face_sticky")).withTextures("minecraft:block/piston_face_sticky").withCustomItemBounds(0,0,0,1,1,1));
@@ -367,7 +367,7 @@ public class BlockModelDispatcher
 
         addDispatch(new BlockModelLayer<>(Block.layerSnow).withTextures("minecraft:block/block_snow"));
         addDispatch(new BlockModelLayer<>(Block.layerLeavesOak).withTextures("minecraft:block/leaves_oak_fancy"));
-        addDispatch(new BlockModelLayer<>(Block.layerSlate).withTextures("minecraft:block/slate_top"));
+        addDispatch(new BlockModelLayer<>(Block.layerSlate).withTextures("minecraft:block/slate_top", "minecraft:block/slate_side"));
 
         addDispatch(new BlockModelIce<>(Block.ice).withTextures("minecraft:block/ice"));
         addDispatch(new BlockModelStandard<>(Block.permaice).withTextures("minecraft:block/permaice"));
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelEmpty.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelEmpty.java
index 04b2aace3..826772431 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelEmpty.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelEmpty.java
@@ -2,6 +2,7 @@ package net.minecraft.client.render.block.model;
 
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
+import org.jetbrains.annotations.Nullable;
 
 public class BlockModelEmpty extends BlockModelStandard<Block> {
     public BlockModelEmpty(Block block) {
@@ -14,7 +15,7 @@ public class BlockModelEmpty extends BlockModelStandard<Block> {
     }
 
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
 
     }
 
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelFence.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelFence.java
index 42336c355..4829a7b28 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelFence.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelFence.java
@@ -5,6 +5,7 @@ import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockFence;
 import net.minecraft.core.util.helper.Side;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelFence<T  extends BlockFence> extends BlockModelStandard<T> {
@@ -73,7 +74,7 @@ public class BlockModelFence<T  extends BlockFence> extends BlockModelStandard<T
     }
 
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         if(renderBlocks.useInventoryTint)
         {
             int color = BlockColorDispatcher.getInstance().getDispatch(block).getFallbackColor(metadata);
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceGate.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceGate.java
index f40e58a29..2c249770e 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceGate.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceGate.java
@@ -5,6 +5,7 @@ import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockFenceGate;
 import net.minecraft.core.util.helper.Side;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelFenceGate<T extends BlockFenceGate> extends BlockModelStandard<T>{
@@ -161,7 +162,7 @@ public class BlockModelFenceGate<T extends BlockFenceGate> extends BlockModelSta
     }
 
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         if(renderBlocks.useInventoryTint)
         {
             int j = BlockColorDispatcher.getInstance().getDispatch(block).getFallbackColor(metadata);
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceThin.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceThin.java
index 13376b781..8e5fbf685 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceThin.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceThin.java
@@ -8,6 +8,7 @@ import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockFenceThin;
 import net.minecraft.core.util.helper.Direction;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelFenceThin<T extends BlockFenceThin> extends BlockModelStandard<T> {
@@ -349,7 +350,7 @@ public class BlockModelFenceThin<T extends BlockFenceThin> extends BlockModelSta
     }
 
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         if(renderBlocks.useInventoryTint)
         {
             int j = BlockColorDispatcher.getInstance().getDispatch(block).getFallbackColor(metadata);
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
index 623b345f9..2f74fbfb6 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
@@ -46,10 +46,10 @@ public class BlockModelFluid<T extends Block> extends BlockModelStandard<T> {
         final float yOff = 0.001f;
         Material material = block.blockMaterial;
         int meta = renderBlocks.blockAccess.getBlockMetadata(x, y, z);
-        float f7 = func_1224_a(x, y, z, material);
-        float f8 = func_1224_a(x, y, z + 1, material);
-        float f9 = func_1224_a(x + 1, y, z + 1, material);
-        float f10 = func_1224_a(x + 1, y, z, material);
+        float f7 = BlockFluid.getFluidHeight(renderBlocks.blockAccess, x, y, z, material);
+        float f8 = BlockFluid.getFluidHeight(renderBlocks.blockAccess, x, y, z + 1, material);
+        float f9 = BlockFluid.getFluidHeight(renderBlocks.blockAccess, x + 1, y, z + 1, material);
+        float f10 = BlockFluid.getFluidHeight(renderBlocks.blockAccess, x + 1, y, z, material);
         if(renderBlocks.renderAllFaces || renderTop)
         {
             didRender = true;
@@ -75,10 +75,12 @@ public class BlockModelFluid<T extends Block> extends BlockModelStandard<T> {
                 double centerV = texture.getSubIconV(0.5);
                 float cSin = MathHelper.cos(rotation)/2;
                 float sin = MathHelper.sin(rotation)/2;
+
                 double minU = texture.getIconUMin();
                 double maxU = texture.getIconUMax();
                 double minV = texture.getIconVMin();
                 double maxV = texture.getIconVMax();
+
                 tessellator.setColorOpaque_F(sideTop * blockBrightness * r, sideTop * blockBrightness * g, sideTop * blockBrightness * b);
                 tessellator.addVertexWithUV(x,      (float)y + f7,      z,      ((minU - centerU) * sin - (maxV - centerV) * cSin) + centerU, ((maxV - centerV) * sin + (minU - centerU) * cSin) + centerV);
                 tessellator.addVertexWithUV(x,      (float)y + f8,      z + 1,  ((maxU - centerU) * sin - (maxV - centerV) * cSin) + centerU, ((maxV - centerV) * sin + (maxU - centerU) * cSin) + centerV);
@@ -208,40 +210,7 @@ public class BlockModelFluid<T extends Block> extends BlockModelStandard<T> {
         block.maxY = d1;
         return didRender;
     }
-    private float func_1224_a(int i, int j, int k, Material material)
-    {
-        int l = 0;
-        float f = 0.0F;
-        for(int i1 = 0; i1 < 4; i1++)
-        {
-            int j1 = i - (i1 & 1);
-            int l1 = k - (i1 >> 1 & 1);
-            if(renderBlocks.blockAccess.getBlockMaterial(j1, j + 1, l1) == material)
-            {
-                return 1.0F;
-            }
-            Material material1 = renderBlocks.blockAccess.getBlockMaterial(j1, j, l1);
-            if(material1 == material)
-            {
-                int i2 = renderBlocks.blockAccess.getBlockMetadata(j1, j, l1);
-                if(i2 >= 8 || i2 == 0)
-                {
-                    f += BlockFluid.getWaterVolume(i2) * 10F;
-                    l += 10;
-                }
-                f += BlockFluid.getWaterVolume(i2);
-                l++;
-                continue;
-            }
-            if(!material1.isSolid())
-            {
-                f++;
-                l++;
-            }
-        }
 
-        return Math.max(1.0F - f / (float)l, 0.015F);
-    }
     @Override
     public boolean shouldItemRender3d() {
         return false;
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelGrass.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelGrass.java
index 6f6a4cb97..dc0ae1411 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelGrass.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelGrass.java
@@ -10,6 +10,7 @@ import net.minecraft.core.block.material.Material;
 import net.minecraft.core.util.helper.Axis;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelGrass<T extends Block> extends BlockModelStandard<T> {
@@ -37,7 +38,7 @@ public class BlockModelGrass<T extends Block> extends BlockModelStandard<T> {
         return didRender;
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         GL11.glColor4f(brightness, brightness, brightness, alpha);
         float yOffset = 0.5F;
         setBlockBoundsForItemRender();
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelLayer.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelLayer.java
index d7b279161..f6719d342 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelLayer.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelLayer.java
@@ -3,6 +3,7 @@ package net.minecraft.client.render.block.model;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.world.WorldSource;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelLayer<T extends Block> extends BlockModelStandard<T> {
@@ -11,9 +12,9 @@ public class BlockModelLayer<T extends Block> extends BlockModelStandard<T> {
         withCustomItemBounds(0.0f, 0.0f, 0.0f, 1.0f, 2 / 16F, 1.0f);
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         GL11.glTranslatef(0, 0.25f, 0);
-        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha);
+        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha, lightmapCoordinate);
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesOverlay.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesOverlay.java
index f09d8063e..6e13d8f7e 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesOverlay.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesOverlay.java
@@ -4,6 +4,7 @@ import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelLeavesOverlay<T extends Block> extends BlockModelLeaves<T> {
@@ -24,8 +25,8 @@ public class BlockModelLeavesOverlay<T extends Block> extends BlockModelLeaves<T
         return true;
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
-        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha);
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
+        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha, lightmapCoordinate);
         GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
 
         IconCoordinate overlayCoord = overlayTexture;
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelMossyStone.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelMossyStone.java
index 6f847043b..055ae05f5 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelMossyStone.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelMossyStone.java
@@ -5,6 +5,7 @@ import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.core.block.Block;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelMossyStone<T extends Block> extends BlockModelStandard<T> {
@@ -25,9 +26,9 @@ public class BlockModelMossyStone<T extends Block> extends BlockModelStandard<T>
     }
 
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         renderBlocks.useInventoryTint = false;
-        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha);
+        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha, lightmapCoordinate);
         renderBlocks.useInventoryTint = true;
         GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
 
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelPiston.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelPiston.java
index dc1e861c9..dff191a91 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelPiston.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelPiston.java
@@ -7,6 +7,7 @@ import net.minecraft.core.block.Block;
 import net.minecraft.core.block.logic.PistonDirections;
 import net.minecraft.core.block.piston.BlockPistonBase;
 import net.minecraft.core.util.helper.Side;
+import org.jetbrains.annotations.Nullable;
 
 public class BlockModelPiston<T extends BlockPistonBase> extends BlockModelStandard<T> {
     private final IconCoordinate faceTexture;
@@ -125,8 +126,8 @@ public class BlockModelPiston<T extends BlockPistonBase> extends BlockModelStand
         return true;
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
-        super.renderBlockOnInventory(tessellator, 1, brightness, alpha);
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
+        super.renderBlockOnInventory(tessellator, 1, brightness, alpha, lightmapCoordinate);
     }
     public IconCoordinate getFaceTexture()
     {
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelRedstoneWire.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelRedstoneWire.java
index 1629d22ae..8158b9bfb 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelRedstoneWire.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelRedstoneWire.java
@@ -7,6 +7,7 @@ import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.client.util.helper.Colors;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockRedstoneWire;
+import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.util.helper.Color;
 
 public class BlockModelRedstoneWire<T extends Block> extends BlockModelStandard<T>{
@@ -27,16 +28,18 @@ public class BlockModelRedstoneWire<T extends Block> extends BlockModelStandard<
         }
         float brightness = 1.0f;
         if(LightmapHelper.isLightmapEnabled()) {
-            int lmc = block.getLightmapCoord(renderBlocks.blockAccess, x, y, z);
-            if(Block.lightEmission[block.id] > 0) {
-                lmc = LightmapHelper.setBlocklightValue(lmc, 15);
-            }
+//            int lmc = block.getLightmapCoord(renderBlocks.blockAccess, x, y, z);
+//            if(Block.lightEmission[block.id] > 0) {
+//                lmc = LightmapHelper.setBlocklightValue(lmc, 15);
+//            }
+            int lmc = LightmapHelper.getLightmapCoord(renderBlocks.blockAccess.getSavedLightValue(LightLayer.Sky, x, y, z), Math.max(renderBlocks.blockAccess.getSavedLightValue(LightLayer.Block, x, y, z), meta & 0xF));
             tessellator.setLightmapCoord(lmc);
         }else {
             brightness = getBlockBrightness(renderBlocks.blockAccess, x, y, z);
             if(Block.lightEmission[block.id] > 0) {
                 brightness = 1.0f;
             }
+            brightness = Math.max(brightness, (meta & 0xF)/16f);
         }
         tessellator.setColorOpaque_F(brightness, brightness, brightness);
 
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelRepeater.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelRepeater.java
index 238cb4581..961c61704 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelRepeater.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelRepeater.java
@@ -41,6 +41,7 @@ public class BlockModelRepeater extends BlockModelStandard<BlockRedstoneRepeater
 
         int j1 = (meta & 0xc) >> 2;
         renderStandardBlock(tessellator, block, x, y, z);
+        resetRenderBlocks();
         float brightness = 1.0f;
         if(LightmapHelper.isLightmapEnabled()) {
         	int lmc = block.getLightmapCoord(renderBlocks.blockAccess, x, y, z);
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelStairs.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelStairs.java
index cd7ed3bd2..ad79f2713 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelStairs.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelStairs.java
@@ -7,6 +7,7 @@ import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockStairs;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelStairs<T extends BlockStairs> extends BlockModelStandard<T> {
@@ -55,7 +56,7 @@ public class BlockModelStairs<T extends BlockStairs> extends BlockModelStandard<
     }
 
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         if(renderBlocks.useInventoryTint)
         {
             int j = BlockColorDispatcher.getInstance().getDispatch(block).getFallbackColor(metadata);
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java
index eb14593e3..d55d6fa2f 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java
@@ -1,13 +1,14 @@
 package net.minecraft.client.render.block.model;
 
+import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
-import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelStandard<T extends Block> extends BlockModel<T>{
@@ -28,7 +29,7 @@ public class BlockModelStandard<T extends Block> extends BlockModel<T>{
     }
 
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         if(renderBlocks.useInventoryTint)
         {
             int color = BlockColorDispatcher.getInstance().getDispatch(block).getFallbackColor(metadata);
@@ -40,36 +41,54 @@ public class BlockModelStandard<T extends Block> extends BlockModel<T>{
             GL11.glColor4f(brightness, brightness, brightness, alpha);
         }
         float yOffset = 0.5F;
-        
+
         setBlockBoundsForItemRender();
         GL11.glTranslatef(-0.5F, 0.0F - yOffset, -0.5F);
 
         tessellator.startDrawingQuads();
+        if (LightmapHelper.isLightmapEnabled() && lightmapCoordinate != null){
+            tessellator.setLightmapCoord(lightmapCoordinate);
+        }
         tessellator.setNormal(0.0F, -1F, 0.0F);
         renderBottomFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.BOTTOM, metadata));
         tessellator.draw();
 
         tessellator.startDrawingQuads();
+        if (LightmapHelper.isLightmapEnabled() && lightmapCoordinate != null){
+            tessellator.setLightmapCoord(lightmapCoordinate);
+        }
         tessellator.setNormal(0.0F, 1.0F, 0.0F);
         renderTopFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.TOP, metadata));
         tessellator.draw();
 
         tessellator.startDrawingQuads();
+        if (LightmapHelper.isLightmapEnabled() && lightmapCoordinate != null){
+            tessellator.setLightmapCoord(lightmapCoordinate);
+        }
         tessellator.setNormal(0.0F, 0.0F, -1F);
         renderNorthFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.NORTH, metadata));
         tessellator.draw();
 
         tessellator.startDrawingQuads();
+        if (LightmapHelper.isLightmapEnabled() && lightmapCoordinate != null){
+            tessellator.setLightmapCoord(lightmapCoordinate);
+        }
         tessellator.setNormal(0.0F, 0.0F, 1.0F);
         renderSouthFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.SOUTH, metadata));
         tessellator.draw();
 
         tessellator.startDrawingQuads();
+        if (LightmapHelper.isLightmapEnabled() && lightmapCoordinate != null){
+            tessellator.setLightmapCoord(lightmapCoordinate);
+        }
         tessellator.setNormal(-1F, 0.0F, 0.0F);
         renderWestFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.WEST, metadata));
         tessellator.draw();
 
         tessellator.startDrawingQuads();
+        if (LightmapHelper.isLightmapEnabled() && lightmapCoordinate != null){
+            tessellator.setLightmapCoord(lightmapCoordinate);
+        }
         tessellator.setNormal(1.0F, 0.0F, 0.0F);
         renderEastFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.EAST, metadata));
         tessellator.draw();
@@ -87,32 +106,55 @@ public class BlockModelStandard<T extends Block> extends BlockModel<T>{
                 GL11.glColor4f(brightness, brightness, brightness, alpha);
             }
 
+            int overbrightLMC = 0;
+            if (LightmapHelper.isLightmapEnabled()){
+                overbrightLMC = LightmapHelper.getLightmapCoord(15, 15);
+            }
+
             tessellator.startDrawingQuads();
+            if (LightmapHelper.isLightmapEnabled()){
+                tessellator.setLightmapCoord(overbrightLMC);
+            }
             tessellator.setNormal(0.0F, -1F, 0.0F);
             renderBottomFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockOverbrightTextureFromSideAndMeta(Side.BOTTOM, metadata));
             tessellator.draw();
 
             tessellator.startDrawingQuads();
+            if (LightmapHelper.isLightmapEnabled()){
+                tessellator.setLightmapCoord(overbrightLMC);
+            }
             tessellator.setNormal(0.0F, 1.0F, 0.0F);
             renderTopFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockOverbrightTextureFromSideAndMeta(Side.TOP, metadata));
             tessellator.draw();
 
             tessellator.startDrawingQuads();
+            if (LightmapHelper.isLightmapEnabled()){
+                tessellator.setLightmapCoord(overbrightLMC);
+            }
             tessellator.setNormal(0.0F, 0.0F, -1F);
             renderNorthFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockOverbrightTextureFromSideAndMeta(Side.NORTH, metadata));
             tessellator.draw();
 
             tessellator.startDrawingQuads();
+            if (LightmapHelper.isLightmapEnabled()){
+                tessellator.setLightmapCoord(overbrightLMC);
+            }
             tessellator.setNormal(0.0F, 0.0F, 1.0F);
             renderSouthFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockOverbrightTextureFromSideAndMeta(Side.SOUTH, metadata));
             tessellator.draw();
 
             tessellator.startDrawingQuads();
+            if (LightmapHelper.isLightmapEnabled()){
+                tessellator.setLightmapCoord(overbrightLMC);
+            }
             tessellator.setNormal(-1F, 0.0F, 0.0F);
             renderWestFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockOverbrightTextureFromSideAndMeta(Side.WEST, metadata));
             tessellator.draw();
 
             tessellator.startDrawingQuads();
+            if (LightmapHelper.isLightmapEnabled()){
+                tessellator.setLightmapCoord(overbrightLMC);
+            }
             tessellator.setNormal(1.0F, 0.0F, 0.0F);
             renderEastFace(tessellator, block, 0.0D, 0.0D, 0.0D, getBlockOverbrightTextureFromSideAndMeta(Side.EAST, metadata));
             tessellator.draw();
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoor.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoor.java
index 882e13fda..915854edd 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoor.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoor.java
@@ -7,6 +7,7 @@ import net.minecraft.core.block.BlockTrapDoor;
 import net.minecraft.core.util.helper.Axis;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.util.helper.Sides;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.opengl.GL11;
 
 public class BlockModelTrapDoor<T extends Block> extends BlockModelStandard<T> {
@@ -66,9 +67,9 @@ public class BlockModelTrapDoor<T extends Block> extends BlockModelStandard<T> {
         return true;
     }
     @Override
-    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha) {
+    public void renderBlockOnInventory(Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
         GL11.glTranslatef(0, 0.25f, 0);
-        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha);
+        super.renderBlockOnInventory(tessellator, metadata, brightness, alpha, lightmapCoordinate);
     }
     @Override
     public IconCoordinate getBlockTextureFromSideAndMetadata(Side side, int data)
diff --git a/src/main/java/net/minecraft/client/render/entity/ItemEntityRenderer.java b/src/main/java/net/minecraft/client/render/entity/ItemEntityRenderer.java
index db48e8bd4..fc9f9db3f 100644
--- a/src/main/java/net/minecraft/client/render/entity/ItemEntityRenderer.java
+++ b/src/main/java/net/minecraft/client/render/entity/ItemEntityRenderer.java
@@ -76,8 +76,10 @@ public class ItemEntityRenderer extends EntityRenderer<EntityItem>
 		}
 		GL11.glTranslatef((float) x, (float) y + bobbingOffset, (float) z);
 		GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/);
+		GL11.glEnable(GL11.GL_BLEND);
 		BlockModel.setRenderBlocks(renderBlocks);
 		ItemModelDispatcher.getInstance().getDispatch(item).renderAsItemEntity(Tessellator.instance, entity, random, itemstack, renderCount, f3, brightness, partialTick);
+		GL11.glDisable(GL11.GL_BLEND);
 		GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/);
 		GL11.glPopMatrix();
 	}
diff --git a/src/main/java/net/minecraft/client/render/entity/MinecartRenderer.java b/src/main/java/net/minecraft/client/render/entity/MinecartRenderer.java
index 44245ffee..1e97d4b8f 100644
--- a/src/main/java/net/minecraft/client/render/entity/MinecartRenderer.java
+++ b/src/main/java/net/minecraft/client/render/entity/MinecartRenderer.java
@@ -1,6 +1,5 @@
 package net.minecraft.client.render.entity;
 
-import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.model.ModelBase;
@@ -93,17 +92,17 @@ public class MinecartRenderer extends EntityRenderer<EntityMinecart>
             }
             if(minecart.minecartType == 1)
             {
-                BlockModelDispatcher.getInstance().getDispatch(Block.chestPlanksOak).renderBlockOnInventory(tessellator, 0, brightness);
+                BlockModelDispatcher.getInstance().getDispatch(Block.chestPlanksOak).renderBlockOnInventory(tessellator, 0, brightness, null);
             } else
             if(minecart.minecartType == 2)
             {
                 if (minecart.fuel > 0)
                 {
-                    BlockModelDispatcher.getInstance().getDispatch(Block.furnaceStoneActive).renderBlockOnInventory(tessellator, 0, brightness);
+                    BlockModelDispatcher.getInstance().getDispatch(Block.furnaceStoneActive).renderBlockOnInventory(tessellator, 0, brightness, null);
                 }
                 else
                 {
-                    BlockModelDispatcher.getInstance().getDispatch(Block.furnaceStoneIdle).renderBlockOnInventory(tessellator, 0, brightness);
+                    BlockModelDispatcher.getInstance().getDispatch(Block.furnaceStoneIdle).renderBlockOnInventory(tessellator, 0, brightness, null);
                 }
             }
             GL11.glRotatef(-90F, 0.0F, 1.0F, 0.0F);
diff --git a/src/main/java/net/minecraft/client/render/entity/MobRenderer.java b/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
index e597567db..160f35626 100644
--- a/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
+++ b/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.render.entity;
 
+import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.item.model.ItemModelDispatcher;
 import net.minecraft.client.render.model.ModelBiped;
 import net.minecraft.client.render.tessellator.Tessellator;
diff --git a/src/main/java/net/minecraft/client/render/entity/SpiderRenderer.java b/src/main/java/net/minecraft/client/render/entity/SpiderRenderer.java
index 67517ddd6..a00bd7d1b 100644
--- a/src/main/java/net/minecraft/client/render/entity/SpiderRenderer.java
+++ b/src/main/java/net/minecraft/client/render/entity/SpiderRenderer.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.entity;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.model.ModelSpider;
 import net.minecraft.core.Global;
 import net.minecraft.core.entity.monster.EntitySpider;
@@ -30,7 +31,9 @@ public class SpiderRenderer extends LivingRenderer<EntitySpider>
             boolean useVariants = Minecraft.getMinecraft(this).gameSettings.mobVariants.value;
             loadTexture("/assets/minecraft/textures/entity/spider/eyes/" + (useVariants ? spider.getSkinVariant() : 0) + ".png");
             float brightness = spider.getBrightness(1.0f);
-            if (Global.accessor.isFullbrightEnabled()) brightness = 1.0f;
+            if(LightmapHelper.isLightmapEnabled()) {
+                LightmapHelper.setLightmapCoord(LightmapHelper.getLightmapCoord(15, 15));
+            }
             float f1 = (1.0F - brightness) * 0.5F;
             GL11.glEnable(3042 /*GL_BLEND*/);
             GL11.glDisable(3008 /*GL_ALPHA_TEST*/);
@@ -49,8 +52,7 @@ public class SpiderRenderer extends LivingRenderer<EntitySpider>
     }
 
     @Override
-    protected boolean shouldRenderPass(EntitySpider entity, int renderPass, float partialTick)
-    {
+    protected boolean shouldRenderPass(EntitySpider entity, int renderPass, float partialTick) {
         return setSpiderEyeBrightness(entity, renderPass, partialTick);
     }
 }
diff --git a/src/main/java/net/minecraft/client/render/entity/TNTRenderer.java b/src/main/java/net/minecraft/client/render/entity/TNTRenderer.java
index 2c2184232..4503ceba7 100644
--- a/src/main/java/net/minecraft/client/render/entity/TNTRenderer.java
+++ b/src/main/java/net/minecraft/client/render/entity/TNTRenderer.java
@@ -1,6 +1,5 @@
 package net.minecraft.client.render.entity;
 
-import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.RenderBlocks;
 import net.minecraft.client.render.block.model.BlockModel;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
@@ -51,7 +50,7 @@ public class TNTRenderer extends EntityRenderer<EntityTNT>
         float brightness = tnt.getBrightness(f1);
         if (Global.accessor.isFullbrightEnabled()) brightness = 1.0f;
         BlockModel<Block> model = BlockModelDispatcher.getInstance().getDispatch(Block.tnt);
-        model.renderBlockOnInventory(tessellator, 0, brightness);
+        model.renderBlockOnInventory(tessellator, 0, brightness, null);
         if((tnt.fuse / 5) % 2 == 0)
         {
             GL11.glDisable(3553 /*GL_TEXTURE_2D*/);
@@ -59,7 +58,7 @@ public class TNTRenderer extends EntityRenderer<EntityTNT>
             GL11.glEnable(3042 /*GL_BLEND*/);
             GL11.glBlendFunc(770, 772);
             GL11.glColor4f(1.0F, 1.0F, 1.0F, f3);
-            model.renderBlockOnInventory(tessellator, 0, 1.0F);
+            model.renderBlockOnInventory(tessellator, 0, 1.0F, null);
             GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             GL11.glDisable(3042 /*GL_BLEND*/);
             GL11.glEnable(2896 /*GL_LIGHTING*/);
diff --git a/src/main/java/net/minecraft/client/render/item/model/ItemModelBlock.java b/src/main/java/net/minecraft/client/render/item/model/ItemModelBlock.java
index 0c15f018a..dd0d26edd 100644
--- a/src/main/java/net/minecraft/client/render/item/model/ItemModelBlock.java
+++ b/src/main/java/net/minecraft/client/render/item/model/ItemModelBlock.java
@@ -81,7 +81,7 @@ public class ItemModelBlock extends ItemModelStandard {
             GL11.glEnable(GL_BLEND);
             GL11.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
             TextureRegistry.blockAtlas.bindTexture();
-            BlockModelDispatcher.getInstance().getDispatch(Block.blocksList[itemstack.itemID]).renderBlockOnInventory(tessellator, itemstack.getMetadata(), brightness);
+            BlockModelDispatcher.getInstance().getDispatch(Block.blocksList[itemstack.itemID]).renderBlockOnInventory(tessellator, itemstack.getMetadata(), brightness, null);
             GL11.glDisable(GL_BLEND);
         } else {
             super.renderItem(tessellator, renderer, itemstack, entity, brightness, handheldTransform);
@@ -126,7 +126,7 @@ public class ItemModelBlock extends ItemModelStandard {
             }
             GL11.glRotatef(-90F, 0.0F, 1.0F, 0.0F);
             BlockModel.renderBlocks.useInventoryTint = useColor;
-            BlockModelDispatcher.getInstance().getDispatch(Block.blocksList[itemStack.itemID]).renderBlockOnInventory(tessellator, itemStack.getMetadata(), brightness, alpha);
+            BlockModelDispatcher.getInstance().getDispatch(Block.blocksList[itemStack.itemID]).renderBlockOnInventory(tessellator, itemStack.getMetadata(), brightness, alpha, null);
             BlockModel.renderBlocks.useInventoryTint = true;
             GL11.glPopMatrix();
         } else {
@@ -158,7 +158,7 @@ public class ItemModelBlock extends ItemModelStandard {
                 if (Global.accessor.isFullbrightEnabled() || itemfullBright) {
                 	brightness = 1.0f;
                 }
-                blockModel.renderBlockOnInventory(tessellator, itemstack.getMetadata(), brightness);
+                blockModel.renderBlockOnInventory(tessellator, itemstack.getMetadata(), brightness, null);
                 GL11.glPopMatrix();
             }
         } else {
@@ -186,7 +186,7 @@ public class ItemModelBlock extends ItemModelStandard {
             }
             GL11.glRotatef(90F, 0.0F, 1.0F, 0.0F);
             BlockModel.renderBlocks.useInventoryTint = useColor;
-            BlockModelDispatcher.getInstance().getDispatch(Block.blocksList[itemStack.itemID]).renderBlockOnInventory(tessellator, itemStack.getMetadata(), brightness, alpha);
+            BlockModelDispatcher.getInstance().getDispatch(Block.blocksList[itemStack.itemID]).renderBlockOnInventory(tessellator, itemStack.getMetadata(), brightness, alpha, null);
             BlockModel.renderBlocks.useInventoryTint = true;
         } else {
             super.renderItemInWorld(tessellator, entity, itemStack, brightness, alpha, worldTransform);
diff --git a/src/main/java/net/minecraft/client/render/item/model/ItemModelStandard.java b/src/main/java/net/minecraft/client/render/item/model/ItemModelStandard.java
index fb521806d..b14ac8af0 100644
--- a/src/main/java/net/minecraft/client/render/item/model/ItemModelStandard.java
+++ b/src/main/java/net/minecraft/client/render/item/model/ItemModelStandard.java
@@ -118,7 +118,7 @@ public class ItemModelStandard extends ItemModel{
         	if(LightmapHelper.isLightmapEnabled()) {
             	int lightmapCoord = entity.getLightmapCoord(1.0f);
             	if(itemfullBright) {
-            		lightmapCoord = LightmapHelper.setBlocklightValue(lightmapCoord, 15);
+            		lightmapCoord = LightmapHelper.getLightmapCoord(15, 15);
             	}
             	LightmapHelper.setLightmapCoord(lightmapCoord);	
         	}
diff --git a/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererFlowerJar.java b/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererFlowerJar.java
index cc2457508..46cf8a00b 100644
--- a/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererFlowerJar.java
+++ b/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererFlowerJar.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.tileentity;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.RenderBlocks;
 import net.minecraft.client.render.block.model.BlockModel;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
@@ -9,6 +10,7 @@ import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.Global;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.entity.TileEntityFlowerJar;
+import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.world.World;
 import org.lwjgl.opengl.GL11;
 
@@ -32,7 +34,15 @@ public class TileEntityRendererFlowerJar extends TileEntityRenderer<TileEntityFl
             float lightLevel = Minecraft.getMinecraft(this).theWorld.getLightBrightness(tileEntity.x, tileEntity.y, tileEntity.z);
             if (Global.accessor.isFullbrightEnabled()) lightLevel = 1.0f;
             BlockModel.setRenderBlocks(renderBlocks);
-            BlockModelDispatcher.getInstance().getDispatch(block).renderBlockOnInventory(tessellator, 0, lightLevel);
+            Integer lmc = null;
+            if (LightmapHelper.isLightmapEnabled()){
+                if (Global.accessor.isFullbrightEnabled()){
+                    lmc = LightmapHelper.getOverbrightLightmapCoord(tileEntity.worldObj.getSavedLightValue(LightLayer.Sky, tileEntity.x, tileEntity.y, tileEntity.z));
+                } else {
+                    lmc = tileEntity.worldObj.getLightmapCoord(tileEntity.x, tileEntity.y, tileEntity.z, 0);
+                }
+            }
+            BlockModelDispatcher.getInstance().getDispatch(block).renderBlockOnInventory(tessellator, 0, lightLevel, lmc);
         }
         GL11.glPopMatrix();
     }
diff --git a/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMesh.java b/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMesh.java
index 96fd83a11..f7c3f4c8a 100644
--- a/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMesh.java
+++ b/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMesh.java
@@ -35,7 +35,9 @@ public class TileEntityRendererMesh extends TileEntityRenderer<TileEntityMeshGol
         if (Global.accessor.isFullbrightEnabled()) lightLevel = 1.0f;
         BlockModel.setRenderBlocks(EntityRenderDispatcher.instance.itemRenderer.renderBlocksInstance);
         GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/);
+        GL11.glEnable(GL11.GL_BLEND);
         ItemModelDispatcher.getInstance().getDispatch(tileEntity.filterItem).renderAsItemEntity(Tessellator.instance, renderEntity, tileEntity.worldObj.rand, tileEntity.filterItem, 1, f3, lightLevel, renderPartialTicks);
+        GL11.glDisable(GL11.GL_BLEND);
         GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/);
         GL11.glPopMatrix();
         
diff --git a/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java b/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
index bacf15a44..b49ca0664 100644
--- a/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
+++ b/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
@@ -4,6 +4,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import net.minecraft.client.render.EntityRenderDispatcher;
+import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.entity.TileEntityMobSpawner;
 import net.minecraft.core.entity.Entity;
@@ -48,7 +49,8 @@ public class TileEntityRendererMobSpawner extends TileEntityRenderer<TileEntityM
             GL11.glRotatef(-30F, 1.0F, 0.0F, 0.0F);
             GL11.glTranslatef(0.0F, -0.4F, 0.0F);
             GL11.glScalef(f1, f1, f1);
-            entity.moveTo(x, y, z, 0.0F, 0.0F);
+//            System.out.printf("X: %f, Y: %f, Z: %f\n", x, y, z);
+            entity.moveTo(mobSpawner.x, mobSpawner.y, mobSpawner.z, 0.0F, 0.0F);
             EntityRenderDispatcher.instance.renderEntityWithPosYaw(tessellator, entity, 0.0D, 0.0D, 0.0D, 0.0F, partialTick);
         }
         GL11.glPopMatrix();
diff --git a/src/main/java/net/minecraft/client/util/debug/DebugRender.java b/src/main/java/net/minecraft/client/util/debug/DebugRender.java
index 2151a5486..ada5836f7 100644
--- a/src/main/java/net/minecraft/client/util/debug/DebugRender.java
+++ b/src/main/java/net/minecraft/client/util/debug/DebugRender.java
@@ -2,6 +2,8 @@ package net.minecraft.client.util.debug;
 
 import static org.lwjgl.opengl.GL11.*;
 
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.window.GameWindowLWJGL2;
 import org.lwjgl.input.Keyboard;
 import org.lwjgl.opengl.Display;
 
@@ -13,8 +15,8 @@ import net.minecraft.core.util.helper.MathHelper;
 public class DebugRender {
 	
 	private static Profiler selectedProfiler = Debug.baseProfiler;
-	private static long[] frametimes = new long[512];
-	private static long[] baseframetimes = new long[512];
+	private static final long[] frametimes = new long[512];
+	private static final long[] baseframetimes = new long[512];
 	private static int pos = 0;
 	private static int scale = 200000;
 	private static int selection = 0;
@@ -158,6 +160,8 @@ public class DebugRender {
 		drawRectangle(tessellator, x, y - h2, frametimes.length, h2);
 		drawRectangle(tessellator, x, y - h1, frametimes.length, h1);
 		tessellator.setColorOpaque_I(0xFFFFFF);
+
+
 		
 		for(int i=0; i < frametimes.length; i++) {
 			float brightness = ((i - pos) & (frametimes.length - 1)) / (float) frametimes.length;
@@ -168,7 +172,28 @@ public class DebugRender {
 			int time = (int) (frametimes[i] / scale);
 			drawRectangle(tessellator, x + i, y - time, 1, time);
 		}
-		
+
+		final int tickLagHeight = (int) ((1000/20d * 1000 * 1000)/(double) scale);
+
+		tessellator.setColorOpaque_I(0xFF0000);
+		drawRectangle(tessellator, x, y - tickLagHeight, frametimes.length, 1);
+
+		Minecraft mc = Minecraft.getMinecraft(Minecraft.class);
+		if (mc.gameSettings.customFpsLimit.value > 0 || mc.gameSettings.enableVsync.value){
+			tessellator.setColorOpaque_I(0x00FF00);
+			int fps = 0;
+			if (mc.gameSettings.enableVsync.value){
+				if(mc.gameWindow instanceof GameWindowLWJGL2){
+					fps = ((GameWindowLWJGL2) mc.gameWindow).defaultDisplayMode.getFrequency(); // Cap fps when minimized
+				}
+			} else {
+				fps = mc.gameSettings.customFpsLimit.value;
+			}
+
+			int frameLagHeight = (int) ((1000d/fps * 1000 * 1000)/scale);
+			drawRectangle(tessellator, x, y - frameLagHeight, frametimes.length, 1);
+		}
+
 		tessellator.draw();
 	}
 	
diff --git a/src/main/java/net/minecraft/client/world/WorldBlockPositionType.java b/src/main/java/net/minecraft/client/world/WorldBlockPositionType.java
index 48e80703a..dabe74d91 100644
--- a/src/main/java/net/minecraft/client/world/WorldBlockPositionType.java
+++ b/src/main/java/net/minecraft/client/world/WorldBlockPositionType.java
@@ -4,28 +4,23 @@ package net.minecraft.client.world;
 // Referenced classes of package net.minecraft.src:
 //            WorldClient
 
-import net.minecraft.client.world.WorldClient;
-
 class WorldBlockPositionType
 {
+    int x;
+    int y;
+    int z;
+    int delayTicks;
+    int blockId;
+    int metadata;
+    final WorldClient worldClient; /* synthetic field */
 
-    public WorldBlockPositionType(WorldClient worldclient, int i, int j, int k, int l, int i1)
-    {
-//        super();
-        field_1203_g = worldclient;
-        field_1202_a = i;
-        field_1201_b = j;
-        field_1207_c = k;
-        field_1206_d = 80;
-        field_1205_e = l;
-        field_1204_f = i1;
+    public WorldBlockPositionType(WorldClient worldclient, int x, int y, int z, int blockId, int metadata) {
+        this.worldClient = worldclient;
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.delayTicks = 80;
+        this.blockId = blockId;
+        this.metadata = metadata;
     }
-
-    int field_1202_a;
-    int field_1201_b;
-    int field_1207_c;
-    int field_1206_d;
-    int field_1205_e;
-    int field_1204_f;
-    final WorldClient field_1203_g; /* synthetic field */
 }
diff --git a/src/main/java/net/minecraft/client/world/WorldClient.java b/src/main/java/net/minecraft/client/world/WorldClient.java
index d79651dad..ca6cd0d75 100644
--- a/src/main/java/net/minecraft/client/world/WorldClient.java
+++ b/src/main/java/net/minecraft/client/world/WorldClient.java
@@ -1,9 +1,5 @@
 package net.minecraft.client.world;
 
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Set;
-
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.net.handler.NetClientHandler;
 import net.minecraft.client.world.chunk.provider.ChunkProviderClient;
@@ -17,23 +13,32 @@ import net.minecraft.core.world.chunk.provider.IChunkProvider;
 import net.minecraft.core.world.pathfinder.IdHashMap;
 import net.minecraft.core.world.save.SaveHandlerClientMP;
 
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Set;
+
 // Referenced classes of package net.minecraft.src:
 //            World, SaveHandlerMP, WorldProvider, MCHash, 
 //            ChunkCoordinates, NetClientHandler, IWorldAccess, Entity, 
 //            WorldBlockPositionType, ChunkProviderClient, Packet255KickDisconnect, WorldInfo, 
 //            IChunkProvider
 
-public class WorldClient extends World
-{
-
+public class WorldClient extends World {
+    private final Minecraft mc;
+    private final LinkedList<WorldBlockPositionType> positionTypesList;
+    private final NetClientHandler sendQueue;
+    private ChunkProviderClient field_20915_C;
+    private final IdHashMap<Entity> entityMap;
+    private final Set<Entity> field_20914_E;
+    private final Set<Entity> field_1053_F;
     public WorldClient(Minecraft minecraft, NetClientHandler netclienthandler, long seed, int dimensionId, int worldTypeId)
     {
         super(new SaveHandlerClientMP(), "MpServer", Dimension.getDimensionList().get(dimensionId), Registries.WORLD_TYPES.getItemByNumericId(worldTypeId), seed);
         this.mc = minecraft;
-        field_1057_z = new LinkedList();
-        entityMap = new IdHashMap();
-        field_20914_E = new HashSet();
-        field_1053_F = new HashSet();
+        positionTypesList = new LinkedList<>();
+        entityMap = new IdHashMap<>();
+        field_20914_E = new HashSet<>();
+        field_1053_F = new HashSet<>();
         sendQueue = netclienthandler;
         setSpawnPoint(new ChunkCoordinates(8, 64, 8));
         savedDataStorage = netclienthandler.savedDataStorage;
@@ -44,7 +49,7 @@ public class WorldClient extends World
     {
         for(int k = 0; k < 10 && !field_1053_F.isEmpty(); k++)
         {
-            Entity entity = (Entity)field_1053_F.iterator().next();
+            Entity entity = field_1053_F.iterator().next();
             if(!loadedEntityList.contains(entity))
             {
                 entityJoinedWorld(entity);
@@ -52,14 +57,14 @@ public class WorldClient extends World
         }
 
         processPackets();
-        for(int l = 0; l < field_1057_z.size(); l++)
+        for(int l = 0; l < positionTypesList.size(); l++)
         {
-            WorldBlockPositionType worldblockpositiontype = (WorldBlockPositionType)field_1057_z.get(l);
-            if(--worldblockpositiontype.field_1206_d == 0)
+            WorldBlockPositionType worldblockpositiontype = positionTypesList.get(l);
+            if(--worldblockpositiontype.delayTicks == 0)
             {
-                super.setBlockAndMetadata(worldblockpositiontype.field_1202_a, worldblockpositiontype.field_1201_b, worldblockpositiontype.field_1207_c, worldblockpositiontype.field_1205_e, worldblockpositiontype.field_1204_f);
-                super.markBlockNeedsUpdate(worldblockpositiontype.field_1202_a, worldblockpositiontype.field_1201_b, worldblockpositiontype.field_1207_c);
-                field_1057_z.remove(l--);
+                super.setBlockAndMetadata(worldblockpositiontype.x, worldblockpositiontype.y, worldblockpositiontype.z, worldblockpositiontype.blockId, worldblockpositiontype.metadata);
+                super.markBlockNeedsUpdate(worldblockpositiontype.x, worldblockpositiontype.y, worldblockpositiontype.z);
+                positionTypesList.remove(l--);
             }
         }
 		updateSeasonAndLight();
@@ -71,12 +76,12 @@ public class WorldClient extends World
 
     public void func_711_c(int i, int j, int k, int l, int i1, int j1)
     {
-        for(int k1 = 0; k1 < field_1057_z.size(); k1++)
+        for(int k1 = 0; k1 < positionTypesList.size(); k1++)
         {
-            WorldBlockPositionType worldblockpositiontype = (WorldBlockPositionType)field_1057_z.get(k1);
-            if(worldblockpositiontype.field_1202_a >= i && worldblockpositiontype.field_1201_b >= j && worldblockpositiontype.field_1207_c >= k && worldblockpositiontype.field_1202_a <= l && worldblockpositiontype.field_1201_b <= i1 && worldblockpositiontype.field_1207_c <= j1)
+            WorldBlockPositionType worldblockpositiontype = positionTypesList.get(k1);
+            if(worldblockpositiontype.x >= i && worldblockpositiontype.y >= j && worldblockpositiontype.z >= k && worldblockpositiontype.x <= l && worldblockpositiontype.y <= i1 && worldblockpositiontype.z <= j1)
             {
-                field_1057_z.remove(k1--);
+                positionTypesList.remove(k1--);
             }
         }
 
@@ -149,10 +154,7 @@ public class WorldClient extends World
 	protected void obtainEntitySkin(Entity entity)
     {
         super.obtainEntitySkin(entity);
-        if(field_1053_F.contains(entity))
-        {
-            field_1053_F.remove(entity);
-        }
+        field_1053_F.remove(entity);
     }
 
     @Override
@@ -183,12 +185,12 @@ public class WorldClient extends World
 
     public Entity getEntityFromId(int i)
     {
-        return (Entity) entityMap.get(i);
+        return entityMap.get(i);
     }
 
     public Entity removeEntityFromWorld(int i)
     {
-        Entity entity = (Entity) entityMap.remove(i);
+        Entity entity = entityMap.remove(i);
         if(entity != null)
         {
             field_20914_E.remove(entity);
@@ -204,7 +206,7 @@ public class WorldClient extends World
         int j1 = getBlockMetadata(i, j, k);
         if(super.setBlockMetadata(i, j, k, l))
         {
-            field_1057_z.add(new WorldBlockPositionType(this, i, j, k, i1, j1));
+            positionTypesList.add(new WorldBlockPositionType(this, i, j, k, i1, j1));
             return true;
         } else
         {
@@ -219,7 +221,7 @@ public class WorldClient extends World
         int k1 = getBlockMetadata(i, j, k);
         if(super.setBlockAndMetadata(i, j, k, l, i1))
         {
-            field_1057_z.add(new WorldBlockPositionType(this, i, j, k, j1, k1));
+            positionTypesList.add(new WorldBlockPositionType(this, i, j, k, j1, k1));
             return true;
         } else
         {
@@ -228,13 +230,13 @@ public class WorldClient extends World
     }
 
     @Override
-	public boolean setBlock(int i, int j, int k, int l)
+	public boolean setBlock(int x, int y, int z, int id)
     {
-        int i1 = getBlockId(i, j, k);
-        int j1 = getBlockMetadata(i, j, k);
-        if(super.setBlock(i, j, k, l))
+        int blockId = getBlockId(x, y, z);
+        int meta = getBlockMetadata(x, y, z);
+        if(super.setBlock(x, y, z, id))
         {
-            field_1057_z.add(new WorldBlockPositionType(this, i, j, k, i1, j1));
+            positionTypesList.add(new WorldBlockPositionType(this, x, y, z, blockId, meta));
             return true;
         } else
         {
@@ -242,12 +244,12 @@ public class WorldClient extends World
         }
     }
 
-    public boolean func_714_c(int i, int j, int k, int l, int i1)
+    public boolean blockChange(int x, int y, int z, int id, int meta)
     {
-        func_711_c(i, j, k, i, j, k);
-        if(super.setBlockAndMetadata(i, j, k, l, i1))
+        func_711_c(x, y, z, x, y, z);
+        if(super.setBlockAndMetadata(x, y, z, id, meta))
         {
-            notifyBlockChange(i, j, k, l);
+            notifyBlockChange(x, y, z, id);
             return true;
         } else
         {
@@ -261,11 +263,8 @@ public class WorldClient extends World
         sendQueue.func_28117_a(new Packet255KickDisconnect("Quitting"));
     }
 
-    private Minecraft mc;
-    private LinkedList field_1057_z;
-    private NetClientHandler sendQueue;
-    private ChunkProviderClient field_20915_C;
-    private IdHashMap entityMap;
-    private Set field_20914_E;
-    private Set field_1053_F;
+    @Override
+    public void sendGlobalMessage(String message){
+
+    }
 }
diff --git a/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java b/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
index 6cc5c89c8..86eaa9f7a 100644
--- a/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
+++ b/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
@@ -19,8 +19,8 @@ public class ChunkProviderClient
 
     public ChunkProviderClient(World world)
     {
-        chunkMapping = new HashMap();
-        field_889_c = new ArrayList();
+        chunkMapping = new HashMap<>();
+        chunks = new ArrayList<>();
         blankChunk = new EmptyChunk(world, 0, 0);
         worldObj = world;
     }
@@ -28,14 +28,17 @@ public class ChunkProviderClient
     @Override
     public boolean isChunkLoaded(int chunkX, int chunkZ)
     {
-        if(this != null)
+        return true;
+
+        // Previous code always returned true, possibly was a bug?
+        /*if(this != null)
         {
             return true;
         } else
         {
             ChunkCoordinate chunkcoordintpair = new ChunkCoordinate(chunkX, chunkZ);
             return chunkMapping.containsKey(chunkcoordintpair);
-        }
+        }*/
     }
 
     @Override
@@ -51,7 +54,7 @@ public class ChunkProviderClient
             chunk.onUnload();
         }
         chunkMapping.remove(new ChunkCoordinate(i, j));
-        field_889_c.remove(chunk);
+        chunks.remove(chunk);
     }
 
     @Override
@@ -67,8 +70,8 @@ public class ChunkProviderClient
     @Override
     public Chunk provideChunk(int chunkX, int chunkZ)
     {
-        ChunkCoordinate chunkcoordintpair = new ChunkCoordinate(chunkX, chunkZ);
-        Chunk chunk = (Chunk)chunkMapping.get(chunkcoordintpair);
+        ChunkCoordinate coordinate = new ChunkCoordinate(chunkX, chunkZ);
+        Chunk chunk = chunkMapping.get(coordinate);
         if(chunk == null)
         {
             return blankChunk;
@@ -110,7 +113,7 @@ public class ChunkProviderClient
     @Override
     public String getInfoString()
     {
-        return (new StringBuilder()).append("MultiplayerChunkCache: ").append(chunkMapping.size()).toString();
+        return "MultiplayerChunkCache: " + chunkMapping.size();
     }
 
     @Override
@@ -118,8 +121,8 @@ public class ChunkProviderClient
         // Do nothing
     }
 
-    private Chunk blankChunk;
-    private Map chunkMapping;
-    private List field_889_c;
-    private World worldObj;
+    private final Chunk blankChunk;
+    private final Map<ChunkCoordinate, Chunk> chunkMapping;
+    private final List<Chunk> chunks;
+    private final World worldObj;
 }
diff --git a/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderStatic.java b/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderStatic.java
index 072c481ff..eb7aaa0e8 100644
--- a/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderStatic.java
+++ b/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderStatic.java
@@ -93,8 +93,8 @@ public class ChunkProviderStatic
         {
             int k = chunkX & 0x1f;
             int l = chunkZ & 0x1f;
-            int i1 = k + l * 32;
-            return chunks[i1] != null && (chunks[i1] == blankChunk || chunks[i1].isAtLocation(chunkX, chunkZ));
+            int chunkIndex = k + l * 32;
+            return chunks[chunkIndex] == blankChunk || (chunks[chunkIndex] != null && chunks[chunkIndex].isAtLocation(chunkX, chunkZ));
         }
     }
 
diff --git a/src/main/java/net/minecraft/core/block/BlockButton.java b/src/main/java/net/minecraft/core/block/BlockButton.java
index 79f0052fc..9db91b6d5 100644
--- a/src/main/java/net/minecraft/core/block/BlockButton.java
+++ b/src/main/java/net/minecraft/core/block/BlockButton.java
@@ -4,6 +4,8 @@ import net.minecraft.core.block.material.Material;
 import net.minecraft.core.entity.EntityLiving;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.enums.EnumDropCause;
+import net.minecraft.core.item.Item;
+import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.util.phys.AABB;
@@ -233,7 +235,7 @@ public class BlockButton extends Block
     @Override
     public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player)
     {
-    	if(!player.isSneaking()) {
+    	if(!Item.hasTag(player.getCurrentEquippedItem(), ItemTags.PREVENT_LEFT_CLICK_INTERACTIONS)) {
     		blockActivated(world, x, y, z, player);
     	}
     }
diff --git a/src/main/java/net/minecraft/core/block/BlockDoor.java b/src/main/java/net/minecraft/core/block/BlockDoor.java
index 237b81e50..f2240c32c 100644
--- a/src/main/java/net/minecraft/core/block/BlockDoor.java
+++ b/src/main/java/net/minecraft/core/block/BlockDoor.java
@@ -9,6 +9,7 @@ import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.Item;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.util.phys.AABB;
 import net.minecraft.core.util.phys.Vec3d;
 import net.minecraft.core.world.World;
@@ -106,7 +107,7 @@ public class BlockDoor extends Block
     
     @Override
 	public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player) {
-    	if(!player.isSneaking()) {
+    	if(!Item.hasTag(player.getCurrentEquippedItem(), ItemTags.PREVENT_LEFT_CLICK_INTERACTIONS)) {
     		blockActivated(world, x, y, z, player);
     	}
     }
diff --git a/src/main/java/net/minecraft/core/block/BlockEdible.java b/src/main/java/net/minecraft/core/block/BlockEdible.java
index 6feeac636..dc0930049 100644
--- a/src/main/java/net/minecraft/core/block/BlockEdible.java
+++ b/src/main/java/net/minecraft/core/block/BlockEdible.java
@@ -77,13 +77,7 @@ public abstract class BlockEdible extends Block {
         eatSlice(world, x, y, z, player);
         return true;
     }
-
-    @Override
-    public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player)
-    {
-        eatSlice(world, x, y, z, player);
-    }
-
+    
     @Override
     public boolean canPlaceBlockAt(World world, int x, int y, int z)
     {
diff --git a/src/main/java/net/minecraft/core/block/BlockFenceGate.java b/src/main/java/net/minecraft/core/block/BlockFenceGate.java
index 2617bb3f7..d66cf1349 100644
--- a/src/main/java/net/minecraft/core/block/BlockFenceGate.java
+++ b/src/main/java/net/minecraft/core/block/BlockFenceGate.java
@@ -3,6 +3,8 @@ package net.minecraft.core.block;
 import net.minecraft.core.block.material.Material;
 import net.minecraft.core.entity.EntityLiving;
 import net.minecraft.core.entity.player.EntityPlayer;
+import net.minecraft.core.item.Item;
+import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.helper.Side;
@@ -89,7 +91,7 @@ public class BlockFenceGate extends Block
     
     @Override
 	public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player) {
-    	if(!player.isSneaking()) {
+    	if(!Item.hasTag(player.getCurrentEquippedItem(), ItemTags.PREVENT_LEFT_CLICK_INTERACTIONS)) {
     		blockActivated(world, x, y, z, player);
     	}
     }
diff --git a/src/main/java/net/minecraft/core/block/BlockFlower.java b/src/main/java/net/minecraft/core/block/BlockFlower.java
index 4852eefa9..13735f24d 100644
--- a/src/main/java/net/minecraft/core/block/BlockFlower.java
+++ b/src/main/java/net/minecraft/core/block/BlockFlower.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import net.minecraft.core.entity.EntityLiving;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.item.IBonemealable;
 import net.minecraft.core.item.ItemStack;
@@ -42,6 +43,12 @@ public class BlockFlower extends Block implements IBonemealable
         return this;
     }
 
+    @Override
+    public void onBlockPlaced(World world, int x, int y, int z, Side placeSide, EntityLiving entity, double sideHeight) {
+        if (entity instanceof EntityPlayer){
+            world.setBlockMetadata(x, y, z, world.getBlockMetadata(x, y, z) | 0b1000_0000); // Set persistent flag
+        }
+    }
     @Override
 	public boolean canPlaceBlockAt(World world, int x, int y, int z)
     {
@@ -66,7 +73,7 @@ public class BlockFlower extends Block implements IBonemealable
     {
         func_268_h(world, x, y, z);
         
-        if (world.getSeasonManager().getCurrentSeason() != null && world.getSeasonManager().getCurrentSeason().killFlowers && killedByWeather && rand.nextInt(256) == 0)
+        if (world.getSeasonManager().getCurrentSeason() != null && ((world.getBlockMetadata(x, y, z) & 0b1000_000) == 0) && world.getSeasonManager().getCurrentSeason().killFlowers && killedByWeather && rand.nextInt(256) == 0)
         {
         	world.setBlockWithNotify(x, y, z, 0);
         }
diff --git a/src/main/java/net/minecraft/core/block/BlockFluid.java b/src/main/java/net/minecraft/core/block/BlockFluid.java
index 7e695b939..45cf867fc 100644
--- a/src/main/java/net/minecraft/core/block/BlockFluid.java
+++ b/src/main/java/net/minecraft/core/block/BlockFluid.java
@@ -34,7 +34,7 @@ public abstract class BlockFluid extends Block
         return (float)(data + 1) / 8F;
     }
 
-    protected int getDepth(World world, int x, int y, int z)
+    protected int getDepth(WorldSource world, int x, int y, int z)
     {
         if(world.getBlockMaterial(x, y, z) != blockMaterial)
         {
@@ -315,4 +315,48 @@ public abstract class BlockFluid extends Block
             world.spawnParticle("largesmoke", (double)x + Math.random(), (double)y + 1.2D, (double)z + Math.random(), 0.0D, 0.0D, 0.0D, 0);
         }
     }
+    @Override
+    public void setBlockBoundsBasedOnState(WorldSource world, int x, int y, int z)
+    {
+        float f7 = BlockFluid.getFluidHeight(world, x, y, z, blockMaterial);
+        float f8 = BlockFluid.getFluidHeight(world, x, y, z + 1, blockMaterial);
+        float f9 = BlockFluid.getFluidHeight(world, x + 1, y, z + 1, blockMaterial);
+        float f10 = BlockFluid.getFluidHeight(world, x + 1, y, z, blockMaterial);
+        setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, Math.max((f7 + f8 + f9 + f10)/4f, 0.2), 1.0F);
+    }
+
+    public static float getFluidHeight(WorldSource worldSource, int x, int y, int z, Material material)
+    {
+        int l = 0;
+        float f = 0.0F;
+        for(int i1 = 0; i1 < 4; i1++)
+        {
+            int j1 = x - (i1 & 1);
+            int l1 = z - (i1 >> 1 & 1);
+            if(worldSource.getBlockMaterial(j1, y + 1, l1) == material)
+            {
+                return 1.0F;
+            }
+            Material material1 = worldSource.getBlockMaterial(j1, y, l1);
+            if(material1 == material)
+            {
+                int i2 = worldSource.getBlockMetadata(j1, y, l1);
+                if(i2 >= 8 || i2 == 0)
+                {
+                    f += BlockFluid.getWaterVolume(i2) * 10F;
+                    l += 10;
+                }
+                f += BlockFluid.getWaterVolume(i2);
+                l++;
+                continue;
+            }
+            if(!material1.isSolid())
+            {
+                f++;
+                l++;
+            }
+        }
+
+        return Math.max(1.0F - f / (float)l, 0.015F);
+    }
 }
diff --git a/src/main/java/net/minecraft/core/block/BlockLever.java b/src/main/java/net/minecraft/core/block/BlockLever.java
index c0dc45b1f..ab833806a 100644
--- a/src/main/java/net/minecraft/core/block/BlockLever.java
+++ b/src/main/java/net/minecraft/core/block/BlockLever.java
@@ -4,6 +4,8 @@ import net.minecraft.core.block.material.Material;
 import net.minecraft.core.entity.EntityLiving;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.enums.EnumDropCause;
+import net.minecraft.core.item.Item;
+import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.Axis;
 import net.minecraft.core.util.helper.Side;
@@ -189,7 +191,7 @@ public class BlockLever extends Block
     @Override
     public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player)
     {
-    	if(!player.isSneaking()) {
+    	if(!Item.hasTag(player.getCurrentEquippedItem(), ItemTags.PREVENT_LEFT_CLICK_INTERACTIONS)) {
     		blockActivated(world, x, y, z, player);
     	}
     }
diff --git a/src/main/java/net/minecraft/core/block/BlockMotionSensor.java b/src/main/java/net/minecraft/core/block/BlockMotionSensor.java
index 632843ee6..7f88d6f2c 100644
--- a/src/main/java/net/minecraft/core/block/BlockMotionSensor.java
+++ b/src/main/java/net/minecraft/core/block/BlockMotionSensor.java
@@ -58,7 +58,8 @@ public class BlockMotionSensor extends BlockTileEntityRotatable
 	private void spawnParticles(World world, int x, int y, int z) {
 		Random random = world.rand;
 
-		Color color = Colors.allRedstoneColors[10];
+        final int redstoneBrightness = 10;
+		Color color = Colors.allRedstoneColors[redstoneBrightness];
 		if(color == null) {
 			return;
 		}
@@ -80,7 +81,7 @@ public class BlockMotionSensor extends BlockTileEntityRotatable
 			if (i == 5 && !world.isBlockOpaqueCube(x - 1, y, z)) px = (x + 0) - d;
 			
 			if (px < x || px > (x + 1) || py < 0.0D || py > (y + 1) || pz < z || pz > (z + 1)) {
-				world.spawnParticle("reddust", px, py, pz, red, green, blue, 0);
+				world.spawnParticle("reddust", px, py, pz, red, green, blue, redstoneBrightness);
 			}
 		}
 	}
diff --git a/src/main/java/net/minecraft/core/block/BlockOreRedstone.java b/src/main/java/net/minecraft/core/block/BlockOreRedstone.java
index fe4305123..2c3bf3034 100644
--- a/src/main/java/net/minecraft/core/block/BlockOreRedstone.java
+++ b/src/main/java/net/minecraft/core/block/BlockOreRedstone.java
@@ -99,7 +99,8 @@ public class BlockOreRedstone extends Block
     private void spawnParticles(World world, int x, int y, int z) {
 		Random random = world.rand;
 
-		Color color = Colors.allRedstoneColors[10];
+        final int redstoneBrightness = 10;
+		Color color = Colors.allRedstoneColors[redstoneBrightness];
 		if(color == null) {
 			return;
 		}
@@ -123,7 +124,7 @@ public class BlockOreRedstone extends Block
 			if (i == 5 && !world.isBlockOpaqueCube(x - 1, y, z)) px = (x + 0) - d;
 			
 			if (px < x || px > (x + 1) || py < 0.0D || py > (y + 1) || pz < z || pz > (z + 1)) {
-				world.spawnParticle("reddust", px, py, pz, red, green, blue, 0);
+				world.spawnParticle("reddust", px, py, pz, red, green, blue, redstoneBrightness);
 			}
 		}
     }
diff --git a/src/main/java/net/minecraft/core/block/BlockRedstone.java b/src/main/java/net/minecraft/core/block/BlockRedstone.java
index 400adb7f8..ee1add575 100644
--- a/src/main/java/net/minecraft/core/block/BlockRedstone.java
+++ b/src/main/java/net/minecraft/core/block/BlockRedstone.java
@@ -65,7 +65,8 @@ public class BlockRedstone extends Block
 	private void spawnParticles(World world, int x, int y, int z) {
 		Random random = world.rand;
 
-		Color color = Colors.allRedstoneColors[10];
+        final int redstoneBrightness = 10;
+		Color color = Colors.allRedstoneColors[redstoneBrightness];
 		if(color == null) {
 			return;
 		}
@@ -87,7 +88,7 @@ public class BlockRedstone extends Block
 			if (i == 5 && !world.isBlockOpaqueCube(x - 1, y, z)) px = (x + 0) - d;
 			
 			if (px < x || px > (x + 1) || py < 0.0D || py > (y + 1) || pz < z || pz > (z + 1)) {
-				world.spawnParticle("reddust", px, py, pz, red, green, blue, 0);
+				world.spawnParticle("reddust", px, py, pz, red, green, blue, redstoneBrightness);
 			}
 		}
 	}
diff --git a/src/main/java/net/minecraft/core/block/BlockRedstoneRepeater.java b/src/main/java/net/minecraft/core/block/BlockRedstoneRepeater.java
index 402f83cff..7722ed4f6 100644
--- a/src/main/java/net/minecraft/core/block/BlockRedstoneRepeater.java
+++ b/src/main/java/net/minecraft/core/block/BlockRedstoneRepeater.java
@@ -213,7 +213,8 @@ public class BlockRedstoneRepeater extends Block
 		double xOffset = 0.0;
 		double zOffset = 0.0;
 
-		Color color = Colors.allRedstoneColors[10];
+        final int redstoneBrightness = 15;
+		Color color = Colors.allRedstoneColors[redstoneBrightness];
 		if(color == null) {
 			return;
 		}
@@ -253,7 +254,7 @@ public class BlockRedstoneRepeater extends Block
 				break;
 			}
 		}
-		world.spawnParticle("reddust", px + xOffset, py, pz + zOffset, red, green, blue, 0);
+		world.spawnParticle("reddust", px + xOffset, py, pz + zOffset, red, green, blue, redstoneBrightness);
 	}
 
     public static final double field_22024_a[] = {
diff --git a/src/main/java/net/minecraft/core/block/BlockRedstoneTorch.java b/src/main/java/net/minecraft/core/block/BlockRedstoneTorch.java
index eb26cb3a2..08eeceed7 100644
--- a/src/main/java/net/minecraft/core/block/BlockRedstoneTorch.java
+++ b/src/main/java/net/minecraft/core/block/BlockRedstoneTorch.java
@@ -210,7 +210,8 @@ public class BlockRedstoneTorch extends BlockTorch
 		double verticalOffset = 0.22D;
 		double horizontalOffset = 0.27D;
 
-		Color color = Colors.allRedstoneColors[10];
+        final int redstoneBrightness = 10;
+		Color color = Colors.allRedstoneColors[redstoneBrightness];
 		if(color == null) {
 			return;
 		}
@@ -219,15 +220,15 @@ public class BlockRedstoneTorch extends BlockTorch
 		float blue = color.getBlue() / 255.0f;
 		
 		if (meta == 1) {
-			world.spawnParticle("reddust", px - horizontalOffset, py + verticalOffset, pz, red, green, blue, 0);
+			world.spawnParticle("reddust", px - horizontalOffset, py + verticalOffset, pz, red, green, blue, redstoneBrightness);
 		} else if (meta == 2) {
-			world.spawnParticle("reddust", px + horizontalOffset, py + verticalOffset, pz, red, green, blue, 0);
+			world.spawnParticle("reddust", px + horizontalOffset, py + verticalOffset, pz, red, green, blue, redstoneBrightness);
 		} else if (meta == 3) {
-			world.spawnParticle("reddust", px, py + verticalOffset, pz - horizontalOffset, red, green, blue, 0);
+			world.spawnParticle("reddust", px, py + verticalOffset, pz - horizontalOffset, red, green, blue, redstoneBrightness);
 		} else if (meta == 4) {
-			world.spawnParticle("reddust", px, py + verticalOffset, pz + horizontalOffset, red, green, blue, 0);
+			world.spawnParticle("reddust", px, py + verticalOffset, pz + horizontalOffset, red, green, blue, redstoneBrightness);
 		} else {
-			world.spawnParticle("reddust", px, py, pz, red, green, blue, 0);
+			world.spawnParticle("reddust", px, py, pz, red, green, blue, redstoneBrightness);
 		}
 	}
 
diff --git a/src/main/java/net/minecraft/core/block/BlockRedstoneWire.java b/src/main/java/net/minecraft/core/block/BlockRedstoneWire.java
index 67ece3c5a..7ed042869 100644
--- a/src/main/java/net/minecraft/core/block/BlockRedstoneWire.java
+++ b/src/main/java/net/minecraft/core/block/BlockRedstoneWire.java
@@ -427,7 +427,8 @@ public class BlockRedstoneWire extends Block
 		double py = (double) y + 0.0625D;
 		double pz = (double) z + 0.5D + (rand.nextFloat() - 0.5D) * 0.2D;
 
-		Color color = Colors.allRedstoneColors[meta & 0xF];
+        final int redstoneBrightness = meta & 0xF;
+		Color color = Colors.allRedstoneColors[redstoneBrightness];
 		if(color == null) {
 			return;
 		}
@@ -435,7 +436,7 @@ public class BlockRedstoneWire extends Block
 		float green = color.getGreen() / 255.0f;
 		float blue = color.getBlue() / 255.0f;
 
-		world.spawnParticle("reddust", px, py, pz, red, green, blue, 0);
+		world.spawnParticle("reddust", px, py, pz, red, green, blue, redstoneBrightness);
 	}
 
     public static boolean isPowerProviderOrWire(WorldSource iblockaccess, int i, int j, int k, int l)
diff --git a/src/main/java/net/minecraft/core/block/BlockTrapDoor.java b/src/main/java/net/minecraft/core/block/BlockTrapDoor.java
index bde3c5884..f369ea782 100644
--- a/src/main/java/net/minecraft/core/block/BlockTrapDoor.java
+++ b/src/main/java/net/minecraft/core/block/BlockTrapDoor.java
@@ -5,6 +5,8 @@ import net.minecraft.core.block.material.Material;
 import net.minecraft.core.entity.EntityLiving;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.enums.PlacementMode;
+import net.minecraft.core.item.Item;
+import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.util.phys.AABB;
@@ -96,7 +98,7 @@ public class BlockTrapDoor extends Block
     
     @Override
     public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player) {
-    	if(!player.isSneaking()) {
+    	if(!Item.hasTag(player.getCurrentEquippedItem(), ItemTags.PREVENT_LEFT_CLICK_INTERACTIONS)) {
     		blockActivated(world, x, y, z, player);
     	}
     }
diff --git a/src/main/java/net/minecraft/core/data/registry/recipe/entry/RecipeEntryRepairable.java b/src/main/java/net/minecraft/core/data/registry/recipe/entry/RecipeEntryRepairable.java
index 66ad711d8..f4fc52261 100644
--- a/src/main/java/net/minecraft/core/data/registry/recipe/entry/RecipeEntryRepairable.java
+++ b/src/main/java/net/minecraft/core/data/registry/recipe/entry/RecipeEntryRepairable.java
@@ -75,7 +75,7 @@ public class RecipeEntryRepairable extends RecipeEntryCraftingDynamic {
 
         for (int i = 0; i < repairMaterialCount; i++)
         {
-            if (inItemStack.getMetadata() < inItemStack.getMaxDamage())
+            if (inItemStack.getMetadata() <= inItemStack.getMaxDamage())
             {
                 inItemStack.setMetadata(inItemStack.getMetadata() - inItemStack.getMaxDamage() / 8);
             }
diff --git a/src/main/java/net/minecraft/core/entity/Entity.java b/src/main/java/net/minecraft/core/entity/Entity.java
index cf12da4c0..c7ce5292d 100644
--- a/src/main/java/net/minecraft/core/entity/Entity.java
+++ b/src/main/java/net/minecraft/core/entity/Entity.java
@@ -16,6 +16,7 @@ import net.minecraft.core.enums.EnumBlockSoundEffectType;
 import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.util.helper.DamageType;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.AABB;
@@ -728,7 +729,7 @@ public abstract class Entity
 
     public boolean checkAndHandleWater(boolean addVelocity)
     {
-        return world.handleMaterialAcceleration(bb.expand(0.0D, -0.40000000596046448D, 0.0D).getInsetBoundingBox(0.001D, 0.001D, 0.001D), Material.water, this, addVelocity);
+        return world.handleMaterialAcceleration(bb/*.expand(0.0D, -0.4D, 0.0D)*/.getInsetBoundingBox(0.001D, 0.001D, 0.001D), Material.water, this, addVelocity);
     }
 
     public boolean isUnderLiquid(Material material)
@@ -757,7 +758,7 @@ public abstract class Entity
 
     public boolean isInLava()
     {
-        return world.isMaterialInBB(bb.expand(-0.1D, -0.4D, -0.1D), Material.lava);
+        return world.isMaterialInBB(bb/*.expand(-0.1D, -0.4D, -0.1D)*/, Material.lava);
     }
 
     public void moveRelative(float f, float f1, float f2)
@@ -1483,6 +1484,9 @@ public abstract class Entity
                 return ((EntityLiving) entity).nickname;
             }
         }
+        if (entity instanceof EntityPlayer){
+            return ((EntityPlayer) entity).getDisplayName();
+        }
         if (MobInfoRegistry.getMobInfo(entity.getClass()) != null){
             return translator.translateKey(MobInfoRegistry.getMobInfo(entity.getClass()).getNameTranslationKey());
         }
diff --git a/src/main/java/net/minecraft/core/entity/EntityLiving.java b/src/main/java/net/minecraft/core/entity/EntityLiving.java
index f93497ea8..9f302adf5 100644
--- a/src/main/java/net/minecraft/core/entity/EntityLiving.java
+++ b/src/main/java/net/minecraft/core/entity/EntityLiving.java
@@ -533,15 +533,15 @@ public abstract class EntityLiving extends Entity
         }
     }
 
-    public void onDeath(Entity entity)
+    public void onDeath(Entity entityKilledBy)
     {
-        if(scoreValue >= 0 && entity != null)
+        if(scoreValue >= 0 && entityKilledBy != null)
         {
-            entity.awardKillScore(this, scoreValue);
+            entityKilledBy.awardKillScore(this, scoreValue);
         }
-        if(entity != null)
+        if(entityKilledBy != null)
         {
-            entity.killed(this);
+            entityKilledBy.killed(this);
         }
         dead = true;
         if(!world.isClientSide)
@@ -553,8 +553,44 @@ public abstract class EntityLiving extends Entity
             vehicle = null;
         }
         world.sendTrackedEntityStatusUpdatePacket(this, (byte)3);
+        if (sendDeathMessage(entityKilledBy)){
+            world.sendGlobalMessage(getDeathMessage(entityKilledBy));
+        }
     }
 
+    public boolean sendDeathMessage(Entity entityKilledBy){
+        return !nickname.isEmpty();
+    }
+    public String getDeathMessage(Entity entityKilledBy){
+        final TextFormatting deathMsgColor = TextFormatting.RED;
+        final TextFormatting reset = TextFormatting.RESET;
+        String name = Entity.getNameFromEntity(this, true);
+        if (entityKilledBy != null){
+            String murdererName = Entity.getNameFromEntity(entityKilledBy, true);
+            return String.format("%s%s was killed by %s%s", name, deathMsgColor, reset, murdererName);
+        }
+        if (world.isMaterialInBB(bb, Material.lava))
+        {
+            return String.format("%s%s swam in lava.", name, deathMsgColor);
+        }
+        if (world.getBlockId(MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z)) == Block.spikes.id)
+        {
+            return String.format("%s%s got impaled.", name, deathMsgColor);
+        }
+        if (fallDistance > 0)
+        {
+            return String.format("%s%s broke their legs.", name, deathMsgColor);
+        }
+        if (airSupply <= 0)
+        {
+            return String.format("%s%s suffocated.", name, deathMsgColor);
+        }
+        if (remainingFireTicks > 0)
+        {
+            return String.format("%s%s was incinerated.", name, deathMsgColor);
+        }
+        return String.format("%s%s died", name, deathMsgColor);
+    }
     protected void dropFewItems()
     {
         List<WeightedRandomLootObject> drops = getMobDrops();
diff --git a/src/main/java/net/minecraft/core/entity/animal/EntityWolf.java b/src/main/java/net/minecraft/core/entity/animal/EntityWolf.java
index 47b9736ca..76adf674b 100644
--- a/src/main/java/net/minecraft/core/entity/animal/EntityWolf.java
+++ b/src/main/java/net/minecraft/core/entity/animal/EntityWolf.java
@@ -54,6 +54,10 @@ public class EntityWolf extends EntityAnimal
             }
         }
     }
+    @Override
+    public boolean sendDeathMessage(Entity entityKilledBy){
+        return super.sendDeathMessage(entityKilledBy) || isWolfTamed();
+    }
 
     public ArmorMaterial getArmorMaterial() {
         ArmorMaterial material = null;
diff --git a/src/main/java/net/minecraft/core/entity/monster/EntityCreeper.java b/src/main/java/net/minecraft/core/entity/monster/EntityCreeper.java
index 16380e8a0..7945ea533 100644
--- a/src/main/java/net/minecraft/core/entity/monster/EntityCreeper.java
+++ b/src/main/java/net/minecraft/core/entity/monster/EntityCreeper.java
@@ -107,10 +107,10 @@ public class EntityCreeper extends EntityMonster
     }
 
     @Override
-	public void onDeath(Entity entity)
+	public void onDeath(Entity entityKilledBy)
     {
-        super.onDeath(entity);
-        if(entity instanceof EntitySkeleton)
+        super.onDeath(entityKilledBy);
+        if(entityKilledBy instanceof EntitySkeleton)
         {
             spawnAtLocation(Item.record13.id + random.nextInt(11), 1);
         }
diff --git a/src/main/java/net/minecraft/core/entity/player/EntityPlayer.java b/src/main/java/net/minecraft/core/entity/player/EntityPlayer.java
index 31187a773..e202cfca4 100644
--- a/src/main/java/net/minecraft/core/entity/player/EntityPlayer.java
+++ b/src/main/java/net/minecraft/core/entity/player/EntityPlayer.java
@@ -19,14 +19,25 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityBobber;
 import net.minecraft.core.entity.EntityDispatcher;
 import net.minecraft.core.entity.EntityItem;
+import net.minecraft.core.entity.EntityLightningBolt;
 import net.minecraft.core.entity.EntityLiving;
+import net.minecraft.core.entity.EntityTNT;
 import net.minecraft.core.entity.animal.EntityPig;
 import net.minecraft.core.entity.animal.EntityWolf;
 import net.minecraft.core.entity.monster.EntityCreeper;
 import net.minecraft.core.entity.monster.EntityGhast;
+import net.minecraft.core.entity.monster.EntityGiant;
 import net.minecraft.core.entity.monster.EntityMonster;
+import net.minecraft.core.entity.monster.EntityPigZombie;
+import net.minecraft.core.entity.monster.EntitySkeleton;
+import net.minecraft.core.entity.monster.EntitySlime;
 import net.minecraft.core.entity.monster.EntitySnowman;
+import net.minecraft.core.entity.monster.EntitySpider;
+import net.minecraft.core.entity.monster.EntityZombie;
 import net.minecraft.core.entity.projectile.EntityArrow;
+import net.minecraft.core.entity.projectile.EntityArrowGolden;
+import net.minecraft.core.entity.projectile.EntityCannonball;
+import net.minecraft.core.entity.projectile.EntityFireball;
 import net.minecraft.core.entity.vehicle.EntityBoat;
 import net.minecraft.core.entity.vehicle.EntityMinecart;
 import net.minecraft.core.enums.ArtType;
@@ -50,6 +61,7 @@ import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
 import net.minecraft.core.world.weather.Weather;
+import net.minecraft.server.entity.player.EntityPlayerMP;
 
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -58,6 +70,7 @@ import java.util.List;
 
 public abstract class EntityPlayer extends EntityLiving
 {
+    public static final TextFormatting deathMsgColor = TextFormatting.RED;
 
     public EntityPlayer(World world)
     {
@@ -321,12 +334,12 @@ public abstract class EntityPlayer extends EntityLiving
     }
 
     @Override
-    public void onDeath(Entity entity)
+    public void onDeath(Entity entityKilledBy)
     {
         if (getGamemode().isPermaDeath()){
             setGamemode(Gamemode.spectator);
         }
-        super.onDeath(entity);
+        super.onDeath(entityKilledBy);
         setSize(0.2F, 0.2F);
         setPos(x, y, z);
         lastDeathCoordinate = new ChunkCoordinates((int) x, (int) y, (int) z);
@@ -348,7 +361,7 @@ public abstract class EntityPlayer extends EntityLiving
             craftingInventory.onCraftGuiClosed(this);
             inventory.dropAllItems();
         }
-        if(entity != null)
+        if(entityKilledBy != null)
         {
             xd = -MathHelper.cos(((attackedAtYaw + yRot) * 3.141593F) / 180F) * 0.1F;
             zd = -MathHelper.sin(((attackedAtYaw + yRot) * 3.141593F) / 180F) * 0.1F;
@@ -359,6 +372,152 @@ public abstract class EntityPlayer extends EntityLiving
         heightOffset = 0.1F;
         addStat(StatList.deathsStat, 1);
     }
+    @Override
+    public boolean sendDeathMessage(Entity entityKilledBy){
+        return true;
+    }
+    @Override
+    public String getDeathMessage(Entity entityKilledBy){
+        if (random.nextInt(8000) == 666)
+        {
+            return getDisplayName() + deathMsgColor + " was killed by Herobrine.";
+        }
+        if (entityKilledBy instanceof EntityZombie)
+        {
+            if (entityKilledBy instanceof EntityPigZombie)
+            {
+                return getDisplayName() + deathMsgColor + " discovered mob mentality.";
+            }
+            else
+            {
+                return getDisplayName() + deathMsgColor + " became a zombie.";
+            }
+        }
+        if (entityKilledBy instanceof EntityCreeper)
+        {
+            return deathMsgColor + "Aw man, " + getDisplayName() + deathMsgColor + " didn't see the creeper.";
+        }
+        if (entityKilledBy instanceof EntitySkeleton)
+        {
+            return getDisplayName() + deathMsgColor + " was a victim of aimbot.";
+        }
+        if (entityKilledBy instanceof EntitySpider)
+        {
+            return getDisplayName() + deathMsgColor + " spent too much time on the web.";
+        }
+        if (entityKilledBy instanceof EntityGhast)
+        {
+            return getDisplayName() + deathMsgColor + " didn't return the serve.";
+        }
+        if (entityKilledBy instanceof EntitySlime)
+        {
+            return getDisplayName() + deathMsgColor + " was slimed.";
+        }
+        if (entityKilledBy instanceof EntityWolf)
+        {
+            return getDisplayName() + deathMsgColor + " got what they deserved.";
+        }
+        if (entityKilledBy instanceof EntityArrowGolden)
+        {
+            if (((EntityArrowGolden) entityKilledBy).owner instanceof EntityPlayerMP)
+            {
+                if (((EntityPlayerMP) ((EntityArrowGolden) entityKilledBy).owner).username.equals(username))
+                {
+                    return getDisplayName() + deathMsgColor + " got gold in their eye.";
+                }
+                return getDisplayName() + deathMsgColor + " got pierced by " +
+                    ((EntityArrow) entityKilledBy).owner.getDisplayName() + deathMsgColor + ".";
+            }
+            else
+            {
+                return getDisplayName() + deathMsgColor + " is Swiss cheese.";
+            }
+        }
+        if (entityKilledBy instanceof EntityArrow)
+        {
+            if (((EntityArrow) entityKilledBy).owner instanceof EntitySkeleton)
+            {
+                return getDisplayName() + deathMsgColor + " was a victim of aimbot.";
+            }
+            else if (((EntityArrow) entityKilledBy).owner instanceof EntityPlayerMP)
+            {
+                if (((EntityPlayerMP) ((EntityArrow) entityKilledBy).owner).username.equals(username))
+                {
+                    return getDisplayName() + deathMsgColor + " lost a game of Russian roulette.";
+                }
+                return getDisplayName() + deathMsgColor + " got 360 noscoped by " +
+                    ((EntityArrow) entityKilledBy).owner.getDisplayName() + deathMsgColor + ".";
+            }
+            else
+            {
+                return getDisplayName() + deathMsgColor + " is a pincushion.";
+            }
+        }
+        if (entityKilledBy instanceof EntityCannonball)
+        {
+            if (((EntityCannonball) entityKilledBy).owner instanceof EntityPlayerMP)
+            {
+                if (((EntityPlayerMP) ((EntityCannonball) entityKilledBy).owner).username.equals(username))
+                {
+                    return getDisplayName() + deathMsgColor + " jumped too high.";
+                }
+                return getDisplayName() + deathMsgColor + " was fragmented by " +
+                    ((EntityCannonball) entityKilledBy).owner.getDisplayName() + deathMsgColor + ".";
+            }
+            else
+            {
+                return getDisplayName() + deathMsgColor + " was detonated remotely.";
+            }
+        }
+        if (entityKilledBy instanceof EntityFireball)
+        {
+            return getDisplayName() + deathMsgColor + " didn't return the serve.";
+        }
+        if (entityKilledBy instanceof EntityGiant)
+        {
+            return getDisplayName() + deathMsgColor + " was killed by- wait, what?!";
+        }
+        if (entityKilledBy instanceof EntityLightningBolt)
+        {
+            return getDisplayName() + deathMsgColor + " was grounded.";
+        }
+        if (entityKilledBy instanceof EntityTNT)
+        {
+            return getDisplayName() + deathMsgColor + " was killed by Popbob.";
+        }
+        if (entityKilledBy instanceof EntityPlayerMP)
+        {
+            return getDisplayName() + deathMsgColor + " was backstabbed by " + ((EntityPlayerMP) entityKilledBy).getDisplayName() + deathMsgColor + ".";
+        }
+        if (entityKilledBy instanceof EntityPig)
+        {
+            return getDisplayName() + deathMsgColor + " is *really* bad at Minecraft.";
+        }
+        else
+        {
+            if (world.getBlockMaterial(MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z)) == Material.lava)
+            {
+                return getDisplayName() + deathMsgColor + " got lost in the sauce.";
+            }
+            if (world.getBlockId(MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z)) == Block.spikes.id)
+            {
+                return getDisplayName() + deathMsgColor + " fell for the trap.";
+            }
+            if (fallDistance > 0)
+            {
+                return getDisplayName() + deathMsgColor + " forgot to tie their laces.";
+            }
+            if (airSupply <= 0)
+            {
+                return getDisplayName() + deathMsgColor + " is sleeping with the fishes.";
+            }
+            if (remainingFireTicks > 0)
+            {
+                return getDisplayName() + deathMsgColor + " was cooked well done.";
+            }
+            return getDisplayName() + deathMsgColor + " died mysteriously.";
+        }
+    }
     
     @Override
     protected void dropFewItems()
@@ -739,12 +898,13 @@ public abstract class EntityPlayer extends EntityLiving
         return false;
     }
 
-    public void useCurrentItemOnEntity(Entity entity)
+    public boolean useCurrentItemOnEntity(Entity entity)
     {
+        boolean flag = false;
         if(entity.interact(this))
         {
             swingItem();
-            return;
+            flag = true;
         }
         ItemStack itemstack = getCurrentEquippedItem();
         if(itemstack != null && (entity instanceof EntityLiving))
@@ -752,12 +912,14 @@ public abstract class EntityPlayer extends EntityLiving
             if (itemstack.useItemOnEntity((EntityLiving)entity, this))
             {
                 swingItem();
+                flag = true;
             }
             if(itemstack.stackSize <= 0)
             {
                 destroyCurrentEquippedItem();
             }
         }
+        return flag;
     }
 
     public ItemStack getCurrentEquippedItem()
diff --git a/src/main/java/net/minecraft/core/entity/projectile/EntityCannonball.java b/src/main/java/net/minecraft/core/entity/projectile/EntityCannonball.java
index de6591856..d0db26ae8 100644
--- a/src/main/java/net/minecraft/core/entity/projectile/EntityCannonball.java
+++ b/src/main/java/net/minecraft/core/entity/projectile/EntityCannonball.java
@@ -30,7 +30,7 @@ public class EntityCannonball extends EntityProjectile
     public void onHit(HitResult hitResult){
         // Check for block collision
         if (hitResult.hitType == HitResult.HitType.TILE){
-            world.newExplosion(this, x, y, z, 1.5F, false, true);
+            world.newExplosion(owner, x, y, z, 1.5F, false, true);
             remove();
         }
     }
diff --git a/src/main/java/net/minecraft/core/entity/projectile/EntityCannonballBouncy.java b/src/main/java/net/minecraft/core/entity/projectile/EntityCannonballBouncy.java
index 0a6caff95..92f72557d 100644
--- a/src/main/java/net/minecraft/core/entity/projectile/EntityCannonballBouncy.java
+++ b/src/main/java/net/minecraft/core/entity/projectile/EntityCannonballBouncy.java
@@ -94,7 +94,7 @@ public class EntityCannonballBouncy extends EntityCannonball
         {
             if (!((collidingEntities != null && collidingEntities.size() == 1) && collidingEntities.get(0) == owner && tickCount < 4))
             {
-                world.newExplosion(this, x, y, z, 1.5F, false, true);
+                world.newExplosion(owner, x, y, z, 1.5F, false, true);
                 remove();
                 return;
             }
diff --git a/src/main/java/net/minecraft/core/entity/projectile/EntityFireball.java b/src/main/java/net/minecraft/core/entity/projectile/EntityFireball.java
index 251f33b33..a23db3386 100644
--- a/src/main/java/net/minecraft/core/entity/projectile/EntityFireball.java
+++ b/src/main/java/net/minecraft/core/entity/projectile/EntityFireball.java
@@ -85,7 +85,7 @@ public class EntityFireball extends EntityProjectile
                         result.entity.hurt(owner, damage, DamageType.COMBAT);
                     }
                 }
-                world.newExplosion(this, x, y, z, 1.5F, true, false);
+                world.newExplosion(owner, x, y, z, 1.5F, true, false);
             }
             remove();
         }
diff --git a/src/main/java/net/minecraft/core/item/Item.java b/src/main/java/net/minecraft/core/item/Item.java
index 8988e2a48..8eedf4059 100644
--- a/src/main/java/net/minecraft/core/item/Item.java
+++ b/src/main/java/net/minecraft/core/item/Item.java
@@ -1,6 +1,11 @@
 package net.minecraft.core.item;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
 import com.mojang.nbt.CompoundTag;
+
 import net.minecraft.core.achievement.stat.StatList;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.data.tag.ITaggable;
@@ -21,10 +26,6 @@ import net.minecraft.core.player.inventory.slot.Slot;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Random;
-
 // Referenced classes of package net.minecraft.src:
 //            ItemStack, StatCollector, ItemSpade, EnumToolMaterial, 
 //            ItemPickaxe, ItemAxe, ItemFlintAndSteel, ItemFood, 
@@ -37,6 +38,7 @@ import java.util.Random;
 //            ItemMap, ItemShears, ItemRecord, StatList, 
 //            EntityPlayer, World, EntityLiving, Entity
 
+@SuppressWarnings("unchecked")
 public class Item
     implements ITaggable<Item>, IItemConvertible
 {
@@ -250,6 +252,21 @@ public class Item
     public boolean showFullDurability() {
     	return false;
     }
+
+    @Override
+    public boolean isIn(Tag<Item> tag) {
+        return tag.appliesTo(this);
+    }
+
+    @Override
+    public Item asItem() {
+        return this;
+    }
+
+    @Override
+    public ItemStack getDefaultStack() {
+        return new ItemStack(this);
+    }
     
     protected static Random itemRand = new Random();
     public static final Map<String, Integer> nameToIdMap = new HashMap<>();
@@ -383,7 +400,7 @@ public class Item
     public static Item armorLeggingsSteel = (new ItemArmor("armor.leggings.steel", 16491, ArmorMaterial.STEEL, 2));
     public static Item armorBootsSteel = (new ItemArmor("armor.boots.steel", 16492, ArmorMaterial.STEEL, 3));
 
-    public static Item toolSwordSteel = (new ItemToolSword("tool.sword.steel", 16493, ToolMaterial.steel)).withTags(ItemTags.PREVENT_CREATIVE_MINING);
+	public static Item toolSwordSteel = (new ItemToolSword("tool.sword.steel", 16493, ToolMaterial.steel)).withTags(ItemTags.PREVENT_CREATIVE_MINING);
     public static Item toolShovelSteel = (new ItemToolShovel("tool.shovel.steel", 16494, ToolMaterial.steel));
     public static Item toolPickaxeSteel = (new ItemToolPickaxe("tool.pickaxe.steel", 16495, ToolMaterial.steel));
     public static Item toolAxeSteel = (new ItemToolAxe("tool.axe.steel", 16496, ToolMaterial.steel));
@@ -436,22 +453,15 @@ public class Item
     protected boolean hasSubtypes;
     private Item containerItem;
     private String key;
+    
     public static void initializeItems(){
         StatList.onItemInit();
     }
-
-    @Override
-    public boolean isIn(Tag<Item> tag) {
-        return tag.appliesTo(this);
-    }
-
-    @Override
-    public Item asItem() {
-        return this;
-    }
-
-    @Override
-    public ItemStack getDefaultStack() {
-        return new ItemStack(this);
+    
+    public static boolean hasTag(ItemStack itemStack, Tag<Item> tag) {
+    	if(itemStack == null) {
+    		return false;
+    	}
+    	return tag.appliesTo(itemsList[itemStack.itemID]);
     }
 }
diff --git a/src/main/java/net/minecraft/core/item/ItemFirestriker.java b/src/main/java/net/minecraft/core/item/ItemFirestriker.java
index a9f079511..08636dc7d 100644
--- a/src/main/java/net/minecraft/core/item/ItemFirestriker.java
+++ b/src/main/java/net/minecraft/core/item/ItemFirestriker.java
@@ -5,6 +5,7 @@ package net.minecraft.core.item;
 //            ItemStack, EntityPlayer
 
 import net.minecraft.core.entity.player.EntityPlayer;
+import net.minecraft.core.item.material.ToolMaterial;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.block.Block;
@@ -17,7 +18,7 @@ public class ItemFirestriker extends Item
     {
         super(name, id);
         maxStackSize = 1;
-        setMaxDamage(128);
+        setMaxDamage(ToolMaterial.iron.getDurability()/2);
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/core/item/ItemFishingRod.java b/src/main/java/net/minecraft/core/item/ItemFishingRod.java
index 4429b3073..e617831de 100644
--- a/src/main/java/net/minecraft/core/item/ItemFishingRod.java
+++ b/src/main/java/net/minecraft/core/item/ItemFishingRod.java
@@ -14,7 +14,7 @@ public class ItemFishingRod extends Item
     public ItemFishingRod(String name, int id)
     {
         super(name, id);
-        setMaxDamage(64);
+        setMaxDamage(196);
         setMaxStackSize(1);
     }
 
diff --git a/src/main/java/net/minecraft/core/item/ItemPlaceable.java b/src/main/java/net/minecraft/core/item/ItemPlaceable.java
index 2b9658955..c84c929eb 100644
--- a/src/main/java/net/minecraft/core/item/ItemPlaceable.java
+++ b/src/main/java/net/minecraft/core/item/ItemPlaceable.java
@@ -21,15 +21,21 @@ public class ItemPlaceable extends Item {
 		if(stack.stackSize <= 0) {
 			return false;
 		}
+		boolean placedInside = false;
 		if(!world.canPlaceInsideBlock(blockX, blockY, blockZ)) {
 			blockX += side.getOffsetX();
 			blockY += side.getOffsetY();
 			blockZ += side.getOffsetZ();
+		} else {
+			placedInside = true;
 		}
 		if(blockY < 0 || blockY >= world.getHeightBlocks()) {
 			return false;
 		}
 		if(world.canBlockBePlacedAt(blockToPlace.id, blockX, blockY, blockZ, false, side) && stack.consumeItem(player)) {
+			if (placedInside){
+				world.playSoundEffect(2001, blockX, blockY, blockZ, world.getBlockId(blockX, blockY, blockZ));
+			}
 			if(world.setBlockWithNotify(blockX, blockY, blockZ, blockToPlace.id)) {
 				blockToPlace.onBlockPlaced(world, blockX, blockY, blockZ, side, player, yPlaced);
 				world.playBlockSoundEffect(player, blockX + 0.5F, blockY + 0.5F, blockZ + 0.5F, blockToPlace, EnumBlockSoundEffectType.PLACE);
diff --git a/src/main/java/net/minecraft/core/item/ItemRope.java b/src/main/java/net/minecraft/core/item/ItemRope.java
index 14b410cda..3154cdbfd 100644
--- a/src/main/java/net/minecraft/core/item/ItemRope.java
+++ b/src/main/java/net/minecraft/core/item/ItemRope.java
@@ -30,15 +30,21 @@ public class ItemRope extends ItemPlaceable{
             }
 
         }
+        boolean placedInside = false;
         if(!world.canPlaceInsideBlock(blockX, blockY, blockZ)) {
             blockX += side.getOffsetX();
             blockY += side.getOffsetY();
             blockZ += side.getOffsetZ();
+        } else {
+            placedInside = true;
         }
         if(blockY < 0 || blockY >= world.getHeightBlocks()) {
             return false;
         }
         if(world.canBlockBePlacedAt(blockToPlace.id, blockX, blockY, blockZ, false, side) && stack.consumeItem(player)) {
+            if (placedInside){
+                world.playSoundEffect(2001, blockX, blockY, blockZ, world.getBlockId(blockX, blockY, blockZ));
+            }
             if(world.setBlockAndMetadataWithNotify(blockX, blockY, blockZ, blockToPlace.id, placeOnSide ? 0b1000_0000 : 0)) {
                 blockToPlace.onBlockPlaced(world, blockX, blockY, blockZ, side, player, yPlaced);
                 world.playBlockSoundEffect(player, blockX + 0.5F, blockY + 0.5F, blockZ + 0.5F, blockToPlace, EnumBlockSoundEffectType.PLACE);
diff --git a/src/main/java/net/minecraft/core/item/block/ItemBlock.java b/src/main/java/net/minecraft/core/item/block/ItemBlock.java
index 9ef5817b0..86697b6ea 100644
--- a/src/main/java/net/minecraft/core/item/block/ItemBlock.java
+++ b/src/main/java/net/minecraft/core/item/block/ItemBlock.java
@@ -34,19 +34,26 @@ public class ItemBlock extends Item
 		if(stack.stackSize <= 0) {
 			return false;
 		}
+        boolean placedInside = false;
 		if(!world.canPlaceInsideBlock(blockX, blockY, blockZ)) {
 			blockX += side.getOffsetX();
 			blockY += side.getOffsetY();
 			blockZ += side.getOffsetZ();
-		}
+		} else {
+            placedInside = true;
+        }
         if(blockY < 0 || blockY >= world.getHeightBlocks()) {
         	return false;
         }
 		if(world.canBlockBePlacedAt(blockID, blockX, blockY, blockZ, false, side) && stack.consumeItem(player)) {
 			Block block = Block.blocksList[blockID];
+            if (placedInside){
+                world.playSoundEffect(2001, blockX, blockY, blockZ, world.getBlockId(blockX, blockY, blockZ));
+            }
 			if(world.setBlockAndMetadataWithNotify(blockX, blockY, blockZ, blockID, getPlacedBlockMetadata(stack.getMetadata()))) {
 				block.onBlockPlaced(world, blockX, blockY, blockZ, side, player, yPlaced);
 				world.playBlockSoundEffect(player, blockX + 0.5F, blockY + 0.5F, blockZ + 0.5F, block, EnumBlockSoundEffectType.PLACE);
+
 			}
 			return true;
 		}
diff --git a/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java b/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java
index a6181b7f1..466ffb0ea 100644
--- a/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java
+++ b/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java
@@ -53,7 +53,11 @@ public class ItemBlockLadder extends ItemBlock {
 	}
 	
 	public boolean placeBlock(World world, int x, int y, int z, int meta, EntityPlayer player, ItemStack stack, Side side, double sideHeight) {
+		Block currentBlock = world.getBlock(x, y, z);
 		if(world.canPlaceInsideBlock(x, y, z) && world.canBlockBePlacedAt(blockID, x, y, z, false, side) && stack.consumeItem(player)) {
+			if (currentBlock != null){
+				world.playSoundEffect(2001, x, y, z, world.getBlockId(x, y, z));
+			}
 			if(world.setBlockAndMetadataWithNotify(x, y, z, blockID, meta)) {
 				Block.getBlock(blockID).onBlockPlaced(world, x, y, z, side, player, sideHeight);
 				world.playBlockSoundEffect(player, x + 0.5f, y + 0.5f, z + 0.5f, blockLadder, EnumBlockSoundEffectType.PLACE);
diff --git a/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java b/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java
index fcd3349d1..54d70aedd 100644
--- a/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java
+++ b/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java
@@ -125,8 +125,13 @@ public class ItemBlockLayer extends ItemBlock
 		if (world.canBlockBePlacedAt(blockID, blockX, blockY, blockZ, false, side))
 		{
 			final Block block = Block.blocksList[blockID];
+			Block currentBlock = world.getBlock(blockX, blockY, blockZ);
+			boolean placedInside = currentBlock != null;
 			if (world.setBlockAndMetadataWithNotify(blockX, blockY, blockZ, blockID, getPlacedBlockMetadata(itemstack.getMetadata())))
 			{
+				if (placedInside){
+					world.playSoundEffect(2001, blockX, blockY, blockZ, currentBlock.id);
+				}
 				Block.blocksList[blockID].onBlockPlaced(world, blockX, blockY, blockZ, null, entityplayer, yPlaced);
 				world.playBlockSoundEffect(entityplayer, blockX + 0.5F, blockY + 0.5F, blockZ + 0.5F, block, EnumBlockSoundEffectType.PLACE);
 				itemstack.consumeItem(entityplayer);
diff --git a/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java b/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java
index a48d94434..f6b1252ff 100644
--- a/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java
+++ b/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java
@@ -122,8 +122,13 @@ public class ItemBlockLayerLeaves extends ItemBlock
 		if (world.canBlockBePlacedAt(blockID, blockX, blockY, blockZ, false, side))
 		{
 			final Block block = Block.blocksList[blockID];
-			if (world.setBlockAndMetadataWithNotify(blockX, blockY, blockZ, blockID, getPlacedBlockMetadata(itemstack.getMetadata()) | 0b10000000))
+			Block currentBlock = world.getBlock(blockX, blockY, blockZ);
+			boolean placedInside = currentBlock != null;
+			if (world.setBlockAndMetadataWithNotify(blockX, blockY, blockZ, blockID, getPlacedBlockMetadata(itemstack.getMetadata())))
 			{
+				if (placedInside){
+					world.playSoundEffect(2001, blockX, blockY, blockZ, currentBlock.id);
+				}
 				Block.blocksList[blockID].onBlockPlaced(world, blockX, blockY, blockZ, null, entityplayer, yPlaced);
 				world.playBlockSoundEffect(entityplayer, blockX + 0.5F, blockY + 0.5F, blockZ + 0.5F, block, EnumBlockSoundEffectType.PLACE);
 				itemstack.consumeItem(entityplayer);
diff --git a/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java b/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java
index d71455451..94d3a88a3 100644
--- a/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java
+++ b/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java
@@ -92,8 +92,13 @@ public class ItemBlockSlab extends ItemBlock
         if(world.canBlockBePlacedAt(blockID, blockX, blockY, blockZ, false, side))
         {
             Block block = Block.blocksList[blockID];
+            Block currentBlock = world.getBlock(blockX, blockY, blockZ);
+            boolean placedInside = currentBlock != null;
             if(world.setBlockAndMetadataWithNotify(blockX, blockY, blockZ, blockID, getPlacedBlockMetadata(itemstack.getMetadata())))
             {
+                if (placedInside){
+                    world.playSoundEffect(2001, blockX, blockY, blockZ, currentBlock.id);
+                }
             	Block.blocksList[blockID].onBlockPlaced(world, blockX, blockY, blockZ, side, entityplayer, yPlaced);
                 world.playBlockSoundEffect(entityplayer, blockX + 0.5F, blockY + 0.5F, blockZ + 0.5F, block, EnumBlockSoundEffectType.PLACE);
                 itemstack.consumeItem(entityplayer);
diff --git a/src/main/java/net/minecraft/core/item/material/ToolMaterial.java b/src/main/java/net/minecraft/core/item/material/ToolMaterial.java
index a68f34288..16625c3e7 100644
--- a/src/main/java/net/minecraft/core/item/material/ToolMaterial.java
+++ b/src/main/java/net/minecraft/core/item/material/ToolMaterial.java
@@ -4,10 +4,10 @@ public class ToolMaterial {
 	
 	public static final ToolMaterial wood = new ToolMaterial().setDurability(64).setEfficiency(2.0f, 4.0f).setMiningLevel(0);
 	public static final ToolMaterial stone = new ToolMaterial().setDurability(128).setEfficiency(4.0f, 6.0f).setMiningLevel(1);
-	public static final ToolMaterial iron = new ToolMaterial().setDurability(256).setEfficiency(6.0f, 8.0f).setMiningLevel(2);
+	public static final ToolMaterial iron = new ToolMaterial().setDurability(384).setEfficiency(6.0f, 8.0f).setMiningLevel(2);
 	public static final ToolMaterial steel = new ToolMaterial().setDurability(4608).setEfficiency(7.0f, 14.0f).setMiningLevel(3);
 	public static final ToolMaterial diamond = new ToolMaterial().setDurability(1536).setEfficiency(14.0f, 45.0f).setMiningLevel(3).setDamage(4).setBlockHitDelay(4);
-	public static final ToolMaterial gold = new ToolMaterial().setDurability(64).setEfficiency(4.0f, 8.0f).setMiningLevel(2).setSilkTouch(true);
+	public static final ToolMaterial gold = new ToolMaterial().setDurability(256).setEfficiency(7.0f, 12f).setMiningLevel(2).setSilkTouch(true);
 	
 	private int miningLevel;
 	private int durability;
diff --git a/src/main/java/net/minecraft/core/item/tag/ItemTags.java b/src/main/java/net/minecraft/core/item/tag/ItemTags.java
index 559e9155a..7114b752b 100644
--- a/src/main/java/net/minecraft/core/item/tag/ItemTags.java
+++ b/src/main/java/net/minecraft/core/item/tag/ItemTags.java
@@ -22,6 +22,10 @@ public abstract class ItemTags
      * Items with this tag will not be shown in the creative inventory.
      */
     public static Tag<Item> NOT_IN_CREATIVE_MENU = Tag.of("not_in_creative_menu");
+    /**
+     * Blocks like doors and levers should not be interacted with when mining them with an item with this tag
+     */
+    public static Tag<Item> PREVENT_LEFT_CLICK_INTERACTIONS = Tag.of("prevent_left_click_interactions");
 
     public static List<Tag<Item>> TAG_LIST;
 
diff --git a/src/main/java/net/minecraft/core/item/tool/ItemTool.java b/src/main/java/net/minecraft/core/item/tool/ItemTool.java
index 346890440..93c419b57 100644
--- a/src/main/java/net/minecraft/core/item/tool/ItemTool.java
+++ b/src/main/java/net/minecraft/core/item/tool/ItemTool.java
@@ -7,6 +7,7 @@ import net.minecraft.core.block.Block;
 import net.minecraft.core.item.Item;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.material.ToolMaterial;
+import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.world.World;
 
 public class ItemTool extends Item
@@ -16,10 +17,12 @@ public class ItemTool extends Item
 	private final int damageVsEntity;
 	protected ToolMaterial material;
 
+	@SuppressWarnings("unchecked")
 	protected ItemTool(String name, int id, int damageDealt, ToolMaterial toolMaterial, Tag<Block> tagEffectiveAgainst) {
 		super(name, id);
 		this.material = toolMaterial;
 		this.tagEffectiveAgainst = tagEffectiveAgainst;
+		withTags(ItemTags.PREVENT_LEFT_CLICK_INTERACTIONS);
 		
 		maxStackSize = 1;
 		setMaxDamage(toolMaterial.getDurability());
diff --git a/src/main/java/net/minecraft/core/sound/SoundTypes.java b/src/main/java/net/minecraft/core/sound/SoundTypes.java
index 70fe18aeb..5d0b32222 100644
--- a/src/main/java/net/minecraft/core/sound/SoundTypes.java
+++ b/src/main/java/net/minecraft/core/sound/SoundTypes.java
@@ -19,11 +19,14 @@ public class SoundTypes {
 	public static void registerSounds() {
 		register("ambient.cave.cave");
 		register("ambient.weather.thunder");
-		
+		register("ambient.weather.rain");
+
 		register("mob.skeleton");
 		register("mob.skeletonhurt");
 		register("mob.spider");
 		register("mob.spiderdeath");
+		register("mob.slime");
+		register("mob.slimeattack");
 		register("mob.ghast.charge");
 		register("mob.ghast.death");
 		register("mob.ghast.fireball");
@@ -31,6 +34,7 @@ public class SoundTypes {
 		register("mob.ghast.scream");
 		register("mob.zombiepig.zpig");
 		register("mob.zombiepig.zpighurt");
+		register("mob.zombiepig.zpigdeath");
 		register("mob.zombie");
 		register("mob.zombiehurt");
 		register("mob.zombiedeath");
@@ -60,6 +64,8 @@ public class SoundTypes {
 		register("random.breath");
 		register("random.click");
 		register("random.drr");
+		register("random.door_open");
+		register("random.door_close");
 		register("random.explode");
 		register("random.fizz");
 		register("random.fuse");
diff --git a/src/main/java/net/minecraft/core/world/AuroraProvider.java b/src/main/java/net/minecraft/core/world/AuroraProvider.java
index d81e4ab17..edf9f0ce0 100644
--- a/src/main/java/net/minecraft/core/world/AuroraProvider.java
+++ b/src/main/java/net/minecraft/core/world/AuroraProvider.java
@@ -15,12 +15,12 @@ public class AuroraProvider
         noise = new ImprovedNoise(new Random(seed));
     }
 
-    public float getAuroraPresence(float x, float z, long worldTime, float celestialAngle)
+    public double getAuroraPresence(double x, double z, long worldTime, float celestialAngle)
     {
-        float auroraLevel = 0.0f;
-        float auroraRadius = 0.03f;
+        double auroraLevel = 0.0f;
+        double auroraRadius = 0.03f;
 
-        float mult = 1.0f;
+        double mult = 1.0d;
         if (celestialAngle < 0.25f || celestialAngle > 0.75f)
         {
             return 0.0f;
@@ -39,8 +39,8 @@ public class AuroraProvider
             mult = celestialAngle;
         }
 
-        float sample = (float)noise.getValue(x / 1000, worldTime / 5000f, z / 1000);
-        sample += (float)noise.getValue(x / 30, worldTime / 50f, z / 30) * 0.05f;
+        double sample = noise.getValue(x / 1000d, worldTime / 5000d, z / 1000d);
+        sample += noise.getValue(x / 30d, worldTime / 50d, z / 30d) * 0.05d;
         if (sample < auroraLevel - auroraRadius || sample > auroraLevel + auroraRadius)
         {
             return 0.0f;
@@ -56,50 +56,49 @@ public class AuroraProvider
             // Range = 1.0 to 0.0 to 1.0
             sample = -sample;
             // Range = -1.0 to 0.0 to -1.0
-            sample += 1.0f;
+            sample += 1.0d;
             // Range = 0.0 to 1.0 to 0.0
             return sample * mult;
         }
     }
 
-    public float getAuroraHeightOffset(float x, float z, float worldTime)
+    public double getAuroraHeightOffset(double x, double z, double worldTime)
     {
-        float sample = (float)noise.getValue(x / 100, worldTime / 5000, z / 100) * 25;
-        return sample;
+        return noise.getValue(x / 100d, worldTime / 5000d, z / 100d) * 25d;
     }
 
-    public float getAuroraRedOffset(float x, float z, float worldTime)
+    public float getAuroraRedOffset(double x, double z, double worldTime)
     {
-        float sample = (float)noise.getValue(x / 500, worldTime / 5000 + 10000, z / 500);
-        float sample2 = (float)noise.getValue(x / 200, worldTime / 5000, z / 200);
+        double sample = noise.getValue(x / 500d, worldTime / 5000d + 10000, z / 500d);
+        double sample2 = noise.getValue(x / 200d, worldTime / 5000d, z / 200d);
         if (sample < 0.0f) sample = 0.0f;
         if (sample > 0.25f) sample = 0.25f;
         if (sample2 < 0.0f) sample2 = 0.0f;
         if (sample2 > 0.1f) sample2 = 0.1f;
 
 
-        return sample * 3 + sample2 * 2;
+        return (float) (sample * 3 + sample2 * 2);
     }
 
-    public float getAuroraGreenOffset(float x, float z, float worldTime)
+    public float getAuroraGreenOffset(double x, double z, double worldTime)
     {
-        float sample = (float)noise.getValue(x / 500, worldTime / 5000 + 10000, z / 500);
-        float sample2 = (float)noise.getValue(x / 500, worldTime / 5000, z / 500);
+        double sample = noise.getValue(x / 500d, worldTime / 5000d + 10000d, z / 500d);
+        double sample2 = noise.getValue(x / 500d, worldTime / 5000d, z / 500d);
         if (sample < 0) sample = 0;
         if (sample > 0.125f) sample = 0.125f;
         if (sample2 < 0.0f) sample2 = 0.0f;
         if (sample2 > 0.25f) sample2 = 0.25f;
 
 
-        return sample * 4 - sample2 * 2;
+        return (float) (sample * 4 - sample2 * 2);
     }
 
-    public float getAuroraBlueOffset(float x, float z, float worldTime)
+    public float getAuroraBlueOffset(double x, double z, double worldTime)
     {
-        float sample = (float)noise.getValue(x / 500, worldTime / 5000, z / 500);
+        double sample = noise.getValue(x / 500d, worldTime / 5000d, z / 500d);
         if (sample < 0.0f) sample = 0.0f;
         if (sample > 0.25f) sample = 0.25f;
 
-        return sample;
+        return (float) sample;
     }
 }
diff --git a/src/main/java/net/minecraft/core/world/SpawnerMobs.java b/src/main/java/net/minecraft/core/world/SpawnerMobs.java
index 386746d05..6ea3c8e13 100644
--- a/src/main/java/net/minecraft/core/world/SpawnerMobs.java
+++ b/src/main/java/net/minecraft/core/world/SpawnerMobs.java
@@ -1,15 +1,20 @@
 package net.minecraft.core.world;
 
+import net.minecraft.core.block.BlockBed;
+import net.minecraft.core.block.material.Material;
 import net.minecraft.core.data.gamerule.GameRules;
-import net.minecraft.core.entity.*;
-import net.minecraft.core.entity.monster.*;
+import net.minecraft.core.entity.EntityLiving;
+import net.minecraft.core.entity.SpawnListEntry;
+import net.minecraft.core.entity.monster.EntityArmoredZombie;
+import net.minecraft.core.entity.monster.EntitySkeleton;
+import net.minecraft.core.entity.monster.EntitySpider;
+import net.minecraft.core.entity.monster.EntityZombie;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.enums.EnumCreatureType;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.Vec3d;
 import net.minecraft.core.world.biome.Biome;
-import net.minecraft.core.block.BlockBed;
-import net.minecraft.core.block.material.Material;
+import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkCoordinate;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.ChunkPosition;
@@ -18,18 +23,8 @@ import net.minecraft.core.world.pathfinder.Path;
 import net.minecraft.core.world.pathfinder.PathFinder;
 
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
-
-
-// Referenced classes of package net.minecraft.src:
-//            World, ChunkPosition, EntityPlayer, MathHelper, 
-//            ChunkCoordIntPair, EnumCreatureType, WorldChunkManager, BiomeGenBase, 
-//            SpawnListEntry, ChunkCoordinates, EntityLiving, Material, 
-//            EntitySpider, EntitySkeleton, EntitySheep, Pathfinder, 
-//            PathEntity, PathPoint, BlockBed, EntityZombie
-
 public final class SpawnerMobs
 {
 
@@ -37,165 +32,155 @@ public final class SpawnerMobs
     {
     }
 
-    private static ChunkPosition getRandomSpawningPointInChunk(World world, int i, int j)
+    private static ChunkPosition getRandomSpawningPointInChunk(World world, int x, int z)
     {
-        int k = i + world.rand.nextInt(16);
-        int l = world.rand.nextInt(world.getHeightBlocks());
-        int i1 = j + world.rand.nextInt(16);
-        return new ChunkPosition(k, l, i1);
+        int newX = x + world.rand.nextInt(16);
+        int newY = world.rand.nextInt(world.getHeightBlocks());
+        int newZ = z + world.rand.nextInt(16);
+        return new ChunkPosition(newX, newY, newZ);
     }
 
     public static int performSpawning(World world, boolean spawnHostileMobs, boolean spawnPassiveMobs)
     {
-        if(!spawnHostileMobs && !spawnPassiveMobs)
-        {
-            return 0;
+        if(!spawnHostileMobs && !spawnPassiveMobs) { return 0; }
+        eligibleChunksForSpawning.clear();
+
+        for (EntityPlayer player : world.players){
+            final int playerChunkX = MathHelper.floor_double(player.x / Chunk.CHUNK_SIZE_X);
+            final int playerChunkZ = MathHelper.floor_double(player.z / Chunk.CHUNK_SIZE_Z);
+            final byte spawnRadius = 8;
+
+            for(int dx = -spawnRadius; dx <= spawnRadius; ++dx) {
+                for(int dz = -spawnRadius; dz <= spawnRadius; ++dz) {
+                    if(world.isChunkLoaded(dx + playerChunkX, dz + playerChunkZ)) {
+                        eligibleChunksForSpawning.add(new ChunkCoordinate(dx + playerChunkX, dz + playerChunkZ));
+                    }
+                }
+            }
         }
-        else
-        {
-            eligibleChunksForSpawning.clear();
 
-            int playerIndex;
-            for(playerIndex = 0; playerIndex < world.players.size(); ++playerIndex)
-            {
-                EntityPlayer player = world.players.get(playerIndex);
-                int playerChunkX = MathHelper.floor_double(player.x / 16.0D);
-                int playerChunkZ = MathHelper.floor_double(player.z / 16.0D);
-                byte spawnRadius = 8;
+        int totalSpawned = 0;
+        final ChunkCoordinates spawnChunk = world.getSpawnPoint();
+        final ChunkCoordinate[] spawnChunks = new ChunkCoordinate[3 * 3];
+        for (int x = 0; x < 3; x++) {
+            for (int z = 0; z < 3; z++) {
+                spawnChunks[x * 3 + z] = new ChunkCoordinate(spawnChunk.x + (x - 1), spawnChunk.z + (z - 1));
+            }
+        }
 
-                for(int dx = -spawnRadius; dx <= spawnRadius; ++dx)
-                {
-                    for(int dz = -spawnRadius; dz <= spawnRadius; ++dz)
-                    {
-                    	if(world.isChunkLoaded(dx + playerChunkX, dz + playerChunkZ)) {
-                    		eligibleChunksForSpawning.add(new ChunkCoordinate(dx + playerChunkX, dz + playerChunkZ));
-                    	}
+
+        for (EnumCreatureType creatureType : EnumCreatureType.values()) {
+
+            if (creatureType.getPeacefulCreature() && !spawnPassiveMobs) continue;
+            if (!creatureType.getPeacefulCreature() && !spawnHostileMobs) continue;
+            if (world.countEntities(creatureType.getCreatureClass()) > ((creatureType.getMaxNumberOfCreature() * eligibleChunksForSpawning.size()) / 256))
+                continue;
+
+            for (ChunkCoordinate chunk : eligibleChunksForSpawning) {
+                boolean checkSpawnDist = false;
+                for (ChunkCoordinate c : spawnChunks){
+                    if (c.equals(chunk)){
+                        checkSpawnDist = true;
+                        break;
                     }
                 }
-            }
 
-            playerIndex = 0;
-            ChunkCoordinates spawnChunk = world.getSpawnPoint();
-            EnumCreatureType[] creatureTypes = EnumCreatureType.values();
+                final int blockX = chunk.x * Chunk.CHUNK_SIZE_X;
+                final int blockZ = chunk.z * Chunk.CHUNK_SIZE_Z;
+                final Biome biome = world.getBlockBiome(blockX, world.getHeightBlocks() - 1, blockZ);
+                final List<SpawnListEntry> spawnableList = biome.getSpawnableList(creatureType);
 
-            for(int i = 0; i < creatureTypes.length; ++i)
-            {
-                EnumCreatureType creatureType = creatureTypes[i];
-                if((!creatureType.getPeacefulCreature() || spawnPassiveMobs) && (creatureType.getPeacefulCreature() || spawnHostileMobs) && world.countEntities(creatureType.getCreatureClass()) <= creatureType.getMaxNumberOfCreature() * eligibleChunksForSpawning.size() / 256)
-                {
-                    Iterator<ChunkCoordinate> chunkIt = eligibleChunksForSpawning.iterator();
+                if (spawnableList == null) continue;
+                if (spawnableList.isEmpty()) continue;
 
-                    label113:
-                    while(chunkIt.hasNext())
-                    {
-                        ChunkCoordinate chunk = chunkIt.next();
-                        Biome biome = world.getBlockBiome(chunk.x * 16, world.getHeightBlocks() - 1, chunk.z * 16);
-                        List<SpawnListEntry> spawnableList = biome.getSpawnableList(creatureType);
-                        if(spawnableList != null && !spawnableList.isEmpty())
-                        {
-                            int totalSpawnRarity = 0;
+                int totalSpawnRarity = 0;
 
-                            SpawnListEntry spawnListEntry;
-                            for (SpawnListEntry listEntry : spawnableList)
-                            {
-                                totalSpawnRarity += listEntry.spawnFrequency;
-                            }
+                SpawnListEntry spawnListEntry;
+                for (SpawnListEntry listEntry : spawnableList) {
+                    totalSpawnRarity += listEntry.spawnFrequency;
+                }
 
-                            int calculatedSpawnChance = world.rand.nextInt(totalSpawnRarity);
-                            spawnListEntry = spawnableList.get(0);
+                int calculatedSpawnChance = world.rand.nextInt(totalSpawnRarity);
+                spawnListEntry = spawnableList.get(0);
 
-                            for (SpawnListEntry listEntry : spawnableList)
-                            {
-                                calculatedSpawnChance -= listEntry.spawnFrequency;
-                                if (calculatedSpawnChance < 0)
-                                {
-                                    spawnListEntry = listEntry;
-                                    break;
-                                }
-                            }
-
-                            ChunkPosition pos = getRandomSpawningPointInChunk(world, chunk.x * 16, chunk.z * 16);
-                            int x = pos.x;
-                            int y = pos.y;
-                            int z = pos.z;
-                            if(!world.isBlockNormalCube(x, y, z) && world.getBlockMaterial(x, y, z) == creatureType.getCreatureMaterial())
-                            {
-                                int countSpawned = 0;
-
-                                for(int tryToSpawnX = 0; tryToSpawnX < 3; ++tryToSpawnX)
-                                {
-                                    int ix = x;
-                                    int iy = y;
-                                    int iz = z;
-                                    byte range = 6;
-
-                                    for(int tryToSpawnZ = 0; tryToSpawnZ < 4; ++tryToSpawnZ)
-                                    {
-                                        ix += world.rand.nextInt(range) - world.rand.nextInt(range);
-                                        iy += world.rand.nextInt(2) - world.rand.nextInt(2);
-                                        iz += world.rand.nextInt(range) - world.rand.nextInt(range);
-                                        if(canCreatureTypeSpawnAtLocation(creatureType, world, ix, iy, iz))
-                                        {
-                                            float dx = (float)ix + 0.5F;
-                                            float dy = (float)iy;
-                                            float dz = (float)iz + 0.5F;
-                                            if(world.getClosestPlayer(dx, dy, dz, 24.0D) == null)
-                                            {
-                                                float spawnDistanceX = dx - (float)spawnChunk.x;
-                                                float spawnDistanceY = dy - (float)spawnChunk.y;
-                                                float spawnDistanceZ = dz - (float)spawnChunk.z;
-                                                float spawnDistanceSquared = spawnDistanceX * spawnDistanceX + spawnDistanceY * spawnDistanceY + spawnDistanceZ * spawnDistanceZ;
-                                                if(spawnDistanceSquared >= 576.0F)
-                                                {
-                                                    EntityLiving mobToSpawn;
-
-                                                    try
-                                                    {
-                                                        mobToSpawn = (EntityLiving)spawnListEntry.entityClass.getConstructor(new Class[]{World.class}).newInstance(new Object[]{world});
-                                                    }
-                                                    catch (Exception e)
-                                                    {
-                                                        e.printStackTrace();
-                                                        return playerIndex;
-                                                    }
-
-                                                    mobToSpawn.moveTo(dx, dy, dz, world.rand.nextFloat() * 360.0F, 0.0F);
-                                                    if(mobToSpawn.getCanSpawnHere())
-                                                    {
-
-                                                        ++countSpawned;
-                                                        mobToSpawn.spawnInit();
-                                                        world.entityJoinedWorld(mobToSpawn);
-                                                        if(countSpawned >= mobToSpawn.getMaxSpawnedInChunk())
-                                                        {
-                                                            continue label113;
-                                                        }
-                                                    }
-
-                                                    playerIndex += countSpawned;
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
+                for (SpawnListEntry listEntry : spawnableList) {
+                    calculatedSpawnChance -= listEntry.spawnFrequency;
+                    if (calculatedSpawnChance < 0) {
+                        spawnListEntry = listEntry;
+                        break;
+                    }
+                }
+
+                final ChunkPosition pos = getRandomSpawningPointInChunk(world, blockX, blockZ);
+                final int x = pos.x;
+                final int y = pos.y;
+                final int z = pos.z;
+                if (/*world.isBlockNormalCube(x, y, z) || */world.getBlockMaterial(x, y, z) != creatureType.getCreatureMaterial())
+                    continue;
+
+                int countSpawned = 0;
+
+                final byte range = 6;
+
+                for (int i = 0; i < 3; i++) {
+                    int ix = x;
+                    int iy = y;
+                    int iz = z;
+                    for (int spawnAttempt = 0; spawnAttempt < 4; ++spawnAttempt) {
+                        ix += world.rand.nextInt(range) - world.rand.nextInt(range);
+                        iy += world.rand.nextInt(2) - world.rand.nextInt(2);
+                        iz += world.rand.nextInt(range) - world.rand.nextInt(range);
+                        if (!canCreatureTypeSpawnAtLocation(creatureType, world, ix, iy, iz)) continue;
+
+                        final double dx = ix + 0.5D;
+                        final double dy = iy;
+                        final double dz = iz + 0.5D;
+                        if (world.getClosestPlayer(dx, dy, dz, 24.0D) != null) continue;
+
+                        // Forbid mob spawning in a 24 block radius around spawn
+                        if (checkSpawnDist) {
+                            final double spawnDistanceX = dx - spawnChunk.x;
+                            final double spawnDistanceY = dy - spawnChunk.y;
+                            final double spawnDistanceZ = dz - spawnChunk.z;
+                            final double spawnDistanceSquared = spawnDistanceX * spawnDistanceX + spawnDistanceY * spawnDistanceY + spawnDistanceZ * spawnDistanceZ;
+                            if (spawnDistanceSquared < 576.0F) continue;
+                        }
+
+                        EntityLiving mobToSpawn;
+                        try {
+                            mobToSpawn = (EntityLiving) spawnListEntry.entityClass.getConstructor(new Class[]{World.class}).newInstance(new Object[]{world});
+                        } catch (Exception e) {
+                            new RuntimeException("Error spawning entity class '" + spawnListEntry.entityClass.getSimpleName() + "' class missing default constructor for World! Skipping spawn attempt!", e).printStackTrace();
+                            return totalSpawned;
+                        }
+
+                        mobToSpawn.moveTo(dx, dy, dz, world.rand.nextFloat() * 360.0F, 0.0F);
+                        if (!mobToSpawn.getCanSpawnHere()) {
+                            continue;
+                        }
+
+                        ++countSpawned;
+                        mobToSpawn.spawnInit();
+                        world.entityJoinedWorld(mobToSpawn);
+                        if (countSpawned >= mobToSpawn.getMaxSpawnedInChunk()) {
+                            break;
                         }
                     }
                 }
+                totalSpawned += countSpawned;
             }
-
-            return playerIndex;
         }
+        return totalSpawned;
     }
 
-    private static boolean canCreatureTypeSpawnAtLocation(EnumCreatureType enumcreaturetype, World world, int i, int j, int k)
+    private static boolean canCreatureTypeSpawnAtLocation(EnumCreatureType enumcreaturetype, World world, int x, int y, int z)
     {
         if(enumcreaturetype.getCreatureMaterial() == Material.water)
         {
-            return world.getBlockMaterial(i, j, k).isLiquid() && !world.isBlockNormalCube(i, j + 1, k);
+            return world.getBlockMaterial(x, y, z).isLiquid() && !world.isBlockNormalCube(x, y + 1, z);
         } else
         {
-            return world.isBlockNormalCube(i, j - 1, k) && !world.isBlockNormalCube(i, j, k) && !world.getBlockMaterial(i, j, k).isLiquid();
+            return world.isBlockNormalCube(x, y - 1, z) && !world.isBlockNormalCube(x, y, z) && !world.getBlockMaterial(x, y, z).isLiquid();
         }
     }
 
diff --git a/src/main/java/net/minecraft/core/world/World.java b/src/main/java/net/minecraft/core/world/World.java
index b53887f60..f050ae9ef 100644
--- a/src/main/java/net/minecraft/core/world/World.java
+++ b/src/main/java/net/minecraft/core/world/World.java
@@ -17,6 +17,7 @@ import com.mojang.nbt.CompoundTag;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.colorizer.Colorizers;
+import net.minecraft.client.util.debug.Debug;
 import net.minecraft.client.world.chunk.provider.ChunkProviderViewer;
 import net.minecraft.core.Global;
 import net.minecraft.core.HitResult;
@@ -74,7 +75,7 @@ public class World implements WorldSource {
     public static boolean AUTOSAVE = true;
 
     private final int heightBlocks = 256;
-    private int heightBits = -1;
+    private final int heightBits = -1;
     private final List<LightUpdate> lightingToUpdate = new LinkedList<>();
     public List<Entity> loadedEntityList = new ArrayList<>();
     private final List<Entity> unloadedEntityList = new ArrayList<>();
@@ -91,7 +92,7 @@ public class World implements WorldSource {
     private final Set<NextTickListEntry> immediatelyUpdatedPositions = new HashSet<>();
     
     public boolean scheduledUpdatesAreImmediate = false;
-    private int dimensionColor = 0xffffff;
+    private final int dimensionColor = 0xffffff;
     public int skyDarken = 0;
     protected int updateLCG = new Random().nextInt();
     public int lightningFlicker = 0;
@@ -1098,7 +1099,7 @@ public class World implements WorldSource {
 		int skyLight = getSavedLightValue(LightLayer.Sky, x, y, z);
 		int blockLight = Math.max(getSavedLightValue(LightLayer.Block, x, y, z), blockLightValue);
 		
-		if(getBlockLitInteriorSurface(x, y, z)) {
+		if(getBlockLitInteriorSurface(x, y, z) || !isBlockOpaqueCube(x, y, z)) {
 			skyLight = Math.max(skyLight, getSavedLightValue(LightLayer.Sky, x, y + 1, z));
 			skyLight = Math.max(skyLight, getSavedLightValue(LightLayer.Sky, x, y - 1, z));
 			skyLight = Math.max(skyLight, getSavedLightValue(LightLayer.Sky, x + 1, y, z));
@@ -1387,11 +1388,7 @@ public class World implements WorldSource {
     {
         int i = MathHelper.floor_double(entity.x / Chunk.CHUNK_SIZE_X);
         int j = MathHelper.floor_double(entity.z / Chunk.CHUNK_SIZE_Z);
-        boolean flag = false;
-        if(entity instanceof EntityPlayer)
-        {
-            flag = true;
-        }
+        boolean flag = entity instanceof EntityPlayer;
         if(flag || isChunkLoaded(i, j))
         {
             if(entity instanceof EntityPlayer)
@@ -1415,7 +1412,7 @@ public class World implements WorldSource {
     {
         for(int i = 0; i < listeners.size(); i++)
         {
-            ((LevelListener) listeners.get(i)).entityAdded(entity);
+            listeners.get(i).entityAdded(entity);
         }
 
     }
@@ -1424,7 +1421,7 @@ public class World implements WorldSource {
     {
         for(int i = 0; i < listeners.size(); i++)
         {
-            ((LevelListener) listeners.get(i)).entityRemoved(entity);
+            listeners.get(i).entityRemoved(entity);
         }
 
     }
@@ -1641,7 +1638,7 @@ public class World implements WorldSource {
             f12 *= 0.45F;
             r = r * (1.0F - f12) + 0.8F * f12;
             g = g * (1.0F - f12) + 0.8F * f12;
-            b = b * (1.0F - f12) + 1.0F * f12;
+            b = b * (1.0F - f12) + f12;
         }
         return Vec3d.createVector(r, g, b);
     }
@@ -1781,7 +1778,7 @@ public class World implements WorldSource {
     {
         for(int i = 0; i < weatherEffects.size(); i++)
         {
-            Entity entity = (Entity)weatherEffects.get(i);
+            Entity entity = weatherEffects.get(i);
             entity.tick();
             if(entity.removed)
             {
@@ -1792,7 +1789,7 @@ public class World implements WorldSource {
         loadedEntityList.removeAll(unloadedEntityList);
         for(int j = 0; j < unloadedEntityList.size(); j++)
         {
-            Entity entity1 = (Entity)unloadedEntityList.get(j);
+            Entity entity1 = unloadedEntityList.get(j);
             int i1 = entity1.chunkCoordX;
             int k1 = entity1.chunkCoordZ;
             if(entity1.addedToChunk && isChunkLoaded(i1, k1))
@@ -1803,13 +1800,13 @@ public class World implements WorldSource {
 
         for(int k = 0; k < unloadedEntityList.size(); k++)
         {
-            releaseEntitySkin((Entity)unloadedEntityList.get(k));
+            releaseEntitySkin(unloadedEntityList.get(k));
         }
 
         unloadedEntityList.clear();
         for(int l = 0; l < loadedEntityList.size(); l++)
         {
-            Entity entity2 = (Entity)loadedEntityList.get(l);
+            Entity entity2 = loadedEntityList.get(l);
             if(entity2.vehicle != null)
             {
                 if(!entity2.vehicle.isRemoved() && entity2.vehicle.getPassenger() == entity2)
@@ -2057,33 +2054,7 @@ public class World implements WorldSource {
 
     public boolean isBoundingBoxBurning(AABB axisalignedbb)
     {
-        int i = MathHelper.floor_double(axisalignedbb.minX);
-        int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D);
-        int k = MathHelper.floor_double(axisalignedbb.minY);
-        int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D);
-        int i1 = MathHelper.floor_double(axisalignedbb.minZ);
-        int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D);
-        if(areBlocksLoaded(i, k, i1, j, l, j1))
-        {
-            for(int k1 = i; k1 < j; k1++)
-            {
-                for(int l1 = k; l1 < l; l1++)
-                {
-                    for(int i2 = i1; i2 < j1; i2++)
-                    {
-                        int j2 = getBlockId(k1, l1, i2);
-                        if(j2 == Block.fire.id || j2 == Block.fluidLavaFlowing.id || j2 == Block.fluidLavaStill.id || j2 == Block.netherrackIgneous.id)
-                        {
-                            return true;
-                        }
-                    }
-
-                }
-
-            }
-
-        }
-        return false;
+        return isMaterialInBB(axisalignedbb, Material.fire, Material.lava);
     }
 
     public boolean handleMaterialAcceleration(AABB axisalignedbb, Material material, Entity entity, boolean addVelocity)
@@ -2107,16 +2078,12 @@ public class World implements WorldSource {
                 for(int i2 = i1; i2 < j1; i2++)
                 {
                     Block block = Block.blocksList[getBlockId(k1, l1, i2)];
-                    if(block == null || block.blockMaterial != material)
+                    if(block == null || !isMaterialInBB(axisalignedbb, material))
                     {
                         continue;
                     }
-                    double d1 = (float)(l1 + 1) - BlockFluid.getWaterVolume(getBlockMetadata(k1, l1, i2));
-                    if((double)l >= d1)
-                    {
-                        flag = true;
-                        block.handleEntityInside(this, k1, l1, i2, entity, vec3d);
-                    }
+                    flag = true;
+                    block.handleEntityInside(this, k1, l1, i2, entity, vec3d);
                 }
 
             }
@@ -2134,29 +2101,41 @@ public class World implements WorldSource {
         return flag;
     }
 
-    public boolean isMaterialInBB(AABB axisalignedbb, Material material)
+    public boolean isMaterialInBB(AABB axisalignedbb, Material ... materials)
     {
-        int i = MathHelper.floor_double(axisalignedbb.minX);
-        int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D);
-        int k = MathHelper.floor_double(axisalignedbb.minY);
-        int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D);
-        int i1 = MathHelper.floor_double(axisalignedbb.minZ);
-        int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D);
-        for(int k1 = i; k1 < j; k1++)
+        int minX_i = MathHelper.floor_double(axisalignedbb.minX);
+        int maxX_i = MathHelper.floor_double(axisalignedbb.maxX + 1.0D);
+        int minY_i = MathHelper.floor_double(axisalignedbb.minY);
+        int maxY_i = MathHelper.floor_double(axisalignedbb.maxY + 1.0D);
+        int minZ_i = MathHelper.floor_double(axisalignedbb.minZ);
+        int maxZ_i = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D);
+        for(int _x = minX_i; _x < maxX_i; _x++)
         {
-            for(int l1 = k; l1 < l; l1++)
+            for(int _y = minY_i; _y < maxY_i; _y++)
             {
-                for(int i2 = i1; i2 < j1; i2++)
+                for(int _z = minZ_i; _z < maxZ_i; _z++)
                 {
-                    Block block = Block.blocksList[getBlockId(k1, l1, i2)];
-                    if(block != null && block.blockMaterial == material)
-                    {
-                        return true;
+                    Block block = Block.blocksList[getBlockId(_x, _y, _z)];
+                    if(block != null) {
+                        boolean isMaterial = false;
+                        for (Material m : materials){
+                            if (block.blockMaterial == m) {
+                                isMaterial = true;
+                                break;
+                            }
+                        }
+                        if (!isMaterial) continue;
+
+                        block.setBlockBoundsBasedOnState(this, _x, _y, _z);
+                        if (axisalignedbb.intersectsWith(
+                            AABB.getBoundingBoxFromPool(_x + block.minZ, _y + block.minY, _z + block.minZ,
+                                _x + block.maxZ, _y + block.maxY, _z + block.maxZ))){
+                            return true;
+                        }
+
                     }
                 }
-
             }
-
         }
 
         return false;
@@ -2200,20 +2179,20 @@ public class World implements WorldSource {
         return false;
     }
 
-    public Explosion createExplosion(Entity entity, double d, double d1, double d2, 
-            float f)
+    public Explosion createExplosion(Entity entity, double x, double y, double z,
+                                     float explosionSize)
     {
-        return newExplosion(entity, d, d1, d2, f, false, false);
+        return newExplosion(entity, x, y, z, explosionSize, false, false);
     }
 
-    public Explosion newExplosion(Entity entity, double d, double d1, double d2, float f, boolean flag, boolean isCannonBall)
+    public Explosion newExplosion(Entity entity, double x, double y, double z, float explosionSize, boolean flaming, boolean isCannonBall)
     {
         Explosion explosion;
         if(!isCannonBall)
-            explosion = new Explosion(this, entity, d, d1, d2, f);
+            explosion = new Explosion(this, entity, x, y, z, explosionSize);
         else
-            explosion = new ExplosionCannonball(this, entity, d, d1, d2, f);
-        explosion.isFlaming = flag;
+            explosion = new ExplosionCannonball(this, entity, x, y, z, explosionSize);
+        explosion.isFlaming = flaming;
         explosion.doExplosionA();
         explosion.doExplosionB(true);
         return explosion;
@@ -2510,12 +2489,19 @@ public class World implements WorldSource {
     }
 
 	public void tick() {
+        Debug.push("misc");
 		immediatelyUpdatedPositions.clear();
+        Debug.change("weather");
 		weatherManager.tick();
+        Debug.change("misc");
 		updateSleepingPlayers();
+        Debug.change("spawning");
+        // TODO mob spawning seems to be the cause of many lag spikes, specifically the checks for is a mob is allowed to spawn at a certain xyz position seem to be the worst offenders
 		SpawnerMobs.performSpawning(this, spawnHostileMobs, spawnPeacefulMobs);
+        Debug.change("chunk");
 		chunkProvider.tick();
 
+        Debug.change("autosave");
 		int autosaveTimeInSeconds = Global.accessor.getAutosaveTimer();
 		int autosaveTimeInTicks = (autosaveTimeInSeconds * 20);
 
@@ -2524,6 +2510,7 @@ public class World implements WorldSource {
 			saveWorld(false, null, true);
 		}
 
+        Debug.change("misc");
 		if(getGameRuleValue(GameRules.DO_DAY_CYCLE)) {
 			levelData.setWorldTime(levelData.getWorldTime() + 1L);
 		}
@@ -2531,8 +2518,11 @@ public class World implements WorldSource {
 		runtime++;
 
 		tickUpdates(false);
+        Debug.change("blocks&cavesSounds");
 		updateBlocksAndPlayCaveSounds();
+        Debug.change("season&light");
 		updateSeasonAndLight();
+        Debug.pop();
 	}
 	
 	public void updateSeasonAndLight() {
@@ -2641,7 +2631,7 @@ public class World implements WorldSource {
         }
         for(int j = 0; j < count; j++)
         {
-            NextTickListEntry entry = (NextTickListEntry)scheduledTickTreeSet.first();
+            NextTickListEntry entry = scheduledTickTreeSet.first();
             if(!all && entry.delay > runtime)
             {
                 break;
@@ -2741,14 +2731,11 @@ public class World implements WorldSource {
         }
     }
 
-    public int countEntities(Class class1)
+    public int countEntities(Class<?> clazz)
     {
         int i = 0;
-        for(int j = 0; j < loadedEntityList.size(); j++)
-        {
-            Entity entity = (Entity)loadedEntityList.get(j);
-            if(class1.isAssignableFrom(entity.getClass()))
-            {
+        for (Entity entity : loadedEntityList) {
+            if (clazz.isAssignableFrom(entity.getClass())) {
                 i++;
             }
         }
@@ -2756,17 +2743,17 @@ public class World implements WorldSource {
         return i;
     }
 
-    public void addLoadedEntities(List list)
+    public void addLoadedEntities(List<Entity> list)
     {
         loadedEntityList.addAll(list);
         for(int i = 0; i < list.size(); i++)
         {
-            obtainEntitySkin((Entity)list.get(i));
+            obtainEntitySkin(list.get(i));
         }
 
     }
 
-    public void unloadEntities(List list)
+    public void unloadEntities(List<Entity> list)
     {
         unloadedEntityList.addAll(list);
     }
@@ -2917,29 +2904,26 @@ public class World implements WorldSource {
 
     public EntityPlayer getClosestPlayer(double x, double y, double z, double radius)
     {
-        double closestDistance = -1D;
+        if (radius < 0) return null;
+
+        double closestDistance = Double.POSITIVE_INFINITY;
         EntityPlayer entityplayer = null;
-        for(int i = 0; i < players.size(); i++)
-        {
-            EntityPlayer entityPlayer1 = players.get(i);
+
+        for (EntityPlayer entityPlayer1 : players) {
             double currentDistance = entityPlayer1.distanceToSqr(x, y, z);
-            if((radius < 0.0D || currentDistance < radius * radius) && (closestDistance == -1D || currentDistance < closestDistance))
-            {
+            if (currentDistance < radius * radius && (currentDistance < closestDistance)) {
                 closestDistance = currentDistance;
                 entityplayer = entityPlayer1;
             }
         }
-
         return entityplayer;
     }
 
     public EntityPlayer getPlayerEntityByName(String s)
     {
-        for(int i = 0; i < players.size(); i++)
-        {
-            if(s.equals(((EntityPlayer)players.get(i)).username))
-            {
-                return (EntityPlayer)players.get(i);
+        for (EntityPlayer player : players) {
+            if (s.equals(player.username)) {
+                return player;
             }
         }
 
@@ -3133,7 +3117,7 @@ public class World implements WorldSource {
         loadedEntityList.removeAll(unloadedEntityList);
         for(int i = 0; i < unloadedEntityList.size(); i++)
         {
-            Entity entity = (Entity)unloadedEntityList.get(i);
+            Entity entity = unloadedEntityList.get(i);
             int l = entity.chunkCoordX;
             int j1 = entity.chunkCoordZ;
             if(entity.addedToChunk && isChunkLoaded(l, j1))
@@ -3144,13 +3128,13 @@ public class World implements WorldSource {
 
         for(int j = 0; j < unloadedEntityList.size(); j++)
         {
-            releaseEntitySkin((Entity)unloadedEntityList.get(j));
+            releaseEntitySkin(unloadedEntityList.get(j));
         }
 
         unloadedEntityList.clear();
         for(int k = 0; k < loadedEntityList.size(); k++)
         {
-            Entity entity1 = (Entity)loadedEntityList.get(k);
+            Entity entity1 = loadedEntityList.get(k);
             if(entity1.vehicle != null)
             {
                 if(!entity1.vehicle.isRemoved() && entity1.vehicle.getPassenger() == entity1)
@@ -3299,10 +3283,10 @@ public class World implements WorldSource {
         playSoundEffect(null, id, x, y, z, data);
     }
 
-    public void playSoundEffect(EntityPlayer entityplayer, int i, int j, int k, int l, int i1)
+    public void playSoundEffect(EntityPlayer entityplayer, int id, int x, int y, int z, int data)
     {
         for (LevelListener listener : listeners) {
-            listener.levelEvent(entityplayer, i, j, k, l, i1);
+            listener.levelEvent(entityplayer, id, x, y, z, data);
         }
 
     }
@@ -3322,4 +3306,9 @@ public class World implements WorldSource {
         entityJoinedWorld(entityitem);
         return entityitem;
     }
+    public void sendGlobalMessage(String message){
+        for (EntityPlayer player: players){
+            player.sendMessage(message);
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/core/world/biome/Biome.java b/src/main/java/net/minecraft/core/world/biome/Biome.java
index ec02aaa15..90e9358eb 100644
--- a/src/main/java/net/minecraft/core/world/biome/Biome.java
+++ b/src/main/java/net/minecraft/core/world/biome/Biome.java
@@ -84,25 +84,17 @@ public class Biome
 
     public List<SpawnListEntry> getSpawnableList(EnumCreatureType creatureType)
     {
-        if(creatureType == EnumCreatureType.monster)
-        {
-            return spawnableMonsterList;
-        }
-        if(creatureType == EnumCreatureType.creature)
-        {
-            return spawnableCreatureList;
-        }
-        if(creatureType == EnumCreatureType.waterCreature)
-        {
-            return spawnableWaterCreatureList;
-        }
-        if(creatureType == EnumCreatureType.ambientCreature)
-        {
-            return spawnableAmbientCreatureList;
-        }
-        else
-        {
-            return null;
+        switch (creatureType){
+            case monster:
+                return spawnableMonsterList;
+            case creature:
+                return spawnableCreatureList;
+            case waterCreature:
+                return spawnableWaterCreatureList;
+            case ambientCreature:
+                return spawnableAmbientCreatureList;
+            default:
+                return null;
         }
     }
     
diff --git a/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java b/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
index bd0db92c0..581f643fc 100644
--- a/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
+++ b/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
@@ -115,7 +115,7 @@ public class ChunkCache
 		int skyLight = worldObj.getSavedLightValue(LightLayer.Sky, x, y, z);
 		int blockLight = Math.max(worldObj.getSavedLightValue(LightLayer.Block, x, y, z), blockLightValue);
 		
-		if(getBlockLitInteriorSurface(x, y, z)) {
+		if(getBlockLitInteriorSurface(x, y, z) || !isBlockOpaqueCube(x, y, z)) {
 			skyLight = Math.max(skyLight, worldObj.getSavedLightValue(LightLayer.Sky, x, y + 1, z));
 			skyLight = Math.max(skyLight, worldObj.getSavedLightValue(LightLayer.Sky, x, y - 1, z));
 			skyLight = Math.max(skyLight, worldObj.getSavedLightValue(LightLayer.Sky, x + 1, y, z));
diff --git a/src/main/java/net/minecraft/core/world/chunk/ChunkPosition.java b/src/main/java/net/minecraft/core/world/chunk/ChunkPosition.java
index c0432a2ac..7a669f107 100644
--- a/src/main/java/net/minecraft/core/world/chunk/ChunkPosition.java
+++ b/src/main/java/net/minecraft/core/world/chunk/ChunkPosition.java
@@ -1,14 +1,16 @@
 package net.minecraft.core.world.chunk;
 
 
-public class ChunkPosition
-{
+public class ChunkPosition {
+    public final int x;
+    public final int y;
+    public final int z;
 
-    public ChunkPosition(int i, int j, int k)
+    public ChunkPosition(int x, int y, int z)
     {
-        x = i;
-        y = j;
-        z = k;
+        this.x = x;
+        this.y = y;
+        this.z = z;
     }
 
     @Override
@@ -29,8 +31,4 @@ public class ChunkPosition
     {
         return x * 0x88f9fa + y * 0xef88b + z;
     }
-
-    public final int x;
-    public final int y;
-    public final int z;
 }
diff --git a/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreeCherry.java b/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreeCherry.java
index ec9563044..61f5cfd7c 100644
--- a/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreeCherry.java
+++ b/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreeCherry.java
@@ -17,7 +17,7 @@ public class WorldFeatureTreeCherry extends WorldFeatureTree {
 	@Override
 	public void placeLeaves(World world, int x, int y, int z, Random rand) {
 		if(rand.nextInt(5) == 0) {
-			world.setBlockAndMetadataWithNotify(x, y, z, Block.leavesCherryFlowering.id, world.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_SPRING ? 1 : 0);
+			world.setBlockAndMetadataWithNotify(x, y, z, Block.leavesCherryFlowering.id, 0);
 		}else {
 			world.setBlockWithNotify(x, y, z, Block.leavesCherry.id);
 		}
diff --git a/src/main/java/net/minecraft/core/world/noise/BaseImprovedNoise.java b/src/main/java/net/minecraft/core/world/noise/BaseImprovedNoise.java
index e31c59774..0301eeb7d 100644
--- a/src/main/java/net/minecraft/core/world/noise/BaseImprovedNoise.java
+++ b/src/main/java/net/minecraft/core/world/noise/BaseImprovedNoise.java
@@ -39,9 +39,9 @@ public abstract class BaseImprovedNoise
 
     public double getValue(double x, double y, double z)
     {
-        int X = (int)Math.floor(x) & 255,                  // FIND UNIT CUBE THAT
-            Y = (int)Math.floor(y) & 255,                  // CONTAINS POINT.
-            Z = (int)Math.floor(z) & 255;
+        int X = (int)((long)Math.floor(x) & 255),                  // FIND UNIT CUBE THAT
+            Y = (int)((long)Math.floor(y) & 255),                  // CONTAINS POINT.
+            Z = (int)((long)Math.floor(z) & 255);
         x -= Math.floor(x);                                // FIND RELATIVE X,Y,Z
         y -= Math.floor(y);                                // OF POINT IN CUBE.
         z -= Math.floor(z);
@@ -52,13 +52,13 @@ public abstract class BaseImprovedNoise
             B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z;      // THE 8 CUBE CORNERS,
 
         return lerp(w, lerp(v, lerp(u, grad(p[AA  ], x  , y  , z   ),  // AND ADD
-                                       grad(p[BA  ], x-1, y  , z   )), // BLENDED
-                               lerp(u, grad(p[AB  ], x  , y-1, z   ),  // RESULTS
-                                       grad(p[BB  ], x-1, y-1, z   ))),// FROM  8
-                       lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),  // CORNERS
-                                       grad(p[BA+1], x-1, y  , z-1 )), // OF CUBE
-                               lerp(u, grad(p[AB+1], x  , y-1, z-1 ),
-                                       grad(p[BB+1], x-1, y-1, z-1 ))));
+                                                            grad(p[BA  ], x-1, y  , z   )), // BLENDED
+                                             lerp(u, grad(p[AB  ], x  , y-1, z   ),  // RESULTS
+                                                            grad(p[BB  ], x-1, y-1, z   ))),// FROM  8
+                              lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),  // CORNERS
+                                                            grad(p[BA+1], x-1, y  , z-1 )), // OF CUBE
+                                             lerp(u, grad(p[AB+1], x  , y-1, z-1 ),
+                                                         grad(p[BB+1], x-1, y-1, z-1 ))));
     }
 
     protected double grad(int hash, double x, double y)
diff --git a/src/main/java/net/minecraft/core/world/pathfinder/IdHashMap.java b/src/main/java/net/minecraft/core/world/pathfinder/IdHashMap.java
index 56d75d775..32f718c54 100644
--- a/src/main/java/net/minecraft/core/world/pathfinder/IdHashMap.java
+++ b/src/main/java/net/minecraft/core/world/pathfinder/IdHashMap.java
@@ -1,8 +1,7 @@
 package net.minecraft.core.world.pathfinder;
 
-public class IdHashMap
-{
-    private transient Entry[] entries;
+public class IdHashMap<T> {
+    private transient Entry<T>[] entries;
     private transient int count;
     private int threshold;
     private final float growFactor = 0.75F;
@@ -25,10 +24,10 @@ public class IdHashMap
         return i & j - 1;
     }
 
-    public Object get(int id)
+    public T get(int id)
     {
         int j = getHash(id);
-        for(Entry mchashentry = entries[getEntryIndex(j, entries.length)]; mchashentry != null; mchashentry = mchashentry.next)
+        for(Entry<T> mchashentry = entries[getEntryIndex(j, entries.length)]; mchashentry != null; mchashentry = mchashentry.next)
         {
             if(mchashentry.hash == id)
             {
@@ -44,10 +43,10 @@ public class IdHashMap
         return lookupEntry(i) != null;
     }
 
-    final Entry lookupEntry(int i)
+    final Entry<T> lookupEntry(int i)
     {
         int j = getHash(i);
-        for(Entry mchashentry = entries[getEntryIndex(j, entries.length)]; mchashentry != null; mchashentry = mchashentry.next)
+        for(Entry<T> mchashentry = entries[getEntryIndex(j, entries.length)]; mchashentry != null; mchashentry = mchashentry.next)
         {
             if(mchashentry.hash == i)
             {
@@ -59,11 +58,11 @@ public class IdHashMap
     }
 
 
-    public void add(int key, Object item)
+    public void add(int key, T item)
     {
         int j = getHash(key);
         int k = getEntryIndex(j, entries.length);
-        for(Entry mchashentry = entries[k]; mchashentry != null; mchashentry = mchashentry.next)
+        for(Entry<T> mchashentry = entries[k]; mchashentry != null; mchashentry = mchashentry.next)
         {
             if(mchashentry.hash == key)
             {
@@ -77,7 +76,7 @@ public class IdHashMap
 
     private void grow(int i)
     {
-        Entry amchashentry[] = entries;
+        Entry<T>[] amchashentry = entries;
         int j = amchashentry.length;
         if(j == 0x40000000)
         {
@@ -85,7 +84,7 @@ public class IdHashMap
             return;
         } else
         {
-            Entry amchashentry1[] = new Entry[i];
+            Entry<T>[] amchashentry1 = new Entry[i];
             copy(amchashentry1);
             entries = amchashentry1;
             threshold = (int)((float)i * growFactor);
@@ -93,13 +92,13 @@ public class IdHashMap
         }
     }
 
-    private void copy(Entry[] amchashentry)
+    private void copy(Entry<T>[] amchashentry)
     {
-        Entry amchashentry1[] = entries;
+        Entry<T>[] amchashentry1 = entries;
         int i = amchashentry.length;
         for(int j = 0; j < amchashentry1.length; j++)
         {
-            Entry mchashentry = amchashentry1[j];
+            Entry<T> mchashentry = amchashentry1[j];
             if(mchashentry == null)
             {
                 continue;
@@ -107,7 +106,7 @@ public class IdHashMap
             amchashentry1[j] = null;
             do
             {
-                Entry mchashentry1 = mchashentry.next;
+                Entry<T> mchashentry1 = mchashentry.next;
                 int k = getEntryIndex(mchashentry.entryIndex, i);
                 mchashentry.next = amchashentry[k];
                 amchashentry[k] = mchashentry;
@@ -117,19 +116,19 @@ public class IdHashMap
 
     }
 
-    public Object remove(int id)
+    public T remove(int id)
     {
-        Entry mchashentry = removeEntry(id);
+        Entry<T> mchashentry = removeEntry(id);
         return mchashentry != null ? mchashentry.value : null;
     }
 
-    final Entry removeEntry(int id)
+    final Entry<T> removeEntry(int id)
     {
         int j = getHash(id);
         int k = getEntryIndex(j, entries.length);
-        Entry mchashentry = entries[k];
-        Entry mchashentry1;
-        Entry mchashentry2;
+        Entry<T> mchashentry = entries[k];
+        Entry<T> mchashentry1;
+        Entry<T> mchashentry2;
         for(mchashentry1 = mchashentry; mchashentry1 != null; mchashentry1 = mchashentry2)
         {
             mchashentry2 = mchashentry1.next;
@@ -155,7 +154,7 @@ public class IdHashMap
     public void clear()
     {
         versionStamp++;
-        Entry[] amchashentry = entries;
+        Entry<T>[] amchashentry = entries;
         for(int i = 0; i < amchashentry.length; i++)
         {
             amchashentry[i] = null;
@@ -164,24 +163,23 @@ public class IdHashMap
         count = 0;
     }
 
-    private void insert(int i, int j, Object obj, int k)
+    private void insert(int i, int j, T obj, int k)
     {
-        Entry mchashentry = entries[k];
-        entries[k] = new Entry(i, j, obj, mchashentry);
+        Entry<T> mchashentry = entries[k];
+        entries[k] = new Entry<>(i, j, obj, mchashentry);
         if(count++ >= threshold)
         {
             grow(2 * entries.length);
         }
     }
 
-    class Entry
-    {
+    static class Entry<T> {
         final int hash;
-        Object value;
-        Entry next;
+        T value;
+        Entry<T> next;
         final int entryIndex;
 
-        Entry(int entryIndex, int hash, Object value, Entry next)
+        Entry(int entryIndex, int hash, T value, Entry<T> next)
         {
             this.value = value;
             this.next = next;
diff --git a/src/main/java/net/minecraft/core/world/pathfinder/PathFinder.java b/src/main/java/net/minecraft/core/world/pathfinder/PathFinder.java
index a22cda382..ecafc696f 100644
--- a/src/main/java/net/minecraft/core/world/pathfinder/PathFinder.java
+++ b/src/main/java/net/minecraft/core/world/pathfinder/PathFinder.java
@@ -11,13 +11,13 @@ public class PathFinder
 {
     private final WorldSource worldSource;
     private final BinaryHeap openSet;
-    private final IdHashMap closedSet;
+    private final IdHashMap<Node> closedSet;
     private final Node[] neighbors;
 
     public PathFinder(WorldSource worldSource)
     {
         openSet = new BinaryHeap();
-        closedSet = new IdHashMap();
+        closedSet = new IdHashMap<>();
         neighbors = new Node[32];
         this.worldSource = worldSource;
     }
@@ -165,10 +165,10 @@ public class PathFinder
         return pathpoint1;
     }
 
-    private final Node getNode(int x, int y, int z)
+    private Node getNode(int x, int y, int z)
     {
         int l = Node.createHash(x, y, z);
-        Node pathpoint = (Node) closedSet.get(l);
+        Node pathpoint = closedSet.get(l);
         if(pathpoint == null)
         {
             pathpoint = new Node(x, y, z);
diff --git a/src/main/java/net/minecraft/server/entity/EntityTracker.java b/src/main/java/net/minecraft/server/entity/EntityTracker.java
index b8938e95c..e4229ae8e 100644
--- a/src/main/java/net/minecraft/server/entity/EntityTracker.java
+++ b/src/main/java/net/minecraft/server/entity/EntityTracker.java
@@ -24,12 +24,12 @@ import net.minecraft.core.net.packet.Packet;
 public class EntityTracker
 {
 
-    public EntityTracker(MinecraftServer minecraftserver, int i)
+    public EntityTracker(MinecraftServer minecraftserver, int dimId)
     {
-        trackedEntitySet = new HashSet();
-        trackedEntityHashTable = new IdHashMap();
+        trackedEntitySet = new HashSet<>();
+        trackedEntityHashTable = new IdHashMap<>();
         mcServer = minecraftserver;
-        field_28113_e = i;
+        dimension = dimId;
         maxTrackingDistanceThreshold = minecraftserver.playerList.getMaxTrackingDistance();
     }
 
@@ -39,14 +39,14 @@ public class EntityTracker
         {
             trackEntity(entity, 512, 2, false);
             EntityPlayerMP entityplayermp = (EntityPlayerMP)entity;
-            Iterator iterator = trackedEntitySet.iterator();
+            Iterator<EntityTrackerEntry> iterator = trackedEntitySet.iterator();
             do
             {
                 if(!iterator.hasNext())
                 {
                     break;
                 }
-                EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next();
+                EntityTrackerEntry entitytrackerentry = iterator.next();
                 if(entitytrackerentry.trackedEntity != entityplayermp)
                 {
                     entitytrackerentry.updatePlayerEntity(entityplayermp);
@@ -133,8 +133,7 @@ public class EntityTracker
             EntityTrackerEntry entitytrackerentry = new EntityTrackerEntry(entity, trackingDistance, packetDelay, shouldSendMotionUpdates);
             trackedEntitySet.add(entitytrackerentry);
             trackedEntityHashTable.add(entity.id, entitytrackerentry);
-            entitytrackerentry.updatePlayerEntities(mcServer.getDimensionWorld(field_28113_e).players);
-            return;
+            entitytrackerentry.updatePlayerEntities(mcServer.getDimensionWorld(dimension).players);
         }
     }
 
@@ -144,13 +143,13 @@ public class EntityTracker
         {
             EntityPlayerMP entityplayermp = (EntityPlayerMP)entity;
             EntityTrackerEntry entitytrackerentry1;
-            for(Iterator iterator = trackedEntitySet.iterator(); iterator.hasNext(); entitytrackerentry1.removeFromTrackedPlayers(entityplayermp))
+            for(Iterator<EntityTrackerEntry> iterator = trackedEntitySet.iterator(); iterator.hasNext(); entitytrackerentry1.removeFromTrackedPlayers(entityplayermp))
             {
-                entitytrackerentry1 = (EntityTrackerEntry)iterator.next();
+                entitytrackerentry1 = iterator.next();
             }
 
         }
-        EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)trackedEntityHashTable.remove(entity.id);
+        EntityTrackerEntry entitytrackerentry = trackedEntityHashTable.remove(entity.id);
         if(entitytrackerentry != null)
         {
             trackedEntitySet.remove(entitytrackerentry);
@@ -160,33 +159,33 @@ public class EntityTracker
 
     public void tick()
     {
-        ArrayList arraylist = new ArrayList();
-        Iterator iterator = trackedEntitySet.iterator();
+        ArrayList<Entity> arraylist = new ArrayList<>();
+        Iterator<EntityTrackerEntry> iterator = trackedEntitySet.iterator();
         do
         {
             if(!iterator.hasNext())
             {
                 break;
             }
-            EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next();
-            entitytrackerentry.tick(mcServer.getDimensionWorld(field_28113_e).players);
+            EntityTrackerEntry entitytrackerentry = iterator.next();
+            entitytrackerentry.tick(mcServer.getDimensionWorld(dimension).players);
             if(entitytrackerentry.playerEntitiesUpdated && (entitytrackerentry.trackedEntity instanceof EntityPlayerMP))
             {
-                arraylist.add((EntityPlayerMP)entitytrackerentry.trackedEntity);
+                arraylist.add(entitytrackerentry.trackedEntity);
             }
         } while(true);
 label0:
         for(int i = 0; i < arraylist.size(); i++)
         {
             EntityPlayerMP entityplayermp = (EntityPlayerMP)arraylist.get(i);
-            Iterator iterator1 = trackedEntitySet.iterator();
+            Iterator<EntityTrackerEntry> iterator1 = trackedEntitySet.iterator();
             do
             {
                 if(!iterator1.hasNext())
                 {
                     continue label0;
                 }
-                EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry)iterator1.next();
+                EntityTrackerEntry entitytrackerentry1 = iterator1.next();
                 if(entitytrackerentry1.trackedEntity != entityplayermp)
                 {
                     entitytrackerentry1.updatePlayerEntity(entityplayermp);
@@ -198,7 +197,7 @@ label0:
 
     public void sendPacketToTrackedPlayers(Entity entity, Packet packet)
     {
-        EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)trackedEntityHashTable.get(entity.id);
+        EntityTrackerEntry entitytrackerentry = trackedEntityHashTable.get(entity.id);
         if(entitytrackerentry != null)
         {
             entitytrackerentry.sendPacketToTrackedPlayers(packet);
@@ -207,7 +206,7 @@ label0:
 
     public void sendPacketToTrackedPlayersAndTrackedEntity(Entity entity, Packet packet)
     {
-        EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)trackedEntityHashTable.get(entity.id);
+        EntityTrackerEntry entitytrackerentry = trackedEntityHashTable.get(entity.id);
         if(entitytrackerentry != null)
         {
             entitytrackerentry.sendPacketToTrackedPlayersAndTrackedEntity(packet);
@@ -217,16 +216,16 @@ label0:
     public void removeTrackedPlayerSymmetric(EntityPlayerMP entityplayermp)
     {
         EntityTrackerEntry entitytrackerentry;
-        for(Iterator iterator = trackedEntitySet.iterator(); iterator.hasNext(); entitytrackerentry.removeTrackedPlayerSymmetric(entityplayermp))
+        for(Iterator<EntityTrackerEntry> iterator = trackedEntitySet.iterator(); iterator.hasNext(); entitytrackerentry.removeTrackedPlayerSymmetric(entityplayermp))
         {
-            entitytrackerentry = (EntityTrackerEntry)iterator.next();
+            entitytrackerentry = iterator.next();
         }
 
     }
 
-    private Set trackedEntitySet;
-    private IdHashMap trackedEntityHashTable;
-    private MinecraftServer mcServer;
-    private int maxTrackingDistanceThreshold;
-    private int field_28113_e;
+    private final Set<EntityTrackerEntry> trackedEntitySet;
+    private final IdHashMap<EntityTrackerEntry> trackedEntityHashTable;
+    private final MinecraftServer mcServer;
+    private final int maxTrackingDistanceThreshold;
+    private final int dimension;
 }
diff --git a/src/main/java/net/minecraft/server/entity/player/EntityPlayerMP.java b/src/main/java/net/minecraft/server/entity/player/EntityPlayerMP.java
index e3beb7d28..5ffdfc737 100644
--- a/src/main/java/net/minecraft/server/entity/player/EntityPlayerMP.java
+++ b/src/main/java/net/minecraft/server/entity/player/EntityPlayerMP.java
@@ -63,12 +63,7 @@ import java.util.Set;
 //            Packet105UpdateProgressbar, Packet101CloseWindow, StatBase, Packet200Statistic, 
 //            StringTranslate, Packet3Chat
 
-public class EntityPlayerMP extends EntityPlayer
-        implements ICrafting
-{
-
-    public static final TextFormatting deathMsgColor = TextFormatting.RED;
-
+public class EntityPlayerMP extends EntityPlayer implements ICrafting {
     public EntityPlayerMP(MinecraftServer minecraftserver, World world, String s, ServerPlayerController iteminworldmanager)
     {
         super(world);
@@ -266,157 +261,6 @@ public class EntityPlayerMP extends EntityPlayer
         }
     }
 
-    private String deathMessage(Entity entity)
-    {
-        if (random.nextInt(8000) == 666)
-        {
-            return getDisplayName() + deathMsgColor + " was killed by Herobrine.";
-        }
-        if (entity instanceof EntityZombie)
-        {
-            if (entity instanceof EntityPigZombie)
-            {
-                return getDisplayName() + deathMsgColor + " discovered mob mentality.";
-            }
-            else
-            {
-                return getDisplayName() + deathMsgColor + " became a zombie.";
-            }
-        }
-        if (entity instanceof EntityCreeper)
-        {
-            return deathMsgColor + "Aw man, " + getDisplayName() + deathMsgColor + " didn't see the creeper.";
-        }
-        if (entity instanceof EntitySkeleton)
-        {
-            return getDisplayName() + deathMsgColor + " was a victim of aimbot.";
-        }
-        if (entity instanceof EntitySpider)
-        {
-            return getDisplayName() + deathMsgColor + " spent too much time on the web.";
-        }
-        if (entity instanceof EntityGhast)
-        {
-            return getDisplayName() + deathMsgColor + " didn't return the serve.";
-        }
-        if (entity instanceof EntitySlime)
-        {
-            return getDisplayName() + deathMsgColor + " was slimed.";
-        }
-        if (entity instanceof EntityWolf)
-        {
-            return getDisplayName() + deathMsgColor + " got what they deserved.";
-        }
-        if (entity instanceof EntityArrowGolden)
-        {
-            if (((EntityArrowGolden) entity).owner instanceof EntityPlayerMP)
-            {
-                if (((EntityPlayerMP) ((EntityArrowGolden) entity).owner).username.equals(username))
-                {
-                    return getDisplayName() + deathMsgColor + " got gold in their eye.";
-                }
-                return getDisplayName() + deathMsgColor + " got pierced by " +
-                    ((EntityArrow) entity).owner.getDisplayName() + deathMsgColor + ".";
-            }
-            else
-            {
-                return getDisplayName() + deathMsgColor + " is Swiss cheese.";
-            }
-        }
-        if (entity instanceof EntityArrow)
-        {
-            if (((EntityArrow) entity).owner instanceof EntitySkeleton)
-            {
-                return getDisplayName() + deathMsgColor + " was a victim of aimbot.";
-            }
-            else if (((EntityArrow) entity).owner instanceof EntityPlayerMP)
-            {
-                if (((EntityPlayerMP) ((EntityArrow) entity).owner).username.equals(username))
-                {
-                    return getDisplayName() + deathMsgColor + " lost a game of Russian roulette.";
-                }
-                return getDisplayName() + deathMsgColor + " got 360 noscoped by " +
-                    ((EntityArrow) entity).owner.getDisplayName() + deathMsgColor + ".";
-            }
-            else
-            {
-                return getDisplayName() + deathMsgColor + " is a pincushion.";
-            }
-        }
-        if (entity instanceof EntityCannonball)
-        {
-            if (((EntityCannonball) entity).owner instanceof EntityPlayerMP)
-            {
-                if (((EntityPlayerMP) ((EntityCannonball) entity).owner).username.equals(username))
-                {
-                    return getDisplayName() + deathMsgColor + " jumped too high.";
-                }
-                return getDisplayName() + deathMsgColor + " was fragmented by " +
-                    ((EntityCannonball) entity).owner.getDisplayName() + deathMsgColor + ".";
-            }
-            else
-            {
-                return getDisplayName() + deathMsgColor + " was detonated remotely.";
-            }
-        }
-        if (entity instanceof EntityFireball)
-        {
-            return getDisplayName() + deathMsgColor + " didn't return the serve.";
-        }
-        if (entity instanceof EntityGiant)
-        {
-            return getDisplayName() + deathMsgColor + " was killed by- wait, what?!";
-        }
-        if (entity instanceof EntityLightningBolt)
-        {
-            return getDisplayName() + deathMsgColor + " was grounded.";
-        }
-        if (entity instanceof EntityTNT)
-        {
-            return getDisplayName() + deathMsgColor + " was killed by Popbob.";
-        }
-        if (entity instanceof EntityPlayerMP)
-        {
-            return getDisplayName() + deathMsgColor + " was backstabbed by " + ((EntityPlayerMP) entity).getDisplayName() + deathMsgColor + ".";
-        }
-        if (entity instanceof EntityPig)
-        {
-            return getDisplayName() + deathMsgColor + " is *really* bad at Minecraft.";
-        }
-        else
-        {
-            if (world.getBlockMaterial(MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z)) == Material.lava)
-            {
-                return getDisplayName() + deathMsgColor + " got lost in the sauce.";
-            }
-            if (world.getBlockId(MathHelper.floor_double(x), MathHelper.floor_double(y), MathHelper.floor_double(z)) == Block.spikes.id)
-            {
-                return getDisplayName() + deathMsgColor + " fell for the trap.";
-            }
-            if (fallDistance > 0)
-            {
-                return getDisplayName() + deathMsgColor + " forgot to tie their laces.";
-            }
-            if (airSupply <= 0)
-            {
-                return getDisplayName() + deathMsgColor + " is sleeping with the fishes.";
-            }
-            if (remainingFireTicks > 0)
-            {
-                return getDisplayName() + deathMsgColor + " was cooked well done.";
-            }
-            return getDisplayName() + deathMsgColor + " died mysteriously.";
-        }
-
-    }
-
-    @Override
-	public void onDeath(Entity entity)
-    {
-        super.onDeath(entity);
-        mcServer.playerList.sendPacketToAllPlayers(new Packet3Chat(deathMessage(entity)));
-    }
-
     @Override
     public boolean hurt(Entity attacker, int i, DamageType type)
     {
diff --git a/src/main/java/net/minecraft/server/net/handler/NetServerHandler.java b/src/main/java/net/minecraft/server/net/handler/NetServerHandler.java
index 6e1ec53c4..a1bc39d45 100644
--- a/src/main/java/net/minecraft/server/net/handler/NetServerHandler.java
+++ b/src/main/java/net/minecraft/server/net/handler/NetServerHandler.java
@@ -691,7 +691,7 @@ public class NetServerHandler extends NetHandler
     public void handleUseEntity(Packet7UseEntity packet)
     {
         WorldServer worldserver = mcServer.getDimensionWorld(playerEntity.dimension);
-        Entity targetEntity = worldserver.func_6158_a(packet.targetEntity);
+        Entity targetEntity = worldserver.getEntityFromId(packet.targetEntity);
         if (targetEntity != null && playerEntity.distanceToSqr(targetEntity) < 36D)
         {
             boolean canAttack = playerEntity.canEntityBeSeen(targetEntity);
diff --git a/src/main/java/net/minecraft/server/world/WorldServer.java b/src/main/java/net/minecraft/server/world/WorldServer.java
index 301fe38db..51f4021fe 100644
--- a/src/main/java/net/minecraft/server/world/WorldServer.java
+++ b/src/main/java/net/minecraft/server/world/WorldServer.java
@@ -20,7 +20,6 @@ import net.minecraft.server.world.chunk.provider.ChunkProviderServer;
 import net.minecraft.core.world.save.LevelStorage;
 import net.minecraft.core.world.type.WorldType;
 import net.minecraft.server.MinecraftServer;
-import org.lwjgl.Sys;
 
 // Referenced classes of package net.minecraft.src:
 //            World, WorldProvider, MCHash, EntityAnimal, 
@@ -37,7 +36,7 @@ public class WorldServer extends World
     {
         super(isavehandler, name, seed, Dimension.getDimensionList().get(dimensionId), worldType);
         field_819_z = false;
-        field_20912_E = new IdHashMap();
+        entityIdHashMap = new IdHashMap<>();
         mcServer = minecraftserver;
     }
 
@@ -48,7 +47,7 @@ public class WorldServer extends World
         {
             entity.remove();
         }
-        if(entity.passenger == null || !(entity.passenger instanceof EntityPlayer))
+        if(!(entity.passenger instanceof EntityPlayer))
         {
             super.updateEntityWithOptionalForce(entity, flag);
         }
@@ -69,10 +68,10 @@ public class WorldServer extends World
 
     public List<TileEntity> getTileEntityList(int i, int j, int k, int l, int i1, int j1)
     {
-        ArrayList arraylist = new ArrayList();
+        ArrayList<TileEntity> arraylist = new ArrayList<>();
         for(int k1 = 0; k1 < loadedTileEntityList.size(); k1++)
         {
-            TileEntity tileentity = (TileEntity)loadedTileEntityList.get(k1);
+            TileEntity tileentity = loadedTileEntityList.get(k1);
             if(tileentity.x >= i && tileentity.y >= j && tileentity.z >= k && tileentity.x < l && tileentity.y < i1 && tileentity.z < j1)
             {
                 arraylist.add(tileentity);
@@ -99,7 +98,7 @@ public class WorldServer extends World
     {
         super.obtainEntitySkin(entity);
         if (entity == null) return;
-        field_20912_E.add(entity.id, entity);
+        entityIdHashMap.add(entity.id, entity);
     }
 
     @Override
@@ -107,7 +106,7 @@ public class WorldServer extends World
     {
         super.releaseEntitySkin(entity);
         if (entity == null) return;
-        field_20912_E.remove(entity.id);
+        entityIdHashMap.remove(entity.id);
     }
 
     @Override
@@ -175,9 +174,9 @@ public class WorldServer extends World
 
     }
 
-    public Entity func_6158_a(int i)
+    public Entity getEntityFromId(int i)
     {
-        return (Entity)field_20912_E.get(i);
+        return entityIdHashMap.get(i);
     }
 
     @Override
@@ -214,32 +213,28 @@ public class WorldServer extends World
     }
 
     @Override
-    public Explosion createExplosion(Entity entity, double d, double d1, double d2,
-                                     float f)
-    {
-        return newExplosion(entity, d, d1, d2, f, false, false);
+    public Explosion createExplosion(Entity entity, double x, double y, double z, float explosionSize) {
+        return newExplosion(entity, x, y, z, explosionSize, false, false);
     }
 
     @Override
-    public Explosion newExplosion(Entity entity, double d, double d1, double d2,
-                                  float f, boolean flag, boolean isCannonBall)
-    {
+    public Explosion newExplosion(Entity entity, double x, double y, double z, float explosionSize, boolean flaming, boolean isCannonBall) {
         Explosion explosion;
         if(!isCannonBall)
-            explosion = new Explosion(this, entity, d, d1, d2, f);
+            explosion = new Explosion(this, entity, x, y, z, explosionSize);
         else
-            explosion = new ExplosionCannonball(this, entity, d, d1, d2, f);
-        explosion.isFlaming = flag;
+            explosion = new ExplosionCannonball(this, entity, x, y, z, explosionSize);
+        explosion.isFlaming = flaming;
         explosion.doExplosionA();
         explosion.doExplosionB(true);
-        mcServer.playerList.sendPacketToPlayersAroundPoint(d, d1, d2, 64D, dimension.id, new Packet60Explosion(d, d1, d2, f, explosion.destroyedBlockPositions, isCannonBall));
+        mcServer.playerList.sendPacketToPlayersAroundPoint(x, y, z, 64D, dimension.id, new Packet60Explosion(x, y, z, explosionSize, explosion.destroyedBlockPositions, isCannonBall));
         return explosion;
     }
     @Override
-    public void triggerEvent(int i, int j, int k, int index, int data)
+    public void triggerEvent(int x, int y, int z, int index, int data)
     {
-        super.triggerEvent(i, j, k, index, data);
-        mcServer.playerList.sendPacketToPlayersAroundPoint(i, j, k, 64D, dimension.id, new Packet54PlayNoteBlock(i, j, k, index, data));
+        super.triggerEvent(x, y, z, index, data);
+        mcServer.playerList.sendPacketToPlayersAroundPoint(x, y, z, 64D, dimension.id, new Packet54PlayNoteBlock(x, y, z, index, data));
     }
 
     public void func_30006_w()
@@ -256,11 +251,15 @@ public class WorldServer extends World
             lastWeatherSend = System.currentTimeMillis();
         }
     }
+    @Override
+    public void sendGlobalMessage(String message){
+        mcServer.playerList.sendPacketToAllPlayers(new Packet3Chat(message));
+    }
 
     public ChunkProviderServer chunkProviderServer;
     public boolean field_819_z;
     public boolean levelSaving;
     public MinecraftServer mcServer;
-    private final IdHashMap field_20912_E;
+    private final IdHashMap<Entity> entityIdHashMap;
     private long lastWeatherSend = System.currentTimeMillis();
 }
diff --git a/src/main/resources/assets/minecraft/textures/art/borders/border_olivine.png b/src/main/resources/assets/minecraft/textures/art/borders/border_olivine.png
index 7011483ba..d72cf7e34 100644
Binary files a/src/main/resources/assets/minecraft/textures/art/borders/border_olivine.png and b/src/main/resources/assets/minecraft/textures/art/borders/border_olivine.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/repeater_active_overlay.png b/src/main/resources/assets/minecraft/textures/block/repeater_active_overlay.png
new file mode 100644
index 000000000..2bf42da37
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/repeater_active_overlay.png differ
