diff --git a/src/common/resources/recipes/workbench.json b/src/common/resources/recipes/workbench.json
index 47af3b748..ecad9029b 100644
--- a/src/common/resources/recipes/workbench.json
+++ b/src/common/resources/recipes/workbench.json
@@ -6846,7 +6846,11 @@
     "symbols": [
       {
         "symbol": "#",
-        "group": "minecraft:planks"
+        "stack": {
+          "key": "tile.planks.oak",
+          "amount": 1,
+          "meta": 0
+        }
       }
     ],
     "result": {
@@ -7264,7 +7268,11 @@
     "symbols": [
       {
         "symbol": "#",
-        "group": "minecraft:planks"
+        "stack": {
+          "key": "tile.planks.oak",
+          "amount": 1,
+          "meta": 0
+        }
       }
     ],
     "result": {
@@ -8431,38 +8439,6 @@
     },
     "consumeContainers": true
   },
-  {
-    "name": "minecraft:workbench/pebbles_to_limestone",
-    "type": "minecraft:crafting/shaped",
-    "pattern": [
-      "#X",
-      "X#"
-    ],
-    "symbols": [
-      {
-        "symbol": "#",
-        "stack": {
-          "id": 16514,
-          "amount": 1,
-          "meta": 0
-        }
-      },
-      {
-        "symbol": "X",
-        "stack": {
-          "id": 250,
-          "amount": 1,
-          "meta": 0
-        }
-      }
-    ],
-    "result": {
-      "id": 13,
-      "amount": 2,
-      "meta": 0
-    },
-    "consumeContainers": true
-  },
   {
     "name": "minecraft:workbench/pebbles_to_granite",
     "type": "minecraft:crafting/shaped",
diff --git a/src/main/java/net/minecraft/client/entity/player/EntityPlayerSP.java b/src/main/java/net/minecraft/client/entity/player/EntityPlayerSP.java
index a250cf302..307acfc02 100644
--- a/src/main/java/net/minecraft/client/entity/player/EntityPlayerSP.java
+++ b/src/main/java/net/minecraft/client/entity/player/EntityPlayerSP.java
@@ -373,6 +373,7 @@ public class EntityPlayerSP extends EntityPlayer
                         return;
                     }
                 }
