diff --git a/devResources/credits.txt b/devResources/credits.txt
index 9c502ef73..332dbfb0d 100644
--- a/devResources/credits.txt
+++ b/devResources/credits.txt
@@ -7,4 +7,6 @@ step.permafrost1 | H2_AIL
 step.permafrost2 | H2_AIL
 step.permafrost3 | H2_AIL
 step.permafrost4 | H2_AIL
-random.equip | Bones edited some freesounds sounds lol
\ No newline at end of file
+random.equip | Bones edited some freesounds sounds lol
+random.bite | mzov4j
+random.bite_extended | mzov4j
\ No newline at end of file
diff --git a/devResources/sound/random/bite.ogg b/devResources/sound/random/bite.ogg
new file mode 100644
index 000000000..f3fa04400
Binary files /dev/null and b/devResources/sound/random/bite.ogg differ
diff --git a/devResources/sound/random/bite_extended.ogg b/devResources/sound/random/bite_extended.ogg
new file mode 100644
index 000000000..ca573484d
Binary files /dev/null and b/devResources/sound/random/bite_extended.ogg differ
diff --git a/src/common/resources/lang/en_US/stats.lang b/src/common/resources/lang/en_US/stats.lang
index f302a8bfa..2ae4118b9 100644
--- a/src/common/resources/lang/en_US/stats.lang
+++ b/src/common/resources/lang/en_US/stats.lang
@@ -87,4 +87,37 @@ achievement.getChainmail.desc=Wear a set of fully repaired chainmail armor
 achievement.openGuidebook=Recipe for Success
 achievement.openGuidebook.desc=Press '%1$s' to open the guidebook.
 achievement.caughtEmAll=Caught 'Em All!
-achievement.caughtEmAll.desc=Collect every color of firefly in a jar.
\ No newline at end of file
+achievement.caughtEmAll.desc=Collect every color of firefly in a jar.
+achievement.craftIcecream=Cherry on Top
+achievement.craftIcecream.desc=Craft an ice cream bucket.
+achievement.craftPumpkinPie=Autumn Special
+achievement.craftPumpkinPie.desc=Craft a pumpkin pie.
+achievement.getDiamonds=Diamonds!
+achievement.getDiamonds.desc=Mine diamond ore to a diamond.
+achievement.allArmorTypes=Master of None
+achievement.allArmorTypes.desc=Wear an armor piece from 4 different sets.
+achievement.allMusicDiscs=Music Collector
+achievement.allMusicDiscs.desc=Collect all music discs.
+achievement.tripleHit=Three for One Deal!
+achievement.tripleHit.desc=Hit three mobs with a single golden arrow.
+
+achievement.enterNether=The Inferno
+achievement.enterNether.desc=Enter the Nether
+achievement.swimNether=Frozen Over
+achievement.swimNether.desc=Melt some ice and take a swim.
+achievement.enterOldworld=As Above...
+achievement.enterOldworld.desc=Enter the Old World
+achievement.enterWarrens=...So Below
+achievement.enterWarrens.desc=Enter the Warrens
+achievement.getNethercoal=Fiery Fuel
+achievement.getNethercoal.desc=Mine some nethercoal from the Nether.
+achievement.hitFireball=I can do Better
+achievement.hitFireball.desc=Hit a Ghast's fireball at another mob.
+achievement.sleepNether=Rude Awakening
+achievement.sleepNether.desc=Attempt to sleep in the Nether.
+achievement.lightSign=Glow in the Dark
+achievement.lightSign.desc=Apply glowstone dust to a sign.
+achievement.mostWanted=Most Wanted
+achievement.mostWanted.desc=Have more then 10 Zombie Pigmen attack you.
+achievement.fastTravel=Dimensional Slingshot
+achievement.fastTravel.desc=Use the Nether to travel more then 8000 blocks in the Overworld.
\ No newline at end of file
diff --git a/src/main/java/com/mojang/nbt/Tag.java b/src/main/java/com/mojang/nbt/Tag.java
index 2d2108ba1..cf6184e0b 100644
--- a/src/main/java/com/mojang/nbt/Tag.java
+++ b/src/main/java/com/mojang/nbt/Tag.java
@@ -108,11 +108,8 @@ public abstract class Tag<T>
         else
         {
             Tag<?> tag = newTag(typeId);
-            if (tag != null)
-            {
-                tag.name = dis.readUTF();
-                tag.read(dis);
-            }
+            tag.name = dis.readUTF();
+            tag.read(dis);
             return tag;
         }
     }
@@ -187,8 +184,7 @@ public abstract class Tag<T>
      * @param type The ID of the type of tag to create.
      * @return The created tag, or null if the type ID doesn't match any tag types.
      */
