Browse Source

improvd type system to reduce amount of needed souce code

Kolja Strohm 1 year ago
parent
commit
5b4c4f2119
55 changed files with 3875 additions and 3951 deletions
  1. 2 7
      FactoryCraft/AddEntityUpdate.cpp
  2. 2 10
      FactoryCraft/AddEntityUpdate.h
  3. 78 426
      FactoryCraft/BasicBlock.cpp
  4. 8 400
      FactoryCraft/BasicBlocks.h
  5. 11 14
      FactoryCraft/BasicItems.cpp
  6. 11 21
      FactoryCraft/BasicItems.h
  7. 243 206
      FactoryCraft/Block.cpp
  8. 123 97
      FactoryCraft/Block.h
  9. 6 0
      FactoryCraft/BlockType.cpp
  10. 68 27
      FactoryCraft/BlockType.h
  11. 10 7
      FactoryCraft/Chunk.cpp
  12. 676 628
      FactoryCraft/Dimension.cpp
  13. 2 2
      FactoryCraft/DimensionGenerator.cpp
  14. 6 0
      FactoryCraft/DimensionGenerator.h
  15. 365 345
      FactoryCraft/Entity.cpp
  16. 86 81
      FactoryCraft/Entity.h
  17. 2 7
      FactoryCraft/EntityRemovedUpdate.cpp
  18. 1 10
      FactoryCraft/EntityRemovedUpdate.h
  19. 12 2
      FactoryCraft/EntityType.h
  20. 698 642
      FactoryCraft/Game.cpp
  21. 1 1
      FactoryCraft/GeneratedStructure.cpp
  22. 44 28
      FactoryCraft/GrasslandBiom.cpp
  23. 49 54
      FactoryCraft/Item.cpp
  24. 39 37
      FactoryCraft/Item.h
  25. 11 4
      FactoryCraft/ItemEntity.cpp
  26. 1 4
      FactoryCraft/ItemEntity.h
  27. 30 18
      FactoryCraft/ItemSkill.cpp
  28. 29 21
      FactoryCraft/ItemSkill.h
  29. 114 97
      FactoryCraft/ItemType.cpp
  30. 62 29
      FactoryCraft/ItemType.h
  31. 31 26
      FactoryCraft/LightSources.cpp
  32. 43 50
      FactoryCraft/LightSources.h
  33. 6 0
      FactoryCraft/MultiblockStructure.h
  34. 3 2
      FactoryCraft/MultiblockTree.cpp
  35. 9 11
      FactoryCraft/MultiblockTree.h
  36. 29 38
      FactoryCraft/NoBlock.cpp
  37. 17 28
      FactoryCraft/NoBlock.h
  38. 2 1
      FactoryCraft/OverworldDimension.cpp
  39. 1 7
      FactoryCraft/OverworldDimension.h
  40. 5 4
      FactoryCraft/Player.cpp
  41. 1 5
      FactoryCraft/Player.h
  42. 6 4
      FactoryCraft/PlayerHand.cpp
  43. 13 14
      FactoryCraft/PlayerHand.h
  44. 276 183
      FactoryCraft/RecipieLoader.cpp
  45. 6 0
      FactoryCraft/Start.cpp
  46. 380 21
      FactoryCraft/StaticInitializerOrder.cpp
  47. 10 14
      FactoryCraft/StaticRegistry.h
  48. 52 52
      FactoryCraft/StoneTool.cpp
  49. 18 31
      FactoryCraft/StoneTool.h
  50. 89 118
      FactoryCraft/TreeSeblingBlock.cpp
  51. 7 55
      FactoryCraft/TreeSeblingBlock.h
  52. 71 46
      FactoryCraft/TreeTemplate.cpp
  53. 3 3
      FactoryCraft/TreeTemplate.h
  54. 0 7
      FactoryCraft/WorldUpdate.cpp
  55. 7 6
      FactoryCraft/WorldUpdate.h

+ 2 - 7
FactoryCraft/AddEntityUpdate.cpp

@@ -5,7 +5,7 @@
 
 
 AddEntityUpdate::AddEntityUpdate(Entity* entity, int dimension)
-	: WorldUpdate(AddEntityUpdateType::ID, dimension, entity->getPosition(), entity->getPosition()),
+	: WorldUpdate(WorldUpdateTypeEnum::ADD_ENTITY, dimension, entity->getPosition(), entity->getPosition()),
 	entity(entity)
 {}
 
@@ -36,9 +36,4 @@ void AddEntityUpdate::write(Framework::StreamWriter* zWriter)
 	zWriter->schreibe((char*)&special, 1);
 	if (special)
 		entity->getSpecialModel().writeTo(zWriter);
-}
-
-
-AddEntityUpdateType::AddEntityUpdateType()
-	: WorldUpdateType(ID)
-{}
+}

+ 2 - 10
FactoryCraft/AddEntityUpdate.h

@@ -2,6 +2,7 @@
 #include "WorldUpdate.h"
 #include "Entity.h"
 
+
 class AddEntityUpdate : public WorldUpdate
 {
 private:
@@ -15,13 +16,4 @@ public:
 	~AddEntityUpdate();
 
 	void onUpdate(Dimension* zDimension) override;
-};
-
-class AddEntityUpdateType : WorldUpdateType
-{
-	REGISTRABLE(AddEntityUpdateType)
-
-protected:
-	AddEntityUpdateType();
-};
-REGISTER(AddEntityUpdateType, WorldUpdateType)
+};

+ 78 - 426
FactoryCraft/BasicBlock.cpp

@@ -1,464 +1,116 @@
+#include "AddEntityUpdate.h"
 #include "BasicBlocks.h"
-#include "ItemEntity.h"
 #include "Game.h"
-#include "AddEntityUpdate.h"
+#include "ItemEntity.h"
 #include "TreeSeblingBlock.h"
 
-
-BasicBlock::BasicBlock(const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos)
-	: Block(zType, zTool, pos, false)
+BasicBlock::BasicBlock(int typeId, ItemType* zTool, Framework::Vec3<int> pos)
+    : Block(typeId, zTool, pos, false)
 {}
 
 bool BasicBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
 {
-	return 0;
+    return 0;
 }
 
-void BasicBlock::onPostTick()
-{}
+void BasicBlock::onPostTick() {}
 
-
-AdditionalItemSpawningBlock::AdditionalItemSpawningBlock(const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos)
-	: BasicBlock(zType, zTool, pos)
+AdditionalItemSpawningBlock::AdditionalItemSpawningBlock(
+    int typeId, ItemType* zTool, Framework::Vec3<int> pos)
+    : BasicBlock(typeId, zTool, pos)
 {}
 
 void AdditionalItemSpawningBlock::addSpawn(SpawnConfig config)
 {
-	spawns.add(config);
+    spawns.add(config);
 }
 
 void AdditionalItemSpawningBlock::onDestroy()
 {
-	for (const SpawnConfig& config : spawns)
-	{
-		if ((double)rand() / RAND_MAX < config.chance)
-		{
-			int amount = config.min + (int)((config.max - config.min) * ((double)rand() / RAND_MAX));
-			if (amount > 0)
-			{
-				ItemStack* spawnedItems = StaticRegistry<ItemType>::INSTANCE.zElement(config.itemType)->createItemStack(amount);
-				if (spawnedItems)
-				{
-					ItemEntity* itemEntity = (ItemEntity*)ItemEntityType::INSTANCE->createEntity(location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f), getDimensionId(), Game::INSTANCE->getNextEntityId());
-					itemEntity->unsaveAddItem(spawnedItems, NO_DIRECTION);
-					spawnedItems->release();
-					Game::INSTANCE->requestWorldUpdate(new AddEntityUpdate(itemEntity, getDimensionId()));
-				}
-			}
-		}
-	}
-	BasicBlock::onDestroy();
+    for (const SpawnConfig& config : spawns)
+    {
+        if ((double)rand() / RAND_MAX < config.chance)
+        {
+            int amount = config.min
+                       + (int)((config.max - config.min)
+                               * ((double)rand() / RAND_MAX));
+            if (amount > 0)
+            {
+                ItemStack* spawnedItems = StaticRegistry<ItemType>::INSTANCE
+                                              .zElement(config.itemType)
+                                              ->createItemStack(amount);
+                if (spawnedItems)
+                {
+                    ItemEntity* itemEntity
+                        = (ItemEntity*)StaticRegistry<EntityType>::INSTANCE
+                              .zElement(EntityTypeEnum::ITEM)
+                              ->createEntity(location
+                                                 + Framework::Vec3<float>(
+                                                     0.5f, 0.5f, 0.5f),
+                                  getDimensionId(),
+                                  Game::INSTANCE->getNextEntityId());
+                    itemEntity->unsaveAddItem(spawnedItems, NO_DIRECTION);
+                    spawnedItems->release();
+                    Game::INSTANCE->requestWorldUpdate(
+                        new AddEntityUpdate(itemEntity, getDimensionId()));
+                }
+            }
+        }
+    }
+    BasicBlock::onDestroy();
 }
 
-
 BasicBlockType::BasicBlockType(int typeId, int itemTypeId, ModelInfo model)
-	: BlockType(typeId, 0, model, 1, 100, 0),
-	itemType(itemTypeId),
-	transparent(0),
-	passable(0),
-	hardness(1.f),
-	zTool(0),
-	speedModifier(1.f),
-	interactable(1)
+    : BasicBlockType(
+        typeId, itemTypeId, model, [typeId](Framework::Vec3<int> pos) {
+            return new BasicBlock(typeId, 0, pos);
+        })
+{}
+
+BasicBlockType::BasicBlockType(int typeId,
+    int itemTypeId,
+    ModelInfo model,
+    std::function<Block*(Framework::Vec3<int>)> creatBlockCustom)
+    : BlockType(typeId, 0, model, 1, 100, 0),
+      itemType(itemTypeId),
+      transparent(0),
+      passable(0),
+      hardness(1.f),
+      zTool(0),
+      speedModifier(1.f),
+      interactable(1),
+      creatBlockCustom(creatBlockCustom)
 {}
 
 void BasicBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 {
-	BasicBlock* block = dynamic_cast<BasicBlock*>(zBlock);
-	if (!block)
-		throw "DirtBlockType::createSuperBlock was called with a block witch is not an instance of BasicBlock";
-	block->transparent = transparent;
-	block->passable = passable;
-	block->hp = (float)getInitialMaxHP();
-	block->maxHP = (float)getInitialMaxHP();
-	block->hardness = hardness;
-	block->zTool = zTool;
-	block->speedModifier = speedModifier;
-	block->interactable = interactable;
-	BlockType::createSuperBlock(zBlock, zItem);
+    BasicBlock* block = dynamic_cast<BasicBlock*>(zBlock);
+    if (!block)
+        throw "DirtBlockType::createSuperBlock was called with a block witch "
+              "is not an instance of BasicBlock";
+    block->transparent = transparent;
+    block->passable = passable;
+    block->hp = (float)getInitialMaxHP();
+    block->maxHP = (float)getInitialMaxHP();
+    block->hardness = hardness;
+    block->zTool = zTool;
+    block->speedModifier = speedModifier;
+    block->interactable = interactable;
+    BlockType::createSuperBlock(zBlock, zItem);
 }
 
 Block* BasicBlockType::createBlock(Framework::Vec3<int> position) const
 {
-	return new BasicBlock(this, 0, position);
+    return creatBlockCustom(position);
 }
 
 Item* BasicBlockType::createItem() const
 {
-	return StaticRegistry<ItemType>::INSTANCE.zElement(itemType)->createItem();
-}
-
-// Dirt
-DirtBlockType::DirtBlockType()
-	: BasicBlockType(ID, DirtBlockItemType::ID, 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" }))
-{
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-DirtBlockItemType::DirtBlockItemType()
-	: BasicBlockItemType(ID, "Dirt", 0, 0, ModelInfo("itemCube", "blocks.ltdb/dirt.png", 6))
-{}
-
-Item* DirtBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, DirtBlockType::INSTANCE, "Dirt");
-	initializeItem(item, 0, 0, 1, 0, 1);
-	return item;
-}
-
-// Stone
-StoneBlockType::StoneBlockType()
-	: BasicBlockType(ID, StoneBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/stone.png", 6))
-{
-	hardness = 2.f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-StoneBlockItemType::StoneBlockItemType()
-	: BasicBlockItemType(ID, "Stone", 0, 0, ModelInfo("itemCube", "blocks.ltdb/stone.png", 6))
-{}
-
-Item* StoneBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, StoneBlockType::INSTANCE, "Stone");
-	initializeItem(item, 0, 0, 2, 0, 1);
-	return item;
-}
-
-// Sand
-SandBlockType::SandBlockType()
-	: BasicBlockType(ID, SandBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/sand.png", 6))
-{
-	hardness = 0.5f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-SandBlockItemType::SandBlockItemType()
-	: BasicBlockItemType(ID, "Sand", 0, 0, ModelInfo("itemCube", "blocks.ltdb/sand.png", 6))
-{}
-
-Item* SandBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, SandBlockType::INSTANCE, "Sand");
-	initializeItem(item, 0, 0, 0.5f, 0, 1);
-	return item;
-}
-
-// Oak Wood
-OakBlockType::OakBlockType()
-	: BasicBlockType(ID, OakBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/oak.png", 6))
-{
-	hardness = 1.5f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-OakBlockItemType::OakBlockItemType()
-	: BasicBlockItemType(ID, "Oak", 0, 0, ModelInfo("itemCube", "blocks.ltdb/oak.png", 6))
-{}
-
-Item* OakBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, OakBlockType::INSTANCE, "Oak");
-	initializeItem(item, 0, 0, 1.5f, 0, 1);
-	return item;
-}
-
-// Oak Leaves
-OakLeavesBlockType::OakLeavesBlockType()
-	: BasicBlockType(ID, OakLeavesBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/leaves.png", 6))
-{
-	hardness = 0.1f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-Block* OakLeavesBlockType::createBlock(Framework::Vec3<int> position) const
-{
-	AdditionalItemSpawningBlock* block = new AdditionalItemSpawningBlock(this, 0, position);
-	block->addSpawn({ 1, 1, 0.015, OakSeblingBlockItemType::ID });
-	return block;
-}
-
-
-OakLeavesBlockItemType::OakLeavesBlockItemType()
-	: BasicBlockItemType(ID, "Leaves", 0, 0, ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6))
-{}
-
-Item* OakLeavesBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, OakLeavesBlockType::INSTANCE, "Oak Leaves");
-	initializeItem(item, 0, 0, 0.1f, 0, 1);
-	return item;
-}
-
-// Oak Sebling
-OakSeblingBlockItemType::OakSeblingBlockItemType()
-	: BasicBlockItemType(ID, "Oak Sebling", 0, 0, ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1))
-{}
-
-Item* OakSeblingBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, OakSeblingBlockType::INSTANCE, "Oak Sebling");
-	initializeItem(item, 0, 0, 0.1f, 0, 1);
-	return item;
-}
-
-// Gravel
-GravelBlockType::GravelBlockType()
-	: BasicBlockType(ID, GravelBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/gravel.png", 6))
-{
-	hardness = 0.75f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-GravelBlockItemType::GravelBlockItemType()
-	: BasicBlockItemType(ID, "Gravel", 0, 0, ModelInfo("itemCube", "blocks.ltdb/gravel.png", 6))
-{}
-
-Item* GravelBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, GravelBlockType::INSTANCE, "Gravel");
-	initializeItem(item, 0, 0, 0.75f, 0, 1);
-	return item;
-}
-
-// Granite
-GraniteBlockType::GraniteBlockType()
-	: BasicBlockType(ID, GraniteBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/granite.png", 6))
-{
-	hardness = 3.f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-GraniteBlockItemType::GraniteBlockItemType()
-	: BasicBlockItemType(ID, "Granite", 0, 0, ModelInfo("itemCube", "blocks.ltdb/granite.png", 6))
-{}
-
-Item* GraniteBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, GraniteBlockType::INSTANCE, "Granite");
-	initializeItem(item, 0, 0, 3.f, 0, 1);
-	return item;
-}
-
-// Cobble
-CobbleBlockType::CobbleBlockType()
-	: BasicBlockType(ID, CobbleBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/cobble.png", 6))
-{
-	hardness = 1.f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-CobbleBlockItemType::CobbleBlockItemType()
-	: BasicBlockItemType(ID, "Cobble", 0, 0, ModelInfo("itemCube", "blocks.ltdb/cobble.png", 6))
-{}
-
-Item* CobbleBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, CobbleBlockType::INSTANCE, "Cobble");
-	initializeItem(item, 0, 0, 1.f, 0, 1);
-	return item;
-}
-
-// Birch Wood
-BirchBlockType::BirchBlockType()
-	: BasicBlockType(ID, BirchBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/birch.png", 6))
-{
-	hardness = 1.5f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-BirchBlockItemType::BirchBlockItemType()
-	: BasicBlockItemType(ID, "Birch", 0, 0, ModelInfo("itemCube", "blocks.ltdb/birch.png", 6))
-{}
-
-Item* BirchBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, BirchBlockType::INSTANCE, "Birch");
-	initializeItem(item, 0, 0, 1.5f, 0, 1);
-	return item;
-}
-
-// Birch Leaves
-BirchLeavesBlockType::BirchLeavesBlockType()
-	: BasicBlockType(ID, BirchLeavesBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/leaves.png", 6))
-{
-	hardness = 0.1f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-Block* BirchLeavesBlockType::createBlock(Framework::Vec3<int> position) const
-{
-	AdditionalItemSpawningBlock* block = new AdditionalItemSpawningBlock(this, 0, position);
-	block->addSpawn({ 1, 1, 0.03, BirchSeblingBlockItemType::ID });
-	return block;
-}
-
-
-BirchLeavesBlockItemType::BirchLeavesBlockItemType()
-	: BasicBlockItemType(ID, "Leaves", 0, 0, ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6))
-{}
-
-Item* BirchLeavesBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, BirchLeavesBlockType::INSTANCE, "Birch Leaves");
-	initializeItem(item, 0, 0, 0.1f, 0, 1);
-	return item;
-}
-
-// Birch Sebling
-BirchSeblingBlockItemType::BirchSeblingBlockItemType()
-	: BasicBlockItemType(ID, "Birch Sebling", 0, 0, ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1))
-{}
-
-Item* BirchSeblingBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, BirchSeblingBlockType::INSTANCE, "Birch Sebling");
-	initializeItem(item, 0, 0, 0.1f, 0, 1);
-	return item;
-}
-
-// Beech Wood
-BeechBlockType::BeechBlockType()
-	: BasicBlockType(ID, BeechBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/beech.png", 6))
-{
-	hardness = 1.5f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-BeechBlockItemType::BeechBlockItemType()
-	: BasicBlockItemType(ID, "Beech", 0, 0, ModelInfo("itemCube", "blocks.ltdb/beech.png", 6))
-{}
-
-Item* BeechBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, BeechBlockType::INSTANCE, "Beech");
-	initializeItem(item, 0, 0, 1.5f, 0, 1);
-	return item;
-}
-
-// Beech Leaves
-BeechLeavesBlockType::BeechLeavesBlockType()
-	: BasicBlockType(ID, BeechLeavesBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/leaves.png", 6))
-{
-	hardness = 0.1f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-Block* BeechLeavesBlockType::createBlock(Framework::Vec3<int> position) const
-{
-	AdditionalItemSpawningBlock* block = new AdditionalItemSpawningBlock(this, 0, position);
-	block->addSpawn({ 1, 1, 0.02, BeechSeblingBlockItemType::ID });
-	return block;
+    return StaticRegistry<ItemType>::INSTANCE.zElement(itemType)->createItem();
 }
 
-
-BeechLeavesBlockItemType::BeechLeavesBlockItemType()
-	: BasicBlockItemType(ID, "Leaves", 0, 0, ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6))
-{}
-
-Item* BeechLeavesBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, BeechLeavesBlockType::INSTANCE, "Beech Leaves");
-	initializeItem(item, 0, 0, 0.1f, 0, 1);
-	return item;
-}
-
-// Beech Sebling
-BeechSeblingBlockItemType::BeechSeblingBlockItemType()
-	: BasicBlockItemType(ID, "Beech Sebling", 0, 0, ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1))
-{}
-
-Item* BeechSeblingBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, BeechSeblingBlockType::INSTANCE, "Beech Sebling");
-	initializeItem(item, 0, 0, 0.1f, 0, 1);
-	return item;
-}
-
-// Basalt
-BasaltBlockType::BasaltBlockType()
-	: BasicBlockType(ID, BasaltBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/basalt.png", 6))
-{
-	hardness = 2.f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-BasaltBlockItemType::BasaltBlockItemType()
-	: BasicBlockItemType(ID, "Basalt", 0, 0, ModelInfo("itemCube", "blocks.ltdb/basalt.png", 6))
-{}
-
-Item* BasaltBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, BasaltBlockType::INSTANCE, "Basalt");
-	initializeItem(item, 0, 0, 2.f, 0, 1);
-	return item;
-}
-
-// Pine Wood
-PineBlockType::PineBlockType()
-	: BasicBlockType(ID, PineBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/pine.png", 6))
-{
-	hardness = 1.4f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-PineBlockItemType::PineBlockItemType()
-	: BasicBlockItemType(ID, "Pine", 0, 0, ModelInfo("itemCube", "blocks.ltdb/pine.png", 6))
-{}
-
-Item* PineBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, PineBlockType::INSTANCE, "Pine");
-	initializeItem(item, 0, 0, 1.4f, 0, 1);
-	return item;
-}
-
-// Pine Leaves
-PineLeavesBlockType::PineLeavesBlockType()
-	: BasicBlockType(ID, PineLeavesBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/leaves.png", 6))
-{
-	hardness = 0.1f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-
-PineLeavesBlockItemType::PineLeavesBlockItemType()
-	: BasicBlockItemType(ID, "Leaves", 0, 0, ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6))
-{}
-
-Item* PineLeavesBlockItemType::createItem() const
-{
-	BasicBlockItem* item = new BasicBlockItem(this, PineLeavesBlockType::INSTANCE, "Pine Leaves");
-	initializeItem(item, 0, 0, 0.1f, 0, 1);
-	return item;
-}
-
-Block* PineLeavesBlockType::createBlock(Framework::Vec3<int> position) const
-{
-	AdditionalItemSpawningBlock* block = new AdditionalItemSpawningBlock(this, 0, position);
-	block->addSpawn({ 1, 1, 0.025, PineSeblingBlockItemType::ID });
-	return block;
-}
-
-// Pine Sebling
-PineSeblingBlockItemType::PineSeblingBlockItemType()
-	: BasicBlockItemType(ID, "Pine Sebling", 0, 0, ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1))
-{}
-
-Item* PineSeblingBlockItemType::createItem() const
+BasicBlockType* BasicBlockType::setHardness(float hardness)
 {
-	BasicBlockItem* item = new BasicBlockItem(this, PineSeblingBlockType::INSTANCE, "Pine Sebling");
-	initializeItem(item, 0, 0, 0.1f, 0, 1);
-	return item;
+    this->hardness = hardness;
+    return this;
 }

+ 8 - 400
FactoryCraft/BasicBlocks.h

@@ -11,7 +11,7 @@ class BasicBlockType;
 class BasicBlock : public Block
 {
 public:
-	BasicBlock(const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos);
+	BasicBlock(int typeId, ItemType* zTool, Framework::Vec3<int> pos);
 	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) override;
 	virtual void onPostTick() override;
 
@@ -32,7 +32,7 @@ private:
 	Framework::Array< SpawnConfig> spawns;
 
 public:
-	AdditionalItemSpawningBlock(const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos);
+	AdditionalItemSpawningBlock(int typeId, ItemType* zTool, Framework::Vec3<int> pos);
 	void addSpawn(SpawnConfig config);
 	virtual void onDestroy() override;
 };
@@ -41,413 +41,21 @@ class BasicBlockType : public BlockType
 {
 private:
 	int itemType;
-
-protected:
 	bool transparent;
 	bool passable;
 	float hardness;
 	ItemType* zTool;
 	float speedModifier;
 	bool interactable;
-
-	BasicBlockType(int typeId, int itemTypeId, ModelInfo model);
-	virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
-
-public:
-	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-	virtual Item* createItem() const override;
-};
-
-// Dirt
-class DirtBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(DirtBlockItemType)
-
-protected:
-	DirtBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(DirtBlockItemType, ItemType)
-
-class DirtBlockType : public BasicBlockType
-{
-	REGISTRABLE(DirtBlockType)
-
-protected:
-	DirtBlockType();
-};
-REGISTER(DirtBlockType, BlockType)
-
-// Stone
-class StoneBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(StoneBlockItemType)
-
-protected:
-	StoneBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(StoneBlockItemType, ItemType)
-
-class StoneBlockType : public BasicBlockType
-{
-	REGISTRABLE(StoneBlockType)
-
-protected:
-	StoneBlockType();
-};
-REGISTER(StoneBlockType, BlockType)
-
-// Sand
-class SandBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(SandBlockItemType)
-
-protected:
-	SandBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(SandBlockItemType, ItemType)
-
-class SandBlockType : public BasicBlockType
-{
-	REGISTRABLE(SandBlockType)
+	std::function<Block* (Framework::Vec3<int>)> creatBlockCustom;
 
 protected:
-	SandBlockType();
-};
-REGISTER(SandBlockType, BlockType)
-
-// Oak Wood
-class OakBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(OakBlockItemType)
-
-protected:
-	OakBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(OakBlockItemType, ItemType)
-
-class OakBlockType : public BasicBlockType
-{
-	REGISTRABLE(OakBlockType)
-
-protected:
-	OakBlockType();
-};
-REGISTER(OakBlockType, BlockType)
-
-// Oak Leaves
-class OakLeavesBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(OakLeavesBlockItemType)
-
-protected:
-	OakLeavesBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(OakLeavesBlockItemType, ItemType)
-
-class OakLeavesBlockType : public BasicBlockType
-{
-	REGISTRABLE(OakLeavesBlockType)
-
-protected:
-	OakLeavesBlockType();
-
-public:
-	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-};
-REGISTER(OakLeavesBlockType, BlockType)
-
-// Oak Sebling
-class OakSeblingBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(OakSeblingBlockItemType)
-
-protected:
-	OakSeblingBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(OakSeblingBlockItemType, ItemType)
-
-// Gravel
-class GravelBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(GravelBlockItemType)
-
-protected:
-	GravelBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(GravelBlockItemType, ItemType)
-
-class GravelBlockType : public BasicBlockType
-{
-	REGISTRABLE(GravelBlockType)
-
-protected:
-	GravelBlockType();
-};
-REGISTER(GravelBlockType, BlockType)
-
-// Granite
-class GraniteBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(GraniteBlockItemType)
-
-protected:
-	GraniteBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(GraniteBlockItemType, ItemType)
-
-class GraniteBlockType : public BasicBlockType
-{
-	REGISTRABLE(GraniteBlockType)
-
-protected:
-	GraniteBlockType();
-};
-REGISTER(GraniteBlockType, BlockType)
-
-// Cobble
-class CobbleBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(CobbleBlockItemType)
-
-protected:
-	CobbleBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(CobbleBlockItemType, ItemType)
-
-class CobbleBlockType : public BasicBlockType
-{
-	REGISTRABLE(CobbleBlockType)
-
-protected:
-	CobbleBlockType();
-};
-REGISTER(CobbleBlockType, BlockType)
-
-// Birch Wood
-class BirchBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(BirchBlockItemType)
-
-protected:
-	BirchBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(BirchBlockItemType, ItemType)
-
-class BirchBlockType : public BasicBlockType
-{
-	REGISTRABLE(BirchBlockType)
-
-protected:
-	BirchBlockType();
-};
-REGISTER(BirchBlockType, BlockType)
-
-// Birch Leaves
-class BirchLeavesBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(BirchLeavesBlockItemType)
-
-protected:
-	BirchLeavesBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(BirchLeavesBlockItemType, ItemType)
-
-class BirchLeavesBlockType : public BasicBlockType
-{
-	REGISTRABLE(BirchLeavesBlockType)
-
-protected:
-	BirchLeavesBlockType();
-
-public:
-	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-};
-REGISTER(BirchLeavesBlockType, BlockType)
-
-// Birch Sebling
-class BirchSeblingBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(BirchSeblingBlockItemType)
-
-protected:
-	BirchSeblingBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(BirchSeblingBlockItemType, ItemType)
-
-// Beech Wood
-class BeechBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(BeechBlockItemType)
-
-protected:
-	BeechBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(BeechBlockItemType, ItemType)
-
-class BeechBlockType : public BasicBlockType
-{
-	REGISTRABLE(BeechBlockType)
-
-protected:
-	BeechBlockType();
-};
-REGISTER(BeechBlockType, BlockType)
-
-// Beech Leaves
-class BeechLeavesBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(BeechLeavesBlockItemType)
-
-protected:
-	BeechLeavesBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(BeechLeavesBlockItemType, ItemType)
-
-class BeechLeavesBlockType : public BasicBlockType
-{
-	REGISTRABLE(BeechLeavesBlockType)
-
-protected:
-	BeechLeavesBlockType();
-
-public:
-	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-};
-REGISTER(BeechLeavesBlockType, BlockType)
-
-// Beech Sebling
-class BeechSeblingBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(BeechSeblingBlockItemType)
-
-protected:
-	BeechSeblingBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(BeechSeblingBlockItemType, ItemType)
-
-// Basalt
-class BasaltBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(BasaltBlockItemType)
-
-protected:
-	BasaltBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(BasaltBlockItemType, ItemType)
-
-class BasaltBlockType : public BasicBlockType
-{
-	REGISTRABLE(BasaltBlockType)
-
-protected:
-	BasaltBlockType();
-};
-REGISTER(BasaltBlockType, BlockType)
-
-// Pine
-class PineBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(PineBlockItemType)
-
-protected:
-	PineBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(PineBlockItemType, ItemType)
-
-class PineBlockType : public BasicBlockType
-{
-	REGISTRABLE(PineBlockType)
-
-protected:
-	PineBlockType();
-};
-REGISTER(PineBlockType, BlockType)
-
-// Pine Leaves
-class PineLeavesBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(PineLeavesBlockItemType)
-
-protected:
-	PineLeavesBlockItemType();
-
-public:
-	virtual Item* createItem() const override;
-};
-REGISTER(PineLeavesBlockItemType, ItemType)
-
-class PineLeavesBlockType : public BasicBlockType
-{
-	REGISTRABLE(PineLeavesBlockType)
-
-protected:
-	PineLeavesBlockType();
+	virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
 
 public:
+	BasicBlockType(int typeId, int itemTypeId, ModelInfo model);
+	BasicBlockType(int typeId, int itemTypeId, ModelInfo model, std::function<Block* (Framework::Vec3<int>)> creatBlockCustom);
 	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-};
-REGISTER(PineLeavesBlockType, BlockType)
-
-// Pine Sebling
-class PineSeblingBlockItemType : public BasicBlockItemType
-{
-	REGISTRABLE(PineSeblingBlockItemType)
-
-protected:
-	PineSeblingBlockItemType();
-
-public:
 	virtual Item* createItem() const override;
-};
-REGISTER(PineSeblingBlockItemType, ItemType)
+	BasicBlockType* setHardness(float hardness);
+};

+ 11 - 14
FactoryCraft/BasicItems.cpp

@@ -1,21 +1,18 @@
 #include "BasicItems.h"
-#include "ModelInfo.h"
-
-WoodStickItemType::WoodStickItemType()
-	: ItemType(ID, "WoodenStick", 0, 0, ModelInfo("items.m3/stick", "items.ltdb/stick.png", 1))
-{}
-
-Item* WoodStickItemType::createItem() const
-{
-	return createBasicItem("Wooden Stick", 1.f, 1.f, 10.f, 10.f, 0, 0, 0, 1, 0, 50);
-}
 
+#include "ModelInfo.h"
 
-ResinItemType::ResinItemType()
-	: ItemType(ID, "Resin", 0, 0, ModelInfo("itemCube", "items.ltdb/resin.png", 6))
+NoBlockItemType::NoBlockItemType(int id,
+    const char* name,
+    ItemSkillLevelUpRule* levelUp,
+    int brokenTypeId,
+    ModelInfo model,
+    std::function<Item*()> createItemImp)
+    : ItemType(id, name, levelUp, brokenTypeId, model),
+      createItemImp(createItemImp)
 {}
 
-Item* ResinItemType::createItem() const
+Item* NoBlockItemType::createItem() const
 {
-	return createBasicItem("Resin", 1.f, 1.f, 10.f, 10.f, 0, 0, 0, 1, 0, 50);
+    return createItemImp();
 }

+ 11 - 21
FactoryCraft/BasicItems.h

@@ -2,27 +2,17 @@
 
 #include "ItemType.h"
 
-class WoodStickItemType : public ItemType
+class NoBlockItemType : public ItemType
 {
-	REGISTRABLE(WoodStickItemType)
-
-protected:
-	WoodStickItemType();
-
-public:
-	Item* createItem() const override;
-};
-REGISTER(WoodStickItemType, ItemType)
-
-
-class ResinItemType : public ItemType
-{
-	REGISTRABLE(ResinItemType)
-
-protected:
-	ResinItemType();
+private:
+    std::function<Item*()> createItemImp;
 
 public:
-	Item* createItem() const override;
-};
-REGISTER(ResinItemType, ItemType)
+    NoBlockItemType(int id,
+        const char* name,
+        ItemSkillLevelUpRule* levelUp,
+        int brokenTypeId,
+        ModelInfo model,
+        std::function<Item*()> createItemImp);
+    Item* createItem() const override;
+};

+ 243 - 206
FactoryCraft/Block.cpp

@@ -1,335 +1,372 @@
 #include "Block.h"
-#include "Inventory.h"
-#include "NoBlock.h"
+
+#include "AddEntityUpdate.h"
 #include "Game.h"
+#include "Inventory.h"
 #include "ItemEntity.h"
-#include "AddEntityUpdate.h"
 #include "MultiblockStructure.h"
+#include "NoBlock.h"
 
-
-Block::Block(const BlockType* zType, const ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory)
-	: Inventory(pos, hasInventory)
-{
-	transparent = false;
-	passable = false;
-	hp = 1;
-	maxHP = 1;
-	hardness = 1;
-	this->zType = zType;
-	this->zTool = zTool;
-	speedModifier = 1;
-	ticksLeftCounter = 0;
-	wasTicked = 0;
-	onTickCalled = 0;
-	minTickTimeout = -1;
-	maxTickTimeout = -1;
-	tickSource = 0;
-	currentTickTimeout = 0;
-	dimensionId = 0;
-	interactable = 0;
-	deadAndRemoved = 0;
-	memset(zNeighbours, 0, sizeof(Block*) * 6);
-	memset(lightEmisionColor, 0, 3);
-}
-
-Block::~Block()
-{}
+Block::Block(int typeId,
+    const ItemType* zTool,
+    Framework::Vec3<int> pos,
+    bool hasInventory)
+    : Inventory(pos, hasInventory)
+{
+    transparent = false;
+    passable = false;
+    hp = 1;
+    maxHP = 1;
+    hardness = 1;
+    this->typeId = typeId;
+    this->zTool = zTool;
+    speedModifier = 1;
+    ticksLeftCounter = 0;
+    wasTicked = 0;
+    onTickCalled = 0;
+    minTickTimeout = -1;
+    maxTickTimeout = -1;
+    tickSource = 0;
+    currentTickTimeout = 0;
+    dimensionId = 0;
+    interactable = 0;
+    deadAndRemoved = 0;
+    memset(zNeighbours, 0, sizeof(Block*) * 6);
+    memset(lightEmisionColor, 0, 3);
+}
+
+Block::~Block() {}
 
 void Block::onDestroy()
 {
-	if (!deadAndRemoved)
-	{
-		for (int i = 0; i < 6; i++)
-		{
-			if (neighbourTypes[i] == NoBlockBlockType::ID)
-			{
-				Framework::Vec3<int> pos = getPos() + getDirection(getDirectionFromIndex(i));
-				Game::INSTANCE->zDimension(dimensionId)->placeBlock(pos, Game::INSTANCE->zGenerator()->generateSingleBlock(pos, dimensionId));
-			}
-		}
-		Item* blockItem = zType->getItemFromBlock(this);
-		if (blockItem)
-		{
-			ItemEntity* itemEntity = (ItemEntity*)ItemEntityType::INSTANCE->createEntity(location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f), dimensionId, Game::INSTANCE->getNextEntityId());
-			ItemStack* stack = new ItemStack(blockItem, 1, blockItem->getMaxStackSize());
-			itemEntity->unsaveAddItem(stack, NO_DIRECTION);
-			stack->release();
-			Game::INSTANCE->requestWorldUpdate(new AddEntityUpdate(itemEntity, dimensionId));
-			deadAndRemoved = 1;
-		}
-		for (MultiblockStructure* structure : structures)
-			structure->onBlockRemoved(this);
-		Game::INSTANCE->zDimension(dimensionId)->placeBlock(getPos(), AirBlockBlockType::ID); // this will be deleted here
-	}
+    if (!deadAndRemoved)
+    {
+        for (int i = 0; i < 6; i++)
+        {
+            if (neighbourTypes[i] == BlockTypeEnum::NO_BLOCK)
+            {
+                Framework::Vec3<int> pos
+                    = getPos() + getDirection(getDirectionFromIndex(i));
+                Game::INSTANCE->zDimension(dimensionId)
+                    ->placeBlock(pos,
+                        Game::INSTANCE->zGenerator()->generateSingleBlock(
+                            pos, dimensionId));
+            }
+        }
+        Item* blockItem = zBlockType()->getItemFromBlock(this);
+        if (blockItem)
+        {
+            ItemEntity* itemEntity
+                = (ItemEntity*)StaticRegistry<EntityType>::INSTANCE
+                      .zElement(EntityTypeEnum::ITEM)
+                      ->createEntity(
+                          location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
+                          dimensionId,
+                          Game::INSTANCE->getNextEntityId());
+            ItemStack* stack
+                = new ItemStack(blockItem, 1, blockItem->getMaxStackSize());
+            itemEntity->unsaveAddItem(stack, NO_DIRECTION);
+            stack->release();
+            Game::INSTANCE->requestWorldUpdate(
+                new AddEntityUpdate(itemEntity, dimensionId));
+            deadAndRemoved = 1;
+        }
+        for (MultiblockStructure* structure : structures)
+            structure->onBlockRemoved(this);
+        Game::INSTANCE->zDimension(dimensionId)
+            ->placeBlock(
+                getPos(), BlockTypeEnum::AIR); // this will be deleted here
+    }
 }
 
 void Block::tick(TickQueue* zQueue)
 {
-	if (wasTicked)
-		return;
-	wasTicked = 1;
-	ticksLeftCounter++;
-	if (minTickTimeout >= 0)
-	{
-		if (currentTickTimeout < ticksLeftCounter)
-		{
-			onTickCalled = 1;
-			bool blocked = 0;
-			bool result = onTick(zQueue, ticksLeftCounter, blocked);
-			if (blocked)
-			{
-				wasTicked = 0;
-				ticksLeftCounter--;
-				onTickCalled = 0;
-				return;
-			}
-			if (result)
-				currentTickTimeout = MAX(MIN(currentTickTimeout - 1, maxTickTimeout), MAX(minTickTimeout, 0));
-			else
-				currentTickTimeout = MAX(MIN(currentTickTimeout + 1, maxTickTimeout), MAX(minTickTimeout, 0));
-			ticksLeftCounter = 0;
-		}
-	}
+    if (wasTicked) return;
+    wasTicked = 1;
+    ticksLeftCounter++;
+    if (minTickTimeout >= 0)
+    {
+        if (currentTickTimeout < ticksLeftCounter)
+        {
+            onTickCalled = 1;
+            bool blocked = 0;
+            bool result = onTick(zQueue, ticksLeftCounter, blocked);
+            if (blocked)
+            {
+                wasTicked = 0;
+                ticksLeftCounter--;
+                onTickCalled = 0;
+                return;
+            }
+            if (result)
+                currentTickTimeout
+                    = MAX(MIN(currentTickTimeout - 1, maxTickTimeout),
+                        MAX(minTickTimeout, 0));
+            else
+                currentTickTimeout
+                    = MAX(MIN(currentTickTimeout + 1, maxTickTimeout),
+                        MAX(minTickTimeout, 0));
+            ticksLeftCounter = 0;
+        }
+    }
 }
 
 void Block::postTick()
 {
-	wasTicked = 0;
-	if (onTickCalled)
-	{
-		onPostTick();
-		onTickCalled = 0;
-	}
+    wasTicked = 0;
+    if (onTickCalled)
+    {
+        onPostTick();
+        onTickCalled = 0;
+    }
 }
 
