diff --git a/src/common/resources/lang/en_US/tile.lang b/src/common/resources/lang/en_US/tile.lang
index a77fdafdc..84cfc5ae2 100644
--- a/src/common/resources/lang/en_US/tile.lang
+++ b/src/common/resources/lang/en_US/tile.lang
@@ -1 +1 @@
-tile.stone.name=Stone
tile.stone.desc=A block of solid stone.
tile.basalt.name=Basalt
tile.basalt.desc=A block of solid basalt.
tile.limestone.name=Limestone
tile.limestone.desc=A block of solid limestone.
tile.granite.name=Granite
tile.granite.desc=A block of solid granite.
tile.marble.name=Marble
tile.marble.desc=A block of solid marble.
tile.slate.name=Slate
tile.slate.desc=A block of solid slate.
tile.permafrost.name=Permafrost
tile.permafrost.desc=A block of frozen stone.

tile.cobble.stone.name=Cobblestone
tile.cobble.stone.desc=Stone, smashed apart and reconstituted.
tile.cobble.stone.mossy.name=Mossy Cobblestone
tile.cobble.stone.mossy.desc=Cobblestone with added greenery.
tile.cobble.basalt.name=Cobbled Basalt
tile.cobble.basalt.desc=Basalt, smashed apart and reconstituted.
tile.cobble.limestone.name=Cobbled Limestone
tile.cobble.limestone.desc=Limestone, smashed apart and reconstituted.
tile.cobble.granite.name=Cobbled Granite
tile.cobble.granite.desc=Granite, smashed apart and reconstituted.
tile.cobble.permafrost.name=Cobbled Permafrost
tile.cobble.permafrost.desc=Permafrost, smashed apart and reconstituted.

tile.pillar.marble.name=Marble Pillar
tile.pillar.marble.desc=A block of marble engraved into a pillar.
tile.capstone.marble.name=Marble Capstone
tile.capstone.marble.desc=A pillar capstone made of solid marble.

tile.sandstone.name=Sandstone
tile.sandstone.desc=Compacted sand.

tile.stone.carved.name=Carved Stone
tile.stone.carved.desc=Polished Stone with lines hewn through the middle.
tile.granite.carved.name=Carved Granite
tile.granite.carved.desc=Polished Granite with lines hewn through the middle.
tile.limestone.carved.name=Carved Limestone
tile.limestone.carved.desc=Polished Limestone with lines hewn through the middle.
tile.basalt.carved.name=Carved Basalt
tile.basalt.carved.desc=Polished Basalt with lines hewn through the middle.
tile.permafrost.carved.name=Carved Permafrost
tile.permafrost.carved.desc=Polished Permafrost with lines hewn through the middle.
tile.netherrack.carved.name=Carved Netherrack
tile.netherrack.carved.desc=Polished Netherrack with lines hewn through the middle.

tile.planks.oak.name=Wooden Planks
tile.planks.oak.desc=Processed tree insides.
tile.planks.oak.painted.name=Mystery Planks
tile.planks.oak.painted.desc=How did you get this?!
tile.planks.oak.painted.black.name=Black Wooden Planks
tile.planks.oak.painted.black.desc=Wooden planks, stained black.
tile.planks.oak.painted.red.name=Red Wooden Planks
tile.planks.oak.painted.red.desc=Wooden planks, stained red.
tile.planks.oak.painted.green.name=Green Wooden Planks
tile.planks.oak.painted.green.desc=Wooden planks, stained green.
tile.planks.oak.painted.brown.name=Brown Wooden Planks
tile.planks.oak.painted.brown.desc=Wooden planks, stained brown.
tile.planks.oak.painted.blue.name=Blue Wooden Planks
tile.planks.oak.painted.blue.desc=Wooden planks, stained blue.
tile.planks.oak.painted.purple.name=Purple Wooden Planks
tile.planks.oak.painted.purple.desc=Wooden planks, stained purple.
tile.planks.oak.painted.cyan.name=Cyan Wooden Planks
tile.planks.oak.painted.cyan.desc=Wooden planks, stained cyan.
tile.planks.oak.painted.silver.name=Light Gray Wooden Planks
tile.planks.oak.painted.silver.desc=Wooden planks, stained light gray.
tile.planks.oak.painted.gray.name=Gray Wooden Planks
tile.planks.oak.painted.gray.desc=Wooden planks, stained gray.
tile.planks.oak.painted.pink.name=Pink Wooden Planks
tile.planks.oak.painted.pink.desc=Wooden planks, stained pink.
tile.planks.oak.painted.lime.name=Lime Wooden Planks
tile.planks.oak.painted.lime.desc=Wooden planks, stained lime.
tile.planks.oak.painted.yellow.name=Yellow Wooden Planks
tile.planks.oak.painted.yellow.desc=Wooden planks, stained yellow.
tile.planks.oak.painted.lightblue.name=Light Blue Wooden Planks
tile.planks.oak.painted.lightblue.desc=Wooden planks, stained light blue.
tile.planks.oak.painted.magenta.name=Magenta Wooden Planks
tile.planks.oak.painted.magenta.desc=Wooden planks, stained magenta.
tile.planks.oak.painted.orange.name=Orange Wooden Planks
tile.planks.oak.painted.orange.desc=Wooden planks, stained orange.
tile.planks.oak.painted.white.name=White Wooden Planks
tile.planks.oak.painted.white.desc=Wooden planks, stained white.

tile.torch.coal.name=Torch
tile.torch.coal.desc=Helps light the way.

tile.ladder.oak.name=Oak Ladder
tile.ladder.oak.desc=For very rapid vertical movement.

tile.fence.planks.oak.name=Oak Fence
tile.fence.planks.oak.desc=Too tall to jump over.

tile.fence.planks.oak.painted.name=Mystery Wooden Fence
tile.fence.planks.oak.painted.desc=How did you get this?!
tile.fence.planks.oak.painted.black.name=Black Wooden Fence
tile.fence.planks.oak.painted.black.desc=A wooden fence, stained black.
tile.fence.planks.oak.painted.red.name=Red Wooden Fence
tile.fence.planks.oak.painted.red.desc=A wooden fence, stained red.
tile.fence.planks.oak.painted.green.name=Green Wooden Fence
tile.fence.planks.oak.painted.green.desc=A wooden fence, stained green.
tile.fence.planks.oak.painted.brown.name=Brown Wooden Fence
tile.fence.planks.oak.painted.brown.desc=A wooden fence, stained brown.
tile.fence.planks.oak.painted.blue.name=Blue Wooden Fence
tile.fence.planks.oak.painted.blue.desc=A wooden fence, stained blue.
tile.fence.planks.oak.painted.purple.name=Purple Wooden Fence
tile.fence.planks.oak.painted.purple.desc=A wooden fence, stained purple.
tile.fence.planks.oak.painted.cyan.name=Cyan Wooden Fence
tile.fence.planks.oak.painted.cyan.desc=A wooden fence, stained cyan.
tile.fence.planks.oak.painted.silver.name=Light Gray Wooden Fence
tile.fence.planks.oak.painted.silver.desc=A wooden fence, stained light gray.
tile.fence.planks.oak.painted.gray.name=Gray Wooden Fence
tile.fence.planks.oak.painted.gray.desc=A wooden fence, stained gray.
tile.fence.planks.oak.painted.pink.name=Pink Wooden Fence
tile.fence.planks.oak.painted.pink.desc=A wooden fence, stained pink.
tile.fence.planks.oak.painted.lime.name=Lime Wooden Fence
tile.fence.planks.oak.painted.lime.desc=A wooden fence, stained lime.
tile.fence.planks.oak.painted.yellow.name=Yellow Wooden Fence
tile.fence.planks.oak.painted.yellow.desc=A wooden fence, stained yellow.
tile.fence.planks.oak.painted.lightblue.name=Light Blue Wooden Fence
tile.fence.planks.oak.painted.lightblue.desc=A wooden fence, stained light blue.
tile.fence.planks.oak.painted.magenta.name=Magenta Wooden Fence
tile.fence.planks.oak.painted.magenta.desc=A wooden fence, stained magenta.
tile.fence.planks.oak.painted.orange.name=Orange Wooden Fence
tile.fence.planks.oak.painted.orange.desc=A wooden fence, stained orange.
tile.fence.planks.oak.painted.white.name=White Wooden Fence
tile.fence.planks.oak.painted.white.desc=A wooden fence, stained white.

tile.fencegate.planks.oak.name=Wooden Fence Gate
tile.fencegate.planks.oak.desc=Like a door but for fences.

tile.fencegate.planks.oak.painted.name=Mystery Wooden Fence Gate
tile.fencegate.planks.oak.painted.desc=How did you get this?!
tile.fencegate.planks.oak.painted.black.name=Black Wooden Fence Gate
tile.fencegate.planks.oak.painted.black.desc=A wooden fence gate, stained black.
tile.fencegate.planks.oak.painted.red.name=Red Wooden Fence Gate
tile.fencegate.planks.oak.painted.red.desc=A wooden fence gate, stained red.
tile.fencegate.planks.oak.painted.green.name=Green Wooden Fence Gate
tile.fencegate.planks.oak.painted.green.desc=A wooden fence gate, stained green.
tile.fencegate.planks.oak.painted.brown.name=Brown Wooden Fence Gate
tile.fencegate.planks.oak.painted.brown.desc=A wooden fence gate, stained brown.
tile.fencegate.planks.oak.painted.blue.name=Blue Wooden Fence Gate
tile.fencegate.planks.oak.painted.blue.desc=A wooden fence gate, stained blue.
tile.fencegate.planks.oak.painted.purple.name=Purple Wooden Fence Gate
tile.fencegate.planks.oak.painted.purple.desc=A wooden fence gate, stained purple.
tile.fencegate.planks.oak.painted.cyan.name=Cyan Wooden Fence Gate
tile.fencegate.planks.oak.painted.cyan.desc=A wooden fence gate, stained cyan.
tile.fencegate.planks.oak.painted.silver.name=Light Gray Wooden Fence Gate
tile.fencegate.planks.oak.painted.silver.desc=A wooden fence gate, stained light gray.
tile.fencegate.planks.oak.painted.gray.name=Gray Wooden Fence Gate
tile.fencegate.planks.oak.painted.gray.desc=A wooden fence gate, stained gray.
tile.fencegate.planks.oak.painted.pink.name=Pink Wooden Fence Gate
tile.fencegate.planks.oak.painted.pink.desc=A wooden fence gate, stained pink.
tile.fencegate.planks.oak.painted.lime.name=Lime Wooden Fence Gate
tile.fencegate.planks.oak.painted.lime.desc=A wooden fence gate, stained lime.
tile.fencegate.planks.oak.painted.yellow.name=Yellow Wooden Fence Gate
tile.fencegate.planks.oak.painted.yellow.desc=A wooden fence gate, stained yellow.
tile.fencegate.planks.oak.painted.lightblue.name=Light Blue Wooden Fence Gate
tile.fencegate.planks.oak.painted.lightblue.desc=A wooden fence gate, stained light blue.
tile.fencegate.planks.oak.painted.magenta.name=Magenta Wooden Fence Gate
tile.fencegate.planks.oak.painted.magenta.desc=A wooden fence gate, stained magenta.
tile.fencegate.planks.oak.painted.orange.name=Orange Wooden Fence Gate
tile.fencegate.planks.oak.painted.orange.desc=A wooden fence gate, stained orange.
tile.fencegate.planks.oak.painted.white.name=White Wooden Fence Gate
tile.fencegate.planks.oak.painted.white.desc=A wooden fence gate, stained white.

tile.bookshelf.planks.oak.name=Bookshelf
tile.bookshelf.planks.oak.desc=A repository of knowledge.

tile.wool.name=Wool
tile.wool.desc=How did you get this?!
tile.wool.black.name=Black Wool
tile.wool.black.desc=Sheep's wool, dyed black.
tile.wool.red.name=Red Wool
tile.wool.red.desc=Sheep's wool, dyed red.
tile.wool.green.name=Green Wool
tile.wool.green.desc=Sheep's wool, dyed green.
tile.wool.brown.name=Brown Wool
tile.wool.brown.desc=Sheep's wool, dyed brown.
tile.wool.blue.name=Blue Wool
tile.wool.blue.desc=Sheep's wool, dyed blue.
tile.wool.purple.name=Purple Wool
tile.wool.purple.desc=Sheep's wool, dyed purple.
tile.wool.cyan.name=Cyan Wool
tile.wool.cyan.desc=Sheep's wool, dyed cyan.
tile.wool.silver.name=Light Gray Wool
tile.wool.silver.desc=Sheep's wool, dyed light gray.
tile.wool.gray.name=Gray Wool
tile.wool.gray.desc=Sheep's wool, dyed gray.
tile.wool.pink.name=Pink Wool
tile.wool.pink.desc=Sheep's wool, dyed pink.
tile.wool.lime.name=Lime Wool
tile.wool.lime.desc=Sheep's wool, dyed lime.
tile.wool.yellow.name=Yellow Wool
tile.wool.yellow.desc=Sheep's wool, dyed yellow.
tile.wool.lightblue.name=Light Blue Wool
tile.wool.lightblue.desc=Sheep's wool, dyed light blue.
tile.wool.magenta.name=Magenta Wool
tile.wool.magenta.desc=Sheep's wool, dyed magenta.
tile.wool.orange.name=Orange Wool
tile.wool.orange.desc=Sheep's wool, dyed orange.
tile.wool.white.name=White Wool
tile.wool.white.desc=Sheep's wool, dyed white.

tile.brick.clay.name=Clay Bricks
tile.brick.clay.desc=Stacked bricks of baked clay.
tile.brick.stone.polished.name=Polished Stone Bricks
tile.brick.stone.polished.desc=Stacked bricks of polished stone.
tile.brick.stone.polished.mossy.name=Mossy Polished Stone Bricks
tile.brick.stone.polished.mossy.desc=Stacked bricks of polished stone with added greenery.
tile.brick.sandstone.name=Sandstone Bricks
tile.brick.sandstone.desc=Stacked bricks of sandstone.
tile.brick.gold.name=Gold Bricks
tile.brick.gold.desc=Stacked bricks of gold.
tile.brick.lapis.name=Lapis Lazuli Bricks
tile.brick.lapis.desc=Stacked bricks of lapis lazuli.
tile.brick.basalt.name=Basalt Bricks
tile.brick.basalt.desc=Stacked bricks of basalt.
tile.brick.limestone.name=Limestone Bricks
tile.brick.limestone.desc=Stacked bricks of limestone.
tile.brick.granite.name=Granite Bricks
tile.brick.granite.desc=Stacked bricks of granite.
tile.brick.marble.name=Marble Bricks
tile.brick.marble.desc=Stacked bricks of marble.
tile.brick.slate.name=Slate Bricks
tile.brick.slate.desc=Stacked bricks of slate.
tile.brick.stone.name=Stone Bricks
tile.brick.stone.desc=Stacked bricks of stone.
tile.brick.permafrost.name=Permafrost Bricks
tile.brick.permafrost.desc=Stacked bricks of permafrost.
tile.brick.iron.name=Iron Bricks
tile.brick.iron.desc=Stacked bricks of iron.

tile.slab.planks.oak.name=Wooden Slab
tile.slab.planks.oak.desc=A slab of wooden planks.
tile.slab.cobble.stone.name=Cobblestone Slab
tile.slab.cobble.stone.desc=A slab of cobblestone.
tile.slab.sandstone.name=Sandstone Slab
tile.slab.sandstone.desc=A slab of sandstone.
tile.slab.brick.stone.polished.name=Polished Stone Brick Slab
tile.slab.brick.stone.polished.desc=A slab of polished stone bricks.
tile.slab.stone.carved.name=Polished Stone Slab
tile.slab.stone.carved.desc=A slab of polished stone.
tile.slab.brick.marble.name=Marble Brick Slab
tile.slab.brick.marble.desc=A slab of marble bricks.
tile.slab.brick.clay.name=Clay Brick Slab
tile.slab.brick.clay.desc=A slab of clay bricks.
tile.slab.capstone.marble.name=Marble Capstone Slab
tile.slab.capstone.marble.desc=Marble sculpted into a capstone.
tile.slab.cobble.basalt.name=Cobbled Basalt Slab
tile.slab.cobble.basalt.desc=A slab of cobbled basalt.
tile.slab.cobble.limestone.name=Cobbled Limestone Slab
tile.slab.cobble.limestone.desc=A slab of cobbled limestone.
tile.slab.cobble.granite.name=Cobbled Granite Slab
tile.slab.cobble.granite.desc=A slab of cobbled granite.
tile.slab.brick.basalt.name=Basalt Brick Slab
tile.slab.brick.basalt.desc=A slab of basalt bricks.
tile.slab.brick.limestone.name=Limestone Brick Slab
tile.slab.brick.limestone.desc=A slab of limestone bricks.
tile.slab.brick.granite.name=Granite Brick Slab
tile.slab.brick.granite.desc=A slab of granite bricks.
tile.slab.brick.slate.name=Slate Brick Slab
tile.slab.brick.slate.desc=A slab of slate bricks.
tile.slab.brick.stone.name=Stone Brick Slab
tile.slab.brick.stone.desc=A slab of stone bricks.
tile.slab.granite.carved.name=Polished Granite Slab
tile.slab.granite.carved.desc=A slab of polished granite.
tile.slab.limestone.carved.name=Polished Limestone Slab
tile.slab.limestone.carved.desc=A slab of polished limestone.
tile.slab.basalt.carved.name=Polished Basalt Slab
tile.slab.basalt.carved.desc=A slab of polished basalt.
tile.slab.permafrost.carved.name=Polished Permafrost Slab
tile.slab.permafrost.carved.desc=A slab of polished permafrost.

tile.slab.planks.oak.painted.name=Mystery Wooden Slab
tile.slab.planks.oak.painted.desc=How did you get this?!
tile.slab.planks.oak.painted.black.name=Black Wooden Slab
tile.slab.planks.oak.painted.black.desc=A slab of wooden planks, stained black.
tile.slab.planks.oak.painted.red.name=Red Wooden Slab
tile.slab.planks.oak.painted.red.desc=A slab of wooden planks, stained red.
tile.slab.planks.oak.painted.green.name=Green Wooden Slab
tile.slab.planks.oak.painted.green.desc=A slab of wooden planks, stained green.
tile.slab.planks.oak.painted.brown.name=Brown Wooden Slab
tile.slab.planks.oak.painted.brown.desc=A slab of wooden planks, stained brown.
tile.slab.planks.oak.painted.blue.name=Blue Wooden Slab
tile.slab.planks.oak.painted.blue.desc=A slab of wooden planks, stained blue.
tile.slab.planks.oak.painted.purple.name=Purple Wooden Slab
tile.slab.planks.oak.painted.purple.desc=A slab of wooden planks, stained purple.
tile.slab.planks.oak.painted.cyan.name=Cyan Wooden Slab
tile.slab.planks.oak.painted.cyan.desc=A slab of wooden planks, stained cyan.
tile.slab.planks.oak.painted.silver.name=Light Gray Wooden Slab
tile.slab.planks.oak.painted.silver.desc=A slab of wooden planks, stained light gray.
tile.slab.planks.oak.painted.gray.name=Gray Wooden Slab
tile.slab.planks.oak.painted.gray.desc=A slab of wooden planks, stained gray.
tile.slab.planks.oak.painted.pink.name=Pink Wooden Slab
tile.slab.planks.oak.painted.pink.desc=A slab of wooden planks, stained pink.
tile.slab.planks.oak.painted.lime.name=Lime Wooden Slab
tile.slab.planks.oak.painted.lime.desc=A slab of wooden planks, stained lime.
tile.slab.planks.oak.painted.yellow.name=Yellow Wooden Slab
tile.slab.planks.oak.painted.yellow.desc=A slab of wooden planks, stained yellow.
tile.slab.planks.oak.painted.lightblue.name=Light Blue Wooden Slab
tile.slab.planks.oak.painted.lightblue.desc=A slab of wooden planks, stained light blue.
tile.slab.planks.oak.painted.magenta.name=Magenta Wooden Slab
tile.slab.planks.oak.painted.magenta.desc=A slab of wooden planks, stained magenta.
tile.slab.planks.oak.painted.orange.name=Orange Wooden Slab
tile.slab.planks.oak.painted.orange.desc=A slab of wooden planks, stained orange.
tile.slab.planks.oak.painted.white.name=White Wooden Slab
tile.slab.planks.oak.painted.white.desc=A slab of wooden planks, stained white.
tile.slab.cobble.permafrost.name=Cobbled Permafrost Slab
tile.slab.cobble.permafrost.desc=A slab of cobbled permafrost.
tile.slab.brick.sandstone.name=Sandstone Brick Slab
tile.slab.brick.sandstone.desc=A slab of sandstone bricks.
tile.slab.brick.permafrost.name=Permafrost Brick Slab
tile.slab.brick.permafrost.desc=A slab of permafrost bricks.

tile.stairs.planks.oak.name=Wooden Stairs
tile.stairs.planks.oak.desc=Wooden block used for rapid vertical movement.
tile.stairs.cobble.stone.name=Cobblestone Stairs
tile.stairs.cobble.stone.desc=Cobblestone block used for rapid vertical movement.
tile.stairs.brick.stone.polished.name=Polished Stone Brick Stairs
tile.stairs.brick.stone.polished.desc=Polished stone brick block used for rapid vertical movement.
tile.stairs.brick.marble.name=Marble Brick Stairs
tile.stairs.brick.marble.desc=Marble brick block used for rapid vertical movement.
tile.stairs.cobble.basalt.name=Cobbled Basalt Stairs
tile.stairs.cobble.basalt.desc=Cobbled basalt block used for rapid vertical movement.
tile.stairs.cobble.limestone.name=Cobbled Limestone Stairs
tile.stairs.cobble.limestone.desc=Cobbled limestone block used for rapid vertical movement.
tile.stairs.cobble.granite.name=Cobbled Granite Stairs
tile.stairs.cobble.granite.desc=Cobbled granite block used for rapid vertical movement.
tile.stairs.brick.basalt.name=Basalt Brick Stairs
tile.stairs.brick.basalt.desc=Basalt brick block used for rapid vertical movement.
tile.stairs.brick.limestone.name=Limestone Brick Stairs
tile.stairs.brick.limestone.desc=Limestone brick block used for rapid vertical movement.
tile.stairs.brick.granite.name=Granite Brick Stairs
tile.stairs.brick.granite.desc=Granite brick block used for rapid vertical movement.
tile.stairs.brick.clay.name=Clay Brick Stairs
tile.stairs.brick.clay.desc=Clay brick block used for rapid vertical movement.
tile.stairs.brick.slate.name=Slate Brick Stairs
tile.stairs.brick.slate.desc=Slate brick block used for rapid vertical movement.
tile.stairs.brick.stone.name=Stone Brick Stairs
tile.stairs.brick.stone.desc=Stone brick block used for rapid vertical movement.
tile.stairs.sandstone.name=Sandstone Stairs
tile.stairs.sandstone.desc=Sandstone block used for rapid vertical movement.
tile.stairs.cobble.permafrost.name=Cobbled Permafrost Stairs
tile.stairs.cobble.permafrost.desc=Cobbled permafrost block used for rapid vertical movement.
tile.stairs.brick.sandstone.name=Sandstone Brick Stairs
tile.stairs.brick.sandstone.desc=Sandstone brick block used for rapid vertical movement.
tile.stairs.brick.permafrost.name=Permafrost Brick Stairs
tile.stairs.brick.permafrost.desc=Permafrost brick block used for rapid vertical movement.

tile.stairs.planks.oak.painted.name=Mystery Wooden Stairs
tile.stairs.planks.oak.painted.desc=How did you get this?!
tile.stairs.planks.oak.painted.black.name=Black Wooden Stairs
tile.stairs.planks.oak.painted.black.desc=Wooden steps, stained black.
tile.stairs.planks.oak.painted.red.name=Red Wooden Stairs
tile.stairs.planks.oak.painted.red.desc=Wooden steps, stained red.
tile.stairs.planks.oak.painted.green.name=Green Wooden Stairs
tile.stairs.planks.oak.painted.green.desc=Wooden steps, stained green.
tile.stairs.planks.oak.painted.brown.name=Brown Wooden Stairs
tile.stairs.planks.oak.painted.brown.desc=Wooden steps, stained brown.
tile.stairs.planks.oak.painted.blue.name=Blue Wooden Stairs
tile.stairs.planks.oak.painted.blue.desc=Wooden steps, stained blue.
tile.stairs.planks.oak.painted.purple.name=Purple Wooden Stairs
tile.stairs.planks.oak.painted.purple.desc=Wooden steps, stained purple.
tile.stairs.planks.oak.painted.cyan.name=Cyan Wooden Stairs
tile.stairs.planks.oak.painted.cyan.desc=Wooden steps, stained cyan.
tile.stairs.planks.oak.painted.silver.name=Light Gray Wooden Stairs
tile.stairs.planks.oak.painted.silver.desc=Wooden steps, stained light gray.
tile.stairs.planks.oak.painted.gray.name=Gray Wooden Stairs
tile.stairs.planks.oak.painted.gray.desc=Wooden steps, stained gray.
tile.stairs.planks.oak.painted.pink.name=Pink Wooden Stairs
tile.stairs.planks.oak.painted.pink.desc=Wooden steps, stained pink.
tile.stairs.planks.oak.painted.lime.name=Lime Wooden Stairs
tile.stairs.planks.oak.painted.lime.desc=Wooden steps, stained lime.
tile.stairs.planks.oak.painted.yellow.name=Yellow Wooden Stairs
tile.stairs.planks.oak.painted.yellow.desc=Wooden steps, stained yellow.
tile.stairs.planks.oak.painted.lightblue.name=Light Blue Wooden Stairs
tile.stairs.planks.oak.painted.lightblue.desc=Wooden steps, stained light blue.
tile.stairs.planks.oak.painted.magenta.name=Magenta Wooden Stairs
tile.stairs.planks.oak.painted.magenta.desc=Wooden steps, stained magenta.
tile.stairs.planks.oak.painted.orange.name=Orange Wooden Stairs
tile.stairs.planks.oak.painted.orange.desc=Wooden steps, stained orange.
tile.stairs.planks.oak.painted.white.name=White Wooden Stairs
tile.stairs.planks.oak.painted.white.desc=Wooden steps, stained white.

tile.obsidian.name=Obsidian
tile.obsidian.desc=Rapidly cooled volcanic rock.

tile.glass.name=Glass
tile.glass.desc=Sand heated until it becomes translucent.
tile.glass.tinted.name=Tinted Glass
tile.glass.tinted.desc=Darkened glass that blocks light.

tile.grass.name=Grass
tile.grass.desc=Crisp, crunchy grass.
tile.grass.retro.name=Retro Grass
tile.grass.retro.desc=Crisp, crunchy grass. Smells old.
tile.grass.scorched.name=Scorched Grass
tile.grass.scorched.desc=Grass that has baked in the sun.

tile.path.dirt.name=Dirt Path
tile.path.dirt.desc=Dirt worn down by frequent travelling.

tile.dirt.name=Dirt
tile.dirt.desc=Crumbly brown dirt.
tile.dirt.scorched.name=Scorched Dirt
tile.dirt.scorched.desc=Dirt that has baked in the sun.
tile.dirt.scorched.rich.name=Rich Scorched Dirt
tile.dirt.scorched.rich.desc=Dirt that has baked in the sun, searing in minerals.

tile.mud.name=Mud
tile.mud.desc=Mud sodden to its core.
tile.mud.baked.name=Baked Mud
tile.mud.baked.desc=Mud that's been dried out and cracked.

tile.sponge.dry.name=Sponge
tile.sponge.dry.desc=A dry sponge, good for soaking up water.
tile.sponge.wet.name=Wet Sponge
tile.sponge.wet.desc=A sponge full of water.
tile.pumice.dry.name=Pumice
tile.pumice.dry.desc=A dry porous volcanic rock, good for soaking up lava.
tile.pumice.wet.name=Molten Pumice
tile.pumice.wet.desc=Rock filled with lava.

tile.moss.stone.name=Mossy Stone
tile.moss.stone.desc=Moss covering a block of stone.
tile.moss.basalt.name=Mossy Basalt
tile.moss.basalt.desc=Moss covering a block of basalt.
tile.moss.limestone.name=Mossy Limestone
tile.moss.limestone.desc=Moss covering a block of limestone.
tile.moss.granite.name=Mossy Granite
tile.moss.granite.desc=Moss covering a block of granite.

tile.sand.name=Sand
tile.sand.desc=Gets everywhere.
tile.gravel.name=Gravel
tile.gravel.desc=A loose collection of pebbles.

tile.bedrock.name=Bedrock
tile.bedrock.desc=The toughest substance known to man.
tile.boneshale.name=Bone Shale
tile.boneshale.desc=An incredibly tough white rock torn from the deepest depths.

tile.fluid.water.flowing.name=Flowing Water
tile.fluid.water.flowing.desc=Water that flows when placed.
tile.fluid.water.still.name=Still Water
tile.fluid.water.still.desc=Water that does not flow when placed.
tile.fluid.lava.flowing.name=Flowing Lava
tile.fluid.lava.flowing.desc=Lava that flows when placed.
tile.fluid.lava.still.name=Still Lava
tile.fluid.lava.still.desc=Lava that does not flow when placed.

tile.log.oak.name=Oak Log
tile.log.oak.desc=A log from an oak tree.
tile.log.pine.name=Pine Log
tile.log.pine.desc=A log from a pine tree.
tile.log.birch.name=Birch Log
tile.log.birch.desc=A log from a birch tree.
tile.log.cherry.name=Cherry Log
tile.log.cherry.desc=A log from a cherry tree.
tile.log.eucalyptus.name=Eucalyptus Log
tile.log.eucalyptus.desc=A log from a eucalyptus tree.
tile.log.oak.mossy.name=Mossy Oak Log
tile.log.oak.mossy.desc=A log from a mossy oak tree.
tile.log.thorn.name=Thorn Log
tile.log.thorn.desc=A log from a thorn tree.
tile.log.palm.name=Palm Log
tile.log.palm.desc=A log from a palm tree.

tile.leaves.oak.name=Oak Leaves
tile.leaves.oak.desc=Leaves from an oak tree.
tile.leaves.pine.name=Pine Leaves
tile.leaves.pine.desc=Leaves from a pine tree.
tile.leaves.birch.name=Birch Leaves
tile.leaves.birch.desc=Leaves from a birch tree.
tile.leaves.cherry.name=Cherry Leaves
tile.leaves.cherry.desc=Leaves from a cherry tree.
tile.leaves.eucalyptus.name=Eucalyptus Leaves
tile.leaves.eucalyptus.desc=Leaves from a eucalyptus tree.
tile.leaves.oak.retro.name=Retro Leaves
tile.leaves.oak.retro.desc=Leaves from long ago.
tile.leaves.shrub.name=Shrub Leaves
tile.leaves.shrub.desc=Leaves from a shrub.
tile.leaves.cherry.flowering.name=Flowering Cherry Leaves
tile.leaves.cherry.flowering.desc=Leaves from a cherry tree that are budding with fruit.
tile.leaves.cacao.name=Cacao Leaves
tile.leaves.cacao.desc=Leaves from a cacao tree.
tile.leaves.thorn.name=Thorn Leaves
tile.leaves.thorn.desc=Leaves from a thorn tree.
tile.leaves.palm.name=Palm Leaves
tile.leaves.palm.desc=Leaves from a palm tree.

tile.sapling.oak.name=Oak Sapling
tile.sapling.oak.desc=Plant to grow an oak tree.
tile.sapling.pine.name=Pine Sapling
tile.sapling.pine.desc=Plant to grow a pine tree.
tile.sapling.birch.name=Birch Sapling
tile.sapling.birch.desc=Plant to grow a birch tree.
tile.sapling.cherry.name=Cherry Sapling
tile.sapling.cherry.desc=Plant to grow a cherry tree.
tile.sapling.eucalyptus.name=Eucalyptus Sapling
tile.sapling.eucalyptus.desc=Plant to grow a eucalyptus tree.
tile.sapling.oak.retro.name=Retro Oak Sapling
tile.sapling.oak.retro.desc=Plant to grow a tree from long ago.
tile.sapling.shrub.name=Shrub Sapling
tile.sapling.shrub.desc=Plant to grow a shrub.
tile.sapling.cacao.name=Cacao Sapling
tile.sapling.cacao.desc=Plant to grow a cacao tree.
tile.sapling.thorn.name=Thorn Sapling
tile.sapling.thorn.desc=Plant to grow a thorn tree.
tile.sapling.palm.name=Palm Sapling
tile.sapling.palm.desc=Plant to grow a palm tree.

tile.tallgrass.name=Tall Grass
tile.tallgrass.desc=Lush, growing grass.
tile.tallgrass.fern.name=Fern
tile.tallgrass.fern.desc=A fern plant.
tile.deadbush.name=Dead Bush
tile.deadbush.desc=A dried and withered plant.
tile.spinifex.name=Spinifex
tile.spinifex.desc=A spindly, thin grass from dry regions.
tile.algae.name=Algae
tile.algae.desc=Gooey vegetation that floats on the water's surface.

tile.flower.yellow.name=Dandelion
tile.flower.yellow.desc=A beautiful yellow flower.
tile.flower.red.name=Rose
tile.flower.red.desc=A beautiful red flower.
tile.flower.purple.name=Heather
tile.flower.purple.desc=Sprigs of purple petals. Brings good luck.
tile.flower.lightblue.name=Bluebell
tile.flower.lightblue.desc=A sad-looking blue flower.
tile.flower.pink.name=Orchid
tile.flower.pink.desc=A beautiful pink flower.
tile.flower.orange.name=Marigold
tile.flower.orange.desc=A beautiful orange flower.

tile.mushroom.red.name=Red Mushroom
tile.mushroom.red.desc=A tasty red mushroom. Good for stew.
tile.mushroom.brown.name=Brown Mushroom
tile.mushroom.brown.desc=A tasty brown mushroom. Good for stew.

tile.ore.coal.stone.name=Stone Coal Ore
tile.ore.coal.stone.desc=A chunk of coal embedded in stone.
tile.ore.coal.basalt.name=Basalt Coal Ore
tile.ore.coal.basalt.desc=A chunk of coal embedded in basalt.
tile.ore.coal.limestone.name=Limestone Coal Ore
tile.ore.coal.limestone.desc=A chunk of coal embedded in limestone.
tile.ore.coal.granite.name=Granite Coal Ore
tile.ore.coal.granite.desc=A chunk of coal embedded in granite.
tile.ore.coal.permafrost.name=Permafrost Coal Ore
tile.ore.coal.permafrost.desc=A chunk of coal embedded in permafrost.

tile.ore.iron.stone.name=Stone Iron Ore
tile.ore.iron.stone.desc=Iron nuggets embedded in stone.
tile.ore.iron.basalt.name=Basalt Iron Ore
tile.ore.iron.basalt.desc=Iron nuggets embedded in basalt.
tile.ore.iron.limestone.name=Limestone Iron Ore
tile.ore.iron.limestone.desc=Iron nuggets embedded in limestone.
tile.ore.iron.granite.name=Granite Iron Ore
tile.ore.iron.granite.desc=Iron nuggets embedded in granite.
tile.ore.iron.permafrost.name=Permafrost Iron Ore
tile.ore.iron.permafrost.desc=Iron nuggets embedded in permafrost.

tile.ore.gold.stone.name=Stone Gold Ore
tile.ore.gold.stone.desc=Gold nuggets embedded in stone.
tile.ore.gold.basalt.name=Basalt Gold Ore
tile.ore.gold.basalt.desc=Gold nuggets embedded in basalt.
tile.ore.gold.limestone.name=Limestone Gold Ore
tile.ore.gold.limestone.desc=Gold nuggets embedded in limestone.
tile.ore.gold.granite.name=Granite Gold Ore
tile.ore.gold.granite.desc=Gold nuggets embedded in granite.
tile.ore.gold.permafrost.name=Permafrost Gold Ore
tile.ore.gold.permafrost.desc=Gold nuggets embedded in permafrost.

tile.ore.lapis.stone.name=Stone Lapis Lazuli Ore
tile.ore.lapis.stone.desc=Chunks of lapis lazuli embedded in stone.
tile.ore.lapis.basalt.name=Basalt Lapis Lazuli Ore
tile.ore.lapis.basalt.desc=Chunks of lapis lazuli embedded in basalt.
tile.ore.lapis.limestone.name=Limestone Lapis Lazuli Ore
tile.ore.lapis.limestone.desc=Chunks of lapis lazuli embedded in limestone.
tile.ore.lapis.granite.name=Granite Lapis Lazuli Ore
tile.ore.lapis.granite.desc=Chunks of lapis lazuli embedded in granite.
tile.ore.lapis.permafrost.name=Permafrost Lapis Lazuli Ore
tile.ore.lapis.permafrost.desc=Chunks of lapis lazuli embedded in permafrost.

tile.ore.redstone.stone.name=Stone Redstone Ore
tile.ore.redstone.stone.desc=Red dust embedded in stone.
tile.ore.redstone.basalt.name=Basalt Redstone Ore
tile.ore.redstone.basalt.desc=Red dust embedded in basalt.
tile.ore.redstone.limestone.name=Limestone Redstone Ore
tile.ore.redstone.limestone.desc=Red dust embedded in limestone.
tile.ore.redstone.granite.name=Granite Redstone Ore
tile.ore.redstone.granite.desc=Red dust embedded in granite.
tile.ore.redstone.permafrost.name=Permafrost Redstone Ore
tile.ore.redstone.permafrost.desc=Red dust embedded in permafrost.
tile.ore.redstone.glowing.stone.name=Glowing Stone Redstone Ore
tile.ore.redstone.glowing.stone.desc=Red dust embedded in stone. Emits a faint light.
tile.ore.redstone.glowing.basalt.name=Glowing Basalt Redstone Ore
tile.ore.redstone.glowing.basalt.desc=Red dust embedded in basalt. Emits a faint light.
tile.ore.redstone.glowing.limestone.name=Glowing Limestone Redstone Ore
tile.ore.redstone.glowing.limestone.desc=Red dust embedded in limestone. Emits a faint light.
tile.ore.redstone.glowing.granite.name=Glowing Granite Redstone Ore
tile.ore.redstone.glowing.granite.desc=Red dust embedded in granite. Emits a faint light.
tile.ore.redstone.glowing.permafrost.name=Glowing Permafrost Redstone Ore
tile.ore.redstone.glowing.permafrost.desc=Red dust embedded in permafrost. Emits a faint light.

tile.ore.diamond.stone.name=Stone Diamond Ore
tile.ore.diamond.stone.desc=A chunk of diamond embedded in stone.
tile.ore.diamond.basalt.name=Basalt Diamond Ore
tile.ore.diamond.basalt.desc=A chunk of diamond embedded in basalt.
tile.ore.diamond.limestone.name=Limestone Diamond Ore
tile.ore.diamond.limestone.desc=A chunk of diamond embedded in limestone.
tile.ore.diamond.granite.name=Granite Diamond Ore
tile.ore.diamond.granite.desc=A chunk of diamond embedded in granite.
tile.ore.diamond.permafrost.name=Permafrost Diamond Ore
tile.ore.diamond.permafrost.desc=A chunk of diamond embedded in permafrost.

tile.ore.nethercoal.netherrack.name=Nether Coal Ore
tile.ore.nethercoal.netherrack.desc=A lump of Nether Coal embedded in netherrack.

tile.block.coal.name=Block of Coal
tile.block.coal.desc=A solid block of coal.
tile.block.iron.name=Block of Iron
tile.block.iron.desc=A solid block of iron. Heavy!
tile.block.gold.name=Block of Gold
tile.block.gold.desc=A solid block of gold, for flaunting your bling.
tile.block.lapis.name=Block of Lapis Lazuli
tile.block.lapis.desc=A solid block of lapis lazuli.
tile.block.redstone.name=Block of Redstone
tile.block.redstone.desc=A solid block of redstone.
tile.block.diamond.name=Block of Diamond
tile.block.diamond.desc=A solid block of diamond. Well done you.
tile.block.nethercoal.name=Block of Nether Coal
tile.block.nethercoal.desc=A solid block of Nether Coal.
tile.block.steel.name=Block of Steel
tile.block.steel.desc=A solid block of steel.
tile.block.quartz.name=Block of Quartz
tile.block.quartz.desc=A solid block of quartz.
tile.block.olivine.name=Block of Olivine
tile.block.olivine.desc=A solid block of olivine.
tile.block.charcoal.name=Block of Charcoal
tile.block.charcoal.desc=A solid block of charcoal.

tile.wire.redstone.name=Redstone Wire
tile.wire.redstone.desc=A strand of redstone dust laid on the ground.

tile.torch.redstone.idle.name=Redstone Torch
tile.torch.redstone.idle.desc=Emits a constant redstone signal.
tile.torch.redstone.active.name=Redstone Torch
tile.torch.redstone.active.desc=Emits a constant redstone signal.

tile.button.stone.name=Stone Button
tile.button.stone.desc=Emits a brief redstone signal when pressed.

tile.lever.cobble.stone.name=Cobblestone Lever
tile.lever.cobble.stone.desc=Allows turning a redstone signal on or off.

tile.pressureplate.stone.name=Stone Pressure Plate
tile.pressureplate.stone.desc=Emits a redstone signal when living creatures step on it.
tile.pressureplate.planks.oak.name=Wooden Pressure Plate
tile.pressureplate.planks.oak.desc=Emits a redstone signal when anything steps on it.
tile.pressureplate.cobble.stone.name=Cobblestone Pressure Plate
tile.pressureplate.cobble.stone.desc=Emits a redstone signal when players step on it.

tile.motionsensor.idle.name=Motion Sensor
tile.motionsensor.idle.desc=Emits a redstone signal when something moves past it.
tile.motionsensor.active.name=Active Motion Sensor
tile.motionsensor.active.desc=Emits a redstone signal when something moves past it.

tile.repeater.idle.name=Redstone Repeater
tile.repeater.idle.desc=Repeats redstone signals over a distance.
tile.repeater.active.name=Redstone Repeater
tile.repeater.active.desc=Repeats redstone signals over a distance.

tile.piston.base.name=Piston
tile.piston.base.desc=Pushes blocks but does not pull them.
tile.piston.base.sticky.name=Sticky Piston
tile.piston.base.sticky.desc=Pushes and pulls blocks.
tile.piston.head.name=Piston Head
tile.piston.head.desc=The pushy part of the piston.
tile.piston.moving.name=Piston Mover
tile.piston.moving.desc=The invisible moving part of the piston.

tile.noteblock.name=Note Block
tile.noteblock.desc=Plays a musical note when powered.

tile.rail.name=Rail
tile.rail.desc=For rapid horizontal movement via minecart.
tile.rail.powered.name=Powered Rail
tile.rail.powered.desc=Makes minecarts go faster when powered.
tile.rail.detector.name=Detector Rail
tile.rail.detector.desc=Emits a redstone signal when a minecart crosses it.

tile.spikes.name=Spike Trap
tile.spikes.desc=Deactivates when powered. Technically a war crime.

tile.dispenser.cobble.stone.name=Dispenser
tile.dispenser.cobble.stone.desc=Fires items out of the hole in the front.

tile.trapdoor.planks.oak.name=Oak Trapdoor
tile.trapdoor.planks.oak.desc=Like a door, but flat.
tile.trapdoor.iron.name=Iron Trapdoor
tile.trapdoor.iron.desc=Like a door, but flat and made of iron.
tile.trapdoor.glass.name=Glass Trapdoor
tile.trapdoor.glass.desc=Useless at its job.

tile.tnt.name=TNT
tile.tnt.desc=Goes off with a bang.

tile.door.planks.oak.bottom.name=Bottom Wooden Door
tile.door.planks.oak.bottom.desc=/give Honeydew 64 46
tile.door.planks.oak.top.name=Top Wooden Door
tile.door.planks.oak.top.desc=Oh, wait, that's not TNT, that's half a door.
tile.door.iron.bottom.name=Bottom Iron Door
tile.door.iron.bottom.desc=Not much good on its own.
tile.door.iron.top.name=Top Iron Door
tile.door.iron.top.desc=Could use a friend.

tile.mesh.name=Mesh Block
tile.mesh.desc=Allows items to pass through but nothing else.
tile.mesh.gold.name=Gold Mesh Block
tile.mesh.gold.desc=Allows a specified item to pass through but nothing else.

tile.bed.name=Bed
tile.bed.desc=Bed!
tile.seat.name=Seat
tile.seat.desc=Sit down and relax.

tile.cobweb.name=Cobweb
tile.cobweb.desc=Sticky silky strands woven by spiders.

tile.fire.name=Fire
tile.fire.desc=Ouch, fire hot!
tile.brazier.inactive.name=Brazier
tile.brazier.inactive.desc=A safe place to keep a fire.
tile.brazier.active.name=Lit Brazier
tile.brazier.active.desc=A safe place to keep a fire.

tile.mobspawner.name=Mob Spawner
tile.mobspawner.desc=A cage filled with horror.
tile.mobspawner.deactivated.name=Deactivated Mob Spawner
tile.mobspawner.deactivated.desc=A cage no longer filled with horror.

tile.workbench.name=Workbench
tile.workbench.desc=For bigger projects.

tile.furnace.stone.idle.name=Furnace
tile.furnace.stone.idle.desc=For melting, heating, and cooking blocks and items.
tile.furnace.stone.active.name=Lit Furnace
tile.furnace.stone.active.desc=For melting, heating, and cooking blocks and items.
tile.furnace.blast.idle.name=Blast Furnace
tile.furnace.blast.idle.desc=Burns hotter than a normal furnace.
tile.furnace.blast.active.name=Lit Blast Furnace
tile.furnace.blast.active.desc=Burns hotter than a normal furnace.

tile.trommel.idle.name=Trommel
tile.trommel.idle.desc=A machine that separates dirt from other useful items.
tile.trommel.active.name=Lit Trommel
tile.trommel.active.desc=A machine that separates dirt from other useful items.

tile.chest.planks.oak.name=Wooden Chest
tile.chest.planks.oak.desc=A place to store your items.
tile.chest.planks.oak.painted.name=Mystery Wooden Chest
tile.chest.planks.oak.painted.desc=How did you get this?!
tile.chest.planks.oak.painted.black.name=Black Wooden Chest
tile.chest.planks.oak.painted.black.desc=A place to store your items.
tile.chest.planks.oak.painted.red.name=Red Wooden Chest
tile.chest.planks.oak.painted.red.desc=A place to store your items.
tile.chest.planks.oak.painted.green.name=Green Wooden Chest
tile.chest.planks.oak.painted.green.desc=A place to store your items.
tile.chest.planks.oak.painted.brown.name=Brown Wooden Chest
tile.chest.planks.oak.painted.brown.desc=A place to store your items.
tile.chest.planks.oak.painted.blue.name=Blue Wooden Chest
tile.chest.planks.oak.painted.blue.desc=A place to store your items.
tile.chest.planks.oak.painted.purple.name=Purple Wooden Chest
tile.chest.planks.oak.painted.purple.desc=A place to store your items.
tile.chest.planks.oak.painted.cyan.name=Cyan Wooden Chest
tile.chest.planks.oak.painted.cyan.desc=A place to store your items.
tile.chest.planks.oak.painted.silver.name=Light Gray Wooden Chest
tile.chest.planks.oak.painted.silver.desc=A place to store your items.
tile.chest.planks.oak.painted.gray.name=Gray Wooden Chest
tile.chest.planks.oak.painted.gray.desc=A place to store your items.
tile.chest.planks.oak.painted.pink.name=Pink Wooden Chest
tile.chest.planks.oak.painted.pink.desc=A place to store your items.
tile.chest.planks.oak.painted.lime.name=Lime Wooden Chest
tile.chest.planks.oak.painted.lime.desc=A place to store your items.
tile.chest.planks.oak.painted.yellow.name=Yellow Wooden Chest
tile.chest.planks.oak.painted.yellow.desc=A place to store your items.
tile.chest.planks.oak.painted.lightblue.name=Light Blue Wooden Chest
tile.chest.planks.oak.painted.lightblue.desc=A place to store your items.
tile.chest.planks.oak.painted.magenta.name=Magenta Wooden Chest
tile.chest.planks.oak.painted.magenta.desc=A place to store your items.
tile.chest.planks.oak.painted.orange.name=Orange Wooden Chest
tile.chest.planks.oak.painted.orange.desc=A place to store your items.
tile.chest.planks.oak.painted.white.name=White Wooden Chest
tile.chest.planks.oak.painted.white.desc=A place to store your items.
tile.chest.legacy.name=Legacy Chest

tile.crops.wheat.name=Wheat Crops
tile.crops.wheat.desc=Wheat, plucked from the ground.
tile.crops.pumpkin.name=Pumpkin Crops
tile.crops.pumpkin.desc=A ripening pumpkin, plucked from the ground.

tile.farmland.dirt.name=Farmland
tile.farmland.dirt.desc=Tilled soil for growing crops.

tile.sign.post.planks.oak.name=Oak Signpost
tile.sign.post.planks.oak.desc=A free-standing oak sign.
tile.sign.wall.planks.oak.name=Oak Wall Sign
tile.sign.wall.planks.oak.desc=An oak sign placed on a wall.

tile.layer.snow.name=Snow Layer
tile.layer.snow.desc=A flat layer of snow.
tile.layer.leaves.oak.name=Leaf Pile
tile.layer.leaves.oak.desc=A pile of leaves.
tile.layer.slate.name=Slate Layer
tile.layer.slate.desc=A flat sheet of slate.

tile.ice.name=Ice
tile.ice.desc=Slippery frozen water.
tile.ice.perma.name=Perma-Ice
tile.ice.perma.desc=Ice imbued with the essence of stone.

tile.block.snow.name=Block of Snow
tile.block.snow.desc=Lots of snow compacted into a block.

tile.cactus.name=Cactus
tile.cactus.desc=A spiky plant that grows in the desert.

tile.block.clay.name=Block of Clay
tile.block.clay.desc=A block of compacted clay.

tile.sugarcane.name=Sugarcane
tile.sugarcane.desc=Not as sweet as you.

tile.block.sugarcane.name=Block of Sugarcane
tile.block.sugarcane.desc=One very big sugar cube.
tile.block.sugarcane.baked.name=Baked Block of Sugarcane
tile.block.sugarcane.baked.desc=Smells absolutely delicious.

tile.jukebox.name=Jukebox
tile.jukebox.desc=Plays your favourite tunes, assuming you have the right record.

tile.pumpkin.name=Pumpkin
tile.pumpkin.desc=An orange squash that grows in the wild.
tile.pumpkin.carved.idle.name=Carved Pumpkin
tile.pumpkin.carved.idle.desc=An orange squash with a spooky face.
tile.pumpkin.carved.active.name=Jack 'o' Lantern
tile.pumpkin.carved.active.desc=An orange squash with a spooky face, lit by a torch.
tile.pumpkin.redstone.name=Redstone Jack 'o' Lantern
tile.pumpkin.redstone.desc=An orange squash with a spooky face, lit by a redstone torch.

tile.cobble.netherrack.name=Cobbled Netherrack
tile.cobble.netherrack.desc=Dark red rock that burns forever.
tile.cobble.netherrack.igneous.name=Igneous Cobbled Netherrack
tile.cobble.netherrack.igneous.desc=Extreme heat has made this rock glow from inside.
tile.cobble.netherrack.mossy.name=Mossy Cobbled Netherrack
tile.cobble.netherrack.mossy.desc=Cobbled netherrack, covered in something like moss.
tile.netherrack.name=Netherrack
tile.netherrack.desc=Dark red rock, smoothed by heat and time.
tile.brick.netherrack.name=Netherrack Bricks
tile.brick.netherrack.desc=Stacked bricks of netherrack.
tile.slab.netherrack.carved.name=Polished Netherrack Slab
tile.slab.netherrack.carved.desc=A slab of polished netherrack.
tile.slab.cobble.netherrack.name=Cobbled Netherrack Slab
tile.slab.cobble.netherrack.desc=A slab of cobbled netherrack.
tile.slab.brick.netherrack.name=Netherrack Brick Slab
tile.slab.brick.netherrack.desc=A slab of netherrack bricks.
tile.stairs.cobble.netherrack.name=Cobbled Netherrack Stairs
tile.stairs.cobble.netherrack.desc=Cobbled netherrack block used for rapid vertical movement.
tile.stairs.brick.netherrack.name=Netherrack Brick Stairs
tile.stairs.brick.netherrack.desc=Netherrack brick block used for rapid vertical movement.

tile.soulsand.name=Soul Sand
tile.soulsand.desc=Squishy brown sand that's tough to walk through.
tile.soulschist.name=Soul Schist
tile.soulschist.desc=A hideous medley of ancient bones, fused through heat, pressure, and time.

tile.glowstone.name=Block of Glowstone
tile.glowstone.desc=Constantly emits a strong yellowish light.

tile.portal.nether.name=Nether Portal
tile.portal.nether.desc=A portal to the Nether.
tile.portal.paradise.name=Paradise Portal
tile.portal.paradise.desc=A portal to Paradise.

tile.cake.name=Cake
tile.cake.desc=I just can't cake it any more.
tile.pumpkin_pie.name=Pumpkin Pie
tile.pumpkin_pie.desc=I don't wanna pie!

tile.lamp.idle.name=Lamp
tile.lamp.idle.desc=How did you get this?!
tile.lamp.idle.black.name=Black Lamp
tile.lamp.idle.black.desc=A redstone lamp that can emit light. Tinted black.
tile.lamp.idle.red.name=Red Lamp
tile.lamp.idle.red.desc=A redstone lamp that can emit light. Tinted red.
tile.lamp.idle.green.name=Green Lamp
tile.lamp.idle.green.desc=A redstone lamp that can emit light. Tinted green.
tile.lamp.idle.brown.name=Brown Lamp
tile.lamp.idle.brown.desc=A redstone lamp that can emit light. Tinted brown.
tile.lamp.idle.blue.name=Blue Lamp
tile.lamp.idle.blue.desc=A redstone lamp that can emit light. Tinted blue.
tile.lamp.idle.purple.name=Purple Lamp
tile.lamp.idle.purple.desc=A redstone lamp that can emit light. Tinted purple.
tile.lamp.idle.cyan.name=Cyan Lamp
tile.lamp.idle.cyan.desc=A redstone lamp that can emit light. Tinted cyan.
tile.lamp.idle.silver.name=Light Gray Lamp
tile.lamp.idle.silver.desc=A redstone lamp that can emit light. Tinted light gray.
tile.lamp.idle.gray.name=Gray Lamp
tile.lamp.idle.gray.desc=A redstone lamp that can emit light. Tinted gray.
tile.lamp.idle.pink.name=Pink Lamp
tile.lamp.idle.pink.desc=A redstone lamp that can emit light. Tinted pink.
tile.lamp.idle.lime.name=Lime Lamp
tile.lamp.idle.lime.desc=A redstone lamp that can emit light. Tinted lime.
tile.lamp.idle.yellow.name=Yellow Lamp
tile.lamp.idle.yellow.desc=A redstone lamp that can emit light. Tinted yellow.
tile.lamp.idle.lightblue.name=Light Blue Lamp
tile.lamp.idle.lightblue.desc=A redstone lamp that can emit light. Tinted light blue.
tile.lamp.idle.magenta.name=Magenta Lamp
tile.lamp.idle.magenta.desc=A redstone lamp that can emit light. Tinted magenta.
tile.lamp.idle.orange.name=Orange Lamp
tile.lamp.idle.orange.desc=A redstone lamp that can emit light. Tinted orange.
tile.lamp.idle.white.name=White Lamp
tile.lamp.idle.white.desc=A redstone lamp that can emit light.

tile.lamp.active.name=Lit Lamp
tile.lamp.active.desc=How did you get this?!
tile.lamp.active.black.name=Lit Black Lamp
tile.lamp.active.black.desc=A redstone lamp that emits light. Tinted black.
tile.lamp.active.red.name=Lit Red Lamp
tile.lamp.active.red.desc=A redstone lamp that emits light. Tinted red.
tile.lamp.active.green.name=Lit Green Lamp
tile.lamp.active.green.desc=A redstone lamp that emits light. Tinted green.
tile.lamp.active.brown.name=Lit Brown Lamp
tile.lamp.active.brown.desc=A redstone lamp that emits light. Tinted brown.
tile.lamp.active.blue.name=Lit Blue Lamp
tile.lamp.active.blue.desc=A redstone lamp that emits light. Tinted blue.
tile.lamp.active.purple.name=Lit Purple Lamp
tile.lamp.active.purple.desc=A redstone lamp that emits light. Tinted purple.
tile.lamp.active.cyan.name=Lit Cyan Lamp
tile.lamp.active.cyan.desc=A redstone lamp that emits light. Tinted cyan.
tile.lamp.active.silver.name=Lit Light Gray Lamp
tile.lamp.active.silver.desc=A redstone lamp that emits light. Tinted light gray.
tile.lamp.active.gray.name=Lit Gray Lamp
tile.lamp.active.gray.desc=A redstone lamp that emits light. Tinted gray.
tile.lamp.active.pink.name=Lit Pink Lamp
tile.lamp.active.pink.desc=A redstone lamp that emits light. Tinted pink.
tile.lamp.active.lime.name=Lit Lime Lamp
tile.lamp.active.lime.desc=A redstone lamp that emits light. Tinted lime.
tile.lamp.active.yellow.name=Yellow Lamp
tile.lamp.active.yellow.desc=A redstone lamp that emits light. Tinted yellow.
tile.lamp.active.lightblue.name=Light Blue Lamp
tile.lamp.active.lightblue.desc=A redstone lamp that emits light. Tinted light blue.
tile.lamp.active.magenta.name=Magenta Lamp
tile.lamp.active.magenta.desc=A redstone lamp that emits light. Tinted magenta.
tile.lamp.active.orange.name=Orange Lamp
tile.lamp.active.orange.desc=A redstone lamp that emits light. Tinted orange.
tile.lamp.active.white.name=White Lamp
tile.lamp.active.white.desc=A redstone lamp that emits light.

tile.stone.polished.name=Polished Stone
tile.stone.polished.desc=A polished block of stone.
tile.granite.polished.name=Polished Granite
tile.granite.polished.desc=A polished block of granite.
tile.limestone.polished.name=Polished Limestone
tile.limestone.polished.desc=A polished block of limestone.
tile.basalt.polished.name=Polished Basalt
tile.basalt.polished.desc=A polished block of basalt.
tile.slate.polished.name=Polished Slate
tile.slate.polished.desc=A polished block of slate.
tile.permafrost.polished.name=Polished Permafrost
tile.permafrost.polished.desc=A polished block of permafrost.
tile.netherrack.polished.name=Polished Netherrack
tile.netherrack.polished.desc=A polished block of netherrack.

tile.candle.wax.soul.name=Soul Wax Candle
tile.candle.wax.soul.desc=A waxy brown candle that glows with an unnatural light.

tile.basket.name=Basket
tile.basket.desc=A wicker container for holding items.

tile.overlay.pebbles.name=Pebbles
tile.overlay.pebbles.desc=A cluster of pebbles.

tile.fence.chainlink.name=Chainlink Fence
tile.fence.chainlink.desc=A fence made of interconnected chain links. Can be climbed!
tile.fence.paper_wall.name=Paper Wall Fence
tile.fence.paper_wall.desc=A fence made of delicate paper. Be careful!

tile.lantern.firefly.green.name=Green Firefly Lantern
tile.lantern.firefly.green.desc=A glass jar containing a swarm of green fireflies.
tile.lantern.firefly.orange.name=Orange Firefly Lantern
tile.lantern.firefly.orange.desc=A glass jar containing a swarm of orange fireflies.
tile.lantern.firefly.blue.name=Blue Firefly Lantern
tile.lantern.firefly.blue.desc=A glass jar containing a swarm of blue fireflies.
tile.lantern.firefly.red.name=Red Firefly Lantern
tile.lantern.firefly.red.desc=A glass jar containing a swarm of red fireflies.

tile.flag.name=Flag
tile.flag.desc=A flag to mark your territory.

tile.paper_wall.name=Paper Wall
tile.paper_wall.desc=A wall made of delicate paper. Be careful!

tile.trapdoor.planks.oak.painted.name=Painted Trapdoor
tile.trapdoor.planks.oak.painted.desc=How did you get this?!
tile.trapdoor.planks.oak.painted.black.name=Black Oak Trapdoor
tile.trapdoor.planks.oak.painted.black.desc=Like a door, but flat and painted black.
tile.trapdoor.planks.oak.painted.red.name=Red Oak Trapdoor
tile.trapdoor.planks.oak.painted.red.desc=Like a door, but flat and painted red.
tile.trapdoor.planks.oak.painted.green.name=Green Oak Trapdoor
tile.trapdoor.planks.oak.painted.green.desc=Like a door, but flat and painted green.
tile.trapdoor.planks.oak.painted.brown.name=Brown Oak Trapdoor
tile.trapdoor.planks.oak.painted.brown.desc=Like a door, but flat and painted brown.
tile.trapdoor.planks.oak.painted.blue.name=Blue Oak Trapdoor
tile.trapdoor.planks.oak.painted.blue.desc=Like a door, but flat and painted blue.
tile.trapdoor.planks.oak.painted.purple.name=Purple Oak Trapdoor
tile.trapdoor.planks.oak.painted.purple.desc=Like a door, but flat and painted purple.
tile.trapdoor.planks.oak.painted.cyan.name=Cyan Oak Trapdoor
tile.trapdoor.planks.oak.painted.cyan.desc=Like a door, but flat and painted cyan.
tile.trapdoor.planks.oak.painted.silver.name=Light Gray Oak Trapdoor
tile.trapdoor.planks.oak.painted.silver.desc=Like a door, but flat and painted light gray.
tile.trapdoor.planks.oak.painted.gray.name=Gray Oak Trapdoor
tile.trapdoor.planks.oak.painted.gray.desc=Like a door, but flat and painted gray.
tile.trapdoor.planks.oak.painted.pink.name=Pink Oak Trapdoor
tile.trapdoor.planks.oak.painted.pink.desc=Like a door, but flat and painted pink.
tile.trapdoor.planks.oak.painted.lime.name=Lime Oak Trapdoor
tile.trapdoor.planks.oak.painted.lime.desc=Like a door, but flat and painted lime.
tile.trapdoor.planks.oak.painted.yellow.name=Yellow Oak Trapdoor
tile.trapdoor.planks.oak.painted.yellow.desc=Like a door, but flat and painted yellow.
tile.trapdoor.planks.oak.painted.lightblue.name=Light Blue Oak Trapdoor
tile.trapdoor.planks.oak.painted.lightblue.desc=Like a door, but flat and painted light blue.
tile.trapdoor.planks.oak.painted.magenta.name=Magenta Oak Trapdoor
tile.trapdoor.planks.oak.painted.magenta.desc=Like a door, but flat and painted magenta.
tile.trapdoor.planks.oak.painted.orange.name=Orange Oak Trapdoor
tile.trapdoor.planks.oak.painted.orange.desc=Like a door, but flat and painted orange.
tile.trapdoor.planks.oak.painted.white.name=White Oak Trapdoor
tile.trapdoor.planks.oak.painted.white.desc=Like a door, but flat and painted white.

tile.door.planks.oak.painted.bottom.name=Bottom Painted Wooden Door
tile.door.planks.oak.painted.bottom.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.black.name=Black Bottom Wooden Door
tile.door.planks.oak.painted.bottom.black.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.red.name=Red Bottom Wooden Door
tile.door.planks.oak.painted.bottom.red.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.green.name=Green Bottom Wooden Door
tile.door.planks.oak.painted.bottom.green.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.brown.name=Brown Bottom Wooden Door
tile.door.planks.oak.painted.bottom.brown.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.blue.name=Blue Bottom Wooden Door
tile.door.planks.oak.painted.bottom.blue.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.purple.name=Purple Bottom Wooden Door
tile.door.planks.oak.painted.bottom.purple.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.cyan.name=Cyan Bottom Wooden Door
tile.door.planks.oak.painted.bottom.cyan.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.silver.name=Light Gray Bottom Wooden Door
tile.door.planks.oak.painted.bottom.silver.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.gray.name=Gray Bottom Wooden Door
tile.door.planks.oak.painted.bottom.gray.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.pink.name=Pink Bottom Wooden Door
tile.door.planks.oak.painted.bottom.pink.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.lime.name=Lime Bottom Wooden Door
tile.door.planks.oak.painted.bottom.lime.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.yellow.name=Yellow Bottom Wooden Door
tile.door.planks.oak.painted.bottom.yellow.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.lightblue.name=Light Blue Bottom Wooden Door
tile.door.planks.oak.painted.bottom.lightblue.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.magenta.name=Magenta Bottom Wooden Door
tile.door.planks.oak.painted.bottom.magenta.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.orange.name=Orange Bottom Wooden Door
tile.door.planks.oak.painted.bottom.orange.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.white.name=White Bottom Wooden Door
tile.door.planks.oak.painted.bottom.white.desc=How did you get this?!

tile.door.planks.oak.painted.top.name=Top Painted Wooden Door
tile.door.planks.oak.painted.top.desc=How did you get this?!
tile.door.planks.oak.painted.top.black.name=Black Top Wooden Door
tile.door.planks.oak.painted.top.black.desc=How did you get this?!
tile.door.planks.oak.painted.top.red.name=Red Top Wooden Door
tile.door.planks.oak.painted.top.red.desc=How did you get this?!
tile.door.planks.oak.painted.top.green.name=Green Top Wooden Door
tile.door.planks.oak.painted.top.green.desc=How did you get this?!
tile.door.planks.oak.painted.top.brown.name=Brown Top Wooden Door
tile.door.planks.oak.painted.top.brown.desc=How did you get this?!
tile.door.planks.oak.painted.top.blue.name=Blue Top Wooden Door
tile.door.planks.oak.painted.top.blue.desc=How did you get this?!
tile.door.planks.oak.painted.top.purple.name=Purple Top Wooden Door
tile.door.planks.oak.painted.top.purple.desc=How did you get this?!
tile.door.planks.oak.painted.top.cyan.name=Cyan Top Wooden Door
tile.door.planks.oak.painted.top.cyan.desc=How did you get this?!
tile.door.planks.oak.painted.top.silver.name=Light Gray Top Wooden Door
tile.door.planks.oak.painted.top.silver.desc=How did you get this?!
tile.door.planks.oak.painted.top.gray.name=Gray Top Wooden Door
tile.door.planks.oak.painted.top.gray.desc=How did you get this?!
tile.door.planks.oak.painted.top.pink.name=Pink Top Wooden Door
tile.door.planks.oak.painted.top.pink.desc=How did you get this?!
tile.door.planks.oak.painted.top.lime.name=Lime Top Wooden Door
tile.door.planks.oak.painted.top.lime.desc=How did you get this?!
tile.door.planks.oak.painted.top.yellow.name=Yellow Top Wooden Door
tile.door.planks.oak.painted.top.yellow.desc=How did you get this?!
tile.door.planks.oak.painted.top.lightblue.name=Light Blue Top Wooden Door
tile.door.planks.oak.painted.top.lightblue.desc=How did you get this?!
tile.door.planks.oak.painted.top.magenta.name=Magenta Top Wooden Door
tile.door.planks.oak.painted.top.magenta.desc=How did you get this?!
tile.door.planks.oak.painted.top.orange.name=Orange Top Wooden Door
tile.door.planks.oak.painted.top.orange.desc=How did you get this?!
tile.door.planks.oak.painted.top.white.name=White Top Wooden Door
tile.door.planks.oak.painted.top.white.desc=How did you get this?!

tile.door.glass.top.name=Top Glass Door
tile.door.glass.top.desc=You shouldn't be seeing this.
tile.door.glass.bottom.name=Bottom Glass Door
tile.door.glass.bottom.desc=And that's not just because it's glass.

tile.door.steel.top.name=Top Steel Door
tile.door.steel.top.desc=Don't take this without asking.
tile.door.steel.bottom.name=Bottom Steel Door
tile.door.steel.bottom.desc=Steeler, no steeling!

tile.trapdoor.steel.name=Steel Trapdoor
tile.trapdoor.steel.desc=Like a door, but flat and made of durable steel.

tile.glass.steel.name=Reinforced Glass
tile.glass.steel.desc=Like glass, but without the fragility.

tile.rope.name=Rope
tile.rope.desc=Rope, rope, rope your boat.
\ No newline at end of file
+tile.stone.name=Stone
tile.stone.desc=A block of solid stone.
tile.basalt.name=Basalt
tile.basalt.desc=A block of solid basalt.
tile.limestone.name=Limestone
tile.limestone.desc=A block of solid limestone.
tile.granite.name=Granite
tile.granite.desc=A block of solid granite.
tile.marble.name=Marble
tile.marble.desc=A block of solid marble.
tile.slate.name=Slate
tile.slate.desc=A block of solid slate.
tile.permafrost.name=Permafrost
tile.permafrost.desc=A block of frozen stone.

tile.cobble.stone.name=Cobblestone
tile.cobble.stone.desc=Stone, smashed apart and reconstituted.
tile.cobble.stone.mossy.name=Mossy Cobblestone
tile.cobble.stone.mossy.desc=Cobblestone with added greenery.
tile.cobble.basalt.name=Cobbled Basalt
tile.cobble.basalt.desc=Basalt, smashed apart and reconstituted.
tile.cobble.limestone.name=Cobbled Limestone
tile.cobble.limestone.desc=Limestone, smashed apart and reconstituted.
tile.cobble.granite.name=Cobbled Granite
tile.cobble.granite.desc=Granite, smashed apart and reconstituted.
tile.cobble.permafrost.name=Cobbled Permafrost
tile.cobble.permafrost.desc=Permafrost, smashed apart and reconstituted.

tile.pillar.marble.name=Marble Pillar
tile.pillar.marble.desc=A block of marble engraved into a pillar.
tile.capstone.marble.name=Marble Capstone
tile.capstone.marble.desc=A pillar capstone made of solid marble.

tile.sandstone.name=Sandstone
tile.sandstone.desc=Compacted sand.

tile.stone.carved.name=Carved Stone
tile.stone.carved.desc=Polished Stone with lines hewn through the middle.
tile.granite.carved.name=Carved Granite
tile.granite.carved.desc=Polished Granite with lines hewn through the middle.
tile.limestone.carved.name=Carved Limestone
tile.limestone.carved.desc=Polished Limestone with lines hewn through the middle.
tile.basalt.carved.name=Carved Basalt
tile.basalt.carved.desc=Polished Basalt with lines hewn through the middle.
tile.permafrost.carved.name=Carved Permafrost
tile.permafrost.carved.desc=Polished Permafrost with lines hewn through the middle.
tile.netherrack.carved.name=Carved Netherrack
tile.netherrack.carved.desc=Polished Netherrack with lines hewn through the middle.

tile.planks.oak.name=Wooden Planks
tile.planks.oak.desc=Processed tree insides.
tile.planks.oak.painted.name=Mystery Planks
tile.planks.oak.painted.desc=How did you get this?!
tile.planks.oak.painted.black.name=Black Wooden Planks
tile.planks.oak.painted.black.desc=Wooden planks, stained black.
tile.planks.oak.painted.red.name=Red Wooden Planks
tile.planks.oak.painted.red.desc=Wooden planks, stained red.
tile.planks.oak.painted.green.name=Green Wooden Planks
tile.planks.oak.painted.green.desc=Wooden planks, stained green.
tile.planks.oak.painted.brown.name=Brown Wooden Planks
tile.planks.oak.painted.brown.desc=Wooden planks, stained brown.
tile.planks.oak.painted.blue.name=Blue Wooden Planks
tile.planks.oak.painted.blue.desc=Wooden planks, stained blue.
tile.planks.oak.painted.purple.name=Purple Wooden Planks
tile.planks.oak.painted.purple.desc=Wooden planks, stained purple.
tile.planks.oak.painted.cyan.name=Cyan Wooden Planks
tile.planks.oak.painted.cyan.desc=Wooden planks, stained cyan.
tile.planks.oak.painted.silver.name=Light Gray Wooden Planks
tile.planks.oak.painted.silver.desc=Wooden planks, stained light gray.
tile.planks.oak.painted.gray.name=Gray Wooden Planks
tile.planks.oak.painted.gray.desc=Wooden planks, stained gray.
tile.planks.oak.painted.pink.name=Pink Wooden Planks
tile.planks.oak.painted.pink.desc=Wooden planks, stained pink.
tile.planks.oak.painted.lime.name=Lime Wooden Planks
tile.planks.oak.painted.lime.desc=Wooden planks, stained lime.
tile.planks.oak.painted.yellow.name=Yellow Wooden Planks
tile.planks.oak.painted.yellow.desc=Wooden planks, stained yellow.
tile.planks.oak.painted.lightblue.name=Light Blue Wooden Planks
tile.planks.oak.painted.lightblue.desc=Wooden planks, stained light blue.
tile.planks.oak.painted.magenta.name=Magenta Wooden Planks
tile.planks.oak.painted.magenta.desc=Wooden planks, stained magenta.
tile.planks.oak.painted.orange.name=Orange Wooden Planks
tile.planks.oak.painted.orange.desc=Wooden planks, stained orange.
tile.planks.oak.painted.white.name=White Wooden Planks
tile.planks.oak.painted.white.desc=Wooden planks, stained white.

tile.torch.coal.name=Torch
tile.torch.coal.desc=Helps light the way.

tile.ladder.oak.name=Oak Ladder
tile.ladder.oak.desc=For very rapid vertical movement.

tile.fence.planks.oak.name=Oak Fence
tile.fence.planks.oak.desc=Too tall to jump over.

tile.fence.planks.oak.painted.name=Mystery Wooden Fence
tile.fence.planks.oak.painted.desc=How did you get this?!
tile.fence.planks.oak.painted.black.name=Black Wooden Fence
tile.fence.planks.oak.painted.black.desc=A wooden fence, stained black.
tile.fence.planks.oak.painted.red.name=Red Wooden Fence
tile.fence.planks.oak.painted.red.desc=A wooden fence, stained red.
tile.fence.planks.oak.painted.green.name=Green Wooden Fence
tile.fence.planks.oak.painted.green.desc=A wooden fence, stained green.
tile.fence.planks.oak.painted.brown.name=Brown Wooden Fence
tile.fence.planks.oak.painted.brown.desc=A wooden fence, stained brown.
tile.fence.planks.oak.painted.blue.name=Blue Wooden Fence
tile.fence.planks.oak.painted.blue.desc=A wooden fence, stained blue.
tile.fence.planks.oak.painted.purple.name=Purple Wooden Fence
tile.fence.planks.oak.painted.purple.desc=A wooden fence, stained purple.
tile.fence.planks.oak.painted.cyan.name=Cyan Wooden Fence
tile.fence.planks.oak.painted.cyan.desc=A wooden fence, stained cyan.
tile.fence.planks.oak.painted.silver.name=Light Gray Wooden Fence
tile.fence.planks.oak.painted.silver.desc=A wooden fence, stained light gray.
tile.fence.planks.oak.painted.gray.name=Gray Wooden Fence
tile.fence.planks.oak.painted.gray.desc=A wooden fence, stained gray.
tile.fence.planks.oak.painted.pink.name=Pink Wooden Fence
tile.fence.planks.oak.painted.pink.desc=A wooden fence, stained pink.
tile.fence.planks.oak.painted.lime.name=Lime Wooden Fence
tile.fence.planks.oak.painted.lime.desc=A wooden fence, stained lime.
tile.fence.planks.oak.painted.yellow.name=Yellow Wooden Fence
tile.fence.planks.oak.painted.yellow.desc=A wooden fence, stained yellow.
tile.fence.planks.oak.painted.lightblue.name=Light Blue Wooden Fence
tile.fence.planks.oak.painted.lightblue.desc=A wooden fence, stained light blue.
tile.fence.planks.oak.painted.magenta.name=Magenta Wooden Fence
tile.fence.planks.oak.painted.magenta.desc=A wooden fence, stained magenta.
tile.fence.planks.oak.painted.orange.name=Orange Wooden Fence
tile.fence.planks.oak.painted.orange.desc=A wooden fence, stained orange.
tile.fence.planks.oak.painted.white.name=White Wooden Fence
tile.fence.planks.oak.painted.white.desc=A wooden fence, stained white.

tile.fencegate.planks.oak.name=Wooden Fence Gate
tile.fencegate.planks.oak.desc=Like a door but for fences.

tile.fencegate.planks.oak.painted.name=Mystery Wooden Fence Gate
tile.fencegate.planks.oak.painted.desc=How did you get this?!
tile.fencegate.planks.oak.painted.black.name=Black Wooden Fence Gate
tile.fencegate.planks.oak.painted.black.desc=A wooden fence gate, stained black.
tile.fencegate.planks.oak.painted.red.name=Red Wooden Fence Gate
tile.fencegate.planks.oak.painted.red.desc=A wooden fence gate, stained red.
tile.fencegate.planks.oak.painted.green.name=Green Wooden Fence Gate
tile.fencegate.planks.oak.painted.green.desc=A wooden fence gate, stained green.
tile.fencegate.planks.oak.painted.brown.name=Brown Wooden Fence Gate
tile.fencegate.planks.oak.painted.brown.desc=A wooden fence gate, stained brown.
tile.fencegate.planks.oak.painted.blue.name=Blue Wooden Fence Gate
tile.fencegate.planks.oak.painted.blue.desc=A wooden fence gate, stained blue.
tile.fencegate.planks.oak.painted.purple.name=Purple Wooden Fence Gate
tile.fencegate.planks.oak.painted.purple.desc=A wooden fence gate, stained purple.
tile.fencegate.planks.oak.painted.cyan.name=Cyan Wooden Fence Gate
tile.fencegate.planks.oak.painted.cyan.desc=A wooden fence gate, stained cyan.
tile.fencegate.planks.oak.painted.silver.name=Light Gray Wooden Fence Gate
tile.fencegate.planks.oak.painted.silver.desc=A wooden fence gate, stained light gray.
tile.fencegate.planks.oak.painted.gray.name=Gray Wooden Fence Gate
tile.fencegate.planks.oak.painted.gray.desc=A wooden fence gate, stained gray.
tile.fencegate.planks.oak.painted.pink.name=Pink Wooden Fence Gate
tile.fencegate.planks.oak.painted.pink.desc=A wooden fence gate, stained pink.
tile.fencegate.planks.oak.painted.lime.name=Lime Wooden Fence Gate
tile.fencegate.planks.oak.painted.lime.desc=A wooden fence gate, stained lime.
tile.fencegate.planks.oak.painted.yellow.name=Yellow Wooden Fence Gate
tile.fencegate.planks.oak.painted.yellow.desc=A wooden fence gate, stained yellow.
tile.fencegate.planks.oak.painted.lightblue.name=Light Blue Wooden Fence Gate
tile.fencegate.planks.oak.painted.lightblue.desc=A wooden fence gate, stained light blue.
tile.fencegate.planks.oak.painted.magenta.name=Magenta Wooden Fence Gate
tile.fencegate.planks.oak.painted.magenta.desc=A wooden fence gate, stained magenta.
tile.fencegate.planks.oak.painted.orange.name=Orange Wooden Fence Gate
tile.fencegate.planks.oak.painted.orange.desc=A wooden fence gate, stained orange.
tile.fencegate.planks.oak.painted.white.name=White Wooden Fence Gate
tile.fencegate.planks.oak.painted.white.desc=A wooden fence gate, stained white.

tile.bookshelf.planks.oak.name=Bookshelf
tile.bookshelf.planks.oak.desc=A repository of knowledge.

tile.wool.name=Wool
tile.wool.desc=How did you get this?!
tile.wool.black.name=Black Wool
tile.wool.black.desc=Sheep's wool, dyed black.
tile.wool.red.name=Red Wool
tile.wool.red.desc=Sheep's wool, dyed red.
tile.wool.green.name=Green Wool
tile.wool.green.desc=Sheep's wool, dyed green.
tile.wool.brown.name=Brown Wool
tile.wool.brown.desc=Sheep's wool, dyed brown.
tile.wool.blue.name=Blue Wool
tile.wool.blue.desc=Sheep's wool, dyed blue.
tile.wool.purple.name=Purple Wool
tile.wool.purple.desc=Sheep's wool, dyed purple.
tile.wool.cyan.name=Cyan Wool
tile.wool.cyan.desc=Sheep's wool, dyed cyan.
tile.wool.silver.name=Light Gray Wool
tile.wool.silver.desc=Sheep's wool, dyed light gray.
tile.wool.gray.name=Gray Wool
tile.wool.gray.desc=Sheep's wool, dyed gray.
tile.wool.pink.name=Pink Wool
tile.wool.pink.desc=Sheep's wool, dyed pink.
tile.wool.lime.name=Lime Wool
tile.wool.lime.desc=Sheep's wool, dyed lime.
tile.wool.yellow.name=Yellow Wool
tile.wool.yellow.desc=Sheep's wool, dyed yellow.
tile.wool.lightblue.name=Light Blue Wool
tile.wool.lightblue.desc=Sheep's wool, dyed light blue.
tile.wool.magenta.name=Magenta Wool
tile.wool.magenta.desc=Sheep's wool, dyed magenta.
tile.wool.orange.name=Orange Wool
tile.wool.orange.desc=Sheep's wool, dyed orange.
tile.wool.white.name=White Wool
tile.wool.white.desc=Sheep's wool, dyed white.

tile.brick.clay.name=Clay Bricks
tile.brick.clay.desc=Stacked bricks of baked clay.
tile.brick.stone.polished.name=Polished Stone Bricks
tile.brick.stone.polished.desc=Stacked bricks of polished stone.
tile.brick.stone.polished.mossy.name=Mossy Polished Stone Bricks
tile.brick.stone.polished.mossy.desc=Stacked bricks of polished stone with added greenery.
tile.brick.sandstone.name=Sandstone Bricks
tile.brick.sandstone.desc=Stacked bricks of sandstone.
tile.brick.gold.name=Gold Bricks
tile.brick.gold.desc=Stacked bricks of gold.
tile.brick.lapis.name=Lapis Lazuli Bricks
tile.brick.lapis.desc=Stacked bricks of lapis lazuli.
tile.brick.basalt.name=Basalt Bricks
tile.brick.basalt.desc=Stacked bricks of basalt.
tile.brick.limestone.name=Limestone Bricks
tile.brick.limestone.desc=Stacked bricks of limestone.
tile.brick.granite.name=Granite Bricks
tile.brick.granite.desc=Stacked bricks of granite.
tile.brick.marble.name=Marble Bricks
tile.brick.marble.desc=Stacked bricks of marble.
tile.brick.slate.name=Slate Bricks
tile.brick.slate.desc=Stacked bricks of slate.
tile.brick.stone.name=Stone Bricks
tile.brick.stone.desc=Stacked bricks of stone.
tile.brick.permafrost.name=Permafrost Bricks
tile.brick.permafrost.desc=Stacked bricks of permafrost.
tile.brick.iron.name=Iron Bricks
tile.brick.iron.desc=Stacked bricks of iron.

tile.slab.planks.oak.name=Wooden Slab
tile.slab.planks.oak.desc=A slab of wooden planks.
tile.slab.cobble.stone.name=Cobblestone Slab
tile.slab.cobble.stone.desc=A slab of cobblestone.
tile.slab.sandstone.name=Sandstone Slab
tile.slab.sandstone.desc=A slab of sandstone.
tile.slab.brick.stone.polished.name=Polished Stone Brick Slab
tile.slab.brick.stone.polished.desc=A slab of polished stone bricks.
tile.slab.stone.carved.name=Polished Stone Slab
tile.slab.stone.carved.desc=A slab of polished stone.
tile.slab.brick.marble.name=Marble Brick Slab
tile.slab.brick.marble.desc=A slab of marble bricks.
tile.slab.brick.clay.name=Clay Brick Slab
tile.slab.brick.clay.desc=A slab of clay bricks.
tile.slab.capstone.marble.name=Marble Capstone Slab
tile.slab.capstone.marble.desc=Marble sculpted into a capstone.
tile.slab.cobble.basalt.name=Cobbled Basalt Slab
tile.slab.cobble.basalt.desc=A slab of cobbled basalt.
tile.slab.cobble.limestone.name=Cobbled Limestone Slab
tile.slab.cobble.limestone.desc=A slab of cobbled limestone.
tile.slab.cobble.granite.name=Cobbled Granite Slab
tile.slab.cobble.granite.desc=A slab of cobbled granite.
tile.slab.brick.basalt.name=Basalt Brick Slab
tile.slab.brick.basalt.desc=A slab of basalt bricks.
tile.slab.brick.limestone.name=Limestone Brick Slab
tile.slab.brick.limestone.desc=A slab of limestone bricks.
tile.slab.brick.granite.name=Granite Brick Slab
tile.slab.brick.granite.desc=A slab of granite bricks.
tile.slab.brick.slate.name=Slate Brick Slab
tile.slab.brick.slate.desc=A slab of slate bricks.
tile.slab.brick.stone.name=Stone Brick Slab
tile.slab.brick.stone.desc=A slab of stone bricks.
tile.slab.granite.carved.name=Polished Granite Slab
tile.slab.granite.carved.desc=A slab of polished granite.
tile.slab.limestone.carved.name=Polished Limestone Slab
tile.slab.limestone.carved.desc=A slab of polished limestone.
tile.slab.basalt.carved.name=Polished Basalt Slab
tile.slab.basalt.carved.desc=A slab of polished basalt.
tile.slab.permafrost.carved.name=Polished Permafrost Slab
tile.slab.permafrost.carved.desc=A slab of polished permafrost.

tile.slab.planks.oak.painted.name=Mystery Wooden Slab
tile.slab.planks.oak.painted.desc=How did you get this?!
tile.slab.planks.oak.painted.black.name=Black Wooden Slab
tile.slab.planks.oak.painted.black.desc=A slab of wooden planks, stained black.
tile.slab.planks.oak.painted.red.name=Red Wooden Slab
tile.slab.planks.oak.painted.red.desc=A slab of wooden planks, stained red.
tile.slab.planks.oak.painted.green.name=Green Wooden Slab
tile.slab.planks.oak.painted.green.desc=A slab of wooden planks, stained green.
tile.slab.planks.oak.painted.brown.name=Brown Wooden Slab
tile.slab.planks.oak.painted.brown.desc=A slab of wooden planks, stained brown.
tile.slab.planks.oak.painted.blue.name=Blue Wooden Slab
tile.slab.planks.oak.painted.blue.desc=A slab of wooden planks, stained blue.
tile.slab.planks.oak.painted.purple.name=Purple Wooden Slab
tile.slab.planks.oak.painted.purple.desc=A slab of wooden planks, stained purple.
tile.slab.planks.oak.painted.cyan.name=Cyan Wooden Slab
tile.slab.planks.oak.painted.cyan.desc=A slab of wooden planks, stained cyan.
tile.slab.planks.oak.painted.silver.name=Light Gray Wooden Slab
tile.slab.planks.oak.painted.silver.desc=A slab of wooden planks, stained light gray.
tile.slab.planks.oak.painted.gray.name=Gray Wooden Slab
tile.slab.planks.oak.painted.gray.desc=A slab of wooden planks, stained gray.
tile.slab.planks.oak.painted.pink.name=Pink Wooden Slab
tile.slab.planks.oak.painted.pink.desc=A slab of wooden planks, stained pink.
tile.slab.planks.oak.painted.lime.name=Lime Wooden Slab
tile.slab.planks.oak.painted.lime.desc=A slab of wooden planks, stained lime.
tile.slab.planks.oak.painted.yellow.name=Yellow Wooden Slab
tile.slab.planks.oak.painted.yellow.desc=A slab of wooden planks, stained yellow.
tile.slab.planks.oak.painted.lightblue.name=Light Blue Wooden Slab
tile.slab.planks.oak.painted.lightblue.desc=A slab of wooden planks, stained light blue.
tile.slab.planks.oak.painted.magenta.name=Magenta Wooden Slab
tile.slab.planks.oak.painted.magenta.desc=A slab of wooden planks, stained magenta.
tile.slab.planks.oak.painted.orange.name=Orange Wooden Slab
tile.slab.planks.oak.painted.orange.desc=A slab of wooden planks, stained orange.
tile.slab.planks.oak.painted.white.name=White Wooden Slab
tile.slab.planks.oak.painted.white.desc=A slab of wooden planks, stained white.
tile.slab.cobble.permafrost.name=Cobbled Permafrost Slab
tile.slab.cobble.permafrost.desc=A slab of cobbled permafrost.
tile.slab.brick.sandstone.name=Sandstone Brick Slab
tile.slab.brick.sandstone.desc=A slab of sandstone bricks.
tile.slab.brick.permafrost.name=Permafrost Brick Slab
tile.slab.brick.permafrost.desc=A slab of permafrost bricks.

tile.stairs.planks.oak.name=Wooden Stairs
tile.stairs.planks.oak.desc=Wooden block used for rapid vertical movement.
tile.stairs.cobble.stone.name=Cobblestone Stairs
tile.stairs.cobble.stone.desc=Cobblestone block used for rapid vertical movement.
tile.stairs.brick.stone.polished.name=Polished Stone Brick Stairs
tile.stairs.brick.stone.polished.desc=Polished stone brick block used for rapid vertical movement.
tile.stairs.brick.marble.name=Marble Brick Stairs
tile.stairs.brick.marble.desc=Marble brick block used for rapid vertical movement.
tile.stairs.cobble.basalt.name=Cobbled Basalt Stairs
tile.stairs.cobble.basalt.desc=Cobbled basalt block used for rapid vertical movement.
tile.stairs.cobble.limestone.name=Cobbled Limestone Stairs
tile.stairs.cobble.limestone.desc=Cobbled limestone block used for rapid vertical movement.
tile.stairs.cobble.granite.name=Cobbled Granite Stairs
tile.stairs.cobble.granite.desc=Cobbled granite block used for rapid vertical movement.
tile.stairs.brick.basalt.name=Basalt Brick Stairs
tile.stairs.brick.basalt.desc=Basalt brick block used for rapid vertical movement.
tile.stairs.brick.limestone.name=Limestone Brick Stairs
tile.stairs.brick.limestone.desc=Limestone brick block used for rapid vertical movement.
tile.stairs.brick.granite.name=Granite Brick Stairs
tile.stairs.brick.granite.desc=Granite brick block used for rapid vertical movement.
tile.stairs.brick.clay.name=Clay Brick Stairs
tile.stairs.brick.clay.desc=Clay brick block used for rapid vertical movement.
tile.stairs.brick.slate.name=Slate Brick Stairs
tile.stairs.brick.slate.desc=Slate brick block used for rapid vertical movement.
tile.stairs.brick.stone.name=Stone Brick Stairs
tile.stairs.brick.stone.desc=Stone brick block used for rapid vertical movement.
tile.stairs.sandstone.name=Sandstone Stairs
tile.stairs.sandstone.desc=Sandstone block used for rapid vertical movement.
tile.stairs.cobble.permafrost.name=Cobbled Permafrost Stairs
tile.stairs.cobble.permafrost.desc=Cobbled permafrost block used for rapid vertical movement.
tile.stairs.brick.sandstone.name=Sandstone Brick Stairs
tile.stairs.brick.sandstone.desc=Sandstone brick block used for rapid vertical movement.
tile.stairs.brick.permafrost.name=Permafrost Brick Stairs
tile.stairs.brick.permafrost.desc=Permafrost brick block used for rapid vertical movement.

tile.stairs.planks.oak.painted.name=Mystery Wooden Stairs
tile.stairs.planks.oak.painted.desc=How did you get this?!
tile.stairs.planks.oak.painted.black.name=Black Wooden Stairs
tile.stairs.planks.oak.painted.black.desc=Wooden steps, stained black.
tile.stairs.planks.oak.painted.red.name=Red Wooden Stairs
tile.stairs.planks.oak.painted.red.desc=Wooden steps, stained red.
tile.stairs.planks.oak.painted.green.name=Green Wooden Stairs
tile.stairs.planks.oak.painted.green.desc=Wooden steps, stained green.
tile.stairs.planks.oak.painted.brown.name=Brown Wooden Stairs
tile.stairs.planks.oak.painted.brown.desc=Wooden steps, stained brown.
tile.stairs.planks.oak.painted.blue.name=Blue Wooden Stairs
tile.stairs.planks.oak.painted.blue.desc=Wooden steps, stained blue.
tile.stairs.planks.oak.painted.purple.name=Purple Wooden Stairs
tile.stairs.planks.oak.painted.purple.desc=Wooden steps, stained purple.
tile.stairs.planks.oak.painted.cyan.name=Cyan Wooden Stairs
tile.stairs.planks.oak.painted.cyan.desc=Wooden steps, stained cyan.
tile.stairs.planks.oak.painted.silver.name=Light Gray Wooden Stairs
tile.stairs.planks.oak.painted.silver.desc=Wooden steps, stained light gray.
tile.stairs.planks.oak.painted.gray.name=Gray Wooden Stairs
tile.stairs.planks.oak.painted.gray.desc=Wooden steps, stained gray.
tile.stairs.planks.oak.painted.pink.name=Pink Wooden Stairs
tile.stairs.planks.oak.painted.pink.desc=Wooden steps, stained pink.
tile.stairs.planks.oak.painted.lime.name=Lime Wooden Stairs
tile.stairs.planks.oak.painted.lime.desc=Wooden steps, stained lime.
tile.stairs.planks.oak.painted.yellow.name=Yellow Wooden Stairs
tile.stairs.planks.oak.painted.yellow.desc=Wooden steps, stained yellow.
tile.stairs.planks.oak.painted.lightblue.name=Light Blue Wooden Stairs
tile.stairs.planks.oak.painted.lightblue.desc=Wooden steps, stained light blue.
tile.stairs.planks.oak.painted.magenta.name=Magenta Wooden Stairs
tile.stairs.planks.oak.painted.magenta.desc=Wooden steps, stained magenta.
tile.stairs.planks.oak.painted.orange.name=Orange Wooden Stairs
tile.stairs.planks.oak.painted.orange.desc=Wooden steps, stained orange.
tile.stairs.planks.oak.painted.white.name=White Wooden Stairs
tile.stairs.planks.oak.painted.white.desc=Wooden steps, stained white.

tile.obsidian.name=Obsidian
tile.obsidian.desc=Rapidly cooled volcanic rock.

tile.glass.name=Glass
tile.glass.desc=Sand heated until it becomes translucent.
tile.glass.tinted.name=Tinted Glass
tile.glass.tinted.desc=Darkened glass that blocks light.

tile.grass.name=Grass
tile.grass.desc=Crisp, crunchy grass.
tile.grass.retro.name=Retro Grass
tile.grass.retro.desc=Crisp, crunchy grass. Smells old.
tile.grass.scorched.name=Scorched Grass
tile.grass.scorched.desc=Grass that has baked in the sun.

tile.path.dirt.name=Dirt Path
tile.path.dirt.desc=Dirt worn down by frequent travelling.

tile.dirt.name=Dirt
tile.dirt.desc=Crumbly brown dirt.
tile.dirt.scorched.name=Scorched Dirt
tile.dirt.scorched.desc=Dirt that has baked in the sun.
tile.dirt.scorched.rich.name=Rich Scorched Dirt
tile.dirt.scorched.rich.desc=Dirt that has baked in the sun, searing in minerals.

tile.mud.name=Mud
tile.mud.desc=Mud sodden to its core.
tile.mud.baked.name=Baked Mud
tile.mud.baked.desc=Mud that's been dried out and cracked.

tile.sponge.dry.name=Sponge
tile.sponge.dry.desc=A dry sponge, good for soaking up water.
tile.sponge.wet.name=Wet Sponge
tile.sponge.wet.desc=A sponge full of water.
tile.pumice.dry.name=Pumice
tile.pumice.dry.desc=A dry porous volcanic rock, good for soaking up lava.
tile.pumice.wet.name=Molten Pumice
tile.pumice.wet.desc=Rock filled with lava.

tile.moss.stone.name=Mossy Stone
tile.moss.stone.desc=Moss covering a block of stone.
tile.moss.basalt.name=Mossy Basalt
tile.moss.basalt.desc=Moss covering a block of basalt.
tile.moss.limestone.name=Mossy Limestone
tile.moss.limestone.desc=Moss covering a block of limestone.
tile.moss.granite.name=Mossy Granite
tile.moss.granite.desc=Moss covering a block of granite.

tile.sand.name=Sand
tile.sand.desc=Gets everywhere.
tile.gravel.name=Gravel
tile.gravel.desc=A loose collection of pebbles.

tile.bedrock.name=Bedrock
tile.bedrock.desc=The toughest substance known to man.
tile.boneshale.name=Bone Shale
tile.boneshale.desc=An incredibly tough white rock torn from the deepest depths.

tile.fluid.water.flowing.name=Flowing Water
tile.fluid.water.flowing.desc=Water that flows when placed.
tile.fluid.water.still.name=Still Water
tile.fluid.water.still.desc=Water that does not flow when placed.
tile.fluid.lava.flowing.name=Flowing Lava
tile.fluid.lava.flowing.desc=Lava that flows when placed.
tile.fluid.lava.still.name=Still Lava
tile.fluid.lava.still.desc=Lava that does not flow when placed.

tile.log.oak.name=Oak Log
tile.log.oak.desc=A log from an oak tree.
tile.log.pine.name=Pine Log
tile.log.pine.desc=A log from a pine tree.
tile.log.birch.name=Birch Log
tile.log.birch.desc=A log from a birch tree.
tile.log.cherry.name=Cherry Log
tile.log.cherry.desc=A log from a cherry tree.
tile.log.eucalyptus.name=Eucalyptus Log
tile.log.eucalyptus.desc=A log from a eucalyptus tree.
tile.log.oak.mossy.name=Mossy Oak Log
tile.log.oak.mossy.desc=A log from a mossy oak tree.
tile.log.thorn.name=Thorn Log
tile.log.thorn.desc=A log from a thorn tree.
tile.log.palm.name=Palm Log
tile.log.palm.desc=A log from a palm tree.

tile.leaves.oak.name=Oak Leaves
tile.leaves.oak.desc=Leaves from an oak tree.
tile.leaves.pine.name=Pine Leaves
tile.leaves.pine.desc=Leaves from a pine tree.
tile.leaves.birch.name=Birch Leaves
tile.leaves.birch.desc=Leaves from a birch tree.
tile.leaves.cherry.name=Cherry Leaves
tile.leaves.cherry.desc=Leaves from a cherry tree.
tile.leaves.eucalyptus.name=Eucalyptus Leaves
tile.leaves.eucalyptus.desc=Leaves from a eucalyptus tree.
tile.leaves.oak.retro.name=Retro Leaves
tile.leaves.oak.retro.desc=Leaves from long ago.
tile.leaves.shrub.name=Shrub Leaves
tile.leaves.shrub.desc=Leaves from a shrub.
tile.leaves.cherry.flowering.name=Flowering Cherry Leaves
tile.leaves.cherry.flowering.desc=Leaves from a cherry tree that are budding with fruit.
tile.leaves.cacao.name=Cacao Leaves
tile.leaves.cacao.desc=Leaves from a cacao tree.
tile.leaves.thorn.name=Thorn Leaves
tile.leaves.thorn.desc=Leaves from a thorn tree.
tile.leaves.palm.name=Palm Leaves
tile.leaves.palm.desc=Leaves from a palm tree.

tile.sapling.oak.name=Oak Sapling
tile.sapling.oak.desc=Plant to grow an oak tree.
tile.sapling.pine.name=Pine Sapling
tile.sapling.pine.desc=Plant to grow a pine tree.
tile.sapling.birch.name=Birch Sapling
tile.sapling.birch.desc=Plant to grow a birch tree.
tile.sapling.cherry.name=Cherry Sapling
tile.sapling.cherry.desc=Plant to grow a cherry tree.
tile.sapling.eucalyptus.name=Eucalyptus Sapling
tile.sapling.eucalyptus.desc=Plant to grow a eucalyptus tree.
tile.sapling.oak.retro.name=Retro Oak Sapling
tile.sapling.oak.retro.desc=Plant to grow a tree from long ago.
tile.sapling.shrub.name=Shrub Sapling
tile.sapling.shrub.desc=Plant to grow a shrub.
tile.sapling.cacao.name=Cacao Sapling
tile.sapling.cacao.desc=Plant to grow a cacao tree.
tile.sapling.thorn.name=Thorn Sapling
tile.sapling.thorn.desc=Plant to grow a thorn tree.
tile.sapling.palm.name=Palm Sapling
tile.sapling.palm.desc=Plant to grow a palm tree.

tile.tallgrass.name=Tall Grass
tile.tallgrass.desc=Lush, growing grass.
tile.tallgrass.fern.name=Fern
tile.tallgrass.fern.desc=A fern plant.
tile.deadbush.name=Dead Bush
tile.deadbush.desc=A dried and withered plant.
tile.spinifex.name=Spinifex
tile.spinifex.desc=A spindly, thin grass from dry regions.
tile.algae.name=Algae
tile.algae.desc=Gooey vegetation that floats on the water's surface.

tile.flower.yellow.name=Dandelion
tile.flower.yellow.desc=A beautiful yellow flower.
tile.flower.red.name=Rose
tile.flower.red.desc=A beautiful red flower.
tile.flower.purple.name=Heather
tile.flower.purple.desc=Sprigs of purple petals. Brings good luck.
tile.flower.lightblue.name=Bluebell
tile.flower.lightblue.desc=A sad-looking blue flower.
tile.flower.pink.name=Orchid
tile.flower.pink.desc=A beautiful pink flower.
tile.flower.orange.name=Marigold
tile.flower.orange.desc=A beautiful orange flower.

tile.mushroom.red.name=Red Mushroom
tile.mushroom.red.desc=A tasty red mushroom. Good for stew.
tile.mushroom.brown.name=Brown Mushroom
tile.mushroom.brown.desc=A tasty brown mushroom. Good for stew.

tile.ore.coal.stone.name=Stone Coal Ore
tile.ore.coal.stone.desc=A chunk of coal embedded in stone.
tile.ore.coal.basalt.name=Basalt Coal Ore
tile.ore.coal.basalt.desc=A chunk of coal embedded in basalt.
tile.ore.coal.limestone.name=Limestone Coal Ore
tile.ore.coal.limestone.desc=A chunk of coal embedded in limestone.
tile.ore.coal.granite.name=Granite Coal Ore
tile.ore.coal.granite.desc=A chunk of coal embedded in granite.
tile.ore.coal.permafrost.name=Permafrost Coal Ore
tile.ore.coal.permafrost.desc=A chunk of coal embedded in permafrost.

tile.ore.iron.stone.name=Stone Iron Ore
tile.ore.iron.stone.desc=Iron nuggets embedded in stone.
tile.ore.iron.basalt.name=Basalt Iron Ore
tile.ore.iron.basalt.desc=Iron nuggets embedded in basalt.
tile.ore.iron.limestone.name=Limestone Iron Ore
tile.ore.iron.limestone.desc=Iron nuggets embedded in limestone.
tile.ore.iron.granite.name=Granite Iron Ore
tile.ore.iron.granite.desc=Iron nuggets embedded in granite.
tile.ore.iron.permafrost.name=Permafrost Iron Ore
tile.ore.iron.permafrost.desc=Iron nuggets embedded in permafrost.

tile.ore.gold.stone.name=Stone Gold Ore
tile.ore.gold.stone.desc=Gold nuggets embedded in stone.
tile.ore.gold.basalt.name=Basalt Gold Ore
tile.ore.gold.basalt.desc=Gold nuggets embedded in basalt.
tile.ore.gold.limestone.name=Limestone Gold Ore
tile.ore.gold.limestone.desc=Gold nuggets embedded in limestone.
tile.ore.gold.granite.name=Granite Gold Ore
tile.ore.gold.granite.desc=Gold nuggets embedded in granite.
tile.ore.gold.permafrost.name=Permafrost Gold Ore
tile.ore.gold.permafrost.desc=Gold nuggets embedded in permafrost.

tile.ore.lapis.stone.name=Stone Lapis Lazuli Ore
tile.ore.lapis.stone.desc=Chunks of lapis lazuli embedded in stone.
tile.ore.lapis.basalt.name=Basalt Lapis Lazuli Ore
tile.ore.lapis.basalt.desc=Chunks of lapis lazuli embedded in basalt.
tile.ore.lapis.limestone.name=Limestone Lapis Lazuli Ore
tile.ore.lapis.limestone.desc=Chunks of lapis lazuli embedded in limestone.
tile.ore.lapis.granite.name=Granite Lapis Lazuli Ore
tile.ore.lapis.granite.desc=Chunks of lapis lazuli embedded in granite.
tile.ore.lapis.permafrost.name=Permafrost Lapis Lazuli Ore
tile.ore.lapis.permafrost.desc=Chunks of lapis lazuli embedded in permafrost.

tile.ore.redstone.stone.name=Stone Redstone Ore
tile.ore.redstone.stone.desc=Red dust embedded in stone.
tile.ore.redstone.basalt.name=Basalt Redstone Ore
tile.ore.redstone.basalt.desc=Red dust embedded in basalt.
tile.ore.redstone.limestone.name=Limestone Redstone Ore
tile.ore.redstone.limestone.desc=Red dust embedded in limestone.
tile.ore.redstone.granite.name=Granite Redstone Ore
tile.ore.redstone.granite.desc=Red dust embedded in granite.
tile.ore.redstone.permafrost.name=Permafrost Redstone Ore
tile.ore.redstone.permafrost.desc=Red dust embedded in permafrost.
tile.ore.redstone.glowing.stone.name=Glowing Stone Redstone Ore
tile.ore.redstone.glowing.stone.desc=Red dust embedded in stone. Emits a faint light.
tile.ore.redstone.glowing.basalt.name=Glowing Basalt Redstone Ore
tile.ore.redstone.glowing.basalt.desc=Red dust embedded in basalt. Emits a faint light.
tile.ore.redstone.glowing.limestone.name=Glowing Limestone Redstone Ore
tile.ore.redstone.glowing.limestone.desc=Red dust embedded in limestone. Emits a faint light.
tile.ore.redstone.glowing.granite.name=Glowing Granite Redstone Ore
tile.ore.redstone.glowing.granite.desc=Red dust embedded in granite. Emits a faint light.
tile.ore.redstone.glowing.permafrost.name=Glowing Permafrost Redstone Ore
tile.ore.redstone.glowing.permafrost.desc=Red dust embedded in permafrost. Emits a faint light.

tile.ore.diamond.stone.name=Stone Diamond Ore
tile.ore.diamond.stone.desc=A chunk of diamond embedded in stone.
tile.ore.diamond.basalt.name=Basalt Diamond Ore
tile.ore.diamond.basalt.desc=A chunk of diamond embedded in basalt.
tile.ore.diamond.limestone.name=Limestone Diamond Ore
tile.ore.diamond.limestone.desc=A chunk of diamond embedded in limestone.
tile.ore.diamond.granite.name=Granite Diamond Ore
tile.ore.diamond.granite.desc=A chunk of diamond embedded in granite.
tile.ore.diamond.permafrost.name=Permafrost Diamond Ore
tile.ore.diamond.permafrost.desc=A chunk of diamond embedded in permafrost.

tile.ore.nethercoal.netherrack.name=Nether Coal Ore
tile.ore.nethercoal.netherrack.desc=A lump of Nether Coal embedded in netherrack.

tile.block.coal.name=Block of Coal
tile.block.coal.desc=A solid block of coal.
tile.block.iron.name=Block of Iron
tile.block.iron.desc=A solid block of iron. Heavy!
tile.block.gold.name=Block of Gold
tile.block.gold.desc=A solid block of gold, for flaunting your bling.
tile.block.lapis.name=Block of Lapis Lazuli
tile.block.lapis.desc=A solid block of lapis lazuli.
tile.block.redstone.name=Block of Redstone
tile.block.redstone.desc=A solid block of redstone.
tile.block.diamond.name=Block of Diamond
tile.block.diamond.desc=A solid block of diamond. Well done you.
tile.block.nethercoal.name=Block of Nether Coal
tile.block.nethercoal.desc=A solid block of Nether Coal.
tile.block.steel.name=Block of Steel
tile.block.steel.desc=A solid block of steel.
tile.block.quartz.name=Block of Quartz
tile.block.quartz.desc=A solid block of quartz.
tile.block.olivine.name=Block of Olivine
tile.block.olivine.desc=A solid block of olivine.
tile.block.charcoal.name=Block of Charcoal
tile.block.charcoal.desc=A solid block of charcoal.

tile.wire.redstone.name=Redstone Wire
tile.wire.redstone.desc=A strand of redstone dust laid on the ground.

tile.torch.redstone.idle.name=Redstone Torch
tile.torch.redstone.idle.desc=Emits a constant redstone signal.
tile.torch.redstone.active.name=Redstone Torch
tile.torch.redstone.active.desc=Emits a constant redstone signal.

tile.button.stone.name=Stone Button
tile.button.stone.desc=Emits a brief redstone signal when pressed.

tile.lever.cobble.stone.name=Cobblestone Lever
tile.lever.cobble.stone.desc=Allows turning a redstone signal on or off.

tile.pressureplate.stone.name=Stone Pressure Plate
tile.pressureplate.stone.desc=Emits a redstone signal when living creatures step on it.
tile.pressureplate.planks.oak.name=Wooden Pressure Plate
tile.pressureplate.planks.oak.desc=Emits a redstone signal when anything steps on it.
tile.pressureplate.cobble.stone.name=Cobblestone Pressure Plate
tile.pressureplate.cobble.stone.desc=Emits a redstone signal when players step on it.

tile.motionsensor.idle.name=Motion Sensor
tile.motionsensor.idle.desc=Emits a redstone signal when something moves past it.
tile.motionsensor.active.name=Active Motion Sensor
tile.motionsensor.active.desc=Emits a redstone signal when something moves past it.

tile.repeater.idle.name=Redstone Repeater
tile.repeater.idle.desc=Repeats redstone signals over a distance.
tile.repeater.active.name=Redstone Repeater
tile.repeater.active.desc=Repeats redstone signals over a distance.

tile.piston.base.name=Piston
tile.piston.base.desc=Pushes blocks but does not pull them.
tile.piston.base.sticky.name=Sticky Piston
tile.piston.base.sticky.desc=Pushes and pulls blocks.
tile.piston.head.name=Piston Head
tile.piston.head.desc=The pushy part of the piston.
tile.piston.moving.name=Piston Mover
tile.piston.moving.desc=The invisible moving part of the piston.
tile.piston.base.steel.name=Steel Piston
tile.piston.base.desc=Pushes blocks and entities with immense force
tile.piston.head.steel.name=Steel Piston Head
tile.piston.head.steel.desc=The pushy part of the steel piston.

tile.noteblock.name=Note Block
tile.noteblock.desc=Plays a musical note when powered.

tile.rail.name=Rail
tile.rail.desc=For rapid horizontal movement via minecart.
tile.rail.powered.name=Powered Rail
tile.rail.powered.desc=Makes minecarts go faster when powered.
tile.rail.detector.name=Detector Rail
tile.rail.detector.desc=Emits a redstone signal when a minecart crosses it.

tile.spikes.name=Spike Trap
tile.spikes.desc=Deactivates when powered. Technically a war crime.

tile.dispenser.cobble.stone.name=Dispenser
tile.dispenser.cobble.stone.desc=Fires items out of the hole in the front.

tile.trapdoor.planks.oak.name=Oak Trapdoor
tile.trapdoor.planks.oak.desc=Like a door, but flat.
tile.trapdoor.iron.name=Iron Trapdoor
tile.trapdoor.iron.desc=Like a door, but flat and made of iron.
tile.trapdoor.glass.name=Glass Trapdoor
tile.trapdoor.glass.desc=Useless at its job.

tile.tnt.name=TNT
tile.tnt.desc=Goes off with a bang.

tile.door.planks.oak.bottom.name=Bottom Wooden Door
tile.door.planks.oak.bottom.desc=/give Honeydew 64 46
tile.door.planks.oak.top.name=Top Wooden Door
tile.door.planks.oak.top.desc=Oh, wait, that's not TNT, that's half a door.
tile.door.iron.bottom.name=Bottom Iron Door
tile.door.iron.bottom.desc=Not much good on its own.
tile.door.iron.top.name=Top Iron Door
tile.door.iron.top.desc=Could use a friend.

tile.mesh.name=Mesh Block
tile.mesh.desc=Allows items to pass through but nothing else.
tile.mesh.gold.name=Gold Mesh Block
tile.mesh.gold.desc=Allows a specified item to pass through but nothing else.

tile.bed.name=Bed
tile.bed.desc=Bed!
tile.seat.name=Seat
tile.seat.desc=Sit down and relax.

tile.cobweb.name=Cobweb
tile.cobweb.desc=Sticky silky strands woven by spiders.

tile.fire.name=Fire
tile.fire.desc=Ouch, fire hot!
tile.brazier.inactive.name=Brazier
tile.brazier.inactive.desc=A safe place to keep a fire.
tile.brazier.active.name=Lit Brazier
tile.brazier.active.desc=A safe place to keep a fire.

tile.mobspawner.name=Mob Spawner
tile.mobspawner.desc=A cage filled with horror.
tile.mobspawner.deactivated.name=Deactivated Mob Spawner
tile.mobspawner.deactivated.desc=A cage no longer filled with horror.

tile.workbench.name=Workbench
tile.workbench.desc=For bigger projects.

tile.furnace.stone.idle.name=Furnace
tile.furnace.stone.idle.desc=For melting, heating, and cooking blocks and items.
tile.furnace.stone.active.name=Lit Furnace
tile.furnace.stone.active.desc=For melting, heating, and cooking blocks and items.
tile.furnace.blast.idle.name=Blast Furnace
tile.furnace.blast.idle.desc=Burns hotter than a normal furnace.
tile.furnace.blast.active.name=Lit Blast Furnace
tile.furnace.blast.active.desc=Burns hotter than a normal furnace.

tile.trommel.idle.name=Trommel
tile.trommel.idle.desc=A machine that separates dirt from other useful items.
tile.trommel.active.name=Lit Trommel
tile.trommel.active.desc=A machine that separates dirt from other useful items.

tile.chest.planks.oak.name=Wooden Chest
tile.chest.planks.oak.desc=A place to store your items.
tile.chest.planks.oak.painted.name=Mystery Wooden Chest
tile.chest.planks.oak.painted.desc=How did you get this?!
tile.chest.planks.oak.painted.black.name=Black Wooden Chest
tile.chest.planks.oak.painted.black.desc=A place to store your items.
tile.chest.planks.oak.painted.red.name=Red Wooden Chest
tile.chest.planks.oak.painted.red.desc=A place to store your items.
tile.chest.planks.oak.painted.green.name=Green Wooden Chest
tile.chest.planks.oak.painted.green.desc=A place to store your items.
tile.chest.planks.oak.painted.brown.name=Brown Wooden Chest
tile.chest.planks.oak.painted.brown.desc=A place to store your items.
tile.chest.planks.oak.painted.blue.name=Blue Wooden Chest
tile.chest.planks.oak.painted.blue.desc=A place to store your items.
tile.chest.planks.oak.painted.purple.name=Purple Wooden Chest
tile.chest.planks.oak.painted.purple.desc=A place to store your items.
tile.chest.planks.oak.painted.cyan.name=Cyan Wooden Chest
tile.chest.planks.oak.painted.cyan.desc=A place to store your items.
tile.chest.planks.oak.painted.silver.name=Light Gray Wooden Chest
tile.chest.planks.oak.painted.silver.desc=A place to store your items.
tile.chest.planks.oak.painted.gray.name=Gray Wooden Chest
tile.chest.planks.oak.painted.gray.desc=A place to store your items.
tile.chest.planks.oak.painted.pink.name=Pink Wooden Chest
tile.chest.planks.oak.painted.pink.desc=A place to store your items.
tile.chest.planks.oak.painted.lime.name=Lime Wooden Chest
tile.chest.planks.oak.painted.lime.desc=A place to store your items.
tile.chest.planks.oak.painted.yellow.name=Yellow Wooden Chest
tile.chest.planks.oak.painted.yellow.desc=A place to store your items.
tile.chest.planks.oak.painted.lightblue.name=Light Blue Wooden Chest
tile.chest.planks.oak.painted.lightblue.desc=A place to store your items.
tile.chest.planks.oak.painted.magenta.name=Magenta Wooden Chest
tile.chest.planks.oak.painted.magenta.desc=A place to store your items.
tile.chest.planks.oak.painted.orange.name=Orange Wooden Chest
tile.chest.planks.oak.painted.orange.desc=A place to store your items.
tile.chest.planks.oak.painted.white.name=White Wooden Chest
tile.chest.planks.oak.painted.white.desc=A place to store your items.
tile.chest.legacy.name=Legacy Chest

tile.crops.wheat.name=Wheat Crops
tile.crops.wheat.desc=Wheat, plucked from the ground.
tile.crops.pumpkin.name=Pumpkin Crops
tile.crops.pumpkin.desc=A ripening pumpkin, plucked from the ground.

tile.farmland.dirt.name=Farmland
tile.farmland.dirt.desc=Tilled soil for growing crops.

tile.sign.post.planks.oak.name=Oak Signpost
tile.sign.post.planks.oak.desc=A free-standing oak sign.
tile.sign.wall.planks.oak.name=Oak Wall Sign
tile.sign.wall.planks.oak.desc=An oak sign placed on a wall.

tile.layer.snow.name=Snow Layer
tile.layer.snow.desc=A flat layer of snow.
tile.layer.leaves.oak.name=Leaf Pile
tile.layer.leaves.oak.desc=A pile of leaves.
tile.layer.slate.name=Slate Layer
tile.layer.slate.desc=A flat sheet of slate.

tile.ice.name=Ice
tile.ice.desc=Slippery frozen water.
tile.ice.perma.name=Perma-Ice
tile.ice.perma.desc=Ice imbued with the essence of stone.

tile.block.snow.name=Block of Snow
tile.block.snow.desc=Lots of snow compacted into a block.

tile.cactus.name=Cactus
tile.cactus.desc=A spiky plant that grows in the desert.

tile.block.clay.name=Block of Clay
tile.block.clay.desc=A block of compacted clay.

tile.sugarcane.name=Sugarcane
tile.sugarcane.desc=Not as sweet as you.

tile.block.sugarcane.name=Block of Sugarcane
tile.block.sugarcane.desc=One very big sugar cube.
tile.block.sugarcane.baked.name=Baked Block of Sugarcane
tile.block.sugarcane.baked.desc=Smells absolutely delicious.

tile.jukebox.name=Jukebox
tile.jukebox.desc=Plays your favourite tunes, assuming you have the right record.

tile.pumpkin.name=Pumpkin
tile.pumpkin.desc=An orange squash that grows in the wild.
tile.pumpkin.carved.idle.name=Carved Pumpkin
tile.pumpkin.carved.idle.desc=An orange squash with a spooky face.
tile.pumpkin.carved.active.name=Jack 'o' Lantern
tile.pumpkin.carved.active.desc=An orange squash with a spooky face, lit by a torch.
tile.pumpkin.redstone.name=Redstone Jack 'o' Lantern
tile.pumpkin.redstone.desc=An orange squash with a spooky face, lit by a redstone torch.

tile.cobble.netherrack.name=Cobbled Netherrack
tile.cobble.netherrack.desc=Dark red rock that burns forever.
tile.cobble.netherrack.igneous.name=Igneous Cobbled Netherrack
tile.cobble.netherrack.igneous.desc=Extreme heat has made this rock glow from inside.
tile.cobble.netherrack.mossy.name=Mossy Cobbled Netherrack
tile.cobble.netherrack.mossy.desc=Cobbled netherrack, covered in something like moss.
tile.netherrack.name=Netherrack
tile.netherrack.desc=Dark red rock, smoothed by heat and time.
tile.brick.netherrack.name=Netherrack Bricks
tile.brick.netherrack.desc=Stacked bricks of netherrack.
tile.slab.netherrack.carved.name=Polished Netherrack Slab
tile.slab.netherrack.carved.desc=A slab of polished netherrack.
tile.slab.cobble.netherrack.name=Cobbled Netherrack Slab
tile.slab.cobble.netherrack.desc=A slab of cobbled netherrack.
tile.slab.brick.netherrack.name=Netherrack Brick Slab
tile.slab.brick.netherrack.desc=A slab of netherrack bricks.
tile.stairs.cobble.netherrack.name=Cobbled Netherrack Stairs
tile.stairs.cobble.netherrack.desc=Cobbled netherrack block used for rapid vertical movement.
tile.stairs.brick.netherrack.name=Netherrack Brick Stairs
tile.stairs.brick.netherrack.desc=Netherrack brick block used for rapid vertical movement.

tile.soulsand.name=Soul Sand
tile.soulsand.desc=Squishy brown sand that's tough to walk through.
tile.soulschist.name=Soul Schist
tile.soulschist.desc=A hideous medley of ancient bones, fused through heat, pressure, and time.

tile.glowstone.name=Block of Glowstone
tile.glowstone.desc=Constantly emits a strong yellowish light.

tile.portal.nether.name=Nether Portal
tile.portal.nether.desc=A portal to the Nether.
tile.portal.paradise.name=Paradise Portal
tile.portal.paradise.desc=A portal to Paradise.

tile.cake.name=Cake
tile.cake.desc=I just can't cake it any more.
tile.pumpkin_pie.name=Pumpkin Pie
tile.pumpkin_pie.desc=I don't wanna pie!

tile.lamp.idle.name=Lamp
tile.lamp.idle.desc=How did you get this?!
tile.lamp.idle.black.name=Black Lamp
tile.lamp.idle.black.desc=A redstone lamp that can emit light. Tinted black.
tile.lamp.idle.red.name=Red Lamp
tile.lamp.idle.red.desc=A redstone lamp that can emit light. Tinted red.
tile.lamp.idle.green.name=Green Lamp
tile.lamp.idle.green.desc=A redstone lamp that can emit light. Tinted green.
tile.lamp.idle.brown.name=Brown Lamp
tile.lamp.idle.brown.desc=A redstone lamp that can emit light. Tinted brown.
tile.lamp.idle.blue.name=Blue Lamp
tile.lamp.idle.blue.desc=A redstone lamp that can emit light. Tinted blue.
tile.lamp.idle.purple.name=Purple Lamp
tile.lamp.idle.purple.desc=A redstone lamp that can emit light. Tinted purple.
tile.lamp.idle.cyan.name=Cyan Lamp
tile.lamp.idle.cyan.desc=A redstone lamp that can emit light. Tinted cyan.
tile.lamp.idle.silver.name=Light Gray Lamp
tile.lamp.idle.silver.desc=A redstone lamp that can emit light. Tinted light gray.
tile.lamp.idle.gray.name=Gray Lamp
tile.lamp.idle.gray.desc=A redstone lamp that can emit light. Tinted gray.
tile.lamp.idle.pink.name=Pink Lamp
tile.lamp.idle.pink.desc=A redstone lamp that can emit light. Tinted pink.
tile.lamp.idle.lime.name=Lime Lamp
tile.lamp.idle.lime.desc=A redstone lamp that can emit light. Tinted lime.
tile.lamp.idle.yellow.name=Yellow Lamp
tile.lamp.idle.yellow.desc=A redstone lamp that can emit light. Tinted yellow.
tile.lamp.idle.lightblue.name=Light Blue Lamp
tile.lamp.idle.lightblue.desc=A redstone lamp that can emit light. Tinted light blue.
tile.lamp.idle.magenta.name=Magenta Lamp
tile.lamp.idle.magenta.desc=A redstone lamp that can emit light. Tinted magenta.
tile.lamp.idle.orange.name=Orange Lamp
tile.lamp.idle.orange.desc=A redstone lamp that can emit light. Tinted orange.
tile.lamp.idle.white.name=White Lamp
tile.lamp.idle.white.desc=A redstone lamp that can emit light.

tile.lamp.active.name=Lit Lamp
tile.lamp.active.desc=How did you get this?!
tile.lamp.active.black.name=Lit Black Lamp
tile.lamp.active.black.desc=A redstone lamp that emits light. Tinted black.
tile.lamp.active.red.name=Lit Red Lamp
tile.lamp.active.red.desc=A redstone lamp that emits light. Tinted red.
tile.lamp.active.green.name=Lit Green Lamp
tile.lamp.active.green.desc=A redstone lamp that emits light. Tinted green.
tile.lamp.active.brown.name=Lit Brown Lamp
tile.lamp.active.brown.desc=A redstone lamp that emits light. Tinted brown.
tile.lamp.active.blue.name=Lit Blue Lamp
tile.lamp.active.blue.desc=A redstone lamp that emits light. Tinted blue.
tile.lamp.active.purple.name=Lit Purple Lamp
tile.lamp.active.purple.desc=A redstone lamp that emits light. Tinted purple.
tile.lamp.active.cyan.name=Lit Cyan Lamp
tile.lamp.active.cyan.desc=A redstone lamp that emits light. Tinted cyan.
tile.lamp.active.silver.name=Lit Light Gray Lamp
tile.lamp.active.silver.desc=A redstone lamp that emits light. Tinted light gray.
tile.lamp.active.gray.name=Lit Gray Lamp
tile.lamp.active.gray.desc=A redstone lamp that emits light. Tinted gray.
tile.lamp.active.pink.name=Lit Pink Lamp
tile.lamp.active.pink.desc=A redstone lamp that emits light. Tinted pink.
tile.lamp.active.lime.name=Lit Lime Lamp
tile.lamp.active.lime.desc=A redstone lamp that emits light. Tinted lime.
tile.lamp.active.yellow.name=Yellow Lamp
tile.lamp.active.yellow.desc=A redstone lamp that emits light. Tinted yellow.
tile.lamp.active.lightblue.name=Light Blue Lamp
tile.lamp.active.lightblue.desc=A redstone lamp that emits light. Tinted light blue.
tile.lamp.active.magenta.name=Magenta Lamp
tile.lamp.active.magenta.desc=A redstone lamp that emits light. Tinted magenta.
tile.lamp.active.orange.name=Orange Lamp
tile.lamp.active.orange.desc=A redstone lamp that emits light. Tinted orange.
tile.lamp.active.white.name=White Lamp
tile.lamp.active.white.desc=A redstone lamp that emits light.

tile.stone.polished.name=Polished Stone
tile.stone.polished.desc=A polished block of stone.
tile.granite.polished.name=Polished Granite
tile.granite.polished.desc=A polished block of granite.
tile.limestone.polished.name=Polished Limestone
tile.limestone.polished.desc=A polished block of limestone.
tile.basalt.polished.name=Polished Basalt
tile.basalt.polished.desc=A polished block of basalt.
tile.slate.polished.name=Polished Slate
tile.slate.polished.desc=A polished block of slate.
tile.permafrost.polished.name=Polished Permafrost
tile.permafrost.polished.desc=A polished block of permafrost.
tile.netherrack.polished.name=Polished Netherrack
tile.netherrack.polished.desc=A polished block of netherrack.

tile.candle.wax.soul.name=Soul Wax Candle
tile.candle.wax.soul.desc=A waxy brown candle that glows with an unnatural light.

tile.basket.name=Basket
tile.basket.desc=A wicker container for holding items.

tile.overlay.pebbles.name=Pebbles
tile.overlay.pebbles.desc=A cluster of pebbles.

tile.fence.chainlink.name=Chainlink Fence
tile.fence.chainlink.desc=A fence made of interconnected chain links. Can be climbed!
tile.fence.paper_wall.name=Paper Wall Fence
tile.fence.paper_wall.desc=A fence made of delicate paper. Be careful!
tile.fence.steel.name=Steel Fence
tile.fence.steel.desc=A fence made of tough steel. Intimidating!

tile.lantern.firefly.green.name=Green Firefly Lantern
tile.lantern.firefly.green.desc=A glass jar containing a swarm of green fireflies.
tile.lantern.firefly.orange.name=Orange Firefly Lantern
tile.lantern.firefly.orange.desc=A glass jar containing a swarm of orange fireflies.
tile.lantern.firefly.blue.name=Blue Firefly Lantern
tile.lantern.firefly.blue.desc=A glass jar containing a swarm of blue fireflies.
tile.lantern.firefly.red.name=Red Firefly Lantern
tile.lantern.firefly.red.desc=A glass jar containing a swarm of red fireflies.

tile.flag.name=Flag
tile.flag.desc=A flag to mark your territory.

tile.paper_wall.name=Paper Wall
tile.paper_wall.desc=A wall made of delicate paper. Be careful!

tile.trapdoor.planks.oak.painted.name=Painted Trapdoor
tile.trapdoor.planks.oak.painted.desc=How did you get this?!
tile.trapdoor.planks.oak.painted.black.name=Black Oak Trapdoor
tile.trapdoor.planks.oak.painted.black.desc=Like a door, but flat and painted black.
tile.trapdoor.planks.oak.painted.red.name=Red Oak Trapdoor
tile.trapdoor.planks.oak.painted.red.desc=Like a door, but flat and painted red.
tile.trapdoor.planks.oak.painted.green.name=Green Oak Trapdoor
tile.trapdoor.planks.oak.painted.green.desc=Like a door, but flat and painted green.
tile.trapdoor.planks.oak.painted.brown.name=Brown Oak Trapdoor
tile.trapdoor.planks.oak.painted.brown.desc=Like a door, but flat and painted brown.
tile.trapdoor.planks.oak.painted.blue.name=Blue Oak Trapdoor
tile.trapdoor.planks.oak.painted.blue.desc=Like a door, but flat and painted blue.
tile.trapdoor.planks.oak.painted.purple.name=Purple Oak Trapdoor
tile.trapdoor.planks.oak.painted.purple.desc=Like a door, but flat and painted purple.
tile.trapdoor.planks.oak.painted.cyan.name=Cyan Oak Trapdoor
tile.trapdoor.planks.oak.painted.cyan.desc=Like a door, but flat and painted cyan.
tile.trapdoor.planks.oak.painted.silver.name=Light Gray Oak Trapdoor
tile.trapdoor.planks.oak.painted.silver.desc=Like a door, but flat and painted light gray.
tile.trapdoor.planks.oak.painted.gray.name=Gray Oak Trapdoor
tile.trapdoor.planks.oak.painted.gray.desc=Like a door, but flat and painted gray.
tile.trapdoor.planks.oak.painted.pink.name=Pink Oak Trapdoor
tile.trapdoor.planks.oak.painted.pink.desc=Like a door, but flat and painted pink.
tile.trapdoor.planks.oak.painted.lime.name=Lime Oak Trapdoor
tile.trapdoor.planks.oak.painted.lime.desc=Like a door, but flat and painted lime.
tile.trapdoor.planks.oak.painted.yellow.name=Yellow Oak Trapdoor
tile.trapdoor.planks.oak.painted.yellow.desc=Like a door, but flat and painted yellow.
tile.trapdoor.planks.oak.painted.lightblue.name=Light Blue Oak Trapdoor
tile.trapdoor.planks.oak.painted.lightblue.desc=Like a door, but flat and painted light blue.
tile.trapdoor.planks.oak.painted.magenta.name=Magenta Oak Trapdoor
tile.trapdoor.planks.oak.painted.magenta.desc=Like a door, but flat and painted magenta.
tile.trapdoor.planks.oak.painted.orange.name=Orange Oak Trapdoor
tile.trapdoor.planks.oak.painted.orange.desc=Like a door, but flat and painted orange.
tile.trapdoor.planks.oak.painted.white.name=White Oak Trapdoor
tile.trapdoor.planks.oak.painted.white.desc=Like a door, but flat and painted white.

tile.door.planks.oak.painted.bottom.name=Bottom Painted Wooden Door
tile.door.planks.oak.painted.bottom.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.black.name=Black Bottom Wooden Door
tile.door.planks.oak.painted.bottom.black.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.red.name=Red Bottom Wooden Door
tile.door.planks.oak.painted.bottom.red.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.green.name=Green Bottom Wooden Door
tile.door.planks.oak.painted.bottom.green.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.brown.name=Brown Bottom Wooden Door
tile.door.planks.oak.painted.bottom.brown.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.blue.name=Blue Bottom Wooden Door
tile.door.planks.oak.painted.bottom.blue.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.purple.name=Purple Bottom Wooden Door
tile.door.planks.oak.painted.bottom.purple.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.cyan.name=Cyan Bottom Wooden Door
tile.door.planks.oak.painted.bottom.cyan.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.silver.name=Light Gray Bottom Wooden Door
tile.door.planks.oak.painted.bottom.silver.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.gray.name=Gray Bottom Wooden Door
tile.door.planks.oak.painted.bottom.gray.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.pink.name=Pink Bottom Wooden Door
tile.door.planks.oak.painted.bottom.pink.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.lime.name=Lime Bottom Wooden Door
tile.door.planks.oak.painted.bottom.lime.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.yellow.name=Yellow Bottom Wooden Door
tile.door.planks.oak.painted.bottom.yellow.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.lightblue.name=Light Blue Bottom Wooden Door
tile.door.planks.oak.painted.bottom.lightblue.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.magenta.name=Magenta Bottom Wooden Door
tile.door.planks.oak.painted.bottom.magenta.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.orange.name=Orange Bottom Wooden Door
tile.door.planks.oak.painted.bottom.orange.desc=How did you get this?!
tile.door.planks.oak.painted.bottom.white.name=White Bottom Wooden Door
tile.door.planks.oak.painted.bottom.white.desc=How did you get this?!

tile.door.planks.oak.painted.top.name=Top Painted Wooden Door
tile.door.planks.oak.painted.top.desc=How did you get this?!
tile.door.planks.oak.painted.top.black.name=Black Top Wooden Door
tile.door.planks.oak.painted.top.black.desc=How did you get this?!
tile.door.planks.oak.painted.top.red.name=Red Top Wooden Door
tile.door.planks.oak.painted.top.red.desc=How did you get this?!
tile.door.planks.oak.painted.top.green.name=Green Top Wooden Door
tile.door.planks.oak.painted.top.green.desc=How did you get this?!
tile.door.planks.oak.painted.top.brown.name=Brown Top Wooden Door
tile.door.planks.oak.painted.top.brown.desc=How did you get this?!
tile.door.planks.oak.painted.top.blue.name=Blue Top Wooden Door
tile.door.planks.oak.painted.top.blue.desc=How did you get this?!
tile.door.planks.oak.painted.top.purple.name=Purple Top Wooden Door
tile.door.planks.oak.painted.top.purple.desc=How did you get this?!
tile.door.planks.oak.painted.top.cyan.name=Cyan Top Wooden Door
tile.door.planks.oak.painted.top.cyan.desc=How did you get this?!
tile.door.planks.oak.painted.top.silver.name=Light Gray Top Wooden Door
tile.door.planks.oak.painted.top.silver.desc=How did you get this?!
tile.door.planks.oak.painted.top.gray.name=Gray Top Wooden Door
tile.door.planks.oak.painted.top.gray.desc=How did you get this?!
tile.door.planks.oak.painted.top.pink.name=Pink Top Wooden Door
tile.door.planks.oak.painted.top.pink.desc=How did you get this?!
tile.door.planks.oak.painted.top.lime.name=Lime Top Wooden Door
tile.door.planks.oak.painted.top.lime.desc=How did you get this?!
tile.door.planks.oak.painted.top.yellow.name=Yellow Top Wooden Door
tile.door.planks.oak.painted.top.yellow.desc=How did you get this?!
tile.door.planks.oak.painted.top.lightblue.name=Light Blue Top Wooden Door
tile.door.planks.oak.painted.top.lightblue.desc=How did you get this?!
tile.door.planks.oak.painted.top.magenta.name=Magenta Top Wooden Door
tile.door.planks.oak.painted.top.magenta.desc=How did you get this?!
tile.door.planks.oak.painted.top.orange.name=Orange Top Wooden Door
tile.door.planks.oak.painted.top.orange.desc=How did you get this?!
tile.door.planks.oak.painted.top.white.name=White Top Wooden Door
tile.door.planks.oak.painted.top.white.desc=How did you get this?!

tile.door.glass.top.name=Top Glass Door
tile.door.glass.top.desc=You shouldn't be seeing this.
tile.door.glass.bottom.name=Bottom Glass Door
tile.door.glass.bottom.desc=And that's not just because it's glass.

tile.door.steel.top.name=Top Steel Door
tile.door.steel.top.desc=Don't take this without asking.
tile.door.steel.bottom.name=Bottom Steel Door
tile.door.steel.bottom.desc=Steeler, no steeling!

tile.trapdoor.steel.name=Steel Trapdoor
tile.trapdoor.steel.desc=Like a door, but flat and made of durable steel.

tile.glass.steel.name=Reinforced Glass
tile.glass.steel.desc=Like glass, but without the fragility.

tile.rope.name=Rope
tile.rope.desc=Rope, rope, rope your boat.
\ No newline at end of file
diff --git a/src/main/java/net/betterthanadventure/utils/BiomeFinder.java b/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
index c7d7813c0..48d9792e8 100644
--- a/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
+++ b/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
@@ -486,7 +486,7 @@ public class BiomeFinder implements MinecraftAccessor {
 		BiomeProviderOverworld.init();
 		biomeCounts.clear();
 		WorldType worldType = WorldTypes.OVERWORLD_EXTENDED;
-		Dimension dimension = Dimension.overworld;
+		Dimension dimension = Dimension.OVERWORLD;
 		BiomeProvider biomeProvider;
 		World world;
 		if (worldFolder == null){
diff --git a/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java b/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
index d973e777f..ba5a31f2a 100644
--- a/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
+++ b/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
@@ -31,9 +31,9 @@ public class RichPresenceHandlerThread extends Thread {
     private static final Map<Dimension, String> dimensionNamesMap = new HashMap<>();
 
     static {
-        dimensionNamesMap.put(Dimension.overworld, "the Overworld");
-        dimensionNamesMap.put(Dimension.nether, "the Nether");
-        dimensionNamesMap.put(Dimension.paradise, "Paradise");
+        dimensionNamesMap.put(Dimension.OVERWORLD, "the Overworld");
+        dimensionNamesMap.put(Dimension.NETHER, "the Nether");
+        dimensionNamesMap.put(Dimension.PARADISE, "Paradise");
     }
 
     private static final Map<Biome, String> biomeNamesMap = new HashMap<>();
diff --git a/src/main/java/net/minecraft/client/entity/player/LocalPlayer.java b/src/main/java/net/minecraft/client/entity/player/LocalPlayer.java
index 10fa3233e..980d205bf 100644
--- a/src/main/java/net/minecraft/client/entity/player/LocalPlayer.java
+++ b/src/main/java/net/minecraft/client/entity/player/LocalPlayer.java
@@ -320,7 +320,7 @@ public class LocalPlayer extends Player
 
     @Override
     public void displayGuidebookScreen() {
-        mc.displayScreen(new GuidebookScreen());
+        mc.displayScreen(new GuidebookScreen(mc.currentScreen));
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/entity/player/MultiplayerLocalPlayer.java b/src/main/java/net/minecraft/client/entity/player/MultiplayerLocalPlayer.java
index 2c8de1243..fb58f2013 100644
--- a/src/main/java/net/minecraft/client/entity/player/MultiplayerLocalPlayer.java
+++ b/src/main/java/net/minecraft/client/entity/player/MultiplayerLocalPlayer.java
@@ -190,7 +190,7 @@ public class MultiplayerLocalPlayer extends LocalPlayer
     @Override
 	public void displayGuidebookScreen()
     {
-        mc.displayScreen(new GuidebookScreen());
+        mc.displayScreen(new GuidebookScreen(mc.currentScreen));
         sendQueue.addToSendQueue(new GuidebookPacket(mc.currentScreen instanceof GuidebookScreen));
     }
 
diff --git a/src/main/java/net/minecraft/client/gui/CreateWorldScreen.java b/src/main/java/net/minecraft/client/gui/CreateWorldScreen.java
index c7247209f..b05c47b55 100644
--- a/src/main/java/net/minecraft/client/gui/CreateWorldScreen.java
+++ b/src/main/java/net/minecraft/client/gui/CreateWorldScreen.java
@@ -152,9 +152,9 @@ public class CreateWorldScreen extends Screen {
             String[] keys = new String[WorldTypeGroups.GROUPS.size()];
             String[] descs = new String[WorldTypeGroups.GROUPS.size()];
             for (int i = 0; i < keys.length; i++) {
-                keys[i] = i18n.translateKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.overworld).getLanguageKey() + ".name");
-                descs[i] = i18n.translateKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.overworld).getLanguageKey() + ".desc") + "\n" +
-                    TextFormatting.GRAY + Registries.WORLD_TYPES.getKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.overworld));
+                keys[i] = i18n.translateKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD).getLanguageKey() + ".name");
+                descs[i] = i18n.translateKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD).getLanguageKey() + ".desc") + "\n" +
+                    TextFormatting.GRAY + Registries.WORLD_TYPES.getKey(WorldTypeGroups.GROUPS.get(i).get(Dimension.OVERWORLD));
             }
 
             PopupScreen popup = new PopupBuilder(this, 150)
@@ -184,7 +184,7 @@ public class CreateWorldScreen extends Screen {
         I18n i18n = I18n.getInstance();
         gamemodeButton.displayString = i18n.translateKeyAndFormat("gui.create_world.button.gamemode", i18n.translateNameKey(selectedGamemode.getLanguageKey()));
         cheatsButton.displayString = i18n.translateKeyAndFormat("gui.create_world.button.cheats", i18n.translateKey(cheatsEnabled ? "gui.create_world.button.cheats.on" : "gui.create_world.button.cheats.off"));
-        worldTypeButton.displayString = i18n.translateKeyAndFormat("gui.create_world.button.world_type", i18n.translateNameKey(worldTypeGroup.get(Dimension.overworld).getLanguageKey()));
+        worldTypeButton.displayString = i18n.translateKeyAndFormat("gui.create_world.button.world_type", i18n.translateNameKey(worldTypeGroup.get(Dimension.OVERWORLD).getLanguageKey()));
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/gui/SelectWorldScreen.java b/src/main/java/net/minecraft/client/gui/SelectWorldScreen.java
index bbef928fb..8657b05d9 100644
--- a/src/main/java/net/minecraft/client/gui/SelectWorldScreen.java
+++ b/src/main/java/net/minecraft/client/gui/SelectWorldScreen.java
@@ -330,7 +330,7 @@ public class SelectWorldScreen extends Screen
             {
                 I18n st = I18n.getInstance();
                 LevelData ld = saveFile.getLevelData();
-                DimensionData dd = saveFile.getDimensionData()[0];
+                DimensionData dd = saveFile.getDimensionData().get(0);
                 if (dd == null){
                     s2 += TextFormatting.RED + st.translateKey("gui.select_world.label.dimension_corrupted");
                 } else {
diff --git a/src/main/java/net/minecraft/client/gui/container/AbstractContainerScreen.java b/src/main/java/net/minecraft/client/gui/container/AbstractContainerScreen.java
index 7bc1cc3bc..cd35d8330 100644
--- a/src/main/java/net/minecraft/client/gui/container/AbstractContainerScreen.java
+++ b/src/main/java/net/minecraft/client/gui/container/AbstractContainerScreen.java
@@ -171,8 +171,8 @@ public abstract class AbstractContainerScreen extends Screen
 				Slot slot = inventorySlots.slots.get(slotId);
 				if(slot.hasItem()){
 					String query = "r:"+slot.getItem().getDisplayName()+"!";
-					removed();
-					mc.thePlayer.closeScreen();
+//					removed();
+//					mc.thePlayer.closeScreen();
 					PageManager.searchQuery = SearchQuery.resolve(query);
 					SearchPage.searchField.setText(query);
 					GuidebookScreen.getPageManager().updatePages();
@@ -192,8 +192,8 @@ public abstract class AbstractContainerScreen extends Screen
 				Slot slot = inventorySlots.slots.get(slotId);
 				if(slot.hasItem()) {
 					String query = "u:" + slot.getItem().getDisplayName() + "!";
-					removed();
-					mc.thePlayer.closeScreen();
+//					removed();
+//					mc.thePlayer.closeScreen();
 					PageManager.searchQuery = SearchQuery.resolve(query);
 					SearchPage.searchField.setText(query);
 					GuidebookScreen.getPageManager().updatePages();
@@ -248,6 +248,9 @@ public abstract class AbstractContainerScreen extends Screen
 				mc.playerController.handleInventoryMouseClick(inventorySlots.containerId, InventoryAction.SORT, new int[] {slotId}, mc.thePlayer);
 			}
 		}
+		if (mc.currentScreen == this && mc.gameSettings.keyGuidebook.isKeyboardKey(eventKey)) {
+			mc.thePlayer.displayGuidebookScreen();
+		}
 	}
 
 	@Override
diff --git a/src/main/java/net/minecraft/client/gui/guidebook/GuidebookPage.java b/src/main/java/net/minecraft/client/gui/guidebook/GuidebookPage.java
index 08e74cfb9..a843288b1 100644
--- a/src/main/java/net/minecraft/client/gui/guidebook/GuidebookPage.java
+++ b/src/main/java/net/minecraft/client/gui/guidebook/GuidebookPage.java
@@ -40,7 +40,9 @@ public abstract class GuidebookPage
 
     public void onMouseDown(int x, int y, int mouseX, int mouseY, int button) { }
 
-    public void keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) { }
+    public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
+        return false;
+    }
 
     public void onTick() { }
 
diff --git a/src/main/java/net/minecraft/client/gui/guidebook/GuidebookScreen.java b/src/main/java/net/minecraft/client/gui/guidebook/GuidebookScreen.java
index 0bf98c479..9553d54f6 100644
--- a/src/main/java/net/minecraft/client/gui/guidebook/GuidebookScreen.java
+++ b/src/main/java/net/minecraft/client/gui/guidebook/GuidebookScreen.java
@@ -46,9 +46,8 @@ public class GuidebookScreen
     private GuidebookPage lastPage = null;
     private boolean canPlaySound = true;
 
-    public GuidebookScreen() {
-        super();
-
+    public GuidebookScreen(Screen parent) {
+        super(parent);
         getPageManager();
     }
 
@@ -60,6 +59,7 @@ public class GuidebookScreen
         Keyboard.enableRepeatEvents(true);
     }
 
+
     @Override
     public void removed() {
         super.removed();
@@ -254,6 +254,10 @@ public class GuidebookScreen
 
     @Override
     public void keyPressed(char eventCharacter, int eventKey, int mx, int my) {
+        if (eventKey == Keyboard.KEY_ESCAPE) {
+            mc.displayScreen(getParentScreen());
+            return;
+        }
         if(eventKey != Keyboard.KEY_BACK) super.keyPressed(eventCharacter, eventKey, mx, my);
 
         int xOffset = 0;
@@ -278,14 +282,19 @@ public class GuidebookScreen
             }
         }
 
+        boolean consumedInput = false;
         if (pageManager.getLeftPage() != null) {
-            pageManager.getLeftPage().keyTyped(eventCharacter, eventKey, left, top, mx, my);
+            consumedInput |= pageManager.getLeftPage().keyTyped(eventCharacter, eventKey, left, top, mx, my);
             updateTabList();
         }
         if (pageManager.getRightPage() != null) {
-            pageManager.getRightPage().keyTyped(eventCharacter, eventKey, left + xSize / 2, top, mx, my);
+            consumedInput |= pageManager.getRightPage().keyTyped(eventCharacter, eventKey, left + xSize / 2, top, mx, my);
             updateTabList();
         }
+
+        if (!consumedInput && mc.gameSettings.keyGuidebook.isKeyboardKey(eventKey)) { // If R pressed and not consumed by page exit guidebook
+            mc.displayScreen(getParentScreen());
+        }
     }
 
     private void handleTabClicks(int mouseX, int mouseY) {
diff --git a/src/main/java/net/minecraft/client/gui/guidebook/crafting/CraftingPage.java b/src/main/java/net/minecraft/client/gui/guidebook/crafting/CraftingPage.java
index 4610f4a1b..e70e8cb2c 100644
--- a/src/main/java/net/minecraft/client/gui/guidebook/crafting/CraftingPage.java
+++ b/src/main/java/net/minecraft/client/gui/guidebook/crafting/CraftingPage.java
@@ -133,7 +133,7 @@ public class CraftingPage
     }
 
     @Override
-    public void keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
+    public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         super.keyTyped(c, key, x, y, mouseX, mouseY);
         if(mc.gameSettings.keyShowRecipe.isKeyboardKey(key)){
             GuidebookSlot hoveringSlot= null;
@@ -147,6 +147,7 @@ public class CraftingPage
                     SearchPage.searchField.setText(query);
                     GuidebookScreen.getPageManager().updatePages();
                     GuidebookScreen.getPageManager().setCurrentPage(GuidebookScreen.getPageManager().getSectionIndex(GuidebookSections.CRAFTING), true);
+                    return true;
                 }
             }
         } else if (mc.gameSettings.keyShowUsage.isKeyboardKey(key)) {
@@ -161,9 +162,11 @@ public class CraftingPage
                     SearchPage.searchField.setText(query);
                     GuidebookScreen.getPageManager().updatePages();
                     GuidebookScreen.getPageManager().setCurrentPage(GuidebookScreen.getPageManager().getSectionIndex(GuidebookSections.CRAFTING), true);
+                    return true;
                 }
             }
         }
+        return false;
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/gui/guidebook/mobs/MobPage.java b/src/main/java/net/minecraft/client/gui/guidebook/mobs/MobPage.java
index 68385cd6a..15edb4988 100644
--- a/src/main/java/net/minecraft/client/gui/guidebook/mobs/MobPage.java
+++ b/src/main/java/net/minecraft/client/gui/guidebook/mobs/MobPage.java
@@ -33,8 +33,6 @@ public class MobPage
     private final Class<? extends Entity> mobClass;
     private final MobInfoRegistry.MobInfo mobInfo;
     private final Mob example;
-    private String[] descLines;
-    private String[] unknownDescLines;
     private List<GuidebookSlot> slots;
     private Map<MobInfoRegistry.MobDrop, GuidebookSlot> dropSlotMap;
     private static final Minecraft mc = Minecraft.getMinecraft(GuidebookPage.class);
@@ -113,17 +111,13 @@ public class MobPage
 
         Lighting.disable();
         if(mobInfo != null) {
-            if (descLines == null) {
-                descLines = createDescLines(fr, mobInfo.getDescriptionTranslationKey());
-            }
-            if (unknownDescLines == null) {
-                unknownDescLines = createDescLines(fr, "guidebook.section.mob.undiscovered");
-            }
             I18n i18n = I18n.getInstance();
 
-            String[] lines = descLines;
+            String[] lines;
             if (!discovered) {
-                lines = unknownDescLines;
+                lines = createDescLines(fr, "guidebook.section.mob.undiscovered");
+            } else {
+                lines = createDescLines(fr, mobInfo.getDescriptionTranslationKey());
             }
 
             // Display name
diff --git a/src/main/java/net/minecraft/client/gui/guidebook/search/SearchPage.java b/src/main/java/net/minecraft/client/gui/guidebook/search/SearchPage.java
index b0d9790b7..45f97deee 100644
--- a/src/main/java/net/minecraft/client/gui/guidebook/search/SearchPage.java
+++ b/src/main/java/net/minecraft/client/gui/guidebook/search/SearchPage.java
@@ -81,11 +81,13 @@ public class SearchPage extends GuidebookPage {
     }
 
     @Override
-    public void keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
+    public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         if(searchField.isFocused) {
             searchField.textboxKeyTyped(c, key);
             PageManager.searchQuery = SearchQuery.resolve(searchField.getText());
             GuidebookScreen.getPageManager().updatePages();
+            return true;
         }
+        return false;
     }
 }
diff --git a/src/main/java/net/minecraft/client/gui/guidebook/smelting/BlastSmeltingPage.java b/src/main/java/net/minecraft/client/gui/guidebook/smelting/BlastSmeltingPage.java
index 702373d59..abbd48a68 100644
--- a/src/main/java/net/minecraft/client/gui/guidebook/smelting/BlastSmeltingPage.java
+++ b/src/main/java/net/minecraft/client/gui/guidebook/smelting/BlastSmeltingPage.java
@@ -88,7 +88,7 @@ public class BlastSmeltingPage
     }
 
     @Override
-    public void keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
+    public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         super.keyTyped(c, key, x, y, mouseX, mouseY);
         if(mc.gameSettings.keyShowRecipe.isKeyboardKey(key)){
             GuidebookSlot hoveringSlot= null;
@@ -102,6 +102,7 @@ public class BlastSmeltingPage
                     SearchPage.searchField.setText(query);
                     GuidebookScreen.getPageManager().updatePages();
                     GuidebookScreen.getPageManager().setCurrentPage(GuidebookScreen.getPageManager().getSectionIndex(GuidebookSections.CRAFTING), true);
+                    return true;
                 }
             }
         } else if (mc.gameSettings.keyShowUsage.isKeyboardKey(key)) {
@@ -116,9 +117,11 @@ public class BlastSmeltingPage
                     SearchPage.searchField.setText(query);
                     GuidebookScreen.getPageManager().updatePages();
                     GuidebookScreen.getPageManager().setCurrentPage(GuidebookScreen.getPageManager().getSectionIndex(GuidebookSections.CRAFTING), true);
+                    return true;
                 }
             }
         }
+        return false;
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/gui/guidebook/smelting/SmeltingPage.java b/src/main/java/net/minecraft/client/gui/guidebook/smelting/SmeltingPage.java
index 7df6ee29d..3df44593a 100644
--- a/src/main/java/net/minecraft/client/gui/guidebook/smelting/SmeltingPage.java
+++ b/src/main/java/net/minecraft/client/gui/guidebook/smelting/SmeltingPage.java
@@ -88,7 +88,7 @@ public class SmeltingPage
     }
 
     @Override
-    public void keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
+    public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         super.keyTyped(c, key, x, y, mouseX, mouseY);
         if(mc.gameSettings.keyShowRecipe.isKeyboardKey(key)){
             GuidebookSlot hoveringSlot= null;
@@ -102,6 +102,7 @@ public class SmeltingPage
                     SearchPage.searchField.setText(query);
                     GuidebookScreen.getPageManager().updatePages();
                     GuidebookScreen.getPageManager().setCurrentPage(GuidebookScreen.getPageManager().getSectionIndex(GuidebookSections.CRAFTING), true);
+                    return true;
                 }
             }
         } else if (mc.gameSettings.keyShowUsage.isKeyboardKey(key)) {
@@ -116,9 +117,11 @@ public class SmeltingPage
                     SearchPage.searchField.setText(query);
                     GuidebookScreen.getPageManager().updatePages();
                     GuidebookScreen.getPageManager().setCurrentPage(GuidebookScreen.getPageManager().getSectionIndex(GuidebookSections.CRAFTING), true);
+                    return true;
                 }
             }
         }
+        return false;
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/gui/guidebook/trommeling/TrommelPage.java b/src/main/java/net/minecraft/client/gui/guidebook/trommeling/TrommelPage.java
index 4757c7745..442371d58 100644
--- a/src/main/java/net/minecraft/client/gui/guidebook/trommeling/TrommelPage.java
+++ b/src/main/java/net/minecraft/client/gui/guidebook/trommeling/TrommelPage.java
@@ -137,7 +137,7 @@ public class TrommelPage
     }
 
     @Override
-    public void keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
+    public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         super.keyTyped(c, key, x, y, mouseX, mouseY);
         if(mc.gameSettings.keyShowRecipe.isKeyboardKey(key)){
             GuidebookSlot hoveringSlot= null;
@@ -151,6 +151,7 @@ public class TrommelPage
                     SearchPage.searchField.setText(query);
                     GuidebookScreen.getPageManager().updatePages();
                     GuidebookScreen.getPageManager().setCurrentPage(GuidebookScreen.getPageManager().getSectionIndex(GuidebookSections.CRAFTING), true);
+                    return true;
                 }
             }
         } else if (mc.gameSettings.keyShowUsage.isKeyboardKey(key)) {
@@ -165,9 +166,11 @@ public class TrommelPage
                     SearchPage.searchField.setText(query);
                     GuidebookScreen.getPageManager().updatePages();
                     GuidebookScreen.getPageManager().setCurrentPage(GuidebookScreen.getPageManager().getSectionIndex(GuidebookSections.CRAFTING), true);
+                    return true;
                 }
             }
         }
+        return false;
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/render/FogManager.java b/src/main/java/net/minecraft/client/render/FogManager.java
index bf0d56965..d081f6611 100644
--- a/src/main/java/net/minecraft/client/render/FogManager.java
+++ b/src/main/java/net/minecraft/client/render/FogManager.java
@@ -96,7 +96,7 @@ public class FogManager {
             {
                 glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, NVFogDistance.GL_EYE_RADIAL_NV);
             }
-            if(mc.theWorld.dimension == Dimension.nether)
+            if(mc.theWorld.dimension == Dimension.NETHER)
             {
                 glFogf(GL_FOG_START, 0.0F);
             }
diff --git a/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java b/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
index b65761693..f2b1a9ca6 100644
--- a/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
+++ b/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
@@ -107,11 +107,11 @@ public class LoadingScreenRenderer
 
     public void updateLoadingBackground(Dimension dimension)
     {
-        if (dimension == Dimension.nether)
+        if (dimension == Dimension.NETHER)
         {
             backgroundPath = "/assets/minecraft/textures/gui/background-loading-nether.png";
         }
-        else if (dimension == Dimension.paradise)
+        else if (dimension == Dimension.PARADISE)
         {
             backgroundPath = "/assets/minecraft/textures/gui/background-loading-paradise.png";
         }
diff --git a/src/main/java/net/minecraft/client/render/PostProcessingManager.java b/src/main/java/net/minecraft/client/render/PostProcessingManager.java
index 85e67a2c7..0cf87c0b1 100644
--- a/src/main/java/net/minecraft/client/render/PostProcessingManager.java
+++ b/src/main/java/net/minecraft/client/render/PostProcessingManager.java
@@ -72,7 +72,7 @@ public class PostProcessingManager
         lastHumidity = humidity;
 
         // Perform base temperature change
-        if (mc.theWorld.dimension == Dimension.overworld)
+        if (mc.theWorld.dimension == Dimension.OVERWORLD)
         {
             lastTemperature = temperature;
             temperature = (temperature * 2) - 1.0; // Ranges from -1.0 to 1.0
@@ -155,7 +155,7 @@ public class PostProcessingManager
         }
 
         // Perform heatwave effects
-        if (mc.theWorld.dimension == Dimension.overworld && (mc.theWorld.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_SUMMER || mc.theWorld.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_FALL))
+        if (mc.theWorld.dimension == Dimension.OVERWORLD && (mc.theWorld.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_SUMMER || mc.theWorld.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_FALL))
         {
             if (temperature >= 0.85 && humidity <= 0.15)
             {
diff --git a/src/main/java/net/minecraft/client/render/RenderBlocks.java b/src/main/java/net/minecraft/client/render/RenderBlocks.java
index 859cd1d46..ac192d9ad 100644
--- a/src/main/java/net/minecraft/client/render/RenderBlocks.java
+++ b/src/main/java/net/minecraft/client/render/RenderBlocks.java
@@ -14,7 +14,7 @@ import net.minecraft.core.world.WorldSource;
 
 // Referenced classes of package net.minecraft.src:
 //            Block, RailBlock, Tessellator, IBlockAccess,
-//            BedBlock, ModelBed, RepeaterBlock, BasePistonBlock,
+//            BedBlock, ModelBed, RepeaterBlock, PistonBaseBlock,
 //            BlockPistonExtension, Vec3D, FireBlock, RedstoneWireBlock,
 //            EntityRenderer, FluidBlock, MathHelper, Material,
 //            DoorBlock, World
diff --git a/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java b/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
index cdaace8af..2a5b68615 100644
--- a/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
+++ b/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
@@ -318,8 +318,12 @@ public class BlockModelDispatcher
 
         addDispatch(new PistonBlockModel<>(Blocks.PISTON_BASE, TextureRegistry.getTexture("minecraft:block/piston_face")).withTextures("minecraft:block/piston_face").withCustomItemBounds(0,0,0,1,1,1));
         addDispatch(new PistonBlockModel<>(Blocks.PISTON_BASE_STICKY,TextureRegistry.getTexture("minecraft:block/piston_face_sticky")).withTextures("minecraft:block/piston_face_sticky").withCustomItemBounds(0,0,0,1,1,1));
-        addDispatch(new PistonHeadBlockModel(Blocks.PISTON_HEAD).withTextures("minecraft:block/piston_face"));
+        addDispatch(new PistonHeadBlockModel(Blocks.PISTON_HEAD, TextureRegistry.getTexture("minecraft:block/piston_side")).withTextures("minecraft:block/piston_face"));
         addDispatch(new EmptyBlockModel(Blocks.PISTON_MOVING));
+        addDispatch(new PistonBlockModel<>(Blocks.PISTON_BASE_STEEL,TextureRegistry.getTexture("minecraft:block/piston_face_steel"), 6/16d)
+            .setPistonTextures("minecraft:block/piston_side_steel", "minecraft:block/piston_top_steel", "minecraft:block/piston_bottom_steel")
+            .withTextures("minecraft:block/piston_face_steel").withCustomItemBounds(0,0,0,1,1,1));
+        addDispatch(new PistonHeadBlockModel(Blocks.PISTON_HEAD_STEEL, TextureRegistry.getTexture("minecraft:block/piston_side_steel"), 6/16d).withTextures("minecraft:block/piston_face_steel"));
 
         addDispatch(new StandardBlockModel<>(Blocks.NOTEBLOCK).withTextures("minecraft:block/noteblock"));
 
@@ -449,6 +453,7 @@ public class BlockModelDispatcher
 
         addDispatch(new FenceThinBlockModel<>(Blocks.FENCE_CHAINLINK,TextureRegistry.getTexture("minecraft:block/fence_chain_center"), null, TextureRegistry.getTexture("minecraft:block/fence_chain_top"), TextureRegistry.getTexture("minecraft:block/fence_chain_column")).withTextures("minecraft:block/fence_chain_center"));
         addDispatch(new FenceThinBlockModel<>(Blocks.FENCE_PAPER_WALL,TextureRegistry.getTexture("minecraft:block/fence_paper_center"), null, null, TextureRegistry.getTexture("minecraft:block/fence_paper_column")).withTextures("minecraft:block/fence_paper_center"));
+        addDispatch(new FenceThinBlockModel<>(Blocks.FENCE_STEEL,TextureRegistry.getTexture("minecraft:block/fence_steel_center"), null, TextureRegistry.getTexture("minecraft:block/fence_steel_top"), TextureRegistry.getTexture("minecraft:block/fence_steel_column")).withTextures("minecraft:block/fence_steel_center"));
 
         addDispatch(new BasketBlockModel<>(Blocks.BASKET).withTextures("minecraft:block/basket_bottom", "minecraft:block/basket_side"));
 
diff --git a/src/main/java/net/minecraft/client/render/block/model/FullRotatableBlockModel.java b/src/main/java/net/minecraft/client/render/block/model/FullRotatableBlockModel.java
index 19ccd91f9..02e606cd1 100644
--- a/src/main/java/net/minecraft/client/render/block/model/FullRotatableBlockModel.java
+++ b/src/main/java/net/minecraft/client/render/block/model/FullRotatableBlockModel.java
@@ -4,7 +4,6 @@ import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.FullRotatableBlock;
-import net.minecraft.core.block.logic.PistonDirections;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import org.jetbrains.annotations.Nullable;
@@ -71,6 +70,6 @@ public class FullRotatableBlockModel<T extends FullRotatableBlock> extends Stand
         if (side == dir.getSide()) {
             return atlasIndices[Side.TOP.getId()];
         }
-        return side.getId() != PistonDirections.directionMap[dir.getId()] ? atlasIndices[Side.NORTH.getId()] : atlasIndices[Side.BOTTOM.getId()];
+        return side.getDirection() != dir.getOpposite() ? atlasIndices[Side.NORTH.getId()] : atlasIndices[Side.BOTTOM.getId()];
     }
 }
diff --git a/src/main/java/net/minecraft/client/render/block/model/PistonBlockModel.java b/src/main/java/net/minecraft/client/render/block/model/PistonBlockModel.java
index ca04ca569..b8973b353 100644
--- a/src/main/java/net/minecraft/client/render/block/model/PistonBlockModel.java
+++ b/src/main/java/net/minecraft/client/render/block/model/PistonBlockModel.java
@@ -4,20 +4,39 @@ import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
-import net.minecraft.core.block.logic.PistonDirections;
-import net.minecraft.core.block.piston.BasePistonBlock;
+import net.minecraft.core.block.piston.PistonBaseBlock;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import org.jetbrains.annotations.Nullable;
 
-public class PistonBlockModel<T extends BasePistonBlock> extends StandardBlockModel<T> {
+public class PistonBlockModel<T extends PistonBaseBlock> extends StandardBlockModel<T> {
     private final IconCoordinate faceTexture;
     protected IconCoordinate sideTexture = TextureRegistry.getTexture("minecraft:block/piston_side");
     protected IconCoordinate topTexture = TextureRegistry.getTexture("minecraft:block/piston_top");
     protected IconCoordinate bottomTexture = TextureRegistry.getTexture("minecraft:block/piston_bottom");
+
+    protected final double headThickness;
     public PistonBlockModel(Block block, IconCoordinate faceTexture){
+        this(block, faceTexture, 4/16d);
+    }
+
+    public PistonBlockModel(Block block, IconCoordinate faceTexture, double headThickness){
         super(block);
+        this.headThickness = headThickness;
         this.faceTexture = faceTexture;
     }
+
+    public PistonBlockModel<T> setPistonTextures(IconCoordinate sideTexture, IconCoordinate topTexture, IconCoordinate bottomTexture) {
+        this.sideTexture = sideTexture;
+        this.topTexture = topTexture;
+        this.bottomTexture = bottomTexture;
+        return this;
+    }
+
+    public PistonBlockModel<T> setPistonTextures(String sideTexture, String topTexture, String bottomTexture) {
+        return setPistonTextures(TextureRegistry.getTexture(sideTexture), TextureRegistry.getTexture(topTexture), TextureRegistry.getTexture(bottomTexture));
+    }
+
     @Override
     public boolean render(Tessellator tessellator, int x, int y, int z){
         block.setBlockBoundsBasedOnState(renderBlocks.blockAccess, x, y, z);
@@ -33,51 +52,51 @@ public class PistonBlockModel<T extends BasePistonBlock> extends StandardBlockMo
     protected boolean renderPistonBase(Tessellator tessellator, int x, int y, int z, boolean noCulling) {
         int meta = renderBlocks.blockAccess.getBlockMetadata(x, y, z);
         boolean extended = noCulling || (meta & 8) != 0;
-        int direction = BasePistonBlock.getDirection(meta);
+        Direction direction = PistonBaseBlock.getDirection(meta);
         if(extended)
         {
             switch(direction)
             {
-                case 0: // '\0'
+                case DOWN: // '\0'
                     renderBlocks.uvRotateEast = 3;
                     renderBlocks.uvRotateWest = 3;
                     renderBlocks.uvRotateSouth = 3;
                     renderBlocks.uvRotateNorth = 3;
-                    block.setBlockBounds(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F);
+                    block.setBlockBounds(0.0F, headThickness, 0.0F, 1.0F, 1.0F, 1.0F);
                     break;
 
-                case 1: // '\001'
-                    block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F);
+                case UP: // '\001'
+                    block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1 - headThickness, 1.0F);
                     break;
 
-                case 2: // '\002'
+                case NORTH: // '\002'
                     renderBlocks.uvRotateSouth = 1;
                     renderBlocks.uvRotateNorth = 2;
-                    block.setBlockBounds(0.0F, 0.0F, 0.25F, 1.0F, 1.0F, 1.0F);
+                    block.setBlockBounds(0.0F, 0.0F, headThickness, 1.0F, 1.0F, 1.0F);
                     break;
 
-                case 3: // '\003'
+                case SOUTH: // '\003'
                     renderBlocks.uvRotateSouth = 2;
                     renderBlocks.uvRotateNorth = 1;
                     renderBlocks.uvRotateTop = 3;
                     renderBlocks.uvRotateBottom = 3;
-                    block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.75F);
+                    block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1 - headThickness);
                     break;
 
-                case 4: // '\004'
+                case WEST: // '\004'
                     renderBlocks.uvRotateEast = 1;
                     renderBlocks.uvRotateWest = 2;
                     renderBlocks.uvRotateTop = 2;
                     renderBlocks.uvRotateBottom = 1;
-                    block.setBlockBounds(0.25F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+                    block.setBlockBounds(headThickness, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
                     break;
 
-                case 5: // '\005'
+                case EAST: // '\005'
                     renderBlocks.uvRotateEast = 2;
                     renderBlocks.uvRotateWest = 1;
                     renderBlocks.uvRotateTop = 1;
                     renderBlocks.uvRotateBottom = 2;
-                    block.setBlockBounds(0.0F, 0.0F, 0.0F, 0.75F, 1.0F, 1.0F);
+                    block.setBlockBounds(0.0F, 0.0F, 0.0F, 1 - headThickness, 1.0F, 1.0F);
                     break;
             }
             renderStandardBlock(tessellator, block, x, y, z);
@@ -87,33 +106,33 @@ public class PistonBlockModel<T extends BasePistonBlock> extends StandardBlockMo
         {
             switch(direction)
             {
-                case 0: // '\0'
+                case DOWN: // '\0'
                     renderBlocks.uvRotateEast = 3;
                     renderBlocks.uvRotateWest = 3;
                     renderBlocks.uvRotateSouth = 3;
                     renderBlocks.uvRotateNorth = 3;
                     break;
 
-                case 2: // '\002'
+                case NORTH: // '\002'
                     renderBlocks.uvRotateSouth = 1;
                     renderBlocks.uvRotateNorth = 2;
                     break;
 
-                case 3: // '\003'
+                case SOUTH: // '\003'
                     renderBlocks.uvRotateSouth = 2;
                     renderBlocks.uvRotateNorth = 1;
                     renderBlocks.uvRotateTop = 3;
                     renderBlocks.uvRotateBottom = 3;
                     break;
 
-                case 4: // '\004'
+                case WEST: // '\004'
                     renderBlocks.uvRotateEast = 1;
                     renderBlocks.uvRotateWest = 2;
                     renderBlocks.uvRotateTop = 2;
                     renderBlocks.uvRotateBottom = 1;
                     break;
 
-                case 5: // '\005'
+                case EAST: // '\005'
                     renderBlocks.uvRotateEast = 2;
                     renderBlocks.uvRotateWest = 1;
                     renderBlocks.uvRotateTop = 1;
@@ -137,14 +156,14 @@ public class PistonBlockModel<T extends BasePistonBlock> extends StandardBlockMo
     @Override
     public IconCoordinate getBlockTextureFromSideAndMetadata(Side side, int data)
     {
-        int direction = BasePistonBlock.getDirection(data);
-        if (direction > 5)
+        Direction direction = PistonBaseBlock.getDirection(data);
+        if (direction == Direction.NONE)
         {
             return atlasIndices[0];
         }
-        if (side.getId() == direction)
+        if (side.getDirection() == direction)
         {
-            if (BasePistonBlock.isPowered(data) || block.minX > 0.0D || block.minY > 0.0D || block.minZ > 0.0D || block.maxX < 1.0D || block.maxY < 1.0D || block.maxZ < 1.0D)
+            if (PistonBaseBlock.isPowered(data) || block.minX > 0.0D || block.minY > 0.0D || block.minZ > 0.0D || block.maxX < 1.0D || block.maxY < 1.0D || block.maxZ < 1.0D)
             {
                 return topTexture;
             }
@@ -153,6 +172,6 @@ public class PistonBlockModel<T extends BasePistonBlock> extends StandardBlockMo
                 return atlasIndices[0];
             }
         }
-        return side.getId() != PistonDirections.directionMap[direction] ? sideTexture : bottomTexture;
+        return side.getDirection() != direction.getOpposite() ? sideTexture : bottomTexture;
     }
 }
diff --git a/src/main/java/net/minecraft/client/render/block/model/PistonHeadBlockModel.java b/src/main/java/net/minecraft/client/render/block/model/PistonHeadBlockModel.java
index cee28d051..0c49435fd 100644
--- a/src/main/java/net/minecraft/client/render/block/model/PistonHeadBlockModel.java
+++ b/src/main/java/net/minecraft/client/render/block/model/PistonHeadBlockModel.java
@@ -5,19 +5,29 @@ import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
-import net.minecraft.core.block.logic.PistonDirections;
+import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.piston.PistonHeadBlock;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import org.jetbrains.annotations.Nullable;
 
 public class PistonHeadBlockModel extends StandardBlockModel<PistonHeadBlock> {
-    protected IconCoordinate pistonSide = TextureRegistry.getTexture("minecraft:block/piston_side");
+    protected IconCoordinate pistonSide;
     protected IconCoordinate pistonDry = TextureRegistry.getTexture("minecraft:block/piston_face");
     protected IconCoordinate pistonSticky = TextureRegistry.getTexture("minecraft:block/piston_face_sticky");
+    protected IconCoordinate pistonSteel = TextureRegistry.getTexture("minecraft:block/piston_face_steel");
     @Nullable
     public IconCoordinate faceTextureOverride;
-    public PistonHeadBlockModel(Block block) {
+
+    protected final double headThickness;
+    public PistonHeadBlockModel(Block block, IconCoordinate pistonSide) {
+        this(block, pistonSide, 4/16d);
+    }
+
+    public PistonHeadBlockModel(Block block, IconCoordinate pistonSide, double headThickness) {
         super(block);
+        this.pistonSide = pistonSide;
+        this.headThickness = headThickness;
     }
 
     @Override
@@ -35,7 +45,7 @@ public class PistonHeadBlockModel extends StandardBlockModel<PistonHeadBlock> {
     }
     protected boolean renderPistonHead(Tessellator tessellator, PistonHeadBlock block, int x, int y, int z, boolean flag) {
         int metadata = renderBlocks.blockAccess.getBlockMetadata(x, y, z);
-        int direction = PistonHeadBlock.getDirectionFromMeta(metadata);
+        Direction direction = PistonHeadBlock.getDirectionFromMeta(metadata);
         float brightness = 1.0f;
         if(LightmapHelper.isLightmapEnabled()) {
         	tessellator.setLightmapCoord(block.getLightmapCoord(renderBlocks.blockAccess, x, y, z));
@@ -46,76 +56,76 @@ public class PistonHeadBlockModel extends StandardBlockModel<PistonHeadBlock> {
         double width = flag ? 1 : 1/2d;
         switch(direction)
         {
-            case 0: // BOTTOM
+            case DOWN: // BOTTOM
                 renderBlocks.uvRotateEast = 3;
                 renderBlocks.uvRotateWest = 3;
                 renderBlocks.uvRotateSouth = 3;
                 renderBlocks.uvRotateNorth = 3;
-                block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F);
+                block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, headThickness, 1.0F);
                 renderStandardBlock(tessellator, block, x, y, z);
-                renderHeadTopBottom(tessellator, (float)x + 0.375F, (float)x + 0.625F, (float)y + 0.25F, (float)y + 0.25F + f1, (float)z + 0.625F, (float)z + 0.625F, brightness * 0.8F, width);
-                renderHeadTopBottom(tessellator, (float)x + 0.625F, (float)x + 0.375F, (float)y + 0.25F, (float)y + 0.25F + f1, (float)z + 0.375F, (float)z + 0.375F, brightness * 0.8F, width);
-                renderHeadTopBottom(tessellator, (float)x + 0.375F, (float)x + 0.375F, (float)y + 0.25F, (float)y + 0.25F + f1, (float)z + 0.375F, (float)z + 0.625F, brightness * 0.6F, width);
-                renderHeadTopBottom(tessellator, (float)x + 0.625F, (float)x + 0.625F, (float)y + 0.25F, (float)y + 0.25F + f1, (float)z + 0.625F, (float)z + 0.375F, brightness * 0.6F, width);
+                renderHeadTopBottom(tessellator, (float)x + 0.375F, (float)x + 0.625F, (float)y + headThickness, (float)y + headThickness + f1, (float)z + 0.625F, (float)z + 0.625F, brightness * 0.8F, width);
+                renderHeadTopBottom(tessellator, (float)x + 0.625F, (float)x + 0.375F, (float)y + headThickness, (float)y + headThickness + f1, (float)z + 0.375F, (float)z + 0.375F, brightness * 0.8F, width);
+                renderHeadTopBottom(tessellator, (float)x + 0.375F, (float)x + 0.375F, (float)y + headThickness, (float)y + headThickness + f1, (float)z + 0.375F, (float)z + 0.625F, brightness * 0.6F, width);
+                renderHeadTopBottom(tessellator, (float)x + 0.625F, (float)x + 0.625F, (float)y + headThickness, (float)y + headThickness + f1, (float)z + 0.625F, (float)z + 0.375F, brightness * 0.6F, width);
                 break;
 
-            case 1: // TOP
-                block.setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F);
+            case UP: // TOP
+                block.setBlockBounds(0.0F, 1 - headThickness, 0.0F, 1.0F, 1.0F, 1.0F);
                 renderStandardBlock(tessellator, block, x, y, z);
-                renderHeadTopBottom(tessellator, (float)x + 0.375F, (float)x + 0.625F, (((float)y - 0.25F) + 1.0F) - f1, ((float)y - 0.25F) + 1.0F, (float)z + 0.625F, (float)z + 0.625F, brightness * 0.8F, width);
-                renderHeadTopBottom(tessellator, (float)x + 0.625F, (float)x + 0.375F, (((float)y - 0.25F) + 1.0F) - f1, ((float)y - 0.25F) + 1.0F, (float)z + 0.375F, (float)z + 0.375F, brightness * 0.8F, width);
-                renderHeadTopBottom(tessellator, (float)x + 0.375F, (float)x + 0.375F, (((float)y - 0.25F) + 1.0F) - f1, ((float)y - 0.25F) + 1.0F, (float)z + 0.375F, (float)z + 0.625F, brightness * 0.6F, width);
-                renderHeadTopBottom(tessellator, (float)x + 0.625F, (float)x + 0.625F, (((float)y - 0.25F) + 1.0F) - f1, ((float)y - 0.25F) + 1.0F, (float)z + 0.625F, (float)z + 0.375F, brightness * 0.6F, width);
+                renderHeadTopBottom(tessellator, (float)x + 0.375F, (float)x + 0.625F, (((float)y - headThickness) + 1.0F) - f1, ((float)y - headThickness) + 1.0F, (float)z + 0.625F, (float)z + 0.625F, brightness * 0.8F, width);
+                renderHeadTopBottom(tessellator, (float)x + 0.625F, (float)x + 0.375F, (((float)y - headThickness) + 1.0F) - f1, ((float)y - headThickness) + 1.0F, (float)z + 0.375F, (float)z + 0.375F, brightness * 0.8F, width);
+                renderHeadTopBottom(tessellator, (float)x + 0.375F, (float)x + 0.375F, (((float)y - headThickness) + 1.0F) - f1, ((float)y - headThickness) + 1.0F, (float)z + 0.375F, (float)z + 0.625F, brightness * 0.6F, width);
+                renderHeadTopBottom(tessellator, (float)x + 0.625F, (float)x + 0.625F, (((float)y - headThickness) + 1.0F) - f1, ((float)y - headThickness) + 1.0F, (float)z + 0.625F, (float)z + 0.375F, brightness * 0.6F, width);
                 break;
 
-            case 2: // NORTH
+            case NORTH: // NORTH
                 renderBlocks.uvRotateSouth = 1;
                 renderBlocks.uvRotateNorth = 2;
-                block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F);
+                block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, headThickness);
                 renderStandardBlock(tessellator, block, x, y, z);
-                renderHeadNorthSouth(tessellator, (float)x + 0.375F, (float)x + 0.375F, (float)y + 0.625F, (float)y + 0.375F, (float)z + 0.25F, (float)z + 0.25F + f1, brightness * 0.6F, width);
-                renderHeadNorthSouth(tessellator, (float)x + 0.625F, (float)x + 0.625F, (float)y + 0.375F, (float)y + 0.625F, (float)z + 0.25F, (float)z + 0.25F + f1, brightness * 0.6F, width);
-                renderHeadNorthSouth(tessellator, (float)x + 0.375F, (float)x + 0.625F, (float)y + 0.375F, (float)y + 0.375F, (float)z + 0.25F, (float)z + 0.25F + f1, brightness * 0.5F, width);
-                renderHeadNorthSouth(tessellator, (float)x + 0.625F, (float)x + 0.375F, (float)y + 0.625F, (float)y + 0.625F, (float)z + 0.25F, (float)z + 0.25F + f1, brightness, width);
+                renderHeadNorthSouth(tessellator, (float)x + 0.375F, (float)x + 0.375F, (float)y + 0.625F, (float)y + 0.375F, (float)z + headThickness, (float)z + headThickness + f1, brightness * 0.6F, width);
+                renderHeadNorthSouth(tessellator, (float)x + 0.625F, (float)x + 0.625F, (float)y + 0.375F, (float)y + 0.625F, (float)z + headThickness, (float)z + headThickness + f1, brightness * 0.6F, width);
+                renderHeadNorthSouth(tessellator, (float)x + 0.375F, (float)x + 0.625F, (float)y + 0.375F, (float)y + 0.375F, (float)z + headThickness, (float)z + headThickness + f1, brightness * 0.5F, width);
+                renderHeadNorthSouth(tessellator, (float)x + 0.625F, (float)x + 0.375F, (float)y + 0.625F, (float)y + 0.625F, (float)z + headThickness, (float)z + headThickness + f1, brightness, width);
                 break;
 
-            case 3: // SOUTH
+            case SOUTH: // SOUTH
                 renderBlocks.uvRotateSouth = 2;
                 renderBlocks.uvRotateNorth = 1;
                 renderBlocks.uvRotateTop = 3;
                 renderBlocks.uvRotateBottom = 3;
-                block.setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F);
+                block.setBlockBounds(0.0F, 0.0F, 1 - headThickness, 1.0F, 1.0F, 1.0F);
                 renderStandardBlock(tessellator, block, x, y, z);
-                renderHeadNorthSouth(tessellator, (float)x + 0.375F, (float)x + 0.375F, (float)y + 0.625F, (float)y + 0.375F, (((float)z - 0.25F) + 1.0F) - f1, ((float)z - 0.25F) + 1.0F, brightness * 0.6F, width);
-                renderHeadNorthSouth(tessellator, (float)x + 0.625F, (float)x + 0.625F, (float)y + 0.375F, (float)y + 0.625F, (((float)z - 0.25F) + 1.0F) - f1, ((float)z - 0.25F) + 1.0F, brightness * 0.6F, width);
-                renderHeadNorthSouth(tessellator, (float)x + 0.375F, (float)x + 0.625F, (float)y + 0.375F, (float)y + 0.375F, (((float)z - 0.25F) + 1.0F) - f1, ((float)z - 0.25F) + 1.0F, brightness * 0.5F, width);
-                renderHeadNorthSouth(tessellator, (float)x + 0.625F, (float)x + 0.375F, (float)y + 0.625F, (float)y + 0.625F, (((float)z - 0.25F) + 1.0F) - f1, ((float)z - 0.25F) + 1.0F, brightness, width);
+                renderHeadNorthSouth(tessellator, (float)x + 0.375F, (float)x + 0.375F, (float)y + 0.625F, (float)y + 0.375F, (((float)z - headThickness) + 1.0F) - f1, ((float)z - headThickness) + 1.0F, brightness * 0.6F, width);
+                renderHeadNorthSouth(tessellator, (float)x + 0.625F, (float)x + 0.625F, (float)y + 0.375F, (float)y + 0.625F, (((float)z - headThickness) + 1.0F) - f1, ((float)z - headThickness) + 1.0F, brightness * 0.6F, width);
+                renderHeadNorthSouth(tessellator, (float)x + 0.375F, (float)x + 0.625F, (float)y + 0.375F, (float)y + 0.375F, (((float)z - headThickness) + 1.0F) - f1, ((float)z - headThickness) + 1.0F, brightness * 0.5F, width);
+                renderHeadNorthSouth(tessellator, (float)x + 0.625F, (float)x + 0.375F, (float)y + 0.625F, (float)y + 0.625F, (((float)z - headThickness) + 1.0F) - f1, ((float)z - headThickness) + 1.0F, brightness, width);
                 break;
 
-            case 4: // WEST
+            case WEST: // WEST
                 renderBlocks.uvRotateEast = 1;
                 renderBlocks.uvRotateWest = 2;
                 renderBlocks.uvRotateTop = 2;
                 renderBlocks.uvRotateBottom = 1;
-                block.setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F);
+                block.setBlockBounds(0.0F, 0.0F, 0.0F, headThickness, 1.0F, 1.0F);
                 renderStandardBlock(tessellator, block, x, y, z);
-                renderHeadEastWest(tessellator, (float)x + 0.25F, (float)x + 0.25F + f1, (float)y + 0.375F, (float)y + 0.375F, (float)z + 0.625F, (float)z + 0.375F, brightness * 0.5F, width);
-                renderHeadEastWest(tessellator, (float)x + 0.25F, (float)x + 0.25F + f1, (float)y + 0.625F, (float)y + 0.625F, (float)z + 0.375F, (float)z + 0.625F, brightness, width);
-                renderHeadEastWest(tessellator, (float)x + 0.25F, (float)x + 0.25F + f1, (float)y + 0.375F, (float)y + 0.625F, (float)z + 0.375F, (float)z + 0.375F, brightness * 0.6F, width);
-                renderHeadEastWest(tessellator, (float)x + 0.25F, (float)x + 0.25F + f1, (float)y + 0.625F, (float)y + 0.375F, (float)z + 0.625F, (float)z + 0.625F, brightness * 0.6F, width);
+                renderHeadEastWest(tessellator, (float)x + headThickness, (float)x + headThickness + f1, (float)y + 0.375F, (float)y + 0.375F, (float)z + 0.625F, (float)z + 0.375F, brightness * 0.5F, width);
+                renderHeadEastWest(tessellator, (float)x + headThickness, (float)x + headThickness + f1, (float)y + 0.625F, (float)y + 0.625F, (float)z + 0.375F, (float)z + 0.625F, brightness, width);
+                renderHeadEastWest(tessellator, (float)x + headThickness, (float)x + headThickness + f1, (float)y + 0.375F, (float)y + 0.625F, (float)z + 0.375F, (float)z + 0.375F, brightness * 0.6F, width);
+                renderHeadEastWest(tessellator, (float)x + headThickness, (float)x + headThickness + f1, (float)y + 0.625F, (float)y + 0.375F, (float)z + 0.625F, (float)z + 0.625F, brightness * 0.6F, width);
                 break;
 
-            case 5: // EAST
+            case EAST: // EAST
                 renderBlocks.uvRotateEast = 2;
                 renderBlocks.uvRotateWest = 1;
                 renderBlocks.uvRotateTop = 1;
                 renderBlocks.uvRotateBottom = 2;
-                block.setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+                block.setBlockBounds(1 - headThickness, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
                 renderStandardBlock(tessellator, block, x, y, z);
-                renderHeadEastWest(tessellator, (((float)x - 0.25F) + 1.0F) - f1, ((float)x - 0.25F) + 1.0F, (float)y + 0.375F, (float)y + 0.375F, (float)z + 0.625F, (float)z + 0.375F, brightness * 0.5F, width);
-                renderHeadEastWest(tessellator, (((float)x - 0.25F) + 1.0F) - f1, ((float)x - 0.25F) + 1.0F, (float)y + 0.625F, (float)y + 0.625F, (float)z + 0.375F, (float)z + 0.625F, brightness, width);
-                renderHeadEastWest(tessellator, (((float)x - 0.25F) + 1.0F) - f1, ((float)x - 0.25F) + 1.0F, (float)y + 0.375F, (float)y + 0.625F, (float)z + 0.375F, (float)z + 0.375F, brightness * 0.6F, width);
-                renderHeadEastWest(tessellator, (((float)x - 0.25F) + 1.0F) - f1, ((float)x - 0.25F) + 1.0F, (float)y + 0.625F, (float)y + 0.375F, (float)z + 0.625F, (float)z + 0.625F, brightness * 0.6F, width);
+                renderHeadEastWest(tessellator, (((float)x - headThickness) + 1.0F) - f1, ((float)x - headThickness) + 1.0F, (float)y + 0.375F, (float)y + 0.375F, (float)z + 0.625F, (float)z + 0.375F, brightness * 0.5F, width);
+                renderHeadEastWest(tessellator, (((float)x - headThickness) + 1.0F) - f1, ((float)x - headThickness) + 1.0F, (float)y + 0.625F, (float)y + 0.625F, (float)z + 0.375F, (float)z + 0.625F, brightness, width);
+                renderHeadEastWest(tessellator, (((float)x - headThickness) + 1.0F) - f1, ((float)x - headThickness) + 1.0F, (float)y + 0.375F, (float)y + 0.625F, (float)z + 0.375F, (float)z + 0.375F, brightness * 0.6F, width);
+                renderHeadEastWest(tessellator, (((float)x - headThickness) + 1.0F) - f1, ((float)x - headThickness) + 1.0F, (float)y + 0.625F, (float)y + 0.375F, (float)z + 0.625F, (float)z + 0.625F, brightness * 0.6F, width);
                 break;
         }
         resetRenderBlocks();
@@ -182,21 +192,23 @@ public class PistonHeadBlockModel extends StandardBlockModel<PistonHeadBlock> {
     @Override
     public IconCoordinate getBlockTextureFromSideAndMetadata(Side side, int data)
     {
-        int direction = PistonHeadBlock.getDirectionFromMeta(data);
-        if(side.getId() == direction)
+        Direction direction = PistonHeadBlock.getDirectionFromMeta(data);
+        if(side.getDirection() == direction)
         {
             if(faceTextureOverride != null)
             {
                 return faceTextureOverride;
             }
-            if((data & 8) != 0)
-            {
-                return pistonSticky;
-            } else
-            {
-                return pistonDry;
+            switch (PistonHeadBlock.getPistonType(data)) {
+                case PistonHeadBlock.TYPE_NORMAL:
+                    return pistonDry;
+                case PistonHeadBlock.TYPE_STICKY:
+                    return pistonSticky;
+                case PistonHeadBlock.TYPE_STEEL:
+                    return pistonSteel;
             }
         }
-        return side.getId() != PistonDirections.directionMap[direction] ? pistonSide : pistonDry;
+        boolean isSteel = block == Blocks.PISTON_HEAD_STEEL; // Todo this is just awful
+        return side.getDirection() != direction.getOpposite() ? pistonSide : ((isSteel) ? pistonSteel : pistonDry); // TODO remove this horrid ternary
     }
 }
diff --git a/src/main/java/net/minecraft/client/render/blockentity/PistonBlockEntityRenderer.java b/src/main/java/net/minecraft/client/render/blockentity/PistonBlockEntityRenderer.java
index b595aab41..4677ed0c6 100644
--- a/src/main/java/net/minecraft/client/render/blockentity/PistonBlockEntityRenderer.java
+++ b/src/main/java/net/minecraft/client/render/blockentity/PistonBlockEntityRenderer.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.blockentity;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.BlockEntityRenderDispatcher;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.RenderBlocks;
 import net.minecraft.client.render.block.model.BlockModel;
@@ -11,23 +12,23 @@ import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
-import net.minecraft.core.block.piston.BasePistonBlock;
+import net.minecraft.core.block.entity.BlockEntity;
+import net.minecraft.core.block.piston.PistonBaseBlock;
 import net.minecraft.core.block.piston.MovingPistonBlockEntity;
 import net.minecraft.core.block.piston.PistonHeadBlock;
+import net.minecraft.core.block.piston.SteelPistonBaseBlock;
+import net.minecraft.core.world.BlocksContainer;
 import net.minecraft.core.world.World;
 import org.lwjgl.opengl.GL11;
 
-// Referenced classes of package net.minecraft.src:
-//            TileEntitySpecialRenderer, Block, TileEntityPiston, Tessellator,
-//            RenderHelper, RenderBlocks, BasePistonBlock, BlockPistonExtension,
-//            World, BlockEntity
-
 public class PistonBlockEntityRenderer extends BlockEntityRenderer<MovingPistonBlockEntity>
 {
-    private static final PistonHeadBlockModel blockModelPistonHead = (PistonHeadBlockModel) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD);
     private RenderBlocks renderBlocks;
     private final Minecraft mc;
 
+    private BlocksContainer container = null;
+    private RenderBlocks containerRenderBlock = null;
+
     public PistonBlockEntityRenderer()
     {
         mc = Minecraft.getMinecraft(this);
@@ -40,12 +41,16 @@ public class PistonBlockEntityRenderer extends BlockEntityRenderer<MovingPistonB
     }
 
     @Override
-	public void doRender(Tessellator tessellator, MovingPistonBlockEntity tileEntity, double x, double y, double z,
+	public void doRender(Tessellator tessellator, MovingPistonBlockEntity blockEntity, double x, double y, double z,
                          float partialTick)
     {
-        Block block = Block.blocksList[tileEntity.getMovedId()];
-        if(block != null && tileEntity.getProgress(partialTick) < 1.0F)
+        Block block = Block.blocksList[blockEntity.getMovedId()];
+        if(block != null && blockEntity.getProgress(partialTick) < 1.0F)
         {
+            if (container == null || container.world != blockEntity.worldObj) {
+                container = new BlocksContainer(blockEntity.worldObj);
+                containerRenderBlock = new RenderBlocks(container);
+            }
             TextureRegistry.blockAtlas.bind();
             Lighting.disable();
             GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
@@ -59,31 +64,50 @@ public class PistonBlockEntityRenderer extends BlockEntityRenderer<MovingPistonB
                 GL11.glShadeModel(GL11.GL_FLAT);
             }
             tessellator.startDrawingQuads();
-            tessellator.setTranslation(((float)x - (float)tileEntity.x) + tileEntity.getXOff(partialTick), ((float)y - (float)tileEntity.y) + tileEntity.getYOff(partialTick), ((float)z - (float)tileEntity.z) + tileEntity.getZOff(partialTick));
-            tessellator.setColorOpaque(1, 1, 1);
-            if(block == Blocks.PISTON_HEAD && tileEntity.getProgress(partialTick) < 0.5F)
+            tessellator.setTranslation(((float)x - (float)blockEntity.x) + blockEntity.getXOff(partialTick), ((float)y - (float)blockEntity.y) + blockEntity.getYOff(partialTick), ((float)z - (float)blockEntity.z) + blockEntity.getZOff(partialTick));
+            if(block instanceof PistonHeadBlock && blockEntity.getProgress(partialTick) < 0.5F)
             {
                 BlockModel.setRenderBlocks(renderBlocks);
-                blockModelPistonHead.renderPistonHeadNoCulling(tessellator, (PistonHeadBlock) block, tileEntity.x, tileEntity.y, tileEntity.z, false);
+                ((PistonHeadBlockModel)BlockModelDispatcher.getInstance().getDispatch(block)).renderPistonHeadNoCulling(tessellator, (PistonHeadBlock) block, blockEntity.x, blockEntity.y, blockEntity.z, false);
             } else
-            if(tileEntity.isSourcePiston() && !tileEntity.isExtending())
+            if(blockEntity.isSourcePiston() && !blockEntity.isExtending())
             {
-                PistonBlockModel<BasePistonBlock> pistonBase = (PistonBlockModel) BlockModelDispatcher.getInstance().getDispatch(block);
+                PistonBlockModel<PistonBaseBlock> pistonBase = (PistonBlockModel) BlockModelDispatcher.getInstance().getDispatch(block);
                 BlockModel.setRenderBlocks(renderBlocks);
-                blockModelPistonHead.setFaceTextureOverride(pistonBase.getFaceTexture());
-                blockModelPistonHead.renderPistonHeadNoCulling(tessellator, (PistonHeadBlock) Blocks.PISTON_HEAD, tileEntity.x, tileEntity.y, tileEntity.z, tileEntity.getProgress(partialTick) < 0.5F);
-                blockModelPistonHead.setFaceTextureOverride(null);
-                tessellator.setTranslation((float)x - (float)tileEntity.x, (float)y - (float)tileEntity.y, (float)z - (float)tileEntity.z);
-                pistonBase.renderNoCulling(tessellator, tileEntity.x, tileEntity.y, tileEntity.z);
+                if (block instanceof SteelPistonBaseBlock) { // Todo remove this terrible hardcoded render code
+                    PistonHeadBlockModel blockModelPistonHead = ((PistonHeadBlockModel) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD_STEEL));
+                    blockModelPistonHead.setFaceTextureOverride(pistonBase.getFaceTexture());
+                    blockModelPistonHead.renderPistonHeadNoCulling(tessellator, (PistonHeadBlock) Blocks.PISTON_HEAD_STEEL, blockEntity.x, blockEntity.y, blockEntity.z, blockEntity.getProgress(partialTick) < 0.5F);
+                    blockModelPistonHead.setFaceTextureOverride(null);
+                } else {
+                    PistonHeadBlockModel blockModelPistonHead = ((PistonHeadBlockModel) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD));
+                    blockModelPistonHead.setFaceTextureOverride(pistonBase.getFaceTexture());
+                    blockModelPistonHead.renderPistonHeadNoCulling(tessellator, (PistonHeadBlock) Blocks.PISTON_HEAD, blockEntity.x, blockEntity.y, blockEntity.z, blockEntity.getProgress(partialTick) < 0.5F);
+                    blockModelPistonHead.setFaceTextureOverride(null);
+                }
+                tessellator.setTranslation((float)x - (float)blockEntity.x, (float)y - (float)blockEntity.y, (float)z - (float)blockEntity.z);
+                pistonBase.renderNoCulling(tessellator, blockEntity.x, blockEntity.y, blockEntity.z);
             } else
             {
-                BlockModel.setRenderBlocks(renderBlocks);
-                BlockModel<Block> model = BlockModelDispatcher.getInstance().getDispatch(block);
-                model.renderNoCulling(tessellator, tileEntity.x, tileEntity.y, tileEntity.z);
+                BlockModel.setRenderBlocks(containerRenderBlock);
+                container.setBlock(blockEntity.x, blockEntity.y, blockEntity.z, block.id, blockEntity.getMovedData(), blockEntity.getMovedEntity());
+                BlockModelDispatcher.getInstance().getDispatch(block).renderNoCulling(Tessellator.instance, blockEntity.x, blockEntity.y, blockEntity.z);
+                container.setLightReferenceEntity(null);
+                container.clear();
             }
             tessellator.setTranslation(0.0D, 0.0D, 0.0D);
             tessellator.draw();
+
             Lighting.enableLight();
+
+            BlockEntity movedEntity = blockEntity.getMovedEntity();
+            BlockEntityRenderer<BlockEntity> renderer = BlockEntityRenderDispatcher.instance.getRenderer(movedEntity);
+            if (renderer != null) {
+                GL11.glPushMatrix();
+                GL11.glTranslatef(blockEntity.getXOff(partialTick), blockEntity.getYOff(partialTick), blockEntity.getZOff(partialTick));
+                renderer.doRender(tessellator, movedEntity, x, y, z, partialTick);
+                GL11.glPopMatrix();
+            }
         }
     }
 }
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureClock.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureClock.java
index 657670f90..b130ffe5b 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureClock.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureClock.java
@@ -16,7 +16,7 @@ public class DynamicTextureClock extends DynamicTextureAbstractClock{
 		if(mc.theWorld != null && mc.thePlayer != null) {
 			float f = mc.theWorld.getCelestialAngle(1.0f);
 			d = -f * Math.PI * 2;
-			if(mc.theWorld.dimension == Dimension.nether) {
+			if(mc.theWorld.dimension == Dimension.NETHER) {
 				d = Math.random() * Math.PI * 2;
 			}
 		}
diff --git a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCompass.java b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCompass.java
index 48c85a82f..81fd413d3 100644
--- a/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCompass.java
+++ b/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCompass.java
@@ -70,7 +70,7 @@ public class DynamicTextureCompass extends DynamicTexture {
 			double var23 = (double)var21.x - this.mc.thePlayer.x;
 			double var25 = (double)var21.z - this.mc.thePlayer.z;
 			angle = (double)(this.mc.thePlayer.yRot - 90.0F) * PI / 180.0D - Math.atan2(var25, var23);
-			if(this.mc.theWorld.dimension == Dimension.nether) {
+			if(this.mc.theWorld.dimension == Dimension.NETHER) {
 				angle = Math.random() * PI * 2;
 			}
 		}
diff --git a/src/main/java/net/minecraft/client/render/entity/PlayerRenderer.java b/src/main/java/net/minecraft/client/render/entity/PlayerRenderer.java
index 98a3097de..4348b3fb2 100644
--- a/src/main/java/net/minecraft/client/render/entity/PlayerRenderer.java
+++ b/src/main/java/net/minecraft/client/render/entity/PlayerRenderer.java
@@ -36,6 +36,7 @@ public class PlayerRenderer extends MobRenderer<Player>
     private final BipedModel modelArmor;
 
     private BlocksContainer container = null;
+    private RenderBlocks containerRenderBlock = null;
 
     public PlayerRenderer()
     {
@@ -147,6 +148,7 @@ public class PlayerRenderer extends MobRenderer<Player>
             BlockEntity.CarriedBlock carriedBlock = (BlockEntity.CarriedBlock)player.getHeldObject();
             if (container == null || container.world != player.world) {
                 container = new BlocksContainer(player.world);
+                containerRenderBlock = new RenderBlocks(container);
             }
 
             Tessellator tessellator = Tessellator.instance;
@@ -170,7 +172,7 @@ public class PlayerRenderer extends MobRenderer<Player>
             int blockY = MathHelper.floor(player.y) + 1;
             int blockZ = MathHelper.floor(player.z);
 
-            BlockModel.setRenderBlocks(new RenderBlocks(container));
+            BlockModel.setRenderBlocks(containerRenderBlock);
             tessellator.startDrawingQuads();
             tessellator.setTranslation(-blockX -0.5, -blockY -0.5, -blockZ -0.5);
 
diff --git a/src/main/java/net/minecraft/core/block/BedBlock.java b/src/main/java/net/minecraft/core/block/BedBlock.java
index 1dd845d5e..47deb8e57 100644
--- a/src/main/java/net/minecraft/core/block/BedBlock.java
+++ b/src/main/java/net/minecraft/core/block/BedBlock.java
@@ -119,7 +119,7 @@ public class BedBlock extends Block {
 	}
 
 	@Override
-	public int getPistonPushReaction() {
+	public int getPistonPushReaction(World world, int x, int y, int z) {
 		return 1;
 	}
 
diff --git a/src/main/java/net/minecraft/core/block/Block.java b/src/main/java/net/minecraft/core/block/Block.java
index c0cb1f72c..c1172e626 100644
--- a/src/main/java/net/minecraft/core/block/Block.java
+++ b/src/main/java/net/minecraft/core/block/Block.java
@@ -11,7 +11,6 @@ import java.util.function.Supplier;
 
 import net.minecraft.core.block.support.FullSupport;
 import net.minecraft.core.block.support.ISupport;
-import net.minecraft.core.block.support.PartialSupport;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -704,7 +703,7 @@ public class Block
         return this;
     }
 
-    public int getPistonPushReaction()
+    public int getPistonPushReaction(World world, int x, int y, int z)
     {
         return blockMaterial.getPushReaction();
     }
diff --git a/src/main/java/net/minecraft/core/block/Blocks.java b/src/main/java/net/minecraft/core/block/Blocks.java
index 794eba74b..28ba3374c 100644
--- a/src/main/java/net/minecraft/core/block/Blocks.java
+++ b/src/main/java/net/minecraft/core/block/Blocks.java
@@ -2,9 +2,11 @@ package net.minecraft.core.block;
 
 import net.minecraft.core.block.material.Material;
 import net.minecraft.core.block.material.MaterialColor;
-import net.minecraft.core.block.piston.BasePistonBlock;
+import net.minecraft.core.block.piston.PistonBaseBlock;
 import net.minecraft.core.block.piston.PistonHeadBlock;
 import net.minecraft.core.block.piston.MovingPistonBlock;
+import net.minecraft.core.block.piston.SteelPistonBaseBlock;
+import net.minecraft.core.block.piston.StickyPistonBaseBlock;
 import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.Mob;
@@ -299,6 +301,8 @@ public final class Blocks {
     public static Block PISTON_BASE_STICKY;
     public static Block PISTON_HEAD;
     public static Block PISTON_MOVING;
+    public static Block PISTON_BASE_STEEL;
+    public static Block PISTON_HEAD_STEEL;
 
     public static Block NOTEBLOCK;
 
@@ -428,6 +432,7 @@ public final class Blocks {
 
     public static Block FENCE_CHAINLINK;
     public static Block FENCE_PAPER_WALL;
+    public static Block FENCE_STEEL;
 
     public static Block BASKET;
 
@@ -671,8 +676,8 @@ public final class Blocks {
         STAIRS_BRICK_PERMAFROST = new StairsBlock(BRICK_PERMAFROST, "minecraft:block/stairs_brick_permafrost", 177).withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-        OBSIDIAN = new Block("obsidian", "minecraft:block/obsidian", 180, Material.stone).withSound(BlockSounds.STONE).withHardness(10F).withBlastResistance(2000F).withOverrideColor(MaterialColor.paintedBlack)
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        OBSIDIAN = new Block("obsidian", "minecraft:block/obsidian", 180, Material.stone).withSound(BlockSounds.STONE).withHardness(10F).withBlastResistance(2000F).withOverrideColor(MaterialColor.paintedBlack).withImmovableFlagSet()
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PISTON_CRUSHING);
 
         GLASS = new GlassBlock("glass", "minecraft:block/glass", 190, Material.glass).withSound(BlockSounds.GLASS).withHardness(0.3F).withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.EXTENDS_MOTION_SENSOR_RANGE);
         GLASS_TINTED = new TintedGlassBlock("glass.tinted", "minecraft:block/glass_tinted", 191).withSound(BlockSounds.GLASS).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange().withTags(BlockTags.MINEABLE_BY_PICKAXE);
@@ -723,9 +728,10 @@ public final class Blocks {
         GRAVEL = new GravelBlock("gravel", "minecraft:block/gravel", 251).withSound(BlockSounds.GRAVEL).withHardness(0.6F)
             .withTags(BlockTags.MINEABLE_BY_SHOVEL);
 
-        BEDROCK = new BedrockBlock("bedrock", "minecraft:block/bedrock", 260, Material.stone).withSound(BlockSounds.STONE).withSetUnbreakable().withBlastResistance(6000000F);
+        BEDROCK = new BedrockBlock("bedrock", "minecraft:block/bedrock", 260, Material.stone).withSound(BlockSounds.STONE).withSetUnbreakable().withBlastResistance(6000000F).withImmovableFlagSet()
+            .withTags(BlockTags.PISTON_CRUSHING);
         BONESHALE = new BoneShaleBlock("boneshale", "minecraft:block/boneshale", 261, Material.stone).withSound(BlockSounds.STONE).withHardness(16F).withBlastResistance(6000000F).withImmovableFlagSet()
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NETHER_MOBS_SPAWN);
 
         FLUID_WATER_FLOWING = new FlowingFluidBlock("fluid.water.flowing", "minecraft:block/fluid_water_flowing", 270, Material.water).withHardness(100F).withLightBlock(3).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
             .withTags(BlockTags.IS_WATER, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
@@ -907,7 +913,7 @@ public final class Blocks {
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
         ORE_NETHERCOAL_NETHERRACK = new NetherCoalOreBlock("ore.nethercoal.netherrack", "minecraft:block/ore_nethercoal_netherrack", 420).withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).withLightEmission(0.625F)
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NETHER_MOBS_SPAWN);
 
         BLOCK_COAL = new Block("block.coal", "minecraft:block/block_coal", 430, Material.stone).withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.coal)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
@@ -953,9 +959,9 @@ public final class Blocks {
         PRESSURE_PLATE_COBBLE_STONE = new PressurePlateBlock("pressureplate.cobble.stone", "minecraft:block/pressure_plate_cobble_stone", 492, Player.class, Material.stone).withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
 
-        MOTION_SENSOR_IDLE = new MotionSensorBlock("motionsensor.idle", "minecraft:block/motion_sensor_idle", 500, false).withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet().withOverrideColor(MaterialColor.stone)
+        MOTION_SENSOR_IDLE = new MotionSensorBlock("motionsensor.idle", "minecraft:block/motion_sensor_idle", 500, false).withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.stone)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-        MOTION_SENSOR_ACTIVE = new MotionSensorBlock("motionsensor.active", "minecraft:block/motion_sensor_active", 501, true).withSound(BlockSounds.STONE).withLightEmission(0.3F).withHardness(2.0F).withBlastResistance(10F).withImmovableFlagSet().withOverrideColor(MaterialColor.stone).setStatParent(() -> MOTION_SENSOR_IDLE)
+        MOTION_SENSOR_ACTIVE = new MotionSensorBlock("motionsensor.active", "minecraft:block/motion_sensor_active", 501, 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);
 
         REPEATER_IDLE = new RepeaterBlock("repeater.idle", "minecraft:block/repeater_idle", 510, false).withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.REPEATER)
@@ -963,14 +969,18 @@ public final class Blocks {
         REPEATER_ACTIVE = new RepeaterBlock("repeater.active", "minecraft:block/repeater_active", 511, true).withSound(BlockSounds.STONE).withHardness(0.0F).withLightEmission(0.625F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> REPEATER_IDLE)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
 
-        PISTON_BASE = new BasePistonBlock("piston.base", "minecraft:block/piston_base", 520, false).withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
+        PISTON_BASE = new PistonBaseBlock("piston.base", "minecraft:block/piston_base", 520, 12).withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-        PISTON_BASE_STICKY = new BasePistonBlock("piston.base.sticky", "minecraft:block/piston_base_sticky", 521, true).withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
+        PISTON_BASE_STICKY = new StickyPistonBaseBlock("piston.base.sticky", "minecraft:block/piston_base_sticky", 521, 12).withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-        PISTON_HEAD = new PistonHeadBlock("piston.head", "minecraft:block/piston_head", 522).withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
+        PISTON_HEAD = new PistonHeadBlock("piston.head", "minecraft:block/piston_head", 522, 4/16d).withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
         PISTON_MOVING = new MovingPistonBlock("piston.moving", "minecraft:block/piston_moving", 523).withSound(BlockSounds.STONE).withDisabledStats()
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU);
+        PISTON_BASE_STEEL = new SteelPistonBaseBlock("piston.base.steel", "minecraft:block/piston_base_steel", 524, 24).withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange()
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        PISTON_HEAD_STEEL = new PistonHeadBlock("piston.head.steel", "minecraft:block/piston_head_steel", 525, 6/16d).withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
+            .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
         NOTEBLOCK = new NoteBlock("noteblock", "minecraft:block/noteblock", 530).withSound(BlockSounds.WOOD).withHardness(0.8F).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.MINEABLE_BY_AXE);
@@ -985,7 +995,7 @@ public final class Blocks {
         SPIKES = new SpikesBlock("spikes", "minecraft:block/spikes", 550, Material.metal).withSound(BlockSounds.METAL).withLightBlock(3).withHardness(2F).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-        DISPENSER_COBBLE_STONE = new DispenserBlock("dispenser.cobble.stone", "minecraft:block/dispenser_cobble_stone", 560).withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet()
+        DISPENSER_COBBLE_STONE = new DispenserBlock("dispenser.cobble.stone", "minecraft:block/dispenser_cobble_stone", 560).withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
         TRAPDOOR_PLANKS_OAK = new TrapDoorBlock("trapdoor.planks.oak", "minecraft:block/trapdoor_planks_oak", 570, Material.wood).withSound(BlockSounds.WOOD).withHardness(3F).withDisabledNeighborNotifyOnMetadataChange()
@@ -1045,33 +1055,33 @@ public final class Blocks {
         BRAZIER_ACTIVE = new BrazierBlock("brazier.active", "minecraft:block/brazier_active", 632, true).withSound(BlockSounds.FIRE).withHardness(1.5F).withLightEmission(1.0F).setStatParent(() -> BRAZIER_INACTIVE)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-        MOBSPAWNER = new MobSpawnerBlock("mobspawner", "minecraft:block/mobspawner", 640).withSound(BlockSounds.METAL).withHardness(5F).withTags(BlockTags.MINEABLE_BY_PICKAXE);
+        MOBSPAWNER = new MobSpawnerBlock("mobspawner", "minecraft:block/mobspawner", 640).withSound(BlockSounds.METAL).withHardness(5F).withImmovableFlagSet().withTags(BlockTags.MINEABLE_BY_PICKAXE);
         MOBSPAWNER_DEACTIVATED = new MobSpawnerDeactivatedBlock("mobspawner.deactivated", "minecraft:block/mobspawner_deactivated", 641, Material.stone).withSound(BlockSounds.METAL).withHardness(5F).withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
         WORKBENCH = new WorkbenchBlock("workbench", "minecraft:block/workbench", 650).withSound(BlockSounds.WOOD).withHardness(2.5F)
             .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
-        FURNACE_STONE_IDLE = new FurnaceBlock("furnace.stone.idle", "minecraft:block/furnace_stone_idle", 660, false).withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet()
+        FURNACE_STONE_IDLE = new FurnaceBlock("furnace.stone.idle", "minecraft:block/furnace_stone_idle", 660, false).withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-        FURNACE_STONE_ACTIVE = new FurnaceBlock("furnace.stone.active", "minecraft:block/furnace_stone_active", 661, true).withSound(BlockSounds.STONE).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet().setStatParent(() -> FURNACE_STONE_IDLE)
+        FURNACE_STONE_ACTIVE = new FurnaceBlock("furnace.stone.active", "minecraft:block/furnace_stone_active", 661, true).withSound(BlockSounds.STONE).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> FURNACE_STONE_IDLE)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-        FURNACE_BLAST_IDLE = new BlastFurnaceBlock("furnace.blast.idle", "minecraft:block/furnace_blast_idle", 662, false).withSound(BlockSounds.METAL).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet().withOverrideColor(MaterialColor.steel)
+        FURNACE_BLAST_IDLE = new BlastFurnaceBlock("furnace.blast.idle", "minecraft:block/furnace_blast_idle", 662, false).withSound(BlockSounds.METAL).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.steel)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-        FURNACE_BLAST_ACTIVE = new BlastFurnaceBlock("furnace.blast.active", "minecraft:block/furnace_blast_active", 663, true).withSound(BlockSounds.METAL).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet().withOverrideColor(MaterialColor.steel).setStatParent(() -> FURNACE_BLAST_IDLE)
+        FURNACE_BLAST_ACTIVE = new BlastFurnaceBlock("furnace.blast.active", "minecraft:block/furnace_blast_active", 663, true).withSound(BlockSounds.METAL).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.steel).setStatParent(() -> FURNACE_BLAST_IDLE)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-        TROMMEL_IDLE = new TrommelBlock("trommel.idle", "minecraft:block/trommel_idle", 670, Material.stone, false).withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet()
+        TROMMEL_IDLE = new TrommelBlock("trommel.idle", "minecraft:block/trommel_idle", 670, Material.stone, false).withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-        TROMMEL_ACTIVE = new TrommelBlock("trommel.active", "minecraft:block/trommel_active", 671, Material.stone, true).withSound(BlockSounds.STONE).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet().setStatParent(() -> TROMMEL_IDLE)
+        TROMMEL_ACTIVE = new TrommelBlock("trommel.active", "minecraft:block/trommel_active", 671, Material.stone, true).withSound(BlockSounds.STONE).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> TROMMEL_IDLE)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
         CHEST_LEGACY = new LegacyChestBlock("chest.legacy", "minecraft:block/chest_legacy", 680).withSound(BlockSounds.WOOD).withHardness(2.5f).withBlastResistance(5.0f).setStatParent(() -> CHEST_PLANKS_OAK)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
         CHEST_LEGACY_PAINTED = new LegacyChestBlock("chest.legacy.painted", "minecraft:block/chest_legacy_painted", 681).withSound(BlockSounds.WOOD).withHardness(2.5f).withBlastResistance(5.0f).setStatParent(() -> CHEST_PLANKS_OAK_PAINTED)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
-        CHEST_PLANKS_OAK = new ChestBlock("chest.planks.oak", "minecraft:block/chest_planks_oak", 682, Material.wood).withSound(BlockSounds.WOOD).withHardness(2.5F).withBlastResistance(5.0f).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet()
+        CHEST_PLANKS_OAK = new ChestBlock("chest.planks.oak", "minecraft:block/chest_planks_oak", 682, Material.wood).withSound(BlockSounds.WOOD).withHardness(2.5F).withBlastResistance(5.0f).withDisabledNeighborNotifyOnMetadataChange()
             .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-        CHEST_PLANKS_OAK_PAINTED = new ChestBlockPainted("chest.planks.oak.painted", "minecraft:block/chest_planks_oak_painted", 683, Material.wood).withSound(BlockSounds.WOOD).withHardness(2.5F).withBlastResistance(5.0f).withDisabledNeighborNotifyOnMetadataChange().withImmovableFlagSet()
+        CHEST_PLANKS_OAK_PAINTED = new ChestBlockPainted("chest.planks.oak.painted", "minecraft:block/chest_planks_oak_painted", 683, Material.wood).withSound(BlockSounds.WOOD).withHardness(2.5F).withBlastResistance(5.0f).withDisabledNeighborNotifyOnMetadataChange()
             .setBlockItem((b) -> new PaintedBlockItem(b, true))
             .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
@@ -1133,13 +1143,13 @@ public final class Blocks {
 
 
         COBBLE_NETHERRACK = new Block("cobble.netherrack", "minecraft:block/cobble_netherrack", 800, Material.netherrack).withSound(BlockSounds.STONE).withHardness(0.4F)
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
         COBBLE_NETHERRACK_IGNEOUS = new Block("cobble.netherrack.igneous", "minecraft:block/cobble_netherrack_igneous", 801, Material.netherrack).withSound(BlockSounds.STONE).withHardness(1.25F).withBlastResistance(7F).withLightEmission(10)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
         COBBLE_NETHERRACK_MOSSY = new Block("cobble.netherrack.mossy", "minecraft:block/cobble_netherrack_mossy", 802, Material.netherrack).withSound(BlockSounds.STONE).withHardness(0.4F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN);
         NETHERRACK = new Block("netherrack", "minecraft:block/netherrack", 803, Material.netherrack).withSound(BlockSounds.STONE).withHardness(0.32F)
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
         BRICK_NETHERRACK = new Block("brick.netherrack", "minecraft:block/brick_netherrack", 804, Material.netherrack).withSound(BlockSounds.STONE).withHardness(0.4F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
         SLAB_NETHERRACK_POLISHED = new SlabBlock(NETHERRACK_CARVED, "minecraft:block/slab_netherrack_polished", 805).withSound(BlockSounds.STONE).withHardness(0.4F)
@@ -1154,9 +1164,9 @@ public final class Blocks {
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
         SOULSAND = new SoulSandBlock("soulsand", "minecraft:block/soulsand", 810).withSound(BlockSounds.SAND).withHardness(0.5F).withOverrideColor(MaterialColor.paintedBrown)
-            .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.CAVES_CUT_THROUGH);
+            .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
         SOULSCHIST = new Block("soulschist", "minecraft:block/soulschist", 811, Material.stone).withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F).withOverrideColor(MaterialColor.paintedBrown)
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NETHER_MOBS_SPAWN);
 
         GLOWSTONE = new GlowStoneBlock("glowstone", "minecraft:block/glowstone", 820, Material.stone).withSound(BlockSounds.GLASS).withHardness(0.3F).withLightEmission(1.0F).withOverrideColor(MaterialColor.paintedYellow)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
@@ -1195,6 +1205,8 @@ public final class Blocks {
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.CAN_HANG_OFF);
         FENCE_PAPER_WALL = new PaperWallFenceBlock("fence.paper_wall", "minecraft:block/fence_paper_wall", 891, Material.cloth).withSound(BlockSounds.CLOTH).withHardness(0.5F)
             .withTags(BlockTags.MINEABLE_BY_SHEARS, BlockTags.FENCES_CONNECT, BlockTags.CAN_HANG_OFF, BlockTags.MINEABLE_BY_AXE);
+        FENCE_STEEL = new SteelFenceBlock("fence.steel", "minecraft:block/fence_steel", 892, Material.metal).withSound(BlockSounds.METAL).withHardness(8F)
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.CAN_HANG_OFF);
 
         BASKET = new BasketBlock("basket", "minecraft:block/basket", 900, Material.cloth).withSound(BlockSounds.CLOTH).withHardness(0.5F).withOverrideColor(MaterialColor.wood).setStatParent(() -> Items.BASKET)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU);
diff --git a/src/main/java/net/minecraft/core/block/ChainlinkFenceBlock.java b/src/main/java/net/minecraft/core/block/ChainlinkFenceBlock.java
index c6dbcab90..4e254cbd9 100644
--- a/src/main/java/net/minecraft/core/block/ChainlinkFenceBlock.java
+++ b/src/main/java/net/minecraft/core/block/ChainlinkFenceBlock.java
@@ -14,10 +14,10 @@ public class ChainlinkFenceBlock extends ThinFenceBlock
     }
 
     @Override
-    public boolean canConnectTo(WorldSource iblockaccess, int x, int y, int z)
+    public boolean canConnectTo(WorldSource world, int x, int y, int z)
     {
-        int l = iblockaccess.getBlockId(x, y, z);
-        return Block.hasTag(l, BlockTags.CHAINLINK_FENCES_CONNECT) || (Block.blocksList[l] != null && (Block.blocksList[l].blockMaterial == Material.stone || Block.blocksList[l].blockMaterial == Material.metal));
+        int id = world.getBlockId(x, y, z);
+        return Block.hasTag(id, BlockTags.CHAINLINK_FENCES_CONNECT) || (Block.blocksList[id] != null && (Block.blocksList[id].blockMaterial == Material.stone || Block.blocksList[id].blockMaterial == Material.metal));
     }
     
     @Override
@@ -25,46 +25,4 @@ public class ChainlinkFenceBlock extends ThinFenceBlock
     {
         return true;
     }
-
-    @Override
-    public boolean shouldDrawColumn(WorldSource world, int x, int y, int z)
-    {
-        boolean drawColumn = shouldDrawColumn_do(world, x, y, z);
-        if (drawColumn) return true;
-
-        int oy = 1;
-        while (world.getBlockId(x, y + oy, z) == this.id)
-        {
-            oy++;
-        }
-        oy--;
-
-        boolean drawColumnFromOther = false;
-        while (world.getBlockId(x, y + oy, z) == this.id)
-        {
-            if (shouldDrawColumn_do(world, x, y + oy, z))
-            {
-                drawColumnFromOther = true;
-                break;
-            }
-            oy--;
-        }
-
-        return drawColumnFromOther;
-    }
-
-    private boolean shouldDrawColumn_do(WorldSource world, int x, int y, int z)
-    {
-        boolean connectNorth = canConnectTo(world, x + Direction.NORTH.getOffsetX(), y + Direction.NORTH.getOffsetY(), z + Direction.NORTH.getOffsetZ());
-        boolean connectSouth = canConnectTo(world, x + Direction.SOUTH.getOffsetX(), y + Direction.SOUTH.getOffsetY(), z + Direction.SOUTH.getOffsetZ());
-        boolean connectEast = canConnectTo(world, x + Direction.EAST.getOffsetX(), y + Direction.EAST.getOffsetY(), z + Direction.EAST.getOffsetZ());
-        boolean connectWest = canConnectTo(world, x + Direction.WEST.getOffsetX(), y + Direction.WEST.getOffsetY(), z + Direction.WEST.getOffsetZ());
-
-        boolean lineNorthSouth = connectNorth && connectSouth;
-        boolean lineEastWest = connectEast && connectWest;
-
-        return (!lineNorthSouth && !lineEastWest) || (lineNorthSouth && lineEastWest) ||
-                (lineNorthSouth && (connectEast || connectWest)) ||
-                (lineEastWest && (connectNorth || connectSouth));
-    }
 }
diff --git a/src/main/java/net/minecraft/core/block/DoorBlock.java b/src/main/java/net/minecraft/core/block/DoorBlock.java
index ee888acf1..fbf3e3196 100644
--- a/src/main/java/net/minecraft/core/block/DoorBlock.java
+++ b/src/main/java/net/minecraft/core/block/DoorBlock.java
@@ -314,7 +314,7 @@ public class DoorBlock extends Block implements IPaintable
     }
 
     @Override
-    public int getPistonPushReaction()
+    public int getPistonPushReaction(World world, int x, int y, int z)
     {
         return 1;
     }
diff --git a/src/main/java/net/minecraft/core/block/FarmlandBlock.java b/src/main/java/net/minecraft/core/block/FarmlandBlock.java
index 7f05ff384..1d1b6243c 100644
--- a/src/main/java/net/minecraft/core/block/FarmlandBlock.java
+++ b/src/main/java/net/minecraft/core/block/FarmlandBlock.java
@@ -49,6 +49,17 @@ public class FarmlandBlock extends Block implements IBonemealable
 		return AABB.getTemporaryBB(x + 0, y + 0, z + 0, x + 1, y + 1, z + 1);
 	}
 
+	@Override
+	public void setBlockBoundsBasedOnState(WorldSource world, int x, int y, int z) {
+		final Material material = world.getBlockMaterial(x, y + 1, z);
+		if (material == Material.vegetable)
+		{
+			setBlockBounds(0, 0, 0, 1, 1, 1);
+		} else {
+			setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F);
+		}
+	}
+
 	@Override
 	public ItemStack[] getBreakResult(World world, EnumDropCause dropCause, int x, int y, int z, int meta, BlockEntity blockEntity)
 	{
@@ -135,7 +146,7 @@ public class FarmlandBlock extends Block implements IBonemealable
 	{
 		super.onNeighborBlockChange(world, x, y, z, blockId);
 		final Material material = world.getBlockMaterial(x, y + 1, z);
-		if (material.isSolid())
+		if (material.isSolid() && material != Material.vegetable)
 		{
 			if(isWet(world.getBlockMetadata(x, y, z)))
 				world.setBlockWithNotify(x, y, z, Blocks.MUD.id);
diff --git a/src/main/java/net/minecraft/core/block/FlowingFluidBlock.java b/src/main/java/net/minecraft/core/block/FlowingFluidBlock.java
index 282ba2dab..4a64f6b57 100644
--- a/src/main/java/net/minecraft/core/block/FlowingFluidBlock.java
+++ b/src/main/java/net/minecraft/core/block/FlowingFluidBlock.java
@@ -40,7 +40,7 @@ public class FlowingFluidBlock extends FluidBlock
     {
         int localFlowDecay = getDepth(world, x, y, z);
         byte flowDecayMod = 1;
-        if(blockMaterial == Material.lava && world.dimension != Dimension.nether)
+        if(blockMaterial == Material.lava && world.dimension != Dimension.NETHER)
         {
             flowDecayMod = 2;
         }
diff --git a/src/main/java/net/minecraft/core/block/IceBlock.java b/src/main/java/net/minecraft/core/block/IceBlock.java
index 918c89d05..13c9c4ed7 100644
--- a/src/main/java/net/minecraft/core/block/IceBlock.java
+++ b/src/main/java/net/minecraft/core/block/IceBlock.java
@@ -64,7 +64,7 @@ public class IceBlock extends TransparentBlock
     }
 
     @Override
-    public int getPistonPushReaction()
+    public int getPistonPushReaction(World world, int x, int y, int z)
     {
         return 0;
     }
diff --git a/src/main/java/net/minecraft/core/block/MudBlock.java b/src/main/java/net/minecraft/core/block/MudBlock.java
index 3cdd7e3ca..866bcd39a 100644
--- a/src/main/java/net/minecraft/core/block/MudBlock.java
+++ b/src/main/java/net/minecraft/core/block/MudBlock.java
@@ -174,7 +174,7 @@ public class MudBlock extends Block{
         }
 
         if(!isHardened){
-            if(isLavaNearby(world, x, y, z) || world.dimension.id == Dimension.nether.id) {
+            if(isLavaNearby(world, x, y, z) || world.dimension.id == Dimension.NETHER.id) {
                 world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, x + 0.5D, y + 0.5D, z + 0.5D, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F);
                 for(int l = 0; l < 8; l++)
                 {
diff --git a/src/main/java/net/minecraft/core/block/PaperWallFenceBlock.java b/src/main/java/net/minecraft/core/block/PaperWallFenceBlock.java
index 6998095f4..1dde81004 100644
--- a/src/main/java/net/minecraft/core/block/PaperWallFenceBlock.java
+++ b/src/main/java/net/minecraft/core/block/PaperWallFenceBlock.java
@@ -13,51 +13,9 @@ public class PaperWallFenceBlock extends ThinFenceBlock
     }
 
     @Override
-    public boolean canConnectTo(WorldSource iblockaccess, int x, int y, int z)
+    public boolean canConnectTo(WorldSource world, int x, int y, int z)
     {
-        int l = iblockaccess.getBlockId(x, y, z);
+        int l = world.getBlockId(x, y, z);
         return Block.hasTag(l, BlockTags.FENCES_CONNECT);
     }
-
-    @Override
-    public boolean shouldDrawColumn(WorldSource world, int x, int y, int z)
-    {
-        boolean drawColumn = shouldDrawColumn_do(world, x, y, z);
-        if (drawColumn) return true;
-
-        int oy = 1;
-        while (world.getBlockId(x, y + oy, z) == this.id)
-        {
-            oy++;
-        }
-        oy--;
-
-        boolean drawColumnFromOther = false;
-        while (world.getBlockId(x, y + oy, z) == this.id)
-        {
-            if (shouldDrawColumn_do(world, x, y + oy, z))
-            {
-                drawColumnFromOther = true;
-                break;
-            }
-            oy--;
-        }
-
-        return drawColumnFromOther;
-    }
-
-    private boolean shouldDrawColumn_do(WorldSource world, int x, int y, int z)
-    {
-        boolean connectNorth = canConnectTo(world, x + Direction.NORTH.getOffsetX(), y + Direction.NORTH.getOffsetY(), z + Direction.NORTH.getOffsetZ());
-        boolean connectSouth = canConnectTo(world, x + Direction.SOUTH.getOffsetX(), y + Direction.SOUTH.getOffsetY(), z + Direction.SOUTH.getOffsetZ());
-        boolean connectEast = canConnectTo(world, x + Direction.EAST.getOffsetX(), y + Direction.EAST.getOffsetY(), z + Direction.EAST.getOffsetZ());
-        boolean connectWest = canConnectTo(world, x + Direction.WEST.getOffsetX(), y + Direction.WEST.getOffsetY(), z + Direction.WEST.getOffsetZ());
-
-        boolean lineNorthSouth = connectNorth && connectSouth;
-        boolean lineEastWest = connectEast && connectWest;
-
-        return (!lineNorthSouth && !lineEastWest) || (lineNorthSouth && lineEastWest) ||
-                (lineNorthSouth && (connectEast || connectWest)) ||
-                (lineEastWest && (connectNorth || connectSouth));
-    }
 }
diff --git a/src/main/java/net/minecraft/core/block/PressurePlateBlock.java b/src/main/java/net/minecraft/core/block/PressurePlateBlock.java
index 4b790392b..7e3565584 100644
--- a/src/main/java/net/minecraft/core/block/PressurePlateBlock.java
+++ b/src/main/java/net/minecraft/core/block/PressurePlateBlock.java
@@ -190,7 +190,7 @@ public class PressurePlateBlock extends Block
     }
 
     @Override
-    public int getPistonPushReaction()
+    public int getPistonPushReaction(World world, int x, int y, int z)
     {
         return 1;
     }
diff --git a/src/main/java/net/minecraft/core/block/PumiceBlock.java b/src/main/java/net/minecraft/core/block/PumiceBlock.java
index e19cb0ada..a000bcddb 100644
--- a/src/main/java/net/minecraft/core/block/PumiceBlock.java
+++ b/src/main/java/net/minecraft/core/block/PumiceBlock.java
@@ -22,7 +22,7 @@ public class PumiceBlock extends Block {
     {
         super.onBlockPlacedByWorld(world, x, y, z);
         byte radius = 2;
-        if(isWet && (inWater(world, x, y, z) || world.dimension.id == Dimension.paradise.id)){
+        if(isWet && (inWater(world, x, y, z) || world.dimension.id == Dimension.PARADISE.id)){
             world.setBlockWithNotify(x, y, z, Blocks.PUMICE_DRY.id);
             world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, x + 0.5D, y + 0.5D, z + 0.5D, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F);
             for(int l = 0; l < 8; l++)
diff --git a/src/main/java/net/minecraft/core/block/RailBlock.java b/src/main/java/net/minecraft/core/block/RailBlock.java
index d0749b316..5e5e56937 100644
--- a/src/main/java/net/minecraft/core/block/RailBlock.java
+++ b/src/main/java/net/minecraft/core/block/RailBlock.java
@@ -228,7 +228,7 @@ public class RailBlock extends Block {
     }
 
     @Override
-    public int getPistonPushReaction()
+    public int getPistonPushReaction(World world, int x, int y, int z)
     {
         return 0;
     }
diff --git a/src/main/java/net/minecraft/core/block/SpongeBlock.java b/src/main/java/net/minecraft/core/block/SpongeBlock.java
index f583b79b5..fd6f03993 100644
--- a/src/main/java/net/minecraft/core/block/SpongeBlock.java
+++ b/src/main/java/net/minecraft/core/block/SpongeBlock.java
@@ -27,7 +27,7 @@ public class SpongeBlock extends Block
     {
         super.onBlockPlacedByWorld(world, x, y, z);
         byte byte0 = 2;
-        if(world.dimension.id == Dimension.nether.id && isWet){
+        if(world.dimension.id == Dimension.NETHER.id && isWet){
             world.setBlockWithNotify(x, y, z, Blocks.SPONGE_DRY.id);
             world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, x + 0.5D, y + 0.5D, z + 0.5D, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F);
             for(int l = 0; l < 8; l++)
diff --git a/src/main/java/net/minecraft/core/block/SteelFenceBlock.java b/src/main/java/net/minecraft/core/block/SteelFenceBlock.java
new file mode 100644
index 000000000..2f554c0a6
--- /dev/null
+++ b/src/main/java/net/minecraft/core/block/SteelFenceBlock.java
@@ -0,0 +1,17 @@
+package net.minecraft.core.block;
+
+import net.minecraft.core.block.material.Material;
+import net.minecraft.core.block.tag.BlockTags;
+import net.minecraft.core.world.WorldSource;
+
+public class SteelFenceBlock extends ThinFenceBlock {
+    public SteelFenceBlock(String key, String namespaceId, int id, Material material) {
+        super(key, namespaceId, id, material);
+    }
+
+    @Override
+    public boolean canConnectTo(WorldSource world, int x, int y, int z) {
+        int id = world.getBlockId(x, y, z);
+        return Block.hasTag(id, BlockTags.CHAINLINK_FENCES_CONNECT) || (Block.blocksList[id] != null && (Block.blocksList[id].blockMaterial == Material.stone || Block.blocksList[id].blockMaterial == Material.metal));
+    }
+}
diff --git a/src/main/java/net/minecraft/core/block/ThinFenceBlock.java b/src/main/java/net/minecraft/core/block/ThinFenceBlock.java
index 7eb18be65..9252fc551 100644
--- a/src/main/java/net/minecraft/core/block/ThinFenceBlock.java
+++ b/src/main/java/net/minecraft/core/block/ThinFenceBlock.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.block;
 
 import net.minecraft.core.block.material.Material;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.phys.AABB;
 import net.minecraft.core.world.WorldSource;
 
@@ -57,7 +58,45 @@ public abstract class ThinFenceBlock extends Block
         return false;
     }
 
-    public abstract boolean canConnectTo(WorldSource iblockaccess, int x, int y, int z);
+    public abstract boolean canConnectTo(WorldSource world, int x, int y, int z);
 
-    public abstract boolean shouldDrawColumn(WorldSource iblockaccess, int x, int y, int z);
+    public boolean shouldDrawColumn(WorldSource world, int x, int y, int z) {
+        boolean drawColumn = shouldDrawColumn_do(world, x, y, z);
+        if (drawColumn) return true;
+
+        int oy = 1;
+        while (world.getBlockId(x, y + oy, z) == this.id)
+        {
+            oy++;
+        }
+        oy--;
+
+        boolean drawColumnFromOther = false;
+        while (world.getBlockId(x, y + oy, z) == this.id)
+        {
+            if (shouldDrawColumn_do(world, x, y + oy, z))
+            {
+                drawColumnFromOther = true;
+                break;
+            }
+            oy--;
+        }
+
+        return drawColumnFromOther;
+    }
+
+    private boolean shouldDrawColumn_do(WorldSource world, int x, int y, int z)
+    {
+        boolean connectNorth = canConnectTo(world, x + Direction.NORTH.getOffsetX(), y + Direction.NORTH.getOffsetY(), z + Direction.NORTH.getOffsetZ());
+        boolean connectSouth = canConnectTo(world, x + Direction.SOUTH.getOffsetX(), y + Direction.SOUTH.getOffsetY(), z + Direction.SOUTH.getOffsetZ());
+        boolean connectEast = canConnectTo(world, x + Direction.EAST.getOffsetX(), y + Direction.EAST.getOffsetY(), z + Direction.EAST.getOffsetZ());
+        boolean connectWest = canConnectTo(world, x + Direction.WEST.getOffsetX(), y + Direction.WEST.getOffsetY(), z + Direction.WEST.getOffsetZ());
+
+        boolean lineNorthSouth = connectNorth && connectSouth;
+        boolean lineEastWest = connectEast && connectWest;
+
+        return (!lineNorthSouth && !lineEastWest) || (lineNorthSouth && lineEastWest) ||
+            (lineNorthSouth && (connectEast || connectWest)) ||
+            (lineEastWest && (connectNorth || connectSouth));
+    }
 }
diff --git a/src/main/java/net/minecraft/core/block/logic/PistonDirections.java b/src/main/java/net/minecraft/core/block/logic/PistonDirections.java
deleted file mode 100644
index 72e6d4c69..000000000
--- a/src/main/java/net/minecraft/core/block/logic/PistonDirections.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package net.minecraft.core.block.logic;
-
-public class PistonDirections {
-
-	public static final int directionMap[] = { 1, 0, 3, 2, 5, 4 };
-	public static final int xOffset[] = { 0, 0, 0, 0, -1, 1 };
-	public static final int yOffset[] = { -1, 1, 0, 0, 0, 0 };
-	public static final int zOffset[] = { 0, 0, -1, 1, 0, 0 };
-
-}
diff --git a/src/main/java/net/minecraft/core/block/material/Material.java b/src/main/java/net/minecraft/core/block/material/Material.java
index 6d2253f0b..38333208f 100644
--- a/src/main/java/net/minecraft/core/block/material/Material.java
+++ b/src/main/java/net/minecraft/core/block/material/Material.java
@@ -2,6 +2,10 @@ package net.minecraft.core.block.material;
 
 public class Material
 {
+    public static final int PISTON_PUSHABLE = 0;
+    public static final int PISTON_DESTROY_ON_PUSH = 1;
+    public static final int PISTON_CANT_PUSH = 2;
+
     public static final int LIGHTNING_NEUTRAL = 0;
     public static final int LIGHTNING_STRONG_CONDUCTOR = 20;
     public static final int LIGHTNING_LIGHT_CONDUCTOR = 5;
@@ -12,7 +16,7 @@ public class Material
     private boolean notSolidBlocking;
     public final MaterialColor color;
     private boolean alwaysDestroyable;
-    private int pushReaction;
+    private int pushReaction = PISTON_PUSHABLE;
     private int lightningConductivity = LIGHTNING_NEUTRAL;
 
     public Material(MaterialColor color)
@@ -99,13 +103,13 @@ public class Material
 
     public Material destroyOnPush()
     {
-        pushReaction = 1;
+        pushReaction = PISTON_DESTROY_ON_PUSH;
         return this;
     }
 
     public Material notPushable()
     {
-        pushReaction = 2;
+        pushReaction = PISTON_CANT_PUSH;
         return this;
     }
     public int getConductivity(){
@@ -153,7 +157,7 @@ public class Material
     public static final Material portal = new PortalMaterial(MaterialColor.none).notPushable();
     public static final Material cake = new Material(MaterialColor.none).destroyOnPush();
     public static final Material web = new Material(MaterialColor.wool).notAlwaysDestroyable().destroyOnPush();
-    public static final Material piston = new Material(MaterialColor.stone).notPushable();
+    public static final Material piston = new Material(MaterialColor.stone);
     public static final Material moss = new Material(MaterialColor.grass).flammable().notAlwaysDestroyable();
     public static final Material woodWet = (new Material(MaterialColor.grass).setConductivity(LIGHTNING_LIGHT_CONDUCTOR));
 }
diff --git a/src/main/java/net/minecraft/core/block/piston/BasePistonBlock.java b/src/main/java/net/minecraft/core/block/piston/BasePistonBlock.java
deleted file mode 100644
index 31edea354..000000000
--- a/src/main/java/net/minecraft/core/block/piston/BasePistonBlock.java
+++ /dev/null
@@ -1,421 +0,0 @@
-package net.minecraft.core.block.piston;
-
-import java.util.ArrayList;
-
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.block.entity.BlockEntity;
-import net.minecraft.core.block.logic.PistonDirections;
-import net.minecraft.core.block.material.Material;
-import net.minecraft.core.entity.Mob;
-import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.enums.EnumDropCause;
-import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.sound.SoundCategory;
-import net.minecraft.core.util.helper.Direction;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.util.phys.AABB;
-import net.minecraft.core.world.World;
-import net.minecraft.core.world.WorldSource;
-
-public class BasePistonBlock extends Block
-{
-
-    public BasePistonBlock(String key, String namespaceId, int id, boolean isSticky)
-    {
-        super(key, namespaceId, id, Material.piston);
-        this.isSticky = isSticky;
-        withHardness(0.5F);
-    }
-
-    @Override
-	public boolean isSolidRender()
-    {
-        return false;
-    }
-
-    @Override
-    public void onBlockPlacedByMob(World world, int x, int y, int z, Side side, Mob mob, double sideHeight) {
-    	Direction placementDirection = mob.getPlacementDirection(side).getOpposite();
-        world.setBlockMetadataWithNotify(x, y, z, placementDirection.getId());
-        if(!world.isClientSide)
-        {
-            checkIfExtend(world, x, y, z);
-        }
-    }
-
-    @Override
-	public void onNeighborBlockChange(World world, int x, int y, int z, int blockId)
-    {
-        checkIfExtend(world, x, y, z);
-    }
-
-    @Override
-	public void onBlockPlacedByWorld(World world, int x, int y, int z)
-    {
-        if(!world.isClientSide && world.getBlockEntity(x, y, z) == null)
-        {
-            checkIfExtend(world, x, y, z);
-        }
-    }
-
-    private void checkIfExtend(World world, int x, int y, int z)
-    {
-        int data = world.getBlockMetadata(x, y, z);
-        int direction = getDirection(data);
-        boolean hasNeighborSignal = getNeighborSignal(world, x, y, z, direction);
-        if(data == 0b111)
-        {
-            return;
-        }
-        if(hasNeighborSignal && !isPowered(data))
-        {
-            if(canPushLine(world, x, y, z, direction))
-            {
-                world.setBlockMetadata(x, y, z, direction | 8);
-                world.triggerEvent(x, y, z, 0, direction);
-            }
-        }
-        else if(!hasNeighborSignal && isPowered(data))
-        {
-            world.setBlockMetadata(x, y, z, direction);
-            world.triggerEvent(x, y, z, 1, direction);
-        }
-    }
-
-    private boolean getNeighborSignal(World world, int x, int y, int z, int direction) {
-        if(direction != 0 && world.getSignal(x, y - 1, z, Side.BOTTOM)) {
-            return true;
-        }
-        if(direction != 1 && world.getSignal(x, y + 1, z, Side.TOP)) {
-            return true;
-        }
-        if(direction != 2 && world.getSignal(x, y, z - 1, Side.NORTH)) {
-            return true;
-        }
-        if(direction != 3 && world.getSignal(x, y, z + 1, Side.SOUTH)) {
-            return true;
-        }
-        if(direction != 5 && world.getSignal(x + 1, y, z, Side.EAST)) {
-            return true;
-        }
-        if(direction != 4 && world.getSignal(x - 1, y, z, Side.WEST)) {
-            return true;
-        }
-        if(world.getSignal(x, y, z, Side.BOTTOM)) {
-            return true;
-        }
-        // QC
-        if(direction != 1 && world.getSignal(x, y + 2, z, Side.TOP)) {
-            return true;
-        }
-        if(world.getSignal(x, y + 1, z - 1, Side.NORTH)) {
-            return true;
-        }
-        if(world.getSignal(x, y + 1, z + 1, Side.SOUTH)) {
-            return true;
-        }
-        if(world.getSignal(x - 1, y + 1, z, Side.WEST)) {
-            return true;
-        }
-        return world.getSignal(x + 1, y + 1, z, Side.EAST);
-    }
-
-    @Override
-    public void triggerEvent(World world, int x, int y, int z, int index, int data)
-    {
-        // Index 0 is pushing, index 1 is retracting
-        int direction = data;
-        if (direction >= 6) direction = 0;
-        if(index == 0)
-        {
-            if(tryExtend(world, x, y, z, direction))
-            {
-                world.setBlockMetadataWithNotify(x, y, z, direction | 8);
-                world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double)x + 0.5D, (double)y + 0.5D, (double)z + 0.5D, "tile.piston.out", 0.5F, world.rand.nextFloat() * 0.25F + 0.6F);
-            }
-        }
-        else if(index == 1)
-        {
-            BlockEntity tileentity = world.getBlockEntity(x + PistonDirections.xOffset[direction], y + PistonDirections.yOffset[direction], z + PistonDirections.zOffset[direction]);
-            if(tileentity != null && (tileentity instanceof MovingPistonBlockEntity))
-            {
-                MovingPistonBlockEntity moving = ((MovingPistonBlockEntity) tileentity);
-                if (!moving.isExtending()) {
-                    ((MovingPistonBlockEntity)tileentity).finalTick();
-                } else {
-                    world.setBlock(x + PistonDirections.xOffset[direction], y + PistonDirections.yOffset[direction], z + PistonDirections.zOffset[direction], 0);
-                }
-            }
-            world.setBlockAndMetadata(x, y, z, Blocks.PISTON_MOVING.id, direction);
-            world.replaceBlockTileEntity(x, y, z, MovingPistonBlock.createTileEntity(id, direction, direction, false, true));
-            if(isSticky)
-            {
-                int x1 = x + PistonDirections.xOffset[direction] * 2;
-                int y1 = y + PistonDirections.yOffset[direction] * 2;
-                int z1 = z + PistonDirections.zOffset[direction] * 2;
-                int id1 = world.getBlockId(x1, y1, z1);
-                int meta1 = world.getBlockMetadata(x1, y1, z1);
-                boolean flag = false;
-                if(id1 == Blocks.PISTON_MOVING.id)
-                {
-                    BlockEntity tileentity1 = world.getBlockEntity(x1, y1, z1);
-                    if(tileentity1 != null && (tileentity1 instanceof MovingPistonBlockEntity))
-                    {
-                        MovingPistonBlockEntity tileentitypiston = (MovingPistonBlockEntity)tileentity1;
-                        if(tileentitypiston.getDirection() == direction && tileentitypiston.isExtending())
-                        {
-                            tileentitypiston.finalTick();
-                            id1 = tileentitypiston.getMovedId();
-                            meta1 = tileentitypiston.getMovedData();
-                            flag = true;
-                        }
-                    }
-                }
-                if(!flag && id1 > 0 && isPushable(id1, world, x1, y1, z1, false) && (Block.blocksList[id1].getPistonPushReaction() == 0 || id1 == Blocks.PISTON_BASE.id || id1 == Blocks.PISTON_BASE_STICKY.id))
-                {
-                    world.setBlock(x1, y1, z1, 0);
-                    x += PistonDirections.xOffset[direction];
-                    y += PistonDirections.yOffset[direction];
-                    z += PistonDirections.zOffset[direction];
-                    world.setBlockAndMetadata(x, y, z, Blocks.PISTON_MOVING.id, meta1);
-                    world.replaceBlockTileEntity(x, y, z, MovingPistonBlock.createTileEntity(id1, meta1, direction, false, false));
-                    world.notifyBlockChange(x1, y1, z1, 0);
-                } else
-                if(!flag)
-                {
-                    world.setBlockWithNotify(x + PistonDirections.xOffset[direction], y + PistonDirections.yOffset[direction], z + PistonDirections.zOffset[direction], 0);
-                }
-            } else
-            {
-                world.setBlockWithNotify(x + PistonDirections.xOffset[direction], y + PistonDirections.yOffset[direction], z + PistonDirections.zOffset[direction], 0);
-            }
-            world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double)x + 0.5D, (double)y + 0.5D, (double)z + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat() * 0.15F + 0.6F);
-        }
-    }
-
-    @Override
-    public void setBlockBoundsBasedOnState(WorldSource world, int x, int y, int z)
-    {
-        int l = world.getBlockMetadata(x, y, z);
-        if(isPowered(l))
-        {
-            switch(getDirection(l))
-            {
-            case 0:
-                setBlockBounds(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F);
-                break;
-            case 1:
-                setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F);
-                break;
-            case 2:
-                setBlockBounds(0.0F, 0.0F, 0.25F, 1.0F, 1.0F, 1.0F);
-                break;
-            case 3:
-                setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.75F);
-                break;
-            case 4:
-                setBlockBounds(0.25F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
-                break;
-            case 5:
-                setBlockBounds(0.0F, 0.0F, 0.0F, 0.75F, 1.0F, 1.0F);
-                break;
-            }
-        } else
-        {
-            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
-        }
-    }
-    @Override
-    public void getCollidingBoundingBoxes(World world, int x, int y, int z, AABB aabb, ArrayList<AABB> aabbs)
-    {
-        setBlockBoundsBasedOnState(world, x, y, z);
-        super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbs);
-    }
-
-    @Override
-	public boolean isCubeShaped()
-    {
-        return false;
-    }
-
-    public static int getDirection(int data)
-    {
-        return data & 0b111;
-    }
-
-    public static boolean isPowered(int data)
-    {
-        return (data & 8) != 0;
-    }
-    
-    private static boolean isPushable(int id, World world, int x, int y, int z, boolean canDestroy)
-    {
-        if(id == Blocks.OBSIDIAN.id)
-        {
-            return false;
-        }
-        if(id == Blocks.PISTON_BASE.id || id == Blocks.PISTON_BASE_STICKY.id)
-        {
-            if(isPowered(world.getBlockMetadata(x, y, z)))
-            {
-                return false;
-            }
-        } else
-        {
-            if(Block.blocksList[id].getHardness() == -1F)
-            {
-                return false;
-            }
-            if(Block.blocksList[id].getPistonPushReaction() == 2)
-            {
-                return false;
-            }
-            if(Block.blocksList[id].getImmovable())
-            {
-                return false;
-            }
-            if(!canDestroy && Block.blocksList[id].getPistonPushReaction() == 1)
-            {
-                return false;
-            }
-        }
-        BlockEntity tileentity = world.getBlockEntity(x, y, z);
-        return tileentity == null;
-    }
-
-    private static boolean canPushLine(World world, int x, int y, int z, int direction)
-    {
-        int xo = x + PistonDirections.xOffset[direction % 6];
-        int yo = y + PistonDirections.yOffset[direction % 6];
-        int zo = z + PistonDirections.zOffset[direction % 6];
-        int i = 0;
-        do
-        {
-            if(i >= 13)
-            {
-                break;
-            }
-            if(yo < 0 || yo >= world.getHeightBlocks())
-            {
-                return false;
-            }
-            int id = world.getBlockId(xo, yo, zo);
-            if(id == 0)
-            {
-                break;
-            }
-            if(!isPushable(id, world, xo, yo, zo, true))
-            {
-                if(i == 1 && (id == Blocks.OBSIDIAN.id || id == Blocks.BEDROCK.id)){
-                    int x2 = x + PistonDirections.xOffset[direction % 6];
-                    int y2 = y + PistonDirections.yOffset[direction % 6];
-                    int z2 = z + PistonDirections.zOffset[direction % 6];
-                    world.playSoundEffect(null, 2001, x2, y2, z2, world.getBlockId(x2, y2, z2));
-                    Block.blocksList[world.getBlockId(x2, y2, z2)].dropBlockWithCause(world, EnumDropCause.SILK_TOUCH, x2, y2, z2, world.getBlockMetadata(x2, y2, z2), null, null);
-                    world.setBlockWithNotify(x2, y2, z2, 0);
-                    break;
-                }
-                return false;
-            }
-            if(Block.blocksList[id].getPistonPushReaction() == 1)
-            {
-                break;
-            }
-            if(i == 12)
-            {
-                return false;
-            }
-            xo += PistonDirections.xOffset[direction % 6];
-            yo += PistonDirections.yOffset[direction % 6];
-            zo += PistonDirections.zOffset[direction % 6];
-            i++;
-        } while(true);
-        return true;
-    }
-
-    private boolean tryExtend(World world, int x, int y, int z, int direction)
-    {
-        int xo = x + PistonDirections.xOffset[direction % 6];
-        int yo = y + PistonDirections.yOffset[direction % 6];
-        int zo = z + PistonDirections.zOffset[direction % 6];
-        int l1 = 0;
-        do
-        {
-            if(l1 >= 13)
-            {
-                break;
-            }
-            if(yo < 0 || yo >= world.getHeightBlocks())
-            {
-                return false;
-            }
-            int j2 = world.getBlockId(xo, yo, zo);
-            if(j2 == 0)
-            {
-                break;
-            }
-            if(!isPushable(j2, world, xo, yo, zo, true))
-            {
-                return false;
-            }
-            if(Block.blocksList[j2].getPistonPushReaction() == 1)
-            {
-                Block.blocksList[j2].dropBlockWithCause(world, EnumDropCause.WORLD, xo, yo, zo, world.getBlockMetadata(xo, yo, zo), null, null);
-                world.setBlockWithNotify(xo, yo, zo, 0);
-                break;
-            }
-            if(l1 == 12)
-            {
-                return false;
-            }
-            xo += PistonDirections.xOffset[direction % 6];
-            yo += PistonDirections.yOffset[direction % 6];
-            zo += PistonDirections.zOffset[direction % 6];
-            l1++;
-        } while(true);
-        int l2 = 0;
-        for(; xo != x || yo != y || zo != z; zo = l2)
-        {
-            int i2 = xo - PistonDirections.xOffset[direction % 6];
-            int k2 = yo - PistonDirections.yOffset[direction % 6];
-            l2 = zo - PistonDirections.zOffset[direction % 6];
-            int i3 = world.getBlockId(i2, k2, l2);
-            int j3 = world.getBlockMetadata(i2, k2, l2);
-            if(i3 == id && i2 == x && k2 == y && l2 == z)
-            {
-                world.setBlockAndMetadata(xo, yo, zo, Blocks.PISTON_MOVING.id, direction | (isSticky ? 8 : 0));
-                world.replaceBlockTileEntity(xo, yo, zo, MovingPistonBlock.createTileEntity(Blocks.PISTON_HEAD.id, direction | (isSticky ? 8 : 0), direction, true, false));
-            } else if (i3 == Blocks.PISTON_MOVING.id)
-            {
-                BlockEntity old = world.getBlockEntity(i2, k2, l2);
-                if (old instanceof MovingPistonBlockEntity) {
-                    MovingPistonBlockEntity moving = (MovingPistonBlockEntity) old;
-                    if (!moving.isSourcePiston()) {
-                        i3 = moving.getMovedId();
-                        j3 = moving.getMovedData();
-                        world.removeBlockTileEntity(i2, k2, l2);
-                    }
-                }
-                world.setBlockAndMetadata(xo, yo, zo, Blocks.PISTON_MOVING.id, j3);
-                world.replaceBlockTileEntity(xo, yo, zo, MovingPistonBlock.createTileEntity(i3, j3, direction, true, false));
-            } else
-            {
-                world.setBlockAndMetadata(xo, yo, zo, Blocks.PISTON_MOVING.id, j3);
-                world.replaceBlockTileEntity(xo, yo, zo, MovingPistonBlock.createTileEntity(i3, j3, direction, true, false));
-            }
-            xo = i2;
-            yo = k2;
-        }
-
-        return true;
-    }
-    
-    @Override
-    public int getPlacedBlockMetadata(Player player, ItemStack stack, World world, int x, int y, int z, Side side, double xPlaced, double yPlaced) {
-    	return 7;
-    }
-
-    private boolean isSticky;
-    
-}
diff --git a/src/main/java/net/minecraft/core/block/piston/MovingPistonBlock.java b/src/main/java/net/minecraft/core/block/piston/MovingPistonBlock.java
index a21b97e82..51c42e8e0 100644
--- a/src/main/java/net/minecraft/core/block/piston/MovingPistonBlock.java
+++ b/src/main/java/net/minecraft/core/block/piston/MovingPistonBlock.java
@@ -6,21 +6,16 @@ import net.minecraft.core.block.entity.BlockEntity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.block.logic.PistonDirections;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.util.phys.AABB;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.World;
 import net.minecraft.core.block.material.Material;
-
-// Referenced classes of package net.minecraft.src:
-//            BlockContainer, Material, World, TileEntityPiston,
-//            Block, PistonBlockTextures, AxisAlignedBB, IBlockAccess,
-//            BlockEntity, Player
+import org.jetbrains.annotations.Nullable;
 
 public class MovingPistonBlock extends EntityBlock
 {
-
     public MovingPistonBlock(String key, String namespaceId, int id)
     {
         super(key, namespaceId, id, Material.piston);
@@ -41,10 +36,10 @@ public class MovingPistonBlock extends EntityBlock
     @Override
     public void onBlockRemoved(World world, int x, int y, int z, int data)
     {
-        BlockEntity tileentity = world.getBlockEntity(x, y, z);
-        if(tileentity != null && (tileentity instanceof MovingPistonBlockEntity))
+        BlockEntity blockEntity = world.getBlockEntity(x, y, z);
+        if((blockEntity instanceof MovingPistonBlockEntity))
         {
-            ((MovingPistonBlockEntity)tileentity).finalTick();
+            ((MovingPistonBlockEntity)blockEntity).finalTick();
         } else
         {
             super.onBlockRemoved(world, x, y, z, data);
@@ -120,9 +115,10 @@ public class MovingPistonBlock extends EntityBlock
         }
     }
 
-    public static BlockEntity createTileEntity(int id, int oldData, int newData, boolean flag, boolean flag1)
+    public static BlockEntity createTileEntity(int movedId, int movedData, @Nullable BlockEntity movedEntity, Direction direction, boolean extending, boolean isSourcePiston)
     {
-        return new MovingPistonBlockEntity(id, oldData, newData, flag, flag1);
+        assert !(movedEntity instanceof MovingPistonBlockEntity) : "Moving piston entity should not be able to be put into another moving piston!";
+        return new MovingPistonBlockEntity(movedId, movedData, movedEntity, direction, extending, isSourcePiston);
     }
 
     @Override
@@ -144,49 +140,49 @@ public class MovingPistonBlock extends EntityBlock
     @Override
     public void setBlockBoundsBasedOnState(WorldSource world, int x, int y, int z)
     {
-        MovingPistonBlockEntity tileentitypiston = getBlockEntity(world, x, y, z);
-        if(tileentitypiston != null)
+        MovingPistonBlockEntity pistonBlockEntity = getBlockEntity(world, x, y, z);
+        if(pistonBlockEntity != null)
         {
-            Block block = Block.blocksList[tileentitypiston.getMovedId()];
+            Block block = Block.blocksList[pistonBlockEntity.getMovedId()];
             if(block == null || block == this)
             {
                 return;
             }
             block.setBlockBoundsBasedOnState(world, x, y, z);
-            float f = tileentitypiston.getProgress(0.0F);
-            if(tileentitypiston.isExtending())
+            float f = pistonBlockEntity.getProgress(0.0F);
+            if(pistonBlockEntity.isExtending())
             {
                 f = 1.0F - f;
             }
-            int l = tileentitypiston.getDirection();
-            minX = block.minX - (double)((float) PistonDirections.xOffset[l] * f);
-            minY = block.minY - (double)((float) PistonDirections.yOffset[l] * f);
-            minZ = block.minZ - (double)((float) PistonDirections.zOffset[l] * f);
-            maxX = block.maxX - (double)((float) PistonDirections.xOffset[l] * f);
-            maxY = block.maxY - (double)((float) PistonDirections.yOffset[l] * f);
-            maxZ = block.maxZ - (double)((float) PistonDirections.zOffset[l] * f);
+            Direction direction = pistonBlockEntity.getDirection();
+            minX = block.minX - direction.getOffsetX() * f;
+            maxX = block.maxX - direction.getOffsetX() * f;
+            minY = block.minY - direction.getOffsetY() * f;
+            maxY = block.maxY - direction.getOffsetY() * f;
+            minZ = block.minZ - direction.getOffsetZ() * f;
+            maxZ = block.maxZ - direction.getOffsetZ() * f;
         }
     }
 
-    public AABB getCollisionShapeFromTileEntity(WorldSource world, int x, int y, int z, int l, float f, int i1)
+    public AABB getCollisionShapeFromTileEntity(WorldSource world, int x, int y, int z, int blockID, float directionStretch, Direction direction)
     {
-        if(l == 0 || l == id)
+        if(blockID == 0 || blockID == id)
         {
             return null;
         }
-        AABB axisalignedbb = Block.blocksList[l].getCollisionBoundingBoxFromPool(world, x, y, z);
-        if(axisalignedbb == null)
+        AABB aabb = Block.blocksList[blockID].getCollisionBoundingBoxFromPool(world, x, y, z);
+        if(aabb == null)
         {
             return null;
         } else
         {
-            axisalignedbb.minX -= (float) PistonDirections.xOffset[i1] * f;
-            axisalignedbb.maxX -= (float) PistonDirections.xOffset[i1] * f;
-            axisalignedbb.minY -= (float) PistonDirections.yOffset[i1] * f;
-            axisalignedbb.maxY -= (float) PistonDirections.yOffset[i1] * f;
-            axisalignedbb.minZ -= (float) PistonDirections.zOffset[i1] * f;
-            axisalignedbb.maxZ -= (float) PistonDirections.zOffset[i1] * f;
-            return axisalignedbb;
+            aabb.minX -= direction.getOffsetX() * directionStretch;
+            aabb.maxX -= direction.getOffsetX() * directionStretch;
+            aabb.minY -= direction.getOffsetY() * directionStretch;
+            aabb.maxY -= direction.getOffsetY() * directionStretch;
+            aabb.minZ -= direction.getOffsetZ() * directionStretch;
+            aabb.maxZ -= direction.getOffsetZ() * directionStretch;
+            return aabb;
         }
     }
 
diff --git a/src/main/java/net/minecraft/core/block/piston/MovingPistonBlockEntity.java b/src/main/java/net/minecraft/core/block/piston/MovingPistonBlockEntity.java
index e9406cf4d..e1f113dd8 100644
--- a/src/main/java/net/minecraft/core/block/piston/MovingPistonBlockEntity.java
+++ b/src/main/java/net/minecraft/core/block/piston/MovingPistonBlockEntity.java
@@ -3,24 +3,38 @@ package net.minecraft.core.block.piston;
 import net.minecraft.core.block.entity.BlockEntity;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.block.Blocks;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.phys.AABB;
 import com.mojang.nbt.CompoundTag;
-import net.minecraft.core.block.logic.PistonDirections;
 import net.minecraft.core.world.World;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
 
 public class MovingPistonBlockEntity extends BlockEntity
 {
+    public static final int TICKS_TO_EXTEND = 2;
+    private static final List<Entity> entityBuffer = new ArrayList<>();
 
+    private int movedId;
+    private int movedData;
+    private @Nullable BlockEntity movedEntity;
+    private Direction direction;
+    private boolean extending;
+    private boolean isSourcePiston;
+    private float progress;
+    private float progressO;
+
+    @SuppressWarnings("unused")
     public MovingPistonBlockEntity()
     {
     }
 
-    public MovingPistonBlockEntity(int movedId, int movedData, int direction, boolean extending, boolean isSourcePiston)
+    public MovingPistonBlockEntity(int movedId, int movedData, @Nullable BlockEntity movedEntity, Direction direction, boolean extending, boolean isSourcePiston)
     {
         this.movedId = movedId;
         this.movedData = movedData;
+        this.movedEntity = movedEntity;
         this.direction = direction;
         this.extending = extending;
         this.isSourcePiston = isSourcePiston;
@@ -38,12 +52,16 @@ public class MovingPistonBlockEntity extends BlockEntity
         return movedData;
     }
 
+    public @Nullable BlockEntity getMovedEntity() {
+        return movedEntity;
+    }
+
     public boolean isExtending()
     {
         return extending;
     }
 
-    public int getDirection()
+    public Direction getDirection()
     {
         return direction;
     }
@@ -66,10 +84,10 @@ public class MovingPistonBlockEntity extends BlockEntity
     {
         if(extending)
         {
-            return (getProgress(partialTick) - 1.0F) * (float) PistonDirections.xOffset[direction];
+            return (getProgress(partialTick) - 1.0F) * (float) direction.getOffsetX();
         } else
         {
-            return (1.0F - getProgress(partialTick)) * (float) PistonDirections.xOffset[direction];
+            return (1.0F - getProgress(partialTick)) * (float) direction.getOffsetX();
         }
     }
 
@@ -77,10 +95,10 @@ public class MovingPistonBlockEntity extends BlockEntity
     {
         if(extending)
         {
-            return (getProgress(partialTick) - 1.0F) * (float) PistonDirections.yOffset[direction];
+            return (getProgress(partialTick) - 1.0F) * (float) direction.getOffsetY();
         } else
         {
-            return (1.0F - getProgress(partialTick)) * (float) PistonDirections.yOffset[direction];
+            return (1.0F - getProgress(partialTick)) * (float) direction.getOffsetY();
         }
     }
 
@@ -88,40 +106,34 @@ public class MovingPistonBlockEntity extends BlockEntity
     {
         if(extending)
         {
-            return (getProgress(partialTick) - 1.0F) * (float) PistonDirections.zOffset[direction];
+            return (getProgress(partialTick) - 1.0F) * (float) direction.getOffsetZ();
         } else
         {
-            return (1.0F - getProgress(partialTick)) * (float) PistonDirections.zOffset[direction];
+            return (1.0F - getProgress(partialTick)) * (float) direction.getOffsetZ();
         }
     }
 
-    private void moveCollidedEntities(float f, float f1)
+    private void moveCollidedEntities(float stretch, float force)
     {
         if(!extending)
         {
-            f--;
+            stretch--;
         } else
         {
-            f = 1.0F - f;
+            stretch = 1.0F - stretch;
         }
-        AABB axisalignedbb = ((MovingPistonBlock) Blocks.PISTON_MOVING).getCollisionShapeFromTileEntity(worldObj, x, y, z, movedId, f, direction);
-        if(axisalignedbb != null)
+        AABB aabb = ((MovingPistonBlock) Blocks.PISTON_MOVING).getCollisionShapeFromTileEntity(worldObj, x, y, z, movedId, stretch, direction);
+        if (aabb == null) return;
+
+        List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(null, aabb);
+        if(!list.isEmpty())
         {
-            List list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
-            if(!list.isEmpty())
-            {
-                field_31018_m.addAll(list);
-                Entity entity = null;
-                Iterator iterator = field_31018_m.iterator();
-                do
-                {
-                    entity = (Entity)iterator.next();
-                    if (entity == null || entity.noPhysics) continue;
-                    entity.move(f1 * (float) PistonDirections.xOffset[direction], f1 * (float) PistonDirections.yOffset[direction], f1 * (float) PistonDirections.zOffset[direction]);
-                } while (iterator.hasNext());
-
-                field_31018_m.clear();
+            entityBuffer.addAll(list);
+            for (Entity entity : entityBuffer) {
+                if (entity == null || entity.noPhysics) continue;
+                entity.move(force * (float) direction.getOffsetX(), force * (float) direction.getOffsetY(), force * (float) direction.getOffsetZ());
             }
+            entityBuffer.clear();
         }
     }
 
@@ -131,7 +143,20 @@ public class MovingPistonBlockEntity extends BlockEntity
         worldObj.removeBlockTileEntity(x, y, z);
         invalidate();
         if(worldObj.getBlockId(x, y, z) == Blocks.PISTON_MOVING.id) {
-            worldObj.setBlockAndMetadataWithNotify(x, y, z, movedId, movedData);
+            worldObj.setBlock(x, y, z, movedId);
+            worldObj.setBlockMetadata(x, y, z, movedData);
+            worldObj.notifyBlockChange(x, y, z, movedId);
+            if (movedEntity != null) {
+                BlockEntity oldEnt = worldObj.getBlockEntity(x, y, z);
+                if (oldEnt != null) {
+                    oldEnt.invalidate();
+                }
+                movedEntity.validate();
+                movedEntity.x = x;
+                movedEntity.y = y;
+                movedEntity.z = z;
+                worldObj.replaceBlockTileEntity(x, y, z, movedEntity);
+            }
         }
     }
 
@@ -145,8 +170,8 @@ public class MovingPistonBlockEntity extends BlockEntity
             finalTick();
             return;
         }
-        progress += 0.5F;
-        if(progress >= 1.0F)
+        progress += 1f/TICKS_TO_EXTEND;
+        if(progress >= 0.999F)
         {
             progress = 1.0F;
         }
@@ -162,7 +187,11 @@ public class MovingPistonBlockEntity extends BlockEntity
         super.readFromNBT(tag);
         movedId = tag.getInteger("blockId");
         movedData = tag.getInteger("blockData");
-        direction = tag.getInteger("facing");
+        if (tag.containsKey("blockEntity")) {
+            CompoundTag entityTag = tag.getCompound("blockEntity");
+            movedEntity = BlockEntity.createAndLoadEntity(entityTag);
+        }
+        direction = Direction.getDirectionById(tag.getInteger("facing"));
         progressO = progress = tag.getFloat("progress");
         extending = tag.getBoolean("extending");
     }
@@ -173,7 +202,12 @@ public class MovingPistonBlockEntity extends BlockEntity
         super.writeToNBT(tag);
         tag.putInt("blockId", movedId);
         tag.putInt("blockData", movedData);
-        tag.putInt("facing", direction);
+        if (movedEntity != null) {
+            CompoundTag entityTag = new CompoundTag();
+            movedEntity.writeToNBT(entityTag);
+            tag.put("blockEntity", entityTag);
+        }
+        tag.putInt("facing", direction.getId());
         tag.putFloat("progress", progressO);
         tag.putBoolean("extending", extending);
     }
@@ -182,14 +216,4 @@ public class MovingPistonBlockEntity extends BlockEntity
     public boolean canBeCarried(World world, Entity potentialHolder) {
         return false;
     }
-
-    private int movedId;
-    private int movedData;
-    private int direction;
-    private boolean extending;
-    private boolean isSourcePiston;
-    private float progress;
-    private float progressO;
-    private static List field_31018_m = new ArrayList();
-
 }
diff --git a/src/main/java/net/minecraft/core/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/core/block/piston/PistonBaseBlock.java
new file mode 100644
index 000000000..8d860ad50
--- /dev/null
+++ b/src/main/java/net/minecraft/core/block/piston/PistonBaseBlock.java
@@ -0,0 +1,380 @@
+package net.minecraft.core.block.piston;
+
+import java.util.ArrayList;
+
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.Blocks;
+import net.minecraft.core.block.entity.BlockEntity;
+import net.minecraft.core.block.material.Material;
+import net.minecraft.core.block.tag.BlockTags;
+import net.minecraft.core.entity.Mob;
+import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.enums.EnumDropCause;
+import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.sound.SoundCategory;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.util.helper.Side;
+import net.minecraft.core.util.phys.AABB;
+import net.minecraft.core.world.LevelListener;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.WorldSource;
+
+public class PistonBaseBlock extends Block
+{
+    public static final int MASK_DIRECTION = 0b0000_0111;
+    public static final int MASK_POWERED = 0b0000_1000;
+
+    public static final int EVENT_EXTEND = 0;
+    public static final int EVENT_RETRACT = 1;
+
+    private final int maxPushedBlocks;
+
+    public PistonBaseBlock(String key, String namespaceId, int id, int maxPushedBlocks)
+    {
+        super(key, namespaceId, id, Material.piston);
+        this.maxPushedBlocks = maxPushedBlocks;
+        withHardness(0.5F);
+    }
+
+    @Override
+	public boolean isSolidRender()
+    {
+        return false;
+    }
+
+    @Override
+    public void onBlockPlacedByMob(World world, int x, int y, int z, Side side, Mob mob, double sideHeight) {
+    	Direction placementDirection = mob.getPlacementDirection(side).getOpposite();
+        world.setBlockMetadataWithNotify(x, y, z, placementDirection.getId());
+        if(!world.isClientSide)
+        {
+            checkIfExtend(world, x, y, z);
+        }
+    }
+
+    @Override
+	public void onNeighborBlockChange(World world, int x, int y, int z, int blockId)
+    {
+        checkIfExtend(world, x, y, z);
+    }
+
+    @Override
+	public void onBlockPlacedByWorld(World world, int x, int y, int z)
+    {
+        if(!world.isClientSide && world.getBlockEntity(x, y, z) == null)
+        {
+            checkIfExtend(world, x, y, z);
+        }
+    }
+
+    private void checkIfExtend(World world, int x, int y, int z)
+    {
+        int data = world.getBlockMetadata(x, y, z);
+        Direction direction = getDirection(data);
+        boolean hasNeighborSignal = getNeighborSignal(world, x, y, z, direction);
+        if(data == MASK_DIRECTION)
+        {
+            return;
+        }
+        if(hasNeighborSignal && !isPowered(data))
+        {
+            if(canPushLine(world, x, y, z, direction, maxPushedBlocks))
+            {
+                world.setBlockMetadata(x, y, z, direction.getId() | MASK_POWERED);
+                world.triggerEvent(x, y, z, EVENT_EXTEND, direction.getId());
+            }
+        }
+        else if(!hasNeighborSignal && isPowered(data))
+        {
+            world.setBlockMetadata(x, y, z, direction.getId());
+            world.triggerEvent(x, y, z, EVENT_RETRACT, direction.getId());
+        }
+    }
+
+    private boolean getNeighborSignal(World world, int x, int y, int z, Direction direction) {
+        if(direction != Direction.DOWN && world.getSignal(x, y - 1, z, Side.BOTTOM)) {
+            return true;
+        }
+        if(direction != Direction.UP && world.getSignal(x, y + 1, z, Side.TOP)) {
+            return true;
+        }
+        if(direction != Direction.NORTH && world.getSignal(x, y, z - 1, Side.NORTH)) {
+            return true;
+        }
+        if(direction != Direction.SOUTH && world.getSignal(x, y, z + 1, Side.SOUTH)) {
+            return true;
+        }
+        if(direction != Direction.EAST && world.getSignal(x + 1, y, z, Side.EAST)) {
+            return true;
+        }
+        if(direction != Direction.WEST && world.getSignal(x - 1, y, z, Side.WEST)) {
+            return true;
+        }
+        if(world.getSignal(x, y, z, Side.BOTTOM)) {
+            return true;
+        }
+        // QC
+        if(direction != Direction.UP && world.getSignal(x, y + 2, z, Side.TOP)) {
+            return true;
+        }
+        if(world.getSignal(x, y + 1, z - 1, Side.NORTH)) {
+            return true;
+        }
+        if(world.getSignal(x, y + 1, z + 1, Side.SOUTH)) {
+            return true;
+        }
+        if(world.getSignal(x - 1, y + 1, z, Side.WEST)) {
+            return true;
+        }
+        return world.getSignal(x + 1, y + 1, z, Side.EAST);
+    }
+
+    @Override
+    public void triggerEvent(World world, int x, int y, int z, int index, int data)
+    {
+        Direction direction = getDirection(data);
+        if (direction == Direction.NONE) direction = Direction.DOWN; // Probably going to end with a downwards facing bedrock breaker
+        if(index == EVENT_EXTEND)
+        {
+            extendEvent(world, x, y, z, data, direction);
+        }
+        else if(index == EVENT_RETRACT)
+        {
+            retractEvent(world, x, y, z, data, direction);
+        }
+    }
+
+    public void extendEvent(World world, int x, int y, int z, int data, Direction direction) {
+        if(tryExtend(world, x, y, z, direction, maxPushedBlocks))
+        {
+            world.setBlockMetadataWithNotify(x, y, z, direction.getId() | MASK_POWERED);
+            world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double)x + 0.5D, (double)y + 0.5D, (double)z + 0.5D, "tile.piston.out", 0.5F, world.rand.nextFloat() * 0.25F + 0.6F);
+        }
+    }
+
+    public void retractEvent(World world, int x, int y, int z, int data, Direction direction) {
+        BlockEntity blockEntity = world.getBlockEntity(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ());
+        if((blockEntity instanceof MovingPistonBlockEntity))
+        {
+            MovingPistonBlockEntity moving = ((MovingPistonBlockEntity) blockEntity);
+            if (!moving.isExtending()) {
+                ((MovingPistonBlockEntity)blockEntity).finalTick();
+            } else {
+                world.setBlock(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ(), 0);
+            }
+        }
+        world.setBlockAndMetadata(x, y, z, Blocks.PISTON_MOVING.id, direction.getId());
+        world.replaceBlockTileEntity(x, y, z, MovingPistonBlock.createTileEntity(id, direction.getId(), null, direction, false, true));
+        world.setBlockWithNotify(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ(), 0);
+        world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double)x + 0.5D, (double)y + 0.5D, (double)z + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat() * 0.15F + 0.6F);
+    }
+
+    @Override
+    public void setBlockBoundsBasedOnState(WorldSource world, int x, int y, int z)
+    {
+        int data = world.getBlockMetadata(x, y, z);
+        if(isPowered(data))
+        {
+            switch(getDirection(data))
+            {
+                case DOWN:
+                setBlockBounds(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F);
+                break;
+                case UP:
+                setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F);
+                break;
+                case NORTH:
+                setBlockBounds(0.0F, 0.0F, 0.25F, 1.0F, 1.0F, 1.0F);
+                break;
+                case SOUTH:
+                setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.75F);
+                break;
+                case WEST:
+                setBlockBounds(0.25F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+                break;
+                case EAST:
+                setBlockBounds(0.0F, 0.0F, 0.0F, 0.75F, 1.0F, 1.0F);
+                break;
+            }
+        } else
+        {
+            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+        }
+    }
+    @Override
+    public void getCollidingBoundingBoxes(World world, int x, int y, int z, AABB aabb, ArrayList<AABB> aabbs)
+    {
+        setBlockBoundsBasedOnState(world, x, y, z);
+        super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbs);
+    }
+
+    @Override
+	public boolean isCubeShaped()
+    {
+        return false;
+    }
+
+    public static Direction getDirection(int data)
+    {
+        return Direction.getDirectionById(data & MASK_DIRECTION);
+    }
+
+    public static boolean isPowered(int data)
+    {
+        return (data & MASK_POWERED) != 0;
+    }
+    
+    protected boolean isPushable(int id, World world, int x, int y, int z, boolean canDestroy)
+    {
+        Block block = Block.getBlock(id);
+        if (block == null) return false;
+        int pushReaction = block.getPistonPushReaction(world, x, y, z);
+        if (block.hasTag(BlockTags.PISTON_CRUSHING) ||
+            block.getImmovable() ||
+            pushReaction == Material.PISTON_CANT_PUSH ||
+            (!canDestroy && pushReaction == Material.PISTON_DESTROY_ON_PUSH) ||
+            block.getHardness() == -1F) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int getPistonPushReaction(World world, int x, int y, int z) {
+        if (isPowered(world.getBlockMetadata(x, y, z))) {
+            return Material.PISTON_CANT_PUSH;
+        }
+        return super.getPistonPushReaction(world, x, y, z);
+    }
+
+    protected boolean canPushLine(World world, int x, int y, int z, Direction direction, int maxPushedBlocks)
+    {
+        int xo = x + direction.getOffsetX();
+        int yo = y + direction.getOffsetY();
+        int zo = z + direction.getOffsetZ();
+        int blocks = 0;
+        while (true) {
+            if (blocks >= maxPushedBlocks + 1) {
+                break;
+            }
+            if (yo < 0 || yo >= world.getHeightBlocks()) {
+                return false;
+            }
+            int id = world.getBlockId(xo, yo, zo);
+            if (id == 0) {
+                break;
+            }
+            if (!isPushable(id, world, xo, yo, zo, true)) {
+                if (blocks == 1 && BlockTags.PISTON_CRUSHING.appliesTo(Block.getBlock(id)) && tryCrush(world, x, y, z, direction)) {
+                    break;
+                }
+                return false;
+            }
+            if (Block.blocksList[id].getPistonPushReaction(world, xo, yo, zo) == Material.PISTON_DESTROY_ON_PUSH) {
+                break;
+            }
+            if (blocks == maxPushedBlocks) {
+                return false;
+            }
+            xo += direction.getOffsetX();
+            yo += direction.getOffsetY();
+            zo += direction.getOffsetZ();
+            blocks++;
+        }
+        return true;
+    }
+
+    public boolean tryCrush(World world, int x, int y, int z, Direction direction) {
+        int x2 = x + direction.getOffsetX();
+        int y2 = y + direction.getOffsetY();
+        int z2 = z + direction.getOffsetZ();
+        Block block = world.getBlock(x2, y2, z2);
+        if (block == null) return true;
+        world.playSoundEffect(null, LevelListener.EVENT_BLOCK_BREAK, x2, y2, z2, world.getBlockId(x2, y2, z2));
+        block.dropBlockWithCause(world, EnumDropCause.SILK_TOUCH, x2, y2, z2, world.getBlockMetadata(x2, y2, z2), null, null);
+        world.setBlockWithNotify(x2, y2, z2, 0);
+        return true;
+    }
+
+    protected boolean tryExtend(World world, int x, int y, int z, Direction direction, int maxPushedBlocks)
+    {
+        int data = world.getBlockMetadata(x, y, z);
+        int xo = x + direction.getOffsetX();
+        int yo = y + direction.getOffsetY();
+        int zo = z + direction.getOffsetZ();
+        int blocks = 0;
+        while (true) {
+            if (blocks >= maxPushedBlocks + 1) {
+                break;
+            }
+            if (yo < 0 || yo >= world.getHeightBlocks()) {
+                return false;
+            }
+            int blockId = world.getBlockId(xo, yo, zo);
+            if (blockId == 0) {
+                break;
+            }
+            if (!isPushable(blockId, world, xo, yo, zo, true)) {
+                return false;
+            }
+            if (Block.blocksList[blockId].getPistonPushReaction(world, xo, yo, zo) == Material.PISTON_DESTROY_ON_PUSH) {
+                Block.blocksList[blockId].dropBlockWithCause(world, EnumDropCause.WORLD, xo, yo, zo, world.getBlockMetadata(xo, yo, zo), null, null);
+                world.setBlockWithNotify(xo, yo, zo, 0);
+                break;
+            }
+            if (blocks == maxPushedBlocks) {
+                return false;
+            }
+            xo += direction.getOffsetX();
+            yo += direction.getOffsetY();
+            zo += direction.getOffsetZ();
+            blocks++;
+        }
+        while (xo != x || yo != y || zo != z) {
+            int px = xo - direction.getOffsetX();
+            int py = yo - direction.getOffsetY();
+            int pz = zo - direction.getOffsetZ();
+            int pushId = world.getBlockId(px, py, pz);
+            int pushMeta = world.getBlockMetadata(px, py, pz);
+            BlockEntity pushEntity = world.getBlockEntity(px, py, pz);
+            if(pushId == id && px == x && py == y && pz == z)
+            {
+                createPistonHeadAt(world, xo, yo, zo, data, direction);
+            } else if (pushId == Blocks.PISTON_MOVING.id)
+            {
+                BlockEntity old = world.getBlockEntity(px, py, pz);
+                if (old instanceof MovingPistonBlockEntity) {
+                    MovingPistonBlockEntity moving = (MovingPistonBlockEntity) old;
+                    if (!moving.isSourcePiston()) {
+                        pushId = moving.getMovedId();
+                        pushMeta = moving.getMovedData();
+                        pushEntity = moving.getMovedEntity();
+                    }
+                }
+                world.removeBlockTileEntity(px, py, pz);
+                world.setBlockAndMetadata(xo, yo, zo, Blocks.PISTON_MOVING.id, pushMeta);
+                world.replaceBlockTileEntity(xo, yo, zo, MovingPistonBlock.createTileEntity(pushId, pushMeta, pushEntity, direction, true, false));
+            } else
+            {
+                world.removeBlockTileEntity(px, py, pz);
+                world.setBlockAndMetadata(xo, yo, zo, Blocks.PISTON_MOVING.id, pushMeta);
+                world.replaceBlockTileEntity(xo, yo, zo, MovingPistonBlock.createTileEntity(pushId, pushMeta, pushEntity, direction, true, false));
+            }
+            xo = px;
+            yo = py;
+            zo = pz;
+        }
+
+        return true;
+    }
+
+    public void createPistonHeadAt(World world, int x, int y, int z, int data, Direction direction) {
+        world.setBlockAndMetadata(x, y, z, Blocks.PISTON_MOVING.id, PistonHeadBlock.setPistonType(PistonHeadBlock.TYPE_NORMAL, direction.getId()));
+        world.replaceBlockTileEntity(x, y, z, MovingPistonBlock.createTileEntity(Blocks.PISTON_HEAD.id, PistonHeadBlock.setPistonType(PistonHeadBlock.TYPE_NORMAL, direction.getId()), null, direction, true, false));
+    }
+    
+    @Override
+    public int getPlacedBlockMetadata(Player player, ItemStack stack, World world, int x, int y, int z, Side side, double xPlaced, double yPlaced) {
+    	return MASK_DIRECTION; // For all faces piston blocks ig
+    }
+}
diff --git a/src/main/java/net/minecraft/core/block/piston/PistonHeadBlock.java b/src/main/java/net/minecraft/core/block/piston/PistonHeadBlock.java
index 027e1d67d..11cb1fdfe 100644
--- a/src/main/java/net/minecraft/core/block/piston/PistonHeadBlock.java
+++ b/src/main/java/net/minecraft/core/block/piston/PistonHeadBlock.java
@@ -8,7 +8,8 @@ import net.minecraft.core.block.entity.BlockEntity;
 import net.minecraft.core.block.material.Material;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.block.logic.PistonDirections;
+import net.minecraft.core.sound.BlockSound;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.util.phys.AABB;
 import net.minecraft.core.world.World;
@@ -16,33 +17,40 @@ import net.minecraft.core.world.WorldSource;
 
 public class PistonHeadBlock extends Block
 {
-
-    public PistonHeadBlock(String key, String namespaceId, int id)
+    public static final int MASK_DIRECTION = 0b0000_0111;
+    public static final int MASK_TYPE = 0b1111_1000;
+    public static final int TYPE_NORMAL = 0;
+    public static final int TYPE_STICKY = 1;
+    public static final int TYPE_STEEL = 2;
+
+    private final double headThickness;
+    public PistonHeadBlock(String key, String namespaceId, int id, double headThickness)
     {
         super(key, namespaceId, id, Material.piston);
         withHardness(0.5F);
+        this.headThickness = headThickness;
     }
 
     @Override
     public void onBlockRemoved(World world, int x, int y, int z, int data)
     {
         super.onBlockRemoved(world, x, y, z, data);
-        int direction = getDirectionFromMeta(data);
-        if(direction >= 6) {
+        Direction direction = getDirectionFromMeta(data);
+        if(direction == Direction.NONE) {
         	return;
         }
-        int orientation = PistonDirections.directionMap[direction];
-        x += PistonDirections.xOffset[orientation];
-        y += PistonDirections.yOffset[orientation];
-        z += PistonDirections.zOffset[orientation];
-        int k1 = world.getBlockId(x, y, z);
-        if(k1 == Blocks.PISTON_BASE.id || k1 == Blocks.PISTON_BASE_STICKY.id)
+        Direction orientation = direction.getOpposite();
+        int x2 = x + orientation.getOffsetX();
+        int y2 = y + orientation.getOffsetY();
+        int z2 = z + orientation.getOffsetZ();
+        Block block = world.getBlock(x2, y2, z2);
+        if(block instanceof PistonBaseBlock)
         {
-            int i1 = world.getBlockMetadata(x, y, z);
-            if(BasePistonBlock.isPowered(i1))
+            int data2 = world.getBlockMetadata(x2, y2, z2);
+            if(PistonBaseBlock.isPowered(data2))
             {
-                Block.blocksList[k1].dropBlockWithCause(world, EnumDropCause.PROPER_TOOL, x, y, z, i1, null, null);
-                world.setBlockWithNotify(x, y, z, 0);
+                block.dropBlockWithCause(world, EnumDropCause.PROPER_TOOL, x2, y2, z2, data2, null, null);
+                world.setBlockWithNotify(x2, y2, z2, 0);
             }
         }
     }
@@ -77,45 +85,45 @@ public class PistonHeadBlock extends Block
         int l = world.getBlockMetadata(x, y, z);
         switch(getDirectionFromMeta(l))
         {
-        case 0: // '\0'
-            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F);
+            case DOWN: // '\0'
+            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, headThickness, 1.0F);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
-            setBlockBounds(0.375F, 0.25F, 0.375F, 0.625F, 1.25F, 0.625F);
+            setBlockBounds(0.375F, headThickness, 0.375F, 0.625F, 1 + headThickness, 0.625F);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
             break;
 
-        case 1: // '\001'
-            setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F);
+            case UP: // '\001'
+            setBlockBounds(0.0F, 1 - headThickness, 0.0F, 1.0F, 1.0F, 1.0F);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
-            setBlockBounds(0.375F, -0.25F, 0.375F, 0.625F, 0.75F, 0.625F);
+            setBlockBounds(0.375F, -headThickness, 0.375F, 0.625F, 1 - headThickness, 0.625F);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
             break;
 
-        case 2: // '\002'
-            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F);
+            case NORTH: // '\002'
+            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, headThickness);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
-            setBlockBounds(0.25F, 0.375F, 0.25F, 0.75F, 0.625F, 1.25F);
+            setBlockBounds(headThickness, 0.375F, headThickness, 1 - headThickness, 0.625F, 1 + headThickness);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
             break;
 
-        case 3: // '\003'
-            setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F);
+            case SOUTH: // '\003'
+            setBlockBounds(0.0F, 0.0F, 1 - headThickness, 1.0F, 1.0F, 1.0F);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
-            setBlockBounds(0.25F, 0.375F, -0.25F, 0.75F, 0.625F, 0.75F);
+            setBlockBounds(headThickness, 0.375F, -headThickness, 1 - headThickness, 0.625F, 1 - headThickness);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
             break;
 
-        case 4: // '\004'
-            setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F);
+            case WEST: // '\004'
+            setBlockBounds(0.0F, 0.0F, 0.0F, headThickness, 1.0F, 1.0F);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
-            setBlockBounds(0.25F, 0.375F, 0.25F, 1.25F, 0.625F, 0.75F);
+            setBlockBounds(headThickness, 0.375F, headThickness, 1 + headThickness, 0.625F, 1 - headThickness);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
             break;
 
-        case 5: // '\005'
-            setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+            case EAST: // '\005'
+            setBlockBounds(1 - headThickness, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
-            setBlockBounds(-0.25F, 0.375F, 0.25F, 0.75F, 0.625F, 0.75F);
+            setBlockBounds(-headThickness, 0.375F, headThickness, 1 - headThickness, 0.625F, 1 - headThickness);
             super.getCollidingBoundingBoxes(world, x, y, z, aabb, aabbList);
             break;
         }
@@ -128,28 +136,28 @@ public class PistonHeadBlock extends Block
         int l = world.getBlockMetadata(x, y, z);
         switch(getDirectionFromMeta(l))
         {
-        case 0: // '\0'
-            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F);
+            case DOWN: // '\0'
+            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, headThickness, 1.0F);
             break;
 
-        case 1: // '\001'
-            setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F);
+            case UP: // '\001'
+            setBlockBounds(0.0F, 1 - headThickness, 0.0F, 1.0F, 1.0F, 1.0F);
             break;
 
-        case 2: // '\002'
-            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F);
+            case NORTH: // '\002'
+            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, headThickness);
             break;
 
-        case 3: // '\003'
-            setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F);
+            case SOUTH: // '\003'
+            setBlockBounds(0.0F, 0.0F, 1 - headThickness, 1.0F, 1.0F, 1.0F);
             break;
 
-        case 4: // '\004'
-            setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F);
+            case WEST: // '\004'
+            setBlockBounds(0.0F, 0.0F, 0.0F, headThickness, 1.0F, 1.0F);
             break;
 
-        case 5: // '\005'
-            setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+            case EAST: // '\005'
+            setBlockBounds(1 - headThickness, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
             break;
         }
     }
@@ -157,23 +165,29 @@ public class PistonHeadBlock extends Block
     @Override
 	public void onNeighborBlockChange(World world, int x, int y, int z, int blockId)
     {
-        int direction = getDirectionFromMeta(world.getBlockMetadata(x, y, z));
-        if(direction >= 6) {
+        Direction direction = getDirectionFromMeta(world.getBlockMetadata(x, y, z));
+        if(direction == Direction.NONE) {
         	return;
         }
-        int id = world.getBlockId(x - PistonDirections.xOffset[direction], y - PistonDirections.yOffset[direction], z - PistonDirections.zOffset[direction]);
-        if(id != Blocks.PISTON_BASE.id && id != Blocks.PISTON_BASE_STICKY.id)
-        {
+        Block block = world.getBlock(x - direction.getOffsetX(), y - direction.getOffsetY(), z - direction.getOffsetZ());
+        if (block instanceof PistonBaseBlock) {
+            block.onNeighborBlockChange(world, x - direction.getOffsetX(), y - direction.getOffsetY(), z - direction.getOffsetZ(), blockId);
+        } else {
             world.setBlockWithNotify(x, y, z, 0);
-        } else
-        {
-            Block.blocksList[id].onNeighborBlockChange(world, x - PistonDirections.xOffset[direction], y - PistonDirections.yOffset[direction], z - PistonDirections.zOffset[direction], blockId);
         }
     }
 
-    public static int getDirectionFromMeta(int meta)
+    public static Direction getDirectionFromMeta(int meta)
     {
-        return meta & 0b111;
+        return Direction.getDirectionById(meta & MASK_DIRECTION);
+    }
+
+    public static int getPistonType(int data) {
+        return ((data & 0xFF) & MASK_TYPE) >> 3;
+    }
+
+    public static int setPistonType(int type, int data) {
+        return ((data & ~MASK_TYPE) | (type << 3)) & 0xFF;
     }
 
     @Override
@@ -181,13 +195,13 @@ public class PistonHeadBlock extends Block
     {
         if (dropCause == EnumDropCause.PICK_BLOCK)
         {
-            if((meta & 0b1000) != 0)
-            {
-                return new ItemStack[] { new ItemStack(Blocks.PISTON_BASE_STICKY) };
-            }
-            else
-            {
-                return new ItemStack[] { new ItemStack(Blocks.PISTON_BASE) };
+            switch (getPistonType(meta)) {
+                case TYPE_NORMAL:
+                    return new ItemStack[] { new ItemStack(Blocks.PISTON_BASE) };
+                case TYPE_STICKY:
+                    return new ItemStack[] { new ItemStack(Blocks.PISTON_BASE_STICKY) };
+                case TYPE_STEEL:
+                    return new ItemStack[] { new ItemStack(Blocks.PISTON_BASE_STEEL) };
             }
         }
 
diff --git a/src/main/java/net/minecraft/core/block/piston/SteelPistonBaseBlock.java b/src/main/java/net/minecraft/core/block/piston/SteelPistonBaseBlock.java
new file mode 100644
index 000000000..ebbf01eeb
--- /dev/null
+++ b/src/main/java/net/minecraft/core/block/piston/SteelPistonBaseBlock.java
@@ -0,0 +1,74 @@
+package net.minecraft.core.block.piston;
+
+import net.minecraft.core.block.Blocks;
+import net.minecraft.core.entity.Entity;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.util.phys.AABB;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.WorldSource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SteelPistonBaseBlock extends PistonBaseBlock{
+    public static final double HEAD_THICKNESS_STEEL = 6/16d;
+
+    public SteelPistonBaseBlock(String key, String namespaceId, int id, int maxPushedBlocks) {
+        super(key, namespaceId, id, maxPushedBlocks);
+    }
+
+    @Override
+    public void setBlockBoundsBasedOnState(WorldSource world, int x, int y, int z)
+    {
+        int data = world.getBlockMetadata(x, y, z);
+        if(isPowered(data))
+        {
+            switch(getDirection(data))
+            {
+                case DOWN:
+                    setBlockBounds(0.0F, HEAD_THICKNESS_STEEL, 0.0F, 1.0F, 1.0F, 1.0F);
+                    break;
+                case UP:
+                    setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1 - HEAD_THICKNESS_STEEL, 1.0F);
+                    break;
+                case NORTH:
+                    setBlockBounds(0.0F, 0.0F, HEAD_THICKNESS_STEEL, 1.0F, 1.0F, 1.0F);
+                    break;
+                case SOUTH:
+                    setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1 - HEAD_THICKNESS_STEEL);
+                    break;
+                case WEST:
+                    setBlockBounds(HEAD_THICKNESS_STEEL, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+                    break;
+                case EAST:
+                    setBlockBounds(0.0F, 0.0F, 0.0F, 1 - HEAD_THICKNESS_STEEL, 1.0F, 1.0F);
+                    break;
+            }
+        } else
+        {
+            setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+        }
+    }
+
+    @Override
+    public void extendEvent(World world, int x, int y, int z, int data, Direction direction) {
+        List<Entity> entityList = new ArrayList<>(world.getEntitiesWithinAABBExcludingEntity(null, AABB.getTemporaryBB((double)x + direction.getOffsetX(), (double)y + direction.getOffsetY(), (double)z + direction.getOffsetZ(), (double)x + direction.getOffsetX() + 1, (double)y + direction.getOffsetY() + 1, (double)z + direction.getOffsetZ() + 1)));
+        for (Entity entity : entityList){
+            if (entity == null || entity.noPhysics) continue;
+            final double speed = 2;
+            entity.xd += speed * direction.getOffsetX();
+            entity.yd += speed * direction.getOffsetY();
+            entity.zd += speed * direction.getOffsetZ();
+            entity.fallDistance = 0;
+            entity.pushTime = 1f;
+        }
+        super.extendEvent(world, x, y, z, data, direction);
+    }
+
+    @Override
+    public void createPistonHeadAt(World world, int x, int y, int z, int data, Direction direction) {
+        world.setBlockAndMetadata(x, y, z, Blocks.PISTON_MOVING.id,  PistonHeadBlock.setPistonType(PistonHeadBlock.TYPE_STEEL, direction.getId()));
+        world.replaceBlockTileEntity(x, y, z, MovingPistonBlock.createTileEntity(Blocks.PISTON_HEAD_STEEL.id, PistonHeadBlock.setPistonType(PistonHeadBlock.TYPE_STEEL, direction.getId()), null, direction, true, false));
+    }
+
+}
diff --git a/src/main/java/net/minecraft/core/block/piston/StickyPistonBaseBlock.java b/src/main/java/net/minecraft/core/block/piston/StickyPistonBaseBlock.java
new file mode 100644
index 000000000..4235a74b1
--- /dev/null
+++ b/src/main/java/net/minecraft/core/block/piston/StickyPistonBaseBlock.java
@@ -0,0 +1,79 @@
+package net.minecraft.core.block.piston;
+
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.Blocks;
+import net.minecraft.core.block.entity.BlockEntity;
+import net.minecraft.core.block.material.Material;
+import net.minecraft.core.sound.SoundCategory;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.world.World;
+
+public class StickyPistonBaseBlock extends PistonBaseBlock {
+    public StickyPistonBaseBlock(String key, String namespaceId, int id, int maxPushedBlocks) {
+        super(key, namespaceId, id, maxPushedBlocks);
+    }
+
+    @Override
+    public void retractEvent(World world, int x, int y, int z, int data, Direction direction) {
+        BlockEntity blockEntity = world.getBlockEntity(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ());
+        if((blockEntity instanceof MovingPistonBlockEntity))
+        {
+            MovingPistonBlockEntity moving = ((MovingPistonBlockEntity) blockEntity);
+            if (!moving.isExtending()) {
+                ((MovingPistonBlockEntity)blockEntity).finalTick();
+            } else {
+                world.setBlock(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ(), 0);
+            }
+        }
+        world.setBlockAndMetadata(x, y, z, Blocks.PISTON_MOVING.id, direction.getId());
+        world.replaceBlockTileEntity(x, y, z, MovingPistonBlock.createTileEntity(id, direction.getId(), null, direction, false, true));
+        int x1 = x + direction.getOffsetX() * 2;
+        int y1 = y + direction.getOffsetY() * 2;
+        int z1 = z + direction.getOffsetZ() * 2;
+        int retractId = world.getBlockId(x1, y1, z1);
+        int retactMeta = world.getBlockMetadata(x1, y1, z1);
+        BlockEntity retractEntity = world.getBlockEntity(x1, y1, z1);
+        boolean pulledMoving = false;
+        if(retractId == Blocks.PISTON_MOVING.id)
+        {
+            BlockEntity blockEntity1 = world.getBlockEntity(x1, y1, z1);
+            if((blockEntity1 instanceof MovingPistonBlockEntity))
+            {
+                MovingPistonBlockEntity movingPistonBlock = (MovingPistonBlockEntity)blockEntity1;
+                if(movingPistonBlock.getDirection() == direction && movingPistonBlock.isExtending())
+                {
+                    movingPistonBlock.finalTick();
+                    retractId = movingPistonBlock.getMovedId();
+                    retactMeta = movingPistonBlock.getMovedData();
+                    retractEntity = movingPistonBlock.getMovedEntity();
+                    pulledMoving = true;
+                }
+            }
+        }
+        if(!pulledMoving && retractId > 0 &&
+            isPushable(retractId, world, x1, y1, z1, false) &&
+            (Block.blocksList[retractId].getPistonPushReaction(world, x1, y1, z1) == Material.PISTON_PUSHABLE || (Block.getBlock(retractId) instanceof PistonBaseBlock)))
+        {
+            if (!(retractEntity instanceof MovingPistonBlockEntity)) {
+                world.removeBlockTileEntity(x1, y1, z1);
+            }
+            world.setBlock(x1, y1, z1, 0);
+            x += direction.getOffsetX();
+            y += direction.getOffsetY();
+            z += direction.getOffsetZ();
+            world.setBlockAndMetadata(x, y, z, Blocks.PISTON_MOVING.id, retactMeta);
+            world.replaceBlockTileEntity(x, y, z, MovingPistonBlock.createTileEntity(retractId, retactMeta, retractEntity, direction, false, false));
+            world.notifyBlockChange(x1, y1, z1, 0);
+        } else
+        if(!pulledMoving)
+        {
+            world.setBlockWithNotify(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ(), 0);
+        }
+        world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double)x + 0.5D, (double)y + 0.5D, (double)z + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat() * 0.15F + 0.6F);
+    }
+    @Override
+    public void createPistonHeadAt(World world, int x, int y, int z, int data, Direction direction) {
+        world.setBlockAndMetadata(x, y, z, Blocks.PISTON_MOVING.id,  PistonHeadBlock.setPistonType(PistonHeadBlock.TYPE_STICKY, direction.getId()));
+        world.replaceBlockTileEntity(x, y, z, MovingPistonBlock.createTileEntity(Blocks.PISTON_HEAD.id, PistonHeadBlock.setPistonType(PistonHeadBlock.TYPE_STICKY, direction.getId()), null, direction, true, false));
+    }
+}
diff --git a/src/main/java/net/minecraft/core/block/tag/BlockTags.java b/src/main/java/net/minecraft/core/block/tag/BlockTags.java
index aa2f3593b..2969d81d7 100644
--- a/src/main/java/net/minecraft/core/block/tag/BlockTags.java
+++ b/src/main/java/net/minecraft/core/block/tag/BlockTags.java
@@ -167,6 +167,14 @@ public abstract class BlockTags
      * Pigs will follow the player if they are holding this block.
      */
     public static Tag<Block> PIGS_FAVOURITE_BLOCK = Tag.of("pigs_favourite_block");
+    /**
+     * Nether mobs can spawn on this block {@link net.minecraft.core.entity.monster.ZombiePigMob ZombiePigMob}}.
+     */
+    public static Tag<Block> NETHER_MOBS_SPAWN = Tag.of("nether_mobs_spawn");
+    /**
+     * Will drop block when piston extends into it
+     */
+    public static Tag<Block> PISTON_CRUSHING = Tag.of("piston_crushing");
 
     public static List<Tag<Block>> TAG_LIST;
 
diff --git a/src/main/java/net/minecraft/core/entity/Entity.java b/src/main/java/net/minecraft/core/entity/Entity.java
index f72982319..e2e7171f4 100644
--- a/src/main/java/net/minecraft/core/entity/Entity.java
+++ b/src/main/java/net/minecraft/core/entity/Entity.java
@@ -59,6 +59,7 @@ public abstract class Entity
     public float xRot;
     public float yRotO;
     public float xRotO;
+    public float pushTime;
     public final AABB bb = AABB.getPermanentBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
     public boolean onGround = false;
     public boolean horizontalCollision;
@@ -234,6 +235,10 @@ public abstract class Entity
 
     public void baseTick()
     {
+        pushTime *= 0.98f;
+        if (pushTime < 0.001f){
+            pushTime = 0;
+        }
         if(vehicle != null && vehicle.isRemoved())
         {
             vehicle = null;
diff --git a/src/main/java/net/minecraft/core/entity/Mob.java b/src/main/java/net/minecraft/core/entity/Mob.java
index 8d83f3675..3a1a5db8c 100644
--- a/src/main/java/net/minecraft/core/entity/Mob.java
+++ b/src/main/java/net/minecraft/core/entity/Mob.java
@@ -884,6 +884,9 @@ public abstract class Mob extends Entity
             {
                 yd = 0.25D;
             }
+            if (!onGround){
+                movementScale = MathHelper.lerp(movementScale, 1f, pushTime);
+            }
             yd -= 0.08D;
             yd *= 0.98D;
             xd *= movementScale;
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 f738e2264..74a05b3bf 100644
--- a/src/main/java/net/minecraft/core/entity/monster/ZombiePigMob.java
+++ b/src/main/java/net/minecraft/core/entity/monster/ZombiePigMob.java
@@ -2,6 +2,8 @@ package net.minecraft.core.entity.monster;
 
 import net.minecraft.core.WeightedRandomLootObject;
 import net.minecraft.core.achievement.Achievements;
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.Items;
@@ -65,7 +67,9 @@ public class ZombiePigMob extends ZombieMob
     	int y = MathHelper.floor(this.y);
     	int z = MathHelper.floor(this.z);
     	if(world.getBlockId(x, y, z) != 0) return false;
-    	int blockLight = world.getSavedLightValue(LightLayer.Block, x, y, z);
+        Block below = world.getBlock(x, y - 1, z);
+        if (!BlockTags.NETHER_MOBS_SPAWN.appliesTo(below)) return false;
+        int blockLight = world.getSavedLightValue(LightLayer.Block, x, y, z);
     	if(blockLight > 7) return false;
         return world.getDifficulty().canHostileMobsSpawn() && world.checkIfAABBIsClear(bb) && world.getCubes(this, bb).size() == 0 && !world.getIsAnyLiquid(bb);
     }
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 0c3bf9202..cbec30952 100644
--- a/src/main/java/net/minecraft/core/entity/player/Player.java
+++ b/src/main/java/net/minecraft/core/entity/player/Player.java
@@ -199,7 +199,7 @@ public abstract class Player extends Mob
     @Override
 	public void tick()
     {
-        if (world.dimension == Dimension.nether) {
+        if (world.dimension == Dimension.NETHER) {
             if (y >= 260) {
                 addStat(Achievements.ENTER_OLDWORLD, 1);
             } else if (y >=128) {
@@ -1367,7 +1367,7 @@ public abstract class Player extends Mob
             if(j > 0)
             {
                 addStat(StatList.distanceSwumStat, j);
-                if (dimension == Dimension.nether.id) {
+                if (dimension == Dimension.NETHER.id) {
                     addStat(Achievements.SWIM_NETHER, 1);
                 }
             }
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 ca5a643eb..01b04f7db 100644
--- a/src/main/java/net/minecraft/core/entity/projectile/FireballProjectile.java
+++ b/src/main/java/net/minecraft/core/entity/projectile/FireballProjectile.java
@@ -17,9 +17,7 @@ import net.minecraft.core.util.helper.DamageType;
 
 public class FireballProjectile extends Projectile
 {
-    public double xPower = 0;
-    public double yPower = 0;
-    public double zPower = 0;
+    public static final double FIREBALL_SPEED = 1d;
 
     public FireballProjectile(World world)
     {
@@ -34,8 +32,7 @@ public class FireballProjectile extends Projectile
         setSize(1.0F, 1.0F);
         moveTo(x, y, z, yRot, xRot);
         setPos(x, y, z);
-        xd = yd = zd = 0.0D;
-        setAccel(vX, vY, vZ);
+        setVelocity(vX, vY, vZ, FIREBALL_SPEED);
     }
     public FireballProjectile(World world, Mob owner, double vX, double vY, double vZ)
     {
@@ -44,22 +41,21 @@ public class FireballProjectile extends Projectile
         moveTo(owner.x, owner.y, owner.z, owner.yRot, owner.xRot);
         setPos(x, y, z);
         heightOffset = 0.0F;
-        xd = yd = zd = 0.0D;
-        vX += random.nextGaussian() * 1.2D;
-        vY += random.nextGaussian() * 1.2D;
-        vZ += random.nextGaussian() * 1.2D;
-        setAccel(vX, vY, vZ);
+        vX += (random.nextGaussian() - random.nextGaussian()) * 0.8D;
+        vY += (random.nextGaussian()) * 0.4D;
+        vZ += (random.nextGaussian() - random.nextGaussian()) * 0.8D;
+        setVelocity(vX, vY, vZ, FIREBALL_SPEED);
     }
-    private void setAccel(double vX, double vY, double vZ){
+    private void setVelocity(double vX, double vY, double vZ, double speed){
         double velocity = MathHelper.sqrt(vX * vX + vY * vY + vZ * vZ);
         if (velocity != 0){
-            xPower = (vX / velocity) * 0.1D;
-            yPower = (vY / velocity) * 0.1D;
-            zPower = (vZ / velocity) * 0.1D;
+            xd = (vX / velocity) * speed;
+            yd = (vY / velocity) * speed;
+            zd = (vZ / velocity) * speed;
         } else {
-            xPower = 0;
-            yPower = 0;
-            zPower = 0;
+            xd = 0;
+            yd = 0;
+            zd = 0;
         }
     }
 
@@ -100,9 +96,6 @@ public class FireballProjectile extends Projectile
     }
     public void afterTick(){
         super.afterTick();
-        xd += xPower;
-        yd += yPower;
-        zd += zPower;
         world.spawnParticle("largesmoke", x, y, z, 0.0D, 0.0D, 0.0D, 0);
     }
 
@@ -115,7 +108,7 @@ public class FireballProjectile extends Projectile
     @Override
 	public float getPickRadius()
     {
-        return 1.0F;
+        return 1f;
     }
     @Override
     public boolean hurt(Entity entity, int i, DamageType type)
@@ -129,12 +122,7 @@ public class FireballProjectile extends Projectile
             }
             if(lookAngle != null)
             {
-                xd = lookAngle.x;
-                yd = lookAngle.y;
-                zd = lookAngle.z;
-                xPower = xd * 0.1D;
-                yPower = yd * 0.1D;
-                zPower = zd * 0.1D;
+                setVelocity(lookAngle.x, lookAngle.y, lookAngle.z, FIREBALL_SPEED);
             }
             return true;
         } else
diff --git a/src/main/java/net/minecraft/core/entity/vehicle/MinecartEntity.java b/src/main/java/net/minecraft/core/entity/vehicle/MinecartEntity.java
index 01e91ef0c..728d6f1c1 100644
--- a/src/main/java/net/minecraft/core/entity/vehicle/MinecartEntity.java
+++ b/src/main/java/net/minecraft/core/entity/vehicle/MinecartEntity.java
@@ -19,7 +19,6 @@ import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.core.player.inventory.container.Container;
 import net.minecraft.core.player.inventory.InventorySorter;
 import net.minecraft.core.util.helper.DamageType;
-import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.Vec3;
 import net.minecraft.core.world.World;
@@ -31,6 +30,9 @@ public class MinecartEntity extends Entity implements Container {
     public static final int PASSENGER_CART = 0;
     public static final int CHEST_CART = 1;
     public static final int FURNACE_CART = 2;
+
+    public static final int TYPE_MASK_COLOR = 0b1111_0000;
+    public static final int TYPE_MASK_PAINTED_CHEST = 0b0000_0001;
     // 10 x 2 x 3 table of something
     private static final int[][][] EXITS = {
         {
@@ -195,7 +197,11 @@ public class MinecartEntity extends Entity implements Container {
                 spawnAtLocation(Items.MINECART.id, 1, 0.0F);
                 switch (this.type){
                     case CHEST_CART:
-                        spawnAtLocation(Blocks.CHEST_PLANKS_OAK.id, 1, 0.0F);
+                        if ((typeMeta & TYPE_MASK_PAINTED_CHEST) != 0) {
+                            spawnAtLocation(new ItemStack(Blocks.CHEST_PLANKS_OAK_PAINTED, 1, typeMeta & TYPE_MASK_COLOR), 0.0F);
+                        } else {
+                            spawnAtLocation(Blocks.CHEST_PLANKS_OAK.id, 1, 0.0F);
+                        }
                         break;
                     case FURNACE_CART:
                         spawnAtLocation(Blocks.FURNACE_STONE_IDLE.id, 1, 0.0F);
@@ -702,9 +708,9 @@ public class MinecartEntity extends Entity implements Container {
                         ChestBlockEntity chest = (ChestBlockEntity) carriedBlock.entity;
                         this.type = CHEST_CART;
                         if (carriedBlock.block == Blocks.CHEST_PLANKS_OAK_PAINTED) {
-                            this.typeMeta = carriedBlock.metadata & 0b1111_0000 | 0b0000_0001;
+                            this.typeMeta = carriedBlock.metadata & TYPE_MASK_COLOR | TYPE_MASK_PAINTED_CHEST;
                         } else {
-                            this.typeMeta = carriedBlock.metadata & 0b1111_0000;
+                            this.typeMeta = carriedBlock.metadata & TYPE_MASK_COLOR;
                         }
                         for (int i = 0; i < this.getContainerSize(); i++) {
                             this.setItem(i, chest.getItem(i));
@@ -731,12 +737,12 @@ public class MinecartEntity extends Entity implements Container {
                         }
                         blockEntity.worldObj = null;
                         Block block;
-                        if ((typeMeta & 0b0000_0001) != 0) {
+                        if ((typeMeta & TYPE_MASK_PAINTED_CHEST) != 0) {
                             block = Blocks.CHEST_PLANKS_OAK_PAINTED;
                         } else {
                             block = Blocks.CHEST_PLANKS_OAK;
                         }
-                        blockEntity.carriedBlock = blockEntity.getCarriedEntry(world, player, block, typeMeta & 0b1111_0000);
+                        blockEntity.carriedBlock = blockEntity.getCarriedEntry(world, player, block, typeMeta & TYPE_MASK_COLOR);
                         player.setHeldObject(blockEntity.carriedBlock);
                         this.type = PASSENGER_CART;
                         this.typeMeta = 0;
diff --git a/src/main/java/net/minecraft/core/item/BucketItem.java b/src/main/java/net/minecraft/core/item/BucketItem.java
index e4c1579ec..5d92fb0fa 100644
--- a/src/main/java/net/minecraft/core/item/BucketItem.java
+++ b/src/main/java/net/minecraft/core/item/BucketItem.java
@@ -87,7 +87,7 @@ public class BucketItem extends Item
 		}
 		
 		if(world.isAirBlock(x, y, z) || !world.getBlockMaterial(x, y, z).isSolid()) {
-			if(world.dimension == Dimension.nether && idToPlace == Blocks.FLUID_WATER_FLOWING.id) {
+			if(world.dimension == Dimension.NETHER && idToPlace == Blocks.FLUID_WATER_FLOWING.id) {
 				world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, z + 0.5, y + 0.5, x + 0.5, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F);
 				for (int l = 0; l < 8; l++) {
 					world.spawnParticle("largesmoke", x + Math.random(), y + Math.random(), z + Math.random(), 0.0D, 0.0D, 0.0D, 0);
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/FireballNetEntry.java b/src/main/java/net/minecraft/core/net/entity/entries/FireballNetEntry.java
index 1efec894c..e1b905560 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/FireballNetEntry.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/FireballNetEntry.java
@@ -18,17 +18,17 @@ public class FireballNetEntry implements IVehicleEntry<FireballProjectile>, ITra
 
     @Override
     public int getTrackingDistance() {
-        return 64;
+        return 128;
     }
 
     @Override
     public int getPacketDelay() {
-        return 10;
+        return 1;
     }
 
     @Override
     public boolean sendMotionUpdates() {
-        return false;
+        return true;
     }
 
     @Override
@@ -43,6 +43,6 @@ public class FireballNetEntry implements IVehicleEntry<FireballProjectile>, ITra
 
     @Override
     public AddEntityPacket getSpawnPacket(EntityTrackerEntry tracker, FireballProjectile trackedObject) {
-        return new AddEntityPacket(trackedObject, -1, -1, trackedObject.xPower, trackedObject.yPower, trackedObject.zPower);
+        return new AddEntityPacket(trackedObject, -1, -1, trackedObject.xd, trackedObject.yd, trackedObject.zd);
     }
 }
diff --git a/src/main/java/net/minecraft/core/world/Dimension.java b/src/main/java/net/minecraft/core/world/Dimension.java
index 633b815a6..5add6e428 100644
--- a/src/main/java/net/minecraft/core/world/Dimension.java
+++ b/src/main/java/net/minecraft/core/world/Dimension.java
@@ -7,6 +7,7 @@ import net.minecraft.core.world.type.WorldType;
 import net.minecraft.core.world.type.WorldTypes;
 
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -74,9 +75,9 @@ public class Dimension
 
 	private static final Map<Integer, Dimension> dimensionList = new HashMap<>();
 
-	public static Dimension overworld;
-	public static Dimension nether;
-	public static Dimension paradise;
+	public static Dimension OVERWORLD;
+	public static Dimension NETHER;
+	public static Dimension PARADISE;
 
 	public static Map<Integer, Dimension> getDimensionList()
 	{
@@ -95,12 +96,12 @@ public class Dimension
 		dimensionList.put(id, dimension);
 	}
 	public static void init(){
-		overworld = new Dimension("overworld", null, 1.0f, -1, WorldTypes.OVERWORLD_DEFAULT);
-		nether = new Dimension("nether", overworld, 0.125f, Blocks.PORTAL_NETHER.id, WorldTypes.NETHER_DEFAULT);
-		paradise = new Dimension("paradise", overworld, 8.0f, Blocks.PORTAL_PARADISE.id, WorldTypes.PARADISE_DEFAULT);
+		OVERWORLD = new Dimension("overworld", null, 1.0f, -1, WorldTypes.OVERWORLD_DEFAULT);
+		NETHER = new Dimension("nether", OVERWORLD, 0.125f, Blocks.PORTAL_NETHER.id, WorldTypes.NETHER_DEFAULT);
+		PARADISE = new Dimension("paradise", OVERWORLD, 8.0f, Blocks.PORTAL_PARADISE.id, WorldTypes.PARADISE_DEFAULT);
 
-		registerDimension(0, overworld);
-		registerDimension(1, nether);
-		registerDimension(2, paradise);
+		registerDimension(0, OVERWORLD);
+		registerDimension(1, NETHER);
+		registerDimension(2, PARADISE);
 	}
 }
diff --git a/src/main/java/net/minecraft/core/world/Explosion.java b/src/main/java/net/minecraft/core/world/Explosion.java
index d0c3c689b..60423c2fc 100644
--- a/src/main/java/net/minecraft/core/world/Explosion.java
+++ b/src/main/java/net/minecraft/core/world/Explosion.java
@@ -168,6 +168,8 @@ public class Explosion {
                 entity.xd += d6 * d14;
                 entity.yd += d8 * d14;
                 entity.zd += d10 * d14;
+
+                entity.pushTime = 1f;
             }
         }
 	}
diff --git a/src/main/java/net/minecraft/core/world/World.java b/src/main/java/net/minecraft/core/world/World.java
index d3bebcc0a..a15af5e56 100644
--- a/src/main/java/net/minecraft/core/world/World.java
+++ b/src/main/java/net/minecraft/core/world/World.java
@@ -300,7 +300,7 @@ public class World implements WorldSource {
 
     // Used for the model viewer
     public World(){
-        this.dimension = Dimension.overworld;
+        this.dimension = Dimension.OVERWORLD;
         this.saveHandler = null;
         levelData = new LevelData(0, "modelviewer");
         this.worldType = WorldTypes.DEBUG;
@@ -1806,7 +1806,6 @@ public class World implements WorldSource {
             }
         }
     }
-
     public void updateEntities()
     {
         for(int i = 0; i < weatherEffects.size(); i++)
@@ -1877,7 +1876,7 @@ public class World implements WorldSource {
                 loadedBlockEntityList.remove(i);
                 Chunk chunk = getChunkFromChunkCoords(Math.floorDiv(blockEntity.x, Chunk.CHUNK_SIZE_X), Math.floorDiv(blockEntity.z, Chunk.CHUNK_SIZE_Z));
                 if (chunk != null) {
-                    chunk.removeBlockEntity(blockEntity.x & (Chunk.CHUNK_SIZE_X - 1), blockEntity.y, blockEntity.z & (Chunk.CHUNK_SIZE_Z - 1));
+                    chunk.removeBlockEntity(blockEntity);
                 }
             }
         }
@@ -2260,23 +2259,23 @@ public class World implements WorldSource {
         }
     }
 
-    public void setBlockTileEntity(int i, int j, int k, BlockEntity blockEntity)
+    public void setBlockTileEntity(int x, int y, int z, BlockEntity blockEntity)
     {
         if(!blockEntity.isInvalid())
         {
-            Chunk chunk = getChunkFromChunkCoords(Math.floorDiv(i, Chunk.CHUNK_SIZE_X), Math.floorDiv(k, Chunk.CHUNK_SIZE_Z));
+            Chunk chunk = getChunkFromChunkCoords(Math.floorDiv(x, Chunk.CHUNK_SIZE_X), Math.floorDiv(z, Chunk.CHUNK_SIZE_Z));
             if(chunk != null)
             {
-                if (chunk.setBlockEntity(i & (Chunk.CHUNK_SIZE_X - 1), j, k & (Chunk.CHUNK_SIZE_Z - 1), blockEntity) && !loadedBlockEntityList.contains(blockEntity)) {
+                if (chunk.setBlockEntity(x & (Chunk.CHUNK_SIZE_X - 1), y, z & (Chunk.CHUNK_SIZE_Z - 1), blockEntity) && !loadedBlockEntityList.contains(blockEntity)) {
                     loadedBlockEntityList.add(blockEntity);
                 }
             }
         }
     }
 
-    public void removeBlockTileEntity(int i, int j, int k)
+    public void removeBlockTileEntity(int x, int y, int z)
     {
-        BlockEntity blockEntity = getBlockEntity(i, j, k);
+        BlockEntity blockEntity = getBlockEntity(x, y, z);
 
         if(blockEntity != null && updatingBlockEntities)
         {
@@ -2287,17 +2286,17 @@ public class World implements WorldSource {
             {
                 loadedBlockEntityList.remove(blockEntity);
             }
-            Chunk chunk = getChunkFromChunkCoords(Math.floorDiv(i, Chunk.CHUNK_SIZE_X), Math.floorDiv(k, Chunk.CHUNK_SIZE_Z));
+            Chunk chunk = getChunkFromChunkCoords(Math.floorDiv(x, Chunk.CHUNK_SIZE_X), Math.floorDiv(z, Chunk.CHUNK_SIZE_Z));
             if(chunk != null)
             {
-                chunk.removeBlockEntity(i & (Chunk.CHUNK_SIZE_X - 1), j, k & (Chunk.CHUNK_SIZE_Z - 1));
+                chunk.removeBlockEntity(blockEntity);
             }
         }
     }
 
-    public void replaceBlockTileEntity(int i, int j, int k, BlockEntity tileentity) {
-        removeBlockTileEntity(i, j, k);
-        setBlockTileEntity(i, j, k, tileentity);
+    public void replaceBlockTileEntity(int x, int y, int z, BlockEntity blockEntity) {
+        removeBlockTileEntity(x, y, z);
+        setBlockTileEntity(x, y, z, blockEntity);
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/core/world/chunk/Chunk.java b/src/main/java/net/minecraft/core/world/chunk/Chunk.java
index 1427443b7..3d86cbb7f 100644
--- a/src/main/java/net/minecraft/core/world/chunk/Chunk.java
+++ b/src/main/java/net/minecraft/core/world/chunk/Chunk.java
@@ -529,7 +529,9 @@ public class Chunk
         {
             blockEntity.validate();
             BlockEntity previous = blockEntityMap.put(chunkposition, blockEntity);
-            world.loadedBlockEntityList.remove(previous);
+            if (previous != null) {
+                previous.invalidate();
+            }
             return true;
         }
         return false;
@@ -548,6 +550,13 @@ public class Chunk
         }
     }
 
+    public void removeBlockEntity(BlockEntity blockEntity) {
+        if (isLoaded && blockEntity != null && blockEntityMap.containsValue(blockEntity)) {
+            blockEntityMap.remove(new ChunkPosition(blockEntity.x & (Chunk.CHUNK_SIZE_X - 1), blockEntity.y, blockEntity.z & (Chunk.CHUNK_SIZE_Z - 1)));
+            blockEntity.invalidate();
+        }
+    }
+
     public void onLoad()
     {
         isLoaded = true;
diff --git a/src/main/java/net/minecraft/core/world/save/SaveFile.java b/src/main/java/net/minecraft/core/world/save/SaveFile.java
index 7ca8f2768..25407b560 100644
--- a/src/main/java/net/minecraft/core/world/save/SaveFile.java
+++ b/src/main/java/net/minecraft/core/world/save/SaveFile.java
@@ -3,13 +3,14 @@ package net.minecraft.core.world.save;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.Map;
 import java.util.Objects;
 
 public class SaveFile
     implements Comparable<SaveFile>
 {
 
-    public SaveFile(@NotNull String fileName, @NotNull String displayName, @Nullable LevelData levelData, DimensionData @NotNull [] dimensionData, long lastTimePlayed, long sizeOnDisk, boolean needsConversion)
+    public SaveFile(@NotNull String fileName, @NotNull String displayName, @Nullable LevelData levelData, @NotNull Map<Integer, DimensionData> dimensionData, long lastTimePlayed, long sizeOnDisk, boolean needsConversion)
     {
         this.fileName = Objects.requireNonNull(fileName);
         this.displayName = Objects.requireNonNull(displayName);
@@ -19,7 +20,7 @@ public class SaveFile
         this.levelData = levelData;
         this.dimensionData = Objects.requireNonNull(dimensionData);
 
-        this.corrupted = levelData == null || (!needsConversion && dimensionData[0] == null);
+        this.corrupted = levelData == null || (!needsConversion && dimensionData.get(0) == null);
     }
 
     public String getFileName()
@@ -36,8 +37,8 @@ public class SaveFile
     {
     	return levelData;
     }
-    @Nullable
-    public DimensionData[] getDimensionData()
+    @NotNull
+    public Map<Integer, DimensionData> getDimensionData()
     {
         return dimensionData;
     }
@@ -87,8 +88,7 @@ public class SaveFile
     private final String displayName;
     @Nullable
     private final LevelData levelData;
-    @NotNull
-    private final DimensionData[] dimensionData;
+    private final @NotNull Map<Integer, DimensionData> dimensionData;
     private final long lastTimePlayed;
     private final long sizeOnDisk;
     private final boolean needsConversion;
diff --git a/src/main/java/net/minecraft/core/world/save/SaveFormatBase.java b/src/main/java/net/minecraft/core/world/save/SaveFormatBase.java
index bad31a653..b5039285a 100644
--- a/src/main/java/net/minecraft/core/world/save/SaveFormatBase.java
+++ b/src/main/java/net/minecraft/core/world/save/SaveFormatBase.java
@@ -11,7 +11,9 @@ import org.slf4j.Logger;
 import java.io.File;
 import java.nio.file.Files;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 public abstract class SaveFormatBase
     implements ISaveFormat
@@ -145,13 +147,12 @@ public abstract class SaveFormatBase
                 String worldName;
                 long lastTimePlayed;
                 long size;
-                DimensionData[] dimensionData;
+                Map<Integer, DimensionData> dimensionData = new HashMap<>();
                 boolean needsConversion = false;
                 if (levelData == null) {
                     worldName = I18n.getInstance().translateKey("save.data.missing.data");
                     lastTimePlayed = System.currentTimeMillis();
                     size = -1;
-                    dimensionData = new DimensionData[Dimension.getDimensionList().size()];
                 } else {
                     lastTimePlayed = levelData.getLastTimePlayed();
                     size = levelData.getSizeOnDisk();
@@ -161,10 +162,9 @@ public abstract class SaveFormatBase
                     {
                         worldName = worldDirName;
                     }
-                    dimensionData = new DimensionData[Dimension.getDimensionList().size()];
                     for (Dimension dimension : Dimension.getDimensionList().values())
                     {
-                        dimensionData[dimension.id] = getDimensionData(worldDirName, dimension.id);
+                        dimensionData.put(dimension.id, getDimensionData(worldDirName, dimension.id));
                     }
                 }
                 saveFileList.add(new SaveFile(worldDirName, worldName, levelData, dimensionData, lastTimePlayed, size, needsConversion));
diff --git a/src/main/java/net/minecraft/core/world/save/legacy/SaveFormatLegacy.java b/src/main/java/net/minecraft/core/world/save/legacy/SaveFormatLegacy.java
index 9a22fee98..7210eed68 100644
--- a/src/main/java/net/minecraft/core/world/save/legacy/SaveFormatLegacy.java
+++ b/src/main/java/net/minecraft/core/world/save/legacy/SaveFormatLegacy.java
@@ -33,7 +33,7 @@ public class SaveFormatLegacy
     {
         File worldDir = new File(savesDir, worldDirName);
 
-        if (dimension == Dimension.overworld)
+        if (dimension == Dimension.OVERWORLD)
         {
             return worldDir;
         }
diff --git a/src/main/java/net/minecraft/core/world/save/mcregion/SaveFormat19132.java b/src/main/java/net/minecraft/core/world/save/mcregion/SaveFormat19132.java
index db1675d91..1573c62da 100644
--- a/src/main/java/net/minecraft/core/world/save/mcregion/SaveFormat19132.java
+++ b/src/main/java/net/minecraft/core/world/save/mcregion/SaveFormat19132.java
@@ -38,7 +38,7 @@ public class SaveFormat19132
     {
         File worldDir = new File(savesDir, worldDirName);
 
-        if (dimension == Dimension.overworld)
+        if (dimension == Dimension.OVERWORLD)
         {
             return worldDir;
         }
diff --git a/src/main/java/net/minecraft/core/world/save/mcregion/SaveFormat19133.java b/src/main/java/net/minecraft/core/world/save/mcregion/SaveFormat19133.java
index b0268709a..9a69e2cd6 100644
--- a/src/main/java/net/minecraft/core/world/save/mcregion/SaveFormat19133.java
+++ b/src/main/java/net/minecraft/core/world/save/mcregion/SaveFormat19133.java
@@ -36,7 +36,7 @@ public class SaveFormat19133
     {
         File worldDir = new File(savesDir, worldDirName);
 
-        if (dimension == Dimension.overworld)
+        if (dimension == Dimension.OVERWORLD)
         {
             return worldDir;
         }
diff --git a/src/main/java/net/minecraft/core/world/type/WorldTypeGroups.java b/src/main/java/net/minecraft/core/world/type/WorldTypeGroups.java
index c5b57133a..3d9ccc21f 100644
--- a/src/main/java/net/minecraft/core/world/type/WorldTypeGroups.java
+++ b/src/main/java/net/minecraft/core/world/type/WorldTypeGroups.java
@@ -56,7 +56,7 @@ public class WorldTypeGroups {
         );
         GROUPS.add(
             new Group(WorldTypes.OVERWORLD_SKYBLOCK)
-                .with(Dimension.nether, WorldTypes.NETHER_SKYBLOCK)
+                .with(Dimension.NETHER, WorldTypes.NETHER_SKYBLOCK)
         );
         GROUPS.add(
             new Group(WorldTypes.EMPTY)
@@ -70,7 +70,7 @@ public class WorldTypeGroups {
         private final Map<Dimension, WorldType> worldTypes = new HashMap<>();
 
         public Group(WorldType overworldType) {
-            worldTypes.put(Dimension.overworld, overworldType);
+            worldTypes.put(Dimension.OVERWORLD, overworldType);
         }
 
         public Group with(Dimension dimension, WorldType worldType) {
diff --git a/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java b/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
index 63c4c7318..fe0078274 100644
--- a/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
+++ b/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
@@ -871,6 +871,7 @@ class WorkbenchGenerator {
 
         fence.addInput('X', Items.STICK).addInput('#', Blocks.PAPER_WALL).create("paper_wall_fence", new ItemStack(Blocks.FENCE_PAPER_WALL, 4));
         fence.addInput('X', Items.INGOT_IRON).addInput('#', Items.CHAINLINK).create("chainlink_fence", new ItemStack(Blocks.FENCE_CHAINLINK, 8));
+        fence.addInput('X', Items.INGOT_STEEL).addInput('#', Items.INGOT_STEEL_CRUDE).create("steel_fence", new ItemStack(Blocks.FENCE_STEEL, 8));
     }
 
     private static void generateFenceGates() {
@@ -1150,6 +1151,17 @@ class WorkbenchGenerator {
             .addInput('P', Blocks.PISTON_BASE)
             .create("sticky_piston", Blocks.PISTON_BASE_STICKY.getDefaultStack());
 
+        RecipeBuilder.Shaped(CORE_NAMESPACE)
+            .setShape(
+                "XXX",
+                "#I#",
+                "#R#")
+            .addInput('X', Items.INGOT_STEEL)
+            .addInput('#', Blocks.BRICK_STONE_POLISHED)
+            .addInput('I', Blocks.PISTON_BASE)
+            .addInput('R', Items.DUST_REDSTONE)
+            .create("steel_piston", Blocks.PISTON_BASE_STEEL.getDefaultStack());
+
         RecipeBuilder.Shaped(CORE_NAMESPACE)
             .setShape(
                 "X#X",
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 359137987..53c601d8c 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -67,6 +67,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 
 import static net.minecraft.core.Global.CURRENT_SAVE_VERSION;
@@ -81,7 +82,7 @@ public class MinecraftServer
     public static HashMap<String, Integer> field_6037_b = new HashMap<>();
     public NetworkListenThread networkServer;
     public PropertyManager propertyManager;
-    public WorldServer[] dimensionWorlds;
+    public Map<Integer, WorldServer> dimensionWorlds;
     public PlayerList playerList;
     private boolean serverRunning;
     public boolean serverStopped;
@@ -90,7 +91,7 @@ public class MinecraftServer
     public int percentDone;
     private final List<IUpdatePlayerListBox> playerListBoxes;
     private final List<ServerCommandEntry> commands;
-    public EntityTracker[] entityTracker;
+    public Map<Integer, EntityTracker> entityTrackerMap;
     public boolean onlineMode;
     public boolean pvpOn;
     public boolean allowFlight;
@@ -234,7 +235,7 @@ public class MinecraftServer
             }
         }
 
-        entityTracker = new EntityTracker[Dimension.getDimensionList().size()];
+        entityTrackerMap = new HashMap<>();
 
         new Registries();
         BiomeProviderOverworld.init();
@@ -302,9 +303,9 @@ public class MinecraftServer
             LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file.");
         }
         playerList = new PlayerList(this);
-        for (int q = 0; q < Dimension.getDimensionList().size(); q++)
+        for (Integer id : Dimension.getDimensionList().keySet())
         {
-            entityTracker[q] = new EntityTracker(this, q);
+            entityTrackerMap.put(id, new EntityTracker(this, id));
         }
         long time = System.nanoTime();
         String lName = propertyManager.getStringProperty("level-name", "world");
@@ -399,40 +400,43 @@ public class MinecraftServer
     private void initWorld(ISaveFormat saveFormat, String worldDirName, long l)
     {
         convertWorld(saveFormat, worldDirName);
-        dimensionWorlds = new WorldServer[Dimension.getDimensionList().size()];
+        dimensionWorlds = new HashMap<>();
         SaveHandlerServer saveHandler = new SaveHandlerServer(saveFormat, new File("."), worldDirName, true);
-        for (int i = 0; i < dimensionWorlds.length; i++)
+        for (Map.Entry<Integer, Dimension> entry : Dimension.getDimensionList().entrySet())
         {
-            if (i == 0)
+            int dimId = entry.getKey();
+            Dimension dimension = entry.getValue();
+            WorldServer worldServer;
+            if (dimId == 0)
             {
-                dimensionWorlds[i] = new WorldServer(this, saveHandler, worldDirName, i, defaultWorldType, l, spawnerConfig);
+                worldServer = new WorldServer(this, saveHandler, worldDirName, dimId, defaultWorldType, l, spawnerConfig);
             }
             else
             {
-                dimensionWorlds[i] = new WorldServerMulti(this, saveHandler, worldDirName, i, Dimension.getDimensionList().get(i).defaultWorldType, l, dimensionWorlds[0], spawnerConfig);
+                worldServer = new WorldServerMulti(this, saveHandler, worldDirName, dimId, dimension.defaultWorldType, l, dimensionWorlds.get(0), spawnerConfig);
             }
-            dimensionWorlds[i].addListener(new WorldManager(this, dimensionWorlds[i]));
-            dimensionWorlds[i].setDifficulty(difficulty, true);
-            dimensionWorlds[i].sleepPercent = sleepPercentage;
+            dimensionWorlds.put(dimId, worldServer);
+            worldServer.addListener(new WorldManager(this, dimensionWorlds.get(dimId)));
+            worldServer.setDifficulty(difficulty, true);
+            worldServer.sleepPercent = sleepPercentage;
             playerList.setPlayerManager(dimensionWorlds);
         }
 
         char c = '\304';
         long l1 = System.currentTimeMillis();
         label0:
-        for (int j = 0; j < dimensionWorlds.length; j++)
+        for (WorldServer worldServer : dimensionWorlds.values())
         {
-            LOGGER.info("Preparing start region for level " + j);
-            if (j == Dimension.nether.id && !propertyManager.getBooleanProperty("allow-nether", true))
+            LOGGER.info("Preparing start region for level {}", worldServer.dimension);
+            if (worldServer.dimension == Dimension.NETHER && !propertyManager.getBooleanProperty("allow-nether", true))
             {
                 continue;
             }
-            if (j == Dimension.paradise.id && !propertyManager.getBooleanProperty("allow-paradise", false))
+            if (worldServer.dimension == Dimension.PARADISE && !propertyManager.getBooleanProperty("allow-paradise", false))
             {
                 continue;
             }
-            WorldServer worldserver = dimensionWorlds[j];
-            ChunkCoordinates chunkcoordinates = worldserver.getSpawnPoint();
+            ChunkCoordinates chunkcoordinates = worldServer.getSpawnPoint();
             int k = -c;
             do
             {
@@ -454,8 +458,8 @@ public class MinecraftServer
                         outputPercentRemaining("Preparing spawn area", (k1 * 100) / j1);
                         l1 = l2;
                     }
-                    worldserver.chunkProviderServer.prepareChunk(chunkcoordinates.x + k >> 4, chunkcoordinates.z + i1 >> 4);
-                    while (worldserver.updatingLighting() && serverRunning) ;
+                    worldServer.chunkProviderServer.prepareChunk(chunkcoordinates.x + k >> 4, chunkcoordinates.z + i1 >> 4);
+                    while (worldServer.updatingLighting() && serverRunning) ;
                 }
 
                 k += 16;
@@ -482,11 +486,10 @@ public class MinecraftServer
     private void saveServerWorld()
     {
         LOGGER.info("Saving chunks");
-        for (int i = 0; i < dimensionWorlds.length; i++)
+        for (WorldServer worldServer : dimensionWorlds.values())
         {
-            WorldServer worldserver = dimensionWorlds[i];
-            worldserver.saveWorld(true, null, i == 0);
-            worldserver.func_30006_w();
+            worldServer.saveWorld(true, null, worldServer.dimension == Dimension.OVERWORLD);
+            worldServer.checkLock();
         }
 
     }
@@ -539,7 +542,7 @@ public class MinecraftServer
                     }
                     timeSinceLastTick += timeChange;
                     startTime = currentTime;
-                    if (dimensionWorlds[0].areEnoughPlayersFullyAsleep())
+                    if (dimensionWorlds.get(Dimension.OVERWORLD.id).areEnoughPlayersFullyAsleep())
                     {
                         doTick();
                         timeSinceLastTick = 0L;
@@ -632,31 +635,30 @@ public class MinecraftServer
         AABB.initializePool();
         Vec3.initializePool();
         deathTime++;
-        for (int i = 0; i < dimensionWorlds.length; i++)
+        for (WorldServer worldServer : dimensionWorlds.values())
         {
-            if (i == Dimension.nether.id && !propertyManager.getBooleanProperty("allow-nether", true))
+            if (worldServer.dimension == Dimension.NETHER && !propertyManager.getBooleanProperty("allow-nether", true))
             {
                 continue;
             }
-            if (i == Dimension.paradise.id && !propertyManager.getBooleanProperty("allow-paradise", false))
+            if (worldServer.dimension == Dimension.PARADISE && !propertyManager.getBooleanProperty("allow-paradise", false))
             {
                 continue;
             }
-            WorldServer worldserver = dimensionWorlds[i];
             if (deathTime % 20 == 0)
             {
-                playerList.sendPacketToAllPlayersInDimension(new SetTimePacket(worldserver.getWorldTime()), worldserver.dimension.id);
+                playerList.sendPacketToAllPlayersInDimension(new SetTimePacket(worldServer.getWorldTime()), worldServer.dimension.id);
             }
-            worldserver.tick();
-            while (worldserver.updatingLighting()) ;
-            worldserver.updateEntities();
+            worldServer.tick();
+            while (worldServer.updatingLighting()) ;
+            worldServer.updateEntities();
         }
 
         networkServer.handleNetworkListenThread();
         playerList.onTick();
-        for (int k = 0; k < entityTracker.length; k++)
+        for (EntityTracker tracker : entityTrackerMap.values())
         {
-            entityTracker[k].tick();
+            tracker.tick();
         }
 
         for (int l = 0; l < playerListBoxes.size(); l++)
@@ -750,14 +752,14 @@ public class MinecraftServer
         return "CONSOLE";
     }
 
-    public WorldServer getDimensionWorld(int dim)
+    public WorldServer getDimensionWorld(int dimId)
     {
-        return dimensionWorlds[dim];
+        return dimensionWorlds.get(dimId);
     }
 
-    public EntityTracker getEntityTracker(int i)
+    public EntityTracker getEntityTracker(int dimId)
     {
-        return entityTracker[i];
+        return entityTrackerMap.get(dimId);
     }
 
     public static boolean isServerRunning(MinecraftServer minecraftserver)
diff --git a/src/main/java/net/minecraft/server/entity/player/ServerPlayer.java b/src/main/java/net/minecraft/server/entity/player/ServerPlayer.java
index 095e6dcf5..c05fb0ac7 100644
--- a/src/main/java/net/minecraft/server/entity/player/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/entity/player/ServerPlayer.java
@@ -304,7 +304,7 @@ public class ServerPlayer extends Player implements ContainerListener {
             int targetDim = ((PortalBlock) Block.blocksList[portalID]).targetDimension;
             boolean netherAllowed = mcServer.propertyManager.getBooleanProperty("allow-nether", true);
             boolean paradiseAllowed = mcServer.propertyManager.getBooleanProperty("allow-paradise", false);
-            if ((netherAllowed && targetDim == Dimension.nether.id) || (paradiseAllowed && targetDim == Dimension.paradise.id) || (targetDim != Dimension.nether.id && targetDim != Dimension.paradise.id))
+            if ((netherAllowed && targetDim == Dimension.NETHER.id) || (paradiseAllowed && targetDim == Dimension.PARADISE.id) || (targetDim != Dimension.NETHER.id && targetDim != Dimension.PARADISE.id))
             {
                 if (craftingInventory != inventorySlots)
                 {
diff --git a/src/main/java/net/minecraft/server/net/PlayerList.java b/src/main/java/net/minecraft/server/net/PlayerList.java
index 9db306f4b..237c9fd96 100644
--- a/src/main/java/net/minecraft/server/net/PlayerList.java
+++ b/src/main/java/net/minecraft/server/net/PlayerList.java
@@ -32,7 +32,7 @@ public class PlayerList
     public static Logger logger = LogUtils.getLogger();
     public List<ServerPlayer> playerEntities;
     private final MinecraftServer server;
-    private final PlayerManager[] playerManagers;
+    private final Map<Integer, PlayerManager> playerManagers;
     private final Set<UUID> bans;
     private final Set<String> ipBans;
     private final Set<UUID> ops;
@@ -53,16 +53,16 @@ public class PlayerList
         ipBans = new HashSet<>();
         ops = new HashSet<>();
         whitelist = new HashSet<>();
-        playerManagers = new PlayerManager[Dimension.getDimensionList().size()];
+        playerManagers = new HashMap<>();
         this.server = server;
         bansFile = server.getFile("banned-players.txt");
         ipBansFile = server.getFile("banned-ips.txt");
         opsFile = server.getFile("ops.txt");
         whitelistFile = server.getFile("white-list.txt");
         int viewDistance = server.propertyManager.getIntProperty("view-distance", 10);
-        for (int dim = 0; dim < Dimension.getDimensionList().size(); dim++)
+        for (Integer dim : Dimension.getDimensionList().keySet())
         {
-            playerManagers[dim] = new PlayerManager(server, dim, viewDistance);
+            playerManagers.put(dim, new PlayerManager(server, dim, viewDistance));
         }
         whitelistEnforced = server.propertyManager.getBooleanProperty("white-list", false);
         loadBannedPlayers();
@@ -102,14 +102,14 @@ public class PlayerList
         }
     }
 
-    public void setPlayerManager(WorldServer[] aworldserver)
+    public void setPlayerManager(Map<Integer, WorldServer> worldServerMap)
     {
-        playerIo = aworldserver[0].getSaveHandler().getPlayerFileData();
+        playerIo = worldServerMap.get(0).getSaveHandler().getPlayerFileData();
     }
 
     public void syncPlayerDimension(ServerPlayer player)
     {
-        for (PlayerManager playerManager : playerManagers) {
+        for (PlayerManager playerManager : playerManagers.values()) {
             playerManager.removePlayer(player);
         }
         getPlayerManager(player.dimension).addPlayer(player);
@@ -119,12 +119,12 @@ public class PlayerList
 
     public int getMaxTrackingDistance()
     {
-        return playerManagers[0].getMaxTrackingDistance();
+        return playerManagers.get(0).getMaxTrackingDistance();
     }
 
     public PlayerManager getPlayerManager(int dim)
     {
-        return playerManagers[dim];
+        return playerManagers.get(dim);
     }
 
     public void load(ServerPlayer player)
@@ -302,7 +302,7 @@ public class PlayerList
 
     public void onTick()
     {
-        for (PlayerManager playerManager : playerManagers) {
+        for (PlayerManager playerManager : playerManagers.values()) {
             playerManager.tick();
         }
     }
diff --git a/src/main/java/net/minecraft/server/net/command/commands/DifficultyCommand.java b/src/main/java/net/minecraft/server/net/command/commands/DifficultyCommand.java
index 14de55a97..f6ef35440 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/DifficultyCommand.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/DifficultyCommand.java
@@ -68,7 +68,7 @@ public class DifficultyCommand {
 
         MinecraftServer server = ((IServerCommandSource)source).getServer();
 
-        for (World world : server.dimensionWorlds) {
+        for (World world : server.dimensionWorlds.values()) {
             world.setDifficulty(difficulty, true);
         }
         server.difficulty = difficulty;
diff --git a/src/main/java/net/minecraft/server/net/command/commands/StopCommand.java b/src/main/java/net/minecraft/server/net/command/commands/StopCommand.java
index fbfc0e334..60511eeca 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/StopCommand.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/StopCommand.java
@@ -3,6 +3,7 @@ package net.minecraft.server.net.command.commands;
 import com.mojang.brigadier.Command;
 import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import net.minecraft.core.world.World;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.server.net.command.IServerCommandSource;
@@ -22,8 +23,8 @@ public class StopCommand {
                     if (server.playerList != null) {
                         server.playerList.savePlayerStates();
                     }
-                    for (int i = 0; i < server.dimensionWorlds.length; ++i) {
-                        server.dimensionWorlds[i].saveWorld(true, null, true);
+                    for (World world : server.dimensionWorlds.values()) {
+                        world.saveWorld(true, null, true);
                     }
                     server.initiateShutdown();
                     return Command.SINGLE_SUCCESS;
diff --git a/src/main/java/net/minecraft/server/world/WorldServer.java b/src/main/java/net/minecraft/server/world/WorldServer.java
index f361f09e7..4a9ae8e22 100644
--- a/src/main/java/net/minecraft/server/world/WorldServer.java
+++ b/src/main/java/net/minecraft/server/world/WorldServer.java
@@ -231,7 +231,7 @@ public class WorldServer extends World
         mcServer.playerList.sendPacketToPlayersAroundPoint(x, y, z, 64D, dimension.id, new BlockEventPacket(x, y, z, index, data));
     }
 
-    public void func_30006_w()
+    public void checkLock()
     {
         saveHandler.checkSessionLock();
     }
diff --git a/src/main/resources/assets/minecraft/textures/block/brick_netherrack.png b/src/main/resources/assets/minecraft/textures/block/brick_netherrack.png
index ea0703178..0846f96d2 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/brick_netherrack.png and b/src/main/resources/assets/minecraft/textures/block/brick_netherrack.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/carved_netherrack.png b/src/main/resources/assets/minecraft/textures/block/carved_netherrack.png
index e2a691e8d..cafe7dbac 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/carved_netherrack.png and b/src/main/resources/assets/minecraft/textures/block/carved_netherrack.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/fence_steel_center.png b/src/main/resources/assets/minecraft/textures/block/fence_steel_center.png
new file mode 100644
index 000000000..024ebb64f
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/fence_steel_center.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/fence_steel_column.png b/src/main/resources/assets/minecraft/textures/block/fence_steel_column.png
new file mode 100644
index 000000000..464f05a61
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/fence_steel_column.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/fence_steel_top.png b/src/main/resources/assets/minecraft/textures/block/fence_steel_top.png
new file mode 100644
index 000000000..06adbd682
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/fence_steel_top.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/netherrack.png b/src/main/resources/assets/minecraft/textures/block/netherrack.png
index 824140246..6c5467a1e 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/netherrack.png and b/src/main/resources/assets/minecraft/textures/block/netherrack.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/piston_bottom_steel.png b/src/main/resources/assets/minecraft/textures/block/piston_bottom_steel.png
new file mode 100644
index 000000000..43591381b
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/piston_bottom_steel.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/piston_face_steel.png b/src/main/resources/assets/minecraft/textures/block/piston_face_steel.png
new file mode 100644
index 000000000..25e28da79
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/piston_face_steel.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/piston_side_steel.png b/src/main/resources/assets/minecraft/textures/block/piston_side_steel.png
new file mode 100644
index 000000000..8e35742f8
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/piston_side_steel.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/piston_top_steel.png b/src/main/resources/assets/minecraft/textures/block/piston_top_steel.png
new file mode 100644
index 000000000..1115cffe3
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/piston_top_steel.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/polished_netherrack_side.png b/src/main/resources/assets/minecraft/textures/block/polished_netherrack_side.png
index 71f15d139..b57b2fbd4 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/polished_netherrack_side.png and b/src/main/resources/assets/minecraft/textures/block/polished_netherrack_side.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/polished_netherrack_top.png b/src/main/resources/assets/minecraft/textures/block/polished_netherrack_top.png
index 8b2278e50..9a8d7e651 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/polished_netherrack_top.png and b/src/main/resources/assets/minecraft/textures/block/polished_netherrack_top.png differ
diff --git a/src/main/resources/assets/minecraft/textures/block/soulschist.png b/src/main/resources/assets/minecraft/textures/block/soulschist.png
index a6f46741f..abe8f1d98 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/soulschist.png and b/src/main/resources/assets/minecraft/textures/block/soulschist.png differ