-    public static Tag<?> newTag(byte type)
-    {
+    public static Tag<?> newTag(byte type) throws IOException {
         switch(type)
         {
         case 0:
@@ -218,7 +214,7 @@ public abstract class Tag<T>
         case 12:
         	return new DoubleArrayTag();
         }
-        return null;
+        throw new IOException("Cannot read NBT Tag type for type '" + type + "'!");
     }
 
     /**
diff --git a/src/main/java/net/betterthanadventure/utils/BiomeFinder.java b/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
index e56e5db6c..5f3b15b42 100644
--- a/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
+++ b/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
@@ -137,10 +137,13 @@ public class BiomeFinder implements MinecraftAccessor {
 			worldDirectory = new File("");
 		}
 
-		Global.accessor = this;
-
 		frame = new JFrame(title);
-		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+		if (Global.accessor != null) {
+			frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+		} else {
+			frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+			Global.accessor = this;
+		}
 
         try {
             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); //set Look and Feel to Windows
diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java
index 0a3eb716d..6ad3ac2e5 100644
--- a/src/main/java/net/minecraft/client/Minecraft.java
+++ b/src/main/java/net/minecraft/client/Minecraft.java
@@ -2082,6 +2082,17 @@ public class Minecraft
         x *= Dimension.getCoordScale(lastDim, newDim);
         z *= Dimension.getCoordScale(lastDim, newDim);
         thePlayer.moveTo(x, y, z, thePlayer.yRot, thePlayer.xRot);
+        ChunkCoordinates newCoordinates = new ChunkCoordinates(MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z));
+        if (thePlayer.dimensionEnterCoordinate != null) {
+            double dx = thePlayer.dimensionEnterCoordinate.x - x;
+            double dy = thePlayer.dimensionEnterCoordinate.y - y;
+            double dz = thePlayer.dimensionEnterCoordinate.z - z;
+            double distSqr = (dx * dx) + (dy * dy) + (dz * dz);
+            if (distSqr > 8000 * 8000) {
+                thePlayer.addStat(Achievements.FAST_TRAVEL, 1);
+            }
+        }
+        thePlayer.dimensionEnterCoordinate = newCoordinates;
         if(thePlayer.isAlive())
         {
             theWorld.updateEntityWithOptionalForce(thePlayer, false);
diff --git a/src/main/java/net/minecraft/client/gui/GuiException.java b/src/main/java/net/minecraft/client/gui/GuiException.java
index ca0860130..71de3b752 100644
--- a/src/main/java/net/minecraft/client/gui/GuiException.java
+++ b/src/main/java/net/minecraft/client/gui/GuiException.java
@@ -30,7 +30,7 @@ public class GuiException {
                 .append(TextFormatting.WHITE).append(".\n\n");
         try
         {
-            s.append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
+            s.append(TextFormatting.WHITE).append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
             s.append("Minecraft: Better than Adventure! ").append(Minecraft.VERSION).append("\n");
             s.append("OS: ").append(System.getProperty("os.name")).append(" (").append(System.getProperty("os.arch")).append(") version ").append(System.getProperty("os.version")).append("\n");
             s.append("Java: ").append(System.getProperty("java.version")).append(", ").append(System.getProperty("java.vendor")).append("\n");
@@ -52,7 +52,7 @@ public class GuiException {
 
 
         GuiPopup popup = new PopupBuilder(parent,860/scale).withLabel("gui.exception.label.exception_occurred")
-                .withMessageBox("gui.exception.list",400/scale,s.toString(),150/scale)
+                .withMessageBox("gui.exception.list",400/scale,s.toString(),(860/scale) / mc.fontRenderer.getCharWidth('m'))
                 .withButtonGroup("gui.exception.choice",new String[]{"gui.exception.button.back","gui.exception.button.copy_error"},new int[]{0,1})
                 .withOnCloseListener(new PopupListener(mc,s.toString().replaceAll("§[0-9a-f|klmnor]","")))
                 .build();
@@ -73,7 +73,7 @@ public class GuiException {
                 .append(TextFormatting.WHITE).append(".\n\n");
         try
         {
-            s.append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
+            s.append(TextFormatting.WHITE).append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
             s.append("Minecraft: Better than Adventure! ").append(Minecraft.VERSION).append("\n");
             s.append("OS: ").append(System.getProperty("os.name")).append(" (").append(System.getProperty("os.arch")).append(") version ").append(System.getProperty("os.version")).append("\n");
             s.append("Java: ").append(System.getProperty("java.version")).append(", ").append(System.getProperty("java.vendor")).append("\n");
@@ -96,7 +96,7 @@ public class GuiException {
         GuiBlank gui = new GuiBlank();
         mc.displayGuiScreen(gui);
         GuiPopup popup = new PopupBuilder(gui,860/scale).withLabel("gui.exception.label.fatal_error")
-                .withMessageBox("gui.exception.list",400/scale,s.toString(),150/scale)
+                .withMessageBox("gui.exception.list",400/scale,s.toString(),(860/scale) / mc.fontRenderer.getCharWidth('m'))
                 .withButtonGroup("gui.exception.choice",new String[]{"gui.exception.button.copy_error","gui.exception.button.copy_error_and_quit"},new int[]{0,2},new boolean[]{false,true})
                 .withBackgroundColor(0xff402020, 0xff501010)
                 .withOnCloseListener(new PopupListener(mc,s.toString().replaceAll("§[0-9a-f|klmnor]","")))
@@ -118,7 +118,7 @@ public class GuiException {
                 .append(TextFormatting.WHITE).append(".\n\n");
         try
         {
-            s.append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
+            s.append(TextFormatting.WHITE).append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
             s.append("Minecraft: Better than Adventure! ").append(Minecraft.VERSION).append("\n");
             s.append("OS: ").append(System.getProperty("os.name")).append(" (").append(System.getProperty("os.arch")).append(") version ").append(System.getProperty("os.version")).append("\n");
             s.append("Java: ").append(System.getProperty("java.version")).append(", ").append(System.getProperty("java.vendor")).append("\n");
@@ -141,7 +141,7 @@ public class GuiException {
         GuiBlank gui = new GuiBlank();
         mc.displayGuiScreen(gui);
         GuiPopup popup = new PopupBuilder(gui,860/scale).withLabel("gui.exception.label.startup_error")
-                .withMessageBox("gui.exception.list",400/scale,s.toString(),150/scale)
+                .withMessageBox("gui.exception.list",400/scale,s.toString(),(860/scale) / mc.fontRenderer.getCharWidth('m'))
                 .withButtonGroup("gui.exception.choice",new String[]{"gui.exception.button.copy_error","gui.exception.button.copy_error_and_quit"},new int[]{0,2},new boolean[]{false,true})
                 .withBackgroundColor(0xff402020, 0xff501010)
                 .withOnCloseListener(new PopupListener(mc,s.toString().replaceAll("§[0-9a-f|klmnor]","")))
diff --git a/src/main/java/net/minecraft/client/gui/achievements/data/AchievementPage.java b/src/main/java/net/minecraft/client/gui/achievements/data/AchievementPage.java
index 3d32ea5e1..d6798d336 100644
--- a/src/main/java/net/minecraft/client/gui/achievements/data/AchievementPage.java
+++ b/src/main/java/net/minecraft/client/gui/achievements/data/AchievementPage.java
@@ -11,16 +11,21 @@ import net.minecraft.core.util.helper.Side;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.Random;
 
 public abstract class AchievementPage {
+    private final List<Achievement> achievementList = new ArrayList<>();
 
     public abstract @NotNull String getName();
 
     public abstract @NotNull String getDescription();
 
-    public abstract void addAchievement(@NotNull Achievement achievement);
+    public void addAchievement(@NotNull Achievement achievement) {
+        achievementList.add(Objects.requireNonNull(achievement));
+    }
 
     public abstract @NotNull Achievement onOpenAchievement();
 
@@ -30,15 +35,27 @@ public abstract class AchievementPage {
 
     public abstract @NotNull ItemStack getIcon();
 
-    public abstract @NotNull List<Achievement> getAchievements();
+    public @NotNull List<Achievement> getAchievements() {
+        return achievementList;
+    }
 
-    public abstract double getCompletionFraction(StatsCounter counter);
+    public double getCompletionFraction(StatsCounter counter) {
+        int completed = 0;
+        for (Achievement a : achievementList) {
+            if (counter.isUnlocked(a)) {
+                completed++;
+            }
+        }
+        return completed / (double) achievementList.size();
+    }
 
     public abstract int backgroundLayers();
 
     public abstract int backgroundColor();
 
-    public abstract boolean hasAchievement(Achievement achievement);
+    public boolean hasAchievement(Achievement achievement) {
+        return achievementList.contains(achievement);
+    }
 
     public abstract IconCoordinate getAchievementIcon(Achievement achievement);
 
@@ -48,7 +65,7 @@ public abstract class AchievementPage {
 
     public abstract int lineColorCanUnlock(boolean isHovered);
 
-    public static IconCoordinate getTextureFromBlock(Block block){
+    public static IconCoordinate getTextureFromBlock(Block block) {
         return BlockModelDispatcher.getInstance().getDispatch(block).getBlockTextureFromSideAndMetadata(Side.TOP, 0);
     }
 }
diff --git a/src/main/java/net/minecraft/client/gui/achievements/data/AchievementPages.java b/src/main/java/net/minecraft/client/gui/achievements/data/AchievementPages.java
index 072688dbc..232b0d142 100644
--- a/src/main/java/net/minecraft/client/gui/achievements/data/AchievementPages.java
+++ b/src/main/java/net/minecraft/client/gui/achievements/data/AchievementPages.java
@@ -1,8 +1,7 @@
 package net.minecraft.client.gui.achievements.data;
 
-import net.minecraft.client.gui.achievements.pages.DefaultPage;
-import net.minecraft.client.gui.achievements.pages.NetherPage;
 import net.minecraft.client.gui.achievements.pages.OverworldPage;
+import net.minecraft.client.gui.achievements.pages.NetherPage;
 import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.block.Blocks;
 
@@ -19,25 +18,8 @@ public class AchievementPages {
     public static void init(){
         if (hasInit) return;
         hasInit = true;
-        overworldPage = register(new OverworldPage());
-        netherPage = register(new NetherPage());
-//        netherPage = new NetherPage();
-
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
-        register(new DefaultPage("DUMMY PAGE", Blocks.SPONGE_DRY.getDefaultStack()));
+        overworldPage = register(new OverworldPage("gui.achievements.page.overworld", Blocks.GRASS.getDefaultStack()));
+        netherPage = register(new NetherPage("gui.achievements.page.nether", Blocks.NETHERRACK.getDefaultStack()));
     }
     static {
         Achievements.init();
diff --git a/src/main/java/net/minecraft/client/gui/achievements/pages/DefaultPage.java b/src/main/java/net/minecraft/client/gui/achievements/pages/DefaultPage.java
deleted file mode 100644
index 30f0d6d52..000000000
--- a/src/main/java/net/minecraft/client/gui/achievements/pages/DefaultPage.java
+++ /dev/null
@@ -1,476 +0,0 @@
-package net.minecraft.client.gui.achievements.pages;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.achievements.GuiAchievements;
-import net.minecraft.client.gui.achievements.data.AchievementPage;
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.WeightedRandomBag;
-import net.minecraft.core.achievement.Achievement;
-import net.minecraft.core.achievement.Achievements;
-import net.minecraft.core.achievement.stat.StatsCounter;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.lang.I18n;
-import net.minecraft.core.util.helper.MathHelper;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Random;
-import java.util.function.BiFunction;
-
-public class DefaultPage extends AchievementPage {
-    protected final Minecraft mc = Minecraft.getMinecraft(this);
-    protected final ItemStack icon;
-    @NotNull
-    private final List<Achievement> achievementList = new ArrayList<>();
-    protected final String key;
-    public DefaultPage(String key, ItemStack icon){
-        this.key = key;
-        this.icon = icon;
-    }
-    @Override
-    public void addAchievement(@NotNull Achievement achievement){
-        achievementList.add(Objects.requireNonNull(achievement));
-    }
-    @Override
-    public @NotNull String getName() {
-        return I18n.getInstance().translateNameKey(key);
-    }
-
-    @Override
-    public @NotNull String getDescription() {
-        return I18n.getInstance().translateDescKey(key);
-    }
-
-    @Override
-    public @NotNull Achievement onOpenAchievement() {
-        return Achievements.BUILD_WORKBENCH;
-    }
-
-    protected static final int ORE_COAL = 0;
-    protected static final int ORE_IRON = 1;
-    protected static final int ORE_GOLD = 2;
-    protected static final int ORE_DIAMOND = 3;
-    protected static final int ORE_REDSTONE = 4;
-    protected static final int ORE_LAPIS = 5;
-    protected static final Block[] STONE_ORES = new Block[]     { Blocks.ORE_COAL_STONE,    Blocks.ORE_IRON_STONE,      Blocks.ORE_GOLD_STONE,      Blocks.ORE_DIAMOND_STONE,       Blocks.ORE_REDSTONE_STONE,      Blocks.ORE_LAPIS_STONE};
-    protected static final Block[] GRANITE_ORES = new Block[]   { Blocks.ORE_COAL_GRANITE,  Blocks.ORE_IRON_GRANITE,    Blocks.ORE_GOLD_GRANITE,    Blocks.ORE_DIAMOND_GRANITE,     Blocks.ORE_REDSTONE_GRANITE,    Blocks.ORE_LAPIS_GRANITE};
-    protected static final Block[] LIMESTONE_ORES = new Block[] { Blocks.ORE_COAL_LIMESTONE,Blocks.ORE_IRON_LIMESTONE,  Blocks.ORE_GOLD_LIMESTONE,  Blocks.ORE_DIAMOND_LIMESTONE,   Blocks.ORE_REDSTONE_LIMESTONE,  Blocks.ORE_LAPIS_LIMESTONE};
-    protected static final Block[] BASALT_ORES = new Block[]    { Blocks.ORE_COAL_BASALT,   Blocks.ORE_IRON_BASALT,     Blocks.ORE_GOLD_BASALT,     Blocks.ORE_DIAMOND_BASALT,      Blocks.ORE_REDSTONE_BASALT,     Blocks.ORE_LAPIS_BASALT};
-
-    @Override
-    public IconCoordinate getBackgroundTile(GuiAchievements guiAchievements, int layer, Random random, int tileX, int tileY) {
-        random.setSeed(random.nextLong() + key.hashCode()); // makes seed different for each instance of this class :)
-        // expect x range from  0  to 45
-        // expect y range from -12 to 50
-        final int sandLayer = -20;
-        final int dirtLayer = 2;
-        final int bedrockLayer = 35;
-        final int stoneLayer = bedrockLayer - (int) ((bedrockLayer - dirtLayer) * 0.5f);
-        final int basaltLayer = bedrockLayer - (int) ((bedrockLayer - dirtLayer) * 0.25f);
-
-        final int graniteColumn = 5;
-        final int limestoneColumn = 50;
-
-        final int offsetX = tileX + random.nextInt(3) - random.nextInt(3);
-        final int offsetY = tileY + random.nextInt(3) - random.nextInt(3);
-
-        if (offsetY <= sandLayer){
-            return getTextureFromBlock(Blocks.SAND);
-        } else if (offsetY <= dirtLayer) {
-            return getTextureFromBlock(Blocks.DIRT);
-        } else if (offsetY >= bedrockLayer) {
-            return getTextureFromBlock(Blocks.BEDROCK);
-        } else {
-            if (offsetY >= basaltLayer){
-                return getOreFromStone(Blocks.BASALT, random, tileX, tileY);
-            } else if (offsetY >= stoneLayer){
-                return getOreFromStone(Blocks.STONE, random, tileX, tileY);
-            } else {
-                if (offsetX <= graniteColumn){
-                    return getOreFromStone(Blocks.GRANITE, random, tileX, tileY);
-                } else if (offsetX >= limestoneColumn) {
-                    return getOreFromStone(Blocks.LIMESTONE, random, tileX, tileY);
-                }
-                return getOreFromStone(Blocks.STONE, random, tileX, tileY);
-            }
-        }
-    }
-
-    @Override
-    public void postProcessBackground(GuiAchievements gui, Random random, GuiAchievements.BGLayer layer, int orgX, int orgY) {
-        random.setSeed(random.nextLong() + key.hashCode()); // makes seed different for each instance of this class :)
-        if (layer.id == 0) {
-
-            int y = 5;
-            int delta = 0;
-            int tYMin = -2;
-            int tYMax = -6;
-            int lowestY = 0;
-            for (int _x = -100; _x < 100; _x++) {
-                delta += random.nextInt(2) - random.nextInt(2);
-                delta = MathHelper.clamp(delta, -3, 3);
-                int sign = (int) Math.signum(delta);
-                int _d = Math.abs(delta);
-                if (_d != 0) {
-                    y += sign * random.nextInt(_d);
-                }
-
-                if (y > tYMax) {
-                    delta -= 1;
-                }
-                if (y < tYMin) {
-                    delta += 1;
-                }
-                if (y > lowestY) y = lowestY;
-
-                for (int rY = y; rY - orgY >= 0; rY--) {
-                    if (rY == y) {
-                        layer.put(TextureRegistry.getTexture("minecraft:block/grass_side"), _x - orgX, rY - orgY);
-                    } else {
-                        layer.put(null, _x - orgX, rY - orgY);
-                    }
-                    gui.getLayer(1).put(null, _x - orgX, rY - orgY);
-                }
-            }
-
-            int[] brickPos = null;
-            int[] cobblePos = null;
-            int lastY = 0;
-            int cave = -1;
-            for (int _x = -100; _x <= 100; _x++) {
-                if (random.nextInt(20) == 0 && cave <= 0) {
-                    cave = 20 + random.nextInt(5) - random.nextInt(5);
-                }
-                if (cave > 0){
-                    lastY = (25 + random.nextInt(4) - random.nextInt(4));
-                    carveCircle(gui, layer, _x - orgX, lastY - orgY, 2 + random.nextInt(3));
-                }
-                if (cave == 0 && (-10 <= _x && _x <= 40)) {
-                    brickPos = new int[]{_x, lastY};
-                }
-                cave--;
-            }
-            cave = -1;
-            for (int _x = -100; _x <= 100; _x++) {
-                if (random.nextInt(10) == 0 && cave <= 0) {
-                    cave = 5 + random.nextInt(5) - random.nextInt(5);
-                }
-                if (cave > 0){
-                    carveCircle(gui, layer, _x - orgX, (10 + random.nextInt(2) - random.nextInt(2)) - orgY, random.nextInt(3));
-                }
-                cave--;
-            }
-
-            if (brickPos == null) {
-                brickPos = new int[]{5 + random.nextInt(20) + random.nextInt(20), 15 + random.nextInt(10)};
-            }
-
-            placeStructure(gui, dungeonBrick, brickPos[0] - orgX,brickPos[1] - orgY, (struct, cache) -> {
-                if (cache == null) {
-                    if (struct == chest || struct == spawner) {
-                        return struct;
-                    }
-                    return null;
-                }
-                return struct;
-            });
-            placeStructure(gui, dungeonCobble, -orgX + 5 + random.nextInt(20) + random.nextInt(20),-orgY + 5 + random.nextInt(5), (struct, cache) -> {
-                if (cache == null) {
-                    if (struct == chest || struct == spawner) {
-                        return struct;
-                    }
-                    return null;
-                }
-                return struct;
-            });
-        } else if (layer.id == 1) {
-            // Remove covered icons
-            IconCoordinate[] foreground = gui.getLayer(0).getData();
-            IconCoordinate[] background = layer.getData();
-            for (int i = 0; i < background.length; i++) {
-                if (foreground[i] != null && foreground[i] != spawner){
-                    background[i] = null;
-                }
-            }
-        }
-    }
-
-    protected void carveCircle(GuiAchievements gui, GuiAchievements.BGLayer layer, int centerX, int centerY, int radius){
-        for (int i = centerX - radius; i <= centerX + radius ; i++) {
-            for (int j = centerY - radius; j < centerY + radius; j++) {
-                double diffX = (i + 0.5) - centerX;
-                double diffY = (j + 0.5) - centerY;
-                if ((diffX * diffX) + (diffY * diffY) < radius * radius){
-                    layer.put(null, i, j);
-                }
-            }
-        }
-    }
-
-    protected void placeStructure(GuiAchievements gui, PageStructure structure, int tileX, int tileY, @Nullable BiFunction<IconCoordinate, IconCoordinate, IconCoordinate> coordinateProcessor) {
-        if (coordinateProcessor == null) {
-            coordinateProcessor = (i, i2) -> i;
-        }
-        for (int layer = 0; layer < structure.layers; layer++) {
-            GuiAchievements.BGLayer cache = gui.getLayer(layer);
-            if (cache != null) {
-                for (int _x = 0; _x < structure.width; _x++) {
-                    for (int _y = 0; _y < structure.height; _y++) {
-                        IconCoordinate coordinate = structure.getIcon(_x, _y, layer);
-                        cache.put(coordinateProcessor.apply(coordinate, cache.get(tileX + _x, tileY + _y)), tileX + _x, tileY + _y);
-                    }
-                }
-            }
-        }
-    }
-
-    private static final WeightedRandomBag<Integer> oreBag = new WeightedRandomBag<>();
-
-    protected IconCoordinate getOreFromStone(Block stoneBlock, Random random, int tileX, int tileY){
-        oreBag.clear();
-
-        random.setSeed(random.nextLong());
-
-        final int coalStart = 2;
-        final int coalEnd = 20;
-
-        final int ironStart = 2;
-        final int ironEnd = 25;
-
-        final int goldStart = 20;
-        final int goldEnd = 35;
-
-        final int diamondStart = 25;
-        final int diamondEnd = 35;
-
-        final int lapisStart = 25;
-        final int lapisEnd = 35;
-
-        final int redstoneStart = 20;
-        final int redstoneEnd = 35;
-
-        oreBag.addEntry(-1, 300);
-
-        if (tileY >= coalStart && tileY <= coalEnd){
-            oreBag.addEntry(ORE_COAL, 15);
-        }
-
-        if (tileY >= ironStart && tileY <= ironEnd){
-            oreBag.addEntry(ORE_IRON, 15);
-        }
-
-        if (tileY >= goldStart && tileY <= goldEnd){
-            oreBag.addEntry(ORE_GOLD, 3);
-        }
-
-        if (tileY >= diamondStart && tileY <= diamondEnd){
-            oreBag.addEntry(ORE_DIAMOND, 1);
-        }
-
-        if (tileY >= lapisStart && tileY <= lapisEnd){
-            oreBag.addEntry(ORE_LAPIS, 2);
-        }
-
-        if (tileY >= redstoneStart && tileY <= redstoneEnd){
-            oreBag.addEntry(ORE_REDSTONE, 5);
-        }
-
-        int oreIndex = oreBag.getRandom(random);
-
-        if (oreIndex >= 0){
-            if (stoneBlock == Blocks.STONE){
-                return getTextureFromBlock(STONE_ORES[oreIndex]);
-            } else if (stoneBlock == Blocks.BASALT) {
-                return getTextureFromBlock(BASALT_ORES[oreIndex]);
-            } else if (stoneBlock == Blocks.GRANITE) {
-                return getTextureFromBlock(GRANITE_ORES[oreIndex]);
-            } else if (stoneBlock == Blocks.LIMESTONE) {
-                return getTextureFromBlock(LIMESTONE_ORES[oreIndex]);
-            }
-        }
-
-        return getTextureFromBlock(stoneBlock);
-    }
-
-//    @Override
-//    public IconCoordinate getBackgroundTile(Random random, int tileX, int tileY) {
-//        int randomY = random.nextInt(Math.max(1 + tileY, 1)) + (tileY) / 2;
-//        IconCoordinate texture = getTextureFromBlock(Blocks.SAND);
-//        Block[] oreArray = STONE_ORES;
-//        if (randomY >= 28 || tileY > 24) {
-//            oreArray = BASALT_ORES;
-//        } if(randomY > 37 || tileY >= 35) {
-//            texture = getTextureFromBlock(Blocks.BEDROCK);
-//        } else if(randomY == 22) {
-//            if(random.nextInt(2) == 0) {
-//                texture = getTextureFromBlock(oreArray[ORE_DIAMOND]);
-//            } else {
-//                texture = getTextureFromBlock(oreArray[ORE_REDSTONE]);
-//            }
-//        } else if(randomY == 10) {
-//            texture = getTextureFromBlock(oreArray[ORE_IRON]);
-//        } else if(randomY == 8) {
-//            texture = getTextureFromBlock(oreArray[ORE_COAL]);
-//        } else if(randomY > 4) {
-//            texture = getTextureFromBlock(Blocks.STONE);
-//            if (randomY >= 28 || tileY > 24) {
-//                texture = getTextureFromBlock(Blocks.BASALT);
-//            }
-//        } else if(randomY > 0) {
-//            texture = getTextureFromBlock(Blocks.DIRT);
-//        }
-//        return texture;
-//    }
-
-    @Override
-    public @NotNull ItemStack getIcon() {
-        return icon;
-    }
-
-    @Override
-    public @NotNull List<Achievement> getAchievements() {
-        return achievementList;
-    }
-
-    @Override
-    public double getCompletionFraction(StatsCounter counter) {
-        int completed = 0;
-        for (Achievement a : achievementList){
-            if (counter.isUnlocked(a)){
-                completed++;
-            }
-        }
-        return completed / (double)achievementList.size();
-    }
-
-    @Override
-    public int backgroundLayers() {
-        return 2;
-    }
-
-    @Override
-    public int backgroundColor() {
-        return 0x76b6ff;
-    }
-
-    @Override
-    public boolean hasAchievement(Achievement achievement) {
-        return achievementList.contains(achievement);
-    }
-
-    @Override
-    public IconCoordinate getAchievementIcon(Achievement achievement) {
-        return TextureRegistry.getTexture(achievement.getType().texture);
-    }
-
-    @Override
-    public int lineColorLocked(boolean isHovered) {
-        return 0x000000;
-    }
-
-    @Override
-    public int lineColorUnlocked(boolean isHovered) {
-        return 0x707070;
-    }
-
-    @Override
-    public int lineColorCanUnlock(boolean isHovered) {
-        return 0x00ff00;
-    }
-
-    private static final IconCoordinate chest = TextureRegistry.getTexture("minecraft:block/chest_planks_oak_front");
-    private static final IconCoordinate spawner = getTextureFromBlock(Blocks.MOBSPAWNER);
-
-    protected static PageStructure dungeonBrick = new PageStructure(new Object[][][]
-        {
-            {
-                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
-                {Blocks.BRICK_CLAY, null,              null,              null,              null,              null,               Blocks.BRICK_CLAY},
-                {Blocks.BRICK_CLAY, null,              null,              null,              null,              null,               Blocks.BRICK_CLAY},
-                {Blocks.BRICK_CLAY, null,              null,              Blocks.MOBSPAWNER, null,              chest,              Blocks.BRICK_CLAY},
-                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
-            },
-            {
-                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
-                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
-                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
-                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
-                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
-            },
-        }
-    );
-
-    protected static PageStructure dungeonCobble = new PageStructure(new Object[][][]
-        {
-            {
-                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY,  Blocks.COBBLE_STONE},
-                {Blocks.COBBLE_STONE,       null,                      null,                      null,                      null,                      null,                       Blocks.COBBLE_STONE_MOSSY},
-                {Blocks.COBBLE_STONE_MOSSY, null,                      null,                      null,                      null,                      null,                       Blocks.COBBLE_STONE},
-                {Blocks.COBBLE_STONE,       chest,                     null,                      Blocks.MOBSPAWNER,         null,                      null,                       Blocks.COBBLE_STONE_MOSSY},
-                {Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
-            },
-            {
-                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
-                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
-                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
-                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
-                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
-            },
-        }
-    );
-
-    public static class PageStructure {
-        private final IconCoordinate[] data;
-        public final int width;
-        public final int height;
-        public final int layers;
-        public PageStructure(Object[][][] structure) {
-            this.layers = structure.length;
-            this.width = structure[0][0].length;
-            this.height = structure[0].length;
-
-            data = new IconCoordinate[width * height * layers];
-            for (int l = 0; l < layers; l++) {
-                for (int x = 0; x < width; x++) {
-                    for (int y = 0; y < height; y++) {
-                        Object o = structure[l][y][x];
-                        IconCoordinate c = null;
-                        if (o instanceof Block) {
-                            c = getTextureFromBlock((Block) o);
-                        } else if (o instanceof IconCoordinate) {
-                            c = (IconCoordinate) o;
-                        }
-                        data[makeIndex(x, y, l)] = c;
-                    }
-                }
-            }
-        }
-        public PageStructure(int width, int height, int layers){
-            this.width = width;
-            this.height = height;
-            this.layers = layers;
-            this.data = new IconCoordinate[width * height * layers];
-        }
-
-        public PageStructure setIcon(IconCoordinate icon, int x, int y, int layer) {
-            if (x < 0 || x >= width || y < 0 || y >= height || layer < 0 || layer >= layers) return this;
-            data[makeIndex(x, y, layer)] = icon;
-            return this;
-        }
-
-        public IconCoordinate getIcon(int x, int y, int layer){
-            if (x < 0 || x >= width || y < 0 || y >= height || layer < 0 || layer >= layers) return null;
-            return data[makeIndex(x, y, layer)];
-        }
-
-        private int makeIndex(int x, int y, int layer) {
-            return x % width + y * width + layer * (width * height);
-        }
-    }
-}
diff --git a/src/main/java/net/minecraft/client/gui/achievements/pages/NetherPage.java b/src/main/java/net/minecraft/client/gui/achievements/pages/NetherPage.java
index 4eb6a4090..46720681f 100644
--- a/src/main/java/net/minecraft/client/gui/achievements/pages/NetherPage.java
+++ b/src/main/java/net/minecraft/client/gui/achievements/pages/NetherPage.java
@@ -1,32 +1,114 @@
 package net.minecraft.client.gui.achievements.pages;
 
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.achievements.GuiAchievements;
+import net.minecraft.client.gui.achievements.data.AchievementPage;
+import net.minecraft.client.gui.achievements.data.AchievementPages;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
+import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.core.achievement.Achievement;
 import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.block.Blocks;
+import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.lang.I18n;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Random;
 
-public class NetherPage extends DefaultPage{
-    public NetherPage() {
-        super("gui.achievements.page.nether", Blocks.NETHERRACK.getDefaultStack());
+public class NetherPage extends AchievementPage {
+    protected final Minecraft mc = Minecraft.getMinecraft(this);
+    protected final ItemStack icon;
+    @NotNull
+    protected final String key;
+
+    public NetherPage(String key, ItemStack icon) {
+        this.key = key;
+        this.icon = icon;
+    }
+
+    @Override
+    public @NotNull String getName() {
+        return I18n.getInstance().translateNameKey(key);
     }
+
+    @Override
+    public @NotNull String getDescription() {
+        return I18n.getInstance().translateDescKey(key);
+    }
+
     @Override
     public @NotNull Achievement onOpenAchievement() {
-        return Achievements.BUILD_PICKAXE;
+        return Achievements.ENTER_NETHER;
     }
+
     @Override
     public IconCoordinate getBackgroundTile(GuiAchievements guiAchievements, int layer, Random random, int tileX, int tileY) {
-        int r = random.nextInt(5);
+        random.setSeed(random.nextLong() + key.hashCode()); // makes seed different for each instance of this class :)
+
+        final int bedrockLayer = 35;
+
+        final int offsetX = tileX + random.nextInt(3) - random.nextInt(3);
+        final int offsetY = tileY + random.nextInt(3) - random.nextInt(3);
+
+        int r = random.nextInt(50);
         IconCoordinate texture = getTextureFromBlock(Blocks.NETHERRACK);
-        if (r == 0){
+        if (offsetY >= bedrockLayer) {
+            texture = getTextureFromBlock(Blocks.BEDROCK);
+        } else if (r < 10) {
             texture = getTextureFromBlock(Blocks.ORE_NETHERCOAL_NETHERRACK);
         }
         return texture;
     }
 
+    @Override
+    public void postProcessBackground(GuiAchievements gui, Random random, GuiAchievements.BGLayer layerCache, int orgX, int orgY) {
+        if (layerCache.id == 0) {
+            int lastY = 0;
+            int cave = -1;
+            for (int _x = -100; _x <= 100; _x++) {
+                if (random.nextInt(20) == 0 && cave <= 0) {
+                    cave = 20 + random.nextInt(5) - random.nextInt(5);
+                }
+                if (cave > 0){
+                    lastY = (25 + random.nextInt(4) - random.nextInt(4));
+                    carveCircle(gui, layerCache, _x - orgX, lastY - orgY, 2 + random.nextInt(3));
+                }
+                cave--;
+            }
+            cave = -1;
+            for (int _x = -100; _x <= 100; _x++) {
+                if (random.nextInt(10) == 0 && cave <= 0) {
+                    cave = 5 + random.nextInt(5) - random.nextInt(5);
+                }
+                if (cave > 0){
+                    carveCircle(gui, layerCache, _x - orgX, (10 + random.nextInt(2) - random.nextInt(2)) - orgY, random.nextInt(3));
+                }
+                cave--;
+            }
+
+        }
+    }
+
+    @Override
+    public @NotNull ItemStack getIcon() {
+        return icon;
+    }
+
+    @Override
+    public int backgroundLayers() {
+        return 1;
+    }
+
+    @Override
+    public int backgroundColor() {
+        return 0x000000;
+    }
+
+    @Override
+    public IconCoordinate getAchievementIcon(Achievement achievement) {
+        return TextureRegistry.getTexture(achievement.getType().texture);
+    }
+
     @Override
     public int lineColorLocked(boolean isHovered) {
         return 0x002233;
@@ -41,4 +123,16 @@ public class NetherPage extends DefaultPage{
     public int lineColorCanUnlock(boolean isHovered) {
         return 0xff0000;
     }
+
+    protected void carveCircle(GuiAchievements gui, GuiAchievements.BGLayer layer, int centerX, int centerY, int radius){
+        for (int i = centerX - radius; i <= centerX + radius ; i++) {
+            for (int j = centerY - radius; j < centerY + radius; j++) {
+                double diffX = (i + 0.5) - centerX;
+                double diffY = (j + 0.5) - centerY;
+                if ((diffX * diffX) + (diffY * diffY) < radius * radius){
+                    layer.put(null, i, j);
+                }
+            }
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/client/gui/achievements/pages/OverworldPage.java b/src/main/java/net/minecraft/client/gui/achievements/pages/OverworldPage.java
index fa95cd452..63e34bf9a 100644
--- a/src/main/java/net/minecraft/client/gui/achievements/pages/OverworldPage.java
+++ b/src/main/java/net/minecraft/client/gui/achievements/pages/OverworldPage.java
@@ -1,9 +1,418 @@
 package net.minecraft.client.gui.achievements.pages;
 
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.achievements.GuiAchievements;
+import net.minecraft.client.gui.achievements.data.AchievementPage;
+import net.minecraft.client.render.texture.stitcher.IconCoordinate;
+import net.minecraft.client.render.texture.stitcher.TextureRegistry;
+import net.minecraft.core.WeightedRandomBag;
+import net.minecraft.core.achievement.Achievement;
+import net.minecraft.core.achievement.Achievements;
+import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
+import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.lang.I18n;
+import net.minecraft.core.util.helper.MathHelper;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
-public class OverworldPage extends DefaultPage{
-    public OverworldPage() {
-        super("gui.achievements.page.overworld", Blocks.GRASS.getDefaultStack());
+import java.util.Random;
+import java.util.function.BiFunction;
+
+public class OverworldPage extends AchievementPage {
+    protected final Minecraft mc = Minecraft.getMinecraft(this);
+    protected final ItemStack icon;
+    @NotNull
+    protected final String key;
+
+    public OverworldPage(String key, ItemStack icon) {
+        this.key = key;
+        this.icon = icon;
+    }
+
+    @Override
+    public @NotNull String getName() {
+        return I18n.getInstance().translateNameKey(key);
+    }
+
+    @Override
+    public @NotNull String getDescription() {
+        return I18n.getInstance().translateDescKey(key);
+    }
+
+    @Override
+    public @NotNull Achievement onOpenAchievement() {
+        return Achievements.BUILD_WORKBENCH;
+    }
+
+    protected static final int ORE_COAL = 0;
+    protected static final int ORE_IRON = 1;
+    protected static final int ORE_GOLD = 2;
+    protected static final int ORE_DIAMOND = 3;
+    protected static final int ORE_REDSTONE = 4;
+    protected static final int ORE_LAPIS = 5;
+    protected static final Block[] STONE_ORES = new Block[]     { Blocks.ORE_COAL_STONE,    Blocks.ORE_IRON_STONE,      Blocks.ORE_GOLD_STONE,      Blocks.ORE_DIAMOND_STONE,       Blocks.ORE_REDSTONE_STONE,      Blocks.ORE_LAPIS_STONE};
+    protected static final Block[] GRANITE_ORES = new Block[]   { Blocks.ORE_COAL_GRANITE,  Blocks.ORE_IRON_GRANITE,    Blocks.ORE_GOLD_GRANITE,    Blocks.ORE_DIAMOND_GRANITE,     Blocks.ORE_REDSTONE_GRANITE,    Blocks.ORE_LAPIS_GRANITE};
+    protected static final Block[] LIMESTONE_ORES = new Block[] { Blocks.ORE_COAL_LIMESTONE,Blocks.ORE_IRON_LIMESTONE,  Blocks.ORE_GOLD_LIMESTONE,  Blocks.ORE_DIAMOND_LIMESTONE,   Blocks.ORE_REDSTONE_LIMESTONE,  Blocks.ORE_LAPIS_LIMESTONE};
+    protected static final Block[] BASALT_ORES = new Block[]    { Blocks.ORE_COAL_BASALT,   Blocks.ORE_IRON_BASALT,     Blocks.ORE_GOLD_BASALT,     Blocks.ORE_DIAMOND_BASALT,      Blocks.ORE_REDSTONE_BASALT,     Blocks.ORE_LAPIS_BASALT};
+
+    @Override
+    public IconCoordinate getBackgroundTile(GuiAchievements guiAchievements, int layer, Random random, int tileX, int tileY) {
+        random.setSeed(random.nextLong() + key.hashCode()); // makes seed different for each instance of this class :)
+        // expect x range from  0  to 45
+        // expect y range from -12 to 50
+        final int sandLayer = -20;
+        final int dirtLayer = 2;
+        final int bedrockLayer = 35;
+        final int stoneLayer = bedrockLayer - (int) ((bedrockLayer - dirtLayer) * 0.5f);
+        final int basaltLayer = bedrockLayer - (int) ((bedrockLayer - dirtLayer) * 0.25f);
+
+        final int graniteColumn = 5;
+        final int limestoneColumn = 50;
+
+        final int offsetX = tileX + random.nextInt(3) - random.nextInt(3);
+        final int offsetY = tileY + random.nextInt(3) - random.nextInt(3);
+
+        if (offsetY <= sandLayer){
+            return getTextureFromBlock(Blocks.SAND);
+        } else if (offsetY <= dirtLayer) {
+            return getTextureFromBlock(Blocks.DIRT);
+        } else if (offsetY >= bedrockLayer) {
+            return getTextureFromBlock(Blocks.BEDROCK);
+        } else {
+            if (offsetY >= basaltLayer){
+                return getOreFromStone(Blocks.BASALT, random, tileX, tileY);
+            } else if (offsetY >= stoneLayer){
+                return getOreFromStone(Blocks.STONE, random, tileX, tileY);
+            } else {
+                if (offsetX <= graniteColumn){
+                    return getOreFromStone(Blocks.GRANITE, random, tileX, tileY);
+                } else if (offsetX >= limestoneColumn) {
+                    return getOreFromStone(Blocks.LIMESTONE, random, tileX, tileY);
+                }
+                return getOreFromStone(Blocks.STONE, random, tileX, tileY);
+            }
+        }
+    }
+
+    @Override
+    public void postProcessBackground(GuiAchievements gui, Random random, GuiAchievements.BGLayer layer, int orgX, int orgY) {
+        random.setSeed(random.nextLong() + key.hashCode()); // makes seed different for each instance of this class :)
+        if (layer.id == 0) {
+
+            int y = 5;
+            int delta = 0;
+            int tYMin = -2;
+            int tYMax = -6;
+            int lowestY = 0;
+            for (int _x = -100; _x < 100; _x++) {
+                delta += random.nextInt(2) - random.nextInt(2);
+                delta = MathHelper.clamp(delta, -3, 3);
+                int sign = (int) Math.signum(delta);
+                int _d = Math.abs(delta);
+                if (_d != 0) {
+                    y += sign * random.nextInt(_d);
+                }
+
+                if (y > tYMax) {
+                    delta -= 1;
+                }
+                if (y < tYMin) {
+                    delta += 1;
+                }
+                if (y > lowestY) y = lowestY;
+
+                for (int rY = y; rY - orgY >= 0; rY--) {
+                    if (rY == y) {
+                        layer.put(TextureRegistry.getTexture("minecraft:block/grass_side"), _x - orgX, rY - orgY);
+                    } else {
+                        layer.put(null, _x - orgX, rY - orgY);
+                    }
+                    gui.getLayer(1).put(null, _x - orgX, rY - orgY);
+                }
+            }
+
+            int[] brickPos = null;
+            int[] cobblePos = null;
+            int lastY = 0;
+            int cave = -1;
+            for (int _x = -100; _x <= 100; _x++) {
+                if (random.nextInt(20) == 0 && cave <= 0) {
+                    cave = 20 + random.nextInt(5) - random.nextInt(5);
+                }
+                if (cave > 0){
+                    lastY = (25 + random.nextInt(4) - random.nextInt(4));
+                    carveCircle(gui, layer, _x - orgX, lastY - orgY, 2 + random.nextInt(3));
+                }
+                if (cave == 0 && (-10 <= _x && _x <= 40)) {
+                    brickPos = new int[]{_x, lastY};
+                }
+                cave--;
+            }
+            cave = -1;
+            for (int _x = -100; _x <= 100; _x++) {
+                if (random.nextInt(10) == 0 && cave <= 0) {
+                    cave = 5 + random.nextInt(5) - random.nextInt(5);
+                }
+                if (cave > 0){
+                    carveCircle(gui, layer, _x - orgX, (10 + random.nextInt(2) - random.nextInt(2)) - orgY, random.nextInt(3));
+                }
+                cave--;
+            }
+
+            if (brickPos == null) {
+                brickPos = new int[]{5 + random.nextInt(20) + random.nextInt(20), 15 + random.nextInt(10)};
+            }
+
+            placeStructure(gui, dungeonBrick, brickPos[0] - orgX,brickPos[1] - orgY, (struct, cache) -> {
+                if (cache == null) {
+                    if (struct == chest || struct == spawner) {
+                        return struct;
+                    }
+                    return null;
+                }
+                return struct;
+            });
+            placeStructure(gui, dungeonCobble, -orgX + 5 + random.nextInt(20) + random.nextInt(20),-orgY + 5 + random.nextInt(5), (struct, cache) -> {
+                if (cache == null) {
+                    if (struct == chest || struct == spawner) {
+                        return struct;
+                    }
+                    return null;
+                }
+                return struct;
+            });
+        } else if (layer.id == 1) {
+            // Remove covered icons
+            IconCoordinate[] foreground = gui.getLayer(0).getData();
+            IconCoordinate[] background = layer.getData();
+            for (int i = 0; i < background.length; i++) {
+                if (foreground[i] != null && foreground[i] != spawner){
+                    background[i] = null;
+                }
+            }
+        }
+    }
+
+    protected void carveCircle(GuiAchievements gui, GuiAchievements.BGLayer layer, int centerX, int centerY, int radius){
+        for (int i = centerX - radius; i <= centerX + radius ; i++) {
+            for (int j = centerY - radius; j < centerY + radius; j++) {
+                double diffX = (i + 0.5) - centerX;
+                double diffY = (j + 0.5) - centerY;
+                if ((diffX * diffX) + (diffY * diffY) < radius * radius){
+                    layer.put(null, i, j);
+                }
+            }
+        }
+    }
+
+    protected void placeStructure(GuiAchievements gui, PageStructure structure, int tileX, int tileY, @Nullable BiFunction<IconCoordinate, IconCoordinate, IconCoordinate> coordinateProcessor) {
+        if (coordinateProcessor == null) {
+            coordinateProcessor = (i, i2) -> i;
+        }
+        for (int layer = 0; layer < structure.layers; layer++) {
+            GuiAchievements.BGLayer cache = gui.getLayer(layer);
+            if (cache != null) {
+                for (int _x = 0; _x < structure.width; _x++) {
+                    for (int _y = 0; _y < structure.height; _y++) {
+                        IconCoordinate coordinate = structure.getIcon(_x, _y, layer);
+                        cache.put(coordinateProcessor.apply(coordinate, cache.get(tileX + _x, tileY + _y)), tileX + _x, tileY + _y);
+                    }
+                }
+            }
+        }
+    }
+
+    private static final WeightedRandomBag<Integer> oreBag = new WeightedRandomBag<>();
+
+    private IconCoordinate getOreFromStone(Block stoneBlock, Random random, int tileX, int tileY){
+        oreBag.clear();
+
+        random.setSeed(random.nextLong());
+
+        final int coalStart = 2;
+        final int coalEnd = 20;
+
+        final int ironStart = 2;
+        final int ironEnd = 25;
+
+        final int goldStart = 20;
+        final int goldEnd = 35;
+
+        final int diamondStart = 25;
+        final int diamondEnd = 35;
+
+        final int lapisStart = 25;
+        final int lapisEnd = 35;
+
+        final int redstoneStart = 20;
+        final int redstoneEnd = 35;
+
+        oreBag.addEntry(-1, 300);
+
+        if (tileY >= coalStart && tileY <= coalEnd){
+            oreBag.addEntry(ORE_COAL, 15);
+        }
+
+        if (tileY >= ironStart && tileY <= ironEnd){
+            oreBag.addEntry(ORE_IRON, 15);
+        }
+
+        if (tileY >= goldStart && tileY <= goldEnd){
+            oreBag.addEntry(ORE_GOLD, 3);
+        }
+
+        if (tileY >= diamondStart && tileY <= diamondEnd){
+            oreBag.addEntry(ORE_DIAMOND, 1);
+        }
+
+        if (tileY >= lapisStart && tileY <= lapisEnd){
+            oreBag.addEntry(ORE_LAPIS, 2);
+        }
+
+        if (tileY >= redstoneStart && tileY <= redstoneEnd){
+            oreBag.addEntry(ORE_REDSTONE, 5);
+        }
+
+        int oreIndex = oreBag.getRandom(random);
+
+        if (oreIndex >= 0){
+            if (stoneBlock == Blocks.STONE){
+                return getTextureFromBlock(STONE_ORES[oreIndex]);
+            } else if (stoneBlock == Blocks.BASALT) {
+                return getTextureFromBlock(BASALT_ORES[oreIndex]);
+            } else if (stoneBlock == Blocks.GRANITE) {
+                return getTextureFromBlock(GRANITE_ORES[oreIndex]);
+            } else if (stoneBlock == Blocks.LIMESTONE) {
+                return getTextureFromBlock(LIMESTONE_ORES[oreIndex]);
+            }
+        }
+
+        return getTextureFromBlock(stoneBlock);
+    }
+
+    @Override
+    public @NotNull ItemStack getIcon() {
+        return icon;
+    }
+
+    @Override
+    public int backgroundLayers() {
+        return 2;
+    }
+
+    @Override
+    public int backgroundColor() {
+        return 0x76b6ff;
+    }
+
+    @Override
+    public IconCoordinate getAchievementIcon(Achievement achievement) {
+        return TextureRegistry.getTexture(achievement.getType().texture);
+    }
+
+    @Override
+    public int lineColorLocked(boolean isHovered) {
+        return 0x000000;
+    }
+
+    @Override
+    public int lineColorUnlocked(boolean isHovered) {
+        return 0x707070;
+    }
+
+    @Override
+    public int lineColorCanUnlock(boolean isHovered) {
+        return 0x00ff00;
+    }
+
+    private static final IconCoordinate chest = TextureRegistry.getTexture("minecraft:block/chest_planks_oak_front");
+    private static final IconCoordinate spawner = getTextureFromBlock(Blocks.MOBSPAWNER);
+
+    protected static PageStructure dungeonBrick = new PageStructure(new Object[][][]
+        {
+            {
+                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
+                {Blocks.BRICK_CLAY, null,              null,              null,              null,              null,               Blocks.BRICK_CLAY},
+                {Blocks.BRICK_CLAY, null,              null,              null,              null,              null,               Blocks.BRICK_CLAY},
+                {Blocks.BRICK_CLAY, null,              null,              Blocks.MOBSPAWNER, null,              chest,              Blocks.BRICK_CLAY},
+                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
+            },
+            {
+                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
+                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
+                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
+                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
+                {Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY, Blocks.BRICK_CLAY,  Blocks.BRICK_CLAY},
+            },
+        }
+    );
+
+    protected static PageStructure dungeonCobble = new PageStructure(new Object[][][]
+        {
+            {
+                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY,  Blocks.COBBLE_STONE},
+                {Blocks.COBBLE_STONE,       null,                      null,                      null,                      null,                      null,                       Blocks.COBBLE_STONE_MOSSY},
+                {Blocks.COBBLE_STONE_MOSSY, null,                      null,                      null,                      null,                      null,                       Blocks.COBBLE_STONE},
+                {Blocks.COBBLE_STONE,       chest,                     null,                      Blocks.MOBSPAWNER,         null,                      null,                       Blocks.COBBLE_STONE_MOSSY},
+                {Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
+            },
+            {
+                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
+                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
+                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
+                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE_MOSSY, Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
+                {Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,       Blocks.COBBLE_STONE,        Blocks.COBBLE_STONE},
+            },
+        }
+    );
+
+    public static class PageStructure {
+        private final IconCoordinate[] data;
+        public final int width;
+        public final int height;
+        public final int layers;
+        public PageStructure(Object[][][] structure) {
+            this.layers = structure.length;
+            this.width = structure[0][0].length;
+            this.height = structure[0].length;
+
+            data = new IconCoordinate[width * height * layers];
+            for (int l = 0; l < layers; l++) {
+                for (int x = 0; x < width; x++) {
+                    for (int y = 0; y < height; y++) {
+                        Object o = structure[l][y][x];
+                        IconCoordinate c = null;
+                        if (o instanceof Block) {
+                            c = getTextureFromBlock((Block) o);
+                        } else if (o instanceof IconCoordinate) {
+                            c = (IconCoordinate) o;
+                        }
+                        data[makeIndex(x, y, l)] = c;
+                    }
+                }
+            }
+        }
+        public PageStructure(int width, int height, int layers){
+            this.width = width;
+            this.height = height;
+            this.layers = layers;
+            this.data = new IconCoordinate[width * height * layers];
+        }
+
+        public PageStructure setIcon(IconCoordinate icon, int x, int y, int layer) {
+            if (x < 0 || x >= width || y < 0 || y >= height || layer < 0 || layer >= layers) return this;
+            data[makeIndex(x, y, layer)] = icon;
+            return this;
+        }
+
+        public IconCoordinate getIcon(int x, int y, int layer){
+            if (x < 0 || x >= width || y < 0 || y >= height || layer < 0 || layer >= layers) return null;
+            return data[makeIndex(x, y, layer)];
+        }
+
+        private int makeIndex(int x, int y, int layer) {
+            return x % width + y * width + layer * (width * height);
+        }
     }
 }
diff --git a/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java b/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
index 394f782ed..c7ded604a 100644
--- a/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
+++ b/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
@@ -291,7 +291,7 @@ public abstract class OptionsPages
             .withComponent(new ShortcutComponent("gui.options.page.debug.button.open.sound_test", () -> mc.displayGuiScreen(new GuiSoundTest(mc.currentScreen))))
             .withComponent(new ShortcutComponent("gui.options.page.debug.button.open.texture_viewer", () -> mc.displayGuiScreen(new GuiTextureViewer(mc.currentScreen))))
             .withComponent(new ShortcutComponent("gui.options.page.debug.button.open.biome_finder", () -> {
-                BiomeFinder.main(new String[0]);
+                new Thread(() -> BiomeFinder.main(new String[0])).start();
                 Global.accessor = mc;
             }))
             .withComponent(new ShortcutComponent("gui.options.page.debug.button.open.datadumper", () ->{
diff --git a/src/main/java/net/minecraft/client/gui/popup/MessageBoxComponent.java b/src/main/java/net/minecraft/client/gui/popup/MessageBoxComponent.java
index 0ad03e175..51ca70739 100644
--- a/src/main/java/net/minecraft/client/gui/popup/MessageBoxComponent.java
+++ b/src/main/java/net/minecraft/client/gui/popup/MessageBoxComponent.java
@@ -10,6 +10,7 @@ import org.lwjgl.opengl.GL11;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 public class MessageBoxComponent
@@ -38,47 +39,53 @@ public class MessageBoxComponent
         setupText(text, chars);
     }
 
-    private void setupText(String text, int chars) {
+    private void setupText(String text, int limit) {
         lines.clear();
 
-        String[] newlines = text.split("\\n");
-        List<String> completeSplit = new ArrayList<>();
-        ArrayList<String> newlineSplit = new ArrayList<>(Arrays.asList(newlines));
+        List<String> completeSplit = new ArrayList<>(); //the processed wrapped text, each entry is one line
+        ArrayList<String> newlineSplit = new ArrayList<>(Arrays.asList(text.split("\\n"))); //text split based only on newlines before processing
 
         String lastFormat = "";
 
         for (String s : newlineSplit) {
-            String[] words = s.split(" ");
+            ArrayList<String> words = new ArrayList<>(Arrays.asList(s.split(" ")));
+            ArrayList<String> limitedSizeWords = new ArrayList<>(); //all words here should not be larger than the limit
             StringBuilder line = new StringBuilder();
             line.append(lastFormat);
-            String currentFormat = lastFormat;
-            boolean formatChanged = false;
-            for (int i = 0; i < words.length; i++) {
-                String word = words[i];
+            //split words larger than the limit into multiple that can fit
+            for (String word : words) {
+                if (word.length() > limit) {
+                    ArrayList<String> split = new ArrayList<>();
+                    for (int j = 0; j <= word.length() / limit; j++) {
+                        split.add(word.substring(j * limit, Math.min((j + 1) * limit, word.length())));
+                    }
+                    limitedSizeWords.addAll(split);
+                } else {
+                    limitedSizeWords.add(word);
+                }
+            }
+            for (String word : limitedSizeWords) {
+                String currentFormat = "";
+                //check for formatting and extract it
                 if (word.contains("§")) {
                     if (word.indexOf('§') < word.length() - 1) {
                         String format = String.valueOf(word.charAt(word.indexOf('§') + 1));
-                        if (format.matches("[0123456789abcdefklmnor]")) {
+                        if (format.matches("[0123456789abcdefklmnor]")) { //if matches any valid text format
                             currentFormat = "§" + format;
-                            formatChanged = true;
                         }
                     }
                 }
-                if (line.length() + 1 + word.length() < chars) {
-                    if(formatChanged) {
-                        line.append(lastFormat);
-                        formatChanged = false;
-                    }
+                if (line.length() + 1 + word.length() < limit) {
+                    //if line has not hit the char limit yet
                     line.append(word).append(" ");
                 } else {
+                    //line has hit the limit, wrap it preserving the last formatting
                     completeSplit.add(line.toString());
                     line = new StringBuilder();
                     line.append(lastFormat);
                     line.append(word).append(" ");
                 }
-                if(i == words.length - 1) {
-                    lastFormat = currentFormat;
-                }
+                if(!currentFormat.isEmpty()) lastFormat = currentFormat; //change last format if a new one was found in this iteration
             }
             completeSplit.add(line.toString());
         }
diff --git a/src/main/java/net/minecraft/client/net/handler/ClientPacketHandler.java b/src/main/java/net/minecraft/client/net/handler/ClientPacketHandler.java
index a374995cc..b3b04d307 100644
--- a/src/main/java/net/minecraft/client/net/handler/ClientPacketHandler.java
+++ b/src/main/java/net/minecraft/client/net/handler/ClientPacketHandler.java
@@ -542,8 +542,18 @@ public class ClientPacketHandler extends PacketHandler
     {
         if (!disconnected) {
             disconnected = true;
-            mc.changeWorld(null);
-            mc.displayGuiScreen(new GuiConnectFailed("disconnect.lost", s, errorLines));
+            try {
+                mc.changeWorld(null); // Leave current world
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            try {
+                mc.displayGuiScreen(null); // Exit out of current GUI
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            mc.displayGuiScreen(new GuiConnectFailed("disconnect.lost", s, errorLines)); // Open error message gui
         }
     }
 
diff --git a/src/main/java/net/minecraft/client/render/entity/MobRenderer.java b/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
index cb82b49ef..d817112cb 100644
--- a/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
+++ b/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
@@ -233,7 +233,7 @@ public class MobRenderer<T extends Mob> extends EntityRenderer<T>
         final float f1 = 1.6F;
         final float f2 = 0.01666667F * f1;
         GL11.glPushMatrix();
-        GL11.glTranslatef((float) d + 0.0F, (float) d1 + 2.3F, (float) d2);
+        GL11.glTranslatef((float) d + 0.0F, (float) d1 + entity.getHeadHeight() + 0.8f, (float) d2);
         GL11.glNormal3f(0.0F, 1.0F, 0.0F);
         GL11.glRotatef(-renderDispatcher.viewLerpYaw, 0.0F, 1.0F, 0.0F);
         GL11.glRotatef(renderDispatcher.viewLerpPitch, 1.0F, 0.0F, 0.0F);
diff --git a/src/main/java/net/minecraft/core/achievement/Achievement.java b/src/main/java/net/minecraft/core/achievement/Achievement.java
index 2324e211c..9f4b14e44 100644
--- a/src/main/java/net/minecraft/core/achievement/Achievement.java
+++ b/src/main/java/net/minecraft/core/achievement/Achievement.java
@@ -34,11 +34,6 @@ public class Achievement extends Stat
         this.x = x;
         this.y = y;
 
-        Achievements.minX = Math.min(Achievements.minX, x);
-        Achievements.maxX = Math.max(Achievements.maxX, x);
-        Achievements.minY = Math.min(Achievements.minY, y);
-        Achievements.maxY = Math.max(Achievements.maxY, y);
-
         this.parent = parent;
     }
 
diff --git a/src/main/java/net/minecraft/core/achievement/Achievements.java b/src/main/java/net/minecraft/core/achievement/Achievements.java
index cc6c6de70..f6448eaab 100644
--- a/src/main/java/net/minecraft/core/achievement/Achievements.java
+++ b/src/main/java/net/minecraft/core/achievement/Achievements.java
@@ -12,10 +12,6 @@ public abstract class Achievements
 {
     
     public static List<Achievement> achievementList = new ArrayList<>();
-    public static int minX;
-    public static int minY;
-    public static int maxX;
-    public static int maxY;
     public static Achievement OPEN_INVENTORY =
         new Achievement(new NamespaceID("minecraft", "open_inventory"), "openInventory", 0, 0, Items.BOOK, null)
         .setClientsideAchievement().registerAchievement()
@@ -23,15 +19,15 @@ public abstract class Achievements
     public static Achievement MINE_WOOD =
         new Achievement(new NamespaceID("minecraft", "mine_wood"), "mineWood", 2, 1, Blocks.LOG_OAK, OPEN_INVENTORY)
             .registerAchievement()
-            .addToPage(AchievementPages.overworldPage, AchievementPages.netherPage);
+            .addToPage(AchievementPages.overworldPage);
     public static Achievement BUILD_WORKBENCH =
         new Achievement(new NamespaceID("minecraft", "build_workbench"), "buildWorkBench", 4, -1, Blocks.WORKBENCH, MINE_WOOD)
             .registerAchievement()
-            .addToPage(AchievementPages.overworldPage, AchievementPages.netherPage);
+            .addToPage(AchievementPages.overworldPage);
     public static Achievement BUILD_PICKAXE =
         new Achievement(new NamespaceID("minecraft", "build_pickaxe"), "buildPickaxe", 4, 2, Items.TOOL_PICKAXE_WOOD, BUILD_WORKBENCH)
             .registerAchievement()
-            .addToPage(AchievementPages.overworldPage, AchievementPages.netherPage);
+            .addToPage(AchievementPages.overworldPage);
     public static Achievement BUILD_FURNACE =
         new Achievement(new NamespaceID("minecraft", "build_furnace"), "buildFurnace", 3, 4, Blocks.FURNACE_STONE_ACTIVE, BUILD_PICKAXE)
             .registerAchievement()
@@ -40,16 +36,29 @@ public abstract class Achievements
         new Achievement(new NamespaceID("minecraft", "acquire_iron"), "acquireIron", 1, 4, Items.INGOT_IRON, BUILD_FURNACE)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
+    public static Achievement GET_DIAMONDS =
+        new Achievement(new NamespaceID("minecraft", "get_diamonds"), "getDiamonds", -1, 4, Items.DIAMOND, ACQUIRE_IRON)
+            .setType(Achievement.TYPE_SPECIAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.overworldPage);
     public static Achievement BUILD_HOE =
-        new Achievement(new NamespaceID("minecraft", "build_hoe"), "buildHoe", 2, -3, Items.TOOL_HOE_WOOD, BUILD_WORKBENCH)
+        new Achievement(new NamespaceID("minecraft", "build_hoe"), "buildHoe", 1, -3, Items.TOOL_HOE_WOOD, BUILD_WORKBENCH)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
     public static Achievement MAKE_BREAD =
-        new Achievement(new NamespaceID("minecraft", "make_bread"), "makeBread", -1, -3, Items.FOOD_BREAD, BUILD_HOE)
+        new Achievement(new NamespaceID("minecraft", "make_bread"), "makeBread", -2, -3, Items.FOOD_BREAD, BUILD_HOE)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
     public static Achievement BAKE_CAKE =
-        new Achievement(new NamespaceID("minecraft", "bake_cake"), "bakeCake", 0, -5, Items.FOOD_CAKE, BUILD_HOE)
+        new Achievement(new NamespaceID("minecraft", "bake_cake"), "bakeCake", -1, -5, Items.FOOD_CAKE, BUILD_HOE)
+            .registerAchievement()
+            .addToPage(AchievementPages.overworldPage);
+    public static Achievement CRAFT_ICECREAM =
+        new Achievement(new NamespaceID("minecraft", "craft_icecream"), "craftIcecream", 1, -6, Items.BUCKET_ICECREAM, BUILD_HOE)
+            .registerAchievement()
+            .addToPage(AchievementPages.overworldPage);
+    public static Achievement CRAFT_PUMPKIN_PIE =
+        new Achievement(new NamespaceID("minecraft", "craft_pumpkin_pie"), "craftPumpkinPie", -1, -1, Items.FOOD_PUMPKIN_PIE, BUILD_HOE)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
     public static Achievement BUILD_BETTER_PICKAXE =
@@ -69,6 +78,11 @@ public abstract class Achievements
         new Achievement(new NamespaceID("minecraft", "build_sword"), "buildSword", 6, -1, Items.TOOL_SWORD_WOOD, BUILD_WORKBENCH)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
+    public static Achievement ALL_ARMOR_TYPES =
+        new Achievement(new NamespaceID("minecraft", "all_armor_types"), "allArmorTypes", 13, 1, Items.ARMOR_CHESTPLATE_STEEL, null)
+            .setType(Achievement.TYPE_SPECIAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.overworldPage);
     public static Achievement KILL_ENEMY =
         new Achievement(new NamespaceID("minecraft", "kill_enemy"), "killEnemy", 8, -1, Items.BONE, BUILD_SWORD)
             .registerAchievement()
@@ -83,7 +97,7 @@ public abstract class Achievements
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
     public static Achievement GET_SENSED =
-        new Achievement(new NamespaceID("minecraft", "get_sensed"), "getSensed", 10, -1, Blocks.MOTION_SENSOR_ACTIVE, KILL_ENEMY)
+        new Achievement(new NamespaceID("minecraft", "get_sensed"), "getSensed", 9, -3, Blocks.MOTION_SENSOR_ACTIVE, KILL_ENEMY)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
     public static Achievement CRAFT_HANDCANNON =
@@ -100,11 +114,11 @@ public abstract class Achievements
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
     public static Achievement REPAIR_ARMOR =
-        new Achievement(new NamespaceID("minecraft", "repair_armor"), "repairArmor", 12, -1, Items.CHAINLINK, GET_SENSED)
+        new Achievement(new NamespaceID("minecraft", "repair_armor"), "repairArmor", 9, 0, Items.CHAINLINK, KILL_ENEMY)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
     public static Achievement GET_CHAINMAIL =
-        new Achievement(new NamespaceID("minecraft", "get_chainmail"), "getChainmail", 14, -1, Items.ARMOR_HELMET_CHAINMAIL, REPAIR_ARMOR)
+        new Achievement(new NamespaceID("minecraft", "get_chainmail"), "getChainmail", 11, 0, Items.ARMOR_HELMET_CHAINMAIL, REPAIR_ARMOR)
             .setType(Achievement.TYPE_SPECIAL)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
@@ -118,6 +132,70 @@ public abstract class Achievements
             .setType(Achievement.TYPE_SPECIAL)
             .registerAchievement()
             .addToPage(AchievementPages.overworldPage);
+    public static Achievement ALL_MUSIC_DISCS =
+        new Achievement(new NamespaceID("minecraft", "all_music_discs"), "allMusicDiscs", -3, 4, Items.RECORD_STAL, null)
+            .setType(Achievement.TYPE_SPECIAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.overworldPage);
+    public static Achievement TRIPLE_HIT =
+        new Achievement(new NamespaceID("minecraft", "triple_hit"), "tripleHit", 11, -2, Items.AMMO_ARROW_GOLD, KILL_ENEMY)
+            .setType(Achievement.TYPE_SPECIAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.overworldPage);
+
+
+    // Nether achievements
+    public static Achievement ENTER_NETHER =
+        new Achievement(new NamespaceID("minecraft", "enter_nether"), "enterNether", 2, 0, Blocks.OBSIDIAN, null)
+            .setType(Achievement.TYPE_SPECIAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement GET_NETHERCOAL =
+        new Achievement(new NamespaceID("minecraft", "get_nethercoal"), "getNethercoal", 1, 2, Items.NETHERCOAL, ENTER_NETHER)
+            .setType(Achievement.TYPE_NORMAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement LIGHT_SIGN =
+        new Achievement(new NamespaceID("minecraft", "light_sign"), "lightSign", 4, 0, Items.DUST_GLOWSTONE, ENTER_NETHER)
+            .setType(Achievement.TYPE_NORMAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement SWIM_NETHER =
+        new Achievement(new NamespaceID("minecraft", "swim_nether"), "swimNether", 3, 2, Blocks.ICE, ENTER_NETHER)
+            .setType(Achievement.TYPE_SPECIAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement HIT_FIREBALL =
+        new Achievement(new NamespaceID("minecraft", "hit_fireball"), "hitFireball", 3, -2, Items.AMMO_FIREBALL, ENTER_NETHER)
+            .setType(Achievement.TYPE_SPECIAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement SLEEP_NETHER =
+        new Achievement(new NamespaceID("minecraft", "sleep_nether"), "sleepNether", 1, -2, Items.BED, ENTER_NETHER)
+            .setType(Achievement.TYPE_SPECIAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement ENTER_OLDWORLD =
+        new Achievement(new NamespaceID("minecraft", "enter_oldworld"), "enterOldworld", 0, -5, Blocks.BEDROCK, ENTER_NETHER)
+            .setType(Achievement.TYPE_NORMAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement ENTER_WARRENS =
+        new Achievement(new NamespaceID("minecraft", "enter_warrens"), "enterWarrens", 0, 5, Blocks.BEDROCK, ENTER_NETHER)
+            .setType(Achievement.TYPE_NORMAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement MOST_WANTED =
+        new Achievement(new NamespaceID("minecraft", "most_wanted"), "mostWanted", -0, -1, Items.TOOL_SWORD_GOLD, ENTER_NETHER)
+            .setType(Achievement.TYPE_NORMAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+    public static Achievement FAST_TRAVEL = // TODO
+        new Achievement(new NamespaceID("minecraft", "fast_travel"), "fastTravel", -0, 1, Blocks.GRASS, ENTER_NETHER)
+            .setType(Achievement.TYPE_NORMAL)
+            .registerAchievement()
+            .addToPage(AchievementPages.netherPage);
+
 
     private static boolean hasInit = false;
     public static void init() {
diff --git a/src/main/java/net/minecraft/core/block/BedBlock.java b/src/main/java/net/minecraft/core/block/BedBlock.java
index 93c9b0e86..1dd845d5e 100644
--- a/src/main/java/net/minecraft/core/block/BedBlock.java
+++ b/src/main/java/net/minecraft/core/block/BedBlock.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.block.entity.BlockEntity;
 import net.minecraft.core.block.material.Material;
 import net.minecraft.core.entity.player.Player;
@@ -46,6 +47,7 @@ public class BedBlock extends Block {
 			if(world.getBlockId(x, y, z) == id) {
 				world.setBlockWithNotify(x, y, z, 0);
             }
+			player.addStat(Achievements.SLEEP_NETHER, 1);
 			world.newExplosion(null, (float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F, 5F, true, false);
 			return true;
 		}
diff --git a/src/main/java/net/minecraft/core/block/DispenserBlock.java b/src/main/java/net/minecraft/core/block/DispenserBlock.java
index 7a0d721cd..a6e680913 100644
--- a/src/main/java/net/minecraft/core/block/DispenserBlock.java
+++ b/src/main/java/net/minecraft/core/block/DispenserBlock.java
@@ -125,7 +125,7 @@ public class DispenserBlock extends RotatableEntityBlock
             else if (itemStack.itemID == Items.AMMO_ARROW.id || itemStack.itemID == Items.AMMO_ARROW_GOLD.id)
             {
 
-                ArrowProjectile arrow = itemStack.itemID == Items.AMMO_ARROW.id ? new ArrowProjectile(world, px, py, pz, 0) : new ArrowProjectileGolden(world, px, py, pz);
+                ArrowProjectile arrow = itemStack.itemID == Items.AMMO_ARROW.id ? new ArrowProjectile(world, px, py, pz, 0) : new GoldenArrowProjectile(world, px, py, pz);
                 arrow.setHeading(xOffset, 0.1D, zOffset, 1.1F, 6F);
                 arrow.setDoesArrowBelongToPlayer(true);
                 world.entityJoinedWorld(arrow);
diff --git a/src/main/java/net/minecraft/core/block/SignBlock.java b/src/main/java/net/minecraft/core/block/SignBlock.java
index cdcb84b7c..2557be6f6 100644
--- a/src/main/java/net/minecraft/core/block/SignBlock.java
+++ b/src/main/java/net/minecraft/core/block/SignBlock.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.block.entity.BlockEntity;
 import net.minecraft.core.block.entity.SignBlockEntity;
 import net.minecraft.core.entity.player.Player;
@@ -163,6 +164,7 @@ public class SignBlock extends EntityBlock
                 if (player.getGamemode().consumeBlocks()) {
                     player.getHeldItem().stackSize--;
                 }
+                player.addStat(Achievements.LIGHT_SIGN, 1);
                 return true;
             } else if (player.getHeldItem() != null && player.getHeldItem().itemID == Items.DYE.id) {
                 return false;
diff --git a/src/main/java/net/minecraft/core/block/StoneBlock.java b/src/main/java/net/minecraft/core/block/StoneBlock.java
index 8b005717c..0b34f12fc 100644
--- a/src/main/java/net/minecraft/core/block/StoneBlock.java
+++ b/src/main/java/net/minecraft/core/block/StoneBlock.java
@@ -31,9 +31,13 @@ public class StoneBlock extends Block {
 	public void harvestBlock(World world, Player player, int x, int y, int z, int meta, BlockEntity blockEntity)
 	{
 		super.harvestBlock(world, player, x, y, z, meta, blockEntity);
-		if(player.getStat(Blocks.BASALT.getStat(StatList.STAT_MINED)) > 0
-				&& player.getStat(Blocks.BASALT.getStat(StatList.STAT_MINED)) > 0
-				&& player.getStat(Blocks.BASALT.getStat(StatList.STAT_MINED)) > 0) {
+		if(
+			player.getStat(Blocks.STONE.getStat(StatList.STAT_MINED)) > 0 &&
+			player.getStat(Blocks.BASALT.getStat(StatList.STAT_MINED)) > 0 &&
+			player.getStat(Blocks.GRANITE.getStat(StatList.STAT_MINED)) > 0 &&
+			player.getStat(Blocks.LIMESTONE.getStat(StatList.STAT_MINED)) > 0 &&
+			player.getStat(Blocks.PERMAFROST.getStat(StatList.STAT_MINED)) > 0) {
+
 			player.triggerAchievement(Achievements.COLLECT_STONE);
 		}
 	}
diff --git a/src/main/java/net/minecraft/core/entity/EntityDispatcher.java b/src/main/java/net/minecraft/core/entity/EntityDispatcher.java
index f50e6a645..d33dc2a93 100644
--- a/src/main/java/net/minecraft/core/entity/EntityDispatcher.java
+++ b/src/main/java/net/minecraft/core/entity/EntityDispatcher.java
@@ -136,9 +136,9 @@ public class EntityDispatcher
         addMapping(MinecartEntity.class, "Minecart", 40);
         addMapping(BoatEntity.class, "Boat", 41);
         addMapping(ZombieArmoredMob.class, "ArmouredZombie", 42);
-        addMapping(ArrowProjectileGolden.class, "ArrowGolden", 43);
+        addMapping(GoldenArrowProjectile.class, "ArrowGolden", 43);
         addMapping(CannonballProjectile.class, "Cannonball", 44);
-        addMapping(ArrowProjectilePurple.class, "ArrowPurple", 45);
+        addMapping(PurpleArrowProjectile.class, "ArrowPurple", 45);
         addMapping(PebbleProjectile.class, "Pebble", 46);
         addMapping(FireflyClusterMob.class, "FireflyCluster", 47);
         addMapping(Mob.class, "Mob", 48);
diff --git a/src/main/java/net/minecraft/core/entity/ItemEntity.java b/src/main/java/net/minecraft/core/entity/ItemEntity.java
index a4394a968..3fc5b2ac2 100644
--- a/src/main/java/net/minecraft/core/entity/ItemEntity.java
+++ b/src/main/java/net/minecraft/core/entity/ItemEntity.java
@@ -19,6 +19,7 @@ import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.Item;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.item.MusicDiscItem;
 import net.minecraft.core.util.helper.DamageType;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.AABB;
@@ -214,6 +215,12 @@ public class ItemEntity extends Entity
 				if(item.itemID == Items.LEATHER.id) {
 					player.triggerAchievement(Achievements.KILL_COW);
 				}
+                if(item.itemID == Items.DIAMOND.id) {
+                    player.triggerAchievement(Achievements.GET_DIAMONDS);
+                }
+                if(item.itemID == Items.NETHERCOAL.id) {
+                    player.triggerAchievement(Achievements.GET_NETHERCOAL);
+                }
 				if(item.itemID == Blocks.ICE.id) {
 					player.triggerAchievement(Achievements.CRUSH_BLOCKS);
 				}
@@ -235,6 +242,24 @@ public class ItemEntity extends Entity
 					}
 				}
 
+                if (item.getItem() instanceof MusicDiscItem) {
+                    if( player.getStat(Items.RECORD_13.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_CAT.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_BLOCKS.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_CHIRP.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_FAR.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_MALL.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_MELLOHI.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_STAL.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_STRAD.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_WARD.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_WAIT.getStat(StatList.STAT_PICKED_UP)) > 0 &&
+                        player.getStat(Items.RECORD_DOG.getStat(StatList.STAT_PICKED_UP)) > 0)
+                    {
+                        player.triggerAchievement(Achievements.ALL_MUSIC_DISCS);
+                    }
+                }
+
 				if(item.stackSize <= 0) {
 					remove();
 				}
diff --git a/src/main/java/net/minecraft/core/entity/monster/ZombiePigMob.java b/src/main/java/net/minecraft/core/entity/monster/ZombiePigMob.java
index 5d33fbc47..92627d569 100644
--- a/src/main/java/net/minecraft/core/entity/monster/ZombiePigMob.java
+++ b/src/main/java/net/minecraft/core/entity/monster/ZombiePigMob.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.entity.monster;
 
 import net.minecraft.core.WeightedRandomLootObject;
+import net.minecraft.core.achievement.Achievement;
+import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.Items;
@@ -37,6 +39,18 @@ public class ZombiePigMob extends ZombieMob
     @Override
 	public void tick()
     {
+        if (tickCount % 200 == 0 && entityToAttack instanceof Player && ((Player) entityToAttack).getStat(Achievements.MOST_WANTED) <= 0) {
+            int agroNumber = 1;
+            for (Entity e : world.loadedEntityList) {
+                if (e instanceof ZombiePigMob && ((ZombiePigMob) e).entityToAttack == this.entityToAttack) {
+                    agroNumber++;
+                }
+                if (agroNumber >= 20) {
+                    ((Player) entityToAttack).addStat(Achievements.MOST_WANTED, 1);
+                    break;
+                }
+            }
+        }
         moveSpeed = entityToAttack == null ? 0.5F : 0.95F;
         if(randomSoundDelay > 0 && --randomSoundDelay == 0)
         {
diff --git a/src/main/java/net/minecraft/core/entity/player/Player.java b/src/main/java/net/minecraft/core/entity/player/Player.java
index 9f0485ba7..0abe40af6 100644
--- a/src/main/java/net/minecraft/core/entity/player/Player.java
+++ b/src/main/java/net/minecraft/core/entity/player/Player.java
@@ -36,7 +36,7 @@ import net.minecraft.core.entity.monster.SnowmanMob;
 import net.minecraft.core.entity.monster.SpiderMob;
 import net.minecraft.core.entity.monster.ZombieMob;
 import net.minecraft.core.entity.projectile.ArrowProjectile;
-import net.minecraft.core.entity.projectile.ArrowProjectileGolden;
+import net.minecraft.core.entity.projectile.GoldenArrowProjectile;
 import net.minecraft.core.entity.projectile.CannonballProjectile;
 import net.minecraft.core.entity.projectile.FireballProjectile;
 import net.minecraft.core.entity.vehicle.BoatEntity;
@@ -59,6 +59,7 @@ import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.util.helper.DamageType;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.AABB;
+import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
@@ -91,6 +92,7 @@ public abstract class Player extends Mob
     public double zd0;
     protected boolean sleeping;
     public ChunkCoordinates bedChunkCoordinates;
+    public ChunkCoordinates dimensionEnterCoordinate;
     private int sleepTimer;
     public float sleepOffX;
     public float sleepOffY;
@@ -189,6 +191,16 @@ public abstract class Player extends Mob
     @Override
 	public void tick()
     {
+        if (world.dimension == Dimension.nether) {
+            if (y >= 260) {
+                addStat(Achievements.ENTER_OLDWORLD, 1);
+            } else if (y >=128) {
+                addStat(Achievements.ENTER_NETHER, 1);
+            } else {
+                addStat(Achievements.ENTER_WARRENS, 1);
+            }
+        }
+
         xdO = xd;
         ydO = yd;
         zd0 = zd;
@@ -460,11 +472,11 @@ public abstract class Player extends Mob
         {
             return getDisplayName() + deathMsgColor + " got what they deserved.";
         }
-        if (entityKilledBy instanceof ArrowProjectileGolden)
+        if (entityKilledBy instanceof GoldenArrowProjectile)
         {
-            if (((ArrowProjectileGolden) entityKilledBy).owner instanceof ServerPlayer)
+            if (((GoldenArrowProjectile) entityKilledBy).owner instanceof ServerPlayer)
             {
-                if (((ServerPlayer) ((ArrowProjectileGolden) entityKilledBy).owner).username.equals(username))
+                if (((ServerPlayer) ((GoldenArrowProjectile) entityKilledBy).owner).username.equals(username))
                 {
                     return getDisplayName() + deathMsgColor + " got gold in their eye.";
                 }
@@ -1322,6 +1334,9 @@ public abstract class Player extends Mob
             if(j > 0)
             {
                 addStat(StatList.distanceSwumStat, j);
+                if (dimension == Dimension.nether.id) {
+                    addStat(Achievements.SWIM_NETHER, 1);
+                }
             }
         } else
         if(canClimb())
diff --git a/src/main/java/net/minecraft/core/entity/projectile/ArrowProjectile.java b/src/main/java/net/minecraft/core/entity/projectile/ArrowProjectile.java
index dba79c5c7..13cd620fc 100644
--- a/src/main/java/net/minecraft/core/entity/projectile/ArrowProjectile.java
+++ b/src/main/java/net/minecraft/core/entity/projectile/ArrowProjectile.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.entity.projectile;
 
 import com.mojang.nbt.CompoundTag;
+import net.minecraft.core.achievement.Achievement;
+import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.util.phys.HitResult;
@@ -24,6 +26,7 @@ public class ArrowProjectile extends Projectile
     public static final int TYPE_NORMAL = 0;
     public static final int TYPE_PURPLE = 1;
     public static final int TYPE_GOLDEN = 2;
+    protected int mobsHit = 0;
     protected int xTile = -1;
     protected int yTile = -1;
     protected int zTile = -1;
@@ -150,7 +153,7 @@ public class ArrowProjectile extends Projectile
             }
             return;
         }
-        else if(this instanceof ArrowProjectileGolden)
+        else if(this instanceof GoldenArrowProjectile)
         {
             world.spawnParticle("arrowtrail", x, y, z, xd * 0.05D, yd * 0.05D - 0.1D, zd * 0.05D, 0);
             world.spawnParticle("arrowtrail", x + xd * 0.5D, y + yd * 0.5D, z + zd * 0.5D, xd * 0.05D, yd * 0.05D - 0.1D, zd * 0.05D, 0);
@@ -172,11 +175,15 @@ public class ArrowProjectile extends Projectile
                 if(!world.isClientSide) {
                 	world.playSoundAtEntity(null, this, "random.drr", 1.0F, 1.2F / (random.nextFloat() * 0.2F + 0.9F));
                 }
-                if(!(this instanceof ArrowProjectileGolden))
+                if(!(this instanceof GoldenArrowProjectile))
                 {
                     remove();
+                } else {
+                    if (owner instanceof Player && ++mobsHit >= 3) {
+                        ((Player) owner).addStat(Achievements.TRIPLE_HIT, 1);
+                    }
                 }
-            } else if(!(this instanceof ArrowProjectileGolden))
+            } else if(!(this instanceof GoldenArrowProjectile))
             {
                 xd *= -0.1D;
                 yd *= -0.1D;
diff --git a/src/main/java/net/minecraft/core/entity/projectile/FireballProjectile.java b/src/main/java/net/minecraft/core/entity/projectile/FireballProjectile.java
index 940c52802..55d1fae8e 100644
--- a/src/main/java/net/minecraft/core/entity/projectile/FireballProjectile.java
+++ b/src/main/java/net/minecraft/core/entity/projectile/FireballProjectile.java
@@ -1,7 +1,9 @@
 package net.minecraft.core.entity.projectile;
 
+import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.monster.GhastMob;
+import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.util.phys.HitResult;
 import net.minecraft.core.util.phys.Vec3;
 import net.minecraft.core.entity.Entity;
@@ -87,6 +89,9 @@ public class FireballProjectile extends Projectile
                     } else {
                         result.entity.hurt(owner, damage, DamageType.COMBAT);
                     }
+                    if (owner instanceof Player) {
+                        ((Player) owner).addStat(Achievements.HIT_FIREBALL, 1);
+                    }
                 }
                 world.newExplosion(owner, x, y, z, 1.5F, true, false);
             }
diff --git a/src/main/java/net/minecraft/core/entity/projectile/ArrowProjectileGolden.java b/src/main/java/net/minecraft/core/entity/projectile/GoldenArrowProjectile.java
similarity index 83%
rename from src/main/java/net/minecraft/core/entity/projectile/ArrowProjectileGolden.java
rename to src/main/java/net/minecraft/core/entity/projectile/GoldenArrowProjectile.java
index b22d2d99a..a16b3ad88 100644
--- a/src/main/java/net/minecraft/core/entity/projectile/ArrowProjectileGolden.java
+++ b/src/main/java/net/minecraft/core/entity/projectile/GoldenArrowProjectile.java
@@ -8,29 +8,28 @@ package net.minecraft.core.entity.projectile;
 
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.item.Item;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.world.World;
 
-public class ArrowProjectileGolden extends ArrowProjectile
+public class GoldenArrowProjectile extends ArrowProjectile
 {
 
-    public ArrowProjectileGolden(World world)
+    public GoldenArrowProjectile(World world)
     {
         super(world, TYPE_GOLDEN);
         this.noPhysics = true;
         stack = new ItemStack(Items.AMMO_ARROW_GOLD);
     }
 
-    public ArrowProjectileGolden(World world, double x, double y, double z)
+    public GoldenArrowProjectile(World world, double x, double y, double z)
     {
         super(world, x, y, z, TYPE_GOLDEN);
         this.noPhysics = true;
         stack = new ItemStack(Items.AMMO_ARROW_GOLD);
     }
 
-    public ArrowProjectileGolden(World world, Mob owner, boolean doesArrowBelongToPlayer)
+    public GoldenArrowProjectile(World world, Mob owner, boolean doesArrowBelongToPlayer)
     {
         super(world, owner, doesArrowBelongToPlayer, TYPE_GOLDEN);
         this.noPhysics = true;
diff --git a/src/main/java/net/minecraft/core/entity/projectile/ArrowProjectilePurple.java b/src/main/java/net/minecraft/core/entity/projectile/PurpleArrowProjectile.java
similarity index 81%
rename from src/main/java/net/minecraft/core/entity/projectile/ArrowProjectilePurple.java
rename to src/main/java/net/minecraft/core/entity/projectile/PurpleArrowProjectile.java
index f53610c9d..ce9c9780e 100644
--- a/src/main/java/net/minecraft/core/entity/projectile/ArrowProjectilePurple.java
+++ b/src/main/java/net/minecraft/core/entity/projectile/PurpleArrowProjectile.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.entity.projectile;
 
 import net.minecraft.core.entity.Mob;
-import net.minecraft.core.item.Item;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.world.World;
 
@@ -11,20 +10,20 @@ import net.minecraft.core.world.World;
 //            MovingObjectPosition, NBTTagCompound, ItemStack, Item, 
 //            InventoryPlayer
 
-public class ArrowProjectilePurple extends ArrowProjectile
+public class PurpleArrowProjectile extends ArrowProjectile
 {
 
-    public ArrowProjectilePurple(World world)
+    public PurpleArrowProjectile(World world)
     {
         super(world, TYPE_PURPLE);
     }
 
-    public ArrowProjectilePurple(World world, double x, double y, double z)
+    public PurpleArrowProjectile(World world, double x, double y, double z)
     {
         super(world, x, y, z, TYPE_PURPLE);
     }
 
-    public ArrowProjectilePurple(World world, Mob owner, boolean doesArrowBelongToPlayer)
+    public PurpleArrowProjectile(World world, Mob owner, boolean doesArrowBelongToPlayer)
     {
         super(world, owner, doesArrowBelongToPlayer, TYPE_PURPLE);
     }
diff --git a/src/main/java/net/minecraft/core/item/BowItem.java b/src/main/java/net/minecraft/core/item/BowItem.java
index a1a7260f8..54af1774f 100644
--- a/src/main/java/net/minecraft/core/item/BowItem.java
+++ b/src/main/java/net/minecraft/core/item/BowItem.java
@@ -6,8 +6,8 @@ package net.minecraft.core.item;
 //            ArrowProjectile, ItemStack
 
 import net.minecraft.core.entity.projectile.ArrowProjectile;
-import net.minecraft.core.entity.projectile.ArrowProjectileGolden;
-import net.minecraft.core.entity.projectile.ArrowProjectilePurple;
+import net.minecraft.core.entity.projectile.GoldenArrowProjectile;
+import net.minecraft.core.entity.projectile.PurpleArrowProjectile;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.world.World;
 
@@ -37,7 +37,7 @@ public class BowItem extends Item
             itemstack.damageItem(1, entityplayer);
             world.playSoundAtEntity(entityplayer, entityplayer, "random.bow", 0.3f, 1.0F / (itemRand.nextFloat() * 0.4F + 0.8F));
             if (!world.isClientSide) {
-                world.entityJoinedWorld(new ArrowProjectilePurple(world, entityplayer, false));
+                world.entityJoinedWorld(new PurpleArrowProjectile(world, entityplayer, false));
             }
         }
         else if (entityplayer.inventory.consumeInventoryItem(Items.AMMO_ARROW_GOLD.id))
@@ -46,7 +46,7 @@ public class BowItem extends Item
             world.playSoundAtEntity(entityplayer, entityplayer, "random.bow", 0.3f, 1.0F / (itemRand.nextFloat() * 0.4F + 0.8F));
             if(!world.isClientSide)
             {
-                world.entityJoinedWorld(new ArrowProjectileGolden(world, entityplayer, true));
+                world.entityJoinedWorld(new GoldenArrowProjectile(world, entityplayer, true));
             }
         }
         else if(entityplayer.inventory.consumeInventoryItem(Items.AMMO_ARROW.id))
diff --git a/src/main/java/net/minecraft/core/item/FoodItem.java b/src/main/java/net/minecraft/core/item/FoodItem.java
index a13f3b984..b0ab4fe5c 100644
--- a/src/main/java/net/minecraft/core/item/FoodItem.java
+++ b/src/main/java/net/minecraft/core/item/FoodItem.java
@@ -26,6 +26,7 @@ public class FoodItem extends Item
                 && entityplayer.getHealth() + entityplayer.getTotalHealingRemaining() < entityplayer.getMaxHealth()
                 && itemstack.consumeItem(entityplayer)) {
             entityplayer.eatFood(this);
+            world.playSoundAtEntity(entityplayer, entityplayer, ticksPerHeal >= 10 ? "random.bite_extended" : "random.bite", 0.5f + (itemRand.nextFloat() - itemRand.nextFloat()) * 0.1f, 1.1f + (itemRand.nextFloat() - itemRand.nextFloat()) * 0.1f);
         }
         return itemstack;
     }
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/ArrowNetEntry.java b/src/main/java/net/minecraft/core/net/entity/entries/ArrowNetEntry.java
index 86ebf4325..4ca4c183e 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/ArrowNetEntry.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/ArrowNetEntry.java
@@ -3,8 +3,8 @@ package net.minecraft.core.net.entity.entries;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.projectile.ArrowProjectile;
-import net.minecraft.core.entity.projectile.ArrowProjectileGolden;
-import net.minecraft.core.entity.projectile.ArrowProjectilePurple;
+import net.minecraft.core.entity.projectile.GoldenArrowProjectile;
+import net.minecraft.core.entity.projectile.PurpleArrowProjectile;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
@@ -42,9 +42,9 @@ public class ArrowNetEntry implements IVehicleEntry<ArrowProjectile>, ITrackedEn
     @Override
     public Entity getEntity(World world, double x, double y, double z, int metadata, boolean hasVelocity, double xd, double yd, double zd, Entity owner) {
         if (metadata == 2) {
-            return new ArrowProjectileGolden(world, x, y, z);
+            return new GoldenArrowProjectile(world, x, y, z);
         } else if (metadata == 1) {
-            return new ArrowProjectilePurple(world, x, y, z);
+            return new PurpleArrowProjectile(world, x, y, z);
         } else {
             return new ArrowProjectile(world, x, y, z, metadata);
         }
diff --git a/src/main/java/net/minecraft/core/player/inventory/slot/ArmorSlot.java b/src/main/java/net/minecraft/core/player/inventory/slot/ArmorSlot.java
index f5a38946f..23483ddae 100644
--- a/src/main/java/net/minecraft/core/player/inventory/slot/ArmorSlot.java
+++ b/src/main/java/net/minecraft/core/player/inventory/slot/ArmorSlot.java
@@ -3,13 +3,18 @@ package net.minecraft.core.player.inventory.slot;
 import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.IArmorItem;
+import net.minecraft.core.item.Item;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.block.BlockItem;
+import net.minecraft.core.item.material.ArmorMaterial;
 import net.minecraft.core.player.inventory.container.Inventory;
 import net.minecraft.core.player.inventory.menu.InventoryMenu;
 import net.minecraft.core.player.inventory.container.Container;
 
+import java.util.HashSet;
+import java.util.Set;
+
 public class ArmorSlot extends Slot
 {
     public static String[] armorOutlines = new String[]{
@@ -56,7 +61,9 @@ public class ArmorSlot extends Slot
 	public void setChanged()
     {
         super.setChanged();
-        
+
+        Set<ArmorMaterial> wornMaterials = new HashSet<>();
+
         int count = 0;
         
         for (int i = 0; i < menu.slots.size(); i++)
@@ -68,6 +75,12 @@ public class ArmorSlot extends Slot
 				{
         			count++;
 				}
+                if (stack != null) {
+                    Item item = stack.getItem();
+                    if (item instanceof IArmorItem){
+                        wornMaterials.add(((IArmorItem) item).getArmorMaterial());
+                    }
+                }
         	}
         }
         
@@ -75,6 +88,9 @@ public class ArmorSlot extends Slot
         {
         	menu.inventory.player.triggerAchievement(Achievements.GET_CHAINMAIL);
         }
+        if (wornMaterials.size() >= 4) {
+            menu.inventory.player.triggerAchievement(Achievements.ALL_ARMOR_TYPES);
+        }
         
         if (getItem() != null && container instanceof Inventory) {
             Player player = ((Inventory) container).player;
diff --git a/src/main/java/net/minecraft/core/player/inventory/slot/ResultSlot.java b/src/main/java/net/minecraft/core/player/inventory/slot/ResultSlot.java
index fb70a181d..b9700428f 100644
--- a/src/main/java/net/minecraft/core/player/inventory/slot/ResultSlot.java
+++ b/src/main/java/net/minecraft/core/player/inventory/slot/ResultSlot.java
@@ -46,6 +46,8 @@ public class ResultSlot extends Slot
 		if(item.id == Blocks.FURNACE_STONE_IDLE.id) thePlayer.addStat(Achievements.BUILD_FURNACE, 1);
 		if(item.id == Items.FOOD_BREAD.id) thePlayer.addStat(Achievements.MAKE_BREAD, 1);
 		if(item.id == Items.FOOD_CAKE.id) thePlayer.addStat(Achievements.BAKE_CAKE, 1);
+		if(item.id == Items.BUCKET_ICECREAM.id) thePlayer.addStat(Achievements.CRAFT_ICECREAM, 1);
+		if(item.id == Items.FOOD_PUMPKIN_PIE.id) thePlayer.addStat(Achievements.CRAFT_PUMPKIN_PIE, 1);
 		if(item.id == Items.HANDCANNON_UNLOADED.id) thePlayer.addStat(Achievements.CRAFT_HANDCANNON, 1);
 		if(item instanceof HoeToolItem) thePlayer.addStat(Achievements.BUILD_HOE, 1);
 		if(item instanceof SwordToolItem) thePlayer.addStat(Achievements.BUILD_SWORD, 1);
diff --git a/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureLabyrinth.java b/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureLabyrinth.java
index cb2a2efb8..e2164ccc7 100644
--- a/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureLabyrinth.java
+++ b/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureLabyrinth.java
@@ -5,6 +5,7 @@ import net.minecraft.core.WeightedRandomLootObject;
 import net.minecraft.core.block.entity.ChestBlockEntity;
 import net.minecraft.core.block.entity.DispenserBlockEntity;
 import net.minecraft.core.block.entity.MobSpawnerBlockEntity;
+import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.item.Item;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
@@ -220,9 +221,16 @@ public class WorldFeatureLabyrinth extends WorldFeature
             world.setBlockWithNotify(x, y, z, 0);
             return true;
         }
-        return world.getBlockMaterial(x, y, z) == Material.grass ||
+        return BlockTags.CAVES_CUT_THROUGH.appliesTo(world.getBlock(x, y, z)) ||
+                world.getBlockMaterial(x, y, z) == Material.grass ||
                 world.getBlockMaterial(x, y, z) == Material.dirt ||
                 world.getBlockMaterial(x, y, z) == Material.stone ||
+                world.getBlockMaterial(x, y, z) == Material.slate ||
+                world.getBlockMaterial(x, y, z) == Material.marble ||
+                world.getBlockMaterial(x, y, z) == Material.limestone ||
+                world.getBlockMaterial(x, y, z) == Material.basalt ||
+                world.getBlockMaterial(x, y, z) == Material.granite ||
+                world.getBlockMaterial(x, y, z) == Material.permafrost ||
                 world.getBlockMaterial(x, y, z) == Material.sand ||
                 world.getBlockMaterial(x, y, z) == Material.moss;
     }
diff --git a/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureLake.java b/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureLake.java
index 5e50c5f3f..9c351498c 100644
--- a/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureLake.java
+++ b/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureLake.java
@@ -100,7 +100,7 @@ public class WorldFeatureLake extends WorldFeature
                 {
                     if(shouldPlaceLiquid[(dx * 16 + dz) * 8 + dy])
                     {
-                        world.setBlock(x + dx, y + dy, z + dz, dy < 4 ? liquidId : 0);
+                        world.setBlockWithNotify(x + dx, y + dy, z + dz, dy < 4 ? liquidId : 0);
                     }
                 }
 
diff --git a/src/main/java/net/minecraft/server/net/PlayerList.java b/src/main/java/net/minecraft/server/net/PlayerList.java
index 864b73f0e..67f0580cc 100644
--- a/src/main/java/net/minecraft/server/net/PlayerList.java
+++ b/src/main/java/net/minecraft/server/net/PlayerList.java
@@ -1,8 +1,10 @@
 package net.minecraft.server.net;
 
+import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.block.entity.BlockEntity;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.server.entity.player.ServerPlayer;
 import net.minecraft.server.net.handler.LoginPacketHandler;
 import net.minecraft.core.net.packet.*;
@@ -226,13 +228,24 @@ public class PlayerList
         serverPlayer.playerNetServerHandler.sendPacket(new RespawnPacket((byte) serverPlayer.dimension, (byte) Registries.WORLD_TYPES.getNumericIdOfItem(worldserver1.worldType)));
         worldserver.removePlayer(serverPlayer);
         serverPlayer.removed = false;
-        double d = serverPlayer.x;
-        double d1 = serverPlayer.z;
-        double d2 = 8D;
-
-        d *= Dimension.getCoordScale(lastDim, newDim);
-        d1 *= Dimension.getCoordScale(lastDim, newDim);
-        serverPlayer.moveTo(d, serverPlayer.y, d1, serverPlayer.yRot, serverPlayer.xRot);
+        double x = serverPlayer.x;
+        double y = serverPlayer.y;
+        double z = serverPlayer.z;
+
+        x *= Dimension.getCoordScale(lastDim, newDim);
+        z *= Dimension.getCoordScale(lastDim, newDim);
+        serverPlayer.moveTo(x, y, z, serverPlayer.yRot, serverPlayer.xRot);
+        ChunkCoordinates newCoordinates = new ChunkCoordinates(MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z));
+        if (serverPlayer.dimensionEnterCoordinate != null) {
+            double dx = serverPlayer.dimensionEnterCoordinate.x - x;
+            double dy = serverPlayer.dimensionEnterCoordinate.y - y;
+            double dz = serverPlayer.dimensionEnterCoordinate.z - z;
+            double distSqr = (dx * dx) + (dy * dy) + (dz * dz);
+            if (distSqr > 8000 * 8000) {
+                serverPlayer.addStat(Achievements.FAST_TRAVEL, 1);
+            }
+        }
+        serverPlayer.dimensionEnterCoordinate = newCoordinates;
         if (serverPlayer.isAlive())
         {
             worldserver.updateEntityWithOptionalForce(serverPlayer, false);
@@ -241,7 +254,7 @@ public class PlayerList
         if (serverPlayer.isAlive())
         {
             worldserver1.entityJoinedWorld(serverPlayer);
-            serverPlayer.moveTo(d, serverPlayer.y, d1, serverPlayer.yRot, serverPlayer.xRot);
+            serverPlayer.moveTo(x, serverPlayer.y, z, serverPlayer.yRot, serverPlayer.xRot);
             worldserver1.updateEntityWithOptionalForce(serverPlayer, false);
             if (generatePortal){
                 worldserver1.chunkProviderServer.chunkLoadOverride = true;
diff --git a/src/main/resources/assets/minecraft/textures/block/door_steel_bottom.png b/src/main/resources/assets/minecraft/textures/block/door_steel_bottom.png
index 7ba84563e..a88cc6a66 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/door_steel_bottom.png and b/src/main/resources/assets/minecraft/textures/block/door_steel_bottom.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/door_steel_top.png b/src/main/resources/assets/minecraft/textures/block/door_steel_top.png
index 9392cf312..ca8f8448e 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/door_steel_top.png and b/src/main/resources/assets/minecraft/textures/block/door_steel_top.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/trapdoor_steel_side.png b/src/main/resources/assets/minecraft/textures/block/trapdoor_steel_side.png
index 2df48296f..332f8874e 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/trapdoor_steel_side.png and b/src/main/resources/assets/minecraft/textures/block/trapdoor_steel_side.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/trapdoor_steel_top.png b/src/main/resources/assets/minecraft/textures/block/trapdoor_steel_top.png
index 61b2b0cd0..00aeb44a8 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/trapdoor_steel_top.png and b/src/main/resources/assets/minecraft/textures/block/trapdoor_steel_top.png differ
diff --git a/src/main/resources/assets/minecraft/textures/item/door_steel.png b/src/main/resources/assets/minecraft/textures/item/door_steel.png
index fb75d2b89..d414e3939 100644
Binary files a/src/main/resources/assets/minecraft/textures/item/door_steel.png and b/src/main/resources/assets/minecraft/textures/item/door_steel.png differ