-void Block::setNeighbour(Direction dir, Framework::Either<Block*, int> neighbour)
+void Block::setNeighbour(
+    Direction dir, Framework::Either<Block*, int> neighbour)
 {
-	if (neighbour.isA())
-		setNeighbourBlock(dir, neighbour);
-	else
-	{
-		setNeighbourBlock(dir, 0);
-		setNeighbourType(dir, neighbour);
-	}
+    if (neighbour.isA())
+        setNeighbourBlock(dir, neighbour);
+    else
+    {
+        setNeighbourBlock(dir, 0);
+        setNeighbourType(dir, neighbour);
+    }
 }
 
 void Block::setNeighbourBlock(Direction dir, Block* zN)
 {
-	if (zN)
-		setNeighbourType(dir, zN->zBlockType()->getId());
-	zNeighbours[getDirectionIndex(dir)] = zN;
+    if (zN) setNeighbourType(dir, zN->zBlockType()->getId());
+    zNeighbours[getDirectionIndex(dir)] = zN;
 }
 
 void Block::setNeighbourType(Direction dir, int type)
 {
-	neighbourTypes[getDirectionIndex(dir)] = type;
+    neighbourTypes[getDirectionIndex(dir)] = type;
 }
 
 void Block::setDimensionId(int id)
 {
-	dimensionId = id;
+    dimensionId = id;
 }
 
 void Block::addToStructure(MultiblockStructure* structure)
 {
-	if (structure->isBlockMember(this))
-		structures.add(structure);
-	else
-		structure->release();
+    if (structure->isBlockMember(this))
+        structures.add(structure);
+    else
+        structure->release();
 }
 
 void Block::onLoaded()
 {
-	for (MultiblockStructure* structure : structures)
-		structure->onBlockLoaded(dynamic_cast<Block*>(getThis()));
+    for (MultiblockStructure* structure : structures)
+        structure->onBlockLoaded(dynamic_cast<Block*>(getThis()));
 }
 
 void Block::onUnloaded()
 {
-	for (MultiblockStructure* structure : structures)
-		structure->onBlockUnloaded(this);
+    for (MultiblockStructure* structure : structures)
+        structure->onBlockUnloaded(this);
 }
 
 void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
 {
-	// TODO: answer api requests
+    // TODO: answer api requests
 }
 
 bool Block::isTickSource() const
 {
-	return tickSource;
+    return tickSource;
 }
 
 const BlockType* Block::zBlockType() const
 {
-	return zType;
+    return StaticRegistry<BlockType>::INSTANCE.zElement(typeId);
 }
 
 bool Block::isTransparent() const
 {
-	return transparent;
+    return transparent;
 }
 
 bool Block::isPassable() const
 {
-	return passable;
+    return passable;
 }
 
 bool Block::isInteractable() const
 {
-	return interactable;
+    return interactable;
 }
 
 float Block::getHP() const
 {
-	return hp;
+    return hp;
 }
 
 float Block::getMaxHP() const
 {
-	return maxHP;
+    return maxHP;
 }
 
 float Block::getHardness() const
 {
-	return hardness;
+    return hardness;
 }
 
 const ItemType* Block::zEffectiveTool() const
 {
-	return zTool;
+    return zTool;
 }
 
 float Block::getSpeedModifier() const
 {
-	return speedModifier;
+    return speedModifier;
 }
 
 const Framework::Vec3<int> Block::getPos() const
 {
-	return (Framework::Vec3<int>)location;
+    return (Framework::Vec3<int>)location;
 }
 
 int Block::getDimensionId() const
 {
-	return dimensionId;
+    return dimensionId;
 }
 
 bool Block::isVisible() const
 {
-	if (passable || transparent)
-		return 1;
-	for (int i = 0; i < 6; i++)
-	{
-		const Block* neighbour = CONST_BLOCK(zNeighbours[i], neighbourTypes[i]);
-		if (neighbour->isPassable() || neighbour->isTransparent())
-			return 1;
-	}
-	return 0;
+    if (passable || transparent) return 1;
+    for (int i = 0; i < 6; i++)
+    {
+        const Block* neighbour = CONST_BLOCK(zNeighbours[i], neighbourTypes[i]);
+        if (neighbour->isPassable() || neighbour->isTransparent()) return 1;
+    }
+    return 0;
 }
 
 void Block::setHP(float hp)
 {
-	bool isDead = this->hp == 0.f;
-	this->hp = MAX(0.f, hp);
-	if (!isDead && this->hp == 0.f)
-	{
-		onDestroy(); // this will be deleted
-	}
-	else
-	{
-		NetworkMessage* changeMsg = new NetworkMessage();
-		changeMsg->addressBlock(this);
-		char* msg = new char[5];
-		msg[0] = 0; // hp changed
-		*(float*)(msg + 1) = this->hp;
-		changeMsg->setMessage(msg, 5);
-		Game::INSTANCE->broadcastMessage(changeMsg);
-	}
+    bool isDead = this->hp == 0.f;
+    this->hp = MAX(0.f, hp);
+    if (!isDead && this->hp == 0.f)
+    {
+        onDestroy(); // this will be deleted
+    }
+    else
+    {
+        NetworkMessage* changeMsg = new NetworkMessage();
+        changeMsg->addressBlock(this);
+        char* msg = new char[5];
+        msg[0] = 0; // hp changed
+        *(float*)(msg + 1) = this->hp;
+        changeMsg->setMessage(msg, 5);
+        Game::INSTANCE->broadcastMessage(changeMsg);
+    }
 }
 
 bool Block::isDeadAndRemoved() const
 {
-	return deadAndRemoved;
+    return deadAndRemoved;
 }
 
 const unsigned char* Block::getLightEmisionColor() const
 {
-	return lightEmisionColor;
+    return lightEmisionColor;
 }
 
 void Block::filterPassingLight(unsigned char rgb[3]) const
 {
-	if (!transparent) // let no light pass intransparent blocks
-		memset(rgb, 0, 3);
+    if (!transparent) // let no light pass intransparent blocks
+        memset(rgb, 0, 3);
 }
 
 Block* Block::zNeighbor(Direction dir) const
 {
-	return zNeighbours[getDirectionIndex(dir)];
+    return zNeighbours[getDirectionIndex(dir)];
 }
 
-
-BasicBlockItem::BasicBlockItem(const ItemType* zType, const BlockType* zPlacedBlockType, const char* name)
-	: Item(zType, name)
+BasicBlockItem::BasicBlockItem(
+    int itemTypeId, int blockTypeId, const char* name)
+    : Item(itemTypeId, name)
 {
-	placeable = 1;
-	zBlockType = zPlacedBlockType;
+    blockTypeId = blockTypeId;
+    placeable = 1;
 }
 
 bool BasicBlockItem::canBeStackedWith(const Item* zItem) const
 {
-	const BasicBlockItem* item = dynamic_cast<const BasicBlockItem*>(zItem);
-	if (item)
-	{
-		return Item::canBeStackedWith(zItem) &&
-			transparent == item->transparent &&
-			passable == item->passable &&
-			hardness == item->hardness &&
-			toolId == item->toolId &&
-			speedModifier == item->speedModifier && interactable == item->interactable;
-	}
-	return 0;
-}
-
-
-BasicBlockItemType::BasicBlockItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType, ModelInfo model)
-	: ItemType(id, name, levelUpRule, zBrokenType, model)
+    const BasicBlockItem* item = dynamic_cast<const BasicBlockItem*>(zItem);
+    if (item)
+    {
+        return Item::canBeStackedWith(zItem) && transparent == item->transparent
+            && passable == item->passable && hardness == item->hardness
+            && toolId == item->toolId && speedModifier == item->speedModifier
+            && interactable == item->interactable;
+    }
+    return 0;
+}
+
+BasicBlockItemType::BasicBlockItemType(int id,
+    const char* name,
+    ItemSkillLevelUpRule* levelUpRule,
+    int brokenTypeId,
+    ModelInfo model,
+    int blockTypeId)
+    : ItemType(id, name, levelUpRule, brokenTypeId, model),
+      transparent(0),
+      passable(0),
+      hardness(1.f),
+      toolId(0),
+      speedModifier(1.f),
+      blockTypeId(blockTypeId)
 {}
 
-void BasicBlockItemType::loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const
-{
-	ItemType::loadSuperItem(zItem, zReader);
-	BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
-	if (!item)
-		throw "BasicBlockItemType::loadSuperItem was called with an invalid item";
-	zReader->lese((char*)&item->transparent, 1);
-	zReader->lese((char*)&item->passable, 1);
-	zReader->lese((char*)&item->hardness, 4);
-	zReader->lese((char*)&item->toolId, 4);
-	zReader->lese((char*)&item->speedModifier, 4);
-	zReader->lese((char*)&item->interactable, 1);
-}
-
-void BasicBlockItemType::saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const
-{
-	ItemType::saveSuperItem(zItem, zWriter);
-	const BasicBlockItem* item = dynamic_cast<const BasicBlockItem*>(zItem);
-	if (!item)
-		throw "BasicBlockItemType::saveSuperItem was called with an invalid item";
-	zWriter->schreibe((char*)&item->transparent, 1);
-	zWriter->schreibe((char*)&item->passable, 1);
-	zWriter->schreibe((char*)&item->hardness, 4);
-	zWriter->schreibe((char*)&item->toolId, 4);
-	zWriter->schreibe((char*)&item->speedModifier, 4);
-	zWriter->schreibe((char*)&item->interactable, 1);
-}
-
-void BasicBlockItemType::initializeItem(BasicBlockItem* zItem, bool transparent, bool passable, float hardness, int toolId, float speedModifier) const
-{
-	zItem->transparent = transparent;
-	zItem->passable = passable;
-	zItem->hardness = hardness;
-	zItem->toolId = toolId;
-	zItem->speedModifier = speedModifier;
+void BasicBlockItemType::loadSuperItem(
+    Item* zItem, Framework::StreamReader* zReader) const
+{
+    ItemType::loadSuperItem(zItem, zReader);
+    BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
+    if (!item)
+        throw "BasicBlockItemType::loadSuperItem was called with an invalid "
+              "item";
+    zReader->lese((char*)&item->transparent, 1);
+    zReader->lese((char*)&item->passable, 1);
+    zReader->lese((char*)&item->hardness, 4);
+    zReader->lese((char*)&item->toolId, 4);
+    zReader->lese((char*)&item->speedModifier, 4);
+    zReader->lese((char*)&item->interactable, 1);
+}
+
+void BasicBlockItemType::saveSuperItem(
+    const Item* zItem, Framework::StreamWriter* zWriter) const
+{
+    ItemType::saveSuperItem(zItem, zWriter);
+    const BasicBlockItem* item = dynamic_cast<const BasicBlockItem*>(zItem);
+    if (!item)
+        throw "BasicBlockItemType::saveSuperItem was called with an invalid "
+              "item";
+    zWriter->schreibe((char*)&item->transparent, 1);
+    zWriter->schreibe((char*)&item->passable, 1);
+    zWriter->schreibe((char*)&item->hardness, 4);
+    zWriter->schreibe((char*)&item->toolId, 4);
+    zWriter->schreibe((char*)&item->speedModifier, 4);
+    zWriter->schreibe((char*)&item->interactable, 1);
+}
+
+Item* BasicBlockItemType::createItem() const
+{
+    BasicBlockItem* item = new BasicBlockItem(id, blockTypeId, name);
+    item->transparent = transparent;
+    item->passable = passable;
+    item->hardness = hardness;
+    item->toolId = toolId;
+    item->speedModifier = speedModifier;
+    return item;
+}
+
+BasicBlockItemType* BasicBlockItemType::setHardness(float hardness)
+{
+    this->hardness = hardness;
+    return this;
 }

+ 123 - 97
FactoryCraft/Block.h

@@ -1,17 +1,20 @@
 #pragma once
 
-#include "BlockType.h"
-#include "ReferenceCounter.h"
-#include "Item.h"
-#include "Inventory.h"
-#include "NetworkMessage.h"
-
+#include <Either.h>
 #include <Trie.h>
 #include <Vec3.h>
-#include <Either.h>
 #include <VecN.h>
 
-#define CONST_BLOCK(maybeBlock, type) (maybeBlock ? maybeBlock : StaticRegistry<BlockType>::INSTANCE.zElement((int)type)->zDefault())
+#include "BlockType.h"
+#include "Inventory.h"
+#include "Item.h"
+#include "NetworkMessage.h"
+#include "ReferenceCounter.h"
+
+#define CONST_BLOCK(maybeBlock, type)                                     \
+    (maybeBlock ? maybeBlock                                              \
+                : StaticRegistry<BlockType>::INSTANCE.zElement((int)type) \
+                      ->zDefault())
 
 class ItemType;
 class Chunk;
@@ -23,110 +26,133 @@ class TickQueue;
 class Block : public Inventory
 {
 private:
-	int ticksLeftCounter;
-	int currentTickTimeout;
-	bool wasTicked;
-	bool onTickCalled;
-	int dimensionId;
+    int ticksLeftCounter;
+    int currentTickTimeout;
+    bool wasTicked;
+    bool onTickCalled;
+    int dimensionId;
 
 protected:
-	bool transparent;
-	bool passable;
-	float hp;
-	float maxHP;
-	float hardness;
-	const BlockType* zType;
-	const ItemType* zTool;
-	float speedModifier;
-	Block* zNeighbours[6];
-	int neighbourTypes[6];
-
-	int minTickTimeout;
-	int maxTickTimeout;
-	bool tickSource;
-	bool interactable;
-	bool transmissionRequested;
-	bool deadAndRemoved;
-	unsigned char lightEmisionColor[3];
-
-	Framework::RCArray<MultiblockStructure> structures;
-
-	/// <summary>
-	/// executes block specific things
-	/// </summary>
-	/// <param name="zqueue">a queue to add neighbor blocks that should be ticked after this block</param>
-	/// <param name="numTicks">the number of ticks passed since the last call (only for tickSources)</param>
-	/// <param name="blocked">can be set to one to tell that this block needs to be tickt again later in the queue of this tick</param>
-	/// <returns>true, iff the block needs to be ticked more often</returns>
-	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) = 0;
-	/// <summary>
-	/// gets called after each block was tickt.
-	/// the order of blocks called will be exactly the same as onTick
-	/// </summary>
-	virtual void onPostTick() = 0;
-	virtual void onDestroy();
+    bool transparent;
+    bool passable;
+    float hp;
+    float maxHP;
+    float hardness;
+    int typeId;
+    const ItemType* zTool;
+    float speedModifier;
+    Block* zNeighbours[6];
+    int neighbourTypes[6];
+
+    int minTickTimeout;
+    int maxTickTimeout;
+    bool tickSource;
+    bool interactable;
+    bool transmissionRequested;
+    bool deadAndRemoved;
+    unsigned char lightEmisionColor[3];
+
+    Framework::RCArray<MultiblockStructure> structures;
+
+    /// <summary>
+    /// executes block specific things
+    /// </summary>
+    /// <param name="zqueue">a queue to add neighbor blocks that should be
+    /// ticked after this block</param> <param name="numTicks">the number of
+    /// ticks passed since the last call (only for tickSources)</param> <param
+    /// name="blocked">can be set to one to tell that this block needs to be
+    /// tickt again later in the queue of this tick</param> <returns>true, iff
+    /// the block needs to be ticked more often</returns>
+    virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) = 0;
+    /// <summary>
+    /// gets called after each block was tickt.
+    /// the order of blocks called will be exactly the same as onTick
+    /// </summary>
+    virtual void onPostTick() = 0;
+    virtual void onDestroy();
 
 public:
-	Block(const BlockType* zType, const ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory);
-	virtual ~Block();
-
-	void tick(TickQueue* zQueue);
-	void postTick();
-	void setDimensionId(int id);
-	void addToStructure(MultiblockStructure* structure);
-	virtual void onLoaded();
-	virtual void onUnloaded();
-	virtual void setNeighbour(Direction dir, Framework::Either<Block*, int> neighbor);
-	virtual void setNeighbourBlock(Direction dir, Block* zN);
-	virtual void setNeighbourType(Direction dir, int type);
-
-	void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse);
-
-	bool isTickSource() const;
-	const BlockType* zBlockType() const;
-	bool isTransparent() const;
-	bool isPassable() const;
-	bool isInteractable() const;
-	float getHP() const;
-	float getMaxHP() const;
-	float getHardness() const;
-	const ItemType* zEffectiveTool() const;
-	float getSpeedModifier() const;
-	const Framework::Vec3<int> getPos() const;
-	int getDimensionId() const;
-	bool isVisible() const;
-	void setHP(float hp);
-	bool isDeadAndRemoved() const;
-	const unsigned char* getLightEmisionColor() const;
-	virtual void filterPassingLight(unsigned char rgb[3]) const;
-	Block* zNeighbor(Direction dir) const;
-
-	friend BlockType;
+    Block(int typeId,
+        const ItemType* zTool,
+        Framework::Vec3<int> pos,
+        bool hasInventory);
+    virtual ~Block();
+
+    void tick(TickQueue* zQueue);
+    void postTick();
+    void setDimensionId(int id);
+    void addToStructure(MultiblockStructure* structure);
+    virtual void onLoaded();
+    virtual void onUnloaded();
+    virtual void setNeighbour(
+        Direction dir, Framework::Either<Block*, int> neighbor);
+    virtual void setNeighbourBlock(Direction dir, Block* zN);
+    virtual void setNeighbourType(Direction dir, int type);
+
+    void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse);
+
+    bool isTickSource() const;
+    const BlockType* zBlockType() const;
+    bool isTransparent() const;
+    bool isPassable() const;
+    bool isInteractable() const;
+    float getHP() const;
+    float getMaxHP() const;
+    float getHardness() const;
+    const ItemType* zEffectiveTool() const;
+    float getSpeedModifier() const;
+    const Framework::Vec3<int> getPos() const;
+    int getDimensionId() const;
+    bool isVisible() const;
+    void setHP(float hp);
+    bool isDeadAndRemoved() const;
+    const unsigned char* getLightEmisionColor() const;
+    virtual void filterPassingLight(unsigned char rgb[3]) const;
+    Block* zNeighbor(Direction dir) const;
+
+    friend BlockType;
 };
 
 class BasicBlockItem : public Item
 {
 protected:
-	bool transparent;
-	bool passable;
-	float hardness;
-	int toolId;
-	float speedModifier;
-	bool interactable;
+    bool transparent;
+    bool passable;
+    float hardness;
+    int toolId;
+    float speedModifier;
+    bool interactable;
 
 public:
-	BasicBlockItem(const ItemType* zType, const BlockType* zPlacedBlockType, const char* name);
-	virtual bool canBeStackedWith(const Item* zItem) const override;
+    BasicBlockItem(int itemTypeId, int blockTypeId, const char* name);
+    virtual bool canBeStackedWith(const Item* zItem) const override;
 
-	friend BasicBlockItemType;
-	friend BlockType;
+    friend BasicBlockItemType;
+    friend BlockType;
 };
 
 class BasicBlockItemType : public ItemType
 {
 protected:
-	BasicBlockItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType, ModelInfo model);
-	virtual void loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const override;
-	virtual void saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const override;
-	void initializeItem(BasicBlockItem* zItem, bool transparent, bool passable, float hardness, int toolId, float speedModifier) const;
+    bool transparent;
+    bool passable;
+    float hardness;
+    int toolId;
+    float speedModifier;
+    int blockTypeId;
+
+    virtual void loadSuperItem(
+        Item* zItem, Framework::StreamReader* zReader) const override;
+    virtual void saveSuperItem(
+        const Item* zItem, Framework::StreamWriter* zWriter) const override;
+    virtual Item* createItem() const override;
+
+public:
+    BasicBlockItemType(int id,
+        const char* name,
+        ItemSkillLevelUpRule* levelUpRule,
+        int brokenTypeId,
+        ModelInfo model,
+        int blockTypeId);
+    BasicBlockItemType* setHardness(float hardness);
 };

+ 6 - 0
FactoryCraft/BlockType.cpp

@@ -170,4 +170,10 @@ const Block* getDefaultBlock(Either<Block*, int> b)
 		return b;
 	else
 		return StaticRegistry<BlockType>::INSTANCE.zElement(b)->zDefault();
+}
+
+BlockType* BlockType::initializeDefault()
+{
+	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
+	return this;
 }

+ 68 - 27
FactoryCraft/BlockType.h

@@ -1,48 +1,89 @@
 #pragma once
 
-#include <Vec3.h>
 #include <Array.h>
-#include <Writer.h>
 #include <Either.h>
+#include <Vec3.h>
+#include <Writer.h>
 
-#include "StaticRegistry.h"
 #include "ModelInfo.h"
+#include "StaticRegistry.h"
 
 class Item;
 class Block;
 
+class BlockTypeEnum
+{
+public:
+    static const int NO_BLOCK = 0;
+    static const int AIR = 1;
+    static const int DIRT = 2;
+    static const int SAND = 3;
+    static const int GRAVEL = 4;
+    static const int STONE = 5;
+    static const int STONE_GRANITE = 6;
+    static const int STONE_COBBLE = 7;
+    static const int STONE_BASALT = 8;
+    static const int WOOD_OAK = 9;
+    static const int WOOD_BIRCH = 10;
+    static const int WOOD_BEECH = 11;
+    static const int WOOD_PINE = 12;
+    static const int LEAVES_WOOD_OAK = 13;
+    static const int LEAVES_WOOD_BIRCH = 14;
+    static const int LEAVES_WOOD_BEECH = 15;
+    static const int LEAVES_WOOD_PINE = 16;
+    static const int SEBLING_WOOD_OAK = 17;
+    static const int SEBLING_WOOD_BIRCH = 18;
+    static const int SEBLING_WOOD_BEECH = 19;
+    static const int SEBLING_WOOD_PINE = 20;
+    static const int TORCH = 21;
+
+	static const int MAX_VALUE = 21;
+};
+
 class BlockType : public virtual Framework::ReferenceCounter
 {
 private:
-	const int id;
-	const ModelInfo model;
-	int initialMaxHP;
-	const bool needsClientInstance;
-	bool lightSource;
+    const int id;
+    const ModelInfo model;
+    int initialMaxHP;
+    const bool needsClientInstance;
+    bool lightSource;
 
 protected:
-	Block* defaultBlock;
-	BlockType(int id, Block* defaultBlock, ModelInfo model, bool needsClientInstance, int initialMaxHP, bool lightSource);
-	virtual ~BlockType();
+    Block* defaultBlock;
+    BlockType(int id,
+        Block* defaultBlock,
+        ModelInfo model,
+        bool needsClientInstance,
+        int initialMaxHP,
+        bool lightSource);
+    virtual ~BlockType();
 
-	virtual void loadSuperBlock(Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const;
-	virtual void saveSuperBlock(Block* zBlock, Framework::StreamWriter* zWriter) const;
-	virtual void createSuperBlock(Block* zBlock, Item* zItem) const;
-	virtual void createSuperItem(Block* zBlock, Item* zItem) const;
-	virtual Block* createBlock(Framework::Vec3<int> position) const = 0;
-	virtual Item* createItem() const = 0;
+    virtual void loadSuperBlock(
+        Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const;
+    virtual void saveSuperBlock(
+        Block* zBlock, Framework::StreamWriter* zWriter) const;
+    virtual void createSuperBlock(Block* zBlock, Item* zItem) const;
+    virtual void createSuperItem(Block* zBlock, Item* zItem) const;
+    virtual Block* createBlock(Framework::Vec3<int> position) const = 0;
+    virtual Item* createItem() const = 0;
 
 public:
-	virtual Block* loadBlock(Framework::Vec3<int> position, Framework::StreamReader* zReader, int dimensionId) const;
-	virtual void saveBlock(Block* zBlock, Framework::StreamWriter* zWriter) const;
-	virtual Item* getItemFromBlock(Block* zBlock) const;
-	virtual Block* createBlockAt(Framework::Vec3<int> position, Item* zUsedItem) const;
-	virtual const Block* zDefault() const;
-	bool doesNeedClientInstance() const;
-	const ModelInfo& getModel() const;
-	int getId() const;
-	int getInitialMaxHP() const;
-	bool isLightSource() const;
+    virtual Block* loadBlock(Framework::Vec3<int> position,
+        Framework::StreamReader* zReader,
+        int dimensionId) const;
+    virtual void saveBlock(
+        Block* zBlock, Framework::StreamWriter* zWriter) const;
+    virtual Item* getItemFromBlock(Block* zBlock) const;
+    virtual Block* createBlockAt(
+        Framework::Vec3<int> position, Item* zUsedItem) const;
+    virtual const Block* zDefault() const;
+    bool doesNeedClientInstance() const;
+    const ModelInfo& getModel() const;
+    int getId() const;
+    int getInitialMaxHP() const;
+    bool isLightSource() const;
+    BlockType* initializeDefault();
 };
 
 const Block* getDefaultBlock(Framework::Either<Block*, int> b);

+ 10 - 7
FactoryCraft/Chunk.cpp

@@ -84,7 +84,8 @@ void Chunk::sendLightToClient(Framework::StreamWriter* zWriter)
 						{
 							int bi = (pos.x * CHUNK_SIZE + pos.y) * WORLD_HEIGHT + pos.z;
 							int type = blockIds[bi];
-							needSend |= type != NoBlockBlockType::ID && type != AirBlockBlockType::ID;
+                            needSend |= type != BlockTypeEnum::NO_BLOCK
+                                     && type != BlockTypeEnum::AIR;
 						}
 						else
 						{
@@ -93,7 +94,8 @@ void Chunk::sendLightToClient(Framework::StreamWriter* zWriter)
 								Vec3<int> offset = getDirection(getDirectionFromIndex(i)) * 16;
 								int bi = ((pos.x - offset.x) * CHUNK_SIZE + (pos.y - offset.y)) * WORLD_HEIGHT + (pos.z - offset.z);
 								int type = zNeighbours[i]->blockIds[bi];
-								needSend |= type != NoBlockBlockType::ID && type != AirBlockBlockType::ID;
+                                needSend |= type != BlockTypeEnum::NO_BLOCK
+                                         && type != BlockTypeEnum::AIR;
 							}
 						}
 						if (needSend)
@@ -361,7 +363,8 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
 			char* msg = new char[9];
 			msg[0] = 0; // set block
 			*(int*)(msg + 1) = index;
-			*(int*)(msg + 5) = block ? block->zBlockType()->getId() : NoBlockBlockType::ID;
+            *(int*)(msg + 5)
+                = block ? block->zBlockType()->getId() : BlockTypeEnum::NO_BLOCK;
 			NetworkMessage* message = new NetworkMessage();
 			message->addressChunck(this);
 			message->setMessage(msg, 9);
@@ -621,7 +624,7 @@ void Chunk::sendToClient(Framework::StreamWriter* zWriter)
 						else
 							visible = blocks[index]->isVisible();
 					}
-					if (visible && (blocks[index] || blockType != AirBlockBlockType::ID))
+					if (visible && (blocks[index] || blockType != BlockTypeEnum::AIR))
 					{
 						zWriter->schreibe((char*)&blockType, 2);
 						zWriter->schreibe((char*)&index, 4);
@@ -660,14 +663,14 @@ void Chunk::removeUnusedBlocks()
 			if (!visible)
 			{
 				putBlockAt({ x,y,z }, 0);
-				putBlockTypeAt({ x, y, z }, NoBlockBlockType::ID);
+				putBlockTypeAt({ x, y, z }, BlockTypeEnum::NO_BLOCK);
 			}
 		}
 	}
 	int count = 0;
 	for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
 	{
-		if (blockIds[i] && blockIds[i] != AirBlockBlockType::ID)
+		if (blockIds[i] && blockIds[i] != BlockTypeEnum::AIR)
 			count++;
 	}
 	std::cout << "chunk " << location.x << ", " << location.y << " was generated with " << count << " blocks.\n";
@@ -757,7 +760,7 @@ void Chunk::setLightData(Framework::Vec3<int> location, unsigned char* data, boo
 			{
 				int bi = (pos.x * CHUNK_SIZE + pos.y) * WORLD_HEIGHT + pos.z;
 				int type = blockIds[bi];
-				needSend |= type != NoBlockBlockType::ID && type != AirBlockBlockType::ID;
+				needSend |= type != BlockTypeEnum::NO_BLOCK && type != BlockTypeEnum::AIR;
 				if (needSend)
 					break;
 			}

+ 676 - 628
FactoryCraft/Dimension.cpp

@@ -1,4 +1,5 @@
 #include "Dimension.h"
+
 #include "Constants.h"
 #include "Datei.h"
 #include "Game.h"
@@ -6,750 +7,797 @@
 
 using namespace Framework;
 
-
 Dimension::Dimension(int id)
-	: Thread(),
-	nextStructureId(0),
-	dimensionId(id),
-	gravity(9.8f),
-	chunks(new Trie<Chunk>()),
-	entities(new RCArray<Entity>())
+    : Thread(),
+      nextStructureId(0),
+      dimensionId(id),
+      gravity(9.8f),
+      chunks(new Trie<Chunk>()),
+      entities(new RCArray<Entity>())
 {
-	Datei d;
-	d.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(id) + "/nst.id");
-	if (d.existiert())
-	{
-		d.open(Datei::Style::lesen);
-		d.lese((char*)&nextStructureId, 8);
-		d.close();
-	}
-	start();
+    Datei d;
+    d.setDatei(
+        Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(id) + "/nst.id");
+    if (d.existiert())
+    {
+        d.open(Datei::Style::lesen);
+        d.lese((char*)&nextStructureId, 8);
+        d.close();
+    }
+    start();
 }
 
 Dimension::~Dimension()
 {
-	entities->release();
-	chunks->release();
+    entities->release();
+    chunks->release();
 }
 
