diff --git a/game/client/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java b/game/client/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
index 9e056fdec..ca1140b30 100644
--- a/game/client/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
@@ -221,6 +221,9 @@ public class ShadersRenderer implements Renderer {
 
             LOGGER.info("Display: {}, Render: {}", fbSize, renderSize);
 
+            if (this.worldFrameBuffer != null) this.worldFrameBuffer.delete();
+            if (this.gameFrameBuffer != null) this.gameFrameBuffer.delete();
+
             this.worldFrameBuffer = new FrameBufferSingleSample(
                 new FrameBufferTextureSingleSample(
                     GL41.GL_RGBA,
diff --git a/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java b/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java
index b5f0c970a..70c8bc788 100644
--- a/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java
+++ b/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java
@@ -334,7 +334,7 @@ public class StaticEntityModelMojang implements StaticEntityModel {
             q.set(x, y, z)
                 .sub(pivot)
                 .rotateX(-rotation.x() * MathHelper.DEG_TO_RAD)
-                .rotateY(-rotation.y() * MathHelper.DEG_TO_RAD)
+                .rotateY( rotation.y() * MathHelper.DEG_TO_RAD)
                 .rotateZ(-rotation.z() * MathHelper.DEG_TO_RAD)
                 .add(pivot);
             tessellator.addVertexWithUV(q, u, v);
diff --git a/game/client/src/main/resources/assets/minecraft/models/entity/humanoid.geo.json b/game/client/src/main/resources/assets/minecraft/models/entity/humanoid.geo.json
index e196e711d..a9de1c201 100644
--- a/game/client/src/main/resources/assets/minecraft/models/entity/humanoid.geo.json
+++ b/game/client/src/main/resources/assets/minecraft/models/entity/humanoid.geo.json
@@ -82,5 +82,171 @@
 				]
 			}
 		]
+	},
+	"geometry.humanoid.armor.boots": {
+		"texturewidth": 64,
+		"textureheight": 32,
+		"visible_bounds_width": 3,
+		"visible_bounds_height": 3,
+		"visible_bounds_offset": [0, 1.5, 0],
+		"bones": [
+			{
+				"name": "waist",
+				"pivot": [0, 12, 0]
+			},
+			{
+				"name": "body",
+				"parent": "waist",
+				"pivot": [0, 24, 0]
+			},
+			{
+				"name": "rightLeg",
+				"parent": "body",
+				"pivot": [-1.9, 12, 0],
+				"cubes": [
+					{"origin": [-4, 0, -2], "size": [4, 12, 4], "uv": [0, 16]}
+				]
+			},
+			{
+				"name": "leftLeg",
+				"parent": "body",
+				"pivot": [1.9, 12, 0],
+				"cubes": [
+					{"origin": [0, 0, -2], "size": [4, 12, 4], "uv": [0, 16], "mirror": true}
+				]
+			}
+		]
+	},
+	"geometry.humanoid.armor.leggings": {
+		"texturewidth": 64,
+		"textureheight": 32,
+		"visible_bounds_width": 3,
+		"visible_bounds_height": 3,
+		"visible_bounds_offset": [0, 1.5, 0],
+		"bones": [
+			{
+				"name": "waist",
+				"pivot": [0, 12, 0]
+			},
+			{
+				"name": "body",
+				"parent": "waist",
+				"pivot": [0, 24, 0]
+			},
+			{
+				"name": "rightLeg",
+				"parent": "body",
+				"pivot": [-1.9, 12, 0],
+				"cubes": [
+					{"origin": [-4, 0, -2], "size": [4, 12, 4], "uv": [0, 16]}
+				]
+			},
+			{
+				"name": "leftLeg",
+				"parent": "body",
+				"pivot": [1.9, 12, 0],
+				"cubes": [
+					{"origin": [0, 0, -2], "size": [4, 12, 4], "uv": [0, 16], "mirror": true}
+				]
+			},
+			{
+				"name": "torso",
+				"parent": "body",
+				"pivot": [0, 24, 0]
+			},
+			{
+				"name": "chest",
+				"parent": "torso",
+				"pivot": [0, 24, 0],
+				"cubes": [
+					{"origin": [-4, 12, -2], "size": [8, 12, 4], "uv": [16, 16]}
+				]
+			}
+		]
+	},
+	"geometry.humanoid.armor.chestplate": {
+		"texturewidth": 64,
+		"textureheight": 32,
+		"visible_bounds_width": 3,
+		"visible_bounds_height": 3,
+		"visible_bounds_offset": [0, 1.5, 0],
+		"bones": [
+			{
+				"name": "waist",
+				"pivot": [0, 12, 0]
+			},
+			{
+				"name": "body",
+				"parent": "waist",
+				"pivot": [0, 24, 0]
+			},
+			{
+				"name": "torso",
+				"parent": "body",
+				"pivot": [0, 24, 0]
+			},
+			{
+				"name": "rightArm",
+				"parent": "torso",
+				"pivot": [-5, 22, 0],
+				"cubes": [
+					{"origin": [-8, 12, -2], "size": [4, 12, 4], "uv": [40, 16]}
+				]
+			},
+			{
+				"name": "rightItem",
+				"parent": "rightArm",
+				"pivot": [-5.5, 12, -2],
+				"rotation": [90, 0, 0]
+			},
+			{
+				"name": "leftArm",
+				"parent": "torso",
+				"pivot": [5, 22, 0],
+				"cubes": [
+					{"origin": [4, 12, -2], "size": [4, 12, 4], "uv": [40, 16], "mirror": true}
+				]
+			},
+			{
+				"name": "leftItem",
+				"parent": "leftArm",
+				"pivot": [5.5, 12, -2],
+				"rotation": [-90, 180, 0]
+			},
+			{
+				"name": "chest",
+				"parent": "torso",
+				"pivot": [0, 24, 0],
+				"cubes": [
+					{"origin": [-4, 12, -2], "size": [8, 12, 4], "uv": [16, 16]}
+				]
+			}
+		]
+	},
+	"geometry.humanoid.armor.helmet": {
+		"texturewidth": 64,
+		"textureheight": 32,
+		"visible_bounds_width": 3,
+		"visible_bounds_height": 3,
+		"visible_bounds_offset": [0, 1.5, 0],
+		"bones": [
+			{
+				"name": "waist",
+				"pivot": [0, 12, 0]
+			},
+			{
+				"name": "body",
+				"parent": "waist",
+				"pivot": [0, 24, 0]
+			},
+			{
+				"name": "head",
+				"parent": "body",
+				"pivot": [0, 24, 0],
+				"cubes": [
+					{"origin": [-4, 24, -4], "size": [8, 8, 8], "uv": [0, 0]}
+				]
+			}
+		]
 	}
 }
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/entity/models.json b/game/client/src/main/resources/assets/minecraft/models/entity/models.json
index 3149837b7..84f8e7338 100644
--- a/game/client/src/main/resources/assets/minecraft/models/entity/models.json
+++ b/game/client/src/main/resources/assets/minecraft/models/entity/models.json
@@ -75,34 +75,34 @@
         },
         "minecraft:skeleton": {
             "main":"geometry.skeleton",
-            "armor.boots":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.leggings":{"model":"geometry.humanoid.armor", "inflation": 0.5},
-            "armor.chestplate":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.helmet":{"model":"geometry.humanoid.armor", "inflation": 1}
+            "armor.boots":{"model":"geometry.humanoid.armor.boots", "inflation": 1},
+            "armor.leggings":{"model":"geometry.humanoid.armor.leggings", "inflation": 0.5},
+            "armor.chestplate":{"model":"geometry.humanoid.armor.chestplate", "inflation": 1},
+            "armor.helmet":{"model":"geometry.humanoid.armor.helmet", "inflation": 1}
         },
         "minecraft:zombie": {
             "main":"geometry.zombie",
-            "armor.boots":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.leggings":{"model":"geometry.humanoid.armor", "inflation": 0.5},
-            "armor.chestplate":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.helmet":{"model":"geometry.humanoid.armor", "inflation": 1}
+            "armor.boots":{"model":"geometry.humanoid.armor.boots", "inflation": 1},
+            "armor.leggings":{"model":"geometry.humanoid.armor.leggings", "inflation": 0.5},
+            "armor.chestplate":{"model":"geometry.humanoid.armor.chestplate", "inflation": 1},
+            "armor.helmet":{"model":"geometry.humanoid.armor.helmet", "inflation": 1}
         },
         "minecraft:zombie_pigman": {
             "main":"geometry.zombie.pig",
-            "armor.boots":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.leggings":{"model":"geometry.humanoid.armor", "inflation": 0.5},
-            "armor.chestplate":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.helmet":{"model":"geometry.humanoid.armor", "inflation": 1}
+            "armor.boots":{"model":"geometry.humanoid.armor.boots", "inflation": 1},
+            "armor.leggings":{"model":"geometry.humanoid.armor.leggings", "inflation": 0.5},
+            "armor.chestplate":{"model":"geometry.humanoid.armor.chestplate", "inflation": 1},
+            "armor.helmet":{"model":"geometry.humanoid.armor.helmet", "inflation": 1}
         },
         "minecraft:snowman": {
             "main":"geometry.zombie"
         },
         "minecraft:zombie_armored": {
             "main":"geometry.zombie",
-            "armor.boots":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.leggings":{"model":"geometry.humanoid.armor", "inflation": 0.5},
-            "armor.chestplate":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.helmet":{"model":"geometry.humanoid.armor", "inflation": 1}
+            "armor.boots":{"model":"geometry.humanoid.armor.boots", "inflation": 1},
+            "armor.leggings":{"model":"geometry.humanoid.armor.leggings", "inflation": 0.5},
+            "armor.chestplate":{"model":"geometry.humanoid.armor.chestplate", "inflation": 1},
+            "armor.helmet":{"model":"geometry.humanoid.armor.helmet", "inflation": 1}
         },
         "minecraft:slime": {
             "main":"geometry.slime"
@@ -113,23 +113,24 @@
             "arms":"geometry.player.base.steve.arms",
             "arms.slim":"geometry.player.base.alex.arms",
             "cape":"geometry.player.cape",
-            "armor.boots":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.leggings":{"model":"geometry.humanoid.armor", "inflation": 0.5},
-            "armor.chestplate":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.helmet":{"model":"geometry.humanoid.armor", "inflation": 1}
+            "armor.boots":{"model":"geometry.humanoid.armor.boots", "inflation": 1},
+            "armor.leggings":{"model":"geometry.humanoid.armor.leggings", "inflation": 0.5},
+            "armor.chestplate":{"model":"geometry.humanoid.armor.chestplate", "inflation": 1},
+            "armor.helmet":{"model":"geometry.humanoid.armor.helmet", "inflation": 1}
         },
         "minecraft:human": {
             "main":"geometry.player.base.steve",
+            "main.slim":"geometry.player.base.alex",
             "arms":"geometry.player.base.steve.arms",
             "arms.slim":"geometry.player.base.alex.arms",
             "cape":"geometry.player.cape"
         },
         "minecraft:giant": {
             "main":"geometry.zombie",
-            "armor.boots":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.leggings":{"model":"geometry.humanoid.armor", "inflation": 0.5},
-            "armor.chestplate":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.helmet":{"model":"geometry.humanoid.armor", "inflation": 1}
+            "armor.boots":{"model":"geometry.humanoid.armor.boots", "inflation": 1},
+            "armor.leggings":{"model":"geometry.humanoid.armor.leggings", "inflation": 0.5},
+            "armor.chestplate":{"model":"geometry.humanoid.armor.chestplate", "inflation": 1},
+            "armor.helmet":{"model":"geometry.humanoid.armor.helmet", "inflation": 1}
         },
         "minecraft:ghast": {
             "main":"geometry.ghast"
@@ -159,10 +160,10 @@
         "minecraft:statue_stone": {
             "main":"geometry.player.base.steve",
             "main.pigman":"geometry.pigman",
-            "armor.boots":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.leggings":{"model":"geometry.humanoid.armor", "inflation": 0.5},
-            "armor.chestplate":{"model":"geometry.humanoid.armor", "inflation": 1},
-            "armor.helmet":{"model":"geometry.humanoid.armor", "inflation": 1}
+            "armor.boots":{"model":"geometry.humanoid.armor.boots", "inflation": 1},
+            "armor.leggings":{"model":"geometry.humanoid.armor.leggings", "inflation": 0.5},
+            "armor.chestplate":{"model":"geometry.humanoid.armor.chestplate", "inflation": 1},
+            "armor.helmet":{"model":"geometry.humanoid.armor.helmet", "inflation": 1}
         }
     }
 }
