#include "BlockType.h"
#include "ItemType.h"
#include "StaticRegistry.h"
// block types
#include "BasicBlocks.h"
#include "Chest.h"
#include "Grass.h"
#include "GrowingPlant.h"
#include "NoBlock.h"
#include "TreeSeblingBlock.h"
// fluid blocks
#include "FluidBlock.h"
// dimensions
#include "OverworldDimension.h"
// entities
#include "ItemEntity.h"
#include "Player.h"
// item skills
#include "Axe.h"
#include "Hoe.h"
#include "Shovel.h"
#include "BasicItems.h"
#include "PlayerHand.h"
// world updates
#include "AddEntityUpdate.h"
#include "EntityRemovedUpdate.h"
// Multiblocks
#include "Game.h"
#include "LightSources.h"
#include "MultiblockTree.h"

using namespace Framework;

void initializeBlockTypes()
{
    new NoBlockBlockType(BlockTypeEnum::NO_BLOCK, &NoBlock::INSTANCE, "");
    new NoBlockBlockType(BlockTypeEnum::AIR, &AirBlock::INSTANCE, "Air");

    (new BasicBlockType(BlockTypeEnum::DIRT,
         ItemTypeEnum::DIRT,
         ModelInfo("cube",
             {"blocks.ltdb/dirt.png",
                 "blocks.ltdb/dirt.png",
                 "blocks.ltdb/dirt.png",
                 "blocks.ltdb/dirt.png",
                 "blocks.ltdb/lawn.png",
                 "blocks.ltdb/dirt.png"}),
         "Dirt",
         0xFF3C7C29))
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::STONE,
         ItemTypeEnum::STONE,
         ModelInfo("cube", "blocks.ltdb/stone.png", 6),
         "Stone",
         0xFF8E8E8D))
        ->setHardness(2.f)
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::SAND,
         ItemTypeEnum::SAND,
         ModelInfo("cube", "blocks.ltdb/sand.png", 6),
         "Sand",
         0xFFAE8558))
        ->setHardness(0.5f)
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::WOOD_OAK,
         ItemTypeEnum::WOOD_OAK,
         ModelInfo("cube", "blocks.ltdb/oak.png", 6),
         "Oak Wood",
         0xFF7F7A70))
        ->setHardness(1.5f)
        ->initializeDefault();
    (new BasicBlockType(
         BlockTypeEnum::LEAVES_WOOD_OAK,
         ItemTypeEnum::LEAVES_WOOD_OAK,
         ModelInfo("cube", "blocks.ltdb/leaves.png", 6),
         [](Vec3<int> pos, int dimensionId) {
             AdditionalItemSpawningBlock* block
                 = new AdditionalItemSpawningBlock(
                     BlockTypeEnum::LEAVES_WOOD_OAK, 0, pos, dimensionId);
             block->addSpawn({1, 1, 0.015, ItemTypeEnum::SEBLING_WOOD_OAK});
             return (Block*)block;
         },
         "Oak Wood Leaves",
         0xFF6A7C37))
        ->setHardness(0.1f)
        ->initializeDefault();

    (new BasicBlockType(BlockTypeEnum::GRAVEL,
         ItemTypeEnum::GRAVEL,
         ModelInfo("cube", "blocks.ltdb/gravel.png", 6),
         "Gravel",
         0xFF928D8C))
        ->setHardness(0.75f)
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::STONE_GRANITE,
         ItemTypeEnum::STONE_GRANITE,
         ModelInfo("cube", "blocks.ltdb/granite.png", 6),
         "Granite Stone",
         0xFF3B3A3E))
        ->setHardness(3.f)
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::STONE_COBBLE,
         ItemTypeEnum::STONE_COBBLE,
         ModelInfo("cube", "blocks.ltdb/cobble.png", 6),
         "Cobble Stone",
         0xFF7E7875))
        ->setHardness(1.f)
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::WOOD_BIRCH,
         ItemTypeEnum::WOOD_BIRCH,
         ModelInfo("cube", "blocks.ltdb/birch.png", 6),
         "Birch Wood",
         0xFF99999D))
        ->setHardness(1.5f)
        ->initializeDefault();
    (new BasicBlockType(
         BlockTypeEnum::LEAVES_WOOD_BIRCH,
         ItemTypeEnum::LEAVES_WOOD_BIRCH,
         ModelInfo("cube", "blocks.ltdb/leaves.png", 6),
         [](Vec3<int> pos, int dimensionId) {
             AdditionalItemSpawningBlock* block
                 = new AdditionalItemSpawningBlock(
                     BlockTypeEnum::LEAVES_WOOD_BIRCH, 0, pos, dimensionId);
             block->addSpawn({1, 1, 0.03, ItemTypeEnum::SEBLING_WOOD_BIRCH});
             return (Block*)block;
         },
         "Birch Wood Leaves",
         0xFF6A7C37))
        ->setHardness(0.1f)
        ->initializeDefault();

    (new BasicBlockType(BlockTypeEnum::WOOD_BEECH,
         ItemTypeEnum::WOOD_BEECH,
         ModelInfo("cube", "blocks.ltdb/beech.png", 6),
         "Beech Wood",
         0xFF778172))
        ->setHardness(1.5f)
        ->initializeDefault();
    (new BasicBlockType(
         BlockTypeEnum::LEAVES_WOOD_BEECH,
         ItemTypeEnum::LEAVES_WOOD_BEECH,
         ModelInfo("cube", "blocks.ltdb/leaves.png", 6),
         [](Vec3<int> pos, int dimensionId) {
             AdditionalItemSpawningBlock* block
                 = new AdditionalItemSpawningBlock(
                     BlockTypeEnum::LEAVES_WOOD_BEECH, 0, pos, dimensionId);
             block->addSpawn({1, 1, 0.02, ItemTypeEnum::SEBLING_WOOD_BEECH});
             return (Block*)block;
         },
         "Beech Wood Leaves",
         0xFF6A7C37))
        ->setHardness(0.1f)
        ->initializeDefault();

    (new BasicBlockType(BlockTypeEnum::STONE_BASALT,
         ItemTypeEnum::STONE_BASALT,
         ModelInfo("cube", "blocks.ltdb/basalt.png", 6),
         "Basalt Stone",
         0xFF595552))
        ->setHardness(2.f)
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::WOOD_PINE,
         ItemTypeEnum::WOOD_PINE,
         ModelInfo("cube", "blocks.ltdb/pine.png", 6),
         "Pine Wood",
         0xFF786C72))
        ->setHardness(1.4f)
        ->initializeDefault();
    (new BasicBlockType(
         BlockTypeEnum::LEAVES_WOOD_PINE,
         ItemTypeEnum::LEAVES_WOOD_PINE,
         ModelInfo("cube", "blocks.ltdb/leaves.png", 6),
         [](Vec3<int> pos, int dimensionId) {
             AdditionalItemSpawningBlock* block
                 = new AdditionalItemSpawningBlock(
                     BlockTypeEnum::LEAVES_WOOD_PINE, 0, pos, dimensionId);
             block->addSpawn({1, 1, 0.025, ItemTypeEnum::SEBLING_WOOD_PINE});
             return (Block*)block;
         },
         "Pine Wood Leaves",
         0xFF6A7C37))
        ->setHardness(0.1f)
        ->initializeDefault();

    (new BasicLightSourceBlockType(BlockTypeEnum::TORCH,
         ItemTypeEnum::TORCH,
         ModelInfo("blocks.m3/torch", "blocks.ltdb/torch.png", 6),
         "Torch"))
        ->setHardness(0.f)
        ->setColor(0x00F69A54)
        ->initializeDefault();

    (new TreeSeblingBlockType(BlockTypeEnum::SEBLING_WOOD_OAK,
         ItemTypeEnum::SEBLING_WOOD_OAK,
         ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1),
         BlockTypeEnum::WOOD_OAK,
         BlockTypeEnum::LEAVES_WOOD_OAK,
         "Oak Wood Sebling",
         0xFD6A7B3A))
        ->setHardness(0.1f)
        ->initializeDefault();
    (new TreeSeblingBlockType(BlockTypeEnum::SEBLING_WOOD_BIRCH,
         ItemTypeEnum::SEBLING_WOOD_BIRCH,
         ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1),
         BlockTypeEnum::WOOD_BIRCH,
         BlockTypeEnum::LEAVES_WOOD_BIRCH,
         "Birch Wood Sebling",
         0xFD6A7B3A))
        ->setHardness(0.1f)
        ->initializeDefault();
    (new TreeSeblingBlockType(BlockTypeEnum::SEBLING_WOOD_BEECH,
         ItemTypeEnum::SEBLING_WOOD_BEECH,
         ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1),
         BlockTypeEnum::WOOD_BEECH,
         BlockTypeEnum::LEAVES_WOOD_BEECH,
         "Beech Wood Sebling",
         0xFD6A7B3A))
        ->setHardness(0.1f)
        ->initializeDefault();
    (new TreeSeblingBlockType(BlockTypeEnum::SEBLING_WOOD_PINE,
         ItemTypeEnum::SEBLING_WOOD_PINE,
         ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1),
         BlockTypeEnum::WOOD_PINE,
         BlockTypeEnum::LEAVES_WOOD_PINE,
         "Pine Wood Sebling",
         0xFD6A7B3A))
        ->setHardness(0.1f)
        ->initializeDefault();
    (new GrassBlockType(BlockTypeEnum::GRASS,
         ItemTypeEnum::GRASS,
         ModelInfo("grass", "blocks.ltdb/grass.png", 1),
         "Grass",
         0x5076C011))
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::FARMLAND,
         ItemTypeEnum::DIRT,
         ModelInfo("cube",
             {"blocks.ltdb/dirt.png",
                 "blocks.ltdb/dirt.png",
                 "blocks.ltdb/dirt.png",
                 "blocks.ltdb/dirt.png",
                 "blocks.ltdb/farmland.png",
                 "blocks.ltdb/dirt.png"}),
         "Farmland",
         0xFF5E3819))
        ->setTransparent(1)
        ->setHardness(0.1f)
        ->initializeDefault();
    (new GrowingPlantBlockType(BlockTypeEnum::WHEAT_SEED,
         ModelInfo("grass", "plants.ltdb/wheatseeds.png", 1).setTransparent(),
         "WheatSeeds",
         BlockTypeEnum::WHEAT,
         "Growing wheat",
         18000,
         0x5076C011))
        ->addGrowthState(0.2f,
            ModelInfo("grass", "plants.ltdb/wheatseedsa.png", 1)
                .setTransparent())
        ->addGrowthState(0.4f,
            ModelInfo("grass", "plants.ltdb/wheatseedsb.png", 1)
                .setTransparent())
        ->addGrowthState(0.6f,
            ModelInfo("grass", "plants.ltdb/wheatseedsc.png", 1)
                .setTransparent())
        ->addGrowthState(0.8f,
            ModelInfo("grass", "plants.ltdb/wheatseedsd.png", 1)
                .setTransparent())
        ->initializeDefault();
    (new BasicBlockType(
         BlockTypeEnum::WHEAT,
         ItemTypeEnum::WHEAT,
         ModelInfo("grass", "plants.ltdb/wheat.png", 1),
         [](Vec3<int> pos, int dimensionId) {
             AdditionalItemSpawningBlock* block
                 = new AdditionalItemSpawningBlock(
                     BlockTypeEnum::WHEAT, 0, pos, dimensionId);
             block->addSpawn({0, 4, 1.0, ItemTypeEnum::WHEAT});
             return (Block*)block;
         },
         "Wheat",
         0x90A8C011))
        ->initializeDefault();
    (new FluidBlockType(BlockTypeEnum::WATER,
         ModelInfo("fluid", "fluids.ltdb/water.png", 6),
         "Water",
         0xFF2323BF, Vec3<float>(0.8f, 0.8f, 0.95f)))
        ->initializeDefault();
    (new BasicBlockType(BlockTypeEnum::CRAFTING_TABLE,
         ItemTypeEnum::CRAFTING_TABLE,
         ModelInfo("cube",
             {"blocks.ltdb/woodplanks.png",
                 "blocks.ltdb/woodplanks.png",
                 "blocks.ltdb/woodplanks.png",
                 "blocks.ltdb/woodplanks.png",
                 "blocks.ltdb/craftingtable.p",
                 "blocks.ltdb/woodplanks.png"}),
         "Crafting Table",
         0xFFC4A783))
        ->initializeDefault(); // TODO: implement crafting table block type
    (new BasicBlockType(
         BlockTypeEnum::CHEST,
         ItemTypeEnum::CHEST,
         ModelInfo("blocks.m3/chest",
             {"blocks.ltdb/chest.png", "blocks.ltdb/chestcover.png"}),
         [](Framework::Vec3<int> pos, int dimensionId) {
             return new Chest(BlockTypeEnum::CHEST, 0, pos, dimensionId);
         },
         "Chest",
         0xFFE2C292,
         1))
        ->initializeDefault();
}