-void Dimension::api(Framework::InMemoryBuffer* zRequest, NetworkMessage* zResponse, Entity* zSource)
+void Dimension::api(Framework::InMemoryBuffer* zRequest,
+    NetworkMessage* zResponse,
+    Entity* zSource)
 {
-	DoLaterHandler laterHandler;
-	char type;
-	zRequest->lese(&type, 1);
-	switch (type)
-	{
-	case 0: // chunk message
-	{
-		Punkt center;
-		zRequest->lese((char*)&center.x, 4);
-		zRequest->lese((char*)&center.y, 4);
-		cs.lock();
-		Chunk* cC = zChunk(center);
-		if (!cC)
-		{
-			// TODO: have a max amount of waiting requests per player
-			waitingRequests.add({ dynamic_cast<InMemoryBuffer*>(zRequest->getThis()), center, zSource->getId() });
-			Game::INSTANCE->requestArea({ center.x - CHUNK_SIZE / 2, center.y - CHUNK_SIZE / 2, center.x + CHUNK_SIZE / 2 - 1, center.y + CHUNK_SIZE / 2 - 1, dimensionId });
-		}
-		else
-		{
-			cC->api(zRequest, zSource, laterHandler);
-		}
-		cs.unlock();
-		break;
-	}
-	}
+    DoLaterHandler laterHandler;
+    char type;
+    zRequest->lese(&type, 1);
+    switch (type)
+    {
+    case 0: // chunk message
+        {
+            Punkt center;
+            zRequest->lese((char*)&center.x, 4);
+            zRequest->lese((char*)&center.y, 4);
+            cs.lock();
+            Chunk* cC = zChunk(center);
+            if (!cC)
+            {
+                // TODO: have a max amount of waiting requests per player
+                waitingRequests.add(
+                    {dynamic_cast<InMemoryBuffer*>(zRequest->getThis()),
+                        center,
+                        zSource->getId()});
+                Game::INSTANCE->requestArea({center.x - CHUNK_SIZE / 2,
+                    center.y - CHUNK_SIZE / 2,
+                    center.x + CHUNK_SIZE / 2 - 1,
+                    center.y + CHUNK_SIZE / 2 - 1,
+                    dimensionId});
+            }
+            else
+            {
+                cC->api(zRequest, zSource, laterHandler);
+            }
+            cs.unlock();
+            break;
+        }
+    }
 }
 
 void Dimension::tickEntities()
 {
-	for (auto entity : *entities)
-	{
-		if (!entity->isRemoved() && (entity->isMoving() || zChunk(Punkt((int)entity->getPosition().x, (int)entity->getPosition().y))))
-			entity->prepareTick(this);
-	}
-	int index = 0;
-	for (auto entity : *entities)
-	{
-		if (!entity->isRemoved() && (entity->isMoving() || zChunk(Punkt((int)entity->getPosition().x, (int)entity->getPosition().y))))
-			entity->tick(this);
-		index++;
-	}
+    for (auto entity : *entities)
+    {
+        if (!entity->isRemoved()
+            && (entity->isMoving()
+                || zChunk(Punkt((int)entity->getPosition().x,
+                    (int)entity->getPosition().y))))
+            entity->prepareTick(this);
+    }
+    int index = 0;
+    for (auto entity : *entities)
+    {
+        if (!entity->isRemoved()
+            && (entity->isMoving()
+                || zChunk(Punkt((int)entity->getPosition().x,
+                    (int)entity->getPosition().y))))
+            entity->tick(this);
+        index++;
+    }
 }
 
 void Dimension::thread()
 {
-	// light calculation
-	int index = 0;
-	ZeitMesser messer;
-	messer.messungStart();
-	double time = 0;
-	bool isForeground = 0;
-	Framework::Array<Framework::Vec3<int>> internalLightUpdateQueue;
-	while (true)
-	{
-		Vec3<int> position;
-		if (internalLightUpdateQueue.getEintragAnzahl())
-		{
-			position = internalLightUpdateQueue.get(0);
-			internalLightUpdateQueue.remove(0);
-		}
-		else
-		{
-			removedChunksCs.lock();
-			if (removedChunks.getEintragAnzahl() > 0)
-			{
-				Chunk* removedChunk = removedChunks.z(0);
-				removedChunksCs.unlock();
-				Text filePath = Game::INSTANCE->getWorldDirectory() + "/dim/" + getDimensionId() + "/";
-				filePath.appendHex(removedChunk->getCenter().x);
-				filePath += "_";
-				filePath.appendHex(removedChunk->getCenter().y);
-				filePath += ".chunk";
-				Datei d;
-				d.setDatei(filePath);
-				d.erstellen();
-				d.open(Datei::Style::schreiben);
-				removedChunk->save(&d);
-				d.close();
-				removedChunksCs.lock();
-				removedChunks.remove(0);
-			}
-			removedChunksCs.unlock();
-			if (priorizedLightUpdateQueue.getEintragAnzahl())
-			{
-				prioLightCs.lock();
-				position = priorizedLightUpdateQueue.get(0);
-				priorizedLightUpdateQueue.remove(0);
-				prioLightCs.unlock();
-				isForeground = 1;
-			}
-			else
-			{
-				if (!lightUpdateQueue.getEintragAnzahl())
-				{
-					messer.messungEnde();
-					time += messer.getSekunden();
-					Sleep(500);
-					messer.messungStart();
-					continue;
-				}
-				lightCs.lock();
-				position = lightUpdateQueue.get(0);
-				lightUpdateQueue.remove(0);
-				lightCs.unlock();
-				isForeground = 0;
-			}
-		}
-		Chunk* chunk = zChunk(Game::INSTANCE->getChunkCenter(position.x, position.y));
-		if (position.z >= 0 && position.z < WORLD_HEIGHT)
-		{
-			if (chunk)
-			{
-				int x = position.x % CHUNK_SIZE;
-				int y = position.y % CHUNK_SIZE;
-				if (x < 0)
-					x += CHUNK_SIZE;
-				if (y < 0)
-					y += CHUNK_SIZE;
-				unsigned char* light = chunk->getLightData(Vec3<int>(x, y, position.z));
-				unsigned char dayLight[6] = { 255, 255, 255, 0, 0, 0 };
-				unsigned char noLight[6] = { 0, 0, 0, 0, 0, 0 };
-				unsigned char newLight[6] = { 0, 0, 0, 0, 0, 0 };
-				// add neighbor light emission
-				for (int i = 0; i < 6; i++)
-				{
-					unsigned char* neighborLeight;
-					Vec3<int> neighborPos = position + getDirection(getDirectionFromIndex(i));
-					if (neighborPos.z < 0)
-					{
-						neighborLeight = noLight;
-					}
-					else if (neighborPos.z >= WORLD_HEIGHT)
-					{
-						neighborLeight = dayLight;
-					}
-					else
-					{
-						Chunk* neighborChunk = zChunk(Game::INSTANCE->getChunkCenter(neighborPos.x, neighborPos.y));
-						int x = neighborPos.x % CHUNK_SIZE;
-						int y = neighborPos.y % CHUNK_SIZE;
-						if (x < 0)
-							x += CHUNK_SIZE;
-						if (y < 0)
-							y += CHUNK_SIZE;
-						if (neighborChunk)
-							neighborLeight = neighborChunk->getLightData(Vec3<int>(x, y, neighborPos.z));
-						else
-							neighborLeight = noLight;
-					}
-					for (int j = 0; j < 3; j++)
-						newLight[j] = (unsigned char)MAX(newLight[j], i == getDirectionIndex(TOP) ? neighborLeight[j] : (unsigned char)((float)neighborLeight[j] * 0.8f));
-					for (int j = 3; j < 6; j++)
-						newLight[j] = (unsigned char)MAX(newLight[j], (unsigned char)((float)neighborLeight[j] * 0.85f));
-				}
-				const Block* current = zBlockOrDefault(position);
-				if (!current)
-					current = &NoBlock::INSTANCE;
-				// add own light emission
-				for (int j = 3; j < 6; j++)
-					newLight[j] = (unsigned char)MAX(newLight[j], current->getLightEmisionColor()[j - 3]);
-				current->filterPassingLight(newLight);
-				current->filterPassingLight(newLight + 3);
-				for (int i = 0; i < 6; i++)
-				{
-					if (newLight[i] != light[i])
-					{
-						chunk->setLightData(Vec3<int>(x, y, position.z), newLight, isForeground);
-						for (int j = 0; j < 6; j++)
-							internalLightUpdateQueue.add(position + getDirection(getDirectionFromIndex(j)), 0);
-						break;
-					}
-				}
-			}
-		}
-		index++;
-		if (index > 100000)
-		{
-			messer.messungEnde();
-			time += messer.getSekunden();
-			std::cout << "100000 light updates needed " << time << " seconds\n";
-			time = 0;
-			index = 0;
-			Sleep(250);
-			messer.messungStart();
-		}
-	}
+    // light calculation
+    int index = 0;
+    ZeitMesser messer;
+    messer.messungStart();
+    double time = 0;
+    bool isForeground = 0;
+    Framework::Array<Framework::Vec3<int>> internalLightUpdateQueue;
+    while (true)
+    {
+        Vec3<int> position;
+        if (internalLightUpdateQueue.getEintragAnzahl())
+        {
+            position = internalLightUpdateQueue.get(0);
+            internalLightUpdateQueue.remove(0);
+        }
+        else
+        {
+            removedChunksCs.lock();
+            if (removedChunks.getEintragAnzahl() > 0)
+            {
+                Chunk* removedChunk = removedChunks.z(0);
+                removedChunksCs.unlock();
+                Text filePath = Game::INSTANCE->getWorldDirectory() + "/dim/"
+                              + getDimensionId() + "/";
+                filePath.appendHex(removedChunk->getCenter().x);
+                filePath += "_";
+                filePath.appendHex(removedChunk->getCenter().y);
+                filePath += ".chunk";
+                Datei d;
+                d.setDatei(filePath);
+                d.erstellen();
+                d.open(Datei::Style::schreiben);
+                removedChunk->save(&d);
+                d.close();
+                removedChunksCs.lock();
+                removedChunks.remove(0);
+            }
+            removedChunksCs.unlock();
+            if (priorizedLightUpdateQueue.getEintragAnzahl())
+            {
+                prioLightCs.lock();
+                position = priorizedLightUpdateQueue.get(0);
+                priorizedLightUpdateQueue.remove(0);
+                prioLightCs.unlock();
+                isForeground = 1;
+            }
+            else
+            {
+                if (!lightUpdateQueue.getEintragAnzahl())
+                {
+                    messer.messungEnde();
+                    time += messer.getSekunden();
+                    Sleep(500);
+                    messer.messungStart();
+                    continue;
+                }
+                lightCs.lock();
+                position = lightUpdateQueue.get(0);
+                lightUpdateQueue.remove(0);
+                lightCs.unlock();
+                isForeground = 0;
+            }
+        }
+        Chunk* chunk
+            = zChunk(Game::INSTANCE->getChunkCenter(position.x, position.y));
+        if (position.z >= 0 && position.z < WORLD_HEIGHT)
+        {
+            if (chunk)
+            {
+                int x = position.x % CHUNK_SIZE;
+                int y = position.y % CHUNK_SIZE;
+                if (x < 0) x += CHUNK_SIZE;
+                if (y < 0) y += CHUNK_SIZE;
+                unsigned char* light
+                    = chunk->getLightData(Vec3<int>(x, y, position.z));
+                unsigned char dayLight[6] = {255, 255, 255, 0, 0, 0};
+                unsigned char noLight[6] = {0, 0, 0, 0, 0, 0};
+                unsigned char newLight[6] = {0, 0, 0, 0, 0, 0};
+                // add neighbor light emission
+                for (int i = 0; i < 6; i++)
+                {
+                    unsigned char* neighborLeight;
+                    Vec3<int> neighborPos
+                        = position + getDirection(getDirectionFromIndex(i));
+                    if (neighborPos.z < 0)
+                    {
+                        neighborLeight = noLight;
+                    }
+                    else if (neighborPos.z >= WORLD_HEIGHT)
+                    {
+                        neighborLeight = dayLight;
+                    }
+                    else
+                    {
+                        Chunk* neighborChunk
+                            = zChunk(Game::INSTANCE->getChunkCenter(
+                                neighborPos.x, neighborPos.y));
+                        int x = neighborPos.x % CHUNK_SIZE;
+                        int y = neighborPos.y % CHUNK_SIZE;
+                        if (x < 0) x += CHUNK_SIZE;
+                        if (y < 0) y += CHUNK_SIZE;
+                        if (neighborChunk)
+                            neighborLeight = neighborChunk->getLightData(
+                                Vec3<int>(x, y, neighborPos.z));
+                        else
+                            neighborLeight = noLight;
+                    }
+                    for (int j = 0; j < 3; j++)
+                        newLight[j] = (unsigned char)MAX(newLight[j],
+                            i == getDirectionIndex(TOP)
+                                ? neighborLeight[j]
+                                : (unsigned char)((float)neighborLeight[j]
+                                                  * 0.8f));
+                    for (int j = 3; j < 6; j++)
+                        newLight[j] = (unsigned char)MAX(newLight[j],
+                            (unsigned char)((float)neighborLeight[j] * 0.85f));
+                }
+                const Block* current = zBlockOrDefault(position);
+                if (!current) current = &NoBlock::INSTANCE;
+                // add own light emission
+                for (int j = 3; j < 6; j++)
+                    newLight[j] = (unsigned char)MAX(
+                        newLight[j], current->getLightEmisionColor()[j - 3]);
+                current->filterPassingLight(newLight);
+                current->filterPassingLight(newLight + 3);
+                for (int i = 0; i < 6; i++)
+                {
+                    if (newLight[i] != light[i])
+                    {
+                        chunk->setLightData(Vec3<int>(x, y, position.z),
+                            newLight,
+                            isForeground);
+                        for (int j = 0; j < 6; j++)
+                            internalLightUpdateQueue.add(
+                                position
+                                    + getDirection(getDirectionFromIndex(j)),
+                                0);
+                        break;
+                    }
+                }
+            }
+        }
+        index++;
+        if (index > 100000)
+        {
+            messer.messungEnde();
+            time += messer.getSekunden();
+            std::cout << "100000 light updates needed " << time << " seconds\n";
+            time = 0;
+            index = 0;
+            Sleep(250);
+            messer.messungStart();
+        }
+    }
 }
 
 void Dimension::getAddrOf(Punkt cPos, char* addr) const
 {
-	*(int*)addr = cPos.x;
-	*((int*)addr + 1) = cPos.y;
+    *(int*)addr = cPos.x;
+    *((int*)addr + 1) = cPos.y;
 }
 
 void Dimension::getAddrOfWorld(Punkt wPos, char* addr) const
 {
-	if (wPos.x < 0)
-		wPos.x -= CHUNK_SIZE;
-	if (wPos.y < 0) // needed because otherwise would (-8, -8) have the same adress as (8, 8)
-		wPos.y -= CHUNK_SIZE;
-	wPos /= CHUNK_SIZE;
-	getAddrOf(wPos, addr);
+    if (wPos.x < 0) wPos.x -= CHUNK_SIZE;
+    if (wPos.y < 0) // needed because otherwise would (-8, -8) have the same
+                    // adress as (8, 8)
+        wPos.y -= CHUNK_SIZE;
+    wPos /= CHUNK_SIZE;
+    getAddrOf(wPos, addr);
 }
 
 Chunk* Dimension::zChunk(Punkt wPos) const
 {
-	char addr[8];
-	getAddrOfWorld(wPos, addr);
-	return chunks->z(addr, 8);
+    char addr[8];
+    getAddrOfWorld(wPos, addr);
+    return chunks->z(addr, 8);
 }
 
 Framework::Either<Block*, int> Dimension::zBlock(Vec3<int> location)
 {
-	Chunk* c = zChunk(Game::INSTANCE->getChunkCenter(location.x, location.y));
-	if (c)
-	{
-		int x = location.x % CHUNK_SIZE;
-		int y = location.y % CHUNK_SIZE;
-		if (x < 0)
-			x += CHUNK_SIZE;
-		if (y < 0)
-			y += CHUNK_SIZE;
-		return c->zBlockAt(Vec3<int>(x, y, location.z));
-	}
-	return 0;
+    Chunk* c = zChunk(Game::INSTANCE->getChunkCenter(location.x, location.y));
+    if (c)
+    {
+        int x = location.x % CHUNK_SIZE;
+        int y = location.y % CHUNK_SIZE;
+        if (x < 0) x += CHUNK_SIZE;
+        if (y < 0) y += CHUNK_SIZE;
+        return c->zBlockAt(Vec3<int>(x, y, location.z));
+    }
+    return 0;
 }
 
 Block* Dimension::zRealBlockInstance(Framework::Vec3<int> location)
 {
-	Chunk* c = zChunk(Game::INSTANCE->getChunkCenter(location.x, location.y));
-	if (c)
-	{
-		int x = location.x % CHUNK_SIZE;
-		int y = location.y % CHUNK_SIZE;
-		if (x < 0)
-			x += CHUNK_SIZE;
-		if (y < 0)
-			y += CHUNK_SIZE;
-		c->instantiateBlock(Vec3<int>(x, y, location.z));
-		auto result = c->zBlockAt(Vec3<int>(x, y, location.z));
-		return result.isA() ? result.getA() : 0;
-	}
-	return 0;
+    Chunk* c = zChunk(Game::INSTANCE->getChunkCenter(location.x, location.y));
+    if (c)
+    {
+        int x = location.x % CHUNK_SIZE;
+        int y = location.y % CHUNK_SIZE;
+        if (x < 0) x += CHUNK_SIZE;
+        if (y < 0) y += CHUNK_SIZE;
+        c->instantiateBlock(Vec3<int>(x, y, location.z));
+        auto result = c->zBlockAt(Vec3<int>(x, y, location.z));
+        return result.isA() ? result.getA() : 0;
+    }
+    return 0;
 }
 
 const Block* Dimension::zBlockOrDefault(Framework::Vec3<int> location)
 {
-	Chunk* c = zChunk(Game::INSTANCE->getChunkCenter(location.x, location.y));
-	if (c)
-	{
-		int x = location.x % CHUNK_SIZE;
-		int y = location.y % CHUNK_SIZE;
-		if (x < 0)
-			x += CHUNK_SIZE;
-		if (y < 0)
-			y += CHUNK_SIZE;
-		return c->zBlockConst(Vec3<int>(x, y, location.z));
-	}
-	return 0;
+    Chunk* c = zChunk(Game::INSTANCE->getChunkCenter(location.x, location.y));
+    if (c)
+    {
+        int x = location.x % CHUNK_SIZE;
+        int y = location.y % CHUNK_SIZE;
+        if (x < 0) x += CHUNK_SIZE;
+        if (y < 0) y += CHUNK_SIZE;
+        return c->zBlockConst(Vec3<int>(x, y, location.z));
+    }
+    return 0;
 }
 
-void Dimension::placeBlock(Framework::Vec3<int> location, Framework::Either<Block*, int> block)
+void Dimension::placeBlock(
+    Framework::Vec3<int> location, Framework::Either<Block*, int> block)
 {
-	Chunk* c = zChunk(Game::getChunkCenter(location.x, location.y));
-	if (c)
-	{
-		int x = location.x % CHUNK_SIZE;
-		int y = location.y % CHUNK_SIZE;
-		if (x < 0)
-			x += CHUNK_SIZE;
-		if (y < 0)
-			y += CHUNK_SIZE;
-		if (block.isA())
-			c->putBlockAt(Vec3<int>(x, y, location.z), block);
-		else
-		{
-			c->putBlockAt(Vec3<int>(x, y, location.z), 0);
-			c->putBlockTypeAt(Vec3<int>(x, y, location.z), block);
-		}
-	}
-	else if (block.isA())
-		block.getA()->release();
+    Chunk* c = zChunk(Game::getChunkCenter(location.x, location.y));
+    if (c)
+    {
+        int x = location.x % CHUNK_SIZE;
+        int y = location.y % CHUNK_SIZE;
+        if (x < 0) x += CHUNK_SIZE;
+        if (y < 0) y += CHUNK_SIZE;
+        if (block.isA())
+            c->putBlockAt(Vec3<int>(x, y, location.z), block);
+        else
+        {
+            c->putBlockAt(Vec3<int>(x, y, location.z), 0);
+            c->putBlockTypeAt(Vec3<int>(x, y, location.z), block);
+        }
+    }
+    else if (block.isA())
+        block.getA()->release();
 }
 
 void Dimension::addEntity(Entity* entity)
 {
-	entities->add(entity);
+    entities->add(entity);
 }
 
 void Dimension::setChunk(Chunk* chunk, Punkt center)
 {
-	chunkCs.lock();
-	char addr[8];
-	getAddrOfWorld(center, addr);
-	Chunk* old = chunks->get(addr, 8);
-	if (old)
-	{
-		old->prepareRemove();
-		for (int i = 0; i < chunkList.getEintragAnzahl(); i++)
-		{
-			if (chunkList.get(i) == old)
-			{
-				chunkList.remove(i);
-				break;
-			}
-		}
-	}
-	chunks->set(addr, 8, chunk);
-	if (chunk)
-	{
-		chunkList.add(chunk);
-		chunk->setAdded();
-	}
-	getAddrOfWorld(center + Punkt(CHUNK_SIZE, 0), addr);
-	Chunk* zChunk = chunks->z(addr, 8);
-	if (zChunk)
-	{
-		zChunk->setNeighbor(WEST, chunk);
-		if (chunk)
-		{
-			chunk->setNeighbor(EAST, zChunk);
-		}
-	}
-	getAddrOfWorld(center + Punkt(-CHUNK_SIZE, 0), addr);
-	zChunk = chunks->z(addr, 8);
-	if (zChunk)
-	{
-		zChunk->setNeighbor(EAST, chunk);
-		if (chunk)
-			chunk->setNeighbor(WEST, zChunk);
-	}
-	getAddrOfWorld(center + Punkt(0, CHUNK_SIZE), addr);
-	zChunk = chunks->z(addr, 8);
-	if (zChunk)
-	{
-		zChunk->setNeighbor(NORTH, chunk);
-		if (chunk)
-			chunk->setNeighbor(SOUTH, zChunk);
-	}
-	getAddrOfWorld(center + Punkt(0, -CHUNK_SIZE), addr);
-	zChunk = chunks->z(addr, 8);
-	if (zChunk)
-	{
-		zChunk->setNeighbor(SOUTH, chunk);
-		if (chunk)
-			chunk->setNeighbor(NORTH, zChunk);
-	}
-	DoLaterHandler laterHandler;
-	if (chunk)
-	{
-		cs.lock();
-		int index = 0;
-		for (Iterator<RequestQueue> iterator = waitingRequests.begin(); iterator; )
-		{
-			Entity* zE = Game::INSTANCE->zEntity(iterator.val().sourceId);
-			if (zE)
-			{
-				if (iterator.val().chunkCenter == chunk->getCenter())
-				{
-					chunk->api(iterator.val().request, zE, laterHandler);
-					iterator.val().request->release();
-					iterator.remove();
-					continue;
-				}
-			}
-			else
-			{
-				iterator.val().request->release();
-				iterator.remove();
-				continue;
-			}
-			iterator++;
-			index++;
-		}
-		cs.unlock();
-	}
-	chunkCs.unlock();
-	if (old)
-	{
-		old->onUnloaded();
-		removedChunksCs.lock();
-		removedChunks.add(old);
-		removedChunksCs.unlock();
-	}
-	if (chunk)
-		chunk->onLoaded();
-	updateLightAtChunkBorders(center);
+    chunkCs.lock();
+    char addr[8];
+    getAddrOfWorld(center, addr);
+    Chunk* old = chunks->get(addr, 8);
+    if (old)
+    {
+        old->prepareRemove();
+        for (int i = 0; i < chunkList.getEintragAnzahl(); i++)
+        {
+            if (chunkList.get(i) == old)
+            {
+                chunkList.remove(i);
+                break;
+            }
+        }
+    }
+    chunks->set(addr, 8, chunk);
+    if (chunk)
+    {
+        chunkList.add(chunk);
+        chunk->setAdded();
+    }
+    getAddrOfWorld(center + Punkt(CHUNK_SIZE, 0), addr);
+    Chunk* zChunk = chunks->z(addr, 8);
+    if (zChunk)
+    {
+        zChunk->setNeighbor(WEST, chunk);
+        if (chunk)
+        {
+            chunk->setNeighbor(EAST, zChunk);
+        }
+    }
+    getAddrOfWorld(center + Punkt(-CHUNK_SIZE, 0), addr);
+    zChunk = chunks->z(addr, 8);
+    if (zChunk)
+    {
+        zChunk->setNeighbor(EAST, chunk);
+        if (chunk) chunk->setNeighbor(WEST, zChunk);
+    }
+    getAddrOfWorld(center + Punkt(0, CHUNK_SIZE), addr);
+    zChunk = chunks->z(addr, 8);
+    if (zChunk)
+    {
+        zChunk->setNeighbor(NORTH, chunk);
+        if (chunk) chunk->setNeighbor(SOUTH, zChunk);
+    }
+    getAddrOfWorld(center + Punkt(0, -CHUNK_SIZE), addr);
+    zChunk = chunks->z(addr, 8);
+    if (zChunk)
+    {
+        zChunk->setNeighbor(SOUTH, chunk);
+        if (chunk) chunk->setNeighbor(NORTH, zChunk);
+    }
+    DoLaterHandler laterHandler;
+    if (chunk)
+    {
+        cs.lock();
+        int index = 0;
+        for (Iterator<RequestQueue> iterator = waitingRequests.begin();
+             iterator;)
+        {
+            Entity* zE = Game::INSTANCE->zEntity(iterator.val().sourceId);
+            if (zE)
+            {
+                if (iterator.val().chunkCenter == chunk->getCenter())
+                {
+                    chunk->api(iterator.val().request, zE, laterHandler);
+                    iterator.val().request->release();
+                    iterator.remove();
+                    continue;
+                }
+            }
+            else
+            {
+                iterator.val().request->release();
+                iterator.remove();
+                continue;
+            }
+            iterator++;
+            index++;
+        }
+        cs.unlock();
+    }
+    chunkCs.unlock();
+    if (old)
+    {
+        old->onUnloaded();
+        removedChunksCs.lock();
+        removedChunks.add(old);
+        removedChunksCs.unlock();
+    }
+    if (chunk) chunk->onLoaded();
+    updateLightAtChunkBorders(center);
 }
 
 void Dimension::save(Text worldDir) const
 {
-	Datei d;
-	d.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(dimensionId) + "/nst.id");
-	d.erstellen();
-	d.open(Datei::Style::schreiben);
-	d.schreibe((char*)&nextStructureId, 8);
-	d.close();
-	for (auto chunk = chunks->getIterator(); chunk; chunk++)
-	{
-		if (!chunk._)
-			continue;
-		Datei* file = new Datei();
-		Text filePath = worldDir + "/dim/" + dimensionId + "/";
-		filePath.appendHex(chunk->getCenter().x);
-		filePath += "_";
-		filePath.appendHex(chunk->getCenter().y);
-		filePath += ".chunk";
-		file->setDatei(filePath);
-		if (file->open(Datei::Style::schreiben))
-			chunk->save(file);
-		file->close();
-		file->release();
-	}
-	Text filePath = worldDir + "/dim/" + dimensionId + "/entities";
-	Datei* file = new Datei();
-	file->setDatei(filePath);
-	if (file->open(Datei::Style::schreiben))
-	{
-		for (Entity* entity : *entities)
-		{
-			if (entity->zType()->getId() != PlayerEntityType::ID)
-			{
-				if (!entity->isRemoved())
-				{
-					int type = entity->zType()->getId();
-					file->schreibe((char*)&type, 4);
-					StaticRegistry<EntityType>::INSTANCE.zElement(type)->saveEntity(entity, file);
-				}
-			}
-			else
-			{
-				Datei pFile;
-				pFile.setDatei(worldDir + "/player/" + ((Player*)entity)->getName());
-				if (pFile.open(Datei::Style::schreiben))
-					PlayerEntityType::INSTANCE->saveEntity(entity, &pFile);
-			}
-		}
-		file->close();
-	}
+    Datei d;
+    d.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(dimensionId)
+               + "/nst.id");
+    d.erstellen();
+    d.open(Datei::Style::schreiben);
+    d.schreibe((char*)&nextStructureId, 8);
+    d.close();
+    for (auto chunk = chunks->getIterator(); chunk; chunk++)
+    {
+        if (!chunk._) continue;
+        Datei* file = new Datei();
+        Text filePath = worldDir + "/dim/" + dimensionId + "/";
+        filePath.appendHex(chunk->getCenter().x);
+        filePath += "_";
+        filePath.appendHex(chunk->getCenter().y);
+        filePath += ".chunk";
+        file->setDatei(filePath);
+        if (file->open(Datei::Style::schreiben)) chunk->save(file);
+        file->close();
+        file->release();
+    }
+    Text filePath = worldDir + "/dim/" + dimensionId + "/entities";
+    Datei* file = new Datei();
+    file->setDatei(filePath);
+    if (file->open(Datei::Style::schreiben))
+    {
+        for (Entity* entity : *entities)
+        {
+            if (entity->zType()->getId() != EntityTypeEnum::PLAYER)
+            {
+                if (!entity->isRemoved())
+                {
+                    int type = entity->zType()->getId();
+                    file->schreibe((char*)&type, 4);
+                    StaticRegistry<EntityType>::INSTANCE.zElement(type)
+                        ->saveEntity(entity, file);
+                }
+            }
+            else
+            {
+                Datei pFile;
+                pFile.setDatei(
+                    worldDir + "/player/" + ((Player*)entity)->getName());
+                if (pFile.open(Datei::Style::schreiben))
+                    StaticRegistry<EntityType>::INSTANCE
+                        .zElement(EntityTypeEnum::PLAYER)
+                        ->saveEntity(entity, &pFile);
+            }
+        }
+        file->close();
+    }
 }
 
 int Dimension::getDimensionId() const
 {
-	return dimensionId;
+    return dimensionId;
 }
 
 bool Dimension::hasChunck(int x, int y)
 {
-	if (zChunk(Punkt(x, y)))
-		return 1;
-	removedChunksCs.lock();
-	for (Chunk* c : removedChunks)
-	{
-		if (c->getCenter().x == x && c->getCenter().y == y)
-		{
-			removedChunksCs.unlock();
-			return 1;
-		}
-	}
-	removedChunksCs.unlock();
-	return 0;
+    if (zChunk(Punkt(x, y))) return 1;
+    removedChunksCs.lock();
+    for (Chunk* c : removedChunks)
+    {
+        if (c->getCenter().x == x && c->getCenter().y == y)
+        {
+            removedChunksCs.unlock();
+            return 1;
+        }
+    }
+    removedChunksCs.unlock();
+    return 0;
 }
 
 bool Dimension::reviveChunk(int x, int y)
 {
-	chunkCs.lock();
-	if (zChunk(Punkt(x, y)))
-	{
-		chunkCs.unlock();
-		return 1;
-	}
-	removedChunksCs.lock();
-	int index = 0;
-	for (Iterator<Chunk*> i = removedChunks.begin(); i; i++)
-	{
-		if (i->getCenter().x == x && i->getCenter().y == y)
-		{
-			setChunk(dynamic_cast<Chunk*>(i->getThis()), Punkt(x, y));
-			if (index > 0)
-				i.remove();
-			removedChunksCs.unlock();
-			chunkCs.unlock();
-			return 1;
-		}
-		index++;
-	}
-	removedChunksCs.unlock();
-	chunkCs.unlock();
-	return 0;
+    chunkCs.lock();
+    if (zChunk(Punkt(x, y)))
+    {
+        chunkCs.unlock();
+        return 1;
+    }
+    removedChunksCs.lock();
+    int index = 0;
+    for (Iterator<Chunk*> i = removedChunks.begin(); i; i++)
+    {
+        if (i->getCenter().x == x && i->getCenter().y == y)
+        {
+            setChunk(dynamic_cast<Chunk*>(i->getThis()), Punkt(x, y));
+            if (index > 0) i.remove();
+            removedChunksCs.unlock();
+            chunkCs.unlock();
+            return 1;
+        }
+        index++;
+    }
+    removedChunksCs.unlock();
+    chunkCs.unlock();
+    return 0;
 }
 
 float Dimension::getGravity() const
 {
-	return gravity;
+    return gravity;
 }
 
 void Dimension::removeOldChunks()
 {
-	chunkCs.lock();
-	int index = 0;
-	for (Chunk* chunk : chunkList)
-	{
-		if (!chunk->hasObservers())
-			setChunk(0, chunk->getCenter());
-		index++;
-	}
-	chunkCs.unlock();
-	structurCs.lock();
-	Iterator<MultiblockStructure*> i = structures.begin();
-	while (i)
-	{
-		if (i->isEmpty())
-			i.remove();
-		else if (i->isFullyUnloaded())
-		{
-			Datei d;
-			Text path = Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(dimensionId) + "/structures/";
-			path.appendHex(i->getStructureId());
-			path += ".str";
-			d.setDatei(path);
-			d.erstellen();
-			d.open(Datei::Style::schreiben);
-			auto uPos = i->getUniquePosition();
-			d.schreibe((char*)&uPos.x, 4);
-			d.schreibe((char*)&uPos.y, 4);
-			d.schreibe((char*)&uPos.z, 4);
-			int typeId = i->getStructureTypeId();
-			d.schreibe((char*)&typeId, 4);
-			__int64 strId = i->getStructureId();
-			d.schreibe((char*)&strId, 8);
-			StaticRegistry<MultiblockStructureType>::INSTANCE.zElement(i->getStructureTypeId())->saveStructure(i.val(), &d);
-			d.close();
-			i.remove();
-		}
-		i++;
-	}
-	structurCs.unlock();
+    chunkCs.lock();
+    int index = 0;
+    for (Chunk* chunk : chunkList)
+    {
+        if (!chunk->hasObservers()) setChunk(0, chunk->getCenter());
+        index++;
+    }
+    chunkCs.unlock();
+    structurCs.lock();
+    Iterator<MultiblockStructure*> i = structures.begin();
+    while (i)
+    {
+        if (i->isEmpty())
+            i.remove();
+        else if (i->isFullyUnloaded())
+        {
+            Datei d;
+            Text path = Game::INSTANCE->getWorldDirectory() + "/dim/"
+                      + Text(dimensionId) + "/structures/";
+            path.appendHex(i->getStructureId());
+            path += ".str";
+            d.setDatei(path);
+            d.erstellen();
+            d.open(Datei::Style::schreiben);
+            auto uPos = i->getUniquePosition();
+            d.schreibe((char*)&uPos.x, 4);
+            d.schreibe((char*)&uPos.y, 4);
+            d.schreibe((char*)&uPos.z, 4);
+            int typeId = i->getStructureTypeId();
+            d.schreibe((char*)&typeId, 4);
+            __int64 strId = i->getStructureId();
+            d.schreibe((char*)&strId, 8);
+            StaticRegistry<MultiblockStructureType>::INSTANCE
+                .zElement(i->getStructureTypeId())
+                ->saveStructure(i.val(), &d);
+            d.close();
+            i.remove();
+        }
+        i++;
+    }
+    structurCs.unlock();
 }
 
 Entity* Dimension::zEntity(int id)
 {
-	for (auto entity : *entities)
-	{
-		if (!entity->isRemoved() && entity->getId() == id)
-			return entity;
-	}
-	return 0;
+    for (auto entity : *entities)
+    {
+        if (!entity->isRemoved() && entity->getId() == id) return entity;
+    }
+    return 0;
 }
 
-Entity* Dimension::zNearestEntity(Framework::Vec3<float> pos, std::function<bool(Entity*)> filter)
+Entity* Dimension::zNearestEntity(
+    Framework::Vec3<float> pos, std::function<bool(Entity*)> filter)
 {
-	Entity* result = 0;
-	float sqDist = 0;
-	for (auto entity : *entities)
-	{
-		if (!entity->isRemoved() && filter(entity))
-		{
-			float d = pos.abstandSq(entity->getPosition());
-			if (!result || d < sqDist)
-			{
-				result = entity;
-				sqDist = d;
-			}
-		}
-	}
-	return result;
+    Entity* result = 0;
+    float sqDist = 0;
+    for (auto entity : *entities)
+    {
+        if (!entity->isRemoved() && filter(entity))
+        {
+            float d = pos.abstandSq(entity->getPosition());
+            if (!result || d < sqDist)
+            {
+                result = entity;
+                sqDist = d;
+            }
+        }
+    }
+    return result;
 }
 
 void Dimension::removeEntity(int id)
 {
-	int index = 0;
-	for (auto entity : *entities)
-	{
-		if (entity->getId() == id)
-		{
-			entities->remove(index);
-			return;
-		}
-		index++;
-	}
+    int index = 0;
+    for (auto entity : *entities)
+    {
+        if (entity->getId() == id)
+        {
+            entities->remove(index);
+            return;
+        }
+        index++;
+    }
 }
 
 void Dimension::removeSubscriptions(Entity* zEntity)
 {
-	for (Chunk* chunk : chunkList)
-		chunk->removeObserver(zEntity);
+    for (Chunk* chunk : chunkList)
+        chunk->removeObserver(zEntity);
 }
 
 void Dimension::updateLightning(Vec3<int> location)
 {
-	lightCs.lock();
-	lightUpdateQueue.add(location, 0);
-	lightCs.unlock();
+    lightCs.lock();
+    lightUpdateQueue.add(location, 0);
+    lightCs.unlock();
 }
 
 void Dimension::updateLightningWithoutWait(Framework::Vec3<int> location)
 {
-	prioLightCs.lock();
-	priorizedLightUpdateQueue.add(location, 0);
-	prioLightCs.unlock();
+    prioLightCs.lock();
+    priorizedLightUpdateQueue.add(location, 0);
+    prioLightCs.unlock();
 }
 
 void Dimension::updateLightAtChunkBorders(Punkt chunkCenter)
 {
-	if (lightUpdateQueue.getEintragAnzahl() > 300000)
-	{
-		std::cout << "warning: light calculation queue is over 300000 blocks long";
-	}
-	for (int i = WORLD_HEIGHT - 1; i >= 0; i--)
-	{
-		for (int j = 0; j < CHUNK_SIZE; j++)
-		{
-			updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 - 1, chunkCenter.y - CHUNK_SIZE / 8 + j, i));
-			updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8, chunkCenter.y - CHUNK_SIZE / 8 + j, i));
-			updateLightning(Vec3<int>(chunkCenter.x + CHUNK_SIZE / 8 - 1, chunkCenter.y - CHUNK_SIZE / 8 + j, i));
-			updateLightning(Vec3<int>(chunkCenter.x + CHUNK_SIZE / 8, chunkCenter.y - CHUNK_SIZE / 8 + j, i));
-			updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j, chunkCenter.y - CHUNK_SIZE / 8 - 1, i));
-			updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j, chunkCenter.y - CHUNK_SIZE / 8, i));
-			updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j, chunkCenter.y + CHUNK_SIZE / 8 - 1, i));
-			updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j, chunkCenter.y + CHUNK_SIZE / 8, i));
-		}
-	}
+    if (lightUpdateQueue.getEintragAnzahl() > 300000)
+    {
+        std::cout
+            << "warning: light calculation queue is over 300000 blocks long";
+    }
+    for (int i = WORLD_HEIGHT - 1; i >= 0; i--)
+    {
+        for (int j = 0; j < CHUNK_SIZE; j++)
+        {
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 - 1,
+                chunkCenter.y - CHUNK_SIZE / 8 + j,
+                i));
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8,
+                chunkCenter.y - CHUNK_SIZE / 8 + j,
+                i));
+            updateLightning(Vec3<int>(chunkCenter.x + CHUNK_SIZE / 8 - 1,
+                chunkCenter.y - CHUNK_SIZE / 8 + j,
+                i));
+            updateLightning(Vec3<int>(chunkCenter.x + CHUNK_SIZE / 8,
+                chunkCenter.y - CHUNK_SIZE / 8 + j,
+                i));
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j,
+                chunkCenter.y - CHUNK_SIZE / 8 - 1,
+                i));
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j,
+                chunkCenter.y - CHUNK_SIZE / 8,
+                i));
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j,
+                chunkCenter.y + CHUNK_SIZE / 8 - 1,
+                i));
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j,
+                chunkCenter.y + CHUNK_SIZE / 8,
+                i));
+        }
+    }
 }
 
 __int64 Dimension::getNextStructureId()
 {
-	return nextStructureId++;
+    return nextStructureId++;
 }
 
 void Dimension::addStructure(MultiblockStructure* structure)
 {
-	structurCs.lock();
-	structures.add(structure);
-	structurCs.unlock();
+    structurCs.lock();
+    structures.add(structure);
+    structurCs.unlock();
 }
 
-MultiblockStructure* Dimension::zStructureByPosition(Framework::Vec3<int> uniquePosition)
+MultiblockStructure* Dimension::zStructureByPosition(
+    Framework::Vec3<int> uniquePosition)
 {
-	structurCs.lock();
-	for (MultiblockStructure* str : structures)
-	{
-		if (str->getUniquePosition() == uniquePosition)
-		{
-			structurCs.unlock();
-			return str;
-		}
-	}
-	// search for structure file
-	Datei dir(Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(dimensionId) + "/structures");
-	RCArray<Text>* names = dir.getDateiListe();
-	if (names)
-	{
-		Vec3<int> uPos;
-		for (Text* name : *names)
-		{
-			Datei d(Text(dir.zPfad()->getText()) + "/" + name->getText());
-			if (d.open(Datei::Style::lesen))
-			{
-				d.lese((char*)&uPos.x, 4);
-				d.lese((char*)&uPos.y, 4);
-				d.lese((char*)&uPos.z, 4);
-				if (uPos == uniquePosition)
-				{
-					int type;
-					d.lese((char*)&type, 4);
-					__int64 strId;
-					d.lese((char*)&strId, 8);
-					MultiblockStructure* str = StaticRegistry<MultiblockStructureType>::INSTANCE.zElement(type)->loadStructure(dimensionId, strId, uniquePosition, &d);
-					d.close();
-					structures.add(str);
-					names->release();
-					structurCs.unlock();
-					return str;
-				}
-				d.close();
-			}
-		}
-		names->release();
-	}
-	structurCs.unlock();
-	return 0;
+    structurCs.lock();
+    for (MultiblockStructure* str : structures)
+    {
+        if (str->getUniquePosition() == uniquePosition)
+        {
+            structurCs.unlock();
+            return str;
+        }
+    }
+    // search for structure file
+    Datei dir(Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(dimensionId)
+              + "/structures");
+    RCArray<Text>* names = dir.getDateiListe();
+    if (names)
+    {
+        Vec3<int> uPos;
+        for (Text* name : *names)
+        {
+            Datei d(Text(dir.zPfad()->getText()) + "/" + name->getText());
+            if (d.open(Datei::Style::lesen))
+            {
+                d.lese((char*)&uPos.x, 4);
+                d.lese((char*)&uPos.y, 4);
+                d.lese((char*)&uPos.z, 4);
+                if (uPos == uniquePosition)
+                {
+                    int type;
+                    d.lese((char*)&type, 4);
+                    __int64 strId;
+                    d.lese((char*)&strId, 8);
+                    MultiblockStructure* str
+                        = StaticRegistry<MultiblockStructureType>::INSTANCE
+                              .zElement(type)
+                              ->loadStructure(
+                                  dimensionId, strId, uniquePosition, &d);
+                    d.close();
+                    structures.add(str);
+                    names->release();
+                    structurCs.unlock();
+                    return str;
+                }
+                d.close();
+            }
+        }
+        names->release();
+    }
+    structurCs.unlock();
+    return 0;
 }
 
 MultiblockStructure* Dimension::zStructureById(__int64 id)
 {
-	structurCs.lock();
-	for (MultiblockStructure* str : structures)
-	{
-		if (str->getStructureId() == id)
-		{
-			structurCs.unlock();
-			return str;
-		}
-	}
-	// search for structure file
-	Text path = Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(dimensionId) + "/structures/";
-	path.appendHex(id);
-	path += ".str";
-	Datei d(path);
-	Vec3<int> uPos;
-	if (d.open(Datei::Style::lesen))
-	{
-		d.lese((char*)&uPos.x, 4);
-		d.lese((char*)&uPos.y, 4);
-		d.lese((char*)&uPos.z, 4);
-		int type;
-		d.lese((char*)&type, 4);
-		__int64 strId;
-		d.lese((char*)&strId, 8);
-		MultiblockStructure* str = StaticRegistry<MultiblockStructureType>::INSTANCE.zElement(type)->loadStructure(dimensionId, strId, uPos, &d);
-		d.close();
-		structures.add(str);
-		structurCs.unlock();
-		return str;
-	}
-	structurCs.unlock();
-	return 0;
+    structurCs.lock();
+    for (MultiblockStructure* str : structures)
+    {
+        if (str->getStructureId() == id)
+        {
+            structurCs.unlock();
+            return str;
+        }
+    }
+    // search for structure file
+    Text path = Game::INSTANCE->getWorldDirectory() + "/dim/"
+              + Text(dimensionId) + "/structures/";
+    path.appendHex(id);
+    path += ".str";
+    Datei d(path);
+    Vec3<int> uPos;
+    if (d.open(Datei::Style::lesen))
+    {
+        d.lese((char*)&uPos.x, 4);
+        d.lese((char*)&uPos.y, 4);
+        d.lese((char*)&uPos.z, 4);
+        int type;
+        d.lese((char*)&type, 4);
+        __int64 strId;
+        d.lese((char*)&strId, 8);
+        MultiblockStructure* str
+            = StaticRegistry<MultiblockStructureType>::INSTANCE.zElement(type)
+                  ->loadStructure(dimensionId, strId, uPos, &d);
+        d.close();
+        structures.add(str);
+        structurCs.unlock();
+        return str;
+    }
+    structurCs.unlock();
+    return 0;
 }

+ 2 - 2
FactoryCraft/DimensionGenerator.cpp