+                sender.sendMessage(TextFormatting.RED + "Command '" + args[0] + "' does not exist!");
             }catch (Exception e) {
                 e.printStackTrace();
                 mc.ingameGUI.addChatMessage(TextFormatting.RED + "Error!");
diff --git a/src/main/java/net/minecraft/client/gui/GuiGameOver.java b/src/main/java/net/minecraft/client/gui/GuiGameOver.java
index 8fa5614eb..8593ee79c 100644
--- a/src/main/java/net/minecraft/client/gui/GuiGameOver.java
+++ b/src/main/java/net/minecraft/client/gui/GuiGameOver.java
@@ -1,6 +1,8 @@
 package net.minecraft.client.gui;
 
+import net.minecraft.client.entity.player.EntityClientPlayerMP;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.packet.Packet0KeepAlive;
 import net.minecraft.core.player.gamemode.Gamemode;
 import org.lwjgl.opengl.GL11;
 
@@ -11,10 +13,19 @@ import net.minecraft.core.net.command.TextFormatting;
 
 public class GuiGameOver extends GuiScreen
 {
+    protected int tickCount = 0;
 
     public GuiGameOver()
     {
     }
+    @Override
+    public void tick(){
+        tickCount++;
+        if (mc.isMultiplayerWorld() && mc.thePlayer instanceof EntityClientPlayerMP && tickCount % 10 == 0){
+            EntityClientPlayerMP clientPlayerMP = (EntityClientPlayerMP) mc.thePlayer;
+            clientPlayerMP.sendQueue.addToSendQueue(new Packet0KeepAlive());
+        }
+    }
 
     @Override
 	public void init()
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 439ff60d4..80e3509f4 100644
--- a/src/main/java/net/minecraft/client/gui/hud/HotbarComponent.java
+++ b/src/main/java/net/minecraft/client/gui/hud/HotbarComponent.java
@@ -69,7 +69,7 @@ public class HotbarComponent
 
         // Setup items
         GL11.glEnable(GL11.GL_DEPTH_TEST);
-        GL11.glDisable(GL11.GL_BLEND);
+        GL11.glEnable(GL11.GL_BLEND);
         GL11.glEnable(GL12.GL_RESCALE_NORMAL);
         Lighting.enableInventoryLight();
         int lastHotbarStart = (mc.thePlayer.inventory.hotbarOffset + 27) % 36;
@@ -146,7 +146,7 @@ public class HotbarComponent
 
         // Setup items
         GL11.glEnable(GL11.GL_DEPTH_TEST);
-        GL11.glDisable(GL11.GL_BLEND);
+        GL11.glEnable(GL11.GL_BLEND);
         GL11.glEnable(GL12.GL_RESCALE_NORMAL);
         Lighting.enableInventoryLight();
 
diff --git a/src/main/java/net/minecraft/client/render/FontRenderer.java b/src/main/java/net/minecraft/client/render/FontRenderer.java
index 8c6b9ff58..bf44707f7 100644
--- a/src/main/java/net/minecraft/client/render/FontRenderer.java
+++ b/src/main/java/net/minecraft/client/render/FontRenderer.java
@@ -3,6 +3,7 @@ package net.minecraft.client.render;
 import net.minecraft.client.lang.text.Text;
 import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.tessellator.Tessellator;
+import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.util.helper.ChatAllowedCharacters;
 import net.minecraft.core.util.helper.Color;
 import net.minecraft.client.util.helper.Colors;
@@ -361,90 +362,139 @@ public class FontRenderer {
             int fontIndex;
             int var6;
             if (c == '\247' && i + 1 < text.length()) {
-                fontIndex = "0123456789abcdefklmnor".indexOf(text.toLowerCase().charAt(i + 1));
-                if (fontIndex < 16) {
-                    this.obfuscatedStyle = false;
-                    this.boldStyle = false;
-                    this.strikethroughStyle = false;
-                    this.underlineStyle = false;
-                    this.italicStyle = false;
-                    if (fontIndex < 0) {
-                        fontIndex = 15;
+                char colorSymbol = text.toLowerCase().charAt(i + 1);
+                if (colorSymbol == '<'){ // Full rgb color code
+                    int offAmount = 1;
+                    int j = i + 2;
+                    StringBuilder colorValue = new StringBuilder();
+                    boolean ended = false;
+                    while (j < text.length()){
+                        offAmount++;
+                        if (text.charAt(j) == '>'){
+                            ended = true;
+                            break;
+                        }
+                        colorValue.append(text.charAt(j));
+                        j++;
                     }
 
-                    if (flag) {
-                        fontIndex += 16;
-                    }
+                    if (ended){
+                        i += offAmount;
 
-                    var6 = this.colorCode[fontIndex];
-                    this.textColor = var6;
-                    GL11.glColor4f((float)(var6 >> 16) / 255.0F, (float)(var6 >> 8 & 255) / 255.0F, (float)(var6 & 255) / 255.0F, this.alpha);
-                } else if (fontIndex == 16) {
-                    this.obfuscatedStyle = true;
-                } else if (fontIndex == 17) {
-                    this.boldStyle = true;
-                } else if (fontIndex == 18) {
-                    this.strikethroughStyle = true;
-                } else if (fontIndex == 19) {
-                    this.underlineStyle = true;
-                } else if (fontIndex == 20) {
-                    this.italicStyle = true;
-                } else if (fontIndex == 21) {
-                    this.obfuscatedStyle = false;
-                    this.boldStyle = false;
-                    this.strikethroughStyle = false;
-                    this.underlineStyle = false;
-                    this.italicStyle = false;
-                    GL11.glColor4f(this.red, this.blue, this.green, this.alpha);
-                }
+                        int colorInt = 0xFFFFFF;
+                        try {
+                            colorInt = Integer.decode("0x" + colorValue.toString().toLowerCase());
+                        } catch (NumberFormatException ignored){
+                        }
 
-                ++i;
-            } else {
-                fontIndex = ChatAllowedCharacters.ALLOWED_CHARACTERS.indexOf(c);
-                if (this.obfuscatedStyle && fontIndex > 0) {
-                    do {
-                        var6 = this.random.nextInt(ChatAllowedCharacters.ALLOWED_CHARACTERS.length());
-                    } while (this.charWidth[fontIndex + 32] != this.charWidth[var6 + 32]);
+                        float r = (float)(colorInt >> 16) / 255.0F;
+                        float g = (float)(colorInt >> 8 & 0xff) / 255.0F;
+                        float b = (float)(colorInt & 0xff) / 255.0F;
 
-                    fontIndex = var6;
-                }
+                        this.obfuscatedStyle = false;
+                        this.boldStyle = false;
+                        this.strikethroughStyle = false;
+                        this.underlineStyle = false;
+                        this.italicStyle = false;
 
-                float var9 = this.renderCharAtPos(fontIndex, c, this.italicStyle);
-                if (this.boldStyle) {
-                    ++this.posX;
-                    this.renderCharAtPos(fontIndex, c, this.italicStyle);
-                    --this.posX;
-                    ++var9;
-                }
+                        if (flag){
+                            r /= 4;
+                            g /= 4;
+                            b /= 4;
+                        }
 
-                Tessellator var7;
-                if(this.strikethroughStyle) {
-                    var7 = Tessellator.instance;
-                    GL11.glDisable(GL11.GL_TEXTURE_2D);
-                    var7.startDrawingQuads();
-                    var7.addVertex(this.posX, this.posY + (float)(this.fontHeight / 2), 0.0D);
-                    var7.addVertex(this.posX + var9, this.posY + (float)(this.fontHeight / 2), 0.0D);
-                    var7.addVertex(this.posX + var9, this.posY + (float)(this.fontHeight / 2) - 1.0F, 0.0D);
-                    var7.addVertex(this.posX, this.posY + (float)(this.fontHeight / 2) - 1.0F, 0.0D);
-                    var7.draw();
-                    GL11.glEnable(GL11.GL_TEXTURE_2D);
-                }
+                        this.textColor = colorInt;
+                        GL11.glColor4f(r, g, b, this.alpha);
+                        continue;
+                    }
+                } else {
+                    fontIndex = "0123456789abcdefklmnor".indexOf(colorSymbol);
+                    if (fontIndex != -1){
+                        if (fontIndex < 16) {
+                            this.obfuscatedStyle = false;
+                            this.boldStyle = false;
+                            this.strikethroughStyle = false;
+                            this.underlineStyle = false;
+                            this.italicStyle = false;
+                            if (fontIndex < 0) {
+                                fontIndex = 15;
+                            }
 
-                if(this.underlineStyle) {
-                    var7 = Tessellator.instance;
-                    GL11.glDisable(GL11.GL_TEXTURE_2D);
-                    var7.startDrawingQuads();
-                    int var8 = this.underlineStyle ? -1 : 0;
-                    var7.addVertex(this.posX + (float)var8, this.posY + (float)this.fontHeight, 0.0D);
-                    var7.addVertex(this.posX + var9, this.posY + (float)this.fontHeight, 0.0D);
-                    var7.addVertex(this.posX + var9, this.posY + (float)this.fontHeight - 1.0F, 0.0D);
-                    var7.addVertex(this.posX + (float)var8, this.posY + (float)this.fontHeight - 1.0F, 0.0D);
-                    var7.draw();
-                    GL11.glEnable(GL11.GL_TEXTURE_2D);
+                            if (flag) {
+                                fontIndex += 16;
+                            }
+
+                            var6 = this.colorCode[fontIndex];
+                            this.textColor = var6;
+                            GL11.glColor4f((float)(var6 >> 16) / 255.0F, (float)(var6 >> 8 & 255) / 255.0F, (float)(var6 & 255) / 255.0F, this.alpha);
+                        } else if (fontIndex == 16) {
+                            this.obfuscatedStyle = true;
+                        } else if (fontIndex == 17) {
+                            this.boldStyle = true;
+                        } else if (fontIndex == 18) {
+                            this.strikethroughStyle = true;
+                        } else if (fontIndex == 19) {
+                            this.underlineStyle = true;
+                        } else if (fontIndex == 20) {
+                            this.italicStyle = true;
+                        } else if (fontIndex == 21) {
+                            this.obfuscatedStyle = false;
+                            this.boldStyle = false;
+                            this.strikethroughStyle = false;
+                            this.underlineStyle = false;
+                            this.italicStyle = false;
+                            GL11.glColor4f(this.red, this.blue, this.green, this.alpha);
+                        }
+                        i++;
+                        continue;
+                    }
                 }
+            }
+            c = text.charAt(i);
+            fontIndex = ChatAllowedCharacters.ALLOWED_CHARACTERS.indexOf(c);
+            if (this.obfuscatedStyle && fontIndex > 0) {
+                do {
+                    var6 = this.random.nextInt(ChatAllowedCharacters.ALLOWED_CHARACTERS.length());
+                } while (this.charWidth[fontIndex + 32] != this.charWidth[var6 + 32]);
+
+                fontIndex = var6;
+            }
 
-                this.posX += (float)((int)var9);
+            float var9 = this.renderCharAtPos(fontIndex, c, this.italicStyle);
+            if (this.boldStyle) {
+                ++this.posX;
+                this.renderCharAtPos(fontIndex, c, this.italicStyle);
+                --this.posX;
+                ++var9;
             }
+
+            Tessellator var7;
+            if(this.strikethroughStyle) {
+                var7 = Tessellator.instance;
+                GL11.glDisable(GL11.GL_TEXTURE_2D);
+                var7.startDrawingQuads();
+                var7.addVertex(this.posX, this.posY + (float)(this.fontHeight / 2), 0.0D);
+                var7.addVertex(this.posX + var9, this.posY + (float)(this.fontHeight / 2), 0.0D);
+                var7.addVertex(this.posX + var9, this.posY + (float)(this.fontHeight / 2) - 1.0F, 0.0D);
+                var7.addVertex(this.posX, this.posY + (float)(this.fontHeight / 2) - 1.0F, 0.0D);
+                var7.draw();
+                GL11.glEnable(GL11.GL_TEXTURE_2D);
+            }
+
+            if(this.underlineStyle) {
+                var7 = Tessellator.instance;
+                GL11.glDisable(GL11.GL_TEXTURE_2D);
+                var7.startDrawingQuads();
+                int var8 = this.underlineStyle ? -1 : 0;
+                var7.addVertex(this.posX + (float)var8, this.posY + (float)this.fontHeight, 0.0D);
+                var7.addVertex(this.posX + var9, this.posY + (float)this.fontHeight, 0.0D);
+                var7.addVertex(this.posX + var9, this.posY + (float)this.fontHeight - 1.0F, 0.0D);
+                var7.addVertex(this.posX + (float)var8, this.posY + (float)this.fontHeight - 1.0F, 0.0D);
+                var7.draw();
+                GL11.glEnable(GL11.GL_TEXTURE_2D);
+            }
+
+            this.posX += (float)((int)var9);
         }
 
     }
@@ -499,6 +549,7 @@ public class FontRenderer {
         if(string == null) {
             return 0;
         } else {
+            string = TextFormatting.removeAllFormatting(string);
             int stringWidth = 0;
             boolean addSpacerPixel = false;
 
@@ -530,9 +581,9 @@ public class FontRenderer {
     }
 
     public int getCharWidth(char c) {
-        if (c == '§') {
+        /*if (c == '§') {
             return -1;
-        } else if (c == ' ') {
+        } else */if (c == ' ') {
             return 4;
         } else {
             int fontIndex = ChatAllowedCharacters.ALLOWED_CHARACTERS.indexOf(c);
diff --git a/src/main/java/net/minecraft/client/render/ItemRenderer.java b/src/main/java/net/minecraft/client/render/ItemRenderer.java
index 17af8e541..3ee5a3986 100644
--- a/src/main/java/net/minecraft/client/render/ItemRenderer.java
+++ b/src/main/java/net/minecraft/client/render/ItemRenderer.java
@@ -242,30 +242,30 @@ public class ItemRenderer
     private void renderFireInFirstPerson(float f)
     {
         Tessellator tessellator = Tessellator.instance;
-        GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.9F);
+        GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.85F);
         GL11.glEnable(GL_BLEND);
         GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
-        float f1 = 1.0F;
+        float scale = 1.5f;
         for(int i = 0; i < 2; i++)
         {
             GL11.glPushMatrix();
             IconCoordinate texture = TextureRegistry.getTexture("minecraft:block/fire");
-            float f2 = (float) texture.getIconUMin();
-            float f3 = (float) texture.getIconUMax();
-            float f4 = (float) texture.getIconVMin();
-            float f5 = (float) texture.getIconVMax();
-            float f6 = (0.0F - f1) / 2.0F;
-            float f7 = f6 + f1;
-            float f8 = 0.0F - f1 / 2.0F;
-            float f9 = f8 + f1;
+            float uMin = (float) texture.getIconUMin();
+            float uMax = (float) texture.getIconUMax();
+            float vMin = (float) texture.getIconVMin();
+            float vMax = (float) texture.getIconVMax();
+            float xMin = (0.0F - scale) / 2.0F;
+            float xMax = xMin + scale;
+            float yMin = 0.0F - scale / 2.0F;
+            float yMax = yMin + scale;
             float f10 = -0.5F;
-            GL11.glTranslatef((float)(-(i * 2 - 1)) * 0.24F, -0.3F, 0.0F);
+            GL11.glTranslatef((float)(-(i * 2 - 1)) * 0.4F, -0.3F, 0.0F);
             GL11.glRotatef((float)(i * 2 - 1) * 10F, 0.0F, 1.0F, 0.0F);
             tessellator.startDrawingQuads();
-            tessellator.addVertexWithUV(f6, f8, f10, f3, f5);
-            tessellator.addVertexWithUV(f7, f8, f10, f2, f5);
-            tessellator.addVertexWithUV(f7, f9, f10, f2, f4);
-            tessellator.addVertexWithUV(f6, f9, f10, f3, f4);
+            tessellator.addVertexWithUV(xMin, yMin - 0.5, f10, uMax, vMax);
+            tessellator.addVertexWithUV(xMax, yMin - 0.5, f10, uMin, vMax);
+            tessellator.addVertexWithUV(xMax, yMax, f10, uMin, vMin);
+            tessellator.addVertexWithUV(xMin, yMax, f10, uMax, vMin);
             tessellator.draw();
             GL11.glPopMatrix();
         }
diff --git a/src/main/java/net/minecraft/client/render/RenderBlockCache.java b/src/main/java/net/minecraft/client/render/RenderBlockCache.java
index 123c7d1fb..2f5b87f33 100644
--- a/src/main/java/net/minecraft/client/render/RenderBlockCache.java
+++ b/src/main/java/net/minecraft/client/render/RenderBlockCache.java
@@ -46,7 +46,7 @@ final public class RenderBlockCache {
 
 		if(LightmapHelper.isLightmapEnabled() || mc.fullbright) {
 			int lightEmission = Block.lightEmission[block.id];
-			if(lightEmission > 0) {
+			if(lightEmission >= 15) {
 				return 1.0f;
 			}
 			if(!mc.isAmbientOcclusionEnabled()) {
@@ -89,7 +89,8 @@ final public class RenderBlockCache {
     public int getLightmapCoord(int relX, int relY, int relZ) {
     	int index = (relX + CACHE_RANGE) * CACHE_SIZE * CACHE_SIZE + (relY + CACHE_RANGE) * CACHE_SIZE + (relZ + CACHE_RANGE);
     	if(!lightmapCoordCached[index]) {
-    		lightmapCoordValue[index] = access.getLightmapCoord(relX + offsetX, relY + offsetY, relZ + offsetZ, Block.lightEmission[block.id]);
+    		int lightEmission = Block.lightEmission[block.id];
+    		lightmapCoordValue[index] = access.getLightmapCoord(relX + offsetX, relY + offsetY, relZ + offsetZ, lightEmission >= 15 ? 15 : 0);
     		lightmapCoordCached[index] = true;
     	}
     	return lightmapCoordValue[index];
diff --git a/src/main/java/net/minecraft/client/render/RenderBlocks.java b/src/main/java/net/minecraft/client/render/RenderBlocks.java
index b43167368..515d52b1e 100644
--- a/src/main/java/net/minecraft/client/render/RenderBlocks.java
+++ b/src/main/java/net/minecraft/client/render/RenderBlocks.java
@@ -8,6 +8,7 @@ import net.minecraft.client.render.block.model.BlockModel;
 import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
+import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
 
@@ -275,8 +276,18 @@ public class RenderBlocks
         
     	if(LightmapHelper.isLightmapEnabled()) {
     		if(overbright) {
-				// TODO use correct skylight value, requires a getSavedLightValue method in WorldSource
-    			int lmc = LightmapHelper.getOverbrightLightmapCoord(0);
+    			int dirX2 = dirX;
+    			int dirY2 = dirY;
+    			int dirZ2 = dirZ;
+    			
+    			if(depth > FULL_CUBE_THRESHOLD) {
+    				dirX2 = 0;
+    				dirY2 = 0;
+    				dirZ2 = 0;
+    			}
+    			
+    			int lmc = LightmapHelper.getOverbrightLightmapCoord(blockAccess.getSavedLightValue(LightLayer.Sky, x + dirX2, y + dirY2, z + dirZ2));
+    			
         		lightmapCoordTopLeft = lightmapCoordBottomLeft = lightmapCoordBottomRight = lightmapCoordTopRight = lmc;
     		}else {
         		if(ao) {
diff --git a/src/main/java/net/minecraft/client/render/RenderEngine.java b/src/main/java/net/minecraft/client/render/RenderEngine.java
index 91c1467a0..39100aefb 100644
--- a/src/main/java/net/minecraft/client/render/RenderEngine.java
+++ b/src/main/java/net/minecraft/client/render/RenderEngine.java
@@ -83,62 +83,67 @@ public class RenderEngine {
 
 		dynamicTextures.clear();
 
-		TexturePack tp = texturePacks.getHighestPriorityPack();
+		TexturePack tp;
 
 		if(mc.gameSettings.animations.value != 0) {
 			boolean useCustomAnimations = mc.gameSettings.animations.value == 2;
 
 			try {
-				if(useCustomAnimations && tp.hasFile("/anim/custom_water_still.png")) {
-					dynamicTextures.add(new DynamicTextureCustom(mc, "/anim/custom_water_still.png", TextureRegistry.getTexture("minecraft:block/water_still")));
+				tp = mc.texturePackList.getHighestPriorityTexturePackWithFile("/anim/custom_water_still.png");
+				if(useCustomAnimations && tp != null) {
+					dynamicTextures.add(new DynamicTextureCustom(mc, tp, "/anim/custom_water_still.png", "minecraft:block/water_still", false));
 				}else {
 					dynamicTextures.add(new DynamicTextureWaterStill());
 				}
 
-				if(useCustomAnimations && tp.hasFile("/anim/custom_water_flowing.png")) {
-					dynamicTextures.add(new DynamicTextureCustom(mc, "/anim/custom_water_flowing.png", TextureRegistry.getTexture("minecraft:block/water_flowing")));
+				tp = mc.texturePackList.getHighestPriorityTexturePackWithFile("/anim/custom_water_flowing.png");
+				if(useCustomAnimations && tp != null) {
+					dynamicTextures.add(new DynamicTextureCustom(mc, tp, "/anim/custom_water_flowing.png", "minecraft:block/water_flowing", true));
 				}else {
 					dynamicTextures.add(new DynamicTextureWaterFlow());
 				}
 
-				if(useCustomAnimations && tp.hasFile("/anim/custom_lava_still.png")) {
-					dynamicTextures.add(new DynamicTextureCustom(mc, "/anim/custom_lava_still.png", TextureRegistry.getTexture("minecraft:block/lava_still")));
+				tp = mc.texturePackList.getHighestPriorityTexturePackWithFile("/anim/custom_lava_still.png");
+				if(useCustomAnimations && tp != null) {
+					dynamicTextures.add(new DynamicTextureCustom(mc, tp, "/anim/custom_lava_still.png", "minecraft:block/lava_still", false));
 				}else {
 					dynamicTextures.add(new DynamicTextureLavaStill());
 				}
 
-				if(useCustomAnimations && tp.hasFile("/anim/custom_lava_flowing.png")) {
-					dynamicTextures.add(new DynamicTextureCustom(mc, "/anim/custom_lava_flowing.png", TextureRegistry.getTexture("minecraft:block/lava_flowing")));
+				tp = mc.texturePackList.getHighestPriorityTexturePackWithFile("/anim/custom_lava_flowing.png");
+				if(useCustomAnimations && tp != null) {
+					dynamicTextures.add(new DynamicTextureCustom(mc, tp, "/anim/custom_lava_flowing.png", "minecraft:block/lava_flowing", true));
 				}else {
 					dynamicTextures.add(new DynamicTextureLavaFlowing());
 				}
 
-				if(useCustomAnimations && tp.hasFile("/anim/custom_portal.png")) {
-					dynamicTextures.add(new DynamicTextureCustom(mc, "/anim/custom_portal.png", TextureRegistry.getTexture("minecraft:block/portal_nether")));
+				tp = mc.texturePackList.getHighestPriorityTexturePackWithFile("/anim/custom_portal.png");
+				if(useCustomAnimations && tp != null) {
+					dynamicTextures.add(new DynamicTextureCustom(mc, tp, "/anim/custom_portal.png", "minecraft:block/portal_nether", false));
 				}else {
 					dynamicTextures.add(new DynamicTexturePortal(false));
 				}
 
-				if(useCustomAnimations && tp.hasFile("/anim/custom_fire.png")) {
-					dynamicTextures.add(new DynamicTextureCustom(mc, "/anim/custom_fire.png", TextureRegistry.getTexture("minecraft:block/fire")));
+				tp = mc.texturePackList.getHighestPriorityTexturePackWithFile("/anim/custom_fire.png");
+				if(useCustomAnimations && tp != null) {
+					dynamicTextures.add(new DynamicTextureCustom(mc, tp, "/anim/custom_fire.png", "minecraft:block/fire", false));
 				}else {
 					dynamicTextures.add(new DynamicTextureFire());
 				}
 
 				String[] fireflycolors = new String[] {"blue", "orange", "green", "red"};
-				IconCoordinate[] fireflytiles = new IconCoordinate[] {
-						TextureRegistry.getTexture("minecraft:block/lantern_firefly_blue"),
-						TextureRegistry.getTexture("minecraft:block/lantern_firefly_orange"),
-						TextureRegistry.getTexture("minecraft:block/lantern_firefly_green"),
-						TextureRegistry.getTexture("minecraft:block/lantern_firefly_red")};
 				for(int i=0; i < 4; i++) {
 					String color = fireflycolors[i];
-					IconCoordinate icon = fireflytiles[i];
-
-					if(useCustomAnimations && tp.hasFile("/anim/custom_firefly_jar_" + color + ".png")) {
-						dynamicTextures.add(new DynamicTextureCustom(mc, "/anim/custom_firefly_jar_" + color + ".png", icon));
+					
+					String animationPath = "/anim/custom_firefly_jar_" + color + ".png";
+					String texturePath = "/assets/minecraft/textures/block/lantern_firefly_" + color + ".png";
+					String textureName = "minecraft:block/lantern_firefly_" + color;
+					
+					tp = mc.texturePackList.getHighestPriorityTexturePackWithFile(animationPath);
+					if(useCustomAnimations && tp != null) {
+						dynamicTextures.add(new DynamicTextureCustom(mc, tp, animationPath, textureName, false));
 					}else {
-						dynamicTextures.add(new DynamicTextureFireflyJar(mc, icon));
+						dynamicTextures.add(new DynamicTextureFireflyJar(mc, texturePath, textureName));
 					}
 				}
 
@@ -146,13 +151,13 @@ public class RenderEngine {
 				errors.add(e);
 			}
 
-			if(useCustomAnimations && tp.hasFile("/anim/animations.json")) {
+			tp = mc.texturePackList.getHighestPriorityTexturePackWithFile("/anim/animations.json");
+			if(useCustomAnimations && tp != null) {
 				loadCustomAnimations(tp, errors);
 			}
 
 			dynamicTextures.add(new DynamicTextureTrommel(mc, TextureRegistry.getTexture("minecraft:block/trommel_active_front"), true));
 			dynamicTextures.add(new DynamicTextureTrommel(mc, TextureRegistry.getTexture("minecraft:block/trommel_active_back"), false));
-
 		}else {
 			updateDynamicTexture(new DynamicTextureTrommel(mc, TextureRegistry.getTexture("minecraft:block/trommel_active_front"), true));
 			updateDynamicTexture(new DynamicTextureTrommel(mc, TextureRegistry.getTexture("minecraft:block/trommel_active_back"), false));
@@ -163,14 +168,14 @@ public class RenderEngine {
 		dynamicTextures.add(new DynamicTextureCompass(mc));
 	}
 	
-	private void loadCustomAnimations(TexturePack selectedTexturePack, List<Throwable> errors) {
+	private void loadCustomAnimations(TexturePack tp, List<Throwable> errors) {
 		if(!mc.gameSettings.customAnimations.value) {
 			return;
 		}
 		try {
 			List<DynamicTexture> customAnimations = new ArrayList<>();
 
-			JsonObject rootObject = TexturePackJsonHelper.readJsonObject(selectedTexturePack, "/anim/animations.json");
+			JsonObject rootObject = TexturePackJsonHelper.readJsonObject(tp, "/anim/animations.json");
 			JsonArray animations = TexturePackJsonHelper.getArray(rootObject, "animations");
 			try {
 				for(int i=0; i < animations.length(); i++) {
@@ -184,16 +189,13 @@ public class RenderEngine {
 
                         String id = TexturePackJsonHelper.getString(animationObject, "id");
 						String name = TexturePackJsonHelper.getString(animationObject, "name");
-
-						if (!TextureRegistry.hasTexture(id)) throw new TexturePackException("Texture id '" + id + "' appears to be invalid!");
-						IconCoordinate texture = TextureRegistry.getTexture(id);
-
-						String texturePath = "/anim/" + name + ".png";
-						if(!selectedTexturePack.hasFile(texturePath)) {
-							throw new TexturePackException("File '"+texturePath+"' does not exist!");
+						
+						String animationSource = "/anim/" + name + ".png";
+						if(!tp.hasFile(animationSource)) {
+							throw new TexturePackException("File '"+animationSource+"' does not exist!");
 						}
-
-						customAnimations.add(new DynamicTextureCustom(mc, texturePath, texture));
+						
+						customAnimations.add(new DynamicTextureCustom(mc, tp, animationSource, id, false));
 					}catch (TexturePackException e) {
 						throw new TexturePackException("Error at index " + i, e);
 					}
@@ -467,19 +469,19 @@ public class RenderEngine {
 		return tex;
 	}
 	
-	public void updateDynamicTexture(DynamicTexture texture) {
-		texture.update();
+	public void updateDynamicTexture(DynamicTexture anim) {
+		anim.update();
 		
-		Buffer.checkBufferSize(texture.imageData.length);
+		Buffer.checkBufferSize(anim.imageData.length);
 		Buffer.reset();
-		buffer.put(texture.imageData);
-		buffer.position(0).limit(texture.imageData.length);
+		buffer.put(anim.imageData);
+		buffer.position(0).limit(anim.imageData.length);
 
-		texture.getTexture().bindTexture();
-		IconCoordinate icon = texture.texture;
+		anim.texture.parentAtlas.bindTexture();
+		IconCoordinate icon = anim.texture;
 
-		int x1 = texture.texture.iconX;
-		int y1 = texture.texture.iconY;
+		int x1 = icon.iconX;
+		int y1 = icon.iconY;
 		glTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, icon.width, icon.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
 		
 		if(mc.gameSettings.mipmapLevels.value > 0) {
@@ -494,17 +496,17 @@ public class RenderEngine {
 						int i = (y * lod) * icon.width + (x * lod);
 						int j = y * (icon.width/lod) + x;
 
-						Buffer.buffer.put(j * 4 + 0, texture.imageData[i * 4 + 0]);
-						Buffer.buffer.put(j * 4 + 1, texture.imageData[i * 4 + 1]);
-						Buffer.buffer.put(j * 4 + 2, texture.imageData[i * 4 + 2]);
-						Buffer.buffer.put(j * 4 + 3, texture.imageData[i * 4 + 3]);
+						Buffer.buffer.put(j * 4 + 0, anim.imageData[i * 4 + 0]);
+						Buffer.buffer.put(j * 4 + 1, anim.imageData[i * 4 + 1]);
+						Buffer.buffer.put(j * 4 + 2, anim.imageData[i * 4 + 2]);
+						Buffer.buffer.put(j * 4 + 3, anim.imageData[i * 4 + 3]);
 					}
 				}
 
 				Buffer.buffer.position(0).limit(icon.width/lod * icon.height/lod * 4);
 
-				x1 = texture.texture.iconX;
-				y1 = texture.texture.iconY;
+				x1 = icon.iconX;
+				y1 = icon.iconY;
 				glTexSubImage2D(GL_TEXTURE_2D, level, x1/lod, y1/lod, icon.width/lod, icon.height/lod, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
 			}
 		}
@@ -558,27 +560,6 @@ public class RenderEngine {
 		}
 	}
 	
-	private int weightedAverageColor(int i, int j) {
-		int k = (i & 0xff000000) >> 24 & 0xff;
-		int l = (j & 0xff000000) >> 24 & 0xff;
-		char c = '\377';
-		if (k + l == 0) {
-			k = 1;
-			l = 1;
-			c = '\0';
-		}
-		int i1 = (i >> 16 & 0xff) * k;
-		int j1 = (i >> 8 & 0xff) * k;
-		int k1 = (i & 0xff) * k;
-		int l1 = (j >> 16 & 0xff) * l;
-		int i2 = (j >> 8 & 0xff) * l;
-		int j2 = (j & 0xff) * l;
-		int k2 = (i1 + l1) / (k + l);
-		int l2 = (j1 + i2) / (k + l);
-		int i3 = (k1 + j2) / (k + l);
-		return c << 24 | k2 << 16 | l2 << 8 | i3;
-	}
-	
 	public BufferedImage getImage(String name) {
 		try {
 			BufferedImage img;
@@ -681,9 +662,17 @@ public class RenderEngine {
 	 * @param errors A list of errors to be displayed in a popup when selecting the texture pack. Errors of type {@link TexturePackException} will be displayed as a readable message
 	 */
 	public void refreshTextures(List<Throwable> errors) {
+		// Animations may change the size of textures, so they need to be initialized before the atlas is generated
+		initDynamicTextures(errors);
+		
 		for (AtlasStitcher stitcher : TextureRegistry.stitcherMap.values()){
 			stitcher.generateAtlas();
 		}
+
+		for(int i=0; i < dynamicTextures.size(); i++) {
+			dynamicTextures.get(i).postInit();
+		}
+		
 		textureNameToImageMap.forEach((i, img) -> setupTexture(img, i));
 		textureMap.forEach((name, id) -> setupTexture(name));
 		
@@ -708,7 +697,6 @@ public class RenderEngine {
 				ioexception1.printStackTrace();
 			}
 		}
-		initDynamicTextures(errors);
 
 		Colors.loadColors();
 		
diff --git a/src/main/java/net/minecraft/client/render/WorldRenderer.java b/src/main/java/net/minecraft/client/render/WorldRenderer.java
index 02eadbb28..1e43de8fb 100644
--- a/src/main/java/net/minecraft/client/render/WorldRenderer.java
+++ b/src/main/java/net/minecraft/client/render/WorldRenderer.java
@@ -712,12 +712,12 @@ public class WorldRenderer
         TextureRegistry.blockAtlas.bindTexture();
 
         Debug.change("water");
+        if(mc.gameSettings.ambientOcclusion.value)
+        {
+            glShadeModel(GL_SMOOTH);
+        }
         if(mc.gameSettings.fancyGraphics.value == 1)
         {
-            if(mc.gameSettings.ambientOcclusion.value)
-            {
-                glShadeModel(GL_SMOOTH);
-            }
             glColorMask(false, false, false, false);
             int i1 = renderGlobal.sortAndRender(mc.activeCamera, 1, partialTick);
             glColorMask(true, true, true, true);
@@ -735,7 +735,6 @@ public class WorldRenderer
                 }
                 lightmapHelper.disableLightmapRendering();
             }
-            glShadeModel(GL_FLAT);
         }
         else
         {
@@ -743,6 +742,7 @@ public class WorldRenderer
             renderGlobal.sortAndRender(mc.activeCamera, 1, partialTick);
             lightmapHelper.disableLightmapRendering();
         }
+        glShadeModel(GL_FLAT);
         
         Debug.change("weather");
         glDepthMask(true);
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
index 0ec8ed312..79b263d9c 100644
--- a/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
+++ b/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
@@ -18,8 +18,8 @@ public final class BlockColorDispatcher
     private BlockColorDispatcher()
     {
         addDispatch(Block.algae, new BlockColorCustom(Colorizers.grass));
-        addDispatch(Block.fluidWaterStill, new BlockColorCustom(Colorizers.water));
-        addDispatch(Block.fluidWaterFlowing, new BlockColorCustom(Colorizers.water));
+        addDispatch(Block.fluidWaterStill, new BlockColorWater(Colorizers.water));
+        addDispatch(Block.fluidWaterFlowing, new BlockColorWater(Colorizers.water));
         addDispatch(Block.grass, new BlockColorCustom(Colorizers.grass));
         addDispatch(Block.layerLeavesOak, new BlockColorCustom(Colorizers.oak));
         addDispatch(Block.leavesBirch, new BlockColorCustom(Colorizers.birch));
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java
new file mode 100644
index 000000000..ca43c3990
--- /dev/null
+++ b/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java
@@ -0,0 +1,31 @@
+package net.minecraft.client.render.block.color;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.colorizer.Colorizer;
+import net.minecraft.core.world.WorldSource;
+
+public class BlockColorWater extends BlockColorCustom {
+
+	public Minecraft mc = Minecraft.getMinecraft(this);
+	
+	public BlockColorWater(Colorizer colorizer) {
+		super(colorizer);
+	}
+	
+	@Override
+	public int getFallbackColor(int meta) {
+		if(!mc.gameSettings.biomeWater.value) {
+			return 0xFFFFFFFF;
+		}
+		return super.getFallbackColor(meta);
+	}
+	
+	@Override
+	public int getWorldColor(WorldSource world, int x, int y, int z) {
+		if(!mc.gameSettings.biomeWater.value) {
+			return 0xFFFFFFFF;
+		}
+		return super.getWorldColor(world, x, y, z);
+	}
+
+}
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelCandle.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelCandle.java
index e1e4eb374..d7a654b06 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelCandle.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelCandle.java
@@ -36,25 +36,25 @@ public class BlockModelCandle<T extends Block> extends BlockModelStandard<T> {
 
         double uOffset = isLit ? 0.0f : (onePix * 3);
 
-        double sideMinU = texU + uOffset;
-        double sideMaxU = texU + uOffset + (onePix * 3);
-        double sideMinV = texV + (onePix * 3);
-        double sideMaxV = texV + (onePix * 3) + (onePix * 8);
+        double sideMinU = texIndex.getSubIconU(uOffset);
+        double sideMaxU = texIndex.getSubIconU(uOffset + (onePix * 3));
+        double sideMinV = texIndex.getSubIconV((onePix * 3));
+        double sideMaxV = texIndex.getSubIconV((onePix * 3) + (onePix * 8));
 
-        double topMinU = texU + uOffset;
-        double topMaxU = texU + uOffset + (onePix * 3);
+        double topMinU = texIndex.getSubIconU(uOffset);
+        double topMaxU = texIndex.getSubIconU(uOffset + (onePix * 3));
         double topMinV = texV;
-        double topMaxV = texV + (onePix * 3);
+        double topMaxV = texIndex.getSubIconV(onePix * 3);
 
-        double bottomMinU = texU + (onePix * 3);
-        double bottomMaxU = texU + (onePix * 3) + (onePix * 3);
+        double bottomMinU = texIndex.getSubIconU(onePix * 3);
+        double bottomMaxU = texIndex.getSubIconU((onePix * 3) + (onePix * 3));
         double bottomMinV = texV;
-        double bottomMaxV = texV + (onePix * 3);
+        double bottomMaxV = texIndex.getSubIconV(onePix * 3);
 
-        double wickMinU = texU + (onePix * 6) + uOffset;
-        double wickMaxU = texU + (onePix * 6) + uOffset + (onePix * 3);
+        double wickMinU = texIndex.getSubIconU((onePix * 6) + uOffset);
+        double wickMaxU = texIndex.getSubIconU((onePix * 6) + uOffset + (onePix * 3));
         double wickMinV = texV;
-        double wickMaxV = texV + (onePix * 6);
+        double wickMaxV = texIndex.getSubIconV(onePix * 6);
 
 
         tessellator.setColorOpaque_F(brightness, brightness, brightness);
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelFire.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelFire.java
index 5a71c2498..56fae4788 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelFire.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelFire.java
@@ -5,6 +5,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.block.BlockFire;
+import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.util.helper.Side;
 
 public class BlockModelFire<T extends Block> extends BlockModelStandard<T>{
@@ -28,8 +29,7 @@ public class BlockModelFire<T extends Block> extends BlockModelStandard<T>{
         }
         float brightness = 1.0f;
         if(LightmapHelper.isLightmapEnabled()) {
-        	// TODO skylight
-        	tessellator.setLightmapCoord(LightmapHelper.getOverbrightLightmapCoord(0));
+        	tessellator.setLightmapCoord(LightmapHelper.getOverbrightLightmapCoord(renderBlocks.blockAccess.getSavedLightValue(LightLayer.Sky, x, y, z)));
         }else {
         	brightness = renderBlocks.getBlockBrightness(renderBlocks.blockAccess, x, y, z);
         }
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelRail.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelRail.java
index 834b15979..865ee6499 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelRail.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelRail.java
@@ -6,6 +6,7 @@ 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.BlockRail;
+import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
 
@@ -35,8 +36,7 @@ public class BlockModelRail<T extends BlockRail> extends BlockModelStandard<T> {
 		float brightness = 1.0f;
 		if(LightmapHelper.isLightmapEnabled()) {
 			if(renderBlocks.overbright) {
-				// TODO use correct skylight value, requires a getSavedLightValue method in WorldSource
-				tessellator.setLightmapCoord(LightmapHelper.getOverbrightLightmapCoord(0));
+				tessellator.setLightmapCoord(LightmapHelper.getOverbrightLightmapCoord(renderBlocks.blockAccess.getSavedLightValue(LightLayer.Sky, x, y, z)));
 			}else {
 				tessellator.setLightmapCoord(block.getLightmapCoord(renderBlocks.blockAccess, x, y, z));
 			}
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 a066dbe3f..4c53551ab 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
@@ -1,14 +1,14 @@
 package net.minecraft.client.render.block.model;
 
-import net.minecraft.client.render.stitcher.IconCoordinate;
+import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockRedstoneRepeater;
-import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
 
+@SuppressWarnings("unchecked")
 public class BlockModelRepeater extends BlockModelStandard<BlockRedstoneRepeater> {
-    private static final BlockModelTorch<Block> modelTorchActive = (BlockModelTorch<Block>) BlockModelDispatcher.getInstance().getDispatch(Block.torchRedstoneActive);
+	private static final BlockModelTorch<Block> modelTorchActive = (BlockModelTorch<Block>) BlockModelDispatcher.getInstance().getDispatch(Block.torchRedstoneActive);
     private static final BlockModelTorch<Block> modelTorchIdle = (BlockModelTorch<Block>) BlockModelDispatcher.getInstance().getDispatch(Block.torchRedstoneIdle);
 
     public BlockModelRepeater(Block block) {
@@ -17,16 +17,24 @@ public class BlockModelRepeater extends BlockModelStandard<BlockRedstoneRepeater
 
     public boolean render(Tessellator tessellator, int x, int y, int z){
         block.setBlockBoundsBasedOnState(renderBlocks.blockAccess, x, y, z);
-        int l = renderBlocks.blockAccess.getBlockMetadata(x, y, z);
-        int i1 = l & 3;
-        int j1 = (l & 0xc) >> 2;
+        int meta = renderBlocks.blockAccess.getBlockMetadata(x, y, z);
+        int i1 = meta & 3;
+        int j1 = (meta & 0xc) >> 2;
         renderStandardBlock(tessellator, block, x, y, z);
-        float f = getBlockBrightness(renderBlocks.blockAccess, x, y, z);
-        if(Block.lightEmission[block.id] > 0)
-        {
-            f = (f + 1.0F) * 0.5F;
+        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);
+        	}
+        	tessellator.setLightmapCoord(lmc);
+        }else {
+    		brightness = getBlockBrightness(renderBlocks.blockAccess, x, y, z);
+    		if(Block.lightEmission[block.id] > 0) {
+    			brightness = 1.0f;
+    		}	
         }
-        tessellator.setColorOpaque_F(f, f, f);
+        tessellator.setColorOpaque_F(brightness, brightness, brightness);
         double d = -0.1875D;
         double d1 = 0.0D;
         double d2 = 0.0D;
@@ -57,46 +65,6 @@ public class BlockModelRepeater extends BlockModelStandard<BlockRedstoneRepeater
         BlockModelTorch<Block> modelTorch = block.isRepeaterPowered ? modelTorchActive : modelTorchIdle;
         modelTorch.renderTorchAtAngle(tessellator, (double)x + d1, (double)y + d, (double)z + d2, 0.0D, 0.0D);
         modelTorch.renderTorchAtAngle(tessellator, (double)x + d3, (double)y + d, (double)z + d4, 0.0D, 0.0D);
-        IconCoordinate texture = getBlockTextureFromSideAndMetadata(Side.TOP, l);
-        double d5 = texture.getIconUMin();
-        double d6 = texture.getIconUMax();
-        double d7 = texture.getIconVMin();
-        double d8 = texture.getIconVMax();
-        float f1 = 0.125F;
-        float f2 = x + 1;
-        float f3 = x + 1;
-        float f4 = x;
-        float f5 = x;
-        float f6 = z;
-        float f7 = z + 1;
-        float f8 = z + 1;
-        float f9 = z;
-        float f10 = (float)y + f1;
-        if(i1 == 2)
-        {
-            f2 = f3 = x;
-            f4 = f5 = x + 1;
-            f6 = f9 = z + 1;
-            f7 = f8 = z;
-        } else
-        if(i1 == 3)
-        {
-            f2 = f5 = x;
-            f3 = f4 = x + 1;
-            f6 = f7 = z;
-            f8 = f9 = z + 1;
-        } else
-        if(i1 == 1)
-        {
-            f2 = f5 = x + 1;
-            f3 = f4 = x;
-            f6 = f7 = z + 1;
-            f8 = f9 = z;
-        }
-        tessellator.addVertexWithUV(f5, f10, f9, d5, d7);
-        tessellator.addVertexWithUV(f4, f10, f8, d5, d8);
-        tessellator.addVertexWithUV(f3, f10, f7, d6, d8);
-        tessellator.addVertexWithUV(f2, f10, f6, d6, d7);
         return true;
     }
     @Override
@@ -107,6 +75,6 @@ public class BlockModelRepeater extends BlockModelStandard<BlockRedstoneRepeater
     @Override
     public boolean shouldSideBeRendered(WorldSource blockAccess, int x, int y, int z, int side)
     {
-        return side != 0 && side != 1;
+        return true;
     }
 }
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexture.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexture.java
index 984a03bca..3c28efe3e 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexture.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexture.java
@@ -1,24 +1,19 @@
 package net.minecraft.client.render.dynamictexture;
 
-import net.minecraft.client.render.stitcher.AtlasStitcher;
 import net.minecraft.client.render.stitcher.IconCoordinate;
 
 public abstract class DynamicTexture {
 
-	public final IconCoordinate texture;
+	public IconCoordinate texture;
+	public byte[] imageData;
 	
-	public final byte[] imageData;
+	public abstract void postInit();
 	
-	public DynamicTexture(IconCoordinate texture) {
-		this.texture = texture;
-		
-		this.imageData = new byte[texture.getArea() * 4];
-	}
-
 	public abstract void update();
 	
-	public AtlasStitcher getTexture(){
-		return texture.parentAtlas;
+	public void setTexture(IconCoordinate texture) {
+		this.texture = texture;
+		this.imageData = new byte[texture.width * texture.height * 4];
 	}
 	
 	public static int pmod(int a, int b) {
@@ -38,27 +33,4 @@ public abstract class DynamicTexture {
 		array[i * 4 + 3] = (byte) a;
 	}
 	
-//	public static void main(String[] args) {
-//		for(int i = -16; i <= 16; i++) {
-//			int a = i & 15;
-//			int b = i % 16;
-//			int c = pmod(i, 16);
-//			System.out.println(expand(3, ""+i)+" "+expand(3, ""+a)+" "+expand(3, ""+b)+" "+expand(3, ""+c));
-//		}
-//		System.out.println("---");
-//		for(int i = -16; i <= 16; i++) {
-//			int a = i & 23;
-//			int b = i % 24;
-//			int c = pmod(i, 24);
-//			System.out.println(expand(3, ""+i)+" "+expand(3, ""+a)+" "+expand(3, ""+b)+" "+expand(3, ""+c));
-//		}
-//	}
-//	
-//	public static String expand(int length, String str) {
-//		while(str.length() < length) {
-//			str = " "+str;
-//		}
-//		return str;
-//	}
-	
 }
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCalendar.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCalendar.java
index 27f8f0081..f31003ef1 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCalendar.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCalendar.java
@@ -15,11 +15,11 @@ public class DynamicTextureCalendar extends DynamicTextureAbstractClock {
 	@Override
 	public double getAngle() {
 		double d = 0.0;
-		if (minecraft.theWorld != null && minecraft.thePlayer != null)
+		if (mc.theWorld != null && mc.thePlayer != null)
 		{
-			if (minecraft.theWorld.getSeasonManager() instanceof SeasonManagerCycle)
+			if (mc.theWorld.getSeasonManager() instanceof SeasonManagerCycle)
 			{
-				SeasonManagerCycle cycleManager = (SeasonManagerCycle) minecraft.theWorld.getSeasonManager();
+				SeasonManagerCycle cycleManager = (SeasonManagerCycle) mc.theWorld.getSeasonManager();
 				float f = cycleManager.getYearProgress() - 0.25f;
 				d = f * Math.PI * 2;
 			}
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureClock.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureClock.java
index 406e260b0..dd23db0e3 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureClock.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureClock.java
@@ -15,10 +15,10 @@ public class DynamicTextureClock extends DynamicTextureAbstractClock{
 	@Override
 	public double getAngle() {
 		double d = 0.0;
-		if(minecraft.theWorld != null && minecraft.thePlayer != null) {
-			float f = minecraft.theWorld.getCelestialAngle(1.0f);
+		if(mc.theWorld != null && mc.thePlayer != null) {
+			float f = mc.theWorld.getCelestialAngle(1.0f);
 			d = -f * Math.PI * 2;
-			if(minecraft.theWorld.dimension == Dimension.nether) {
+			if(mc.theWorld.dimension == Dimension.nether) {
 				d = Math.random() * Math.PI * 2;
 			}
 		}
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCompass.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCompass.java
index e916ec6e3..b79b8a49c 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCompass.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCompass.java
@@ -9,7 +9,7 @@ import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.Dimension;
 
-public class DynamicTextureCompass extends DynamicTexture{
+public class DynamicTextureCompass extends DynamicTexture {
 	
 	private Minecraft mc;
 	
@@ -21,10 +21,13 @@ public class DynamicTextureCompass extends DynamicTexture{
 	private double scaleFactor;
 	
 	public DynamicTextureCompass(Minecraft minecraft) {
-		super(TextureRegistry.getTexture("minecraft:item/tool_compass"));
-		
 		this.mc = minecraft;
+	}
 
+	@Override
+	public void postInit() {
+		setTexture(TextureRegistry.getTexture("minecraft:item/tool_compass"));
+		
 		BufferedImage atlas = texture.parentAtlas.atlas;
 		compassImageData = new byte[texture.getArea() * 4];
 
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCustom.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCustom.java
index 2995f22ed..4c9c09f0e 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCustom.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCustom.java
@@ -1,17 +1,19 @@
 package net.minecraft.client.render.dynamictexture;
 
+import java.awt.image.BufferedImage;
+import java.util.Random;
+
 import com.b100.json.element.JsonObject;
+
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.stitcher.IconCoordinate;
+import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.texturepack.TexturePack;
 import net.minecraft.client.render.texturepack.TexturePackException;
 import net.minecraft.client.util.helper.TexturePackJsonHelper;
 import net.minecraft.client.util.helper.Textures;
 
-import java.awt.image.BufferedImage;
-import java.util.Random;
-
-public class DynamicTextureCustom extends DynamicTexture{
+public class DynamicTextureCustom extends DynamicTexture {
 	
 	private static Random rand = new Random();
 	
@@ -22,46 +24,29 @@ public class DynamicTextureCustom extends DynamicTexture{
 	private int frametime = 1;
 	private boolean random = false;
 	private boolean interpolate = false;
+	private boolean tile2x2 = false;
 	
 	private int currentFrame = -1;
 	private int previousFrame = -1;
 	private int nextFrameDelay = 0;
 	
-	public DynamicTextureCustom(Minecraft mc, String animationSource, IconCoordinate textureIndex) {
-		super(textureIndex);
-
-		TexturePack texturePack = mc.texturePackList.getHighestPriorityPack();
-		BufferedImage image = Textures.readImage(mc.texturePackList.getResourceAsStream(animationSource));
-
+	public DynamicTextureCustom(Minecraft mc, TexturePack texturePack, String animationSource, String texturePath, boolean shouldBeTiled) {
+		IconCoordinate texture = TextureRegistry.getTexture(texturePath);
+		
+		BufferedImage image = Textures.readImage(texturePack.getResourceAsStream(animationSource));
 		try {
-			if(image == null){
+			if(image == null) {
 				throw new TexturePackException("Could not load image!");
 			}
-			if(image.getWidth() != textureIndex.width) {
-				throw new TexturePackException("Invalid width! Expected " + textureIndex.width + " but got " + image.getWidth() + "!");
-			}
 			if(image.getHeight() < image.getWidth()) {
 				throw new TexturePackException("Height is smaller than width!");
-			}	
+			}
 		}catch (TexturePackException e) {
 			throw new TexturePackException("Error in animation " + animationSource, e);
 		}
-		
+
 		frameCount = image.getHeight() / image.getWidth();
 		
-		System.out.println("Frame Count: " + frameCount);
-		
-		frameData = new byte[textureIndex.getArea() * 4 * frameCount];
-		
-		for(int frame=0; frame < frameCount; frame++) {
-			for(int x=0; x < textureIndex.width; x++) {
-				for(int y=0; y < textureIndex.width; y++) {
-					int c = image.getRGB(x, frame * textureIndex.height + y);
-					putPixel(frameData, frame * textureIndex.getArea() + y * textureIndex.width + x, c);
-				}
-			}
-		}
-		
 		String jsonFilePath = animationSource.replace(".png", ".json");
 		if(texturePack.hasFile(jsonFilePath)) {
 			try {
@@ -85,10 +70,47 @@ public class DynamicTextureCustom extends DynamicTexture{
 						}
 					}
 				}
+				if(rootObject.has("tile2x2")) {
+					this.tile2x2 = TexturePackJsonHelper.getBoolean(rootObject, "tile2x2");
+				}
 			}catch (Exception e) {
 				throw new TexturePackException("Error in " + jsonFilePath, e);
 			}
 		}
+		
+		int tileCount = 1;
+		if(tile2x2) {
+			tileCount = 2;
+		}
+		
+		int res = image.getWidth();
+		int tiledRes = res * tileCount;
+		
+		texture.setDimension(tiledRes, tiledRes);
+		texture.parentAtlas.dontSetSize.add(texture);
+		setTexture(texture);
+		
+		frameData = new byte[tiledRes * tiledRes * 4 * frameCount];
+		for(int frame=0; frame < frameCount; frame++) {
+			for(int x=0; x < res; x++) {
+				for(int y=0; y < res; y++) {
+					int c = image.getRGB(x, frame * res + y);
+					for(int tileX = 0; tileX < tileCount; tileX++) {
+						for(int tileY = 0; tileY < tileCount; tileY++) {
+							int x1 = tileX * res + x;
+							int y1 = tileY * res + y;
+							int i = frame * tiledRes * tiledRes + y1 * tiledRes + x1;
+							putPixel(frameData, i, c);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	@Override
+	public void postInit() {
+		
 	}
 	
 	@Override
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFire.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFire.java
index ce690f042..84c9e5f2a 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFire.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFire.java
@@ -1,6 +1,5 @@
 package net.minecraft.client.render.dynamictexture;
 
-import net.minecraft.client.render.stitcher.AtlasStitcher;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 
 public class DynamicTextureFire extends DynamicTexture{
@@ -11,16 +10,14 @@ public class DynamicTextureFire extends DynamicTexture{
 	private int height;
 	private float scaleFactor;
 	
-	public DynamicTextureFire() {
-		super(TextureRegistry.getTexture("minecraft:block/fire"));
-		
+	@Override
+	public void postInit() {
+		setTexture(TextureRegistry.getTexture("minecraft:block/fire"));
 		scaleFactor = texture.height / 16.0f;
 		
 		height = (int) (20 * scaleFactor);
 		this.arr1 = new float[texture.width * (height + 4)];
 		this.arr2 = new float[texture.width * (height + 4)];
-		
-		
 	}
 
 	@Override
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFireflyJar.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFireflyJar.java
index 97ea14561..c14c68d6b 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFireflyJar.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFireflyJar.java
@@ -3,31 +3,39 @@ package net.minecraft.client.render.dynamictexture;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.stitcher.TextureRegistry;
+import net.minecraft.client.render.texturepack.TexturePackException;
 import net.minecraft.client.util.helper.Textures;
 import net.minecraft.core.util.helper.MathHelper;
 
 import java.awt.image.BufferedImage;
 
-public class DynamicTextureFireflyJar
-    extends DynamicTexture
-{
+public class DynamicTextureFireflyJar extends DynamicTexture {
     private final byte[] originalData;
     private long ticks = 0;
 
-    public DynamicTextureFireflyJar(Minecraft minecraft, IconCoordinate textureIndex)
-    {
-        super(textureIndex);
-
-        this.originalData = new byte[textureIndex.getArea() * 4];
-
-        BufferedImage image = Textures.readImage(minecraft.texturePackList.getResourceAsStream(TextureRegistry.blockAtlas.getSourceImagePath(textureIndex.namespaceId)));
-
-        for (int x = 0; x < textureIndex.width; x++) {
-            for (int y = 0; y < textureIndex.height; y++) {
-                putPixel(originalData, y * textureIndex.width + x, image.getRGB(x, y));
-            }
-        }
-    }
+	public DynamicTextureFireflyJar(Minecraft mc, String animationSource, String texturePath) {
+		BufferedImage image = Textures.readImage(mc.texturePackList.getResourceAsStream(animationSource));
+		if(image == null) {
+			throw new TexturePackException("Could not load image!");
+		}
+		this.originalData = new byte[image.getWidth() * image.getHeight() * 4];
+
+		IconCoordinate texture = TextureRegistry.getTexture(texturePath);
+		texture.setDimension(image.getWidth(), image.getHeight());
+		texture.parentAtlas.dontSetSize.add(texture);
+		setTexture(texture);
+		
+		for(int x = 0; x < texture.width; x++) {
+			for(int y = 0; y < texture.height; y++) {
+				putPixel(originalData, y * texture.width + x, image.getRGB(x, y));
+			}
+		}
+	}
+
+	@Override
+	public void postInit() {
+		
+	}
 
     private float getInternalBrightness()
     {
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureLavaFlowing.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureLavaFlowing.java
index b076406b1..fd6c73dda 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureLavaFlowing.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureLavaFlowing.java
@@ -1,7 +1,5 @@
 package net.minecraft.client.render.dynamictexture;
 
-import net.minecraft.client.render.block.model.BlockModelStandard;
-import net.minecraft.client.render.stitcher.AtlasStitcher;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.core.util.helper.MathHelper;
 
@@ -13,9 +11,10 @@ public class DynamicTextureLavaFlowing extends DynamicTexture {
 	private float[] arr4;
 	private int ticks = 0;
 
-	public DynamicTextureLavaFlowing() {
-		super(TextureRegistry.getTexture("minecraft:block/lava_flowing"));
-
+	@Override
+	public void postInit() {
+		setTexture(TextureRegistry.getTexture("minecraft:block/lava_flowing"));
+		
 		arr1 = new float[texture.getArea()];
 		arr2 = new float[texture.getArea()];
 		arr3 = new float[texture.getArea()];
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureLavaStill.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureLavaStill.java
index d61eafb81..fd28296fe 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureLavaStill.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureLavaStill.java
@@ -1,7 +1,5 @@
 package net.minecraft.client.render.dynamictexture;
 
-import net.minecraft.client.render.block.model.BlockModelStandard;
-import net.minecraft.client.render.stitcher.AtlasStitcher;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.core.util.helper.MathHelper;
 
@@ -12,9 +10,10 @@ public class DynamicTextureLavaStill extends DynamicTexture {
 	private float[] arr3;
 	private float[] arr4;
 
-	public DynamicTextureLavaStill() {
-		super(TextureRegistry.getTexture("minecraft:block/lava_still"));
-
+	@Override
+	public void postInit() {
+		setTexture(TextureRegistry.getTexture("minecraft:block/lava_still"));
+		
 		arr1 = new float[texture.getArea()];
 		arr2 = new float[texture.getArea()];
 		arr3 = new float[texture.getArea()];
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexturePortal.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexturePortal.java
index e793839dc..1fa41e4e5 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexturePortal.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexturePortal.java
@@ -7,11 +7,17 @@ import net.minecraft.core.util.helper.MathHelper;
 
 public class DynamicTexturePortal extends DynamicTexture{
 	
+	private boolean altTexture;
 	private int portalTickCounter = 0;
 	private byte[][] portalTextureData;
 	
 	public DynamicTexturePortal(boolean altTexture) {
-		super(TextureRegistry.getTexture("minecraft:block/portal_nether"));
+		this.altTexture = altTexture;
+	}
+
+	@Override
+	public void postInit() {
+		setTexture(TextureRegistry.getTexture("minecraft:block/portal_nether"));
 		Random var1 = new Random(100L);
 		
 		portalTextureData = new byte[32][texture.getArea() * 4];
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureRotating.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureRotating.java
index a9c59731e..ca3dd61b4 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureRotating.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureRotating.java
@@ -10,7 +10,7 @@ import net.minecraft.core.util.helper.MathHelper;
 
 public abstract class DynamicTextureRotating extends DynamicTexture {
 
-	protected final Minecraft minecraft;
+	protected final Minecraft mc;
 
 	protected byte[] dialImageData;
 	protected int dialTexRes;
@@ -20,17 +20,20 @@ public abstract class DynamicTextureRotating extends DynamicTexture {
 	protected double angleFinal;
 	protected double delta;
 
-	public DynamicTextureRotating(Minecraft minecraft, IconCoordinate textureIndex) {
-		super(textureIndex);
-
-		this.minecraft = minecraft;
-		clockImageData = new byte[textureIndex.getArea() * 4];
-
-		BufferedImage atlas = textureIndex.parentAtlas.atlas;
-		
-		for (int x = 0; x < textureIndex.width; x++) {
-			for (int y = 0; y < textureIndex.height; y++) {
-				putPixel(clockImageData, y * textureIndex.width + x, atlas.getRGB(textureIndex.iconX + x, textureIndex.iconY + y));
+	public DynamicTextureRotating(Minecraft minecraft, IconCoordinate texture) {
+		this.mc = minecraft;
+		this.texture = texture;
+	}
+	
+	@Override
+	public void postInit() {
+		setTexture(texture);
+
+		BufferedImage atlas = texture.parentAtlas.atlas;
+		clockImageData = new byte[texture.getArea() * 4];
+		for (int x = 0; x < texture.width; x++) {
+			for (int y = 0; y < texture.height; y++) {
+				putPixel(clockImageData, y * texture.width + x, atlas.getRGB(texture.iconX + x, texture.iconY + y));
 			}
 		}
 	}
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureTrommel.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureTrommel.java
index 099bee88e..be379116b 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureTrommel.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureTrommel.java
@@ -3,41 +3,44 @@ package net.minecraft.client.render.dynamictexture;
 import java.awt.image.BufferedImage;
 
 import net.minecraft.client.Minecraft;
-import net.minecraft.client.render.stitcher.AtlasStitcher;
 import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.stitcher.TextureRegistry;
-import net.minecraft.client.util.helper.Textures;
 
-public class DynamicTextureTrommel extends DynamicTextureRotating{
+public class DynamicTextureTrommel extends DynamicTextureRotating {
 	
 	private boolean counterClockwise;
 	
 	private double rotation = 0.0;
-	
 	private double speed = 0.12;
 	
 	public DynamicTextureTrommel(Minecraft minecraft, IconCoordinate textureIndex, boolean counterClockwise) {
 		super(minecraft, textureIndex);
-		
+
 		this.counterClockwise = counterClockwise;
+	}
+	
+	@Override
+	public void postInit() {
+		setTexture(texture);
+		
+		BufferedImage atlasImage = texture.parentAtlas.atlas;
 		
-		BufferedImage bufferedimage = textureIndex.parentAtlas.atlas;
-		IconCoordinate background = TextureRegistry.getTexture("minecraft:block/trommel_active_front_background");
 		IconCoordinate foreground = TextureRegistry.getTexture("minecraft:block/trommel_active_front_foreground");
-		dialImageData = new byte[textureIndex.getArea() * 4];
-		for(int x=0; x < textureIndex.width; x++) {
-			for(int y=0; y < textureIndex.height; y++) {
-				putPixel(dialImageData, y * textureIndex.width + x, bufferedimage.getRGB(foreground.iconX + x, foreground.iconY + y));
+		dialImageData = new byte[foreground.getArea() * 4];
+		for(int x=0; x < foreground.width; x++) {
+			for(int y=0; y < foreground.height; y++) {
+				putPixel(dialImageData, y * foreground.width + x, atlasImage.getRGB(foreground.iconX + x, foreground.iconY + y));
 			}
 		}
-		clockImageData = new byte[textureIndex.getArea() * 4];
-		for(int x=0; x < textureIndex.width; x++) {
-			for(int y=0; y < textureIndex.height; y++) {
-				putPixel(clockImageData, y * textureIndex.width + x, bufferedimage.getRGB(background.iconX+ x, background.iconY + y));
+		dialTexRes = foreground.width;
+		
+		IconCoordinate background = TextureRegistry.getTexture("minecraft:block/trommel_active_front_background");
+		clockImageData = new byte[background.getArea() * 4];
+		for(int x=0; x < background.width; x++) {
+			for(int y=0; y < background.height; y++) {
+				putPixel(clockImageData, y * background.width + x, atlasImage.getRGB(background.iconX+ x, background.iconY + y));
 			}
 		}
-		
-		dialTexRes = textureIndex.height;
 	}
 
 	@Override
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
index 049c77706..6f60365cd 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
@@ -13,9 +13,10 @@ public class DynamicTextureWaterFlow extends DynamicTexture {
 	private float[] arr4;
 	private int ticks = 0;
 
-	public DynamicTextureWaterFlow() {
-		super(TextureRegistry.getTexture("minecraft:block/water_flowing"));
-
+	@Override
+	public void postInit() {
+		setTexture(TextureRegistry.getTexture("minecraft:block/water_flowing"));
+		
 		arr1 = new float[texture.getArea()];
 		arr2 = new float[texture.getArea()];
 		arr3 = new float[texture.getArea()];
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
index d40cea63a..1cf3862ec 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
@@ -12,8 +12,9 @@ public class DynamicTextureWaterStill extends DynamicTexture {
 	private float[] arr3;
 	private float[] arr4;
 
-	public DynamicTextureWaterStill() {
-		super(TextureRegistry.getTexture("minecraft:block/water_still"));
+	@Override
+	public void postInit() {
+		setTexture(TextureRegistry.getTexture("minecraft:block/water_still"));
 
 		arr1 = new float[texture.getArea()];
 		arr2 = new float[texture.getArea()];
diff --git a/src/main/java/net/minecraft/client/render/entity/ArmoredZombieRenderer.java b/src/main/java/net/minecraft/client/render/entity/ArmoredZombieRenderer.java
index e3bcfaddd..8f2757d95 100644
--- a/src/main/java/net/minecraft/client/render/entity/ArmoredZombieRenderer.java
+++ b/src/main/java/net/minecraft/client/render/entity/ArmoredZombieRenderer.java
@@ -19,7 +19,7 @@ public class ArmoredZombieRenderer extends MobRenderer<EntityArmoredZombie>
 
     protected boolean setArmorModel(EntityArmoredZombie zombie, int renderPass, float partialTick)
     {
-        loadTexture("/armor/chain" + "_" + (renderPass != 2 ? 1 : 2) + ".png");
+        loadTexture("/assets/minecraft/textures/armor/chain" + "_" + (renderPass != 2 ? 1 : 2) + ".png");
         ModelZombie model = renderPass != 2 ? modelArmorChestplate : modelArmor;
         model.bipedHead.showModel = renderPass == 0;
         model.bipedHeadOverlay.showModel = renderPass == 0;
diff --git a/src/main/java/net/minecraft/client/render/stitcher/AtlasStitcher.java b/src/main/java/net/minecraft/client/render/stitcher/AtlasStitcher.java
index 28abaeede..eb3137b22 100644
--- a/src/main/java/net/minecraft/client/render/stitcher/AtlasStitcher.java
+++ b/src/main/java/net/minecraft/client/render/stitcher/AtlasStitcher.java
@@ -1,22 +1,27 @@
 package net.minecraft.client.render.stitcher;
 
-import net.minecraft.client.GLAllocation;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.util.helper.Textures;
-import org.jetbrains.annotations.Nullable;
-
-import java.awt.*;
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
 import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+
+import org.jetbrains.annotations.Nullable;
+
+import net.minecraft.client.GLAllocation;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.util.helper.Textures;
 
 public class AtlasStitcher {
     private static final Minecraft mc = Minecraft.getMinecraft(AtlasStitcher.class);
     public static final String rootAssetPath = "/assets";
     public Map<String, IconCoordinate> textureMap = new HashMap<>();
+    public Set<IconCoordinate> dontSetSize = new HashSet<>();
     public BufferedImage atlas;
     public final String directoryPath;
     @Nullable
@@ -52,6 +57,9 @@ public class AtlasStitcher {
         int maxWidth = 0;
         List<IconCoordinate> coordinateList = new ArrayList<>(textureMap.values());
         for (IconCoordinate coordinate : coordinateList){
+        	if(dontSetSize.contains(coordinate)) {
+        		continue;
+        	}
             BufferedImage image = Textures.readImage(mc.texturePackList.getResourceAsStream(coordinate.sourceImage));
             if (image == null || image == Textures.missingTexture){
                 System.out.println(coordinate.sourceImage + " could not be found!");
@@ -65,6 +73,7 @@ public class AtlasStitcher {
             area += coordinate.getArea();
             if (coordinate.width > maxWidth) maxWidth = coordinate.width;
         }
+        dontSetSize.clear();
         // Calculate an okay atlas width to keep the aspect ratio of the final atlas mostly 1:1
         int targetWidth = (int) (Math.max(Math.ceil(Math.sqrt(area)), maxWidth));
         Collections.sort(coordinateList);
diff --git a/src/main/java/net/minecraft/client/render/stitcher/IconCoordinate.java b/src/main/java/net/minecraft/client/render/stitcher/IconCoordinate.java
index c59f497f3..32bf70e6c 100644
--- a/src/main/java/net/minecraft/client/render/stitcher/IconCoordinate.java
+++ b/src/main/java/net/minecraft/client/render/stitcher/IconCoordinate.java
@@ -10,7 +10,6 @@ public class IconCoordinate implements Comparable<IconCoordinate> {
     public int iconY;
     public int width;
     public int height;
-    private int area;
     protected final String sourceImage;
     public final String namespaceId;
     public final AtlasStitcher parentAtlas;
@@ -29,14 +28,13 @@ public class IconCoordinate implements Comparable<IconCoordinate> {
     public void setDimension(int width, int height){
         this.width = width;
         this.height = height;
-        this.area = width * height;
     }
     public void setPosition(int x, int y){
         this.iconX = x;
         this.iconY = y;
     }
     public int getArea(){
-        return area;
+        return width * height;
     }
     protected void drawToAtlas(Graphics2D atlas){
         atlas.drawImage(_imageStorage, iconX, iconY, null);
diff --git a/src/main/java/net/minecraft/client/render/tessellator/TessellatorStandard.java b/src/main/java/net/minecraft/client/render/tessellator/TessellatorStandard.java
index 0b8a59c59..958b64dd7 100644
--- a/src/main/java/net/minecraft/client/render/tessellator/TessellatorStandard.java
+++ b/src/main/java/net/minecraft/client/render/tessellator/TessellatorStandard.java
@@ -135,6 +135,17 @@ public class TessellatorStandard extends TessellatorBase {
 	public void addVertex(double x, double y, double z) {
 		checkIsDrawing();
 
+		if(buffer.capacity() < buffer.position() + 64) {
+			int newSize = buffer.capacity() * 2;
+			
+			System.out.println("Expanding Tessellator Buffer (" + buffer.capacity() + " -> " + newSize + ")");
+			
+			ByteBuffer newBuffer = ByteBuffer.allocateDirect(newSize).order(ByteOrder.nativeOrder());
+			this.buffer.flip();
+			newBuffer.put(buffer);
+			this.buffer = newBuffer;
+		}
+		
 		buffer.putFloat((float) (offsetX + x));
 		buffer.putFloat((float) (offsetY + y));
 		buffer.putFloat((float) (offsetZ + z));
diff --git a/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java b/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
index a3114b2a5..24459217c 100644
--- a/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
+++ b/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
@@ -194,4 +194,17 @@ public class TexturePackList
 		if (selectedPacks.isEmpty()) return defaultTexturePack;
 		return selectedPacks.get(selectedPacks.size()-1);
 	}
+	
+	public TexturePack getHighestPriorityTexturePackWithFile(String path) {
+		for(int i = selectedPacks.size() - 1; i >= 0; i--) {
+			TexturePack texturePack = selectedPacks.get(i);
+			if(texturePack.hasFile(path)) {
+				return texturePack;
+			}
+		}
+		if(defaultTexturePack.hasFile(path)) {
+			return defaultTexturePack;
+		}
+		return null;
+	}
 }
diff --git a/src/main/java/net/minecraft/core/block/entity/TileEntitySeat.java b/src/main/java/net/minecraft/core/block/entity/TileEntitySeat.java
index 6c6401dd2..165d39805 100644
--- a/src/main/java/net/minecraft/core/block/entity/TileEntitySeat.java
+++ b/src/main/java/net/minecraft/core/block/entity/TileEntitySeat.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block.entity;
 
+import net.minecraft.core.block.Block;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.world.IVehicle;
 
@@ -17,6 +18,11 @@ public class TileEntitySeat
         if (passenger != null) {
             worldObj.updateEntity(passenger);
         }
+
+        // TODO the server really needs a better way of telling the client that a tile entity no longer exists, but this works to fix the client thinking that the seat remains if its broken in multiplayer
+        if (worldObj.getBlock(x, y, z) != Block.seat){
+            ejectRider();
+        }
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/core/crafting/ICrafting.java b/src/main/java/net/minecraft/core/crafting/ICrafting.java
index 88a42602d..a686b2c74 100644
--- a/src/main/java/net/minecraft/core/crafting/ICrafting.java
+++ b/src/main/java/net/minecraft/core/crafting/ICrafting.java
@@ -10,7 +10,7 @@ import java.util.List;
 
 public interface ICrafting
 {
-    void updateCraftingInventory(Container container, List list);
+    void updateCraftingInventory(Container container, List<ItemStack> list);
 	
     void updateInventorySlot(Container container, int i, ItemStack itemstack);
 
diff --git a/src/main/java/net/minecraft/core/entity/EntityLiving.java b/src/main/java/net/minecraft/core/entity/EntityLiving.java
index eb89adc33..f93497ea8 100644
--- a/src/main/java/net/minecraft/core/entity/EntityLiving.java
+++ b/src/main/java/net/minecraft/core/entity/EntityLiving.java
@@ -548,6 +548,10 @@ public abstract class EntityLiving extends Entity
         {
             dropFewItems();
         }
+        if (vehicle != null){
+            vehicle.ejectRider();
+            vehicle = null;
+        }
         world.sendTrackedEntityStatusUpdatePacket(this, (byte)3);
     }
 
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 2792ac683..47b9736ca 100644
--- a/src/main/java/net/minecraft/core/entity/animal/EntityWolf.java
+++ b/src/main/java/net/minecraft/core/entity/animal/EntityWolf.java
@@ -381,7 +381,7 @@ public class EntityWolf extends EntityAnimal
         super.tick();
 
         List<Entity> entitiesNearWolf = world.getEntitiesWithinAABBExcludingEntity(this, bb);
-        if(entitiesNearWolf != null && entitiesNearWolf.size() > 0)
+        if(entitiesNearWolf != null && entitiesNearWolf.size() > 0 && isAlive())
         {
             for (Entity entity : entitiesNearWolf) {
                 if(entity instanceof EntityItem && (this.getWolfHeldItem() == null || this.getWolfHeldItem().getItem() == null)){
diff --git a/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java b/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
index 2534592c4..74e99b3bd 100644
--- a/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
+++ b/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
@@ -147,6 +147,21 @@ public class EntityBoat extends Entity
         }
         return true;
     }
+    @Override
+    public void remove(){
+        Entity entity = passenger;
+
+        if (entity != null){
+            double bbCenterX = (bb.minX + bb.maxX)/2;
+            double bbCenterZ = (bb.minZ + bb.maxZ)/2;
+
+            this.passenger = null;
+            entity.vehicle = null;
+            entity.moveTo(bbCenterX, this.bb.maxY + 0.1, bbCenterZ, entity.yRot, entity.xRot);
+        }
+
+        super.remove();
+    }
 
     @Override
 	public void animateHurt()
@@ -466,8 +481,11 @@ public class EntityBoat extends Entity
     
     @Override
     public Entity ejectRider() {
-    	Entity entity = super.ejectRider();
-    	if(entity == null) return null;
+        Entity entity = passenger;
+        if(entity == null) return null;
+
+        this.passenger = null;
+        entity.vehicle = null;
 
         double bbCenterX = (bb.minX + bb.maxX)/2;
         double bbCenterY = (bb.minY + bb.maxY)/2;
@@ -488,7 +506,7 @@ public class EntityBoat extends Entity
         if (!flag){
             entity.moveTo(bbCenterX, this.bb.maxY + 0.1, bbCenterZ, entity.yRot, entity.xRot);
         }
-    	return entity;
+        return entity;
     }
     @Override
     protected void causeFallDamage(float f){}
diff --git a/src/main/java/net/minecraft/core/lang/I18n.java b/src/main/java/net/minecraft/core/lang/I18n.java
index 87548b9ca..808480f2e 100644
--- a/src/main/java/net/minecraft/core/lang/I18n.java
+++ b/src/main/java/net/minecraft/core/lang/I18n.java
@@ -36,6 +36,9 @@ public class I18n {
         }
         try {
             currentLanguage = LanguageSeeker.seek(languageCode);
+            if (currentLanguage == null){
+                currentLanguage = Language.Default.INSTANCE;
+            }
         } catch (IOException e) {
             // Fallback to the default language if the specified language is not found
             currentLanguage = Language.Default.INSTANCE;
diff --git a/src/main/java/net/minecraft/core/lang/LanguageSeeker.java b/src/main/java/net/minecraft/core/lang/LanguageSeeker.java
index 2aa4da8d7..73cf25313 100644
--- a/src/main/java/net/minecraft/core/lang/LanguageSeeker.java
+++ b/src/main/java/net/minecraft/core/lang/LanguageSeeker.java
@@ -5,6 +5,8 @@ import com.b100.json.element.JsonArray;
 import com.b100.json.element.JsonElement;
 import com.b100.json.element.JsonObject;
 import net.minecraft.core.Global;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.io.*;
 import java.nio.charset.StandardCharsets;
@@ -28,6 +30,7 @@ public class LanguageSeeker {
      * @return the language found, or <tt>null</tt> if no language with the specific ID is found
      * @throws IOException if an I/O error has occured
      */
+    @Nullable
     public static Language seek(String id) throws IOException {
         if (id.equals("en_US")) return Language.Default.INSTANCE;
         Language ret = null;
diff --git a/src/main/java/net/minecraft/core/net/command/ClientCommandHandler.java b/src/main/java/net/minecraft/core/net/command/ClientCommandHandler.java
index e2a5e248a..9063c475a 100644
--- a/src/main/java/net/minecraft/core/net/command/ClientCommandHandler.java
+++ b/src/main/java/net/minecraft/core/net/command/ClientCommandHandler.java
@@ -3,6 +3,7 @@ package net.minecraft.core.net.command;
 import net.minecraft.client.Minecraft;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.world.World;
+import org.jetbrains.annotations.Nullable;
 
 public class ClientCommandHandler implements CommandHandler{
 
@@ -27,7 +28,7 @@ public class ClientCommandHandler implements CommandHandler{
 	}
 
 	@Override
-	public EntityPlayer getPlayer(String name) {
+	public @Nullable EntityPlayer getPlayer(String name) {
 		if(minecraft.thePlayer.username.equalsIgnoreCase(name)) {
 			return minecraft.thePlayer;
 		}else {
diff --git a/src/main/java/net/minecraft/core/net/command/ClientPlayerCommandSender.java b/src/main/java/net/minecraft/core/net/command/ClientPlayerCommandSender.java
index 95214f844..91b3c525a 100644
--- a/src/main/java/net/minecraft/core/net/command/ClientPlayerCommandSender.java
+++ b/src/main/java/net/minecraft/core/net/command/ClientPlayerCommandSender.java
@@ -2,6 +2,7 @@ package net.minecraft.core.net.command;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.core.entity.player.EntityPlayer;
+import net.minecraft.core.world.World;
 import net.minecraft.client.entity.player.EntityPlayerSP;
 
 public class ClientPlayerCommandSender extends PlayerCommandSender{
@@ -35,5 +36,10 @@ public class ClientPlayerCommandSender extends PlayerCommandSender{
 	public String getName() {
 		return player.getDisplayName();
 	}
+
+	@Override
+	public World getWorld() {
+		return minecraft.theWorld;
+	}
 	
 }
diff --git a/src/main/java/net/minecraft/core/net/command/CommandHandler.java b/src/main/java/net/minecraft/core/net/command/CommandHandler.java
index d79983558..f6a3b30c9 100644
--- a/src/main/java/net/minecraft/core/net/command/CommandHandler.java
+++ b/src/main/java/net/minecraft/core/net/command/CommandHandler.java
@@ -2,44 +2,45 @@ package net.minecraft.core.net.command;
 
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.world.World;
+import org.jetbrains.annotations.Nullable;
 
 public interface CommandHandler {
 	
 	/**
 	 * Sends command feedback to the player who sent the command, and to all admins
 	 */
-	public void sendCommandFeedback(CommandSender sender, String message);
+    void sendCommandFeedback(CommandSender sender, String message);
 	
-	public void sendMessageToAdmins(String msg);
+	void sendMessageToAdmins(String msg);
 	
-	public void sendMessageToAllPlayers(String msg);
+	void sendMessageToAllPlayers(String msg);
 	
-	public void sendMessageToPlayer(EntityPlayer player, String messsage);
-	
-	public EntityPlayer getPlayer(String name);
+	void sendMessageToPlayer(EntityPlayer player, String messsage);
+
+	@Nullable EntityPlayer getPlayer(String name);
 	
-	public boolean playerExists(String name);
+	boolean playerExists(String name);
 	
-	public World getWorld(int dimension);
+	World getWorld(int dimension);
 
 	
-	public default World getWorld(EntityPlayer player) {
+	default World getWorld(EntityPlayer player) {
 		return getWorld(player.dimension);
 	}
 	
-	public default boolean isServer() {
+	default boolean isServer() {
 		return this instanceof ServerCommandHandler;
 	}
 	
-	public default boolean isClient() {
+	default boolean isClient() {
 		return this instanceof ClientCommandHandler;
 	}
 	
-	public default ServerCommandHandler asServer() {
+	default ServerCommandHandler asServer() {
 		return (ServerCommandHandler) this;
 	}
 	
-	public default ClientCommandHandler asClient() {
+	default ClientCommandHandler asClient() {
 		return (ClientCommandHandler) this;
 	}
 
diff --git a/src/main/java/net/minecraft/core/net/command/CommandSender.java b/src/main/java/net/minecraft/core/net/command/CommandSender.java
index 489603394..f91de575f 100644
--- a/src/main/java/net/minecraft/core/net/command/CommandSender.java
+++ b/src/main/java/net/minecraft/core/net/command/CommandSender.java
@@ -1,12 +1,15 @@
 package net.minecraft.core.net.command;
 
 import net.minecraft.core.entity.player.EntityPlayer;
+import net.minecraft.core.world.World;
 
 public interface CommandSender {
 	
 	public boolean isAdmin();
 	
 	public EntityPlayer getPlayer();
+	
+	public World getWorld();
 
 	public void sendMessage(String string);
 	
diff --git a/src/main/java/net/minecraft/core/net/command/ConsoleCommandSender.java b/src/main/java/net/minecraft/core/net/command/ConsoleCommandSender.java
index fff12b7e9..98695cb71 100644
--- a/src/main/java/net/minecraft/core/net/command/ConsoleCommandSender.java
+++ b/src/main/java/net/minecraft/core/net/command/ConsoleCommandSender.java
@@ -1,13 +1,11 @@
 package net.minecraft.core.net.command;
 
+import org.apache.log4j.Logger;
 
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.server.MinecraftServer;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.util.helper.LogPrintStream;
-import org.apache.log4j.Logger;
-
+import net.minecraft.core.world.World;
+import net.minecraft.server.MinecraftServer;
 
 public class ConsoleCommandSender implements CommandSender{
 	
@@ -39,5 +37,10 @@ public class ConsoleCommandSender implements CommandSender{
 		return "Console";
 	}
 
+	@Override
+	public World getWorld() {
+		return minecraftServer.getDimensionWorld(0);
+	}
+
 
 }
diff --git a/src/main/java/net/minecraft/core/net/command/ServerCommandHandler.java b/src/main/java/net/minecraft/core/net/command/ServerCommandHandler.java
index 0df5d99cf..27a177b64 100644
--- a/src/main/java/net/minecraft/core/net/command/ServerCommandHandler.java
+++ b/src/main/java/net/minecraft/core/net/command/ServerCommandHandler.java
@@ -5,6 +5,7 @@ import net.minecraft.server.MinecraftServer;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.net.packet.Packet3Chat;
 import net.minecraft.core.world.World;
+import org.jetbrains.annotations.Nullable;
 
 public class ServerCommandHandler implements CommandHandler{
 
@@ -20,7 +21,7 @@ public class ServerCommandHandler implements CommandHandler{
 	}
 
 	@Override
-	public EntityPlayer getPlayer(String name) {
+	public @Nullable EntityPlayer getPlayer(String name) {
 		return minecraftServer.playerList.getPlayerEntity(name);
 	}
 
diff --git a/src/main/java/net/minecraft/core/net/command/ServerPlayerCommandSender.java b/src/main/java/net/minecraft/core/net/command/ServerPlayerCommandSender.java
index 4c58d5cb0..eea4757e6 100644
--- a/src/main/java/net/minecraft/core/net/command/ServerPlayerCommandSender.java
+++ b/src/main/java/net/minecraft/core/net/command/ServerPlayerCommandSender.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.net.command;
 
 import net.minecraft.core.util.helper.AES;
+import net.minecraft.core.world.World;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.server.entity.player.EntityPlayerMP;
@@ -40,4 +41,9 @@ public class ServerPlayerCommandSender extends PlayerCommandSender{
 		return player.getDisplayName();
 	}
 
+	@Override
+	public World getWorld() {
+		return player.world;
+	}
+
 }
diff --git a/src/main/java/net/minecraft/core/net/command/TextFormatting.java b/src/main/java/net/minecraft/core/net/command/TextFormatting.java
index 5d91c01e3..c953a03c7 100644
--- a/src/main/java/net/minecraft/core/net/command/TextFormatting.java
+++ b/src/main/java/net/minecraft/core/net/command/TextFormatting.java
@@ -25,7 +25,7 @@ public class TextFormatting {
     public static final TextFormatting UNDERLINE = new TextFormatting(19).setNames("Underline");
     public static final TextFormatting ITALIC = new TextFormatting(20).setNames("Italic");
     public static final TextFormatting RESET = new TextFormatting(21).setNames("Reset");
-	
+
 	public final int id;
 	public final char code;
 	private String[] names;
@@ -53,10 +53,7 @@ public class TextFormatting {
 		return null;
 	}
 	public static String removeAllFormatting(String name){
-		for (TextFormatting formatting : FORMATTINGS) {
-			name = name.replace(formatting.toString(), "");
-		}
-		return name;
+		return name.replaceAll("§[0123456789abcdefklmnor]|§<(.*?)>", "");
 	}
 
     public static String formatted(String string, TextFormatting... formattings) {
diff --git a/src/main/java/net/minecraft/core/net/command/commands/DeopCommand.java b/src/main/java/net/minecraft/core/net/command/commands/DeopCommand.java
index bbd29854d..1bffff740 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/DeopCommand.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/DeopCommand.java
@@ -18,12 +18,17 @@ public class DeopCommand extends ServerCommand{
 	public boolean execute(CommandHandler handler, CommandSender sender, String[] args) {
 		if(args.length == 0) return false;
 		String name = args[0];
-		
+
+		boolean playerWasOp = server.playerList.isOp(name);
+
 		server.playerList.deopPlayer(name);
-		handler.sendCommandFeedback(sender, "De-opping "+name);
+
+		if (playerWasOp) {
+			handler.sendCommandFeedback(sender, "De-opping "+name);
+		}
 
 		EntityPlayerMP player = (EntityPlayerMP) handler.getPlayer(name);
-		if(player != null) {
+		if(player != null && playerWasOp) {
 			handler.sendMessageToPlayer(player, TextFormatting.YELLOW + "You are no longer op!");
 			player.mcServer.playerList.sendPacketToAllPlayers(new Packet72UpdatePlayerProfile(player.username, player.nickname, player.score, player.chatColor, true, player.isOperator()));
 		}
diff --git a/src/main/java/net/minecraft/core/net/command/commands/NicknameCommand.java b/src/main/java/net/minecraft/core/net/command/commands/NicknameCommand.java
index 55c278caa..acee986f0 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/NicknameCommand.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/NicknameCommand.java
@@ -28,7 +28,8 @@ public class NicknameCommand extends ServerCommand
             StringBuilder enteredNicknameStr = new StringBuilder();
             for (int i = 1; i < args.length; i++) enteredNicknameStr.append(args[i]).append(" ");
 
-            String enteredNickname = enteredNicknameStr.substring(0, enteredNicknameStr.length() - 1);
+            String enteredNickname = TextFormatting.removeAllFormatting(enteredNicknameStr.substring(0, enteredNicknameStr.length() - 1));
+            System.out.println(enteredNickname);
             if (enteredNickname.length() > 16) enteredNickname = enteredNickname.substring(0, 16);
 
             player.nickname = enteredNickname;
@@ -67,7 +68,8 @@ public class NicknameCommand extends ServerCommand
                 StringBuilder enteredNicknameStr = new StringBuilder();
                 for (int i = 2; i < args.length; i++) enteredNicknameStr.append(args[i]).append(" ");
 
-                String enteredNickname = enteredNicknameStr.substring(0, enteredNicknameStr.length() - 1);
+                String enteredNickname = TextFormatting.removeAllFormatting(enteredNicknameStr.substring(0, enteredNicknameStr.length() - 1));
+                System.out.println(enteredNickname);
                 if (enteredNickname.length() > 16) enteredNickname = enteredNickname.substring(0, 16);
 
                 player.nickname = enteredNickname;
diff --git a/src/main/java/net/minecraft/core/net/command/commands/WeatherCommand.java b/src/main/java/net/minecraft/core/net/command/commands/WeatherCommand.java
index 4e68c8573..99e2cdb82 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/WeatherCommand.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/WeatherCommand.java
@@ -1,15 +1,12 @@
 package net.minecraft.core.net.command.commands;
 
-import net.minecraft.core.entity.player.EntityPlayer;
-import net.minecraft.core.world.weather.Weather;
-import net.minecraft.core.world.World;
-import net.minecraft.core.net.command.TextFormatting;
-import net.minecraft.core.net.command.ClientCommandHandler;
 import net.minecraft.core.net.command.Command;
 import net.minecraft.core.net.command.CommandError;
 import net.minecraft.core.net.command.CommandHandler;
 import net.minecraft.core.net.command.CommandSender;
-import net.minecraft.core.net.command.ServerCommandHandler;
+import net.minecraft.core.net.command.TextFormatting;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.weather.Weather;
 
 public class WeatherCommand extends Command{
 
@@ -19,7 +16,9 @@ public class WeatherCommand extends Command{
 
 	@Override
 	public boolean execute(CommandHandler handler, CommandSender sender, String[] args) {
-		if(args.length == 0) return false;
+		if(args.length == 0) {
+			return false;
+		}
 		
 		if(args[0].equals("list")) {
 			StringBuilder weatherString = new StringBuilder();
@@ -39,63 +38,45 @@ public class WeatherCommand extends Command{
 			return true;
 		}
 		
-		if(sender.isPlayer()) {
-			EntityPlayer player = sender.getPlayer();
-			
-			if(args[0].equals("next")) {
-				player.world.weatherManager.skip();
-				handler.sendCommandFeedback(sender, "Skipping to next weather");
-				return true;
-			}
-			else if (args[0].equals("set"))
-			{
-				int dimension = player.dimension;
-				Long duration = null;
-				Weather weather = null;
-				Float power = null;
-
-				World world = null;
-				if(handler instanceof ServerCommandHandler) {
-					ServerCommandHandler server = (ServerCommandHandler) handler;
-					world = server.minecraftServer.dimensionWorlds[dimension];
-				}
-				if(handler instanceof ClientCommandHandler) {
-					ClientCommandHandler client = (ClientCommandHandler) handler;
-					world = client.minecraft.theWorld;
-				}
-
-				if(world == null) return false;
-
-				weather = getWeather(args[1], world);
-				if(weather == null) throw new CommandError("Weather \""+args[1]+"\" doesn't exist!");
-
-				if(args.length >= 3) {
-					duration = Long.parseLong(args[2]) * 20;
-				}
-				if(args.length >= 4) {
-					power = Float.parseFloat(args[3]);
-				}
-
-				if (duration != null && power != null) {
-					world.weatherManager.overrideWeather(weather, duration, power);
-				} else if (duration != null) {
-					world.weatherManager.overrideWeather(weather, duration);
-				} else {
-					world.weatherManager.overrideWeather(weather);
-				}
-
-				handler.sendCommandFeedback(sender, TextFormatting.LIGHT_GRAY + "Changing weather to " + TextFormatting.WHITE + weather.getLanguageKey().substring(8));
-
-				return true;
-			}
-			else
-			{
-				return false;
-			}
+		World world = sender.getWorld();
+		if(args[0].equals("next")) {
+			world.weatherManager.skip();
+			handler.sendCommandFeedback(sender, "Skipping to next weather");
+			return true;
+		}
+		
+		int offset = 0;
+		if(args[0].equals("set")) {
+			offset = 1;
+		}
+		
+		String weatherId = args[offset];
+		Weather weather = getWeather(weatherId, world);
+		if(weather == null) {
+			throw new CommandError("Weather \"" + weatherId + "\" doesn't exist!");
+		}
+		
+		Long duration = null;
+		if(args.length > offset + 1) {
+			duration = Long.parseLong(args[offset + 1]) * 20;
+		}
+		
+		Float power = null;
+		if(args.length > offset + 2) {
+			power = Float.parseFloat(args[offset + 2]);
+		}
 
+		if(duration != null && power != null) {
+			world.weatherManager.overrideWeather(weather, duration, power);
+		}else if(duration != null) {
+			world.weatherManager.overrideWeather(weather, duration);
 		}else {
-			return false;
+			world.weatherManager.overrideWeather(weather);
 		}
+		
+		handler.sendCommandFeedback(sender, TextFormatting.LIGHT_GRAY + "Changing weather to " + TextFormatting.WHITE + weather.getLanguageKey().substring(8));
+		
+		return true;
 	}
 
 	@Override
@@ -106,28 +87,25 @@ public class WeatherCommand extends Command{
 	@Override
 	public void sendCommandSyntax(CommandHandler handler, CommandSender sender) {
 		sender.sendMessage("/weather list");
-		if(sender.isPlayer()) {
-			sender.sendMessage("/weather next");
-			sender.sendMessage("/weather set <weather> [duration (sec)] [power (0.0-1.0)]");
-		}
+		sender.sendMessage("/weather next");
+		sender.sendMessage("/weather set <weather> [duration (sec)] [power (0.0-1.0)]");
+		sender.sendMessage("/weather <weather> [duration (sec)] [power (0.0-1.0)]");
 	}
 	
 	public static Weather getWeather(String string, World world) {
 		try {
-			try {
-				return Weather.getWeather(Integer.parseInt(string));
-			}catch (Exception e) {}
-			
-			if(string.equalsIgnoreCase("clear")) {
-				Weather w = world.worldType.getDefaultWeather();
-				if(w == null) throw new CommandError("Dimension "+world.dimension.getTranslatedName()+" does not have a default weather!");
-				return w;
+			return Weather.getWeather(Integer.parseInt(string));
+		}catch (NumberFormatException e) {}
+
+		if(string.equalsIgnoreCase("clear")) {
+			Weather weather = world.worldType.getDefaultWeather();
+			if(weather == null) {
+				throw new CommandError("Dimension " + world.dimension.getTranslatedName() + " does not have a default weather!");
 			}
-			
-			return Weather.getWeatherByLanguageKey(string);
-		}catch (Exception e) {
-			throw new RuntimeException(e);
+			return weather;
 		}
+		
+		return Weather.getWeatherByLanguageKey(string);
 	}
 
 }
diff --git a/src/main/java/net/minecraft/core/net/packet/Packet104WindowItems.java b/src/main/java/net/minecraft/core/net/packet/Packet104WindowItems.java
index 0e6b51677..188d58772 100644
--- a/src/main/java/net/minecraft/core/net/packet/Packet104WindowItems.java
+++ b/src/main/java/net/minecraft/core/net/packet/Packet104WindowItems.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.net.packet;
 
+import com.mojang.nbt.CompoundTag;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.net.handler.NetHandler;
 
@@ -16,13 +17,13 @@ public class Packet104WindowItems extends Packet
     {
     }
     
-    public Packet104WindowItems(int i, List list)
+    public Packet104WindowItems(int i, List<ItemStack> list)
     {
         windowId = i;
         itemStack = new ItemStack[list.size()];
         for(int j = 0; j < itemStack.length; j++)
         {
-            ItemStack itemstack = (ItemStack)list.get(j);
+            ItemStack itemstack = list.get(j);
             itemStack[j] = itemstack != null ? itemstack.copy() : null;
         }
 
@@ -42,7 +43,11 @@ public class Packet104WindowItems extends Packet
             {
                 byte byte0 = dis.readByte();
                 short word2 = dis.readShort();
-                itemStack[i] = new ItemStack(word1, byte0, word2);
+                CompoundTag tag = null;
+                if (dis.readByte() == 1){
+                    tag = readCompressedCompoundTag(dis);
+                }
+                itemStack[i] = new ItemStack(word1, byte0, word2, tag);
             }
         }
 
@@ -64,6 +69,12 @@ public class Packet104WindowItems extends Packet
                 dos.writeShort((short)itemStack[i].itemID);
                 dos.writeByte((byte)itemStack[i].stackSize);
                 dos.writeShort((short)itemStack[i].getMetadata());
+                if (!itemStack[i].getData().getValues().isEmpty()){
+                    dos.writeByte(0);
+                } else {
+                    dos.writeByte(1);
+                    writeCompressedCompoundTag(itemStack[i].getData(), dos);
+                }
             }
         }
 
@@ -82,5 +93,5 @@ public class Packet104WindowItems extends Packet
     }
 
     public int windowId;
-    public ItemStack itemStack[];
+    public ItemStack[] itemStack;
 }
diff --git a/src/main/java/net/minecraft/core/net/packet/Packet255KickDisconnect.java b/src/main/java/net/minecraft/core/net/packet/Packet255KickDisconnect.java
index c4229c07b..a60b3b05f 100644
--- a/src/main/java/net/minecraft/core/net/packet/Packet255KickDisconnect.java
+++ b/src/main/java/net/minecraft/core/net/packet/Packet255KickDisconnect.java
@@ -27,7 +27,7 @@ public class Packet255KickDisconnect extends Packet
 	public void readPacketData(DataInputStream dis)
         throws IOException
     {
-        reason = readUTF16BEString(dis, 200);
+        reason = readUTF16BEString(dis, 255);
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/core/world/World.java b/src/main/java/net/minecraft/core/world/World.java
index 28423c816..621d320b8 100644
--- a/src/main/java/net/minecraft/core/world/World.java
+++ b/src/main/java/net/minecraft/core/world/World.java
@@ -1029,6 +1029,7 @@ public class World implements WorldSource {
         }
     }
 
+    @Override
     public int getSavedLightValue(LightLayer layer, int x, int y, int z)
     {
         if(y < 0)
diff --git a/src/main/java/net/minecraft/core/world/WorldSource.java b/src/main/java/net/minecraft/core/world/WorldSource.java
index 10699959d..e5843d29c 100644
--- a/src/main/java/net/minecraft/core/world/WorldSource.java
+++ b/src/main/java/net/minecraft/core/world/WorldSource.java
@@ -3,6 +3,7 @@ package net.minecraft.core.world;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.material.Material;
+import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.season.SeasonManager;
 
@@ -32,4 +33,6 @@ public interface WorldSource
     double getBlockHumidity(int x, int z);
     SeasonManager getSeasonManager();
     Biome getBlockBiome(int x, int y, int z);
+    
+    public int getSavedLightValue(LightLayer layer, int x, int y, int z);
 }
diff --git a/src/main/java/net/minecraft/core/world/biome/Biomes.java b/src/main/java/net/minecraft/core/world/biome/Biomes.java
index 6df483bca..12e736592 100644
--- a/src/main/java/net/minecraft/core/world/biome/Biomes.java
+++ b/src/main/java/net/minecraft/core/world/biome/Biomes.java
@@ -17,7 +17,7 @@ public class Biomes
     public static final Biome OVERWORLD_TAIGA = register("minecraft:overworld.taiga", new BiomeTaiga("taiga").setColor(0x8abcff).setSurfaceSnow());
     public static final Biome OVERWORLD_BOREAL_FOREST = register("minecraft:overworld.boreal_forest", new BiomeBorealForest("boreal_forest").setColor(0x148564));
     public static final Biome OVERWORLD_DESERT = register("minecraft:overworld.desert", new BiomeDesert("desert").setColor(0xEDE26F).setBlockedWeathers(Weather.overworldRain, Weather.overworldSnow, Weather.overworldStorm).setTopBlock(Block.sand.id).setFillerBlock(Block.sand.id));
-    public static final Biome OVERWORLD_PLAINS = register("minecraft:overworld.plains", new BiomeForest("plains").setColor(0xA3C649));
+    public static final Biome OVERWORLD_PLAINS = register("minecraft:overworld.plains", new BiomePlains("plains").setColor(0xA3C649));
     public static final Biome OVERWORLD_GLACIER = register("minecraft:overworld.glacier", new Biome("glacier").setColor(0xcbf6ff).setSurfaceSnow().setTopBlock(Block.blockSnow.id).setFillerBlock(Block.blockSnow.id));
     public static final Biome OVERWORLD_TUNDRA = register("minecraft:overworld.tundra", new Biome("tundra").setColor(0x57e0ff).setSurfaceSnow());
     public static final Biome OVERWORLD_MEADOW = register("minecraft:overworld.meadow", new BiomeBorealForest("meadow").setColor(0x8c8c22));
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 86b6079a2..bd0db92c0 100644
--- a/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
+++ b/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
@@ -276,4 +276,9 @@ public class ChunkCache
     public Biome getBlockBiome(int x, int y, int z) {
         return worldObj.getBlockBiome(x, y, z);
     }
+
+	@Override
+	public int getSavedLightValue(LightLayer layer, int x, int y, int z) {
+		return worldObj.getSavedLightValue(layer, x, y, z);
+	}
 }
diff --git a/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreeThorn.java b/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreeThorn.java
index 99907a0a3..191d15527 100644
--- a/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreeThorn.java
+++ b/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreeThorn.java
@@ -62,6 +62,7 @@ public class WorldFeatureTreeThorn extends WorldFeatureSpoonerTreeProcedural {
             } else {
                 branchY = posY - dist * slope;
             }
+            branchY = Math.max(branchY, pos[1]);
             int[] startCoord = new int[] { treePosition[0], (int) branchY, treePosition[2]};
             taperedLimb(startCoord, coord, 1.0, 1.0, world);
         }
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 95cb97222..e3beb7d28 100644
--- a/src/main/java/net/minecraft/server/entity/player/EntityPlayerMP.java
+++ b/src/main/java/net/minecraft/server/entity/player/EntityPlayerMP.java
@@ -788,14 +788,14 @@ public class EntityPlayerMP extends EntityPlayer
     }
 
     @Override
-	public void updateCraftingInventory(Container container, List list)
+	public void updateCraftingInventory(Container container, List<ItemStack> list)
     {
 
         //playernetserverhandler returning false?
         if (playerNetServerHandler != null)
         {
             playerNetServerHandler.sendPacket(new Packet104WindowItems(container.windowId, list));
-            playerNetServerHandler.sendPacket(new Packet103SetSlot(-1, -1, inventory.getHeldItemStack()));
+//            playerNetServerHandler.sendPacket(new Packet103SetSlot(-1, -1, inventory.getHeldItemStack()));
         }
     }
 
diff --git a/src/main/java/net/minecraft/server/net/ConsoleCommandHandler.java b/src/main/java/net/minecraft/server/net/ConsoleCommandHandler.java
index 5fdb32b64..ba3bee281 100644
--- a/src/main/java/net/minecraft/server/net/ConsoleCommandHandler.java
+++ b/src/main/java/net/minecraft/server/net/ConsoleCommandHandler.java
@@ -61,6 +61,7 @@ public class ConsoleCommandHandler
     			return true;
     		}
     	}
+        sender.sendMessage(TextFormatting.RED + "Command '" + args[0] + "' does not exist!");
     	
     	return false;
     }
diff --git a/src/main/java/net/minecraft/server/net/PlayerList.java b/src/main/java/net/minecraft/server/net/PlayerList.java
index ad272edd0..cc66f95cf 100644
--- a/src/main/java/net/minecraft/server/net/PlayerList.java
+++ b/src/main/java/net/minecraft/server/net/PlayerList.java
@@ -16,6 +16,7 @@ import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.save.PlayerIO;
 import net.minecraft.server.MinecraftServer;
 import org.apache.log4j.Logger;
+import org.jetbrains.annotations.Nullable;
 
 
 import java.io.*;
@@ -515,7 +516,7 @@ public class PlayerList
     {
         return ops.contains(s.trim().toLowerCase());
     }
-
+    @Nullable
     public EntityPlayerMP getPlayerEntity(String s)
     {
         for (int i = 0; i < playerEntities.size(); i++)
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 72d01acde..6e1ec53c4 100644
--- a/src/main/java/net/minecraft/server/net/handler/NetServerHandler.java
+++ b/src/main/java/net/minecraft/server/net/handler/NetServerHandler.java
@@ -534,7 +534,7 @@ public class NetServerHandler extends NetHandler
 		}
 		
 		message = message.trim();
-		message = message.replace('\u00A7', '$');
+//		message = message.replace('\u00A7', '$');
 		
 		for(int i = 0; i < message.length(); i++) {
 			char c = message.charAt(i);
@@ -771,10 +771,10 @@ public class NetServerHandler extends NetHandler
                 field_10_k.put(Integer.valueOf(playerEntity.craftingInventory.windowId), Short.valueOf(packet.actionId));
                 playerEntity.playerNetServerHandler.sendPacket(new Packet106Transaction(packet.window_Id, packet.actionId, false));
                 playerEntity.craftingInventory.setCanCraft(playerEntity, false);
-                ArrayList arraylist = new ArrayList();
+                ArrayList<ItemStack> arraylist = new ArrayList<>();
                 for (int i = 0; i < playerEntity.craftingInventory.inventorySlots.size(); i++)
                 {
-                    arraylist.add(((Slot) playerEntity.craftingInventory.inventorySlots.get(i)).getStack());
+                    arraylist.add(playerEntity.craftingInventory.inventorySlots.get(i).getStack());
                 }
 
                 playerEntity.updateCraftingInventory(playerEntity.craftingInventory, arraylist);
@@ -934,6 +934,6 @@ public class NetServerHandler extends NetHandler
     private double lastPosY;
     private double lastPosZ;
     private boolean hasMoved;
-    private Map field_10_k;
+    private final Map<Integer, Short> field_10_k;
 
 }
diff --git a/src/main/resources/assets/minecraft/textures/colormap/oak/overworld_winter.png b/src/main/resources/assets/minecraft/textures/colormap/oak/overworld_winter.png
new file mode 100644
index 000000000..7fa6cf0e5
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/oak/overworld_winter.png differ