void initializeItemTypes()
{
    (new BasicBlockItemType(ItemTypeEnum::DIRT,
        "Dirt",
        0,
        0,
        ModelInfo("itemCube", "blocks.ltdb/dirt.png", 6),
        BlockTypeEnum::DIRT));
    (new BasicBlockItemType(ItemTypeEnum::STONE,
         "Stone",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/stone.png", 6),
         BlockTypeEnum::STONE))
        ->setHardness(2.f);
    (new BasicBlockItemType(ItemTypeEnum::SAND,
         "Sand",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/sand.png", 6),
         BlockTypeEnum::SAND))
        ->setHardness(0.5f);
    (new BasicBlockItemType(ItemTypeEnum::WOOD_OAK,
         "Oak",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/oak.png", 6),
         BlockTypeEnum::WOOD_OAK))
        ->setHardness(1.5f);
    (new BasicBlockItemType(ItemTypeEnum::LEAVES_WOOD_OAK,
         "Oak Leaves",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6),
         BlockTypeEnum::LEAVES_WOOD_OAK))
        ->setHardness(0.1f);
    (new BasicBlockItemType(ItemTypeEnum::SEBLING_WOOD_OAK,
         "Oak Sebling",
         0,
         0,
         ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1),
         BlockTypeEnum::SEBLING_WOOD_OAK))
        ->setHardness(0.1f);
    (new BasicBlockItemType(ItemTypeEnum::GRAVEL,
         "Gravel",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/gravel.png", 6),
         BlockTypeEnum::GRAVEL))
        ->setHardness(0.75f);
    (new BasicBlockItemType(ItemTypeEnum::STONE_GRANITE,
         "Granite",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/granite.png", 6),
         BlockTypeEnum::STONE_GRANITE))
        ->setHardness(3.f);
    (new BasicBlockItemType(ItemTypeEnum::STONE_COBBLE,
         "Cobble",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/cobble.png", 6),
         BlockTypeEnum::STONE_COBBLE))
        ->setHardness(1.f);
    (new BasicBlockItemType(ItemTypeEnum::WOOD_BIRCH,
         "Birch",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/birch.png", 6),
         BlockTypeEnum::WOOD_BIRCH))
        ->setHardness(1.5f);
    (new BasicBlockItemType(ItemTypeEnum::LEAVES_WOOD_BIRCH,
         "Birch Leaves",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6),
         BlockTypeEnum::LEAVES_WOOD_BIRCH))
        ->setHardness(0.1f);
    (new BasicBlockItemType(ItemTypeEnum::SEBLING_WOOD_BIRCH,
         "Birch Sebling",
         0,
         0,
         ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1),
         BlockTypeEnum::SEBLING_WOOD_BIRCH))
        ->setHardness(0.1f);
    (new BasicBlockItemType(ItemTypeEnum::WOOD_BEECH,
         "Beech",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/beech.png", 6),
         BlockTypeEnum::WOOD_BEECH))
        ->setHardness(1.5f);
    (new BasicBlockItemType(ItemTypeEnum::LEAVES_WOOD_BEECH,
         "Beech Leaves",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6),
         BlockTypeEnum::LEAVES_WOOD_BEECH))
        ->setHardness(0.1f);
    (new BasicBlockItemType(ItemTypeEnum::SEBLING_WOOD_BEECH,
         "Beech Sebling",
         0,
         0,
         ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1),
         BlockTypeEnum::SEBLING_WOOD_BEECH))
        ->setHardness(0.1f);
    (new BasicBlockItemType(ItemTypeEnum::STONE_BASALT,
         "Basalt",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/basalt.png", 6),
         BlockTypeEnum::STONE_BASALT))
        ->setHardness(2.f);
    (new BasicBlockItemType(ItemTypeEnum::WOOD_PINE,
         "Pine",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/pine.png", 6),
         BlockTypeEnum::WOOD_PINE))
        ->setHardness(1.4f);
    (new BasicBlockItemType(ItemTypeEnum::LEAVES_WOOD_PINE,
         "Pine Leaves",
         0,
         0,
         ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6),
         BlockTypeEnum::LEAVES_WOOD_PINE))
        ->setHardness(0.1f);
    (new BasicBlockItemType(ItemTypeEnum::SEBLING_WOOD_PINE,
         "Pine Sebling",
         0,
         0,
         ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1),
         BlockTypeEnum::SEBLING_WOOD_PINE))
        ->setHardness(0.1f);

    (new LightSourceItemType(ItemTypeEnum::TORCH,
         "Torch",
         ModelInfo("items.m3/stick", "blocks.ltdb/torch.png", 6),
         BlockTypeEnum::TORCH))
        ->setColor(0x00F69A54);

    new PlayerHandItemType();

    (new NoBlockItemType(ItemTypeEnum::WOOD_STICK,
        "WoodenStick",
        0,
        0,
        ModelInfo("items.m3/stick", "items.ltdb/stick.png", 1),
        []() {
            return ItemType::createBasicItem(ItemTypeEnum::WOOD_STICK,
                "Wooden Stick",
                1.f,
                1.f,
                10.f,
                10.f,
                0,
                0,
                0,
                1,
                0,
                50);
        }));
    (new NoBlockItemType(ItemTypeEnum::RESIN,
        "Resin",
        0,
        0,
        ModelInfo("itemCube", "items.ltdb/resin.png", 6),
        []() {
            return ItemType::createBasicItem(ItemTypeEnum::RESIN,
                "Resin",
                1.f,
                1.f,
                10.f,
                10.f,
                0,
                0,
                0,
                1,
                0,
                50);
        }));
    new AxeToolItemType();
    (new NoBlockItemType(ItemTypeEnum::AXE_BROKEN,
        "Broken Axe",
        0,
        0,
        ModelInfo("tools.m3/axe", "tools.ltdb/stoneaxe.png", 6),
        []() {
            return ItemType::createBasicItem(ItemTypeEnum::AXE_BROKEN,
                "Broken Axe",
                100.f,
                100.f,
                100.f,
                100.f,
                0,
                0,
                0,
                1,
                0,
                10);
        }));
    new HoeToolItemType();
    new NoBlockItemType(ItemTypeEnum::BROKEN_HOE,
        "BrokenHoe",
        0,
        0,
        ModelInfo("tools.m3/hoe", "tools.ltdb/stonehoe.png", 1),
        []() {
            return ItemType::createBasicItem(ItemTypeEnum::BROKEN_HOE,
                "Broken Hoe",
                100.f,
                100.f,
                100.f,
                100.f,
                0,
                0,
                0,
                1,
                0,
                10);
        });

    (new NoBlockItemType(ItemTypeEnum::FLINT,
        "Flint",
        0,
        0,
        ModelInfo("items.m3/flint", "items.ltdb/flint.png", 1),
        []() {
            return ItemType::createBasicItem(ItemTypeEnum::FLINT,
                "Flint",
                1.f,
                1.f,
                10.f,
                10.f,
                0,
                0,
                0,
                1,
                0,
                50);
        }));

    (new BasicBlockItemType(ItemTypeEnum::WHEAT_SEED,
         "Wheat Seeds",
         0,
         0,
         ModelInfo("grass", "plants.ltdb/wheatseeds.png", 1),
         BlockTypeEnum::WHEAT_SEED))
        ->setHardness(0.1f)
        ->setPlacableProof(
            [](const Item* self,
                int dimensionId,
                Framework::Vec3<int> worldPos) {
                if (worldPos.z > 0)
                {
                    auto below = Game::INSTANCE->zBlockAt(
                        worldPos + getDirection(Direction::BOTTOM),
                        dimensionId);
                    return (below.isA()
                               && below.getA()->zBlockType()->getId()
                                      == BlockTypeEnum::FARMLAND)
                        || (below.isB()
                            && below.getB() == BlockTypeEnum::FARMLAND);
                }
                return (bool)0;
            },
            1);
    (new NoBlockItemType(ItemTypeEnum::WHEAT,
        "Wheat",
        0,
        0,
        ModelInfo("grass", "plants.ltdb/wheat.png", 1),
        []() {
            Item* item = ItemType::createBasicItem(ItemTypeEnum::WHEAT,
                "Wheat",
                1.f,
                1.f,
                10.f,
                10.f,
                1,
                0,
                0,
                1,
                0,
                50);
            item->setFoodEffect([](Entity* zEntity) {
                zEntity->setHunger(zEntity->getHunger() + 0.5f);
                zEntity->setThirst(
                    zEntity->getThirst() + 1.f); // TODO: remove thirst addition
                                                 // when drinkable water exists
            });
            return item;
        }));

    (new BasicBlockItemType(ItemTypeEnum::CRAFTING_TABLE,
        "Crafting Table",
        0,
        0,
        ModelInfo("itemCube",
            {"blocks.ltdb/woodplanks.png",
                "blocks.ltdb/woodplanks.png",
                "blocks.ltdb/woodplanks.png",
                "blocks.ltdb/woodplanks.png",
                "blocks.ltdb/craftingtable.p",
                "blocks.ltdb/woodplanks.png"}),
        BlockTypeEnum::CRAFTING_TABLE)); // TODO: implement crafting table item
                                         // type

    (new BasicBlockItemType(ItemTypeEnum::CHEST,
        "Chest",
        0,
        0,
        ModelInfo("blocks.m3/chest",
            {"blocks.ltdb/chest.png", "blocks.ltdb/chestcover.png"}),
        BlockTypeEnum::CHEST));

    new ShovelToolItemType();
    (new NoBlockItemType(ItemTypeEnum::SHOVEL_BROKEN,
        "Broken Shovel",
        0,
        0,
        ModelInfo("tools.m3/shovel", "tools.ltdb/stonehoe.png", 6),
        []() {
            return ItemType::createBasicItem(ItemTypeEnum::SHOVEL_BROKEN,
                "Broken Shovel",
                100.f,
                100.f,
                100.f,
                100.f,
                0,
                0,
                0,
                1,
                0,
                10);
        }));
}

void initializeEntityTypes()
{
    new PlayerEntityType();
    new ItemEntityType();
}

void initializeDimensions()
{
    //new OverworldDimension();
}

void initializeMultiblockTypes()
{
    new MultiblockTreeStructureType();
}