@@ -118,7 +118,7 @@ Chunk* DimensionGenerator::generateChunk(int centerX, int centerY)
 			int actualSurfaceHeight = (int)((float)maxSurfaceHeight * (1.f - VARIABLE_SURFACE_PART) + ((float)maxSurfaceHeight * VARIABLE_SURFACE_PART * (float)biom->zHeightMapNoise(seed)->getNoise((double)(x + centerX), (double)(y + centerY), 10.0)));
 			for (int z = 0; z < WORLD_HEIGHT; z++)
 			{
-				Framework::Either<Block*, int> generated = AirBlockBlockType::ID;
+				Framework::Either<Block*, int> generated = BlockTypeEnum::AIR;
 				bool structureAffected = 0;
 				for (auto structure : *structures)
 				{
@@ -172,7 +172,7 @@ Framework::Either<Block*, int> DimensionGenerator::generateBlock(Framework::Vec3
 		return biom->generateSurfaceBlock(location.x, location.y, location.z);
 	else if (location.z < height)
 		return biom->generateBelowSurfaceBlock(location.x, location.y, location.z);
-	return AirBlockBlockType::ID;
+	return BlockTypeEnum::AIR;
 }
 
 bool DimensionGenerator::spawnStructure(Framework::Vec3<int> location, std::function<bool(GenerationTemplate* tmpl)> filter)

+ 6 - 0
FactoryCraft/DimensionGenerator.h

@@ -8,6 +8,12 @@
 #include "Chunk.h"
 #include "CaveGenerator.h"
 
+class DimensionEnum
+{
+public:
+	static const int OVERWORLD = 0;
+};
+
 class DimensionGenerator : public virtual Framework::ReferenceCounter
 {
 private:

+ 365 - 345
FactoryCraft/Entity.cpp

@@ -1,368 +1,388 @@
 #include "Entity.h"
+
+#include "BlockType.h"
 #include "Dimension.h"
+#include "EntityRemovedUpdate.h"
 #include "Game.h"
-#include "BlockType.h"
 #include "ItemSkill.h"
-#include "EntityRemovedUpdate.h"
 #include "NoBlock.h"
 
-
 ActionTarget::ActionTarget(Vec3<int> blockPos, Direction blockSide)
-	: blockPos(blockPos),
-	targetBlockSide(blockSide),
-	entityId(-1)
+    : blockPos(blockPos),
+      targetBlockSide(blockSide),
+      entityId(-1)
 {}
 
 ActionTarget::ActionTarget(int entityId)
-	: entityId(entityId)
+    : entityId(entityId)
 {}
 
-bool ActionTarget::isBlock(Framework::Vec3<int> blockPos, Direction blockSide) const
+bool ActionTarget::isBlock(
+    Framework::Vec3<int> blockPos, Direction blockSide) const
 {
-	return this->entityId == -1 && this->blockPos == blockPos && this->targetBlockSide == targetBlockSide;
+    return this->entityId == -1 && this->blockPos == blockPos
+        && this->targetBlockSide == targetBlockSide;
 }
 
 bool ActionTarget::isEntity(int entityId) const
 {
-	return this->entityId == entityId;
+    return this->entityId == entityId;
 }
 
-void ActionTarget::applyItemSkillOnTarget(Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem)
+void ActionTarget::applyItemSkillOnTarget(
+    Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem)
 {
-	if (entityId >= 0)
-	{
-		// TODO: get entity from game and apply skill
-	}
-	else
-	{
-		Block* block = Game::INSTANCE->zRealBlockInstance(blockPos, zActor->getCurrentDimensionId());
-		if (block)
-			zItemSkill->use(zActor, zUsedItem, block);
-	}
+    if (entityId >= 0)
+    {
+        // TODO: get entity from game and apply skill
+    }
+    else
+    {
+        Block* block = Game::INSTANCE->zRealBlockInstance(
+            blockPos, zActor->getCurrentDimensionId());
+        if (block) zItemSkill->use(zActor, zUsedItem, block);
+    }
 }
 
 void ActionTarget::placeBlock(Entity* zActor, Item* zItem)
 {
-	// TODO: check stamina of actor
-	auto zB = Game::INSTANCE->zBlockAt(blockPos + getDirection(targetBlockSide), zActor->getCurrentDimensionId());
-	if ((zB.isA() && zB.getA()->zBlockType()->getId() == AirBlockBlockType::ID) || (zB.isB() && zB.isB() == AirBlockBlockType::ID))
-	{
-		Block* block = zItem->zPlacedBlockType()->createBlockAt(blockPos + getDirection(targetBlockSide), zItem);
-		if (block)
-		{
-			Game::INSTANCE->zDimension(zActor->getCurrentDimensionId())->placeBlock(block->getPos(), block);
-			zItem->onPlaced();
-			// TODO: decrese stamina of actor
-		}
-	}
+    // TODO: check stamina of actor
+    auto zB = Game::INSTANCE->zBlockAt(blockPos + getDirection(targetBlockSide),
+        zActor->getCurrentDimensionId());
+    if ((zB.isA() && zB.getA()->zBlockType()->getId() == BlockTypeEnum::AIR)
+        || (zB.isB() && zB.isB() == BlockTypeEnum::AIR))
+    {
+        Block* block = zItem->zPlacedBlockType()->createBlockAt(
+            blockPos + getDirection(targetBlockSide), zItem);
+        if (block)
+        {
+            Game::INSTANCE->zDimension(zActor->getCurrentDimensionId())
+                ->placeBlock(block->getPos(), block);
+            zItem->onPlaced();
+            // TODO: decrese stamina of actor
+        }
+    }
 }
 
 void ActionTarget::toMessage(const ActionTarget* zTarget, NetworkMessage* zMsg)
 {
-	if (zTarget)
-	{
-		if (zTarget->entityId >= 0)
-		{
-			char* message = new char[6];
-			message[0] = 3;
-			message[1] = 1;
-			*(int*)(message + 2) = zTarget->entityId;
-			zMsg->setMessage(message, 6);
-		}
-		else
-		{
-			char* message = new char[18];
-			message[0] = 3;
-			message[1] = 2;
-			*(int*)(message + 2) = zTarget->blockPos.x;
-			*(int*)(message + 6) = zTarget->blockPos.y;
-			*(int*)(message + 10) = zTarget->blockPos.z;
-			*(int*)(message + 14) = zTarget->targetBlockSide;
-			zMsg->setMessage(message, 18);
-		}
-	}
-	else
-	{
-		char* message = new char[2];
-		message[0] = 3;
-		message[1] = 0;
-		zMsg->setMessage(message, 2);
-	}
+    if (zTarget)
+    {
+        if (zTarget->entityId >= 0)
+        {
+            char* message = new char[6];
+            message[0] = 3;
+            message[1] = 1;
+            *(int*)(message + 2) = zTarget->entityId;
+            zMsg->setMessage(message, 6);
+        }
+        else
+        {
+            char* message = new char[18];
+            message[0] = 3;
+            message[1] = 2;
+            *(int*)(message + 2) = zTarget->blockPos.x;
+            *(int*)(message + 6) = zTarget->blockPos.y;
+            *(int*)(message + 10) = zTarget->blockPos.z;
+            *(int*)(message + 14) = zTarget->targetBlockSide;
+            zMsg->setMessage(message, 18);
+        }
+    }
+    else
+    {
+        char* message = new char[2];
+        message[0] = 3;
+        message[1] = 0;
+        zMsg->setMessage(message, 2);
+    }
 }
 
 void ActionTarget::save(ActionTarget* zTarget, Framework::StreamWriter* zWriter)
 {
-	if (zTarget)
-	{
-		if (zTarget->entityId >= 0)
-		{
-			char b = 1;
-			zWriter->schreibe(&b, 1);
-			zWriter->schreibe((char*)&zTarget->entityId, 4);
-		}
-		else
-		{
-			char b = 2;
-			zWriter->schreibe(&b, 1);
-			zWriter->schreibe((char*)&zTarget->blockPos.x, 4);
-			zWriter->schreibe((char*)&zTarget->blockPos.y, 4);
-			zWriter->schreibe((char*)&zTarget->blockPos.z, 4);
-			zWriter->schreibe((char*)&zTarget->targetBlockSide, 4);
-		}
-	}
-	else
-	{
-		char b = 0;
-		zWriter->schreibe(&b, 1);
-	}
+    if (zTarget)
+    {
+        if (zTarget->entityId >= 0)
+        {
+            char b = 1;
+            zWriter->schreibe(&b, 1);
+            zWriter->schreibe((char*)&zTarget->entityId, 4);
+        }
+        else
+        {
+            char b = 2;
+            zWriter->schreibe(&b, 1);
+            zWriter->schreibe((char*)&zTarget->blockPos.x, 4);
+            zWriter->schreibe((char*)&zTarget->blockPos.y, 4);
+            zWriter->schreibe((char*)&zTarget->blockPos.z, 4);
+            zWriter->schreibe((char*)&zTarget->targetBlockSide, 4);
+        }
+    }
+    else
+    {
+        char b = 0;
+        zWriter->schreibe(&b, 1);
+    }
 }
 
 ActionTarget* ActionTarget::load(Framework::StreamReader* zReader)
 {
-	char b;
-	zReader->lese(&b, 1);
-	if (b == 1)
-	{
-		int id;
-		zReader->lese((char*)&id, 4);
-		return new ActionTarget(id);
-	}
-	else if (b == 2)
-	{
-		Framework::Vec3<int> pos;
-		Direction side;
-		zReader->lese((char*)&pos.x, 4);
-		zReader->lese((char*)&pos.y, 4);
-		zReader->lese((char*)&pos.z, 4);
-		zReader->lese((char*)&side, 4);
-		return new ActionTarget(pos, side);
-	}
-	return 0;
-}
-
-
-Entity::Entity(const EntityType* zType, Framework::Vec3<float> location, int dimensionId, int entityId)
-	: Inventory(location, true),
-	speed(0, 0, 0),
-	faceDir(1, 0, 0),
-	target(0),
-	zEntityType(zType),
-	currentDimensionId(dimensionId),
-	removed(0),
-	gravityMultiplier(1.f),
-	id(entityId)
+    char b;
+    zReader->lese(&b, 1);
+    if (b == 1)
+    {
+        int id;
+        zReader->lese((char*)&id, 4);
+        return new ActionTarget(id);
+    }
+    else if (b == 2)
+    {
+        Framework::Vec3<int> pos;
+        Direction side;
+        zReader->lese((char*)&pos.x, 4);
+        zReader->lese((char*)&pos.y, 4);
+        zReader->lese((char*)&pos.z, 4);
+        zReader->lese((char*)&side, 4);
+        return new ActionTarget(pos, side);
+    }
+    return 0;
+}
+
+Entity::Entity(
+    int typeId, Framework::Vec3<float> location, int dimensionId, int entityId)
+    : Inventory(location, true),
+      speed(0, 0, 0),
+      faceDir(1, 0, 0),
+      target(0),
+      typeId(typeId),
+      currentDimensionId(dimensionId),
+      removed(0),
+      gravityMultiplier(1.f),
+      id(entityId)
 {}
 
 void Entity::onDeath()
 {
-	removed = 1;
-	Game::INSTANCE->requestWorldUpdate(new EntityRemovedUpdate(id, currentDimensionId, location));
-}
-
-void Entity::useItem(const ItemType* zType, Item* zItem)
-{
-	if (zItem && zItem->isEatable())
-	{ // TODO: eat item
-		zItem->applyFoodEffects(this);
-	}
-	else if (zItem && zItem->isPlaceable())
-	{ // TODO: place item
-		cs.lock();
-		if (target)
-			target->placeBlock(this, zItem);
-		cs.unlock();
-	}
-	else if (!zItem || zItem->isUsable())
-	{ // use item skill
-		cs.lock();
-		if (target)
-		{
-			ItemSkill* selected = 0;
-			for (ItemSkill* skill : skills)
-			{
-				if (skill->zSkillType() == zType)
-				{
-					selected = skill;
-					break;
-				}
-			}
-			if (!selected)
-			{
-				selected = zType->createDefaultItemSkill();
-				skills.add(selected);
-			}
-			target->applyItemSkillOnTarget(this, selected, zItem);
-		}
-		cs.unlock();
-	}
-}
-
-void Entity::onTargetChange()
-{}
+    removed = 1;
+    Game::INSTANCE->requestWorldUpdate(
+        new EntityRemovedUpdate(id, currentDimensionId, location));
+}
+
+void Entity::useItem(int typeId, Item* zItem)
+{
+    if (zItem && zItem->isEatable())
+    { // TODO: eat item
+        zItem->applyFoodEffects(this);
+    }
+    else if (zItem && zItem->isPlaceable())
+    { // TODO: place item
+        cs.lock();
+        if (target) target->placeBlock(this, zItem);
+        cs.unlock();
+    }
+    else if (!zItem || zItem->isUsable())
+    { // use item skill
+        cs.lock();
+        if (target)
+        {
+            ItemSkill* selected = 0;
+            for (ItemSkill* skill : skills)
+            {
+                if (skill->getTypeId() == typeId)
+                {
+                    selected = skill;
+                    break;
+                }
+            }
+            if (!selected)
+            {
+                selected = selected->zSkillType()->createDefaultItemSkill();
+                skills.add(selected);
+            }
+            target->applyItemSkillOnTarget(this, selected, zItem);
+        }
+        cs.unlock();
+    }
+}
+
+void Entity::onTargetChange() {}
 
 void Entity::addMovementFrame(MovementFrame& frame)
 {
-	cs.lock();
-	movements.add(frame);
-	cs.unlock();
-	NetworkMessage* message = new NetworkMessage();
-	message->addressEntity(this);
-	char* msg = new char[37];
-	msg[0] = 0;
-	*(float*)(msg + 1) = frame.direction.x;
-	*(float*)(msg + 5) = frame.direction.y;
-	*(float*)(msg + 9) = frame.direction.z;
-	*(float*)(msg + 13) = frame.targetPosition.x;
-	*(float*)(msg + 17) = frame.targetPosition.y;
-	*(float*)(msg + 21) = frame.targetPosition.z;
-	*(int*)(msg + 25) = frame.movementFlags;
-	*(double*)(msg + 29) = frame.duration;
-	message->setMessage(msg, 37);
-	Game::INSTANCE->broadcastMessage(message);
-	faceDir = frame.direction;
-	// TODO implement subscription system to notify only interested clients
-}
-
-void Entity::calculateTarget(Framework::Vec3<float> basePos, Framework::Vec3<float> direction)
-{
-	Vec3<float> headPosition = basePos + faceOffset;
-	int px = (int)floor(headPosition.x);
-	int py = (int)floor(headPosition.y);
-	int pz = (int)floor(headPosition.z);
-	direction.normalize();
-	Direction dir = BOTTOM;
-	while (true)
-	{
-		if (getDefaultBlock(Game::INSTANCE->zBlockAt(Vec3<int>{ px, py, pz }, currentDimensionId))->isInteractable())
-		{
-			if (!target || !target->isBlock({ px, py, pz }, dir))
-			{
-				cs.lock();
-				delete target;
-				target = new ActionTarget({ px, py, pz }, dir);
-				cs.unlock();
-				onTargetChange();
-			}
-			break;
-		}
-		// collision to neighbor of current block
-		if (direction.x > 0)
-		{
-			float xt = ((float)px + 1.f - headPosition.x) / direction.x;
-			Vec3<float> tmp = headPosition + direction * xt;
-			if (xt <= targetDistanceLimit && tmp.y >= (float)py && tmp.y < (float)py + 1.f && tmp.z >= (float)pz && tmp.z < (float)pz + 1.f)
-			{
-				dir = WEST;
-				px++;
-				continue;
-			}
-		}
-		if (direction.x < 0)
-		{
-			float xt = ((float)px - headPosition.x) / direction.x;
-			Vec3<float> tmp = headPosition + direction * xt;
-			if (xt <= targetDistanceLimit && tmp.y >= (float)py && tmp.y < (float)py + 1.f && tmp.z >= (float)pz && tmp.z < (float)pz + 1.f)
-			{
-				dir = EAST;
-				px--;
-				continue;
-			}
-		}
-		if (direction.y > 0)
-		{
-			float yt = ((float)py + 1.f - headPosition.y) / direction.y;
-			Vec3<float> tmp = headPosition + direction * yt;
-			if (yt <= targetDistanceLimit && tmp.x >= (float)px && tmp.x < (float)px + 1.f && tmp.z >= (float)pz && tmp.z < (float)pz + 1.f)
-			{
-				dir = NORTH;
-				py++;
-				continue;
-			}
-		}
-		if (direction.y < 0)
-		{
-			float yt = ((float)py - headPosition.y) / direction.y;
-			Vec3<float> tmp = headPosition + direction * yt;
-			if (yt <= targetDistanceLimit && tmp.x >= (float)px && tmp.x < (float)px + 1.f && tmp.z >= (float)pz && tmp.z < (float)pz + 1.f)
-			{
-				dir = SOUTH;
-				py--;
-				continue;
-			}
-		}
-		if (direction.z > 0)
-		{
-			float zt = ((float)pz + 1.f - headPosition.z) / direction.z;
-			Vec3<float> tmp = headPosition + direction * zt;
-			if (zt <= targetDistanceLimit && tmp.x >= (float)px && tmp.x < (float)px + 1.f && tmp.y >= (float)py && tmp.y < (float)py + 1.f)
-			{
-				dir = BOTTOM;
-				pz++;
-				continue;
-			}
-		}
-		if (direction.z < 0)
-		{
-			float zt = ((float)pz - headPosition.z) / direction.z;
-			Vec3<float> tmp = headPosition + direction * zt;
-			if (zt <= targetDistanceLimit && tmp.x >= (float)px && tmp.x < (float)px + 1.f && tmp.y >= (float)py && tmp.y < (float)py + 1)
-			{
-				dir = TOP;
-				pz--;
-				continue;
-			}
-		}
-		if (target)
-		{
-			cs.lock();
-			delete target;
-			target = 0;
-			cs.unlock();
-			onTargetChange();
-		}
-		break;
-	}
-}
-
-void Entity::prepareTick(const Dimension* zDimension)
-{}
+    cs.lock();
+    movements.add(frame);
+    cs.unlock();
+    NetworkMessage* message = new NetworkMessage();
+    message->addressEntity(this);
+    char* msg = new char[37];
+    msg[0] = 0;
+    *(float*)(msg + 1) = frame.direction.x;
+    *(float*)(msg + 5) = frame.direction.y;
+    *(float*)(msg + 9) = frame.direction.z;
+    *(float*)(msg + 13) = frame.targetPosition.x;
+    *(float*)(msg + 17) = frame.targetPosition.y;
+    *(float*)(msg + 21) = frame.targetPosition.z;
+    *(int*)(msg + 25) = frame.movementFlags;
+    *(double*)(msg + 29) = frame.duration;
+    message->setMessage(msg, 37);
+    Game::INSTANCE->broadcastMessage(message);
+    faceDir = frame.direction;
+    // TODO implement subscription system to notify only interested clients
+}
+
+void Entity::calculateTarget(
+    Framework::Vec3<float> basePos, Framework::Vec3<float> direction)
+{
+    Vec3<float> headPosition = basePos + faceOffset;
+    int px = (int)floor(headPosition.x);
+    int py = (int)floor(headPosition.y);
+    int pz = (int)floor(headPosition.z);
+    direction.normalize();
+    Direction dir = BOTTOM;
+    while (true)
+    {
+        if (getDefaultBlock(Game::INSTANCE->zBlockAt(
+                                Vec3<int>{px, py, pz}, currentDimensionId))
+                ->isInteractable())
+        {
+            if (!target || !target->isBlock({px, py, pz}, dir))
+            {
+                cs.lock();
+                delete target;
+                target = new ActionTarget({px, py, pz}, dir);
+                cs.unlock();
+                onTargetChange();
+            }
+            break;
+        }
+        // collision to neighbor of current block
+        if (direction.x > 0)
+        {
+            float xt = ((float)px + 1.f - headPosition.x) / direction.x;
+            Vec3<float> tmp = headPosition + direction * xt;
+            if (xt <= targetDistanceLimit && tmp.y >= (float)py
+                && tmp.y < (float)py + 1.f && tmp.z >= (float)pz
+                && tmp.z < (float)pz + 1.f)
+            {
+                dir = WEST;
+                px++;
+                continue;
+            }
+        }
+        if (direction.x < 0)
+        {
+            float xt = ((float)px - headPosition.x) / direction.x;
+            Vec3<float> tmp = headPosition + direction * xt;
+            if (xt <= targetDistanceLimit && tmp.y >= (float)py
+                && tmp.y < (float)py + 1.f && tmp.z >= (float)pz
+                && tmp.z < (float)pz + 1.f)
+            {
+                dir = EAST;
+                px--;
+                continue;
+            }
+        }
+        if (direction.y > 0)
+        {
+            float yt = ((float)py + 1.f - headPosition.y) / direction.y;
+            Vec3<float> tmp = headPosition + direction * yt;
+            if (yt <= targetDistanceLimit && tmp.x >= (float)px
+                && tmp.x < (float)px + 1.f && tmp.z >= (float)pz
+                && tmp.z < (float)pz + 1.f)
+            {
+                dir = NORTH;
+                py++;
+                continue;
+            }
+        }
+        if (direction.y < 0)
+        {
+            float yt = ((float)py - headPosition.y) / direction.y;
+            Vec3<float> tmp = headPosition + direction * yt;
+            if (yt <= targetDistanceLimit && tmp.x >= (float)px
+                && tmp.x < (float)px + 1.f && tmp.z >= (float)pz
+                && tmp.z < (float)pz + 1.f)
+            {
+                dir = SOUTH;
+                py--;
+                continue;
+            }
+        }
+        if (direction.z > 0)
+        {
+            float zt = ((float)pz + 1.f - headPosition.z) / direction.z;
+            Vec3<float> tmp = headPosition + direction * zt;
+            if (zt <= targetDistanceLimit && tmp.x >= (float)px
+                && tmp.x < (float)px + 1.f && tmp.y >= (float)py
+                && tmp.y < (float)py + 1.f)
+            {
+                dir = BOTTOM;
+                pz++;
+                continue;
+            }
+        }
+        if (direction.z < 0)
+        {
+            float zt = ((float)pz - headPosition.z) / direction.z;
+            Vec3<float> tmp = headPosition + direction * zt;
+            if (zt <= targetDistanceLimit && tmp.x >= (float)px
+                && tmp.x < (float)px + 1.f && tmp.y >= (float)py
+                && tmp.y < (float)py + 1)
+            {
+                dir = TOP;
+                pz--;
+                continue;
+            }
+        }
+        if (target)
+        {
+            cs.lock();
+            delete target;
+            target = 0;
+            cs.unlock();
+            onTargetChange();
+        }
+        break;
+    }
+}
+
+void Entity::prepareTick(const Dimension* zDimension) {}
 
 void Entity::tick(const Dimension* zDimension)
 {
-	if (time.isMeasuring())
-	{
-		time.messungEnde();
-		if (movements.getEintragAnzahl() > 0)
-		{
-			MovementFrame currentFrame = movements.get(0);
-			double seconds = time.getSekunden();
-			while (seconds > 0)
-			{
-				if (currentFrame.duration <= 0)
-				{
-					cs.lock();
-					movements.remove(0);
-					cs.unlock();
-					if (movements.getEintragAnzahl() > 0)
-						currentFrame = movements.get(0);
-					else
-						break;
-				}
-				double t = MIN(currentFrame.duration, seconds);
-				// TODO: add collisin detection to reduce cheating capability
-				location += (currentFrame.targetPosition - location) * (float)(t / currentFrame.duration);
-				currentFrame.duration -= t;
-				seconds -= t;
-				if (currentFrame.duration <= 0)
-				{
-					location = currentFrame.targetPosition;
-				}
-			}
-			if (currentFrame.duration > 0)
-				movements.set(currentFrame, 0);
-		}
-	}
-	time.messungStart();
+    if (time.isMeasuring())
+    {
+        time.messungEnde();
+        if (movements.getEintragAnzahl() > 0)
+        {
+            MovementFrame currentFrame = movements.get(0);
+            double seconds = time.getSekunden();
+            while (seconds > 0)
+            {
+                if (currentFrame.duration <= 0)
+                {
+                    cs.lock();
+                    movements.remove(0);
+                    cs.unlock();
+                    if (movements.getEintragAnzahl() > 0)
+                        currentFrame = movements.get(0);
+                    else
+                        break;
+                }
+                double t = MIN(currentFrame.duration, seconds);
+                // TODO: add collisin detection to reduce cheating capability
+                location += (currentFrame.targetPosition - location)
+                          * (float)(t / currentFrame.duration);
+                currentFrame.duration -= t;
+                seconds -= t;
+                if (currentFrame.duration <= 0)
+                {
+                    location = currentFrame.targetPosition;
+                }
+            }
+            if (currentFrame.duration > 0) movements.set(currentFrame, 0);
+        }
+    }
+    time.messungStart();
 }
 
 void Entity::api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
@@ -370,118 +390,118 @@ void Entity::api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
 
 void Entity::onFall(float collisionSpeed)
 {
-	if (collisionSpeed > 5)
-	{
-		// TODO: take damage
-	}
+    if (collisionSpeed > 5)
+    {
+        // TODO: take damage
+    }
 }
 
 void Entity::setPosition(Framework::Vec3<float> pos)
 {
-	location = pos;
+    location = pos;
 }
 
 float Entity::getMaxHP() const
 {
-	return maxHP;
+    return maxHP;
 }
 
 float Entity::getCurrentHP() const
 {
-	return currentHP;
+    return currentHP;
 }
 
 float Entity::getStamina() const
 {
-	return stamina;
+    return stamina;
 }
 
 float Entity::getMaxStamina() const
 {
-	return maxStamina;
+    return maxStamina;
 }
 
 float Entity::getHunger() const
 {
-	return hunger;
+    return hunger;
 }
 
 float Entity::getMaxHunger() const
 {
-	return maxHunger;
+    return maxHunger;
 }
 
 float Entity::getThirst() const
 {
-	return thirst;
+    return thirst;
 }
 
 float Entity::getMaxThirst() const
 {
-	return maxThirst;
+    return maxThirst;
 }
 
 Framework::Vec3<float> Entity::getSpeed() const
 {
-	return speed;
+    return speed;
 }
 
 Framework::Vec3<float> Entity::getFaceDir() const
 {
-	return faceDir;
+    return faceDir;
 }
 
 Framework::Vec3<float> Entity::getPosition() const
 {
-	return location;
+    return location;
 }
 
 float Entity::getGravityMultiplier() const
 {
-	return gravityMultiplier;
+    return gravityMultiplier;
 }
 
 int Entity::getCurrentDimensionId() const
 {
-	return currentDimensionId;
+    return currentDimensionId;
 }
 
 bool Entity::isRemoved() const
 {
-	return removed;
+    return removed;
 }
 
 const EntityType* Entity::zType() const
 {
-	return zEntityType;
+    return StaticRegistry<EntityType>::INSTANCE.zElement(typeId);
 }
 
 const ActionTarget* Entity::zTarget() const
 {
-	return target;
+    return target;
 }
 
 int Entity::getId() const
 {
-	return id;
+    return id;
 }
 
 bool Entity::hasDefaultModel() const
 {
-	return 1;
+    return 1;
 }
 
 ModelInfo Entity::getSpecialModel() const
 {
-	return ModelInfo("", "", 0);
+    return ModelInfo("", "", 0);
 }
 
 float Entity::getMaxSpeed() const
 {
-	return maxMovementSpeed;
+    return maxMovementSpeed;
 }
 
 bool Entity::isMoving() const
 {
-	return movements.getEintragAnzahl() > 0;
+    return movements.getEintragAnzahl() > 0;
 }

+ 86 - 81
FactoryCraft/Entity.h

@@ -1,16 +1,15 @@
 #pragma once
 
 #include <ReferenceCounter.h>
-#include <Vec3.h>
 #include <Vec2.h>
+#include <Vec3.h>
 #include <Writer.h>
 #include <Zeit.h>
 
 #include "Effect.h"
 #include "Inventory.h"
-#include "NetworkMessage.h"
 #include "ItemSkill.h"
-
+#include "NetworkMessage.h"
 
 class EntityType;
 class Dimension;
@@ -18,97 +17,103 @@ class Dimension;
 class ActionTarget
 {
 private:
-	Framework::Vec3<int> blockPos;
-	Direction targetBlockSide;
-	int entityId;
+    Framework::Vec3<int> blockPos;
+    Direction targetBlockSide;
+    int entityId;
 
 public:
-	ActionTarget(Framework::Vec3<int> blockPos, Direction blockSide);
-	ActionTarget(int entityId);
+    ActionTarget(Framework::Vec3<int> blockPos, Direction blockSide);
+    ActionTarget(int entityId);
+
+    bool isBlock(Framework::Vec3<int> blockPos, Direction blockSide) const;
+    bool isEntity(int entityId) const;
 
-	bool isBlock(Framework::Vec3<int> blockPos, Direction blockSide) const;
-	bool isEntity(int entityId) const;
+    void applyItemSkillOnTarget(
+        Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem);
+    void placeBlock(Entity* zActor, Item* zItem);
 
-	void applyItemSkillOnTarget(Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem);
-	void placeBlock(Entity* zActor, Item* zItem);
-	static void toMessage(const ActionTarget* zTarget, NetworkMessage* zMsg);
-	static void save(ActionTarget* zTarget, Framework::StreamWriter* zWriter);
-	static ActionTarget* load(Framework::StreamReader* zReader);
+    static void toMessage(const ActionTarget* zTarget, NetworkMessage* zMsg);
+    static void save(ActionTarget* zTarget, Framework::StreamWriter* zWriter);
+    static ActionTarget* load(Framework::StreamReader* zReader);
 };
 
 struct MovementFrame
 {
-	Framework::Vec3<float> direction;
-	Framework::Vec3<float> targetPosition;
-	int movementFlags;
-	double duration;
+    Framework::Vec3<float> direction;
+    Framework::Vec3<float> targetPosition;
+    int movementFlags;
+    double duration;
 };
 
 class Entity : public Inventory
 {
 protected:
-	float maxHP;
-	float currentHP;
-	float stamina;
-	float maxStamina;
-	float hunger;
-	float maxHunger;
-	float thirst;
-	float maxThirst;
-	float targetDistanceLimit;
-	float maxMovementSpeed;
-	Framework::Vec3<float> speed;
-	Framework::Vec3<float> faceDir;
-	Framework::Vec3<float> faceOffset;
-	Framework::RCArray<ItemSkill> skills;
-	ActionTarget* target;
-	const EntityType* zEntityType;
-	int currentDimensionId;
-	bool removed;
-	float gravityMultiplier;
-	int id;
-	Framework::ZeitMesser time;
-	Framework::Array<MovementFrame> movements;
-	Framework::Critical cs;
-
-	virtual void onDeath();
-	virtual void useItem(const ItemType* zType, Item* zItem);
-	Entity(const EntityType* zType, Framework::Vec3<float> location, int dimensionId, int entityId);
-	virtual void onTargetChange();
-	void addMovementFrame(MovementFrame& frame);
-	void calculateTarget(Framework::Vec3<float> basePos, Framework::Vec3<float> direction);
+    float maxHP;
+    float currentHP;
+    float stamina;
+    float maxStamina;
+    float hunger;
+    float maxHunger;
+    float thirst;
+    float maxThirst;
+    float targetDistanceLimit;
+    float maxMovementSpeed;
+    Framework::Vec3<float> speed;
+    Framework::Vec3<float> faceDir;
+    Framework::Vec3<float> faceOffset;
+    Framework::RCArray<ItemSkill> skills;
+    ActionTarget* target;
+    int typeId;
+    int currentDimensionId;
+    bool removed;
+    float gravityMultiplier;
+    int id;
+    Framework::ZeitMesser time;
+    Framework::Array<MovementFrame> movements;
+    Framework::Critical cs;
+
+    virtual void onDeath();
+    virtual void useItem(int typeId, Item* zItem);
+    Entity(int typeId,
+        Framework::Vec3<float> location,
+        int dimensionId,
+        int entityId);
+    virtual void onTargetChange();
+    void addMovementFrame(MovementFrame& frame);
+    void calculateTarget(
+        Framework::Vec3<float> basePos, Framework::Vec3<float> direction);
 
 public:
-	virtual void prepareTick(const Dimension* zDimension);
-	virtual void tick(const Dimension* zDimension);
-
-	virtual void api(Framework::StreamReader* zRequest, NetworkMessage* zResponse);
-
-	virtual void onFall(float collisionSpeed);
-	void setPosition(Framework::Vec3<float> pos);
-	float getMaxHP() const;
-	float getCurrentHP() const;
-	float getStamina() const;
-	float getMaxStamina() const;
-	float getHunger() const;
-	float getMaxHunger() const;
-	float getThirst() const;
-	float getMaxThirst() const;
-	Framework::Vec3<float> getSpeed() const;
-	Framework::Vec3<float> getFaceDir() const;
-	Framework::Vec3<float> getPosition() const;
-	float getGravityMultiplier() const;
-	int getCurrentDimensionId() const;
-	bool isRemoved() const;
-
-	const EntityType* zType() const;
-	const ActionTarget* zTarget() const;
-	int getId() const;
-	virtual bool hasDefaultModel() const;
-	virtual ModelInfo getSpecialModel() const;
-	float getMaxSpeed() const;
-	bool isMoving() const;
-
-	friend Effect;
-	friend EntityType;
+    virtual void prepareTick(const Dimension* zDimension);
+    virtual void tick(const Dimension* zDimension);
+
+    virtual void api(
+        Framework::StreamReader* zRequest, NetworkMessage* zResponse);
+
+    virtual void onFall(float collisionSpeed);
+    void setPosition(Framework::Vec3<float> pos);
+    float getMaxHP() const;
+    float getCurrentHP() const;
+    float getStamina() const;
+    float getMaxStamina() const;
+    float getHunger() const;
+    float getMaxHunger() const;
+    float getThirst() const;
+    float getMaxThirst() const;
+    Framework::Vec3<float> getSpeed() const;
+    Framework::Vec3<float> getFaceDir() const;
+    Framework::Vec3<float> getPosition() const;
+    float getGravityMultiplier() const;
+    int getCurrentDimensionId() const;
+    bool isRemoved() const;
+    const EntityType* zType() const;
+    const ActionTarget* zTarget() const;
+    int getId() const;
+    virtual bool hasDefaultModel() const;
+    virtual ModelInfo getSpecialModel() const;
+    float getMaxSpeed() const;
+    bool isMoving() const;
+
+    friend Effect;
+    friend EntityType;
 };

+ 2 - 7
FactoryCraft/EntityRemovedUpdate.cpp

@@ -3,7 +3,7 @@
 
 
 EntityRemovedUpdate::EntityRemovedUpdate(int entityId, int dimensionId, Framework::Vec3<int> pos)
-	: WorldUpdate(EntityRemovedUpdateType::ID, dimensionId, pos, pos),
+    : WorldUpdate(WorldUpdateTypeEnum::REMOVE_ENTITY, dimensionId, pos, pos),
 	entityId(entityId)
 {}
 
@@ -18,9 +18,4 @@ void EntityRemovedUpdate::onUpdate(Dimension* zDimension)
 void EntityRemovedUpdate::write(Framework::StreamWriter* zWriter)
 {
 	zWriter->schreibe((char*)&entityId, 4);
-}
-
-
-EntityRemovedUpdateType::EntityRemovedUpdateType()
-	: WorldUpdateType(ID)
-{}
+}

+ 1 - 10
FactoryCraft/EntityRemovedUpdate.h

@@ -15,13 +15,4 @@ public:
 	~EntityRemovedUpdate();
 
 	void onUpdate(Dimension* zDimension) override;
-};
-
-class EntityRemovedUpdateType : WorldUpdateType
-{
-	REGISTRABLE(EntityRemovedUpdateType)
-
-protected:
-	EntityRemovedUpdateType();
-};
-REGISTER(EntityRemovedUpdateType, WorldUpdateType)
+};

+ 12 - 2
FactoryCraft/EntityType.h

@@ -10,6 +10,13 @@
 
 class Entity;
 