\ No newline at end of file
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java
index 2b27ba2b2..983adec37 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java
@@ -61,7 +61,7 @@ public class BlockLogicCactus
         }
     }
 
-    private void growCactusOnTop(final @NotNull World world, final @NotNull TilePosc tilePos) {
+    private boolean growCactusOnTop(final @NotNull World world, final @NotNull TilePosc tilePos) {
         final @NotNull TilePos offsetPos = new TilePos(tilePos);
 
         offsetPos.y = tilePos.y() + 1;
@@ -71,7 +71,9 @@ public class BlockLogicCactus
 
         if (world.isAirBlock(offsetPos)) {
             world.setBlockTypeNotify(offsetPos, this.block);
+            return true;
         }
+        return false;
     }
 
     @Override
@@ -138,11 +140,8 @@ public class BlockLogicCactus
 
     @Override
     public boolean onBonemealUsed(final @NotNull ItemStack itemStack, final @Nullable Player player, final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
-        if (!world.isClientSide) {
-            this.growCactusOnTop(world, tilePos);
-            if (player == null || player.getGamemode().hasBlockConsumption()) {
-                itemStack.stackSize--;
-            }
+        if (!world.isClientSide && this.growCactusOnTop(world, tilePos)) {
+            itemStack.consumeItem(player);
         }
         return true;
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/Blocks.java b/game/core/src/main/java/net/minecraft/core/block/Blocks.java
index 95ac8901b..a4d30ebe9 100644
--- a/game/core/src/main/java/net/minecraft/core/block/Blocks.java
+++ b/game/core/src/main/java/net/minecraft/core/block/Blocks.java
@@ -46,83 +46,83 @@ public final class Blocks {
         .withTags(BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> STONE = register("stone", "minecraft:block/stone", 1, (b) -> new BlockLogicStone(b, Blocks.COBBLE_STONE, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BASALT = register("basalt", "minecraft:block/basalt", 2, (b) -> new BlockLogicStone(b, Blocks.COBBLE_BASALT, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> LIMESTONE = register("limestone", "minecraft:block/limestone", 3, (b) -> new BlockLogicStone(b, Blocks.COBBLE_LIMESTONE, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> GRANITE = register("granite", "minecraft:block/granite", 4, (b) -> new BlockLogicStone(b, Blocks.COBBLE_GRANITE, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> MARBLE = register("marble", "minecraft:block/marble", 5, (b) -> new BlockLogic(b, Materials.MARBLE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange()
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> SLATE = register("slate", "minecraft:block/slate", 6, (b) -> new BlockLogic(b, Materials.SLATE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> PERMAFROST = register("permafrost", "minecraft:block/permafrost", 7, (b) -> new BlockLogicStone(b, Blocks.COBBLE_PERMAFROST, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<?> COBBLE_STONE = register("cobble.stone", "minecraft:block/cobble_stone", 10, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> COBBLE_STONE_MOSSY = register("cobble.stone.mossy", "minecraft:block/cobble_stone_mossy", 11, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS);
     public static final @NotNull Block<?> COBBLE_BASALT = register("cobble.basalt", "minecraft:block/cobble_basalt", 12, (b) -> new BlockLogicCobble(b, Materials.BASALT, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> COBBLE_LIMESTONE = register("cobble.limestone", "minecraft:block/cobble_limestone", 13, (b) -> new BlockLogicCobble(b, Materials.LIMESTONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> COBBLE_GRANITE = register("cobble.granite", "minecraft:block/cobble_granite", 14, (b) -> new BlockLogicCobble(b, Materials.GRANITE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> COBBLE_PERMAFROST = register("cobble.permafrost", "minecraft:block/cobble_permafrost", 15, (b) -> new BlockLogicCobble(b, Materials.PERMAFROST, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.PERMAFROST).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> COBBLE_BASALT_MOSSY = register("cobble.basalt.mossy", "minecraft:block/cobble_basalt_mossy", 16, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS);
     public static final @NotNull Block<?> COBBLE_LIMESTONE_MOSSY = register("cobble.limestone.mossy", "minecraft:block/cobble_limestone_mossy", 17, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS);
     public static final @NotNull Block<?> COBBLE_GRANITE_MOSSY = register("cobble.granite.mossy", "minecraft:block/cobble_granite_mossy", 18, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS);
 
     public static final @NotNull Block<?> PILLAR_MARBLE = register("pillar.marble", "minecraft:block/pillar_marble", 20, (b) -> new BlockLogicAxisAligned(b, Materials.MARBLE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> CAPSTONE_MARBLE = register("capstone.marble", "minecraft:block/capstone_marble", 21, (b) -> new BlockLogic(b, Materials.MARBLE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<?> SANDSTONE = register("sandstone", "minecraft:block/sandstone", 30, (b) -> new BlockLogicSandstone(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(0.8F).withOverrideColor(MaterialColor.sand)
-        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<?> STONE_CARVED = register("stone.carved", "minecraft:block/stone_carved", 40, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
-        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> GRANITE_CARVED = register("granite.carved", "minecraft:block/granite_carved", 41, (b) -> new BlockLogic(b, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
-        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> LIMESTONE_CARVED = register("limestone.carved", "minecraft:block/limestone_carved", 42, (b) -> new BlockLogic(b, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
-        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BASALT_CARVED = register("basalt.carved", "minecraft:block/basalt_carved", 43, (b) -> new BlockLogic(b, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
-        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> PERMAFROST_CARVED = register("permafrost.carved", "minecraft:block/permafrost_carved", 44, (b) -> new BlockLogic(b, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
-        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> NETHERRACK_CARVED = register("netherrack.carved", "minecraft:block/netherrack_carved", 45, (b) -> new BlockLogic(b, Materials.NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.4F).withBlastResistance(1F).withDisabledStats()
-        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<?> PLANKS_OAK = register("planks.oak", "minecraft:block/planks_oak", 50, BlockLogicPlanks::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange()
@@ -172,49 +172,49 @@ public final class Blocks {
 
     public static final @NotNull Block<?> BRICK_CLAY = register("brick.clay", "minecraft:block/brick_clay", 120, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3.0F).withBlastResistance(10F).withOverrideColor(MaterialColor.brick)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_STONE_POLISHED = register("brick.stone.polished", "minecraft:block/brick_stone_polished", 121, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_STONE_POLISHED_MOSSY = register("brick.stone.polished.mossy", "minecraft:block/brick_stone_polished_mossy", 122, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(2F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS);
     public static final @NotNull Block<?> BRICK_SANDSTONE = register("brick.sandstone", "minecraft:block/brick_sandstone", 123, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(0.8F).withBlastResistance(10F).withOverrideColor(MaterialColor.sand)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_GOLD = register("brick.gold", "minecraft:block/brick_gold", 124, (b) -> new BlockLogic(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.gold)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_LAPIS = register("brick.lapis", "minecraft:block/brick_lapis", 125, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.lapis)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_BASALT = register("brick.basalt", "minecraft:block/brick_basalt", 126, (b) -> new BlockLogic(b, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_LIMESTONE = register("brick.limestone", "minecraft:block/brick_limestone", 127, (b) -> new BlockLogic(b, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_GRANITE = register("brick.granite", "minecraft:block/brick_granite", 128, (b) -> new BlockLogic(b, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_MARBLE = register("brick.marble", "minecraft:block/brick_marble", 129, (b) -> new BlockLogic(b, Materials.MARBLE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_SLATE = register("brick.slate", "minecraft:block/brick_slate", 130, (b) -> new BlockLogic(b, Materials.SLATE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_STONE = register("brick.stone", "minecraft:block/brick_stone", 131, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_PERMAFROST = register("brick.permafrost", "minecraft:block/brick_permafrost", 132, (b) -> new BlockLogic(b, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(1.0F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_IRON = register("brick.iron", "minecraft:block/brick_iron", 133, (b) -> new BlockLogic(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(5F).withBlastResistance(10F).withOverrideColor(MaterialColor.iron)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_STEEL = register("brick.steel", "minecraft:block/brick_steel", 134, (b) -> new BlockLogic(b, Materials.STEEL))
         .withSound(BlockSounds.METAL).withHardness(5F).withBlastResistance(2000F).withOverrideColor(MaterialColor.steel)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<BlockLogicSlab> SLAB_PLANKS_OAK = register("slab.planks.oak", "minecraft:block/slab_planks_oak", 140, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlabPaintable(b, Blocks.PLANKS_OAK))
         .withSound(BlockSounds.WOOD).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
@@ -336,7 +336,7 @@ public final class Blocks {
 
     public static final @NotNull Block<?> OBSIDIAN = register("obsidian", "minecraft:block/obsidian", 180, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(10F).withBlastResistance(2000F).withOverrideColor(MaterialColor.paintedBlack).withImmovableFlagSet()
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PISTON_CRUSHING);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.PISTON_CRUSHING);
 
     public static final @NotNull Block<?> GLASS = register("glass", "minecraft:block/glass", 190, (b) -> new BlockLogicGlass(b, Materials.GLASS))
         .withSound(BlockSounds.GLASS).withHardness(0.3F)
@@ -394,16 +394,16 @@ public final class Blocks {
 
     public static final @NotNull Block<?> MOSS_STONE = register("moss.stone", "minecraft:block/moss_stone", 240, (b) -> new BlockLogicMoss(b, Blocks.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
     public static final @NotNull Block<?> MOSS_BASALT = register("moss.basalt", "minecraft:block/moss_basalt", 241, (b) -> new BlockLogicMoss(b, Blocks.BASALT))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
     public static final @NotNull Block<?> MOSS_LIMESTONE = register("moss.limestone", "minecraft:block/moss_limestone", 242, (b) -> new BlockLogicMoss(b, Blocks.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
     public static final @NotNull Block<?> MOSS_GRANITE = register("moss.granite", "minecraft:block/moss_granite", 243, (b) -> new BlockLogicMoss(b, Blocks.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
 
     public static final @NotNull Block<?> SAND = register("sand", "minecraft:block/sand", 250, BlockLogicSand::new)
         .withSound(BlockSounds.SAND).withHardness(0.5F)
@@ -417,10 +417,10 @@ public final class Blocks {
 
     public static final @NotNull Block<?> BEDROCK = register("bedrock", "minecraft:block/bedrock", 260, (b) -> new BlockLogicBedrock(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withSetUnbreakable().withBlastResistance(6000000F).withImmovableFlagSet()
-        .withTags(BlockTags.PISTON_CRUSHING);
+        .withTags(BlockTags.PISTON_CRUSHING, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BONESHALE = register("boneshale", "minecraft:block/boneshale", 261, (b) -> new BlockLogicBoneShale(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(16F).withBlastResistance(6000000F).withImmovableFlagSet()
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NETHER_MOBS_SPAWN);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.NETHER_MOBS_SPAWN);
 
     public static final @NotNull Block<BlockLogicFluid> FLUID_WATER_FLOWING = register("fluid.water.flowing", "minecraft:block/fluid_water_flowing", 270, (BlockLogicSupplier<BlockLogicFluid>) b -> new BlockLogicFluidFlowing(b, Materials.WATER, new FluidWater(), Blocks.FLUID_WATER_STILL))
         .withHardness(100F).withLitInteriorSurface(true).withLightBlock(3).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
@@ -696,37 +696,37 @@ public final class Blocks {
 
     public static final @NotNull Block<?> BLOCK_COAL = register("block.coal", "minecraft:block/block_coal", 430, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.coal)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_IRON = register("block.iron", "minecraft:block/block_iron", 431, (b) -> new BlockLogic(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(5F).withBlastResistance(10F).withOverrideColor(MaterialColor.iron)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_GOLD = register("block.gold", "minecraft:block/block_gold", 432, (b) -> new BlockLogic(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.gold)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_LAPIS = register("block.lapis", "minecraft:block/block_lapis", 433, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).withOverrideColor(MaterialColor.lapis)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_REDSTONE = register("block.redstone", "minecraft:block/block_redstone", 434, (b) -> new BlockLogicRedstone(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(5F).withBlastResistance(10F).withOverrideColor(MaterialColor.redstone)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_DIAMOND = register("block.diamond", "minecraft:block/block_diamond", 435, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(5F).withBlastResistance(10F).withOverrideColor(MaterialColor.diamond)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_NETHER_COAL = register("block.nethercoal", "minecraft:block/block_nethercoal", 436, (b) -> new BlockLogic(b, Materials.NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_STEEL = register("block.steel", "minecraft:block/block_steel", 437, (b) -> new BlockLogic(b, Materials.STEEL))
         .withSound(BlockSounds.METAL).withHardness(5F).withBlastResistance(2000F).withOverrideColor(MaterialColor.steel)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_QUARTZ = register("block.quartz", "minecraft:block/block_quartz", 438, (b) -> new BlockLogic(b, Materials.STEEL))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.quartz)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_OLIVINE = register("block.olivine", "minecraft:block/block_olivine", 439, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.olivine)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BLOCK_CHARCOAL = register("block.charcoal", "minecraft:block/block_charcoal", 440, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.coal)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<BlockLogicWireRedstone> WIRE_REDSTONE = register("wire.redstone", "minecraft:block/wire_redstone", 450, BlockLogicWireRedstone::new)
         .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.DUST_REDSTONE)
@@ -770,10 +770,10 @@ public final class Blocks {
 
     public static final @NotNull Block<BlockLogicMotionSensor> MOTION_SENSOR_IDLE = register("motionsensor.idle", "minecraft:block/motion_sensor_idle", 500, (BlockLogicSupplier<BlockLogicMotionSensor>)(b) -> new BlockLogicMotionSensor(b, false))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.stone)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<BlockLogicMotionSensor> MOTION_SENSOR_ACTIVE = register("motionsensor.active", "minecraft:block/motion_sensor_active", 501, (BlockLogicSupplier<BlockLogicMotionSensor>)(b) -> new BlockLogicMotionSensor(b, true))
         .withSound(BlockSounds.STONE).withLightEmission(0.3F).withHardness(2.0F).withBlastResistance(10F).withOverrideColor(MaterialColor.stone).setStatParent(() -> MOTION_SENSOR_IDLE)
-        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<BlockLogicRepeater> REPEATER_IDLE = register("repeater.idle", "minecraft:block/repeater_idle", 510, (BlockLogicSupplier<BlockLogicRepeater>)b -> new BlockLogicRepeater(b, false))
         .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.REPEATER)
@@ -898,10 +898,10 @@ public final class Blocks {
 
     public static final @NotNull Block<?> MESH = register("mesh", "minecraft:block/mesh", 600, BlockLogicMesh::new)
         .withSound(BlockSounds.METAL).withHardness(1.5F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CAN_HANG_OFF);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.CAN_HANG_OFF);
     public static final @NotNull Block<?> MESH_GOLD = register("mesh.gold", "minecraft:block/mesh_gold", 601, BlockLogicMeshGold::new)
         .withSound(BlockSounds.METAL).withHardness(1F).withOverrideColor(MaterialColor.gold)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CAN_HANG_OFF);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.CAN_HANG_OFF);
 
     public static final @NotNull Block<BlockLogicBed> BED = register("bed", "minecraft:block/bed", 610, (BlockLogicSupplier<BlockLogicBed>)BlockLogicBed::new)
         .withSound(BlockSounds.WOOD).withHardness(0.2F).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true).setStatParent(() -> Items.BED)
@@ -1067,16 +1067,16 @@ public final class Blocks {
 
     public static final @NotNull Block<?> COBBLE_NETHERRACK = register("cobble.netherrack", "minecraft:block/cobble_netherrack", 800, (b) -> new BlockLogicCobble(b, Materials.NETHERRACK, null))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
     public static final @NotNull Block<?> COBBLE_NETHERRACK_IGNEOUS = register("cobble.netherrack.igneous", "minecraft:block/cobble_netherrack_igneous", 801, BlockLogicNetherrackIgneous::new)
         .withSound(BlockSounds.STONE).withHardness(1.25F).withBlastResistance(7F).withLightEmission(10)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> COBBLE_NETHERRACK_MOSSY = register("cobble.netherrack.mossy", "minecraft:block/cobble_netherrack_mossy", 802, (b) -> new BlockLogicCobble(b, Materials.NETHERRACK, null))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.INFINITE_BURN);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS, BlockTags.INFINITE_BURN);
     public static final @NotNull Block<?> NETHERRACK = register("netherrack", "minecraft:block/netherrack", 803, (b) -> new BlockLogicStone(b, Blocks.COBBLE_NETHERRACK, Materials.NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.32F)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
     public static final @NotNull Block<?> BRICK_NETHERRACK = register("brick.netherrack", "minecraft:block/brick_netherrack", 804, (b) -> new BlockLogic(b, Materials.NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
@@ -1101,11 +1101,11 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN, BlockTags.INFINITE_BURN_COLD);
     public static final @NotNull Block<?> SOULSCHIST = register("soulschist", "minecraft:block/soulschist", 811, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.SOULSAND))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F).withOverrideColor(MaterialColor.paintedBrown)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NETHER_MOBS_SPAWN);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.NETHER_MOBS_SPAWN);
 
     public static final @NotNull Block<?> GLOWSTONE = register("glowstone", "minecraft:block/glowstone", 820, (b) -> new BlockLogicGlowStone(b, Materials.STONE))
         .withSound(BlockSounds.GLASS).withHardness(0.3F).withLightEmission(1.0F).withOverrideColor(MaterialColor.paintedYellow)
-        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> CRYSTAL = register("crystal", "minecraft:block/crystal", 821, (b) -> new BlockLogicCrystal(b))
         .withSound(BlockSounds.GLASS).withLightEmission(0.8F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
@@ -1147,25 +1147,25 @@ public final class Blocks {
 
     public static final @NotNull Block<?> STONE_POLISHED = register("stone.polished", "minecraft:block/stone_polished", 860, (b) -> new BlockLogic(b, Materials.STONE))
             .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> GRANITE_POLISHED = register("granite.polished", "minecraft:block/granite_polished", 861, (b) -> new BlockLogic(b, Materials.GRANITE))
             .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> LIMESTONE_POLISHED = register("limestone.polished", "minecraft:block/limestone_polished", 862, (b) -> new BlockLogic(b, Materials.LIMESTONE))
             .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BASALT_POLISHED = register("basalt.polished", "minecraft:block/basalt_polished", 863, (b) -> new BlockLogic(b, Materials.BASALT))
             .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> SLATE_POLISHED = register("slate.polished", "minecraft:block/slate_polished", 864, (b) -> new BlockLogic(b, Materials.SLATE))
             .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> PERMAFROST_POLISHED = register("permafrost.polished", "minecraft:block/permafrost_polished", 865, (b) -> new BlockLogic(b, Materials.PERMAFROST))
             .withSound(BlockSounds.PERMAFROST).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> NETHERRACK_POLISHED = register("netherrack.polished", "minecraft:block/netherrack_polished", 866, (b) -> new BlockLogic(b, Materials.NETHERRACK))
             .withSound(BlockSounds.STONE).withHardness(0.4F).withDisabledNeighborNotifyOnMetadataChange()
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<?> LANTERN_FIREFLY_GREEN = register("lantern.firefly.green", "minecraft:block/lantern_firefly_green", 870,
         (b) -> new BlockLogicLanternFirefly(b, MobFireflyCluster.FireflyColor.GREEN, () -> Items.LANTERN_FIREFLY_GREEN))
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
index af2b60b1d..2aa273d5b 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
@@ -66,30 +66,30 @@ public class TileEntityTrommel extends TileEntity
     @Override
 	public int getContainerSize()
     {
-        return itemStacks.length;
+        return this.itemStacks.length;
     }
 
     @Override
 	public @Nullable ItemStack getItem(int slot)
     {
-        return itemStacks[slot];
+        return this.itemStacks[slot];
     }
 
     @Override
 	public @Nullable ItemStack removeItem(int slot, int takeAmount)
     {
-        if(itemStacks[slot] != null)
+        if(this.itemStacks[slot] != null)
         {
-            if(itemStacks[slot].stackSize <= takeAmount)
+            if(this.itemStacks[slot].stackSize <= takeAmount)
             {
-                ItemStack itemstack = itemStacks[slot];
-                itemStacks[slot] = null;
+                ItemStack itemstack = this.itemStacks[slot];
+                this.itemStacks[slot] = null;
                 return itemstack;
             }
-            ItemStack itemstack1 = itemStacks[slot].splitStack(takeAmount);
-            if(itemStacks[slot].stackSize <= 0)
+            ItemStack itemstack1 = this.itemStacks[slot].splitStack(takeAmount);
+            if(this.itemStacks[slot].stackSize <= 0)
             {
-                itemStacks[slot] = null;
+                this.itemStacks[slot] = null;
             }
             return itemstack1;
         } else
@@ -101,7 +101,7 @@ public class TileEntityTrommel extends TileEntity
     @Override
 	public void setItem(int slot, @Nullable ItemStack stack)
     {
-        itemStacks[slot] = stack;
+        this.itemStacks[slot] = stack;
         if(stack != null && stack.stackSize > getMaxStackSize())
         {
             stack.stackSize = getMaxStackSize();
@@ -118,35 +118,35 @@ public class TileEntityTrommel extends TileEntity
 	public void readAdditionalData(@NotNull CompoundTag compoundTag)
     {
         ListTag nbttaglist = compoundTag.getList("Items");
-        itemStacks = new ItemStack[getContainerSize()];
+        this.itemStacks = new ItemStack[getContainerSize()];
         for(int i = 0; i < nbttaglist.tagCount(); i++)
         {
             CompoundTag nbttagcompound1 = (CompoundTag)nbttaglist.tagAt(i);
             byte byte0 = nbttagcompound1.getByte("Slot");
-            if(byte0 >= 0 && byte0 < itemStacks.length)
+            if(byte0 >= 0 && byte0 < this.itemStacks.length)
             {
-                itemStacks[byte0] = ItemStack.readItemStackFromNbt(nbttagcompound1);
+                this.itemStacks[byte0] = ItemStack.readItemStackFromNbt(nbttagcompound1);
             }
         }
 
-        burnTime = compoundTag.getShort("BurnTime");
-        itemPopTime = compoundTag.getShort("CookTime");
-        currentItemBurnTime = getItemBurnTime(itemStacks[SLOT_FUEL]);
+        this.burnTime = compoundTag.getShort("BurnTime");
+        this.itemPopTime = compoundTag.getShort("CookTime");
+        this.currentItemBurnTime = getItemBurnTime(this.itemStacks[SLOT_FUEL]);
     }
 
     @Override
     public void writeAdditionalData(@NotNull CompoundTag compoundTag)
     {
-        compoundTag.putShort("BurnTime", (short) burnTime);
-        compoundTag.putShort("CookTime", (short) itemPopTime);
+        compoundTag.putShort("BurnTime", (short) this.burnTime);
+        compoundTag.putShort("CookTime", (short) this.itemPopTime);
         ListTag nbttaglist = new ListTag();
-        for(int i = 0; i < itemStacks.length; i++)
+        for(int i = 0; i < this.itemStacks.length; i++)
         {
-            if(itemStacks[i] != null)
+            if(this.itemStacks[i] != null)
             {
                 CompoundTag nbttagcompound1 = new CompoundTag();
                 nbttagcompound1.putByte("Slot", (byte)i);
-                itemStacks[i].writeToNBT(nbttagcompound1);
+                this.itemStacks[i].writeToNBT(nbttagcompound1);
                 nbttaglist.addTag(nbttagcompound1);
             }
         }
@@ -162,98 +162,98 @@ public class TileEntityTrommel extends TileEntity
 
     public float getCookProgressPercent(int i)
     {
-        return ((float)itemPopTime / MAX_BURN_TIME) *i;
+        return ((float) this.itemPopTime / MAX_BURN_TIME) *i;
     }
 
     public int getBurnTimeRemainingScaled(int i)
     {
-        if(currentItemBurnTime == 0)
+        if(this.currentItemBurnTime == 0)
         {
-            currentItemBurnTime = MAX_BURN_TIME;
+            this.currentItemBurnTime = MAX_BURN_TIME;
         }
-        return (burnTime * i) / currentItemBurnTime;
+        return (this.burnTime * i) / this.currentItemBurnTime;
     }
 
     public boolean isBurning()
     {
-        return burnTime > 0;
+        return this.burnTime > 0;
     }
 
     @Override
 	public void tick()
     {
-        boolean isClient = worldObj == null ? carriedBlock.holder.world.isClientSide : worldObj.isClientSide;
-        if(nextToSieve >= SLOTS_INGREDIENT.length) {
-            nextToSieve = 0;
+        boolean isClient = this.worldObj == null ? this.carriedBlock.holder.world.isClientSide : this.worldObj.isClientSide;
+        if(this.nextToSieve >= SLOTS_INGREDIENT.length) {
+            this.nextToSieve = 0;
         }
-        boolean isBurning = burnTime > 0;
+        boolean isBurning = this.burnTime > 0;
         boolean flag1 = false;
         if(isBurning)
         {
-            burnTime--;
+            this.burnTime--;
         }
         if(!isClient)
         {
-        	if(worldObj == null || worldObj.getBlockId(x, y, z) == Blocks.TROMMEL_IDLE.id()) {
-            	if(currentItemBurnTime == 0 && itemStacks[SLOTS_INGREDIENT[0]] == null && itemStacks[SLOTS_INGREDIENT[1]] == null && itemStacks[SLOTS_INGREDIENT[2]] == null && itemStacks[SLOTS_INGREDIENT[3]] == null) {
-            		if(itemStacks[SLOT_FUEL] != null && itemStacks[SLOT_FUEL].itemID == Blocks.COBBLE_NETHERRACK.id()) {
-            			itemStacks[SLOT_FUEL].stackSize--;
-            			if(itemStacks[SLOT_FUEL].stackSize <= 0) {
-                            itemStacks[SLOT_FUEL] = null;
+        	if(this.worldObj == null || this.worldObj.getBlockId(this.x, this.y, this.z) == Blocks.TROMMEL_IDLE.id()) {
+            	if(this.currentItemBurnTime == 0 && this.itemStacks[SLOTS_INGREDIENT[0]] == null && this.itemStacks[SLOTS_INGREDIENT[1]] == null && this.itemStacks[SLOTS_INGREDIENT[2]] == null && this.itemStacks[SLOTS_INGREDIENT[3]] == null) {
+            		if(this.itemStacks[SLOT_FUEL] != null && this.itemStacks[SLOT_FUEL].itemID == Blocks.COBBLE_NETHERRACK.id()) {
+                        this.itemStacks[SLOT_FUEL].stackSize--;
+            			if(this.itemStacks[SLOT_FUEL].stackSize <= 0) {
+                            this.itemStacks[SLOT_FUEL] = null;
                         }
-            			if (worldObj != null) {
-                            BlockLogicTrommel.updateTrommelBlockState(worldObj, new TilePos(x, y, z), true);
-                        } else if (carriedBlock != null) {
-                            carriedBlock.blockId = Blocks.TROMMEL_ACTIVE.id();
+            			if (this.worldObj != null) {
+                            BlockLogicTrommel.updateTrommelBlockState(this.worldObj, new TilePos(this.x, this.y, this.z), true);
+                        } else if (this.carriedBlock != null) {
+                            this.carriedBlock.blockId = Blocks.TROMMEL_ACTIVE.id();
                         }
                         flag1 = true;
                     }
             	}
         	}
-            if(!canProduce(SLOTS_INGREDIENT[nextToSieve])) {
-                nextToSieve = (nextToSieve + 1) % SLOTS_INGREDIENT.length;
+            if(!canProduce(SLOTS_INGREDIENT[this.nextToSieve])) {
+                this.nextToSieve = (this.nextToSieve + 1) % SLOTS_INGREDIENT.length;
             }
-            if(burnTime == 0 && canProduce(SLOTS_INGREDIENT[nextToSieve]))
+            if(this.burnTime == 0 && canProduce(SLOTS_INGREDIENT[this.nextToSieve]))
             {
-                currentItemBurnTime = burnTime = getItemBurnTime(itemStacks[SLOT_FUEL]);
-                if(burnTime > 0)
+                this.currentItemBurnTime = this.burnTime = getItemBurnTime(this.itemStacks[SLOT_FUEL]);
+                if(this.burnTime > 0)
                 {
                     flag1 = true;
-                    if(itemStacks[SLOT_FUEL] != null)
+                    if(this.itemStacks[SLOT_FUEL] != null)
                     {
-                    	if(itemStacks[SLOT_FUEL].getItem() == Items.BUCKET_LAVA) {
-                    		itemStacks[SLOT_FUEL] = new ItemStack(Items.BUCKET);
+                    	if(this.itemStacks[SLOT_FUEL].getItem() == Items.BUCKET_LAVA) {
+                            this.itemStacks[SLOT_FUEL] = new ItemStack(Items.BUCKET);
                     	}else {
-                            itemStacks[SLOT_FUEL].stackSize--;
-                            if(itemStacks[SLOT_FUEL].stackSize <= 0)
+                            this.itemStacks[SLOT_FUEL].stackSize--;
+                            if(this.itemStacks[SLOT_FUEL].stackSize <= 0)
                             {
-                                itemStacks[SLOT_FUEL] = null;
+                                this.itemStacks[SLOT_FUEL] = null;
                             }
                     	}
                     }
                 }
             }
-            if(isBurning() && canProduce(SLOTS_INGREDIENT[nextToSieve]))
+            if(isBurning() && canProduce(SLOTS_INGREDIENT[this.nextToSieve]))
             {
-                itemPopTime++;
-                if(itemPopTime >= MAX_BURN_TIME)
+                this.itemPopTime++;
+                if(this.itemPopTime >= MAX_BURN_TIME)
                 {
-                    itemPopTime = 0;
-                    sieveItem(SLOTS_INGREDIENT[nextToSieve]);
-                    nextToSieve = (nextToSieve + 1) % SLOTS_INGREDIENT.length;
+                    this.itemPopTime = 0;
+                    sieveItem(SLOTS_INGREDIENT[this.nextToSieve]);
+                    this.nextToSieve = (this.nextToSieve + 1) % SLOTS_INGREDIENT.length;
                     flag1 = true;
                 }
             } else
             {
-                itemPopTime = 0;
+                this.itemPopTime = 0;
             }
-            if(isBurning != (burnTime > 0))
+            if(isBurning != (this.burnTime > 0))
             {
                 flag1 = true;
-                if (worldObj != null) {
-                    BlockLogicTrommel.updateTrommelBlockState(worldObj, new TilePos(x, y, z), burnTime > 0);
-                } else if (carriedBlock != null) {
-                    carriedBlock.blockId = burnTime > 0 ? Blocks.TROMMEL_ACTIVE.id() : Blocks.TROMMEL_IDLE.id();
+                if (this.worldObj != null) {
+                    BlockLogicTrommel.updateTrommelBlockState(this.worldObj, new TilePos(this.x, this.y, this.z), this.burnTime > 0);
+                } else if (this.carriedBlock != null) {
+                    this.carriedBlock.blockId = this.burnTime > 0 ? Blocks.TROMMEL_ACTIVE.id() : Blocks.TROMMEL_IDLE.id();
                 }
             }
         }
@@ -265,7 +265,7 @@ public class TileEntityTrommel extends TileEntity
 
     private boolean canProduce(int slotIndex)
     {
-        return itemStacks[slotIndex] != null && canItemBeTrommeled(itemStacks[slotIndex]);
+        return this.itemStacks[slotIndex] != null && canItemBeTrommeled(this.itemStacks[slotIndex]);
     }
 
     public void sieveItem(int slotIndex)
@@ -275,41 +275,42 @@ public class TileEntityTrommel extends TileEntity
             return;
         }
         ItemStack itemResult;
-        itemResult = getItemResult(itemStacks[slotIndex]);
+        itemResult = getItemResult(this.itemStacks[slotIndex]);
 
-        itemStacks[slotIndex].stackSize--;
-        if (itemStacks[slotIndex].stackSize <= 0) {
-            itemStacks[slotIndex] = null;
+        this.itemStacks[slotIndex].stackSize--;
+        if (this.itemStacks[slotIndex].stackSize <= 0) {
+            this.itemStacks[slotIndex] = null;
         }
+        Direction direction = Direction.NONE;
+        if (this.worldObj != null) {
+            // 90-degree rotation CCW around the y-axis to get the direction of the output slot
+            switch (BlockLogicRotatable.getDirectionFromMeta(this.worldObj.getBlockMetadata(this.x, this.y, this.z))) {
+                case NORTH: {
+                    direction = Direction.WEST;
+                    break;
+                }
+                case SOUTH: {
+                    direction = Direction.EAST;
+                    break;
+                }
+                case WEST: {
+                    direction = Direction.SOUTH;
+                    break;
+                }
+                case EAST: {
+                    direction = Direction.NORTH;
+                    break;
+                }
+            }
+        }
+
         if(itemResult!=null)
         {
         	// Check if chest is adjacent
-            Direction direction = Direction.NONE;
-        	if (worldObj != null) {
-                // 90-degree rotation CCW around the y-axis to get the direction of the output slot
-                switch (BlockLogicRotatable.getDirectionFromMeta(worldObj.getBlockMetadata(x, y, z))) {
-                    case NORTH: {
-                        direction = Direction.WEST;
-                        break;
-                    }
-                    case SOUTH: {
-                        direction = Direction.EAST;
-                        break;
-                    }
-                    case WEST: {
-                        direction = Direction.SOUTH;
-                        break;
-                    }
-                    case EAST: {
-                        direction = Direction.NORTH;
-                        break;
-                    }
-                }
-            }
-        	int adjacentId = worldObj != null ? worldObj.getBlockId(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ()) : 0;
 
-        	if (worldObj != null && Block.hasLogicClass(Blocks.blocksList[adjacentId], BlockLogicChest.class)) {
-                Container chest = BlockLogicChest.getInventory(worldObj, new TilePos(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ()));
+        	int adjacentId = this.worldObj != null ? this.worldObj.getBlockId(this.x + direction.getOffsetX(), this.y + direction.getOffsetY(), this.z + direction.getOffsetZ()) : 0;
+        	if (this.worldObj != null && Block.hasLogicClass(Blocks.blocksList[adjacentId], BlockLogicChest.class)) {
+                Container chest = BlockLogicChest.getInventory(this.worldObj, new TilePos(this.x + direction.getOffsetX(), this.y + direction.getOffsetY(), this.z + direction.getOffsetZ()));
 
                 for (int i = 0; i < chest.getContainerSize(); i++)
                 {
@@ -338,30 +339,42 @@ public class TileEntityTrommel extends TileEntity
         	}
 
             if(itemResult.stackSize > 0) {
-                if (worldObj != null) {
-                    worldObj.dropItem(x, y, z, itemResult);
-                } else if (carriedBlock != null) {
-                    carriedBlock.world.dropItem(MathHelper.floor(carriedBlock.holder.x), MathHelper.floor(carriedBlock.holder.y), MathHelper.floor(carriedBlock.holder.z), itemResult);
+                if (this.worldObj != null) {
+                    if (this.worldObj.isAirBlock(new TilePos(this.x, this.y, this.z).add(direction))) {
+                        EntityItem droppedItem = new EntityItem(this.worldObj, this.x + 0.5 + direction.getOffsetX() * 0.5, this.y + 0.5 + direction.getOffsetY() * 0.5, this.z + 0.5 + direction.getOffsetZ() * 0.5, itemResult);
+                        droppedItem.pickupDelay = 10;
+                        droppedItem.fling(direction.getOffsetX() * 0.3125, direction.getOffsetY() * 0.3125, direction.getOffsetZ() * 0.3125, 1);
+                        this.worldObj.entityJoinedWorld(droppedItem);
+                    } else {
+                        this.worldObj.dropItem(this.x, this.y, this.z, itemResult);
+                    }
+                } else if (this.carriedBlock != null) {
+                    this.carriedBlock.world.dropItem(MathHelper.floor(this.carriedBlock.holder.x), MathHelper.floor(this.carriedBlock.holder.y), MathHelper.floor(this.carriedBlock.holder.z), itemResult);
                 }
 
             }
         }
-        if(random.nextInt(4000)==0) {
+        if(this.random.nextInt(4000)==0) {
 
             float f = (((float) 1 - 0.5F)) / 4F;
             float f1 = (((float) 1 - 0.5F)) / 4F;
-            MobSlime mobSlime = new MobSlime(carriedBlock != null ? carriedBlock.world : worldObj);
+            MobSlime mobSlime = new MobSlime(this.carriedBlock != null ? this.carriedBlock.world : this.worldObj);
             mobSlime.setSlimeSize(1);
             float f3 = 0.05F;
-            mobSlime.xd = (float) random.nextGaussian() * f3;
-            mobSlime.yd = (float) random.nextGaussian() * f3 + 0.2F;
-            mobSlime.zd = (float) random.nextGaussian() * f3;
-            if (worldObj != null) {
-                mobSlime.moveTo(x + (double)f, y + 1D, z + (double)f1, random.nextFloat() * 360F, 0.0F);
-                worldObj.entityJoinedWorld(mobSlime);
-            } else if (carriedBlock != null) {
-                mobSlime.moveTo(carriedBlock.holder.x + (double)f, carriedBlock.holder.y + carriedBlock.holder.heightOffset, carriedBlock.holder.z + (double)f1, random.nextFloat() * 360F, 0.0F);
-                carriedBlock.world.entityJoinedWorld(mobSlime);
+            mobSlime.xd = (float) this.random.nextGaussian() * f3;
+            mobSlime.yd = (float) this.random.nextGaussian() * f3 + 0.2F;
+            mobSlime.zd = (float) this.random.nextGaussian() * f3;
+            if (this.worldObj != null) {
+                if (this.worldObj.isAirBlock(new TilePos(this.x, this.y, this.z).add(direction))) {
+                    mobSlime.moveTo(this.x + 0.5 + direction.getOffsetX(), this.y + 0.5 + direction.getOffsetY(), this.z + 0.5 + direction.getOffsetZ(), this.random.nextFloat() * 360F, 0.0F);
+                    mobSlime.fling(direction.getOffsetX() * 0.75, direction.getOffsetY() * 0.75, direction.getOffsetZ() * 0.75, 1);
+                } else {
+                    mobSlime.moveTo(this.x + (double)f, this.y + 1D, this.z + (double)f1, this.random.nextFloat() * 360F, 0.0F);
+                }
+                this.worldObj.entityJoinedWorld(mobSlime);
+            } else if (this.carriedBlock != null) {
+                mobSlime.moveTo(this.carriedBlock.holder.x + (double)f, this.carriedBlock.holder.y + this.carriedBlock.holder.heightOffset, this.carriedBlock.holder.z + (double)f1, this.random.nextFloat() * 360F, 0.0F);
+                this.carriedBlock.world.entityJoinedWorld(mobSlime);
             }
         }
     }
@@ -402,11 +415,11 @@ public class TileEntityTrommel extends TileEntity
     @Override
 	public boolean stillValid(@NotNull Player player)
     {
-        if(worldObj == null || worldObj.getTileEntity(x, y, z) != this)
+        if(this.worldObj == null || this.worldObj.getTileEntity(this.x, this.y, this.z) != this)
         {
             return false;
         }
-        return player.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
+        return player.distanceToSqr((double) this.x + 0.5D, (double) this.y + 0.5D, (double) this.z + 0.5D) <= 64D;
     }
 
     @Override
@@ -428,23 +441,23 @@ public class TileEntityTrommel extends TileEntity
                     if (itemstack == null) {
                         continue;
                     }
-                    float f = random.nextFloat() * 0.8F + 0.1F;
-                    float f1 = random.nextFloat() * 0.8F + 0.1F;
-                    float f2 = random.nextFloat() * 0.8F + 0.1F;
+                    float f = this.random.nextFloat() * 0.8F + 0.1F;
+                    float f1 = this.random.nextFloat() * 0.8F + 0.1F;
+                    float f2 = this.random.nextFloat() * 0.8F + 0.1F;
                     do {
                         if (itemstack.stackSize <= 0) {
                             continue label0;
                         }
-                        int i1 = random.nextInt(21) + 10;
+                        int i1 = this.random.nextInt(21) + 10;
                         if (i1 > itemstack.stackSize) {
                             i1 = itemstack.stackSize;
                         }
                         itemstack.stackSize -= i1;
                         EntityItem item = new EntityItem(world, (float) x + f, (float) y + f1, (float) z + f2, new ItemStack(itemstack.itemID, i1, itemstack.getMetadata()));
                         float f3 = 0.05F;
-                        item.xd = (float) random.nextGaussian() * f3;
-                        item.yd = (float) random.nextGaussian() * f3 + 0.2F;
-                        item.zd = (float) random.nextGaussian() * f3;
+                        item.xd = (float) this.random.nextGaussian() * f3;
+                        item.yd = (float) this.random.nextGaussian() * f3 + 0.2F;
+                        item.zd = (float) this.random.nextGaussian() * f3;
                         world.entityJoinedWorld(item);
                     } while (true);
                 }
@@ -497,17 +510,17 @@ public class TileEntityTrommel extends TileEntity
         public void addStack(ItemStack stack) {
             if (this.item == null) {
                 assert stack == null : "stack must be null for a null item!";
-                timesOccured++;
+                this.timesOccured++;
             } else {
-                assert item == stack.getItem() : "stack's item must match current item!";
-                timesOccured++;
-                totalItems += stack.stackSize;
+                assert this.item == stack.getItem() : "stack's item must match current item!";
+                this.timesOccured++;
+                this.totalItems += stack.stackSize;
             }
         }
 
         @Override
         public String toString() {
-            return String.format("\t%s - Occurred: %sx - Total Items: %s (%.2f stacks)", item == null ? "NULL" : item.namespaceID, timesOccured, totalItems, totalItems/64f);
+            return String.format("\t%s - Occurred: %sx - Total Items: %s (%.2f stacks)", this.item == null ? "NULL" : this.item.namespaceID, this.timesOccured, this.totalItems, this.totalItems /64f);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java b/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java
index 00c2abe4a..2ceaec495 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java
@@ -232,6 +232,9 @@ public class EntityFallingBlock extends Entity
             tag.getShort("Tile") & 0x3fff,
             tag.getShort("TileData") & 0xff,
             tag.containsKey("TileEntity") ? TileEntityDispatcher.createAndLoadEntity(tag.getCompound("TileEntity")) : null);
+        if (this.carriedBlock.entity != null) {
+            this.carriedBlock.entity.carriedBlock = this.carriedBlock;
+        }
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/helpers/DoubleCoordinate.java b/game/core/src/main/java/net/minecraft/core/net/command/helpers/DoubleCoordinate.java
index d5559c6cd..7ab9bee15 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/helpers/DoubleCoordinate.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/helpers/DoubleCoordinate.java
@@ -28,7 +28,8 @@ public class DoubleCoordinate {
     public static DoubleCoordinate parse(StringReader reader) throws CommandSyntaxException {
         if (!reader.canRead()) throw CommandExceptions.incomplete().createWithContext(reader);
 
-        if (reader.peek() == '~') {
+        char peak = reader.peek();
+        if (peak == '~' || peak == '#') {
             reader.skip();
             if (reader.canRead() && reader.peek() != ' ') {
                 double coordinate = reader.readDouble();
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/helpers/IntegerCoordinate.java b/game/core/src/main/java/net/minecraft/core/net/command/helpers/IntegerCoordinate.java
index 02e3b32b5..0134a3076 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/helpers/IntegerCoordinate.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/helpers/IntegerCoordinate.java
@@ -29,7 +29,8 @@ public class IntegerCoordinate {
     public static IntegerCoordinate parse(StringReader reader) throws CommandSyntaxException {
         if (!reader.canRead()) throw CommandExceptions.incomplete().createWithContext(reader);
 
-        if (reader.peek() == '~') {
+        char peak = reader.peek();
+        if (peak == '~' || peak == '#') {
             reader.skip();
             if (reader.canRead() && reader.peek() != ' ') {
                 int coordinate = reader.readInt();
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketCustomPayload.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketCustomPayload.java
index b815a0073..ca444b787 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketCustomPayload.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketCustomPayload.java
@@ -55,7 +55,7 @@ public class PacketCustomPayload extends Packet {
 		
 		if(length > 0 && length < 32768) {
 			this.data = new byte[length];
-			in.read(data);
+			in.readFully(data);
 		}
 	}
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/ExplosionCannonball.java b/game/core/src/main/java/net/minecraft/core/world/ExplosionCannonball.java
index 7484e458e..79e1b78ca 100644
--- a/game/core/src/main/java/net/minecraft/core/world/ExplosionCannonball.java
+++ b/game/core/src/main/java/net/minecraft/core/world/ExplosionCannonball.java
@@ -1,20 +1,17 @@
 package net.minecraft.core.world;
 
-import net.minecraft.core.block.entity.TileEntity;
-import net.minecraft.core.block.material.Materials;
 import net.minecraft.core.entity.Entity;
+import net.minecraft.core.entity.EntityItem;
 import net.minecraft.core.entity.IArmorWearing;
-import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.MathHelper;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.world.chunk.ChunkPosition;
 import net.minecraft.core.util.helper.DamageType;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.joml.Math;
 import org.joml.Vector3d;
 import org.joml.Vector3dc;
+import org.joml.Vector3f;
 import org.joml.primitives.AABBd;
 
 import java.util.*;
@@ -27,59 +24,13 @@ public class ExplosionCannonball extends Explosion {
 
     @Override
     public void explode() {
-        int i = 16;
-        for (int j = 0; j < i; j++) {
-            for (int l = 0; l < i; l++) {
-                label0:
-                for (int j1 = 0; j1 < i; j1++) {
-                    if (j != 0 && j != i - 1 && l != 0 && l != i - 1 && j1 != 0 && j1 != i - 1) {
-                        continue;
-                    }
-                    double d = ((float) j / ((float) i - 1.0F)) * 2.0F - 1.0F;
-                    double d1 = ((float) l / ((float) i - 1.0F)) * 2.0F - 1.0F;
-                    double d2 = ((float) j1 / ((float) i - 1.0F)) * 2.0F - 1.0F;
-                    double d3 = java.lang.Math.sqrt(d * d + d1 * d1 + d2 * d2);
-                    d /= d3;
-                    d1 /= d3;
-                    d2 /= d3;
-                    float f1 = this.explosionSize * (0.7F + this.world.rand.nextFloat() * 0.6F);
-                    double d5 = this.explosionX;
-                    double d7 = this.explosionY;
-                    double d9 = this.explosionZ;
-                    float f2 = 0.3F;
-                    do {
-                        if (f1 <= 0.0F) {
-                            continue label0;
-                        }
-                        int j4 = MathHelper.floor(d5);
-                        int k4 = MathHelper.floor(d7);
-                        int l4 = MathHelper.floor(d9);
-                        int i5 = this.world.getBlockId(j4, k4, l4);
-                        if (i5 > 0) {
-                            f1 -= (Blocks.blocksList[i5].getBlastResistance(this.exploder) + 0.3F) * f2;
-                        }
-                        if (f1 > 0.0F) {
-                            this.destroyedBlockPositions.add(new ChunkPosition(j4, k4, l4));
-                        }
-                        d5 += d * (double) f2;
-                        d7 += d1 * (double) f2;
-                        d9 += d2 * (double) f2;
-                        f1 -= f2 * 0.75F;
-                    } while (true);
-                }
-
-            }
-
-        }
-
-        this.explosionSize *= 2.0F;
+        this.explosionSize *= 3.0F;
         int minX = MathHelper.floor(this.explosionX - (double) this.explosionSize - 1.0D);
         int maxX = MathHelper.floor(this.explosionX + (double) this.explosionSize + 1.0D);
         int minY = MathHelper.floor(this.explosionY - (double) this.explosionSize - 1.0D);
         int maxY = MathHelper.floor(this.explosionY + (double) this.explosionSize + 1.0D);
         int minZ = MathHelper.floor(this.explosionZ - (double) this.explosionSize - 1.0D);
         int maxZ = MathHelper.floor(this.explosionZ + (double) this.explosionSize + 1.0D);
-//        List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(exploder, AABB.getBoundingBoxFromPool(minX, minY, minZ, maxX, maxY, maxZ));
         List<Entity> list = this.world.getEntitiesWithinAABB(Entity.class, new AABBd(minX, minY, minZ, maxX, maxY, maxZ)); // Cannon balls can explode their owners
         Vector3dc vec3 = new Vector3d(this.explosionX, this.explosionY, this.explosionZ);
         for (int k2 = 0; k2 < list.size(); k2++) {
@@ -87,7 +38,7 @@ public class ExplosionCannonball extends Explosion {
             double d4 = entity.distanceTo(this.explosionX, this.explosionY, this.explosionZ) / (double) this.explosionSize;
             if (d4 <= 1.0D) {
                 double xComp = entity.x - this.explosionX;
-                double yComp = entity.y - this.explosionY;
+                double yComp = (entity.y + entity.bbHeight/2) - this.explosionY;
                 double zComp = entity.z - this.explosionZ;
                 double d11 = MathHelper.sqrt(xComp * xComp + yComp * yComp + zComp * zComp);
                 xComp *= 2.5;
@@ -96,30 +47,16 @@ public class ExplosionCannonball extends Explosion {
                 zComp *= 2.5;
                 double d12 = this.world.getSeenPercent(vec3, entity.bb);
                 double flingForce = (1.0D - d4) * d12;
-                entity.hurt(this.exploder, (int) (((flingForce * flingForce + flingForce) / 2D) * 8D * (double) this.explosionSize + 1.0D), DamageType.BLAST);
-                if (entity instanceof IArmorWearing && entity != this.exploder) {
-                    float proc = 1 - (((IArmorWearing<?>) entity).getTotalProtectionAmount(DamageType.BLAST) / 2f);
+                if (!(entity instanceof EntityItem)) {
+                    entity.hurt(this.exploder, (int) (((flingForce * flingForce + flingForce) / 2D) * 8D * (this.explosionSize * 2d/3d) + 1.0D), DamageType.BLAST);
+                }
+                if (entity instanceof IArmorWearing<?> entArmored && entArmored != this.exploder) {
+                    float proc = 1 - entArmored.getTotalProtectionAmount(DamageType.BLAST) / 2f;
                     flingForce *= proc;
                 }
                 entity.fling(xComp * flingForce, yComp * flingForce, zComp * flingForce, 1);
             }
         }
-
-        ArrayList<ChunkPosition> arraylist = new ArrayList<>(this.destroyedBlockPositions);
-        if (this.isFlaming) {
-            for (int l2 = arraylist.size() - 1; l2 >= 0; l2--) {
-                ChunkPosition chunkposition = arraylist.get(l2);
-                int i3 = chunkposition.x;
-                int j3 = chunkposition.y;
-                int k3 = chunkposition.z;
-                int l3 = this.world.getBlockId(i3, j3, k3);
-                int i4 = this.world.getBlockId(i3, j3 - 1, k3);
-                if (l3 == Blocks.AIR.id() && Blocks.solid[i4] && this.ExplosionRNG.nextInt(3) == 0) {
-                    this.world.setBlockWithNotify(i3, j3, k3, Blocks.FIRE.id());
-                }
-            }
-
-        }
     }
 
     @Override
@@ -127,44 +64,17 @@ public class ExplosionCannonball extends Explosion {
         if (!this.world.isClientSide) {
             this.world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, this.explosionX, this.explosionY, this.explosionZ, "random.explode", 4F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F);
         }
-        ArrayList<ChunkPosition> arraylist = new ArrayList<>(this.destroyedBlockPositions);
-        for (int i = arraylist.size() - 1; i >= 0; i--) {
-            ChunkPosition chunkposition = arraylist.get(i);
-            int x = chunkposition.x;
-            int y = chunkposition.y;
-            int z = chunkposition.z;
-            Block<?> block = this.world.getBlock(x, y, z);
-            TileEntity tileEntity = this.world.getTileEntity(x, y, z);
-            if (particles) {
-                double d = (double) x + this.world.rand.nextFloat();
-                double d1 = (double) y + this.world.rand.nextFloat();
-                double d2 = (double) z + this.world.rand.nextFloat();
-                double d3 = d - this.explosionX;
-                double d4 = d1 - this.explosionY;
-                double d5 = d2 - this.explosionZ;
-                double d6 = MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
-                d3 /= d6;
-                d4 /= d6;
-                d5 /= d6;
-                double d7 = 0.5D / (d6 / (double) this.explosionSize + 0.1D);
-                d7 *= this.world.rand.nextFloat() * this.world.rand.nextFloat() + 0.3F;
-                d3 *= d7;
-                d4 *= d7;
-                d5 *= d7;
-                this.world.spawnParticle("explode", (d + this.explosionX) / 2D, (d1 + this.explosionY) / 2D, (d2 + this.explosionZ) / 2D, d3, d4, d5, 0);
-                this.world.spawnParticle("smoke", d, d1, d2, d3, d4, d5, 0);
+        if (particles) {
+            Vector3d d = new Vector3d(0, 0, 1);
+            for (int i = 0; i < 64; i++) {
+                d.set(0, 0, 0.25);
+                d.rotateY(ExplosionRNG.nextDouble() * Math.PI_TIMES_2);
+                d.rotateX(ExplosionRNG.nextDouble() * Math.PI_TIMES_2);
+                d.mul(1 - ExplosionRNG.nextDouble() * 0.25d);
+                this.world.spawnParticle("explode", this.explosionX + d.x(), this.explosionY + d.y(), this.explosionZ + d.z(), d.x() * 2, d.y() * 2, d.z() * 2, 0);
+                this.world.spawnParticle("smoke", this.explosionX + d.x(), this.explosionY + d.y(), this.explosionZ + d.z(), d.x() * 2, d.y() * 2, d.z() * 2, 0);
             }
-            if (block != null && (block == Blocks.GLASS
-                || block.getMaterial() == Materials.TOP_SNOW
-                || block.getMaterial() == Materials.PLANT
-                || block.getMaterial() == Materials.WEB
-                || block.getMaterial() == Materials.DECORATION
-                || block.getMaterial() == Materials.ICE)) {
-                block.dropBlockWithCause(this.world, EnumDropCause.EXPLOSION, x, y, z, this.world.getBlockMetadata(x, y, z), tileEntity, null);
-                this.world.setBlockWithNotify(x, y, z, 0);
-                block.onBlockDestroyedByExplosion(this.world, x, y, z);
-            }
-        }
 
+        }
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/conversion/ChunkConverter.java b/game/core/src/main/java/net/minecraft/core/world/save/conversion/ChunkConverter.java
index 51130e82b..e91f96377 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/conversion/ChunkConverter.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/conversion/ChunkConverter.java
@@ -124,7 +124,7 @@ public class ChunkConverter
 		@Override
 		public int[] getConversion(int metadata)
 		{
-			if (metadata > metaIds.length) return new int[] { backup, 0 };
+			if (metadata >= metaIds.length) return new int[] { backup, 0 };
 			
 			return new int[] { metaIds[metadata], metaMetas[metadata] };
 		}