+class EntityTypeEnum
+{
+public:
+    static const int PLAYER = 0;
+    static const int ITEM = 1;
+};
+
 class EntityType : public virtual Framework::ReferenceCounter
 {
 private:
@@ -22,12 +29,15 @@ protected:
 	virtual void loadSuperEntity(Entity* zEntity, Framework::StreamReader* zReader) const;
 	virtual void saveSuperEntity(Entity* zEntity, Framework::StreamWriter* zWriter) const;
 	virtual void createSuperEntity(Entity* zEntity) const;
-	virtual Entity* createEntity(Framework::Vec3<float> position, int dimensionId, int entityId) const = 0;
 
 public:
 	virtual Entity* loadEntity(Framework::StreamReader* zReader) const;
 	virtual void saveEntity(Entity* zEntity, Framework::StreamWriter* zWriter) const;
-	virtual Entity* createEntityAt(Framework::Vec3<float> position, int dimensionId) const;
+    virtual Entity* createEntityAt(
+        Framework::Vec3<float> position, int dimensionId) const;
+    virtual Entity* createEntity(Framework::Vec3<float> position,
+        int dimensionId,
+        int entityId) const = 0;
 
 	int getId() const;
 	const ModelInfo& getModel() const;

+ 698 - 642
FactoryCraft/Game.cpp

@@ -1,831 +1,887 @@
 #include "Game.h"
-#include "Zeit.h"
-#include "Player.h"
-#include "OverworldDimension.h"
-#include "NoBlock.h"
+
+#include "AddEntityUpdate.h"
 #include "AsynchronCall.h"
 #include "Entity.h"
-#include "AddEntityUpdate.h"
 #include "EntityRemovedUpdate.h"
 #include "NetworkMessage.h"
+#include "NoBlock.h"
+#include "OverworldDimension.h"
+#include "Player.h"
+#include "Zeit.h"
 
 using namespace Framework;
 
 char* randomKey(int& len)
 {
-	len = 1024 + (int)(((double)rand() / RAND_MAX - 0.5) * 512);
-	char* key = new char[len];
-	for (int i = 0; i < len; i++)
-		key[i] = (char)((((double)rand() / RAND_MAX) * 254) + 1);
-	return key;
+    len = 1024 + (int)(((double)rand() / RAND_MAX - 0.5) * 512);
+    char* key = new char[len];
+    for (int i = 0; i < len; i++)
+        key[i] = (char)((((double)rand() / RAND_MAX) * 254) + 1);
+    return key;
 }
 
 GameClient::GameClient(Player* zPlayer, FCKlient* client)
-	: Thread(),
-	zPlayer(zPlayer),
-	client(client),
-	viewDistance(DEFAULT_VIEW_DISTANCE),
-	first(1),
-	online(1),
-	finished(0),
-	backgroundFinished(0),
-	foregroundFinished(0)
-{
-	new AsynchronCall("Game Client Updates", [this]()
-		{
-			while (online)
-			{
-				other.lock();
-				if (updateQueue.hat(0))
-				{
-					WorldUpdate* update = updateQueue.get(0);
-					updateQueue.remove(0);
-					other.unlock();
-					background.lock();
-					this->client->zBackgroundWriter()->schreibe((char*)&Message::WORLD_UPDATE, 1);
-					update->writeAndCheck(this->client->zBackgroundWriter());
-					background.unlock();
-					update->release();
-				}
-				else
-				{
-					other.unlock();
-					updateSync.wait();
-				}
-			}
-			finished = 1;
-		});
-	start();
+    : Thread(),
+      zPlayer(zPlayer),
+      client(client),
+      viewDistance(DEFAULT_VIEW_DISTANCE),
+      first(1),
+      online(1),
+      finished(0),
+      backgroundFinished(0),
+      foregroundFinished(0)
+{
+    new AsynchronCall("Game Client Updates", [this]() {
+        while (online)
+        {
+            other.lock();
+            if (updateQueue.hat(0))
+            {
+                WorldUpdate* update = updateQueue.get(0);
+                updateQueue.remove(0);
+                other.unlock();
+                background.lock();
+                this->client->zBackgroundWriter()->schreibe(
+                    (char*)&Message::WORLD_UPDATE, 1);
+                update->writeAndCheck(this->client->zBackgroundWriter());
+                background.unlock();
+                update->release();
+            }
+            else
+            {
+                other.unlock();
+                updateSync.wait();
+            }
+        }
+        finished = 1;
+    });
+    start();
 }
 
 GameClient::~GameClient()
 {
-	online = 0;
-	updateSync.notify();
-	emptyForegroundQueueSync.notifyAll();
-	emptyBackgroundQueueSync.notifyAll();
-	foregroundQueueSync.notify();
-	backgroundQueueSync.notify();
-	while (!finished || !foregroundFinished || !backgroundFinished)
-		Sleep(100);
-	client->release();
+    online = 0;
+    updateSync.notify();
+    emptyForegroundQueueSync.notifyAll();
+    emptyBackgroundQueueSync.notifyAll();
+    foregroundQueueSync.notify();
+    backgroundQueueSync.notify();
+    while (!finished || !foregroundFinished || !backgroundFinished)
+        Sleep(100);
+    client->release();
 }
 
 void GameClient::thread()
 {
-	new AsynchronCall("Game Client Background", [this]()
-		{
-			while (online)
-			{
-				queueCs.lock();
-				if (backgroundQueue.hat(0))
-				{
-					NetworkMessage* message = backgroundQueue.get(0);
-					backgroundQueue.remove(0);
-					queueCs.unlock();
-					background.lock();
-					message->writeTo(client->zBackgroundWriter());
-					background.unlock();
-					message->release();
-				}
-				else
-				{
-					queueCs.unlock();
-					emptyBackgroundQueueSync.notifyAll();
-					backgroundQueueSync.wait();
-				}
-			}
-			backgroundFinished = 1;
-		});
-	while (online)
-	{
-		queueCs.lock();
-		if (foregroundQueue.hat(0))
-		{
-			NetworkMessage* message = foregroundQueue.get(0);
-			foregroundQueue.remove(0);
-			queueCs.unlock();
-			foreground.lock();
-			message->writeTo(client->zForegroundWriter());
-			foreground.unlock();
-			message->release();
-		}
-		else
-		{
-			queueCs.unlock();
-			emptyForegroundQueueSync.notifyAll();
-			foregroundQueueSync.wait();
-		}
-	}
-	foregroundFinished = 1;
+    new AsynchronCall("Game Client Background", [this]() {
+        while (online)
+        {
+            queueCs.lock();
+            if (backgroundQueue.hat(0))
+            {
+                NetworkMessage* message = backgroundQueue.get(0);
+                backgroundQueue.remove(0);
+                queueCs.unlock();
+                background.lock();
+                message->writeTo(client->zBackgroundWriter());
+                background.unlock();
+                message->release();
+            }
+            else
+            {
+                queueCs.unlock();
+                emptyBackgroundQueueSync.notifyAll();
+                backgroundQueueSync.wait();
+            }
+        }
+        backgroundFinished = 1;
+    });
+    while (online)
+    {
+        queueCs.lock();
+        if (foregroundQueue.hat(0))
+        {
+            NetworkMessage* message = foregroundQueue.get(0);
+            foregroundQueue.remove(0);
+            queueCs.unlock();
+            foreground.lock();
+            message->writeTo(client->zForegroundWriter());
+            foreground.unlock();
+            message->release();
+        }
+        else
+        {
+            queueCs.unlock();
+            emptyForegroundQueueSync.notifyAll();
+            foregroundQueueSync.wait();
+        }
+    }
+    foregroundFinished = 1;
 }
 
 void GameClient::sendWorldUpdate(WorldUpdate* update)
 {
-	bool add = 0;
-	if (zPlayer->getCurrentDimensionId() == update->getAffectedDimension())
-	{
-		auto pos = (Vec3<int>)zPlayer->getPosition();
-		int dist = update->distanceTo(pos.x, pos.y);
-		if (dist < viewDistance * CHUNK_SIZE)
-		{
-			other.lock();
-			int index = 0;
-			for (auto update2 : updateQueue)
-			{
-				int dist2 = update2->distanceTo(pos.x, pos.y);
-				if (dist2 > dist)
-					break;
-				index++;
-			}
-			updateQueue.add(update, index);
-			other.unlock();
-			updateSync.notify();
-			add = 1;
-		}
-	}
-	if (!add)
-		update->release();
+    bool add = 0;
+    if (zPlayer->getCurrentDimensionId() == update->getAffectedDimension())
+    {
+        auto pos = (Vec3<int>)zPlayer->getPosition();
+        int dist = update->distanceTo(pos.x, pos.y);
+        if (dist < viewDistance * CHUNK_SIZE)
+        {
+            other.lock();
+            int index = 0;
+            for (auto update2 : updateQueue)
+            {
+                int dist2 = update2->distanceTo(pos.x, pos.y);
+                if (dist2 > dist) break;
+                index++;
+            }
+            updateQueue.add(update, index);
+            other.unlock();
+            updateSync.notify();
+            add = 1;
+        }
+    }
+    if (!add) update->release();
 }
 
 void GameClient::reply()
 {
-	other.lock();
-	for (auto req : requests)
-		Game::INSTANCE->api(req, this);
-	requests.leeren();
-	other.unlock();
-	if (first)
-	{
-		foreground.lock();
-		int id = zPlayer->getId();
-		client->zForegroundWriter()->schreibe((char*)&Message::POSITION_UPDATE, 1);
-		client->zForegroundWriter()->schreibe((char*)&id, 4);
-		foreground.unlock();
-		first = 0;
-	}
+    other.lock();
+    for (auto req : requests)
+        Game::INSTANCE->api(req, this);
+    requests.leeren();
+    other.unlock();
+    if (first)
+    {
+        foreground.lock();
+        int id = zPlayer->getId();
+        client->zForegroundWriter()->schreibe(
+            (char*)&Message::POSITION_UPDATE, 1);
+        client->zForegroundWriter()->schreibe((char*)&id, 4);
+        foreground.unlock();
+        first = 0;
+    }
 }
 
 void GameClient::logout()
 {
-	online = 0;
+    online = 0;
 }
 
 void GameClient::addMessage(StreamReader* reader)
 {
-	short len = 0;
-	reader->lese((char*)&len, 2);
-	InMemoryBuffer* buffer = new InMemoryBuffer();
-	char* tmp = new char[len];
-	reader->lese(tmp, len);
-	buffer->schreibe(tmp, len);
-	delete[]tmp;
-	other.lock();
-	requests.add(buffer);
-	other.unlock();
+    short len = 0;
+    reader->lese((char*)&len, 2);
+    InMemoryBuffer* buffer = new InMemoryBuffer();
+    char* tmp = new char[len];
+    reader->lese(tmp, len);
+    buffer->schreibe(tmp, len);
+    delete[] tmp;
+    other.lock();
+    requests.add(buffer);
+    other.unlock();
 }
 
 bool GameClient::isOnline() const
 {
-	return online;
+    return online;
 }
 
 void GameClient::sendResponse(NetworkMessage* response)
 {
-	queueCs.lock();
-	if (response->isUseBackground())
-	{
-		if (backgroundQueue.getEintragAnzahl() > 20)
-		{
-			queueCs.unlock();
-			emptyBackgroundQueueSync.wait();
-			queueCs.lock();
-		}
-		backgroundQueue.add(response);
-		queueCs.unlock();
-		backgroundQueueSync.notify();
-	}
-	else
-	{
-		if (foregroundQueue.getEintragAnzahl() > 100)
-		{
-			queueCs.unlock();
-			std::cout << "WARNING: Game paused because nework connection to " << zPlayer->getName() << " is to slow.\n";
-			ZeitMesser m;
-			m.messungStart();
-			emptyForegroundQueueSync.wait();
-			m.messungEnde();
-			std::cout << "WARNING: Game resumed after " << m.getSekunden() << " seconds.\n";
-			queueCs.lock();
-		}
-		foregroundQueue.add(response);
-		queueCs.unlock();
-		foregroundQueueSync.notify();
-	}
+    queueCs.lock();
+    if (response->isUseBackground())
+    {
+        if (backgroundQueue.getEintragAnzahl() > 20)
+        {
+            queueCs.unlock();
+            emptyBackgroundQueueSync.wait();
+            queueCs.lock();
+        }
+        backgroundQueue.add(response);
+        queueCs.unlock();
+        backgroundQueueSync.notify();
+    }
+    else
+    {
+        if (foregroundQueue.getEintragAnzahl() > 100)
+        {
+            queueCs.unlock();
+            std::cout << "WARNING: Game paused because nework connection to "
+                      << zPlayer->getName() << " is to slow.\n";
+            ZeitMesser m;
+            m.messungStart();
+            emptyForegroundQueueSync.wait();
+            m.messungEnde();
+            std::cout << "WARNING: Game resumed after " << m.getSekunden()
+                      << " seconds.\n";
+            queueCs.lock();
+        }
+        foregroundQueue.add(response);
+        queueCs.unlock();
+        foregroundQueueSync.notify();
+    }
 }
 
 Player* GameClient::zEntity() const
 {
-	return zPlayer;
+    return zPlayer;
 }
 
 void GameClient::sendTypes()
 {
-	foreground.lock();
-	int count = StaticRegistry<BlockType>::INSTANCE.getCount();
-	client->zForegroundWriter()->schreibe((char*)&count, 4);
-	for (int i = 0; i < count; i++)
-	{
-		BlockType* t = StaticRegistry<BlockType>::INSTANCE.zElement(i);
-		int id = t->getId();
-		client->zForegroundWriter()->schreibe((char*)&id, 4);
-		bool inst = t->doesNeedClientInstance();
-		client->zForegroundWriter()->schreibe((char*)&inst, 1);
-		int maxHp = t->getInitialMaxHP();
-		client->zForegroundWriter()->schreibe((char*)&maxHp, 4);
-		t->getModel().writeTo(client->zForegroundWriter());
-	}
-	count = StaticRegistry<ItemType>::INSTANCE.getCount();
-	client->zForegroundWriter()->schreibe((char*)&count, 4);
-	for (int i = 0; i < count; i++)
-	{
-		ItemType* t = StaticRegistry<ItemType>::INSTANCE.zElement(i);
-		int id = t->getId();
-		client->zForegroundWriter()->schreibe((char*)&id, 4);
-		t->getModel().writeTo(client->zForegroundWriter());
-	}
-	count = StaticRegistry<EntityType>::INSTANCE.getCount();
-	client->zForegroundWriter()->schreibe((char*)&count, 4);
-	for (int i = 0; i < count; i++)
-	{
-		EntityType* t = StaticRegistry<EntityType>::INSTANCE.zElement(i);
-		int id = t->getId();
-		client->zForegroundWriter()->schreibe((char*)&id, 4);
-		t->getModel().writeTo(client->zForegroundWriter());
-	}
-	foreground.unlock();
+    foreground.lock();
+    int count = StaticRegistry<BlockType>::INSTANCE.getCount();
+    client->zForegroundWriter()->schreibe((char*)&count, 4);
+    for (int i = 0; i < count; i++)
+    {
+        BlockType* t = StaticRegistry<BlockType>::INSTANCE.zElement(i);
+        int id = t->getId();
+        client->zForegroundWriter()->schreibe((char*)&id, 4);
+        bool inst = t->doesNeedClientInstance();
+        client->zForegroundWriter()->schreibe((char*)&inst, 1);
+        int maxHp = t->getInitialMaxHP();
+        client->zForegroundWriter()->schreibe((char*)&maxHp, 4);
+        t->getModel().writeTo(client->zForegroundWriter());
+    }
+    count = 0;
+    for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
+    {
+        if (StaticRegistry<ItemType>::INSTANCE.zElement(i)) count++;
+    }
+    client->zForegroundWriter()->schreibe((char*)&count, 4);
+    for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
+    {
+        if (StaticRegistry<ItemType>::INSTANCE.zElement(i))
+        {
+            ItemType* t = StaticRegistry<ItemType>::INSTANCE.zElement(i);
+            int id = t->getId();
+            client->zForegroundWriter()->schreibe((char*)&id, 4);
+            t->getModel().writeTo(client->zForegroundWriter());
+        }
+    }
+    count = StaticRegistry<EntityType>::INSTANCE.getCount();
+    client->zForegroundWriter()->schreibe((char*)&count, 4);
+    for (int i = 0; i < count; i++)
+    {
+        EntityType* t = StaticRegistry<EntityType>::INSTANCE.zElement(i);
+        int id = t->getId();
+        client->zForegroundWriter()->schreibe((char*)&id, 4);
+        t->getModel().writeTo(client->zForegroundWriter());
+    }
+    foreground.unlock();
 }
 
-
 Game::Game(Framework::Text name, Framework::Text worldsDir)
-	: Thread(),
-	name(name),
-	dimensions(new RCArray<Dimension>()),
-	updates(new RCArray<WorldUpdate>()),
-	clients(new RCArray<GameClient>()),
-	ticker(new TickOrganizer()),
-	path((const char*)(worldsDir + "/" + name)),
-	stop(0),
-	tickId(0),
-	nextEntityId(0),
-	generator(0),
-	loader(0),
-	totalTickTime(0),
-	tickCounter(0)
-{
-	if (!DateiExistiert(worldsDir + "/" + name))
-		DateiPfadErstellen(worldsDir + "/" + name + "/");
-	Datei d;
-	d.setDatei(path + "/eid");
-	if (d.existiert())
-	{
-		d.open(Datei::Style::lesen);
-		d.lese((char*)&nextEntityId, 4);
-		d.close();
-	}
-	start();
+    : Thread(),
+      name(name),
+      dimensions(new RCArray<Dimension>()),
+      updates(new RCArray<WorldUpdate>()),
+      clients(new RCArray<GameClient>()),
+      ticker(new TickOrganizer()),
+      path((const char*)(worldsDir + "/" + name)),
+      stop(0),
+      tickId(0),
+      nextEntityId(0),
+      generator(0),
+      loader(0),
+      totalTickTime(0),
+      tickCounter(0)
+{
+    if (!DateiExistiert(worldsDir + "/" + name))
+        DateiPfadErstellen(worldsDir + "/" + name + "/");
+    Datei d;
+    d.setDatei(path + "/eid");
+    if (d.existiert())
+    {
+        d.open(Datei::Style::lesen);
+        d.lese((char*)&nextEntityId, 4);
+        d.close();
+    }
+    start();
 }
 
 Game::~Game()
 {
-	dimensions->release();
-	updates->release();
-	clients->release();
-	generator->release();
-	loader->release();
+    dimensions->release();
+    updates->release();
+    clients->release();
+    generator->release();
+    loader->release();
 }
 
 void Game::initialize()
 {
-	int seed = 0;
-	int index = 0;
-	for (const char* n = name; *n; n++)
-		seed += (int)pow((float)*n * 31, (float)++index);
-	generator = new WorldGenerator(seed);
-	loader = new WorldLoader();
-	recipies.loadRecipies("data/recipies");
+    int seed = 0;
+    int index = 0;
+    for (const char* n = name; *n; n++)
+        seed += (int)pow((float)*n * 31, (float)++index);
+    generator = new WorldGenerator(seed);
+    loader = new WorldLoader();
+    recipies.loadRecipies("data/recipies");
 }
 
 void Game::thread()
 {
-	ZeitMesser waitForLock;
-	ZeitMesser removeOldClients;
-	ZeitMesser tickEntities;
-	ZeitMesser worldUpdates;
-	ZeitMesser clientReply;
-	ZeitMesser removeOldChunks;
-	ZeitMesser m;
-	while (!stop)
-	{
-		m.messungStart();
-		ticker->nextTick();
-		actionsCs.lock();
-		while (actions.getEintragAnzahl() > 0)
-		{
-			actions.get(0)();
-			actions.remove(0);
-		}
-		actionsCs.unlock();
-		Array<int> removed;
-		double waitTotal = 0;
-		waitForLock.messungStart();
-		cs.lock();
-		waitForLock.messungEnde();
-		waitTotal += waitForLock.getSekunden();
-		removeOldClients.messungStart();
-		int index = 0;
-		for (auto player : *clients)
-		{
-			if (!player->isOnline())
-			{
-				std::cout << "player " << player->zEntity()->getName() << " disconnected.\n";
-				Datei pFile;
-				pFile.setDatei(path + "/player/" + player->zEntity()->getName());
-				pFile.erstellen();
-				if (pFile.open(Datei::Style::schreiben))
-					PlayerEntityType::INSTANCE->saveEntity(player->zEntity(), &pFile);
-				pFile.close();
-				removed.add(index, 0);
-				Dimension* dim = zDimension(player->zEntity()->getCurrentDimensionId());
-				dim->removeSubscriptions(player->zEntity());
-				this->requestWorldUpdate(new EntityRemovedUpdate(player->zEntity()->getId(), player->zEntity()->getCurrentDimensionId(), player->zEntity()->getPosition()));
-
-			}
-			index++;
-		}
-		for (auto i : removed)
-			clients->remove(i);
-		removeOldClients.messungEnde();
-		cs.unlock();
-		tickEntities.messungStart();
-		for (auto dim : *dimensions)
-			dim->tickEntities();
-		tickEntities.messungEnde();
-		waitForLock.messungStart();
-		cs.lock();
-		waitForLock.messungEnde();
-		waitTotal += waitForLock.getSekunden();
-		worldUpdates.messungStart();
-		while (updates->hat(0))
-		{
-			WorldUpdate* update = updates->z(0);
-			for (auto client : *clients)
-				client->sendWorldUpdate(dynamic_cast<WorldUpdate*>(update->getThis()));
-			if (!zDimension(update->getAffectedDimension()))
-				addDimension(new Dimension(update->getAffectedDimension()));
-			update->onUpdate(zDimension(update->getAffectedDimension()));
-			updates->remove(0);
-		}
-		worldUpdates.messungEnde();
-		cs.unlock();
-		clientReply.messungStart();
-		for (auto client : *clients)
-			client->reply();
-		clientReply.messungEnde();
-		waitForLock.messungStart();
-		cs.lock();
-		waitForLock.messungEnde();
-		waitTotal += waitForLock.getSekunden();
-		removeOldChunks.messungStart();
-		for (auto dim : *dimensions)
-			dim->removeOldChunks();
-		removeOldChunks.messungEnde();
-		cs.unlock();
-		m.messungEnde();
-		double sec = m.getSekunden();
-		tickCounter++;
-		totalTickTime += sec;
-		if (tickCounter >= 1000)
-		{
-			std::cout << "Average Tick time: " << (totalTickTime / 1000) << "\n";
-			if ((totalTickTime / 1000) * 20 > 1)
-			{
-				std::cout << "The game runns slower than normal.\n";
-			}
-			else
-			{
-				std::cout << "No performance issues detected.\n";
-			}
-			totalTickTime = 0;
-			tickCounter = 0;
-		}
-		if (sec < 0.05)
-			Sleep((int)((0.05 - sec) * 1000));
-		else if (sec > 1)
-		{
-			std::cout << "WARNING: tick needed " << sec << " seconds. The game will run sower then normal.\n";
-			std::cout << "waiting: " << waitTotal << "\nremoveOldClients: " << removeOldClients.getSekunden() << "\ntickEntities:" << tickEntities.getSekunden() << "\nworldUpdates: " << worldUpdates.getSekunden() << "\nclientReply: " << clientReply.getSekunden() << "\nremoveOldChunks:" << removeOldChunks.getSekunden() << "\n";
-		}
-	}
-	save();
+    ZeitMesser waitForLock;
+    ZeitMesser removeOldClients;
+    ZeitMesser tickEntities;
+    ZeitMesser worldUpdates;
+    ZeitMesser clientReply;
+    ZeitMesser removeOldChunks;
+    ZeitMesser m;
+    while (!stop)
+    {
+        m.messungStart();
+        ticker->nextTick();
+        actionsCs.lock();
+        while (actions.getEintragAnzahl() > 0)
+        {
+            actions.get(0)();
+            actions.remove(0);
+        }
+        actionsCs.unlock();
+        Array<int> removed;
+        double waitTotal = 0;
+        waitForLock.messungStart();
+        cs.lock();
+        waitForLock.messungEnde();
+        waitTotal += waitForLock.getSekunden();
+        removeOldClients.messungStart();
+        int index = 0;
+        for (auto player : *clients)
+        {
+            if (!player->isOnline())
+            {
+                std::cout << "player " << player->zEntity()->getName()
+                          << " disconnected.\n";
+                Datei pFile;
+                pFile.setDatei(
+                    path + "/player/" + player->zEntity()->getName());
+                pFile.erstellen();
+                if (pFile.open(Datei::Style::schreiben))
+                    StaticRegistry<EntityType>::INSTANCE
+                        .zElement(EntityTypeEnum::PLAYER)
+                        ->saveEntity(player->zEntity(), &pFile);
+                pFile.close();
+                removed.add(index, 0);
+                Dimension* dim
+                    = zDimension(player->zEntity()->getCurrentDimensionId());
+                dim->removeSubscriptions(player->zEntity());
+                this->requestWorldUpdate(
+                    new EntityRemovedUpdate(player->zEntity()->getId(),
+                        player->zEntity()->getCurrentDimensionId(),
+                        player->zEntity()->getPosition()));
+            }
+            index++;
+        }
+        for (auto i : removed)
+            clients->remove(i);
+        removeOldClients.messungEnde();
+        cs.unlock();
+        tickEntities.messungStart();
+        for (auto dim : *dimensions)
+            dim->tickEntities();
+        tickEntities.messungEnde();
+        waitForLock.messungStart();
+        cs.lock();
+        waitForLock.messungEnde();
+        waitTotal += waitForLock.getSekunden();
+        worldUpdates.messungStart();
+        while (updates->hat(0))
+        {
+            WorldUpdate* update = updates->z(0);
+            for (auto client : *clients)
+                client->sendWorldUpdate(
+                    dynamic_cast<WorldUpdate*>(update->getThis()));
+            if (!zDimension(update->getAffectedDimension()))
+                addDimension(new Dimension(update->getAffectedDimension()));
+            update->onUpdate(zDimension(update->getAffectedDimension()));
+            updates->remove(0);
+        }
+        worldUpdates.messungEnde();
+        cs.unlock();
+        clientReply.messungStart();
+        for (auto client : *clients)
+            client->reply();
+        clientReply.messungEnde();
+        waitForLock.messungStart();
+        cs.lock();
+        waitForLock.messungEnde();
+        waitTotal += waitForLock.getSekunden();
+        removeOldChunks.messungStart();
+        for (auto dim : *dimensions)
+            dim->removeOldChunks();
+        removeOldChunks.messungEnde();
+        cs.unlock();
+        m.messungEnde();
+        double sec = m.getSekunden();
+        tickCounter++;
+        totalTickTime += sec;
+        if (tickCounter >= 1000)
+        {
+            std::cout << "Average Tick time: " << (totalTickTime / 1000)
+                      << "\n";
+            if ((totalTickTime / 1000) * 20 > 1)
+            {
+                std::cout << "The game runns slower than normal.\n";
+            }
+            else
+            {
+                std::cout << "No performance issues detected.\n";
+            }
+            totalTickTime = 0;
+            tickCounter = 0;
+        }
+        if (sec < 0.05)
+            Sleep((int)((0.05 - sec) * 1000));
+        else if (sec > 1)
+        {
+            std::cout << "WARNING: tick needed " << sec
+                      << " seconds. The game will run sower then normal.\n";
+            std::cout << "waiting: " << waitTotal << "\nremoveOldClients: "
+                      << removeOldClients.getSekunden()
+                      << "\ntickEntities:" << tickEntities.getSekunden()
+                      << "\nworldUpdates: " << worldUpdates.getSekunden()
+                      << "\nclientReply: " << clientReply.getSekunden()
+                      << "\nremoveOldChunks:" << removeOldChunks.getSekunden()
+                      << "\n";
+        }
+    }
+    save();
 }
 
 void Game::api(Framework::InMemoryBuffer* zRequest, GameClient* zOrigin)
 {
-	char type;
-	zRequest->lese(&type, 1);
-	NetworkMessage* response = new NetworkMessage();
-	switch (type)
-	{
-	case 1: // world
-	{
-		Dimension* dim = zDimension(zOrigin->zEntity()->getCurrentDimensionId());
-		if (!dim)
-		{
-			dim = new Dimension(zOrigin->zEntity()->getCurrentDimensionId());
-			addDimension(dim);
-		}
-		dim->api(zRequest, response, zOrigin->zEntity());
-		break;
-	}
-	case 2: // player
-		zOrigin->zEntity()->playerApi(zRequest, response);
-		break;
-	case 3: // entity
-	{
-		int id;
-		zRequest->lese((char*)&id, 4);
-		for (Dimension* dim : *dimensions)
-		{
-			Entity* entity = dim->zEntity(id);
-			if (entity)
-			{
-				entity->api(zRequest, response);
-				break;
-			}
-		}
-		break;
-	}
-	case 4:
-	{ // inventory
-		bool isEntity;
-		zRequest->lese((char*)&isEntity, 1);
-		Inventory* target;
-		if (isEntity)
-		{
-			int id;
-			zRequest->lese((char*)&id, 4);
-			target = zEntity(id);
-		}
-		else
-		{
-			int dim;
-			Vec3<int> pos;
-			zRequest->lese((char*)&dim, 4);
-			zRequest->lese((char*)&pos.x, 4);
-			zRequest->lese((char*)&pos.y, 4);
-			zRequest->lese((char*)&pos.z, 4);
-			target = zBlockAt(pos, dim);
-		}
-		if (target)
-			target->inventoryApi(zRequest, response, zOrigin->zEntity());
-		break;
-	}
-	default:
-		std::cout << "received unknown api request in game with type " << (int)type << "\n";
-	}
-	if (!response->isEmpty())
-	{
-		if (response->isBroadcast())
-			broadcastMessage(response);
-		else
-			zOrigin->sendResponse(response);
-	}
-	else
-	{
-		response->release();
-	}
+    char type;
+    zRequest->lese(&type, 1);
+    NetworkMessage* response = new NetworkMessage();
+    switch (type)
+    {
+    case 1: // world
+        {
+            Dimension* dim
+                = zDimension(zOrigin->zEntity()->getCurrentDimensionId());
+            if (!dim)
+            {
+                dim = new Dimension(
+                    zOrigin->zEntity()->getCurrentDimensionId());
+                addDimension(dim);
+            }
+            dim->api(zRequest, response, zOrigin->zEntity());
+            break;
+        }
+    case 2: // player
+        zOrigin->zEntity()->playerApi(zRequest, response);
+        break;
+    case 3: // entity
+        {
+            int id;
+            zRequest->lese((char*)&id, 4);
+            for (Dimension* dim : *dimensions)
+            {
+                Entity* entity = dim->zEntity(id);
+                if (entity)
+                {
+                    entity->api(zRequest, response);
+                    break;
+                }
+            }
+            break;
+        }
+    case 4:
+        { // inventory
+            bool isEntity;
+            zRequest->lese((char*)&isEntity, 1);
+            Inventory* target;
+            if (isEntity)
+            {
+                int id;
+                zRequest->lese((char*)&id, 4);
+                target = zEntity(id);
+            }
+            else
+            {
+                int dim;
+                Vec3<int> pos;
+                zRequest->lese((char*)&dim, 4);
+                zRequest->lese((char*)&pos.x, 4);
+                zRequest->lese((char*)&pos.y, 4);
+                zRequest->lese((char*)&pos.z, 4);
+                target = zBlockAt(pos, dim);
+            }
+            if (target)
+                target->inventoryApi(zRequest, response, zOrigin->zEntity());
+            break;
+        }
+    default:
+        std::cout << "received unknown api request in game with type "
+                  << (int)type << "\n";
+    }
+    if (!response->isEmpty())
+    {
+        if (response->isBroadcast())
+            broadcastMessage(response);
+        else
+            zOrigin->sendResponse(response);
+    }
+    else
+    {
+        response->release();
+    }
 }
 
 void Game::updateLightning(int dimensionId, Vec3<int> location)
 {
-	Dimension* zDim = zDimension(dimensionId);
-	if (zDim)
-		zDim->updateLightning(location);
+    Dimension* zDim = zDimension(dimensionId);
+    if (zDim) zDim->updateLightning(location);
 }
 
 void Game::updateLightningWithoutWait(int dimensionId, Vec3<int> location)
 {
-	Dimension* zDim = zDimension(dimensionId);
-	if (zDim)
-		zDim->updateLightningWithoutWait(location);
+    Dimension* zDim = zDimension(dimensionId);
+    if (zDim) zDim->updateLightningWithoutWait(location);
 }
 
 void Game::broadcastMessage(NetworkMessage* response)
 {
-	for (auto client : *clients)
-		client->sendResponse(dynamic_cast<NetworkMessage*>(response->getThis()));
+    for (auto client : *clients)
+        client->sendResponse(
+            dynamic_cast<NetworkMessage*>(response->getThis()));
 }
 
 void Game::sendMessage(NetworkMessage* response, Entity* zTargetPlayer)
 {
-	for (auto client : *clients)
-	{
-		if (client->zEntity()->getId() == zTargetPlayer->getId())
-		{
-			client->sendResponse(response);
-			return;
-		}
-	}
-	response->release();
+    for (auto client : *clients)
+    {
+        if (client->zEntity()->getId() == zTargetPlayer->getId())
+        {
+            client->sendResponse(response);
+            return;
+        }
+    }
+    response->release();
 }
 
 bool Game::requestWorldUpdate(WorldUpdate* update)
 {
-	cs.lock();
-	for (WorldUpdate* u : *updates)
-	{
-		if (u->getMaxAffectedPoint().x >= update->getMinAffectedPoint().x && u->getMinAffectedPoint().x <= update->getMaxAffectedPoint().x &&
-			u->getMaxAffectedPoint().y >= update->getMinAffectedPoint().y && u->getMinAffectedPoint().y <= update->getMaxAffectedPoint().y &&
-			u->getMaxAffectedPoint().z >= update->getMinAffectedPoint().z && u->getMinAffectedPoint().z <= update->getMaxAffectedPoint().z && u->getType() == update->getType())
-		{
-			cs.unlock();
-			update->release();
-			return 0;
-		}
-	}
-	updates->add(update);
-	cs.unlock();
-	return 1;
+    cs.lock();
+    for (WorldUpdate* u : *updates)
+    {
+        if (u->getMaxAffectedPoint().x >= update->getMinAffectedPoint().x
+            && u->getMinAffectedPoint().x <= update->getMaxAffectedPoint().x
+            && u->getMaxAffectedPoint().y >= update->getMinAffectedPoint().y
+            && u->getMinAffectedPoint().y <= update->getMaxAffectedPoint().y
+            && u->getMaxAffectedPoint().z >= update->getMinAffectedPoint().z
+            && u->getMinAffectedPoint().z <= update->getMaxAffectedPoint().z
+            && u->getType() == update->getType())
+        {
+            cs.unlock();
+            update->release();
+            return 0;
+        }
+    }
+    updates->add(update);
+    cs.unlock();
+    return 1;
 }
 
 bool Game::checkPlayer(Framework::Text name, Framework::Text secret)
 {
-	Datei pFile;
-	pFile.setDatei(path + "/player/" + name + ".key");
-	if (!pFile.existiert())
-	{
-		if (!secret.getLength())
-			return 1;
-		else
-		{
-			std::cout << "player " << name.getText() << " tryed to connect with an invalid secret.\n";
-			return 0;
-		}
-	}
-	pFile.open(Datei::Style::lesen);
-	char* buffer = new char[(int)pFile.getSize()];
-	pFile.lese(buffer, (int)pFile.getSize());
-	bool eq = 1;
-	int sLen = secret.getLength();
-	for (int i = 0; i < pFile.getSize(); i++) // !!SECURITY!! runtime should not be dependent on the position of the first unequal character in the secret
-		eq &= buffer[i] == (sLen > i ? secret[i] : ~buffer[i]);
-	delete[] buffer;
-	pFile.close();
-	if (!eq)
-	{
-		std::cout << "player " << name.getText() << " tryed to connect with an invalid secret.\n";
-	}
-	return eq;
+    Datei pFile;
+    pFile.setDatei(path + "/player/" + name + ".key");
+    if (!pFile.existiert())
+    {
+        if (!secret.getLength())
+            return 1;
+        else
+        {
+            std::cout << "player " << name.getText()
+                      << " tryed to connect with an invalid secret.\n";
+            return 0;
+        }
+    }
+    pFile.open(Datei::Style::lesen);
+    char* buffer = new char[(int)pFile.getSize()];
+    pFile.lese(buffer, (int)pFile.getSize());
+    bool eq = 1;
+    int sLen = secret.getLength();
+    for (int i = 0; i < pFile.getSize();
+         i++) // !!SECURITY!! runtime should not be dependent on the position of
+              // the first unequal character in the secret
+        eq &= buffer[i] == (sLen > i ? secret[i] : ~buffer[i]);
+    delete[] buffer;
+    pFile.close();
+    if (!eq)
+    {
+        std::cout << "player " << name.getText()
+                  << " tryed to connect with an invalid secret.\n";
+    }
+    return eq;
 }
 
 bool Game::existsPlayer(Framework::Text name)
 {
-	Datei pFile;
-	pFile.setDatei(path + "/player/" + name + ".key");
-	return pFile.existiert();
+    Datei pFile;
+    pFile.setDatei(path + "/player/" + name + ".key");
+    return pFile.existiert();
 }
 
 Framework::Text Game::createPlayer(Framework::Text name)
 {
-	Datei pFile;
-	pFile.setDatei(path + "/player/" + name + ".key");
-	if (!pFile.existiert())
-	{
-		pFile.erstellen();
-		int keyLen;
-		char* key = randomKey(keyLen);
-		pFile.open(Datei::Style::schreiben);
-		pFile.schreibe(key, keyLen);
-		pFile.close();
-		Text res = "";
-		for (int i = 0; i < keyLen; i++)
-			res.append(key[i]);
-		delete[] key;
-		return res;
-	}
-	return "";
+    Datei pFile;
+    pFile.setDatei(path + "/player/" + name + ".key");
+    if (!pFile.existiert())
+    {
+        pFile.erstellen();
+        int keyLen;
+        char* key = randomKey(keyLen);
+        pFile.open(Datei::Style::schreiben);
+        pFile.schreibe(key, keyLen);
+        pFile.close();
+        Text res = "";
+        for (int i = 0; i < keyLen; i++)
+            res.append(key[i]);
+        delete[] key;
+        return res;
+    }
+    return "";
 }
 
 GameClient* Game::addPlayer(FCKlient* client, Framework::Text name)
 {
-	cs.lock();
-	Datei pFile;
-	pFile.setDatei(path + "/player/" + name);
-	std::cout << "player " << name.getText() << " connected.\n";
-	Player* player;
-	bool isNew = 0;
-	if (!pFile.existiert() || !pFile.open(Datei::Style::lesen))
-	{
-		player = (Player*)PlayerEntityType::INSTANCE->createEntityAt(Vec3<float>(0.5, 0.5, 0), OverworldDimension::ID);
-		player->setName(name);
-		isNew = 1;
-	}
-	else
-	{
-		player = (Player*)PlayerEntityType::INSTANCE->loadEntity(&pFile);
-		pFile.close();
-	}
-	if (player->getId() >= nextEntityId)
-	{
-		nextEntityId = player->getId() + 1;
-	}
-	GameClient* gameClient = new GameClient(player, client);
-	gameClient->sendTypes();
-	clients->add(gameClient);
-	if (!zDimension(player->getCurrentDimensionId()))
-	{
-		this->addDimension(new Dimension(player->getCurrentDimensionId()));
-	}
-	// subscribe the new player as an observer of the new chunk
-	Dimension* dim = zDimension(player->getCurrentDimensionId());
-	InMemoryBuffer* buffer = new InMemoryBuffer();
-	buffer->schreibe("\0", 1);
-	Punkt center = getChunkCenter((int)player->getPosition().x, (int)player->getPosition().y);
-	buffer->schreibe((char*)&center.x, 4);
-	buffer->schreibe((char*)&center.y, 4);
-	buffer->schreibe("\0", 1);
-	dim->api(buffer, 0, player);
-	buffer->release();
-	while (isNew && !dim->zChunk(getChunkCenter((int)player->getPosition().x, (int)player->getPosition().y)))
-	{
-		cs.unlock();
-		Sleep(1000);
-		cs.lock();
-	}
-	if (isNew)
-	{
-		Either<Block*, int> b = AirBlockBlockType::ID;
-		int h = WORLD_HEIGHT;
-		while (((b.isA() && (!(Block*)b || ((Block*)b)->isPassable())) || (b.isB() && StaticRegistry<BlockType>::INSTANCE.zElement(b)->zDefault()->isPassable())) && h > 0)
-			b = zBlockAt({ (int)player->getPosition().x, (int)player->getPosition().y, --h }, player->getCurrentDimensionId());
-		player->setPosition({ player->getPosition().x, player->getPosition().y, (float)h + 1.f });
-	}
-	requestWorldUpdate(new AddEntityUpdate(player, player->getCurrentDimensionId()));
-	cs.unlock();
-	return dynamic_cast<GameClient*>(gameClient->getThis());
+    cs.lock();
+    Datei pFile;
+    pFile.setDatei(path + "/player/" + name);
+    std::cout << "player " << name.getText() << " connected.\n";
+    Player* player;
+    bool isNew = 0;
+    if (!pFile.existiert() || !pFile.open(Datei::Style::lesen))
+    {
+        player = (Player*)StaticRegistry<EntityType>::INSTANCE
+                     .zElement(EntityTypeEnum::PLAYER)
+                     ->createEntityAt(
+                         Vec3<float>(0.5, 0.5, 0), DimensionEnum::OVERWORLD);
+        player->setName(name);
+        isNew = 1;
+    }
+    else
+    {
+        player = (Player*)StaticRegistry<EntityType>::INSTANCE
+                     .zElement(EntityTypeEnum::PLAYER)
+                     ->loadEntity(&pFile);
+        pFile.close();
+    }
+    if (player->getId() >= nextEntityId)
+    {
+        nextEntityId = player->getId() + 1;
+    }
+    GameClient* gameClient = new GameClient(player, client);
+    gameClient->sendTypes();
+    clients->add(gameClient);
+    if (!zDimension(player->getCurrentDimensionId()))
+    {
+        this->addDimension(new Dimension(player->getCurrentDimensionId()));
+    }
+    // subscribe the new player as an observer of the new chunk
+    Dimension* dim = zDimension(player->getCurrentDimensionId());
+    InMemoryBuffer* buffer = new InMemoryBuffer();
+    buffer->schreibe("\0", 1);
+    Punkt center = getChunkCenter(
+        (int)player->getPosition().x, (int)player->getPosition().y);
+    buffer->schreibe((char*)&center.x, 4);
+    buffer->schreibe((char*)&center.y, 4);
+    buffer->schreibe("\0", 1);
+    dim->api(buffer, 0, player);
+    buffer->release();
+    while (isNew
+           && !dim->zChunk(getChunkCenter(
+               (int)player->getPosition().x, (int)player->getPosition().y)))
+    {
+        cs.unlock();
+        Sleep(1000);
+        cs.lock();
+    }
+    if (isNew)
+    {
+        Either<Block*, int> b = BlockTypeEnum::AIR;
+        int h = WORLD_HEIGHT;
+        while (((b.isA() && (!(Block*)b || ((Block*)b)->isPassable()))
+                   || (b.isB()
+                       && StaticRegistry<BlockType>::INSTANCE.zElement(b)
+                              ->zDefault()
+                              ->isPassable()))
+               && h > 0)
+            b = zBlockAt({(int)player->getPosition().x,
+                             (int)player->getPosition().y,
+                             --h},
+                player->getCurrentDimensionId());
+        player->setPosition(
+            {player->getPosition().x, player->getPosition().y, (float)h + 1.f});
+    }
+    requestWorldUpdate(
+        new AddEntityUpdate(player, player->getCurrentDimensionId()));
+    cs.unlock();
+    return dynamic_cast<GameClient*>(gameClient->getThis());
 }
 
 bool Game::isChunkLoaded(int x, int y, int dimension) const
 {
-	Dimension* dim = zDimension(dimension);
-	return (dim && dim->hasChunck(x, y));
+    Dimension* dim = zDimension(dimension);
+    return (dim && dim->hasChunck(x, y));
 }
 
 bool Game::doesChunkExist(int x, int y, int dimension)
 {
-	cs.lock();
-	bool result = isChunkLoaded(x, y, dimension) || loader->existsChunk(x, y, dimension);
-	cs.unlock();
-	return result;
+    cs.lock();
+    bool result = isChunkLoaded(x, y, dimension)
+               || loader->existsChunk(x, y, dimension);
+    cs.unlock();
+    return result;
 }
 
-Framework::Either<Block*, int> Game::zBlockAt(Framework::Vec3<int> location, int dimension) const
+Framework::Either<Block*, int> Game::zBlockAt(
+    Framework::Vec3<int> location, int dimension) const
 {
-	Dimension* dim = zDimension(dimension);
-	if (dim)
-		return dim->zBlock(location);
-	return 0;
+    Dimension* dim = zDimension(dimension);
+    if (dim) return dim->zBlock(location);
+    return 0;
 }
 
 Block* Game::zRealBlockInstance(Framework::Vec3<int> location, int dimension)
 {
-	Dimension* dim = zDimension(dimension);
-	if (dim)
-		return dim->zRealBlockInstance(location);
-	return 0;
+    Dimension* dim = zDimension(dimension);
+    if (dim) return dim->zRealBlockInstance(location);
+    return 0;
 }
 
 Dimension* Game::zDimension(int id) const
 {
-	for (auto dim : *dimensions)
-	{
-		if (dim->getDimensionId() == id)
-			return dim;
-	}
-	return 0;
+    for (auto dim : *dimensions)
+    {
+        if (dim->getDimensionId() == id) return dim;
+    }
+    return 0;
 }
 
 Framework::Punkt Game::getChunkCenter(int x, int y)
 {
-	return Punkt(((x < 0 ? x + 1 : x) / CHUNK_SIZE) * CHUNK_SIZE + (x < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2, ((y < 0 ? y + 1 : y) / CHUNK_SIZE) * CHUNK_SIZE + (y < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2);
+    return Punkt(((x < 0 ? x + 1 : x) / CHUNK_SIZE) * CHUNK_SIZE
+                     + (x < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2,
+        ((y < 0 ? y + 1 : y) / CHUNK_SIZE) * CHUNK_SIZE
+            + (y < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2);
 }
 
 Area Game::getChunckArea(Punkt center) const
 {
-	return { center.x - CHUNK_SIZE / 2, center.y - CHUNK_SIZE / 2, center.x + CHUNK_SIZE / 2 - 1, center.y + CHUNK_SIZE / 2 - 1, 0 };
+    return {center.x - CHUNK_SIZE / 2,
+        center.y - CHUNK_SIZE / 2,
+        center.x + CHUNK_SIZE / 2 - 1,
+        center.y + CHUNK_SIZE / 2 - 1,
+        0};
 }
 
 Framework::Text Game::getWorldDirectory() const
 {
-	return path;
+    return path;
 }
 
 void Game::requestArea(Area area)
 {
-	generator->requestGeneration(area);
-	loader->requestLoading(area);
+    generator->requestGeneration(area);
+    loader->requestLoading(area);
 }
 
 void Game::save() const
 {
-	Datei d;
-	d.setDatei(path + "/eid");
-	d.open(Datei::Style::schreiben);
-	d.schreibe((char*)&nextEntityId, 4);
-	d.close();
-	for (auto dim : *dimensions)
-		dim->save(path);
+    Datei d;
+    d.setDatei(path + "/eid");
+    d.open(Datei::Style::schreiben);
+    d.schreibe((char*)&nextEntityId, 4);
+    d.close();
+    for (auto dim : *dimensions)
+        dim->save(path);
 }
 
 void Game::requestStop()
 {
-	stop = 1;
-	warteAufThread(1000000);
+    stop = 1;
+    warteAufThread(1000000);
 }
 
 void Game::addDimension(Dimension* d)
 {
-	dimensions->add(d);
+    dimensions->add(d);
 }
 
 int Game::getNextEntityId()
 {
-	cs.lock();
-	int result = nextEntityId++;
-	cs.unlock();
-	return result;
+    cs.lock();
+    int result = nextEntityId++;
+    cs.unlock();
+    return result;
 }
 
 WorldGenerator* Game::zGenerator() const
 {
-	return generator;
+    return generator;
 }
 
 Game* Game::INSTANCE = 0;
 
 void Game::initialize(Framework::Text name, Framework::Text worldsDir)
 {
-	if (!Game::INSTANCE)
-	{
-		Game::INSTANCE = new Game(name, worldsDir);
-		Game::INSTANCE->initialize();
-	}
+    if (!Game::INSTANCE)
+    {
+        Game::INSTANCE = new Game(name, worldsDir);
+        Game::INSTANCE->initialize();
+    }
 }
 
 Entity* Game::zEntity(int id, int dimensionId) const
 {
-	Dimension* d = zDimension(dimensionId);
-	if (d)
-		return d->zEntity(id);
-	return 0;
+    Dimension* d = zDimension(dimensionId);
+    if (d) return d->zEntity(id);
+    return 0;
 }
 
 Entity* Game::zEntity(int id) const
 {
-	for (Dimension* d : *dimensions)
-	{
-		Entity* e = d->zEntity(id);
-		if (e)
-			return e;
-	}
-	// for new players that are currently loading
-	for (GameClient* client : *clients)
-	{
-		if (client->zEntity()->getId() == id)
-		{
-			return client->zEntity();
-		}
-	}
-	return 0;
+    for (Dimension* d : *dimensions)
+    {
+        Entity* e = d->zEntity(id);
+        if (e) return e;
+    }
+    // for new players that are currently loading
+    for (GameClient* client : *clients)
+    {
+        if (client->zEntity()->getId() == id)
+        {
+            return client->zEntity();
+        }
+    }
+    return 0;
 }
 
-Entity* Game::zNearestEntity(int dimensionId, Framework::Vec3<float> pos, std::function<bool(Entity*)> filter)
+Entity* Game::zNearestEntity(int dimensionId,
+    Framework::Vec3<float> pos,
+    std::function<bool(Entity*)> filter)
 {
-	Dimension* d = zDimension(dimensionId);
-	if (!d)
-		return 0;
-	return d->zNearestEntity(pos, filter);
+    Dimension* d = zDimension(dimensionId);
+    if (!d) return 0;
+    return d->zNearestEntity(pos, filter);
 }
 
 const RecipieLoader& Game::getRecipies() const
 {
-	return recipies;
+    return recipies;
 }
 
 void Game::doLater(std::function<void()> action)
 {
-	actionsCs.lock();
-	actions.add(action);
-	actionsCs.unlock();
+    actionsCs.lock();
+    actions.add(action);
+    actionsCs.unlock();
 }

+ 1 - 1
FactoryCraft/GeneratedStructure.cpp

@@ -68,7 +68,7 @@ Framework::Either<Block*, int> GeneratedStructure::generateBlockAt(Framework::Ve
 				blocks[index]->addToStructure(dynamic_cast<MultiblockStructure*>(multiblock->getThis()));
 				return blocks[index];
 			}
-			if (blockIds[index] && blockIds[index] != AirBlockBlockType::ID)
+			if (blockIds[index] && blockIds[index] != BlockTypeEnum::AIR)
 			{
 				Block* result = StaticRegistry<BlockType>::INSTANCE.zElement(blockIds[index])->createBlockAt(minAffectedPos + localPos, 0);
 				if (result)

+ 44 - 28
FactoryCraft/GrasslandBiom.cpp

@@ -1,53 +1,69 @@
 #include "GrasslandBiom.h"
-#include "BlockType.h"
+
 #include "BasicBlocks.h"
+#include "BlockType.h"
 #include "FastNoiseLite.h"
 #include "FastNoiseWrapper.h"
-#include "TreeTemplate.h"
 #include "NoBlock.h"
+#include "TreeTemplate.h"
 
-
-GrasslandBiom::GrasslandBiom()
-	: BiomGenerator()
+GrasslandBiom::GrasslandBiom() : BiomGenerator()
 {
-	addTemplateGenerator(new TreeTemplate(0.02f, BirchBlockType::INSTANCE, BirchLeavesBlockType::INSTANCE, 8, 15));
-	addTemplateGenerator(new TreeTemplate(0.01f, BeechBlockType::INSTANCE, BeechLeavesBlockType::INSTANCE, 8, 13));
-	addTemplateGenerator(new TreeTemplate(0.005f, OakBlockType::INSTANCE, OakLeavesBlockType::INSTANCE, 10, 15));
-	addTemplateGenerator(new TreeTemplate(0.0025f, PineBlockType::INSTANCE, PineLeavesBlockType::INSTANCE, 15, 24));
-	heightNoise = 0;
+    addTemplateGenerator(new TreeTemplate(0.02f,
+        BlockTypeEnum::WOOD_BIRCH,
+        BlockTypeEnum::LEAVES_WOOD_BIRCH,
+        8,
+        15));
+    addTemplateGenerator(new TreeTemplate(0.01f,
+        BlockTypeEnum::WOOD_BEECH,
+        BlockTypeEnum::LEAVES_WOOD_BEECH,
+        8,
+        13));
+    addTemplateGenerator(new TreeTemplate(0.005f,
+        BlockTypeEnum::WOOD_OAK,
+        BlockTypeEnum::LEAVES_WOOD_OAK,
+        10,
+        15));
+    addTemplateGenerator(new TreeTemplate(0.0025f,
+        BlockTypeEnum::WOOD_PINE,
+        BlockTypeEnum::LEAVES_WOOD_PINE,
+        15,
+        24));
+    heightNoise = 0;
 }
 
 GrasslandBiom::~GrasslandBiom()
 {
-	if (heightNoise)
-		heightNoise->release();
+    if (heightNoise) heightNoise->release();
 }
 
-Framework::Either<Block*, int> GrasslandBiom::generateSurfaceBlock(int x, int y, int z)
+Framework::Either<Block*, int> GrasslandBiom::generateSurfaceBlock(
+    int x, int y, int z)
 {
-	if (((float)rand() / (float)RAND_MAX) < 0.05f) // TODO: use random noise
-		return CobbleBlockType::ID;
-	return DirtBlockType::ID;
+    if (((float)rand() / (float)RAND_MAX) < 0.05f) // TODO: use random noise
+        return BlockTypeEnum::STONE_COBBLE;
+    return BlockTypeEnum::DIRT;
 }
 
-Framework::Either<Block*, int> GrasslandBiom::generateBelowSurfaceBlock(int x, int y, int z)
+Framework::Either<Block*, int> GrasslandBiom::generateBelowSurfaceBlock(
+    int x, int y, int z)
 {
-	return StoneBlockType::ID;
+    return BlockTypeEnum::STONE;
 }
 
-Framework::Either<Block*, int> GrasslandBiom::generateCaveBlock(int x, int y, int z)
+Framework::Either<Block*, int> GrasslandBiom::generateCaveBlock(
+    int x, int y, int z)
 {
-	return AirBlockBlockType::ID;
+    return BlockTypeEnum::AIR;
 }
 
 Noise* GrasslandBiom::zHeightMapNoise(int seed)
 {
-	if (heightNoise)
-		return heightNoise;
-	FastNoiseLite* noise = new FastNoiseLite(seed);
-	noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_ValueCubic);
-	FastNoiseWrapper* wrapper = new FastNoiseWrapper(noise, seed);
-	wrapper->setMultiplier(0.2f);
-	heightNoise = wrapper;
-	return heightNoise;
+    if (heightNoise) return heightNoise;
+    FastNoiseLite* noise = new FastNoiseLite(seed);
+    noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_ValueCubic);
+    FastNoiseWrapper* wrapper = new FastNoiseWrapper(noise, seed);
+    wrapper->setMultiplier(0.2f);
+    heightNoise = wrapper;
+    return heightNoise;
 }

+ 49 - 54
FactoryCraft/Item.cpp

@@ -1,128 +1,123 @@
 #include "Item.h"
-#include <Text.h>
 
+#include <Text.h>
 
-Item::Item(const ItemType* zType, const char* name)
-	: ReferenceCounter(),
-	zType(zType),
-	zBlockType(0),
-	hp(1),
-	maxHp(1),
-	durability(1),
-	maxDurability(1),
-	eatable(0),
-	placeable(0),
-	equippable(0),
-	solid(1),
-	usable(0),
-	maxStackSize(50),
-	name(name)
+Item::Item(int itemTypeId, const char* name)
+    : ReferenceCounter(),
+      itemTypeId(itemTypeId),
+      blockTypeId(0),
+      hp(1),
+      maxHp(1),
+      durability(1),
+      maxDurability(1),
+      eatable(0),
+      placeable(0),
+      equippable(0),
+      solid(1),
+      usable(0),
+      maxStackSize(50),
+      name(name)
 {}
 
 void Item::setHp(float hp)
 {
-	this->hp = hp;
+    this->hp = hp;
 }
 
-void Item::tick()
-{}
+void Item::tick() {}
 
 const ItemType* Item::zItemType() const
 {
-	return zType;
+    return StaticRegistry<ItemType>::INSTANCE.zElement(itemTypeId);
+}
+
+int Item::getTypeId() const
+{
+	return itemTypeId;
 }
 
 const BlockType* Item::zPlacedBlockType() const
 {
-	return zBlockType;
+    return StaticRegistry<BlockType>::INSTANCE.zElement(blockTypeId);
 }
 
 float Item::getHp() const
 {
-	return hp;
+    return hp;
 }
 
 float Item::getDurability() const
 {
-	return durability;
+    return durability;
 }
 
 bool Item::isUsable() const
 {
-	return usable;
+    return usable;
 }
 
 bool Item::isEatable() const
 {
-	return eatable;
+    return eatable;
 }
 
 bool Item::isPlaceable() const
 {
-	return placeable;
+    return placeable;
 }
 
 bool Item::isEquippable() const
 {
-	return equippable;
+    return equippable;
 }
 
 bool Item::isSolid() const
 {
-	return solid;
+    return solid;
 }
 
 float Item::getMaxDurability() const
 {
-	return maxDurability;
+    return maxDurability;
 }
 
 int Item::getMaxStackSize() const
 {
-	return maxStackSize;
+    return maxStackSize;
 }
 
 float Item::getMaxHp() const
 {
-	return maxHp;
+    return maxHp;
 }
 
 bool Item::canBeStackedWith(const Item* zItem) const
 {
-	return zType == zItem->zType &&
-		durability == maxDurability &&
-		zItem->durability == zItem->maxDurability &&
-		maxHp == zItem->maxHp &&
-		eatable == zItem->eatable &&
-		placeable == zItem->placeable &&
-		equippable == zItem->eatable &&
-		solid == zItem->solid &&
-		usable == zItem->usable &&
-		maxStackSize == zItem->maxStackSize &&
-		name.istGleich(zItem->name);
+    return itemTypeId == zItem->itemTypeId && durability == maxDurability
+        && zItem->durability == zItem->maxDurability && maxHp == zItem->maxHp
+        && eatable == zItem->eatable && placeable == zItem->placeable
+        && equippable == zItem->eatable && solid == zItem->solid
+        && usable == zItem->usable && maxStackSize == zItem->maxStackSize
+        && name.istGleich(zItem->name);
 }
 
 void Item::onPlaced()
 {
-	hp = 0;
+    hp = 0;
 }
 
 Framework::Text Item::getTooltipUIML() const
 {
-	return Framework::Text("<tip><text width=\"auto\" height=\"auto\">") + name + "</text></tip>";
+    return Framework::Text("<tip><text width=\"auto\" height=\"auto\">") + name
+         + "</text></tip>";
 }
 
-void Item::applyInventoryEffects(Entity* zTarget)
-{}
+void Item::applyInventoryEffects(Entity* zTarget) {}
 
-void Item::removeInventoryEffects(Entity* zTarget)
-{}
+void Item::removeInventoryEffects(Entity* zTarget) {}
 
-void Item::applyEquippedEffects(Entity* zTarget)
-{}
+void Item::applyEquippedEffects(Entity* zTarget) {}
 
-void Item::removeEquippedEffects(Entity* zTarget)
-{}
+void Item::removeEquippedEffects(Entity* zTarget) {}
 
-void Item::applyFoodEffects(Entity* zTarget)
-{}
+void Item::applyFoodEffects(Entity* zTarget) {}

+ 39 - 37
FactoryCraft/Item.h

@@ -10,46 +10,48 @@ class StoneToolItemType;
 class Item : public virtual Framework::ReferenceCounter
 {
 protected:
-	const ItemType* zType;
-	const BlockType* zBlockType;
-	float hp; // an item will be removed once its hp reaches 0
-	float maxHp;
-	float durability; // an item will break into another item once its durability reaches 0
-	float maxDurability;
-	bool eatable;
-	bool placeable;
-	bool equippable;
-	bool solid;
-	bool usable;
-	int maxStackSize;
-	Framework::Text name;
-	Item(const ItemType* zType, const char* name);
+    int itemTypeId;
+    int blockTypeId;
+    float hp; // an item will be removed once its hp reaches 0
+    float maxHp;
+    float durability; // an item will break into another item once its
+                      // durability reaches 0
+    float maxDurability;
+    bool eatable;
+    bool placeable;
+    bool equippable;
+    bool solid;
+    bool usable;
+    int maxStackSize;
+    Framework::Text name;
+    Item(int itemTypeId, const char* name);
 
 public:
-	void setHp(float hp);
-	virtual void tick();
+    void setHp(float hp);
+    virtual void tick();
 
-	const ItemType* zItemType() const;
-	const BlockType* zPlacedBlockType() const;
-	float getHp() const;
-	float getDurability() const;
-	bool isUsable() const;
-	bool isEatable() const;
-	bool isPlaceable() const;
-	bool isEquippable() const;
-	bool isSolid() const;
-	float getMaxDurability() const;
-	int getMaxStackSize() const;
-	float getMaxHp() const;
-	virtual bool canBeStackedWith(const Item* zItem) const;
-	virtual void onPlaced();
-	virtual Framework::Text getTooltipUIML() const;
+    const ItemType* zItemType() const;
+    int getTypeId() const;
+    const BlockType* zPlacedBlockType() const;
+    float getHp() const;
+    float getDurability() const;
+    bool isUsable() const;
+    bool isEatable() const;
+    bool isPlaceable() const;
+    bool isEquippable() const;
+    bool isSolid() const;
+    float getMaxDurability() const;
+    int getMaxStackSize() const;
+    float getMaxHp() const;
+    virtual bool canBeStackedWith(const Item* zItem) const;
+    virtual void onPlaced();
+    virtual Framework::Text getTooltipUIML() const;
 
-	virtual void applyInventoryEffects(Entity* zTarget);
-	virtual void removeInventoryEffects(Entity* zTarget);
-	virtual void applyEquippedEffects(Entity* zTarget);
-	virtual void removeEquippedEffects(Entity* zTarget);
-	virtual void applyFoodEffects(Entity* zTarget);
+    virtual void applyInventoryEffects(Entity* zTarget);
+    virtual void removeInventoryEffects(Entity* zTarget);
+    virtual void applyEquippedEffects(Entity* zTarget);
+    virtual void removeEquippedEffects(Entity* zTarget);
+    virtual void applyFoodEffects(Entity* zTarget);
 
-	friend ItemType;
+    friend ItemType;
 };

+ 11 - 4
FactoryCraft/ItemEntity.cpp

@@ -3,7 +3,7 @@
 
 
 ItemEntity::ItemEntity(Framework::Vec3<float> location, int dimensionId, int entityId)
-	: Entity(ItemEntityType::INSTANCE, location, dimensionId, entityId)
+    : Entity(EntityTypeEnum::ITEM, location, dimensionId, entityId)
 {
 	slot = new ItemSlot("Inventory", __INT32_MAX__, 0, 0, 0, ANY_DIRECTION, 0);
 	addSlot(slot);
@@ -28,7 +28,11 @@ void ItemEntity::prepareTick(const Dimension* zDimension)
 	{
 		Entity* zOther = Game::INSTANCE->zNearestEntity(currentDimensionId, location, [this](Entity* zOther)
 			{
-				return zOther != this && zOther->numberOfAddableItems(slot->zStack(), NO_DIRECTION) && (!this->slot->isFull() || zOther->zType()->getId() != ItemEntityType::ID);
+                return zOther != this
+                    && zOther->numberOfAddableItems(
+                        slot->zStack(), NO_DIRECTION)
+                    && (!this->slot->isFull()
+                        || zOther->zType()->getId() != EntityTypeEnum::ITEM);
 			});
 		if (zOther)
 		{
@@ -47,7 +51,10 @@ void ItemEntity::tick(const Dimension* zDimension)
 {
 	Entity* zOther = Game::INSTANCE->zNearestEntity(currentDimensionId, location, [this](Entity* zOther)
 		{
-			return zOther != this && zOther->numberOfAddableItems(slot->zStack(), NO_DIRECTION) && (!this->slot->isFull() || zOther->zType()->getId() != ItemEntityType::ID);
+            return zOther != this
+                && zOther->numberOfAddableItems(slot->zStack(), NO_DIRECTION)
+                && (!this->slot->isFull()
+                    || zOther->zType()->getId() != EntityTypeEnum::ITEM);
 		});
 	if (zOther)
 	{
@@ -84,7 +91,7 @@ ModelInfo ItemEntity::getSpecialModel() const
 
 
 ItemEntityType::ItemEntityType()
-	: EntityType(ID, ModelInfo("", "", 0))
+    : EntityType(EntityTypeEnum::ITEM, ModelInfo("", "", 0))
 {}
 
 Entity* ItemEntityType::createEntity(Framework::Vec3<float> position, int dimensionId, int entityId) const

+ 1 - 4
FactoryCraft/ItemEntity.h

@@ -25,11 +25,8 @@ public:
 
 class ItemEntityType : public EntityType
 {
-	REGISTRABLE(ItemEntityType)
-
 public:
 	ItemEntityType();
 
 	virtual Entity* createEntity(Framework::Vec3<float> position, int dimensionId, int entityId) const override;
-};
-REGISTER(ItemEntityType, EntityType)
+};

+ 30 - 18
FactoryCraft/ItemSkill.cpp

@@ -1,31 +1,43 @@
 #include "ItemSkill.h"
 
+#include "ItemType.h"
+#include "StaticRegistry.h"
 
-ItemSkill::ItemSkill(const ItemType* zSkillType)
-	: Framework::ReferenceCounter(),
-	skillType(zSkillType)
+ItemSkill::ItemSkill(int itemTypeId)
+    : Framework::ReferenceCounter(),
+      itemTypeId(itemTypeId)
 {}
 
 const ItemType* ItemSkill::zSkillType()
 {
-	return skillType;
+    return StaticRegistry<ItemType>::INSTANCE.zElement(itemTypeId);
 }
 
+int ItemSkill::getTypeId()
+{
+	return itemTypeId;
+}
 
-BasicItemSkill::BasicItemSkill(const ItemType* zSkillType, float maxXP, float durabilityModifier, float speedModifier, float luckModifier, float staminaModifier, float hungerModifier, float xpIncrease)
-	: ItemSkill(zSkillType),
-	level(1),
-	xp(0),
-	maxXP(maxXP),
-	durabilityModifier(durabilityModifier),
-	speedModifier(speedModifier),
-	luckModifier(luckModifier),
-	staminaModifier(staminaModifier),
-	hungerModifier(hungerModifier)
-{}
 
-void BasicItemSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
+BasicItemSkill::BasicItemSkill(int itemTypeId,
+    float maxXP,
+    float durabilityModifier,
+    float speedModifier,
+    float luckModifier,
+    float staminaModifier,
+    float hungerModifier,
+    float xpIncrease)
+    : ItemSkill(itemTypeId),
+      level(1),
+      xp(0),
+      maxXP(maxXP),
+      durabilityModifier(durabilityModifier),
+      speedModifier(speedModifier),
+      luckModifier(luckModifier),
+      staminaModifier(staminaModifier),
+      hungerModifier(hungerModifier)
 {}
 
-void BasicItemSkill::use(Entity* zActor, Item* zUsedItem, Entity* zTarget)
-{}
+void BasicItemSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget) {}
+
+void BasicItemSkill::use(Entity* zActor, Item* zUsedItem, Entity* zTarget) {}

+ 29 - 21
FactoryCraft/ItemSkill.h

@@ -1,10 +1,10 @@
 #pragma once
 
-#include "Reader.h"
-
 #include <JSON.h>
 #include <ReferenceCounter.h>
 
+#include "Reader.h"
+
 class ItemType;
 class ItemSkill;
 class Block;
@@ -15,38 +15,46 @@ class Item;
 class ItemSkillLevelUpRule : public virtual Framework::ReferenceCounter
 {
 public:
-	virtual void applyOn(ItemSkill* zSkill) = 0;
+    virtual void applyOn(ItemSkill* zSkill) = 0;
 };
 
 class ItemSkill : public virtual Framework::ReferenceCounter
 {
 private:
-	const ItemType* skillType;
+    const int itemTypeId;
 
 public:
-	ItemSkill(const ItemType* zSkillType);
-	virtual void use(Entity* zActor, Item* zUsedItem, Block* zTarget) = 0;
-	virtual void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) = 0;
-	const ItemType* zSkillType();
+    ItemSkill(int itemTypeId);
+    virtual void use(Entity* zActor, Item* zUsedItem, Block* zTarget) = 0;
+    virtual void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) = 0;
+    const ItemType* zSkillType();
+    int getTypeId();
 };
 
 class BasicItemSkill : public ItemSkill
 {
 protected:
-	int level;
-	float xp;
-	float maxXP;
-	float durabilityModifier;
-	float speedModifier;
-	float luckModifier;
-	float staminaModifier;
-	float hungerModifier;
-
-	BasicItemSkill(const ItemType* zSkillType, float maxXp = 100.f, float durabilityModifier = 1.f, float speedModifier = 1.f, float luckModifier = 1.f, float staminaModifier = 1.f, float hungerModifier = 1.f, float xpIncrease = 1.1f);
+    int level;
+    float xp;
+    float maxXP;
+    float durabilityModifier;
+    float speedModifier;
+    float luckModifier;
+    float staminaModifier;
+    float hungerModifier;
+
+    BasicItemSkill(int itemTypeId,
+        float maxXp = 100.f,
+        float durabilityModifier = 1.f,
+        float speedModifier = 1.f,
+        float luckModifier = 1.f,
+        float staminaModifier = 1.f,
+        float hungerModifier = 1.f,
+        float xpIncrease = 1.1f);
 
 public:
-	virtual void use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
-	virtual void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
+    virtual void use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
+    virtual void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
 
-	friend ItemType;
+    friend ItemType;
 };

+ 114 - 97
FactoryCraft/ItemType.cpp

@@ -1,158 +1,175 @@
 
+#include "ItemType.h"
+
 #include <InMemoryBuffer.h>
 
-#include "ItemType.h"
 #include "ItemSkill.h"
 #include "ItemStack.h"
 
-ItemType::ItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType, ModelInfo model)
-	: ReferenceCounter(),
-	id(id),
-	name(name),
-	levelUpRule(levelUpRule),
-	zBrokenType(zBrokenType),
-	model(model)
+ItemType::ItemType(int id,
+    const char* name,
+    ItemSkillLevelUpRule* levelUpRule,
+    int brokenTypeId,
+    ModelInfo model)
+    : ReferenceCounter(),
+      id(id),
+      name(name),
+      levelUpRule(levelUpRule),
+      brokenTypeId(brokenTypeId),
+      model(model)
 {
-	StaticRegistry<ItemType>::INSTANCE.registerT(this, id);
+    StaticRegistry<ItemType>::INSTANCE.registerT(this, id);
 }
 
 ItemType::~ItemType()
 {
-	if (levelUpRule)
-		levelUpRule->release();
-}
-
-void ItemType::loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const
-{
-	zReader->lese((char*)&zItem->hp, 4);
-	zReader->lese((char*)&zItem->maxHp, 4);
-	zReader->lese((char*)&zItem->durability, 4);
-	zReader->lese((char*)&zItem->maxDurability, 4);
-	unsigned char flags = 0;
-	zReader->lese((char*)&flags, 1);
-	zItem->eatable = (flags | 1) == flags;
-	zItem->placeable = (flags | 2) == flags;
-	zItem->equippable = (flags | 4) == flags;
-	zItem->solid = (flags | 8) == flags;
-	zItem->usable = (flags | 16) == flags;
-	zReader->lese((char*)&zItem->maxStackSize, 1);
-	unsigned char len = 0;
-	zReader->lese((char*)&len, 1);
-	zItem->name.fillText(' ', len);
-	zReader->lese((char*)zItem->name.getText(), len);
-}
-
-void ItemType::saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const
-{
-	zWriter->schreibe((char*)&zItem->hp, 4);
-	zWriter->schreibe((char*)&zItem->maxHp, 4);
-	zWriter->schreibe((char*)&zItem->durability, 4);
-	zWriter->schreibe((char*)&zItem->maxDurability, 4);
-	unsigned char flags = (unsigned char)((zItem->usable << 4) | (zItem->solid << 3) | (zItem->equippable << 2) | (zItem->placeable << 1) | zItem->eatable);
-	zWriter->schreibe((char*)&flags, 1);
-	zWriter->schreibe((char*)&zItem->maxStackSize, 1);
-	unsigned char len = (unsigned char)zItem->name.getLength();
-	zWriter->schreibe((char*)&len, 1);
-	zWriter->schreibe(zItem->name, len);
-}
-
-void ItemType::loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const
-{
-
-}
-
-void ItemType::saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
-{
-
-}
-
-Item* ItemType::createBasicItem(const char* name, float hp, float maxHp, float durability, float maxDurability, bool eatable, bool placeable, bool equippable, bool solid, bool usable, int maxStackSize) const
-{
-	Item* item = new Item(this, name);
-	item->hp = hp;
-	item->maxHp = maxHp;
-	item->durability = durability;
-	item->maxDurability = maxDurability;
-	item->eatable = eatable;
-	item->placeable = placeable;
-	item->equippable = equippable;
-	item->solid = solid;
-	item->usable = usable;
-	item->maxStackSize = maxStackSize;
-	return item;
-}
+    if (levelUpRule) levelUpRule->release();
+}
+
+void ItemType::loadSuperItem(
+    Item* zItem, Framework::StreamReader* zReader) const
+{
+    zReader->lese((char*)&zItem->hp, 4);
+    zReader->lese((char*)&zItem->maxHp, 4);
+    zReader->lese((char*)&zItem->durability, 4);
+    zReader->lese((char*)&zItem->maxDurability, 4);
+    unsigned char flags = 0;
+    zReader->lese((char*)&flags, 1);
+    zItem->eatable = (flags | 1) == flags;
+    zItem->placeable = (flags | 2) == flags;
+    zItem->equippable = (flags | 4) == flags;
+    zItem->solid = (flags | 8) == flags;
+    zItem->usable = (flags | 16) == flags;
+    zReader->lese((char*)&zItem->maxStackSize, 1);
+    unsigned char len = 0;
+    zReader->lese((char*)&len, 1);
+    zItem->name.fillText(' ', len);
+    zReader->lese((char*)zItem->name.getText(), len);
+}
+
+void ItemType::saveSuperItem(
+    const Item* zItem, Framework::StreamWriter* zWriter) const
+{
+    zWriter->schreibe((char*)&zItem->hp, 4);
+    zWriter->schreibe((char*)&zItem->maxHp, 4);
+    zWriter->schreibe((char*)&zItem->durability, 4);
+    zWriter->schreibe((char*)&zItem->maxDurability, 4);
+    unsigned char flags
+        = (unsigned char)((zItem->usable << 4) | (zItem->solid << 3)
+                          | (zItem->equippable << 2) | (zItem->placeable << 1)
+                          | zItem->eatable);
+    zWriter->schreibe((char*)&flags, 1);
+    zWriter->schreibe((char*)&zItem->maxStackSize, 1);
+    unsigned char len = (unsigned char)zItem->name.getLength();
+    zWriter->schreibe((char*)&len, 1);
+    zWriter->schreibe(zItem->name, len);
+}
+
+void ItemType::loadSuperItemSkill(
+    ItemSkill* zSkill, Framework::StreamReader* zReader) const
+{}
+
+void ItemType::saveSuperItemSkill(
+    const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
+{}
 
 int ItemType::getId() const
 {
-	return id;
+    return id;
 }
 
 const Framework::Text& ItemType::getName() const
 {
-	return name;
+    return name;
 }
 
 const ItemType* ItemType::zBrokenItemType() const
 {
-	return zBrokenType;
+    return StaticRegistry<ItemType>::INSTANCE.zElement(brokenTypeId);
 }
 
 ItemStack* ItemType::createItemStack(int size) const
 {
-	Item* item = createItem();
-	if (!item)
-		return 0;
-	return new ItemStack(item, MIN(size, item->getMaxStackSize()));
+    Item* item = createItem();
+    if (!item) return 0;
+    return new ItemStack(item, MIN(size, item->getMaxStackSize()));
 }
 
 ItemSkill* ItemType::createDefaultItemSkill() const
 {
-	return 0;
+    return 0;
 }
 
 void ItemType::levelUpItemSkill(ItemSkill* zSkill) const
 {
-	if (levelUpRule)
-		levelUpRule->applyOn(zSkill);
+    if (levelUpRule) levelUpRule->applyOn(zSkill);
 }
 
 Item* ItemType::loadItem(Framework::StreamReader* zReader) const
 {
-	Item* item = createItem();
-	loadSuperItem(item, zReader);
-	return item;
+    Item* item = createItem();
+    loadSuperItem(item, zReader);
+    return item;
 }
 
-void ItemType::saveItem(const Item* zItem, Framework::StreamWriter* zWriter) const
+void ItemType::saveItem(
+    const Item* zItem, Framework::StreamWriter* zWriter) const
 {
-	saveSuperItem(zItem, zWriter);
+    saveSuperItem(zItem, zWriter);
 }
 
 Item* ItemType::cloneItem(const Item* zItem) const
 {
-	Framework::InMemoryBuffer buffer;
-	saveItem(zItem, &buffer);
-	return loadItem(&buffer);
+    Framework::InMemoryBuffer buffer;
+    saveItem(zItem, &buffer);
+    return loadItem(&buffer);
 }
 
 ItemSkill* ItemType::loadItemSkill(Framework::StreamReader* zReader) const
 {
-	ItemSkill* skill = createDefaultItemSkill();
-	loadSuperItemSkill(skill, zReader);
-	return skill;
+    ItemSkill* skill = createDefaultItemSkill();
+    loadSuperItemSkill(skill, zReader);
+    return skill;
 }
 
-void ItemType::saveItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
+void ItemType::saveItemSkill(
+    const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
 {
-	saveSuperItemSkill(zSkill, zWriter);
+    saveSuperItemSkill(zSkill, zWriter);
 }
 
 Item* ItemType::breakItem(const Item* zItem) const
 {
-	return 0;
+    return 0;
 }
 
 const ModelInfo& ItemType::getModel() const
 {
-	return model;
+    return model;
+}
+
+Item* ItemType::createBasicItem(int id, const char* name,
+    float hp,
+    float maxHp,
+    float durability,
+    float maxDurability,
+    bool eatable,
+    bool placeable,
+    bool equippable,
+    bool solid,
+    bool usable,
+    int maxStackSize)
+{
+    Item* item = new Item(id, name);
+    item->hp = hp;
+    item->maxHp = maxHp;
+    item->durability = durability;
+    item->maxDurability = maxDurability;
+    item->eatable = eatable;
+    item->placeable = placeable;
+    item->equippable = equippable;
+    item->solid = solid;
+    item->usable = usable;
+    item->maxStackSize = maxStackSize;
+    return item;
 }

+ 62 - 29
FactoryCraft/ItemType.h

@@ -1,51 +1,84 @@
 #pragma once
 
-#include <Text.h>
 #include <JSON.h>
+#include <Text.h>
 #include <Trie.h>
 #include <Writer.h>
 
+#include "BlockType.h"
 #include "Effect.h"
-#include "StaticRegistry.h"
 #include "ModelInfo.h"
+#include "StaticRegistry.h"
 
 class Item;
 class ItemStack;
 class ItemSkill;
 class ItemSkillLevelUpRule;
 
+class ItemTypeEnum : public BlockTypeEnum
+{
+public:
+    static const int WOOD_STICK = BlockTypeEnum::MAX_VALUE + 1;
+    static const int STONE_TOOL = BlockTypeEnum::MAX_VALUE + 2;
+    static const int RESIN = BlockTypeEnum::MAX_VALUE + 3;
+    static const int PLAYER_HAND = BlockTypeEnum::MAX_VALUE + 4;
+    static const int STONE_TOOL_BROKEN = BlockTypeEnum::MAX_VALUE + 5;
+};
+
 class ItemType : public virtual Framework::ReferenceCounter
 {
 protected:
-	const int id;
-	const Framework::Text name;
-	ItemSkillLevelUpRule* levelUpRule;
-	const ItemType* zBrokenType;
-	const ModelInfo model;
+    const int id;
+    const Framework::Text name;
+    ItemSkillLevelUpRule* levelUpRule;
+    int brokenTypeId;
+    const ModelInfo model;
 
-	ItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType, ModelInfo model);
+    ItemType(int id,
+        const char* name,
+        ItemSkillLevelUpRule* levelUpRule,
+        int brokenTypeId,
+        ModelInfo model);
 
-	virtual void loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const;
-	virtual void saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const;
-	virtual void loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const;
-	virtual void saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const;
-	Item* createBasicItem(const char* name, float hp, float maxHp, float durability, float maxDurability, bool eatable, bool placeable, bool equippable, bool solid, bool usable, int maxStackSize) const;
+    virtual void loadSuperItem(
+        Item* zItem, Framework::StreamReader* zReader) const;
+    virtual void saveSuperItem(
+        const Item* zItem, Framework::StreamWriter* zWriter) const;
+    virtual void loadSuperItemSkill(
+        ItemSkill* zSkill, Framework::StreamReader* zReader) const;
+    virtual void saveSuperItemSkill(
+        const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const;
 
 public:
-	~ItemType();
-
-	int getId() const;
-	const Framework::Text& getName() const;
-	const ItemType* zBrokenItemType() const;
-	virtual Item* createItem() const = 0;
-	virtual ItemStack* createItemStack(int size) const;
-	virtual ItemSkill* createDefaultItemSkill() const;
-	virtual void levelUpItemSkill(ItemSkill* zSkill) const;
-	virtual Item* loadItem(Framework::StreamReader* zReader) const;
-	virtual void saveItem(const Item* zItem, Framework::StreamWriter* zWriter) const;
-	virtual ItemSkill* loadItemSkill(Framework::StreamReader* zReader) const;
-	virtual void saveItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const;
-	virtual Item* cloneItem(const Item* zItem) const;
-	virtual Item* breakItem(const Item* zItem) const;
-	const ModelInfo& getModel() const;
+    ~ItemType();
+
+    int getId() const;
+    const Framework::Text& getName() const;
+    const ItemType* zBrokenItemType() const;
+    virtual Item* createItem() const = 0;
+    virtual ItemStack* createItemStack(int size) const;
+    virtual ItemSkill* createDefaultItemSkill() const;
+    virtual void levelUpItemSkill(ItemSkill* zSkill) const;
+    virtual Item* loadItem(Framework::StreamReader* zReader) const;
+    virtual void saveItem(
+        const Item* zItem, Framework::StreamWriter* zWriter) const;
+    virtual ItemSkill* loadItemSkill(Framework::StreamReader* zReader) const;
+    virtual void saveItemSkill(
+        const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const;
+    virtual Item* cloneItem(const Item* zItem) const;
+    virtual Item* breakItem(const Item* zItem) const;
+    const ModelInfo& getModel() const;
+
+    static Item* createBasicItem(int id,
+        const char* name,
+        float hp,
+        float maxHp,
+        float durability,
+        float maxDurability,
+        bool eatable,
+        bool placeable,
+        bool equippable,
+        bool solid,
+        bool usable,
+        int maxStackSize);
 };

+ 31 - 26
FactoryCraft/LightSources.cpp

@@ -1,7 +1,7 @@
 #include "LightSources.h"
 
-LightSourceItem::LightSourceItem(const ItemType* zType, const BlockType* zPlacedBlockType, const char* name)
-	: BasicBlockItem(zType, zPlacedBlockType, name),
+LightSourceItem::LightSourceItem(int itemType, int blockType, const char* name)
+    : BasicBlockItem(itemType, blockType, name),
 	color(0XFFFFFFFF)
 {}
 
@@ -12,9 +12,13 @@ bool LightSourceItem::canBeStackedWith(const Item* zItem) const
 }
 
 
-LightSourceItemType::LightSourceItemType(int id, const char* name, const ModelInfo model)
-	:BasicBlockItemType(id, name, 0, 0, model)
-{}
+LightSourceItemType::LightSourceItemType(int id, const char* name, const ModelInfo model, int blockTypeId)
+    : BasicBlockItemType(id, name, 0, 0, model, blockTypeId)
+{
+    transparent = 1;
+    passable = 1;
+    hardness = 0;
+}
 
 void LightSourceItemType::loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const
 {
@@ -30,15 +34,25 @@ void LightSourceItemType::saveSuperItem(const Item* zItem, Framework::StreamWrit
 	BasicBlockItemType::saveSuperItem(zItem, zWriter);
 }
 
-void LightSourceItemType::initializeItem(LightSourceItem* zItem, int color, bool transparent, bool passable, float hardness, int toolId, float speedModifier) const
+Item* LightSourceItemType::createItem() const
+{
+    LightSourceItem* item
+        = new LightSourceItem(id, blockTypeId, name);
+    item->color = color;
+    return item;
+}
+
+
+
+LightSourceItemType* LightSourceItemType::setColor(int color)
 {
-	zItem->color = color;
-	BasicBlockItemType::initializeItem(zItem, transparent, passable, hardness, toolId, speedModifier);
+	this->color = color;
+	return this;
 }
 
 
-BasicLightSource::BasicLightSource(const BlockType* zType, Framework::Vec3<int> pos)
-	: Block(zType, 0, pos, 0)
+BasicLightSource::BasicLightSource(int typeId, Framework::Vec3<int> pos)
+	: Block(typeId, 0, pos, 0)
 {}
 
 void BasicLightSource::setLight(int light)
@@ -107,7 +121,7 @@ void BasicLightSourceBlockType::saveSuperBlock(Block* zBlock, Framework::StreamW
 
 Block* BasicLightSourceBlockType::createBlock(Framework::Vec3<int> position) const
 {
-	return new BasicLightSource(this, position);
+	return new BasicLightSource(getId(), position);
 }
 
 Item* BasicLightSourceBlockType::createItem() const
@@ -115,23 +129,14 @@ Item* BasicLightSourceBlockType::createItem() const
 	return StaticRegistry<ItemType>::INSTANCE.zElement(itemType)->createItem();
 }
 
-
-TorchBlockItemType::TorchBlockItemType()
-	: LightSourceItemType(ID, "Torch", ModelInfo("items.m3/stick", "blocks.ltdb/torch.png", 6))
-{}
-
-Item* TorchBlockItemType::createItem() const
+BasicLightSourceBlockType* BasicLightSourceBlockType::setHardness(float hardness)
 {
-	LightSourceItem* item = new LightSourceItem(this, TorchBlockType::INSTANCE, "Torch");
-	initializeItem(item, 0x00F69A54);
-	return item;
+	this->hardness = hardness;
+	return this;
 }
 
-
-TorchBlockType::TorchBlockType()
-	: BasicLightSourceBlockType(ID, TorchBlockItemType::ID, ModelInfo("blocks.m3/torch", "blocks.ltdb/torch.png", 6))
+BasicLightSourceBlockType* BasicLightSourceBlockType::setColor(int color)
 {
-	hardness = 0.f;
-	color = 0x00F69A54;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
+	this->color = color;
+	return this;
 }

+ 43 - 50
FactoryCraft/LightSources.h

@@ -1,8 +1,8 @@
 #pragma once
 
-#include "BlockType.h"
 #include "BasicBlocks.h"
 #include "Block.h"
+#include "BlockType.h"
 
 class BasicLightSourceBlockType;
 class LightSourceItemType;
@@ -10,77 +10,70 @@ class LightSourceItemType;
 class LightSourceItem : public BasicBlockItem
 {
 protected:
-	int color;
+    int color;
 
 public:
-	LightSourceItem(const ItemType* zType, const BlockType* zPlacedBlockType, const char* name);
-	virtual bool canBeStackedWith(const Item* zItem) const override;
+    LightSourceItem(int itemType, int blockType, const char* name);
+    virtual bool canBeStackedWith(const Item* zItem) const override;
 
-	friend LightSourceItemType;
-	friend BasicLightSourceBlockType;
+    friend LightSourceItemType;
+    friend BasicLightSourceBlockType;
 };
 
 class LightSourceItemType : public BasicBlockItemType
 {
+private:
+    int color;
+
 protected:
-	LightSourceItemType(int id, const char* name, const ModelInfo model);
-	virtual void loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const override;
-	virtual void saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const override;
-	void initializeItem(LightSourceItem* zItem, int color, bool transparent = 1, bool passable = 1, float hardness = 0, int toolId = 0, float speedModifier = 1) const;
+    virtual void loadSuperItem(
+        Item* zItem, Framework::StreamReader* zReader) const override;
+    virtual void saveSuperItem(
+        const Item* zItem, Framework::StreamWriter* zWriter) const override;
+    virtual Item* createItem() const override;
+
+public:
+    LightSourceItemType(
+        int id, const char* name, const ModelInfo model, int blockTypeId);
+    LightSourceItemType* setColor(int color);
 };
 
 class BasicLightSource : public Block
 {
 protected:
-	void setLight(int light);
+    void setLight(int light);
 
 public:
-	BasicLightSource(const BlockType* zType, Framework::Vec3<int> pos);
-	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) override;
-	virtual void onPostTick() override;
+    BasicLightSource(int typeId, Framework::Vec3<int> pos);
+    virtual bool onTick(
+        TickQueue* zQueue, int numTicks, bool& blocked) override;
+    virtual void onPostTick() override;
 
-	friend BasicLightSourceBlockType;
+    friend BasicLightSourceBlockType;
 };
 
 class BasicLightSourceBlockType : public BlockType
 {
 private:
-	int itemType;
-
-protected:
-	bool transparent;
-	bool passable;
-	float hardness;
-	bool interactable;
-	int color;
-
-	BasicLightSourceBlockType(int typeId, int itemTypeId, ModelInfo model);
-	virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
-	virtual void loadSuperBlock(Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const override;
-	virtual void saveSuperBlock(Block* zBlock, Framework::StreamWriter* zWriter) const override;
-
-public:
-	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-	virtual Item* createItem() const override;
-};
-
-class TorchBlockItemType : public LightSourceItemType
-{
-	REGISTRABLE(TorchBlockItemType)
+    int itemType;
+    bool transparent;
+    bool passable;
+    float hardness;
+    bool interactable;
+    int color;
 
 protected:
-	TorchBlockItemType();
+    virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
+    virtual void loadSuperBlock(Block* zBlock,
+        Framework::StreamReader* zReader,
+        int dimensionId) const override;
+    virtual void saveSuperBlock(
+        Block* zBlock, Framework::StreamWriter* zWriter) const override;
 
 public:
-	virtual Item* createItem() const override;
-};
-REGISTER(TorchBlockItemType, ItemType)
-
-class TorchBlockType : public BasicLightSourceBlockType
-{
-	REGISTRABLE(TorchBlockType)
-
-protected:
-	TorchBlockType();
-};
-REGISTER(TorchBlockType, BlockType)
+    BasicLightSourceBlockType(int typeId, int itemTypeId, ModelInfo model);
+    virtual Block* createBlock(Framework::Vec3<int> position) const override;
+    virtual Item* createItem() const override;
+    BasicLightSourceBlockType* setHardness(float hardness);
+    BasicLightSourceBlockType* setColor(int color);
+};

+ 6 - 0
FactoryCraft/MultiblockStructure.h

@@ -7,6 +7,12 @@
 
 class MultiblockStructureType;
 
+class MultiblockStructureEnum
+{
+public:
+    static const int TREE = 0;
+};
+
 class MultiblockStructure : public virtual Framework::ReferenceCounter
 {
 private:

+ 3 - 2
FactoryCraft/MultiblockTree.cpp

@@ -3,7 +3,8 @@
 using namespace Framework;
 
 MultiblockTree::MultiblockTree(int dimensionId, __int64 structureId, Framework::Vec3<int> uniquePosition)
-	: MultiblockStructure(dimensionId, structureId, uniquePosition, MultiblockTreeStructureType::ID)
+    : MultiblockStructure(
+        dimensionId, structureId, uniquePosition, MultiblockStructureEnum::TREE)
 {}
 
 void MultiblockTree::onBlockRemoved(Block* zBlock)
@@ -71,7 +72,7 @@ void MultiblockTree::onBlockRemoved(Block* zBlock)
 
 
 MultiblockTreeStructureType::MultiblockTreeStructureType()
-	: MultiblockStructureType(ID)
+	: MultiblockStructureType(MultiblockStructureEnum::TREE)
 {}
 
 MultiblockStructure* MultiblockTreeStructureType::createStructure(int dimensionId, __int64 structureId, Framework::Vec3<int> uniquePosition) const

+ 9 - 11
FactoryCraft/MultiblockTree.h

@@ -6,19 +6,17 @@
 class MultiblockTree : public MultiblockStructure
 {
 public:
-	MultiblockTree(int dimensionId, __int64 structureId, Framework::Vec3<int> uniquePosition);
-	virtual void onBlockRemoved(Block* zBlock) override;
+    MultiblockTree(int dimensionId,
+        __int64 structureId,
+        Framework::Vec3<int> uniquePosition);
+    virtual void onBlockRemoved(Block* zBlock) override;
 };
 
-
 class MultiblockTreeStructureType : public MultiblockStructureType
 {
-	REGISTRABLE(MultiblockTreeStructureType)
-
-protected:
-	MultiblockTreeStructureType();
-
 public:
-	virtual MultiblockStructure* createStructure(int dimensionId, __int64 structureId, Framework::Vec3<int> uniquePosition) const override;
-};
-REGISTER(MultiblockTreeStructureType, MultiblockStructureType)
+    MultiblockTreeStructureType();
+    virtual MultiblockStructure* createStructure(int dimensionId,
+        __int64 structureId,
+        Framework::Vec3<int> uniquePosition) const override;
+};

+ 29 - 38
FactoryCraft/NoBlock.cpp

@@ -1,31 +1,9 @@
 #include "NoBlock.h"
 
-NoBlock::NoBlock()
-	: Block(NoBlockBlockType::INSTANCE, 0, { 0,0,0 }, false)
-{
-	transparent = 0;
-	passable = 0;
-	hp = 0;
-	maxHP = 0;
-	hardness = 0;
-}
-
-bool NoBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
-{
-	return 0;
-}
-
-void NoBlock::onPostTick() {}
-
-const NoBlock NoBlock::INSTANCE;
-
 
-NoBlockBlockType::NoBlockBlockType()
-	: BlockType(ID, 0, ModelInfo("", "", 0), 0, 1, 0)
-{}
-
-NoBlockBlockType::NoBlockBlockType(int id)
-	: BlockType(id, 0, ModelInfo("", "", 0), 0, 1, 0)
+NoBlockBlockType::NoBlockBlockType(int id, const Block* defaultB)
+	: BlockType(id, 0, ModelInfo("", "", 0), 0, 1, 0),
+	defaultB(defaultB)
 {}
 
 Block* NoBlockBlockType::createBlock(Framework::Vec3<int> position) const
@@ -58,11 +36,34 @@ Block* NoBlockBlockType::createBlockAt(Framework::Vec3<int> position, Item* zUse
 
 const Block* NoBlockBlockType::zDefault() const
 {
-	return &NoBlock::INSTANCE;
+	return defaultB;
 }
 
+
+
+NoBlock::NoBlock()
+	: Block(BlockTypeEnum::NO_BLOCK, 0, { 0,0,0 }, false)
+{
+	transparent = 0;
+	passable = 0;
+	hp = 0;
+	maxHP = 0;
+	hardness = 0;
+}
+
+bool NoBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
+{
+	return 0;
+}
+
+void NoBlock::onPostTick() {}
+
+const NoBlock NoBlock::INSTANCE;
+
+
+
 AirBlock::AirBlock()
-	: Block(AirBlockBlockType::INSTANCE, 0, { 0,0,0 }, false)
+	: Block(BlockTypeEnum::AIR, 0, { 0,0,0 }, false)
 {
 	transparent = 1;
 	passable = 1;
@@ -79,14 +80,4 @@ bool AirBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
 void AirBlock::onPostTick()
 {}
 
-const AirBlock AirBlock::INSTANCE;
-
-
-AirBlockBlockType::AirBlockBlockType()
-	: NoBlockBlockType(ID)
-{}
-
-const Block* AirBlockBlockType::zDefault() const
-{
-	return &AirBlock::INSTANCE;
-}
+const AirBlock AirBlock::INSTANCE;

+ 17 - 28
FactoryCraft/NoBlock.h

@@ -3,57 +3,46 @@
 #include "BlockType.h"
 #include "Block.h"
 
-class NoBlockBlockType;
-
-class NoBlock : public Block
-{
-public:
-	static const NoBlock INSTANCE;
-
-protected:
-	NoBlock();
-
-	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) override;
-	virtual void onPostTick() override;
-};
-
 class NoBlockBlockType : public BlockType
 {
-	REGISTRABLE(NoBlockBlockType)
+private:
+	const Block* defaultB;
 
 protected:
-	NoBlockBlockType();
-	NoBlockBlockType(int id);
 	virtual Block* createBlock(Framework::Vec3<int> position) const override;
 	virtual Item* createItem() const override;
 	virtual Block* loadBlock(Framework::Vec3<int> position, Framework::StreamReader* zReader, int dimensionId) const override;
 	virtual void saveBlock(Block* zBlock, Framework::StreamWriter* zWriter) const override;
 	virtual Item* getItemFromBlock(Block* zBlock) const override;
 	virtual Block* createBlockAt(Framework::Vec3<int> position, Item* zUsedItem) const override;
+	virtual const Block* zDefault() const override;
 
 public:
-	virtual const Block* zDefault() const override;
+	NoBlockBlockType(int id, const Block* defaultB);
 };
-REGISTER(NoBlockBlockType, BlockType)
 
-class AirBlock : public Block
+
+class NoBlock : public Block
 {
 public:
-	static const AirBlock INSTANCE;
+	static const NoBlock INSTANCE;
 
 protected:
-	AirBlock();
+	NoBlock();
 
 	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) override;
 	virtual void onPostTick() override;
 };
 
-class AirBlockBlockType : public NoBlockBlockType
+
+class AirBlock : public Block
 {
-	REGISTRABLE(AirBlockBlockType)
+public:
+	static const AirBlock INSTANCE;
 
 protected:
-	AirBlockBlockType();
-	virtual const Block* zDefault() const override;
-};
-REGISTER(AirBlockBlockType, BlockType)
+	AirBlock();
+
+	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) override;
+	virtual void onPostTick() override;
+};

+ 2 - 1
FactoryCraft/OverworldDimension.cpp

@@ -6,7 +6,8 @@
 
 
 OverworldDimension::OverworldDimension()
-	: DimensionGenerator(ID, new WormCaveGenerator(75, 150, 1, 6, 0.1f))
+    : DimensionGenerator(
+        DimensionEnum::OVERWORLD, new WormCaveGenerator(75, 150, 1, 6, 0.1f))
 {
 	registerBiom(new GrasslandBiom(), 1.0);
 	biomNoise = 0;

+ 1 - 7
FactoryCraft/OverworldDimension.h

@@ -6,8 +6,6 @@
 
 class OverworldDimension : public DimensionGenerator
 {
-	REGISTRABLE(OverworldDimension)
-
 private:
 	Noise* biomNoise;
 	Noise* structureNoise;
@@ -17,8 +15,4 @@ public:
 	~OverworldDimension();
 	Noise* zBiomNoise() override;
 	Noise* zStructureNoise() override;
-};
-
-#ifdef REGISTER
-REGISTER(OverworldDimension, DimensionGenerator)
-#endif
+};

+ 5 - 4
FactoryCraft/Player.cpp

@@ -5,7 +5,7 @@
 
 
 Player::Player(Framework::Vec3<float> location, int dimensionId, int entityId)
-	: Entity(PlayerEntityType::INSTANCE, location, dimensionId, entityId),
+	: Entity(EntityTypeEnum::PLAYER, location, dimensionId, entityId),
 	BasicShapedCrafter(3, 3, this, "inventory")
 {
 	for (int i = 0; i < 10; i++)
@@ -82,7 +82,7 @@ void Player::useItemSlot(ItemSlot* zSlot)
 		if (stack)
 		{
 			Item* item = stack->extractFromStack();
-			Entity::useItem(item->zItemType(), item);
+			Entity::useItem(item->getTypeId(), item);
 			if (item->getHp() > 0)
 			{
 				if (item->getDurability() > 0)
@@ -138,7 +138,7 @@ void Player::useItemSlot(ItemSlot* zSlot)
 		}
 	}
 	else
-		Entity::useItem(PlayerHandItemType::INSTANCE, 0); // hand usage
+		Entity::useItem(ItemTypeEnum::PLAYER_HAND, 0); // hand usage
 }
 
 void Player::setName(Framework::Text name)
@@ -334,7 +334,8 @@ void Player::onFall(float collisionSpeed)
 
 
 PlayerEntityType::PlayerEntityType()
-	: EntityType(ID, ModelInfo("player", "player.ltdb/player.png", 6))
+    : EntityType(
+        EntityTypeEnum::PLAYER, ModelInfo("player", "player.ltdb/player.png", 6))
 {}
 
 void PlayerEntityType::loadSuperEntity(Entity* zEntity, Framework::StreamReader* zReader) const

+ 1 - 5
FactoryCraft/Player.h

@@ -45,8 +45,6 @@ public:
 
 class PlayerEntityType : public EntityType
 {
-	REGISTRABLE(PlayerEntityType)
-
 protected:
 	virtual void loadSuperEntity(Entity* zEntity, Framework::StreamReader* zReader) const override;
 	virtual void saveSuperEntity(Entity* zEntity, Framework::StreamWriter* zWriter) const override;
@@ -55,6 +53,4 @@ public:
 	PlayerEntityType();
 
 	virtual Entity* createEntity(Framework::Vec3<float> position, int dimensionId, int entityId) const override;
-};
-
-REGISTER(PlayerEntityType, EntityType)
+};

+ 6 - 4
FactoryCraft/PlayerHand.cpp

@@ -3,7 +3,11 @@
 
 
 PlayerHandItemType::PlayerHandItemType()
-	: ItemType(ID, "PlayerHand", new PlayerHandLevelUpRule(), 0, ModelInfo("", "", 0))
+    : ItemType(ItemTypeEnum::PLAYER_HAND,
+        "PlayerHand",
+        new PlayerHandLevelUpRule(),
+        0,
+        ModelInfo("", "", 0))
 {}
 
 void PlayerHandItemType::loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const
@@ -37,9 +41,7 @@ void PlayerHandLevelUpRule::applyOn(ItemSkill* zSkill)
 }
 
 
-PlayerHandSkill::PlayerHandSkill()
-	: ItemSkill(PlayerHandItemType::INSTANCE)
-{}
+PlayerHandSkill::PlayerHandSkill() : ItemSkill(ItemTypeEnum::PLAYER_HAND) {}
 
 void PlayerHandSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
 {

+ 13 - 14
FactoryCraft/PlayerHand.h

@@ -1,34 +1,33 @@
 #pragma once
 
-#include "ItemType.h"
 #include "ItemSkill.h"
+#include "ItemType.h"
 
 class PlayerHandItemType : public ItemType
 {
-	REGISTRABLE(PlayerHandItemType)
-
 protected:
-	void loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const override;
-	void saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const override;
+    void loadSuperItemSkill(
+        ItemSkill* zSkill, Framework::StreamReader* zReader) const override;
+    void saveSuperItemSkill(const ItemSkill* zSkill,
+        Framework::StreamWriter* zWriter) const override;
 
 public:
-	PlayerHandItemType();
-	Item* createItem() const override;
-	ItemSkill* createDefaultItemSkill() const override;
+    PlayerHandItemType();
+    Item* createItem() const override;
+    ItemSkill* createDefaultItemSkill() const override;
 };
-REGISTER(PlayerHandItemType, ItemType)
 
 class PlayerHandLevelUpRule : public ItemSkillLevelUpRule
 {
 public:
-	PlayerHandLevelUpRule();
-	void applyOn(ItemSkill* zSkill) override;
+    PlayerHandLevelUpRule();
+    void applyOn(ItemSkill* zSkill) override;
 };
 
 class PlayerHandSkill : public ItemSkill
 {
 public:
-	PlayerHandSkill();
-	void use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
-	void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
+    PlayerHandSkill();
+    void use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
+    void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
 };

+ 276 - 183
FactoryCraft/RecipieLoader.cpp

@@ -1,232 +1,325 @@
-#include <stdexcept>
+#include "RecipieLoader.h"
+
 #include <Datei.h>
 #include <iostream>
+#include <stdexcept>
 
-#include "RecipieLoader.h"
 #include "ItemType.h"
 
 using namespace Framework::JSON;
 using namespace Validator;
 
 RecipieLoader::RecipieLoader()
-	: Framework::ReferenceCounter(),
-	validator(0)
+    : Framework::ReferenceCounter(),
+      validator(0)
 {}
 
 RecipieLoader::~RecipieLoader()
 {
-	if (validator)
-		validator->release();
+    if (validator) validator->release();
 }
 
 void RecipieLoader::loadRecipies(const char* path)
 {
-	shapedLists.leeren();
-	lists.leeren();
-	std::cout << "loading recipies from '" << path << "'" << std::endl;
-	Framework::Datei d;
-	d.setDatei(path);
-	if (d.istOrdner())
-	{
-		Framework::RCArray<Framework::Text>* files = d.getDateiListe();
-		for (Framework::Text* f : *files)
-			loadRecipies(Framework::Text(path) + "/" + *f);
-		files->release();
-	}
-	else
-	{
-		JSONValue* json = loadJSONFromFile(path);
-		JSONValidator* validator = zRecipieValidator();
-		JSONValue* valid = validator->getValidParts(json);
-		json->release();
-		if (valid)
-		{
-			for (JSONValue* recipie : *valid->asArray())
-				loadRecipie(recipie->asObject());
-			valid->release();
-		}
-	}
+    shapedLists.leeren();
+    lists.leeren();
+    std::cout << "loading recipies from '" << path << "'" << std::endl;
+    Framework::Datei d;
+    d.setDatei(path);
+    if (d.istOrdner())
+    {
+        Framework::RCArray<Framework::Text>* files = d.getDateiListe();
+        for (Framework::Text* f : *files)
+            loadRecipies(Framework::Text(path) + "/" + *f);
+        files->release();
+    }
+    else
+    {
+        JSONValue* json = loadJSONFromFile(path);
+        JSONValidator* validator = zRecipieValidator();
+        JSONValue* valid = validator->getValidParts(json);
+        json->release();
+        if (valid)
+        {
+            for (JSONValue* recipie : *valid->asArray())
+                loadRecipie(recipie->asObject());
+            valid->release();
+        }
+    }
 }
 
 void RecipieLoader::loadRecipie(JSONObject* zRecipie)
 {
-	Framework::Text group = zRecipie->zValue("group")->asString()->getString();
-	if (zRecipie->zValue("type")->asString()->getString().istGleich("shaped"))
-	{
-		int width = (int)zRecipie->zValue("width")->asNumber()->getNumber();
-		int height = (int)zRecipie->zValue("height")->asNumber()->getNumber();
-		ShapedRecipie* recipie = new ShapedRecipie(width, height);
-		for (JSONValue* input : *zRecipie->zValue("inputs")->asArray())
-		{
-			int x = (int)input->asObject()->zValue("x")->asNumber()->getNumber();
-			int y = (int)input->asObject()->zValue("y")->asNumber()->getNumber();
-			ItemFilter* filter = loadFilter(input->asObject()->zValue("filter")->asObject());
-			CombinedItemModifier* resultingModifier = new CombinedItemModifier();
-			for (JSONValue* modifier : *input->asObject()->zValue("modifiers")->asArray())
-				resultingModifier->addModifier(loadModifier(modifier->asObject()));
-			recipie->setIngredient(x, y, filter, resultingModifier);
-		}
-		int outputCount = (int)zRecipie->asObject()->zValue("outputCount")->asNumber()->getNumber();
-		Framework::Text outputType = zRecipie->asObject()->zValue("output")->asObject()->zValue("itemType")->asString()->getString();
-		Item* item = 0;
-		for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
-		{
-			if (StaticRegistry<ItemType>::INSTANCE.zElement(i)->getName().istGleich(outputType))
-			{
-				item = StaticRegistry<ItemType>::INSTANCE.zElement(i)->createItem();
-				break;
-			}
-		}
-		recipie->setOutput(item, outputCount);
-		if (!zShapedRecipieList(group))
-			registerShapedRecipieList(group);
-		zShapedRecipieList(group)->addRecipie(recipie);
-	}
-	else if (zRecipie->zValue("type")->asString()->getString().istGleich("unordered"))
-	{
-		Recipie* recipie = new Recipie();
-		for (JSONValue* input : *zRecipie->zValue("inputs")->asArray())
-		{
-			int count = (int)input->asObject()->zValue("count")->asNumber()->getNumber();
-			ItemFilter* filter = loadFilter(input->asObject()->zValue("filter")->asObject());
-			recipie->addIngredient(filter, count);
-		}
-		for (JSONValue* output : *zRecipie->zValue("outputs")->asArray())
-		{
-			int count = (int)output->asObject()->zValue("count")->asNumber()->getNumber();
-			Framework::Text outputType = output->asObject()->zValue("item")->asObject()->zValue("itemType")->asString()->getString();
-			Item* item = 0;
-			for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
-			{
-				if (StaticRegistry<ItemType>::INSTANCE.zElement(i)->getName().istGleich(outputType))
-				{
-					item = StaticRegistry<ItemType>::INSTANCE.zElement(i)->createItem();
-					break;
-				}
-			}
-			recipie->addOutput(item, count);
-		}
-		if (!zRecipieList(group))
-			registerRecipieList(group);
-		zRecipieList(group)->addRecipie(recipie);
-	}
+    Framework::Text group = zRecipie->zValue("group")->asString()->getString();
+    if (zRecipie->zValue("type")->asString()->getString().istGleich("shaped"))
+    {
+        int width = (int)zRecipie->zValue("width")->asNumber()->getNumber();
+        int height = (int)zRecipie->zValue("height")->asNumber()->getNumber();
+        ShapedRecipie* recipie = new ShapedRecipie(width, height);
+        for (JSONValue* input : *zRecipie->zValue("inputs")->asArray())
+        {
+            int x
+                = (int)input->asObject()->zValue("x")->asNumber()->getNumber();
+            int y
+                = (int)input->asObject()->zValue("y")->asNumber()->getNumber();
+            ItemFilter* filter
+                = loadFilter(input->asObject()->zValue("filter")->asObject());
+            CombinedItemModifier* resultingModifier
+                = new CombinedItemModifier();
+            for (JSONValue* modifier :
+                *input->asObject()->zValue("modifiers")->asArray())
+                resultingModifier->addModifier(
+                    loadModifier(modifier->asObject()));
+            recipie->setIngredient(x, y, filter, resultingModifier);
+        }
+        int outputCount = (int)zRecipie->asObject()
+                              ->zValue("outputCount")
+                              ->asNumber()
+                              ->getNumber();
+        Framework::Text outputType = zRecipie->asObject()
+                                         ->zValue("output")
+                                         ->asObject()
+                                         ->zValue("itemType")
+                                         ->asString()
+                                         ->getString();
+        Item* item = 0;
+        for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
+        {
+            if (StaticRegistry<ItemType>::INSTANCE
+                    .zElement(i) && StaticRegistry<ItemType>::INSTANCE.zElement(i)
+                    ->getName()
+                    .istGleich(outputType))
+            {
+                item = StaticRegistry<ItemType>::INSTANCE.zElement(i)
+                           ->createItem();
+                break;
+            }
+        }
+        recipie->setOutput(item, outputCount);
+        if (!zShapedRecipieList(group)) registerShapedRecipieList(group);
+        zShapedRecipieList(group)->addRecipie(recipie);
+    }
+    else if (zRecipie->zValue("type")->asString()->getString().istGleich(
+                 "unordered"))
+    {
+        Recipie* recipie = new Recipie();
+        for (JSONValue* input : *zRecipie->zValue("inputs")->asArray())
+        {
+            int count = (int)input->asObject()
+                            ->zValue("count")
+                            ->asNumber()
+                            ->getNumber();
+            ItemFilter* filter
+                = loadFilter(input->asObject()->zValue("filter")->asObject());
+            recipie->addIngredient(filter, count);
+        }
+        for (JSONValue* output : *zRecipie->zValue("outputs")->asArray())
+        {
+            int count = (int)output->asObject()
+                            ->zValue("count")
+                            ->asNumber()
+                            ->getNumber();
+            Framework::Text outputType = output->asObject()
+                                             ->zValue("item")
+                                             ->asObject()
+                                             ->zValue("itemType")
+                                             ->asString()
+                                             ->getString();
+            Item* item = 0;
+            for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount();
+                 i++)
+            {
+                if (StaticRegistry<ItemType>::INSTANCE.zElement(i)
+                    && StaticRegistry<ItemType>::INSTANCE.zElement(i)
+                        ->getName()
+                        .istGleich(outputType))
+                {
+                    item = StaticRegistry<ItemType>::INSTANCE.zElement(i)
+                               ->createItem();
+                    break;
+                }
+            }
+            recipie->addOutput(item, count);
+        }
+        if (!zRecipieList(group)) registerRecipieList(group);
+        zRecipieList(group)->addRecipie(recipie);
+    }
 }
 
 ItemFilter* RecipieLoader::loadFilter(JSONObject* zFilter)
 {
-	Framework::Text type = zFilter->zValue("itemType")->asString()->getString();
-	for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
-	{
-		if (StaticRegistry<ItemType>::INSTANCE.zElement(i)->getName().istGleich(type))
-			return new TypeItemFilter(StaticRegistry<ItemType>::INSTANCE.zElement(i));
-	}
-	return 0;
+    Framework::Text type = zFilter->zValue("itemType")->asString()->getString();
+    for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
+    {
+        if (StaticRegistry<ItemType>::INSTANCE.zElement(i)
+            && StaticRegistry<ItemType>::INSTANCE.zElement(i)
+                   ->getName()
+                   .istGleich(type))
+            return new TypeItemFilter(
+                StaticRegistry<ItemType>::INSTANCE.zElement(i));
+    }
+    return 0;
 }
 
 RecipieList* RecipieLoader::zRecipieList(const char* name) const
 {
-	for (RecipieList* l : lists)
-	{
-		if (l->getName().istGleich(name))
-			return l;
-	}
-	return 0;
+    for (RecipieList* l : lists)
+    {
+        if (l->getName().istGleich(name)) return l;
+    }
+    return 0;
 }
 
 ShapedRecipieList* RecipieLoader::zShapedRecipieList(const char* name) const
 {
-	for (ShapedRecipieList* l : shapedLists)
-	{
-		if (l->getName().istGleich(name))
-			return l;
-	}
-	return 0;
+    for (ShapedRecipieList* l : shapedLists)
+    {
+        if (l->getName().istGleich(name)) return l;
+    }
+    return 0;
 }
 
 void RecipieLoader::registerRecipieList(const char* name)
 {
-	if (zRecipieList(name))
-		throw new std::invalid_argument("the recipie list already exists");
-	lists.add(new RecipieList(name));
+    if (zRecipieList(name))
+        throw new std::invalid_argument("the recipie list already exists");
+    lists.add(new RecipieList(name));
 }
 
 void RecipieLoader::registerShapedRecipieList(const char* name)
 {
-	if (zShapedRecipieList(name))
-		throw new std::invalid_argument("the recipie list already exists");
-	shapedLists.add(new ShapedRecipieList(name));
+    if (zShapedRecipieList(name))
+        throw new std::invalid_argument("the recipie list already exists");
+    shapedLists.add(new ShapedRecipieList(name));
 }
 
-ItemModifier* RecipieLoader::loadModifier(Framework::JSON::JSONObject* zModifier)
+ItemModifier* RecipieLoader::loadModifier(
+    Framework::JSON::JSONObject* zModifier)
 {
-	return new AttributeItemModifier(zModifier->zValue("attribute")->asString()->getString(), zModifier->zValue("value")->asString()->getString());
+    return new AttributeItemModifier(
+        zModifier->zValue("attribute")->asString()->getString(),
+        zModifier->zValue("value")->asString()->getString());
 }
 
 JSONValidator* RecipieLoader::zRecipieValidator()
 {
-	if (validator)
-		return validator;
-	Framework::RCArray<Framework::Text> itemTypes;
-	for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
-		itemTypes.add(new Framework::Text(StaticRegistry<ItemType>::INSTANCE.zElement(i)->getName().getText()));
-	JSONValidator* filterValidator = JSONValidator::buildForObject()
-		->withRequiredString("itemType")->whichIsOneOf(itemTypes)->finishString()
-		->finishObject();
-	JSONValidator* outputValidator = JSONValidator::buildForObject()
-		->withRequiredString("itemType")->whichIsOneOf(itemTypes)->finishString()
-		->finishObject();
-	validator = JSONValidator::buildForArray()
-		->typeSpecifiedByAttribute("type")
-		->removeInvalidEntries()
-		->addAcceptedTypeInArray(
-			JSONValidator::buildForObject()
-			->withRequiredString("type")->withExactMatch("shaped")->finishString()
-			->withRequiredString("group")->finishString()
-			->withRequiredNumber("width")->whichIsGreaterThen(0)->finishNumber()
-			->withRequiredNumber("height")->whichIsGreaterThen(0)->finishNumber()
-			->withRequiredAttribute("inputs",
-				JSONValidator::buildForArray()
-				->withDefault(new JSONArray())
-				->addAcceptedTypeInArray(JSONValidator::buildForObject()
-					->withRequiredNumber("x")->whichIsGreaterOrEqual(0)->finishNumber()
-					->withRequiredNumber("y")->whichIsGreaterOrEqual(0)->finishNumber()
-					->withRequiredAttribute("filter", dynamic_cast<JSONValidator*>(filterValidator->getThis()))
-					->withRequiredAttribute("modifiers",
-						JSONValidator::buildForArray()
-						->withDefault(Parser::getValue("[{\"attribute\": \"hp\", \"value\": \"=0\"}]")->asArray())
-						->addAcceptedTypeInArray(JSONValidator::buildForObject()
-							->withRequiredString("attribute")->finishString()
-							->withRequiredString("value")->finishString()
-							->finishObject())
-						->finishArray())
-					->finishObject())
-				->finishArray())
-			->withRequiredAttribute("output", dynamic_cast<JSONValidator*>(outputValidator->getThis()))
-			->withRequiredNumber("outputCount")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
-			->finishObject())
-		->addAcceptedTypeInArray(
-			JSONValidator::buildForObject()
-			->withRequiredString("type")->withExactMatch("unordered")->finishString()
-			->withRequiredString("group")->finishString()
-			->withRequiredAttribute("inputs",
-				JSONValidator::buildForArray()
-				->withDefault(new JSONArray())
-				->addAcceptedTypeInArray(
-					JSONValidator::buildForObject()
-					->withRequiredNumber("count")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
-					->withRequiredAttribute("filter", dynamic_cast<JSONValidator*>(filterValidator->getThis()))
-					->finishObject())
-				->finishArray())
-			->withRequiredAttribute("output",
-				JSONValidator::buildForArray()
-				->addAcceptedTypeInArray(JSONValidator::buildForObject()
-					->withRequiredAttribute("item", dynamic_cast<JSONValidator*>(outputValidator->getThis()))
-					->withRequiredNumber("count")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
-					->finishObject())
-				->finishArray())
-			->finishObject())
-		->finishArray();
-	filterValidator->release();
-	outputValidator->release();
-	return validator;
+    if (validator) return validator;
+    Framework::RCArray<Framework::Text> itemTypes;
+    for (int i = 0; i < StaticRegistry<ItemType>::INSTANCE.getCount(); i++)
+    {
+        if (StaticRegistry<ItemType>::INSTANCE.zElement(i))
+        {
+            itemTypes.add(new Framework::Text(
+                StaticRegistry<ItemType>::INSTANCE.zElement(i)
+                    ->getName()
+                    .getText()));
+        }
+    }
+    JSONValidator* filterValidator = JSONValidator::buildForObject()
+                                         ->withRequiredString("itemType")
+                                         ->whichIsOneOf(itemTypes)
+                                         ->finishString()
+                                         ->finishObject();
+    JSONValidator* outputValidator = JSONValidator::buildForObject()
+                                         ->withRequiredString("itemType")
+                                         ->whichIsOneOf(itemTypes)
+                                         ->finishString()
+                                         ->finishObject();
+    validator
+        = JSONValidator::buildForArray()
+              ->typeSpecifiedByAttribute("type")
+              ->removeInvalidEntries()
+              ->addAcceptedTypeInArray(
+                  JSONValidator::buildForObject()
+                      ->withRequiredString("type")
+                      ->withExactMatch("shaped")
+                      ->finishString()
+                      ->withRequiredString("group")
+                      ->finishString()
+                      ->withRequiredNumber("width")
+                      ->whichIsGreaterThen(0)
+                      ->finishNumber()
+                      ->withRequiredNumber("height")
+                      ->whichIsGreaterThen(0)
+                      ->finishNumber()
+                      ->withRequiredAttribute("inputs",
+                          JSONValidator::buildForArray()
+                              ->withDefault(new JSONArray())
+                              ->addAcceptedTypeInArray(
+                                  JSONValidator::buildForObject()
+                                      ->withRequiredNumber("x")
+                                      ->whichIsGreaterOrEqual(0)
+                                      ->finishNumber()
+                                      ->withRequiredNumber("y")
+                                      ->whichIsGreaterOrEqual(0)
+                                      ->finishNumber()
+                                      ->withRequiredAttribute("filter",
+                                          dynamic_cast<JSONValidator*>(
+                                              filterValidator->getThis()))
+                                      ->withRequiredAttribute("modifiers",
+                                          JSONValidator::buildForArray()
+                                              ->withDefault(Parser::getValue(
+                                                  "[{\"attribute\": \"hp\", "
+                                                  "\"value\": \"=0\"}]")
+                                                                ->asArray())
+                                              ->addAcceptedTypeInArray(
+                                                  JSONValidator::
+                                                      buildForObject()
+                                                          ->withRequiredString(
+                                                              "attribute")
+                                                          ->finishString()
+                                                          ->withRequiredString(
+                                                              "value")
+                                                          ->finishString()
+                                                          ->finishObject())
+                                              ->finishArray())
+                                      ->finishObject())
+                              ->finishArray())
+                      ->withRequiredAttribute("output",
+                          dynamic_cast<JSONValidator*>(
+                              outputValidator->getThis()))
+                      ->withRequiredNumber("outputCount")
+                      ->withDefault(1)
+                      ->whichIsGreaterThen(0)
+                      ->finishNumber()
+                      ->finishObject())
+              ->addAcceptedTypeInArray(
+                  JSONValidator::buildForObject()
+                      ->withRequiredString("type")
+                      ->withExactMatch("unordered")
+                      ->finishString()
+                      ->withRequiredString("group")
+                      ->finishString()
+                      ->withRequiredAttribute("inputs",
+                          JSONValidator::buildForArray()
+                              ->withDefault(new JSONArray())
+                              ->addAcceptedTypeInArray(
+                                  JSONValidator::buildForObject()
+                                      ->withRequiredNumber("count")
+                                      ->withDefault(1)
+                                      ->whichIsGreaterThen(0)
+                                      ->finishNumber()
+                                      ->withRequiredAttribute("filter",
+                                          dynamic_cast<JSONValidator*>(
+                                              filterValidator->getThis()))
+                                      ->finishObject())
+                              ->finishArray())
+                      ->withRequiredAttribute("output",
+                          JSONValidator::buildForArray()
+                              ->addAcceptedTypeInArray(
+                                  JSONValidator::buildForObject()
+                                      ->withRequiredAttribute("item",
+                                          dynamic_cast<JSONValidator*>(
+                                              outputValidator->getThis()))
+                                      ->withRequiredNumber("count")
+                                      ->withDefault(1)
+                                      ->whichIsGreaterThen(0)
+                                      ->finishNumber()
+                                      ->finishObject())
+                              ->finishArray())
+                      ->finishObject())
+              ->finishArray();
+    filterValidator->release();
+    outputValidator->release();
+    return validator;
 }

+ 6 - 0
FactoryCraft/Start.cpp

@@ -22,6 +22,12 @@ void exit()
 
 int main()
 {
+	initializeBlockTypes();
+    initializeItemTypes();
+    initializeEntityTypes();
+    initializeDimensions();
+    initializeMultiblockTypes();
+	
 	struct rlimit core_limits;
 	core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
 	setrlimit(RLIMIT_CORE, &core_limits);

+ 380 - 21
FactoryCraft/StaticInitializerOrder.cpp

@@ -1,38 +1,397 @@
-#include "StaticRegistry.h"
 #include "BlockType.h"
 #include "ItemType.h"
-
-int count_DimensionGenerator = 0;
-int count_ItemType = 0;
-int count_BlockType = 0;
-int count_WorldUpdateType = 0;
-int count_EntityType = 0;
-int count_MultiblockStructureType = 0;
-
-#undef REGISTER
-#define REGISTER(c, typ)																\
-const int c::ID = count_##typ++;														\
-int registry_initializer_##c##_##typ = StaticRegistry<typ>::INSTANCE.getCount();        \
-const c *c::INSTANCE = new c();															\
-bool initialized_##c##_##typ = StaticRegistry<typ>::INSTANCE.info(c::ID);
-
-// order of includes determines the ids
+#include "StaticRegistry.h"
 // block types
-#include "NoBlock.h" // must be first
 #include "BasicBlocks.h"
+#include "NoBlock.h"
+#include "TreeSeblingBlock.h"
 // dimensions
 #include "OverworldDimension.h"
 // entities
-#include "Player.h"
 #include "ItemEntity.h"
+#include "Player.h"
 // item skills
+#include "BasicItems.h"
 #include "PlayerHand.h"
 #include "StoneTool.h"
-#include "BasicItems.h"
 // world updates
 #include "AddEntityUpdate.h"
 #include "EntityRemovedUpdate.h"
 // Multiblocks
+#include "LightSources.h"
 #include "MultiblockTree.h"
 
-#include "LightSources.h"
+using namespace Framework;
+
+void initializeBlockTypes()
+{
+    new NoBlockBlockType(BlockTypeEnum::NO_BLOCK, &NoBlock::INSTANCE);
+    new NoBlockBlockType(BlockTypeEnum::AIR, &AirBlock::INSTANCE);
+
+    (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"})))
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::STONE,
+         ItemTypeEnum::STONE,
+         ModelInfo("cube", "blocks.ltdb/stone.png", 6)))
+        ->setHardness(2.f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::SAND,
+         ItemTypeEnum::SAND,
+         ModelInfo("cube", "blocks.ltdb/sand.png", 6)))
+        ->setHardness(0.5f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::WOOD_OAK,
+         ItemTypeEnum::WOOD_OAK,
+         ModelInfo("cube", "blocks.ltdb/oak.png", 6)))
+        ->setHardness(1.5f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::LEAVES_WOOD_OAK,
+         ItemTypeEnum::LEAVES_WOOD_OAK,
+         ModelInfo("cube", "blocks.ltdb/leaves.png", 6),
+         [](Vec3<int> pos) {
+             AdditionalItemSpawningBlock* block
+                 = new AdditionalItemSpawningBlock(
+                     BlockTypeEnum::LEAVES_WOOD_OAK, 0, pos);
+             block->addSpawn({1, 1, 0.015, ItemTypeEnum::SEBLING_WOOD_OAK});
+             return (Block*)block;
+         }))
+        ->setHardness(0.1f)
+        ->initializeDefault();
+
+    (new BasicBlockType(BlockTypeEnum::GRAVEL,
+         ItemTypeEnum::GRAVEL,
+         ModelInfo("cube", "blocks.ltdb/gravel.png", 6)))
+        ->setHardness(0.75f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::STONE_GRANITE,
+         ItemTypeEnum::STONE_GRANITE,
+         ModelInfo("cube", "blocks.ltdb/granite.png", 6)))
+        ->setHardness(3.f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::STONE_COBBLE,
+         ItemTypeEnum::STONE_COBBLE,
+         ModelInfo("cube", "blocks.ltdb/cobble.png", 6)))
+        ->setHardness(1.f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::WOOD_BIRCH,
+         ItemTypeEnum::WOOD_BIRCH,
+         ModelInfo("cube", "blocks.ltdb/birch.png", 6)))
+        ->setHardness(1.5f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::LEAVES_WOOD_BIRCH,
+         ItemTypeEnum::LEAVES_WOOD_BIRCH,
+         ModelInfo("cube", "blocks.ltdb/leaves.png", 6),
+         [](Vec3<int> pos) {
+             AdditionalItemSpawningBlock* block
+                 = new AdditionalItemSpawningBlock(
+                     BlockTypeEnum::LEAVES_WOOD_BIRCH, 0, pos);
+             block->addSpawn({1, 1, 0.03, ItemTypeEnum::SEBLING_WOOD_BIRCH});
+             return (Block*)block;
+         }))
+        ->setHardness(0.1f)
+        ->initializeDefault();
+
+    (new BasicBlockType(BlockTypeEnum::WOOD_BEECH,
+         ItemTypeEnum::WOOD_BEECH,
+         ModelInfo("cube", "blocks.ltdb/beech.png", 6)))
+        ->setHardness(1.5f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::LEAVES_WOOD_BEECH,
+         ItemTypeEnum::LEAVES_WOOD_BEECH,
+         ModelInfo("cube", "blocks.ltdb/leaves.png", 6),
+         [](Vec3<int> pos) {
+             AdditionalItemSpawningBlock* block
+                 = new AdditionalItemSpawningBlock(
+                     BlockTypeEnum::LEAVES_WOOD_BEECH, 0, pos);
+             block->addSpawn({1, 1, 0.02, ItemTypeEnum::SEBLING_WOOD_BEECH});
+             return (Block*)block;
+         }))
+        ->setHardness(0.1f)
+        ->initializeDefault();
+
+    (new BasicBlockType(BlockTypeEnum::STONE_BASALT,
+         ItemTypeEnum::STONE_BASALT,
+         ModelInfo("cube", "blocks.ltdb/basalt.png", 6)))
+        ->setHardness(2.f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::WOOD_PINE,
+         ItemTypeEnum::WOOD_PINE,
+         ModelInfo("cube", "blocks.ltdb/pine.png", 6)))
+        ->setHardness(1.4f)
+        ->initializeDefault();
+    (new BasicBlockType(BlockTypeEnum::LEAVES_WOOD_PINE,
+         ItemTypeEnum::LEAVES_WOOD_PINE,
+         ModelInfo("cube", "blocks.ltdb/leaves.png", 6),
+         [](Vec3<int> pos) {
+             AdditionalItemSpawningBlock* block
+                 = new AdditionalItemSpawningBlock(
+                     BlockTypeEnum::LEAVES_WOOD_PINE, 0, pos);
+             block->addSpawn({1, 1, 0.025, ItemTypeEnum::SEBLING_WOOD_PINE});
+             return (Block*)block;
+         }))
+        ->setHardness(0.1f)
+        ->initializeDefault();
+
+    (new BasicLightSourceBlockType(BlockTypeEnum::TORCH,
+         ItemTypeEnum::TORCH,
+         ModelInfo("blocks.m3/torch", "blocks.ltdb/torch.png", 6)))
+        ->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))
+        ->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))
+        ->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))
+        ->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))
+        ->setHardness(0.1f)
+        ->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 StoneToolItemType();
+
+    (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 NoBlockItemType(ItemTypeEnum::STONE_TOOL_BROKEN,
+        "BrokenStoneTool",
+        0,
+        0,
+        ModelInfo("itemCube", "blocks.ltdb/stone.png", 6),
+        []() {
+            return ItemType::createBasicItem(ItemTypeEnum::STONE_TOOL_BROKEN,
+                "Stone Tool",
+                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();
+}

+ 10 - 14
FactoryCraft/StaticRegistry.h

@@ -2,16 +2,6 @@
 
 #include <iostream>
 
-#define REGISTRABLE( c )          \
-public:                           \
-    static const c *INSTANCE;     \
-    static const int ID;          \
-                                  \
-private:
-
-#define REGISTER(c, typ)
-
-
 template<typename T>
 class StaticRegistry
 {
@@ -41,7 +31,8 @@ private:
 		}
 		delete[]registry;
 	}
-
+	
+public:
 	void registerT(T* type, int id)
 	{
 		if (id >= count)
@@ -55,8 +46,7 @@ private:
 		}
 		registry[id] = type;
 	}
-
-public:
+	
 	T* zElement(int id)
 	{
 		if (id < 0 || id >= count)
@@ -79,4 +69,10 @@ public:
 };
 
 template <typename T>
-StaticRegistry<T> StaticRegistry<T>::INSTANCE;
+StaticRegistry<T> StaticRegistry<T>::INSTANCE;
+
+void initializeBlockTypes();
+void initializeItemTypes();
+void initializeEntityTypes();
+void initializeDimensions();
+void initializeMultiblockTypes();

+ 52 - 52
FactoryCraft/StoneTool.cpp

@@ -1,90 +1,90 @@
 #include "StoneTool.h"
-#include "Block.h"
-
-
-BrokenStoneToolItemType::BrokenStoneToolItemType()
-	: ItemType(ID, "BrokenStoneTool", 0, 0, ModelInfo("itemCube", "blocks.ltdb/stone.png", 6)) // TODO: correct model
-{}
-
-Item* BrokenStoneToolItemType::createItem() const
-{
-	return createBasicItem("Stone Tool", 100.f, 100.f, 100.f, 100.f, 0, 0, 0, 1, 0, 10);
-}
 
+#include "Block.h"
 
 StoneToolItemType::StoneToolItemType()
-	: ItemType(ID, "StoneTool", new StoneToolLevelUpRule(), BrokenStoneToolItemType::INSTANCE, ModelInfo("items.m3/stoneTool", "blocks.ltdb/stone.png", 6)) // TODO: correct model
+    : ItemType(ItemTypeEnum::STONE_TOOL,
+        "StoneTool",
+        new StoneToolLevelUpRule(),
+        ItemTypeEnum::STONE_TOOL_BROKEN,
+        ModelInfo("items.m3/stoneTool",
+            "blocks.ltdb/stone.png",
+            6)) // TODO: correct model
 {}
 
-void StoneToolItemType::loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const
+void StoneToolItemType::loadSuperItemSkill(
+    ItemSkill* zSkill, Framework::StreamReader* zReader) const
 {
-	StoneToolSkill* skill = dynamic_cast<StoneToolSkill*>(zSkill);
-	if (!skill)
-		throw "StoneToolItemType::loadSuperItemSkill was called with an invalid skill";
-	zReader->lese((char*)&skill->level, 4);
-	zReader->lese((char*)&skill->xp, 4);
-	zReader->lese((char*)&skill->maxXP, 4);
+    StoneToolSkill* skill = dynamic_cast<StoneToolSkill*>(zSkill);
+    if (!skill)
+        throw "StoneToolItemType::loadSuperItemSkill was called with an "
+              "invalid skill";
+    zReader->lese((char*)&skill->level, 4);
+    zReader->lese((char*)&skill->xp, 4);
+    zReader->lese((char*)&skill->maxXP, 4);
 }
 
-void StoneToolItemType::saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
+void StoneToolItemType::saveSuperItemSkill(
+    const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
 {
-	const StoneToolSkill* skill = dynamic_cast<const StoneToolSkill*>(zSkill);
-	if (!skill)
-		throw "StoneToolItemType::saveSuperItemSkill was called with an invalid skill";
-	zWriter->schreibe((char*)&skill->level, 4);
-	zWriter->schreibe((char*)&skill->xp, 4);
-	zWriter->schreibe((char*)&skill->maxXP, 4);
+    const StoneToolSkill* skill = dynamic_cast<const StoneToolSkill*>(zSkill);
+    if (!skill)
+        throw "StoneToolItemType::saveSuperItemSkill was called with an "
+              "invalid skill";
+    zWriter->schreibe((char*)&skill->level, 4);
+    zWriter->schreibe((char*)&skill->xp, 4);
+    zWriter->schreibe((char*)&skill->maxXP, 4);
 }
 
 Item* StoneToolItemType::createItem() const
 {
-	return createBasicItem("Stone Tool", 100.f, 100.f, 100.f, 100.f, 0, 0, 0, 1, 1, 1);
+    return createBasicItem(
+        id, "Stone Tool", 100.f, 100.f, 100.f, 100.f, 0, 0, 0, 1, 1, 1);
 }
 
 ItemSkill* StoneToolItemType::createDefaultItemSkill() const
 {
-	return new StoneToolSkill();
+    return new StoneToolSkill();
 }
 
-
 StoneToolLevelUpRule::StoneToolLevelUpRule()
-	: ItemSkillLevelUpRule()
+    : ItemSkillLevelUpRule()
 {}
 
 void StoneToolLevelUpRule::applyOn(ItemSkill* zSkill)
 {
-	StoneToolSkill* skill = dynamic_cast<StoneToolSkill*>(zSkill);
-	if (!skill)
-		throw "StoneToolLevelUpRule::applyOn was called with an invalid skill";
-	if (skill->xp >= skill->maxXP)
-	{
-		skill->level++;
-		skill->xp = 0;
-		skill->maxXP = skill->maxXP * 1.5f;
-	}
+    StoneToolSkill* skill = dynamic_cast<StoneToolSkill*>(zSkill);
+    if (!skill)
+        throw "StoneToolLevelUpRule::applyOn was called with an invalid skill";
+    if (skill->xp >= skill->maxXP)
+    {
+        skill->level++;
+        skill->xp = 0;
+        skill->maxXP = skill->maxXP * 1.5f;
+    }
 }
 
-
 StoneToolSkill::StoneToolSkill()
-	: ItemSkill(StoneToolItemType::INSTANCE)
+    : ItemSkill(ItemTypeEnum::STONE_TOOL)
 {
-	level = 1;
-	xp = 0;
-	maxXP = 10;
+    level = 1;
+    xp = 0;
+    maxXP = 10;
 }
 
 void StoneToolSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
 {
-	if (zTarget && zTarget->getHardness() <= 2)
-	{
-		float damage = (1 + ((float)level / 10.f)) / (zTarget->getHardness() + 1);
-		zTarget->setHP(zTarget->getHP() - damage);
-		xp += damage / 20;
-		zUsedItem->setHp(zUsedItem->getHp() - damage / 50);
-	}
+    if (zTarget && zTarget->getHardness() <= 2)
+    {
+        float damage
+            = (1 + ((float)level / 10.f)) / (zTarget->getHardness() + 1);
+        zTarget->setHP(zTarget->getHP() - damage);
+        xp += damage / 20;
+        zUsedItem->setHp(zUsedItem->getHp() - damage / 50);
+    }
 }
 
 void StoneToolSkill::use(Entity* zActor, Item* zUsedItem, Entity* zTarget)
 {
-	// TODO
+    // TODO
 }

+ 18 - 31
FactoryCraft/StoneTool.h

@@ -1,54 +1,41 @@
 #pragma once
 
-#include "ItemType.h"
 #include "ItemSkill.h"
-
-class BrokenStoneToolItemType : public ItemType
-{
-	REGISTRABLE(BrokenStoneToolItemType)
-
-protected:
-	BrokenStoneToolItemType();
-
-public:
-	Item* createItem() const override;
-};
-REGISTER(BrokenStoneToolItemType, ItemType)
+#include "ItemType.h"
 
 class StoneToolItemType : public ItemType
 {
-	REGISTRABLE(StoneToolItemType)
-
 protected:
-	StoneToolItemType();
-	void loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const override;
-	void saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const override;
+    void loadSuperItemSkill(
+        ItemSkill* zSkill, Framework::StreamReader* zReader) const override;
+    void saveSuperItemSkill(const ItemSkill* zSkill,
+        Framework::StreamWriter* zWriter) const override;
 
 public:
-	Item* createItem() const override;
-	ItemSkill* createDefaultItemSkill() const override;
+    StoneToolItemType();
+    Item* createItem() const override;
+    ItemSkill* createDefaultItemSkill() const override;
 };
-REGISTER(StoneToolItemType, ItemType)
 
 class StoneToolLevelUpRule : public ItemSkillLevelUpRule
 {
 public:
-	StoneToolLevelUpRule();
-	void applyOn(ItemSkill* zSkill) override;
+    StoneToolLevelUpRule();
+    void applyOn(ItemSkill* zSkill) override;
 };
 
 class StoneToolSkill : public ItemSkill
 {
 private:
-	int level;
-	float xp;
-	float maxXP;
+    int level;
+    float xp;
+    float maxXP;
 
 public:
-	StoneToolSkill();
-	void use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
-	void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
+    StoneToolSkill();
+    void use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
+    void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
 
-	friend StoneToolItemType;
-	friend StoneToolLevelUpRule;
+    friend StoneToolItemType;
+    friend StoneToolLevelUpRule;
 };

+ 89 - 118
FactoryCraft/TreeSeblingBlock.cpp

@@ -1,155 +1,126 @@
 #include "TreeSeblingBlock.h"
+
 #include "BasicBlocks.h"
-#include "TreeTemplate.h"
-#include "RandNoise.h"
 #include "Game.h"
 #include "NoBlock.h"
+#include "RandNoise.h"
+#include "TreeTemplate.h"
 
-
-TreeSeblingBlock::TreeSeblingBlock(const BlockType* zType, const ItemType* zTool, Framework::Vec3<int> pos, const BlockType* wood, const BlockType* leaves)
-	: Block(zType, zTool, pos, 0),
-	wood(wood),
-	leaves(leaves)
+TreeSeblingBlock::TreeSeblingBlock(int typeId,
+    const ItemType* zTool,
+    Framework::Vec3<int> pos,
+    const BlockType* wood,
+    const BlockType* leaves)
+    : Block(typeId, zTool, pos, 0), wood(wood), leaves(leaves)
 {
-	tickSource = 1;
+    tickSource = 1;
 }
 
 bool TreeSeblingBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
 {
-	seblingTicks += 1;
-	return 0;
+    seblingTicks += 1;
+    return 0;
 }
 
 void TreeSeblingBlock::onPostTick()
 {
-	if (seblingTicks >= seblingTicksMax)
-	{
-		Game::INSTANCE->doLater([wood = wood, leaves = leaves, pos = getPos(), dim = getDimensionId()]()
-			{
-				// the tree sebling object will be deleted during this operation
-				RandNoise noise((int)time(0));
-				if (!Game::INSTANCE->zGenerator()->spawnStructure(pos, dim, [wood = wood, leaves = leaves](GenerationTemplate* tmpl)
-					{
-						TreeTemplate* tree = dynamic_cast<TreeTemplate*>(tmpl);
-						return tree && tree->getWoodType() == wood && tree->getLeavesType() == leaves;
-					}))
-				{
-					Game::INSTANCE->zDimension(dim)->placeBlock(pos, AirBlockBlockType::ID);
-				}
-			});
-	}
+    if ((int)seblingTicks >= seblingTicksMax)
+    {
+        Game::INSTANCE->doLater([wood = wood,
+                                    leaves = leaves,
+                                    pos = getPos(),
+                                    dim = getDimensionId()]() {
+            // the tree sebling object will be deleted during this operation
+            RandNoise noise((int)time(0));
+            if (!Game::INSTANCE->zGenerator()->spawnStructure(pos,
+                    dim,
+                    [wood = wood, leaves = leaves](GenerationTemplate* tmpl) {
+                        TreeTemplate* tree = dynamic_cast<TreeTemplate*>(tmpl);
+                        return tree && tree->getWoodType() == wood
+                            && tree->getLeavesType() == leaves;
+                    }))
+            {
+                Game::INSTANCE->zDimension(dim)->placeBlock(
+                    pos, BlockTypeEnum::AIR);
+            }
+        });
+    }
 }
 
-
-TreeSeblingBlockType::TreeSeblingBlockType(int typeId, int itemTypeId, ModelInfo model)
-	: BlockType(typeId, 0, model, 1, 10, 0),
-	itemType(itemTypeId),
-	transparent(true),
-	passable(true),
-	hardness(0.1f),
-	zTool(0),
-	speedModifier(0.5f),
-	interactable(1)
+TreeSeblingBlockType::TreeSeblingBlockType(
+    int typeId, int itemTypeId, ModelInfo model, int woodType, int leavesType)
+    : BlockType(typeId, 0, model, 1, 10, 0), itemType(itemTypeId),
+      transparent(true), passable(true), hardness(0.1f), zTool(0),
+      speedModifier(0.5f), interactable(1), woodType(woodType),
+      leavesType(leavesType)
 {}
 
 void TreeSeblingBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 {
-	TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
-	if (!block)
-		throw "TreeSeblingBlockType::createSuperBlock was called with a block witch is not an instance of TreeSeblingBlock";
-	block->transparent = transparent;
-	block->passable = passable;
-	block->hp = (float)getInitialMaxHP();
-	block->maxHP = (float)getInitialMaxHP();
-	block->hardness = hardness;
-	block->zTool = zTool;
-	block->speedModifier = speedModifier;
-	block->interactable = interactable;
-	BlockType::createSuperBlock(zBlock, zItem);
+    TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
+    if (!block)
+        throw "TreeSeblingBlockType::createSuperBlock was called with a block "
+              "witch is not an instance of TreeSeblingBlock";
+    block->transparent = transparent;
+    block->passable = passable;
+    block->hp = (float)getInitialMaxHP();
+    block->maxHP = (float)getInitialMaxHP();
+    block->hardness = hardness;
+    block->zTool = zTool;
+    block->speedModifier = speedModifier;
+    block->interactable = interactable;
+    BlockType::createSuperBlock(zBlock, zItem);
 }
 
-void TreeSeblingBlockType::loadSuperBlock(Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
+void TreeSeblingBlockType::loadSuperBlock(
+    Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
 {
-	TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
-	if (!block)
-		throw "TreeSeblingBlockType::loadSuperBlock was called with a block witch is not an instance of TreeSeblingBlock";
-	zReader->lese((char*)&block->seblingTicks, 4);
-	zReader->lese((char*)&block->seblingTicksMax, 4);
-	int id;
-	zReader->lese((char*)&id, 4);
-	block->wood = StaticRegistry<BlockType>::INSTANCE.zElement(id);
-	zReader->lese((char*)&id, 4);
-	block->leaves = StaticRegistry<BlockType>::INSTANCE.zElement(id);
-	BlockType::loadSuperBlock(zBlock, zReader, dimensionId);
+    TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
+    if (!block)
+        throw "TreeSeblingBlockType::loadSuperBlock was called with a block "
+              "witch is not an instance of TreeSeblingBlock";
+    zReader->lese((char*)&block->seblingTicks, 4);
+    zReader->lese((char*)&block->seblingTicksMax, 4);
+    int id;
+    zReader->lese((char*)&id, 4);
+    block->wood = StaticRegistry<BlockType>::INSTANCE.zElement(id);
+    zReader->lese((char*)&id, 4);
+    block->leaves = StaticRegistry<BlockType>::INSTANCE.zElement(id);
+    BlockType::loadSuperBlock(zBlock, zReader, dimensionId);
 }
 
-void TreeSeblingBlockType::saveSuperBlock(Block* zBlock, Framework::StreamWriter* zWriter) const
+void TreeSeblingBlockType::saveSuperBlock(
+    Block* zBlock, Framework::StreamWriter* zWriter) const
 {
-	TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
-	if (!block)
-		throw "TreeSeblingBlockType::saveSuperBlock was called with a block witch is not an instance of TreeSeblingBlock";
-	zWriter->schreibe((char*)&block->seblingTicks, 4);
-	zWriter->schreibe((char*)&block->seblingTicksMax, 4);
-	int id = block->wood->getId();
-	zWriter->schreibe((char*)&id, 4);
-	int id = block->leaves->getId();
-	zWriter->schreibe((char*)&id, 4);
-	BlockType::saveSuperBlock(zBlock, zWriter);
+    TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
+    if (!block)
+        throw "TreeSeblingBlockType::saveSuperBlock was called with a block "
+              "witch is not an instance of TreeSeblingBlock";
+    zWriter->schreibe((char*)&block->seblingTicks, 4);
+    zWriter->schreibe((char*)&block->seblingTicksMax, 4);
+    int id = block->wood->getId();
+    zWriter->schreibe((char*)&id, 4);
+    id = block->leaves->getId();
+    zWriter->schreibe((char*)&id, 4);
+    BlockType::saveSuperBlock(zBlock, zWriter);
 }
 
 Item* TreeSeblingBlockType::createItem() const
 {
-	return StaticRegistry<ItemType>::INSTANCE.zElement(itemType)->createItem();
+    return StaticRegistry<ItemType>::INSTANCE.zElement(itemType)->createItem();
 }
 
-
-OakSeblingBlockType::OakSeblingBlockType()
-	: TreeSeblingBlockType(ID, OakSeblingBlockItemType::ID, ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1))
-{
-	hardness = 0.1f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-Block* OakSeblingBlockType::createBlock(Framework::Vec3<int> position) const
-{
-	return new TreeSeblingBlock(this, zTool, position, OakBlockType::INSTANCE, OakLeavesBlockType::INSTANCE);
-}
-
-
-BirchSeblingBlockType::BirchSeblingBlockType()
-	: TreeSeblingBlockType(ID, BirchSeblingBlockItemType::ID, ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1))
-{
-	hardness = 0.1f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-Block* BirchSeblingBlockType::createBlock(Framework::Vec3<int> position) const
-{
-	return new TreeSeblingBlock(this, zTool, position, BirchBlockType::INSTANCE, BirchLeavesBlockType::INSTANCE);
-}
-
-
-BeechSeblingBlockType::BeechSeblingBlockType()
-	: TreeSeblingBlockType(ID, BeechSeblingBlockItemType::ID, ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1))
-{
-	hardness = 0.1f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
-}
-
-Block* BeechSeblingBlockType::createBlock(Framework::Vec3<int> position) const
-{
-	return new TreeSeblingBlock(this, zTool, position, BeechBlockType::INSTANCE, BeechLeavesBlockType::INSTANCE);
-}
-
-
-PineSeblingBlockType::PineSeblingBlockType()
-	: TreeSeblingBlockType(ID, PineSeblingBlockItemType::ID, ModelInfo("blocks.m3/sebling", "blocks.ltdb/sebling.png", 1))
+Block* TreeSeblingBlockType::createBlock(Framework::Vec3<int> position) const
 {
-	hardness = 0.1f;
-	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
+    return new TreeSeblingBlock(getId(),
+        zTool,
+        position,
+        StaticRegistry<BlockType>::INSTANCE.zElement(woodType),
+        StaticRegistry<BlockType>::INSTANCE.zElement(leavesType));
 }
 
-Block* PineSeblingBlockType::createBlock(Framework::Vec3<int> position) const
+TreeSeblingBlockType* TreeSeblingBlockType::setHardness(float hardness)
 {
-	return new TreeSeblingBlock(this, zTool, position, PineBlockType::INSTANCE, PineLeavesBlockType::INSTANCE);
+    this->hardness = hardness;
+    return this;
 }

+ 7 - 55
FactoryCraft/TreeSeblingBlock.h

@@ -13,7 +13,7 @@ private:
 	const BlockType* leaves;
 
 public:
-	TreeSeblingBlock(const BlockType* zType, const ItemType* zTool, Framework::Vec3<int> pos, const BlockType* wood, const BlockType* leaves);
+	TreeSeblingBlock(int typeId, const ItemType* zTool, Framework::Vec3<int> pos, const BlockType* wood, const BlockType* leaves);
 	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) override;
 	virtual void onPostTick() override;
 
@@ -25,71 +25,23 @@ class TreeSeblingBlockType : public BlockType
 {
 private:
 	int itemType;
-
-protected:
 	bool transparent;
 	bool passable;
 	float hardness;
 	const ItemType* zTool;
 	float speedModifier;
 	bool interactable;
+	int woodType;
+	int leavesType;
 
-	TreeSeblingBlockType(int typeId, int itemTypeId, ModelInfo model);
+protected:
 	virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
 	virtual void loadSuperBlock(Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const override;
 	virtual void saveSuperBlock(Block* zBlock, Framework::StreamWriter* zWriter) const override;
 	virtual Item* createItem() const override;
-};
-
-
-class OakSeblingBlockType : public TreeSeblingBlockType
-{
-	REGISTRABLE(OakSeblingBlockType)
-
-protected:
-	OakSeblingBlockType();
-
-public:
 	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-};
-REGISTER(OakSeblingBlockType, BlockType)
-
-
-class BirchSeblingBlockType : public TreeSeblingBlockType
-{
-	REGISTRABLE(BirchSeblingBlockType)
-
-protected:
-	BirchSeblingBlockType();
 
 public:
-	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-};
-REGISTER(BirchSeblingBlockType, BlockType)
-
-
-class BeechSeblingBlockType : public TreeSeblingBlockType
-{
-	REGISTRABLE(BeechSeblingBlockType)
-
-protected:
-	BeechSeblingBlockType();
-
-public:
-	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-};
-REGISTER(BeechSeblingBlockType, BlockType)
-
-
-class PineSeblingBlockType : public TreeSeblingBlockType
-{
-	REGISTRABLE(PineSeblingBlockType)
-
-protected:
-	PineSeblingBlockType();
-
-public:
-	virtual Block* createBlock(Framework::Vec3<int> position) const override;
-	
-};
-REGISTER(PineSeblingBlockType, BlockType)
+	TreeSeblingBlockType(int typeId, int itemTypeId, ModelInfo model, int woodType, int leavesType);
+	TreeSeblingBlockType* setHardness(float hardness);
+};

+ 71 - 46
FactoryCraft/TreeTemplate.cpp

@@ -1,61 +1,86 @@
 #include "TreeTemplate.h"
-#include "MultiblockTree.h"
-#include "Game.h"
 
+#include "Game.h"
+#include "MultiblockTree.h"
 
-TreeTemplate::TreeTemplate(float propability, const BlockType* zWoodType, const BlockType* zLeaveType, int minHeight, int maxHeight)
-	: GenerationTemplate(propability, 0, 1, Framework::Vec3<int>(-2, -2, 0), Framework::Vec3<int>(5, 5, maxHeight)),
-	zWoodType(zWoodType),
-	zLeaveType(zLeaveType),
-	minHeight(minHeight),
-	maxHeight(maxHeight)
+TreeTemplate::TreeTemplate(float propability,
+    int woodBlockTypeId,
+    int leaveBlockType,
+    int minHeight,
+    int maxHeight)
+    : GenerationTemplate(propability,
+        0,
+        1,
+        Framework::Vec3<int>(-2, -2, 0),
+        Framework::Vec3<int>(5, 5, maxHeight)),
+      woodBlockTypeId(woodBlockTypeId),
+      leaveBlockType(leaveBlockType),
+      minHeight(minHeight),
+      maxHeight(maxHeight)
 {}
 
-GeneratedStructure* TreeTemplate::generateAt(Framework::Vec3<int> location, Noise* zNoise, int dimensionId)
+GeneratedStructure* TreeTemplate::generateAt(
+    Framework::Vec3<int> location, Noise* zNoise, int dimensionId)
 {
-	double noise = zNoise->getNoise((double)location.x + 40, (double)location.y + 70, (double)location.z - 20);
-	int height = (int)(minHeight + (noise * (maxHeight - minHeight)));
-	Dimension* zDim = Game::INSTANCE->zDimension(dimensionId);
-	MultiblockStructure* treeStructure = zDim->zStructureByPosition(location);
-	if (!treeStructure)
-	{
-		treeStructure = new MultiblockTree(dimensionId, zDim->getNextStructureId(), location);
-		zDim->addStructure(treeStructure);
-	}
-	Framework::Vec3<int> minAffected = Framework::Vec3<int>(-2, -2, 0) + location;
-	GeneratedStructure* generated = new GeneratedStructure(dynamic_cast<GenerationTemplate*>(getThis()), location, Framework::Vec3<int>(5, 5, height), minAffected);
-	for (int x = 1; x < 4; x++)
-	{
-		for (int y = 1; y < 4; y++)
-		{
-			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, y, height - 1));
-			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, y, height - 5));
-		}
-	}
-	for (int z = height - 2; z >= height - 4; z--)
-	{
-		for (int x = 1; x < 4; x++)
-		{
-			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, 0, z));
-			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(0, x, z));
-			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, 4, z));
-			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(4, x, z));
-			for (int y = 1; y < 4; y++)
-				generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, y, z));
-		}
-	}
-	for (int i = 0; i < height - 1; i++)
-		generated->setBlockAt(zWoodType->getId(), Framework::Vec3<int>(2, 2, i));
-	generated->addAllBlocksToStructure(dynamic_cast<MultiblockStructure*>(treeStructure->getThis()));
-	return generated;
+    double noise = zNoise->getNoise((double)location.x + 40,
+        (double)location.y + 70,
+        (double)location.z - 20);
+    int height = (int)(minHeight + (noise * (maxHeight - minHeight)));
+    Dimension* zDim = Game::INSTANCE->zDimension(dimensionId);
+    MultiblockStructure* treeStructure = zDim->zStructureByPosition(location);
+    if (!treeStructure)
+    {
+        treeStructure = new MultiblockTree(
+            dimensionId, zDim->getNextStructureId(), location);
+        zDim->addStructure(treeStructure);
+    }
+    Framework::Vec3<int> minAffected
+        = Framework::Vec3<int>(-2, -2, 0) + location;
+    GeneratedStructure* generated
+        = new GeneratedStructure(dynamic_cast<GenerationTemplate*>(getThis()),
+            location,
+            Framework::Vec3<int>(5, 5, height),
+            minAffected);
+    for (int x = 1; x < 4; x++)
+    {
+        for (int y = 1; y < 4; y++)
+        {
+            generated->setBlockAt(
+                leaveBlockType, Framework::Vec3<int>(x, y, height - 1));
+            generated->setBlockAt(
+                leaveBlockType, Framework::Vec3<int>(x, y, height - 5));
+        }
+    }
+    for (int z = height - 2; z >= height - 4; z--)
+    {
+        for (int x = 1; x < 4; x++)
+        {
+            generated->setBlockAt(
+                leaveBlockType, Framework::Vec3<int>(x, 0, z));
+            generated->setBlockAt(
+                leaveBlockType, Framework::Vec3<int>(0, x, z));
+            generated->setBlockAt(
+                leaveBlockType, Framework::Vec3<int>(x, 4, z));
+            generated->setBlockAt(
+                leaveBlockType, Framework::Vec3<int>(4, x, z));
+            for (int y = 1; y < 4; y++)
+                generated->setBlockAt(
+                    leaveBlockType, Framework::Vec3<int>(x, y, z));
+        }
+    }
+    for (int i = 0; i < height - 1; i++)
+        generated->setBlockAt(woodBlockTypeId, Framework::Vec3<int>(2, 2, i));
+    generated->addAllBlocksToStructure(
+        dynamic_cast<MultiblockStructure*>(treeStructure->getThis()));
+    return generated;
 }
 
 const BlockType* TreeTemplate::getWoodType() const
 {
-	return zWoodType;
+    return StaticRegistry<BlockType>::INSTANCE.zElement(woodBlockTypeId);
 }
 
 const BlockType* TreeTemplate::getLeavesType() const
 {
-	return zLeaveType;
+    return StaticRegistry<BlockType>::INSTANCE.zElement(leaveBlockType);
 }

+ 3 - 3
FactoryCraft/TreeTemplate.h

@@ -5,13 +5,13 @@
 class TreeTemplate : public GenerationTemplate
 {
 private:
-	const BlockType* zWoodType;
-	const BlockType* zLeaveType;
+    int woodBlockTypeId;
+    int leaveBlockType;
 	int minHeight;
 	int maxHeight;
 
 public:
-	TreeTemplate(float propability, const BlockType* zWoodType, const BlockType* zLeaveType, int minHeight, int maxHeight);
+	TreeTemplate(float propability, int woodBlockTypeId, int leaveBlockType, int minHeight, int maxHeight);
 	virtual GeneratedStructure* generateAt(Framework::Vec3<int> location, Noise* zNoise, int dimensionId) override;
 	const BlockType* getWoodType() const;
 	const BlockType* getLeavesType() const;

+ 0 - 7
FactoryCraft/WorldUpdate.cpp

@@ -44,11 +44,4 @@ int WorldUpdate::distanceTo(int x, int y) const
 	if (y >= minAffected.y && y <= maxAffected.y)
 		yDist = 0;
 	return MIN(xDist, yDist);
-}
-
-
-WorldUpdateType::WorldUpdateType(int id)
-	: ReferenceCounter()
-{
-	StaticRegistry<WorldUpdateType>::INSTANCE.registerT(this, id);
 }

+ 7 - 6
FactoryCraft/WorldUpdate.h

@@ -8,6 +8,13 @@
 
 class Dimension;
 
+class WorldUpdateTypeEnum
+{
+public:
+    static const int ADD_ENTITY = 0;
+    static const int REMOVE_ENTITY = 1;
+};
+
 class WorldUpdate : public Framework::ReferenceCounter
 {
 private:
@@ -30,10 +37,4 @@ public:
 	const Framework::Vec3<int>& getMaxAffectedPoint() const;
 	int getType() const;
 	int distanceTo(int x, int y) const;
-};
-
-class WorldUpdateType : public Framework::ReferenceCounter
-{
-protected:
-	WorldUpdateType(int id);
 };