Browse Source

blocks are now lazy instantiated to save memory
shared block instances are used if the blocks match the default state of there type

Kolja Strohm 3 years ago
parent
commit
a57b9f9611
72 changed files with 1127 additions and 748 deletions
  1. 8 8
      FactoryCraft/AddChunkUpdate.cpp
  2. 4 4
      FactoryCraft/AddChunkUpdate.h
  3. 6 6
      FactoryCraft/Area.cpp
  4. 11 11
      FactoryCraft/BasicBlock.cpp
  5. 9 9
      FactoryCraft/BasicBlocks.h
  6. 9 6
      FactoryCraft/BasicInterpolator.cpp
  7. 1 1
      FactoryCraft/BasicInterpolator.h
  8. 2 1
      FactoryCraft/BiomGenerator.h
  9. 2 1
      FactoryCraft/BiomInterpolator.h
  10. 41 31
      FactoryCraft/Block.cpp
  11. 20 19
      FactoryCraft/Block.h
  12. 47 30
      FactoryCraft/BlockType.cpp
  13. 13 11
      FactoryCraft/BlockType.h
  14. 126 53
      FactoryCraft/Chunk.cpp
  15. 19 14
      FactoryCraft/Chunk.h
  16. 2 1
      FactoryCraft/Constants.h
  17. 20 19
      FactoryCraft/Dimension.cpp
  18. 10 10
      FactoryCraft/Dimension.h
  19. 36 25
      FactoryCraft/DimensionGenerator.cpp
  20. 7 5
      FactoryCraft/DimensionGenerator.h
  21. 1 1
      FactoryCraft/Effect.h
  22. 1 1
      FactoryCraft/EffectFactory.h
  23. 4 4
      FactoryCraft/Entity.cpp
  24. 5 5
      FactoryCraft/Entity.h
  25. 38 38
      FactoryCraft/EntityType.cpp
  26. 7 7
      FactoryCraft/EntityType.h
  27. 2 0
      FactoryCraft/FactoryCraft.vcxproj
  28. 6 0
      FactoryCraft/FactoryCraft.vcxproj.filters
  29. 78 65
      FactoryCraft/Game.cpp
  30. 22 21
      FactoryCraft/Game.h
  31. 2 2
      FactoryCraft/GrasslandBiom.cpp
  32. 1 1
      FactoryCraft/GrasslandBiom.h
  33. 49 47
      FactoryCraft/Inventory.cpp
  34. 21 21
      FactoryCraft/Inventory.h
  35. 8 8
      FactoryCraft/Item.cpp
  36. 9 9
      FactoryCraft/Item.h
  37. 5 5
      FactoryCraft/ItemFilter.cpp
  38. 9 9
      FactoryCraft/ItemFilter.h
  39. 2 2
      FactoryCraft/ItemSkill.cpp
  40. 5 5
      FactoryCraft/ItemSkill.h
  41. 8 8
      FactoryCraft/ItemSlot.cpp
  42. 5 5
      FactoryCraft/ItemSlot.h
  43. 9 9
      FactoryCraft/ItemStack.cpp
  44. 9 9
      FactoryCraft/ItemStack.h
  45. 32 32
      FactoryCraft/ItemType.cpp
  46. 13 13
      FactoryCraft/ItemType.h
  47. 20 15
      FactoryCraft/NetworkResponse.cpp
  48. 8 7
      FactoryCraft/NetworkResponse.h
  49. 67 0
      FactoryCraft/NoBlock.cpp
  50. 46 0
      FactoryCraft/NoBlock.h
  51. 1 1
      FactoryCraft/Noise.cpp
  52. 1 1
      FactoryCraft/Noise.h
  53. 5 5
      FactoryCraft/PerlinNoise.cpp
  54. 97 6
      FactoryCraft/Player.cpp
  55. 20 5
      FactoryCraft/Player.h
  56. 26 31
      FactoryCraft/Server.cpp
  57. 15 16
      FactoryCraft/Server.h
  58. 7 7
      FactoryCraft/Start.cpp
  59. 1 0
      FactoryCraft/StaticInitializerOrder.cpp
  60. 7 7
      FactoryCraft/StaticRegistry.h
  61. 8 7
      FactoryCraft/TickOrganizer.cpp
  62. 5 5
      FactoryCraft/TickOrganizer.h
  63. 11 11
      FactoryCraft/TickQueue.cpp
  64. 4 4
      FactoryCraft/TickQueue.h
  65. 2 2
      FactoryCraft/TickWorker.cpp
  66. 2 2
      FactoryCraft/TickWorker.h
  67. 9 4
      FactoryCraft/WorldGenerator.cpp
  68. 4 3
      FactoryCraft/WorldGenerator.h
  69. 9 9
      FactoryCraft/WorldLoader.cpp
  70. 2 2
      FactoryCraft/WorldLoader.h
  71. 2 2
      FactoryCraft/WorldUpdate.cpp
  72. 4 4
      FactoryCraft/WorldUpdate.h

+ 8 - 8
FactoryCraft/AddChunkUpdate.cpp

@@ -4,7 +4,7 @@
 #include "Dimension.h"
 
 
-AddChunkUpdate::AddChunkUpdate( Chunk *chunk )
+AddChunkUpdate::AddChunkUpdate( Chunk* chunk )
     : WorldUpdate( chunk->getDimensionId(), Framework::Vec3<int>( chunk->getCenter().x - CHUNK_SIZE / 2, chunk->getCenter().y - CHUNK_SIZE / 2, 0 ), Framework::Vec3<int>( chunk->getCenter().x + CHUNK_SIZE / 2, chunk->getCenter().y + CHUNK_SIZE / 2, WORLD_HEIGHT - 1 ) ),
     chunk( chunk )
 {}
@@ -14,19 +14,19 @@ AddChunkUpdate::~AddChunkUpdate()
     chunk->release();
 }
 
-void AddChunkUpdate::onUpdate( Dimension *zDimension )
+void AddChunkUpdate::onUpdate( Dimension* zDimension )
 {
-    zDimension->addChunk( dynamic_cast<Chunk *>( chunk->getThis() ) );
+    zDimension->addChunk( dynamic_cast<Chunk*>(chunk->getThis()) );
 }
 
-void AddChunkUpdate::write( Framework::StreamWriter *zWriter )
+void AddChunkUpdate::write( Framework::StreamWriter* zWriter )
 {
-    zWriter->schreibe( (char *)&AddChunkUpdateType::ID, 4 );
+    zWriter->schreibe( (char*)&AddChunkUpdateType::ID, 4 );
     int dimensionID = chunk->getDimensionId();
-    zWriter->schreibe( (char *)&dimensionID, 4 );
+    zWriter->schreibe( (char*)&dimensionID, 4 );
     Framework::Punkt center = chunk->getCenter();
-    zWriter->schreibe( (char *)&center.x, 4 );
-    zWriter->schreibe( (char *)&center.y, 4 );
+    zWriter->schreibe( (char*)&center.x, 4 );
+    zWriter->schreibe( (char*)&center.y, 4 );
     chunk->save( zWriter );
 }
 

+ 4 - 4
FactoryCraft/AddChunkUpdate.h

@@ -7,14 +7,14 @@ class Chunk;
 class AddChunkUpdate : public WorldUpdate
 {
 private:
-    Chunk *chunk;
+    Chunk* chunk;
 
 public:
-    AddChunkUpdate( Chunk *chunk );
+    AddChunkUpdate( Chunk* chunk );
     ~AddChunkUpdate();
 
-    void onUpdate( Dimension *zDimension ) override;
-    void write( Framework::StreamWriter *zWriter ) override;
+    void onUpdate( Dimension* zDimension ) override;
+    void write( Framework::StreamWriter* zWriter ) override;
 };
 
 class AddChunkUpdateType : WorldUpdateType

+ 6 - 6
FactoryCraft/Area.cpp

@@ -42,17 +42,17 @@ Directions getDirections( Framework::Vec3<float> currentPos, Framework::Vec3<flo
 Framework::Vec3<int> getDirection( Directions dir )
 {
     Framework::Vec3<int> result( 0, 0, 0 );
-    if( ( dir | NORTH ) == dir )
+    if( (dir | NORTH) == dir )
         --result.y;
-    if( ( dir | EAST ) == dir )
+    if( (dir | EAST) == dir )
         ++result.x;
-    if( ( dir | SOUTH ) == dir )
+    if( (dir | SOUTH) == dir )
         ++result.y;
-    if( ( dir | WEST ) == dir )
+    if( (dir | WEST) == dir )
         --result.x;
-    if( ( dir | TOP ) == dir )
+    if( (dir | TOP) == dir )
         ++result.z;
-    if( ( dir | BOTTOM ) == dir )
+    if( (dir | BOTTOM) == dir )
         --result.z;
     return result;
 }

+ 11 - 11
FactoryCraft/BasicBlock.cpp

@@ -1,11 +1,11 @@
 #include "BasicBlocks.h"
 
 
-BasicBlock::BasicBlock( BlockType *zType, ItemType *zTool, Framework::Vec3<int> pos )
+BasicBlock::BasicBlock( BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos )
     : Block( zType, zTool, pos, false )
 {}
 
-bool BasicBlock::onTick( TickQueue *zQueue, int numTicks, bool &blocked )
+bool BasicBlock::onTick( TickQueue* zQueue, int numTicks, bool& blocked )
 {
     return 0;
 }
@@ -18,23 +18,23 @@ DirtBlockType::DirtBlockType()
     : BlockType( ID )
 {}
 
-void DirtBlockType::loadSuperBlock( Block *zBlock, Framework::StreamReader *zReader )
+void DirtBlockType::loadSuperBlock( Block* zBlock, Framework::StreamReader* zReader )
 {
     BlockType::loadSuperBlock( zBlock, zReader );
 }
 
-void DirtBlockType::saveSuperBlock( Block *zBlock, Framework::StreamWriter *zWriter )
+void DirtBlockType::saveSuperBlock( Block* zBlock, Framework::StreamWriter* zWriter )
 {
     BlockType::saveSuperBlock( zBlock, zWriter );
 }
 
-void DirtBlockType::createSuperBlock( Block *zBlock, Item *zItem )
+void DirtBlockType::createSuperBlock( Block* zBlock, Item* zItem )
 {
     if( zItem )
         BlockType::createSuperBlock( zBlock, zItem );
     else
     {
-        BasicBlock *block = dynamic_cast<BasicBlock *>( zBlock );
+        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 = 0;
@@ -47,17 +47,17 @@ void DirtBlockType::createSuperBlock( Block *zBlock, Item *zItem )
     }
 }
 
-void DirtBlockType::createSuperItem( Block *zBlock, Item *zItem )
+void DirtBlockType::createSuperItem( Block* zBlock, Item* zItem )
 {
     BlockType::createSuperItem( zBlock, zItem );
 }
 
-Block *DirtBlockType::createBlock( Framework::Vec3<int> position, Game *zTarget )
+Block* DirtBlockType::createBlock( Framework::Vec3<int> position, Game* zTarget )
 {
     return new BasicBlock( this, 0, position ); // TODO: add efective tool
 }
 
-Item *DirtBlockType::createItem( Game *zTarget )
+Item* DirtBlockType::createItem( Game* zTarget )
 {
     return StaticRegistry<ItemType>::INSTANCE.zElement( DirtBlockItemType::ID )->createItem();
 }
@@ -67,9 +67,9 @@ DirtBlockItemType::DirtBlockItemType()
     : BasicBlockItemType( ID, 0, 0 )
 {}
 
-Item *DirtBlockItemType::createItem() const
+Item* DirtBlockItemType::createItem() const
 {
-    BasicBlockItem *item = new BasicBlockItem( (ItemType *)this, "Dirt" );
+    BasicBlockItem* item = new BasicBlockItem( (ItemType*)this, "Dirt" );
     initializeItem( item, 0, 0, 100, 100, 1, 0, 1 );
     return item;
 }

+ 9 - 9
FactoryCraft/BasicBlocks.h

@@ -12,8 +12,8 @@ class DirtBlockItemType;
 class BasicBlock : public Block
 {
 public:
-    BasicBlock( BlockType *zType, ItemType *zTool, Framework::Vec3<int> pos );
-    virtual bool onTick( TickQueue *zQueue, int numTicks, bool &blocked ) override;
+    BasicBlock( BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos );
+    virtual bool onTick( TickQueue* zQueue, int numTicks, bool& blocked ) override;
     virtual void onPostTick() override;
 
     friend DirtBlockType;
@@ -24,12 +24,12 @@ class DirtBlockType : public BlockType
     REGISTRABLE( DirtBlockType )
 
 protected:
-    virtual void loadSuperBlock( Block *zBlock, Framework::StreamReader *zReader ) override;
-    virtual void saveSuperBlock( Block *zBlock, Framework::StreamWriter *zWriter ) override;
-    virtual void createSuperBlock( Block *zBlock, Item *zItem ) override;
-    virtual void createSuperItem( Block *zBlock, Item *zItem ) override;
-    virtual Block *createBlock( Framework::Vec3<int> position, Game *zTarget ) override;
-    virtual Item *createItem( Game *zTarget ) override;
+    virtual void loadSuperBlock( Block* zBlock, Framework::StreamReader* zReader ) override;
+    virtual void saveSuperBlock( Block* zBlock, Framework::StreamWriter* zWriter ) override;
+    virtual void createSuperBlock( Block* zBlock, Item* zItem ) override;
+    virtual void createSuperItem( Block* zBlock, Item* zItem ) override;
+    virtual Block* createBlock( Framework::Vec3<int> position, Game* zTarget ) override;
+    virtual Item* createItem( Game* zTarget ) override;
     DirtBlockType();
 };
 REGISTER( DirtBlockType, BlockType )
@@ -42,6 +42,6 @@ protected:
     DirtBlockItemType();
 
 public:
-    virtual Item *createItem() const override;
+    virtual Item* createItem() const override;
 };
 REGISTER( DirtBlockItemType, ItemType )

+ 9 - 6
FactoryCraft/BasicInterpolator.cpp

@@ -1,22 +1,25 @@
 #include "BasicInterpolator.h"
 #include "Block.h"
 
-Block *BasicInterpolator::interpolateBlocks( Block *a, Block *b, double aWeight, double bWeight, Noise *zNoise )
+Framework::Either<Block*, int> BasicInterpolator::interpolateBlocks( Framework::Either<Block*, int> a, Framework::Either<Block*, int> b, double aWeight, double bWeight, Noise* zNoise )
 {
     if( aWeight < bWeight )
         return interpolateBlocks( b, a, bWeight, aWeight, zNoise );
     double score = bWeight / aWeight;
     if( score < 0.8 )
     {
-        b->release();
+        if( b.isA() )
+            ((Block*)b)->release();
         return a;
     }
-    score = ( score - 0.8 ) * 5;
-    if( score < zNoise->getNoise( ( score + 60 ) * 5, 100, 50 ) )
+    score = (score - 0.8) * 5;
+    if( score < zNoise->getNoise( (score + 60) * 5, 100, 50 ) )
     {
-        b->release();
+        if( b.isA() )
+            ((Block*)b)->release();
         return a;
     }
-    a->release();
+    if( a.isA() )
+        ((Block*)a)->release();
     return b;
 }

+ 1 - 1
FactoryCraft/BasicInterpolator.h

@@ -5,5 +5,5 @@
 class BasicInterpolator : public BiomInterpolator
 {
 public:
-    Block *interpolateBlocks( Block *a, Block *b, double aWeight, double bWeight, Noise *zNoise ) override;
+    Framework::Either<Block*, int> interpolateBlocks( Framework::Either<Block*, int> a, Framework::Either<Block*, int> b, double aWeight, double bWeight, Noise* zNoise ) override;
 };

+ 2 - 1
FactoryCraft/BiomGenerator.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <ReferenceCounter.h>
+#include <Either.h> 
 
 class Block;
 class Noise;
@@ -18,7 +19,7 @@ protected:
 
 public:
     BiomGenerator();
-    virtual Block *getBlock( Noise *zNoise, int x, int y, int z, Game *zGame ) = 0;
+    virtual Framework::Either<Block*, int> getBlock( Noise* zNoise, int x, int y, int z, Game* zGame ) = 0;
     double getBiomXMultiplier();
     double getBiomYMultiplier();
     double getBiomOutputMultiplier();

+ 2 - 1
FactoryCraft/BiomInterpolator.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <ReferenceCounter.h>
+#include <Either.h>
 
 #include "Noise.h"
 
@@ -20,5 +21,5 @@ public:
     /// <param name="bWeight">the weight for block b</param>
     /// <param name="zNoise">the noise to use</param>
     /// <returns>either a or b</returns>
-    virtual Block *interpolateBlocks( Block *a, Block *b, double aWeight, double bWeight, Noise *zNoise ) = 0;
+    virtual Framework::Either<Block*, int> interpolateBlocks( Framework::Either<Block*, int> a, Framework::Either<Block*, int> b, double aWeight, double bWeight, Noise* zNoise ) = 0;
 };

+ 41 - 31
FactoryCraft/Block.cpp

@@ -1,7 +1,7 @@
 #include "Block.h"
 #include "Inventory.h"
 
-Block::Block( const BlockType *zType, ItemType *zTool, Framework::Vec3<int> pos, bool hasInventory )
+Block::Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory )
     : Inventory( pos, hasInventory )
 {
     transparent = false;
@@ -20,13 +20,13 @@ Block::Block( const BlockType *zType, ItemType *zTool, Framework::Vec3<int> pos,
     tickSource = 0;
     currentTickTimeout = 0;
     dimansionId = 0;
-    memset( zNeighbours, 0, sizeof( Block * ) * 6 );
+    memset( zNeighbours, 0, sizeof( Block* ) * 6 );
 }
 
 Block::~Block()
 {}
 
-void Block::tick( TickQueue *zQueue )
+void Block::tick( TickQueue* zQueue )
 {
     if( wasTicked )
         return;
@@ -65,17 +65,24 @@ void Block::postTick()
     }
 }
 
-void Block::setNeighbour( Direction dir, Block *zN )
+void Block::setNeighbour( Direction dir, Block* zN )
 {
+    if( zN )
+        setNeighbourType( dir, zN->zBlockType()->getId() );
     zNeighbours[ getDirectionIndex( dir ) ] = zN;
 }
 
+void Block::setNeighbourType( Direction dir, int type )
+{
+    neighbourTypes[ getDirectionIndex( dir ) ] = type;
+}
+
 void Block::setDimensionId( int id )
 {
     dimansionId = id;
 }
 
-void api( Framework::StreamReader *zRequest, NetworkResponse *zResponse )
+void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
 {
     // TODO: answer api requests
 }
@@ -85,7 +92,7 @@ bool Block::isTickSource() const
     return tickSource;
 }
 
-const BlockType *Block::zBlockType() const
+const BlockType* Block::zBlockType() const
 {
     return zType;
 }
@@ -115,7 +122,7 @@ float Block::getHardness() const
     return hardness;
 }
 
-ItemType *Block::zEffectiveTool() const
+ItemType* Block::zEffectiveTool() const
 {
     return zTool;
 }
@@ -137,24 +144,27 @@ int Block::getDimensionId() const
 
 bool Block::isVisible() const
 {
+    if( passable || transparent )
+        return 1;
     for( int i = 0; i < 6; i++ )
     {
-        if( zNeighbours[ i ] == (Block*)AIR_BLOCK || (IS_BLOCK( zNeighbours[ i ] ) && zNeighbours[ i ]->isTransparent()))
+        const Block* neighbour = CONST_BLOCK( zNeighbours[ i ], neighbourTypes[ i ] );
+        if( neighbour->isPassable() || neighbour->isTransparent() )
             return 1;
     }
     return 0;
 }
 
 
-BasicBlockItem::BasicBlockItem( const ItemType *zType, const char *name )
+BasicBlockItem::BasicBlockItem( const ItemType* zType, const char* name )
     : Item( zType, name )
 {
     placeable = 1;
 }
 
-bool BasicBlockItem::canBeStackedWith( Item *zItem ) const
+bool BasicBlockItem::canBeStackedWith( Item* zItem ) const
 {
-    BasicBlockItem *item = dynamic_cast<BasicBlockItem *>( zItem );
+    BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
     if( item )
     {
         return Item::canBeStackedWith( zItem ) &&
@@ -170,41 +180,41 @@ bool BasicBlockItem::canBeStackedWith( Item *zItem ) const
 }
 
 
-BasicBlockItemType::BasicBlockItemType( int id, ItemSkillLevelUpRule *levelUpRule, const ItemType *zBrokenType )
+BasicBlockItemType::BasicBlockItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType )
     : ItemType( id, levelUpRule, zBrokenType )
 {}
 
-void BasicBlockItemType::loadSuperItem( Item *zItem, Framework::StreamReader *zReader ) const
+void BasicBlockItemType::loadSuperItem( Item* zItem, Framework::StreamReader* zReader ) const
 {
     ItemType::loadSuperItem( zItem, zReader );
-    BasicBlockItem *item = dynamic_cast<BasicBlockItem *>( zItem );
+    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->hp, 4 );
-    zReader->lese( (char *)&item->maxHP, 4 );
-    zReader->lese( (char *)&item->hardness, 4 );
-    zReader->lese( (char *)&item->toolId, 4 );
-    zReader->lese( (char *)&item->speedModifier, 4 );
+    zReader->lese( (char*)&item->transparent, 1 );
+    zReader->lese( (char*)&item->passable, 1 );
+    zReader->lese( (char*)&item->hp, 4 );
+    zReader->lese( (char*)&item->maxHP, 4 );
+    zReader->lese( (char*)&item->hardness, 4 );
+    zReader->lese( (char*)&item->toolId, 4 );
+    zReader->lese( (char*)&item->speedModifier, 4 );
 }
 
-void BasicBlockItemType::saveSuperItem( const Item *zItem, Framework::StreamWriter *zWriter ) const
+void BasicBlockItemType::saveSuperItem( const Item* zItem, Framework::StreamWriter* zWriter ) const
 {
     ItemType::saveSuperItem( zItem, zWriter );
-    const BasicBlockItem *item = dynamic_cast<const BasicBlockItem *>( zItem );
+    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->hp, 4 );
-    zWriter->schreibe( (char *)&item->maxHP, 4 );
-    zWriter->schreibe( (char *)&item->hardness, 4 );
-    zWriter->schreibe( (char *)&item->toolId, 4 );
-    zWriter->schreibe( (char *)&item->speedModifier, 4 );
+    zWriter->schreibe( (char*)&item->transparent, 1 );
+    zWriter->schreibe( (char*)&item->passable, 1 );
+    zWriter->schreibe( (char*)&item->hp, 4 );
+    zWriter->schreibe( (char*)&item->maxHP, 4 );
+    zWriter->schreibe( (char*)&item->hardness, 4 );
+    zWriter->schreibe( (char*)&item->toolId, 4 );
+    zWriter->schreibe( (char*)&item->speedModifier, 4 );
 }
 
-void BasicBlockItemType::initializeItem( BasicBlockItem *zItem, bool transparent, bool passable, float hp, float maxHP, float hardness, int toolId, float speedModifier ) const
+void BasicBlockItemType::initializeItem( BasicBlockItem* zItem, bool transparent, bool passable, float hp, float maxHP, float hardness, int toolId, float speedModifier ) const
 {
     zItem->transparent = transparent;
     zItem->passable = passable;

+ 20 - 19
FactoryCraft/Block.h

@@ -9,15 +9,14 @@
 #include <Trie.h>
 #include <Vec3.h>
 
+#define CONST_BLOCK(maybeBlock, type) (maybeBlock ? maybeBlock : StaticRegistry<BlockType>::INSTANCE.zElement((int)type)->zDefault())
+
 class ItemType;
 class Chunk;
 class BasicBlockItemType;
 
 class TickQueue;
 
-#define AIR_BLOCK -1
-#define IS_BLOCK(b) (((__int64)b) > 0)
-
 class Block : public Inventory
 {
 private:
@@ -33,10 +32,11 @@ protected:
     float hp;
     float maxHP;
     float hardness;
-    const BlockType *zType;
-    ItemType *zTool;
+    const BlockType* zType;
+    ItemType* zTool;
     float speedModifier;
-    Block *zNeighbours[ 6 ];
+    Block* zNeighbours[ 6 ];
+    int neighbourTypes[ 6 ];
 
     int minTickTimeout;
     int maxTickTimeout;
@@ -49,7 +49,7 @@ protected:
     /// <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;
+    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
@@ -57,24 +57,25 @@ protected:
     virtual void onPostTick() = 0;
 
 public:
-    Block( const BlockType *zType, ItemType *zTool, Framework::Vec3<int> pos, bool hasInventory );
+    Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory );
     virtual ~Block();
 
-    void tick( TickQueue *zQueue );
+    void tick( TickQueue* zQueue );
     void postTick();
     void setDimensionId( int id );
-    virtual void setNeighbour( Direction dir, Block *zN );
+    virtual void setNeighbour( Direction dir, Block* zN );
+    virtual void setNeighbourType( Direction dir, int type );
 
-    void api( Framework::StreamReader *zRequest, NetworkResponse *zResponse );
+    void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse );
 
     bool isTickSource() const;
-    const BlockType *zBlockType() const;
+    const BlockType* zBlockType() const;
     bool isTransparent() const;
     bool isPassable() const;
     float getHP() const;
     float getMaxHP() const;
     float getHardness() const;
-    ItemType *zEffectiveTool() const;
+    ItemType* zEffectiveTool() const;
     float getSpeedModifier() const;
     const Framework::Vec3<int> getPos() const;
     int getDimensionId() const;
@@ -95,8 +96,8 @@ protected:
     float speedModifier;
 
 public:
-    BasicBlockItem( const ItemType *zType, const char *name );
-    virtual bool canBeStackedWith( Item *zItem ) const override;
+    BasicBlockItem( const ItemType* zType, const char* name );
+    virtual bool canBeStackedWith( Item* zItem ) const override;
 
     friend BasicBlockItemType;
     friend BlockType;
@@ -105,8 +106,8 @@ public:
 class BasicBlockItemType : public ItemType
 {
 protected:
-    BasicBlockItemType( int id, ItemSkillLevelUpRule *levelUpRule, const ItemType *zBrokenType );
-    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 hp, float maxHP, float hardness, int toolId, float speedModifier ) const;
+    BasicBlockItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType );
+    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 hp, float maxHP, float hardness, int toolId, float speedModifier ) const;
 };

+ 47 - 30
FactoryCraft/BlockType.cpp

@@ -7,41 +7,51 @@ using namespace Framework;
 
 BlockType::BlockType( int id )
     : ReferenceCounter(),
-    id( id )
+    id( id ),
+    defaultBlock( 0 )
 {
     StaticRegistry<BlockType>::INSTANCE.registerT( this, id );
 }
 
-void BlockType::loadSuperBlock( Block *zBlock, Framework::StreamReader *zReader )
+BlockType::~BlockType()
+{
+    if( defaultBlock )
+        defaultBlock->release();
+}
+
+void BlockType::loadSuperBlock( Block* zBlock, Framework::StreamReader* zReader )
 {
     zBlock->loadInventory( zReader );
-    zReader->lese( (char *)&zBlock->transparent, 1 );
-    zReader->lese( (char *)&zBlock->passable, 1 );
-    zReader->lese( (char *)&zBlock->hp, 4 );
-    zReader->lese( (char *)&zBlock->maxHP, 4 );
-    zReader->lese( (char *)&zBlock->hardness, 4 );
-    zReader->lese( (char *)&zBlock->speedModifier, 4 );
+    zReader->lese( (char*)&zBlock->transparent, 1 );
+    zReader->lese( (char*)&zBlock->passable, 1 );
+    zReader->lese( (char*)&zBlock->hp, 4 );
+    zReader->lese( (char*)&zBlock->maxHP, 4 );
+    zReader->lese( (char*)&zBlock->hardness, 4 );
+    zReader->lese( (char*)&zBlock->speedModifier, 4 );
     int effectiveToolId;
-    zReader->lese( (char *)&effectiveToolId, 4 );
-    zBlock->zTool = StaticRegistry<ItemType>::INSTANCE.zElement( effectiveToolId );
+    zReader->lese( (char*)&effectiveToolId, 4 );
+    if( effectiveToolId >= 0 )
+        zBlock->zTool = StaticRegistry<ItemType>::INSTANCE.zElement( effectiveToolId );
+    else
+        zBlock->zTool = 0;
 }
 
-void BlockType::saveSuperBlock( Block *zBlock, Framework::StreamWriter *zWriter )
+void BlockType::saveSuperBlock( Block* zBlock, Framework::StreamWriter* zWriter )
 {
     zBlock->saveInventory( zWriter );
-    zWriter->schreibe( (char *)&zBlock->transparent, 1 );
-    zWriter->schreibe( (char *)&zBlock->passable, 1 );
-    zWriter->schreibe( (char *)&zBlock->hp, 4 );
-    zWriter->schreibe( (char *)&zBlock->maxHP, 4 );
-    zWriter->schreibe( (char *)&zBlock->hardness, 4 );
-    zWriter->schreibe( (char *)&zBlock->speedModifier, 4 );
-    int effectiveToolId = zBlock->zTool->getId();
-    zWriter->schreibe( (char *)&effectiveToolId, 4 );
+    zWriter->schreibe( (char*)&zBlock->transparent, 1 );
+    zWriter->schreibe( (char*)&zBlock->passable, 1 );
+    zWriter->schreibe( (char*)&zBlock->hp, 4 );
+    zWriter->schreibe( (char*)&zBlock->maxHP, 4 );
+    zWriter->schreibe( (char*)&zBlock->hardness, 4 );
+    zWriter->schreibe( (char*)&zBlock->speedModifier, 4 );
+    int effectiveToolId = zBlock->zTool ? zBlock->zTool->getId() : -1;
+    zWriter->schreibe( (char*)&effectiveToolId, 4 );
 }
 
-void BlockType::createSuperBlock( Block *zBlock, Item *zItem )
+void BlockType::createSuperBlock( Block* zBlock, Item* zItem )
 {
-    BasicBlockItem *item = dynamic_cast<BasicBlockItem *>( zItem );
+    BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
     if( !item )
     {
         throw "BlockType::createSuperBlock was called with an item witch was not an instance of BasicBlockItem";
@@ -55,9 +65,9 @@ void BlockType::createSuperBlock( Block *zBlock, Item *zItem )
     zBlock->zTool = StaticRegistry<ItemType>::INSTANCE.zElement( item->toolId );
 }
 
-void BlockType::createSuperItem( Block *zBlock, Item *zItem )
+void BlockType::createSuperItem( Block* zBlock, Item* zItem )
 {
-    BasicBlockItem *item = dynamic_cast<BasicBlockItem *>( zItem );
+    BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
     if( !item )
     {
         throw "BlockType::createSuperItem was called with an item witch was not an instance of BasicBlockItem";
@@ -71,28 +81,28 @@ void BlockType::createSuperItem( Block *zBlock, Item *zItem )
     item->toolId = zBlock->zTool->getId();
 }
 
-Block *BlockType::loadBlock( Framework::Vec3<int> position, Game *zTarget, Framework::StreamReader *zReader )
+Block* BlockType::loadBlock( Framework::Vec3<int> position, Game* zTarget, Framework::StreamReader* zReader )
 {
-    Block *result = createBlock( position, zTarget );
+    Block* result = createBlock( position, zTarget );
     loadSuperBlock( result, zReader );
     return result;
 }
 
-void BlockType::saveBlock( Block *zBlock, Framework::StreamWriter *zWriter )
+void BlockType::saveBlock( Block* zBlock, Framework::StreamWriter* zWriter )
 {
     saveSuperBlock( zBlock, zWriter );
 }
 
-Item *BlockType::getItemFromBlock( Block *zBlock, Game *zTarget )
+Item* BlockType::getItemFromBlock( Block* zBlock, Game* zTarget )
 {
-    Item *result = createItem( zTarget );
+    Item* result = createItem( zTarget );
     createSuperItem( zBlock, result );
     return result;
 }
 
-Block *BlockType::createBlockAt( Framework::Vec3<int> position, Game *zTarget, Item *zUsedItem )
+Block* BlockType::createBlockAt( Framework::Vec3<int> position, Game* zTarget, Item* zUsedItem )
 {
-    Block *result = createBlock( position, zTarget );
+    Block* result = createBlock( position, zTarget );
     createSuperBlock( result, zUsedItem );
     return result;
 }
@@ -100,4 +110,11 @@ Block *BlockType::createBlockAt( Framework::Vec3<int> position, Game *zTarget, I
 int BlockType::getId() const
 {
     return id;
+}
+
+const Block* BlockType::zDefault()
+{
+    if( !defaultBlock )
+        defaultBlock = createBlock( { 0, 0, 0 }, 0 );
+    return defaultBlock;
 }

+ 13 - 11
FactoryCraft/BlockType.h

@@ -14,22 +14,24 @@ class BlockType : public virtual Framework::ReferenceCounter
 {
 private:
     const int id;
+    Block* defaultBlock;
 
 protected:
     BlockType( int id );
+    virtual ~BlockType();
 
-    virtual void loadSuperBlock( Block *zBlock, Framework::StreamReader *zReader );
-    virtual void saveSuperBlock( Block *zBlock, Framework::StreamWriter *zWriter );
-    virtual void createSuperBlock( Block *zBlock, Item *zItem );
-    virtual void createSuperItem( Block *zBlock, Item *zItem );
-    virtual Block *createBlock( Framework::Vec3<int> position, Game *zTarget ) = 0;
-    virtual Item *createItem( Game *zTarget ) = 0;
+    virtual void loadSuperBlock( Block* zBlock, Framework::StreamReader* zReader );
+    virtual void saveSuperBlock( Block* zBlock, Framework::StreamWriter* zWriter );
+    virtual void createSuperBlock( Block* zBlock, Item* zItem );
+    virtual void createSuperItem( Block* zBlock, Item* zItem );
+    virtual Block* createBlock( Framework::Vec3<int> position, Game* zTarget ) = 0;
+    virtual Item* createItem( Game* zTarget ) = 0;
 
 public:
-    virtual Block *loadBlock( Framework::Vec3<int> position, Game *zTarget, Framework::StreamReader *zReader );
-    virtual void saveBlock( Block *zBlock, Framework::StreamWriter *zWriter );
-    virtual Item *getItemFromBlock( Block *zBlock, Game *zTarget );
-    virtual Block *createBlockAt( Framework::Vec3<int> position, Game *zTarget, Item *zUsedItem );
-
+    virtual Block* loadBlock( Framework::Vec3<int> position, Game* zTarget, Framework::StreamReader* zReader );
+    virtual void saveBlock( Block* zBlock, Framework::StreamWriter* zWriter );
+    virtual Item* getItemFromBlock( Block* zBlock, Game* zTarget );
+    virtual Block* createBlockAt( Framework::Vec3<int> position, Game* zTarget, Item* zUsedItem );
+    virtual const Block* zDefault();
     int getId() const;
 };

+ 126 - 53
FactoryCraft/Chunk.cpp

@@ -1,24 +1,26 @@
 #include "Chunk.h"
 #include "Constants.h"
 #include "Game.h"
+#include "NoBlock.h"
 
 
-Chunk::Chunk( Framework::Punkt location, Game *zGame, int dimensionId )
+Chunk::Chunk( Framework::Punkt location, Game* zGame, int dimensionId )
     : ReferenceCounter(),
     zGame( zGame ),
     dimensionId( dimensionId ),
     location( location )
 {
     blocks = new Block * [ CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ];
-    Block *val = (Block *)AIR_BLOCK;
-    std::uninitialized_fill_n( blocks, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT, val );
+    blockIds = new unsigned short[ CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ];
+    memset( blocks, 0, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof( Block* ) );
+    memset( blockIds, 0, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof( unsigned short ) );
     zNeighbours[ 0 ] = 0;
     zNeighbours[ 1 ] = 0;
     zNeighbours[ 2 ] = 0;
     zNeighbours[ 3 ] = 0;
 }
 
-Chunk::Chunk( Framework::Punkt location, Game *zGame, int dimensionId, Framework::StreamReader *zReader )
+Chunk::Chunk( Framework::Punkt location, Game* zGame, int dimensionId, Framework::StreamReader* zReader )
     : Chunk( location, zGame, dimensionId )
 {
     load( zReader );
@@ -28,82 +30,145 @@ Chunk::~Chunk()
 {
     for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
     {
-        if( IS_BLOCK( blocks[ i ] ) )
+        if( blocks[ i ] )
             blocks[ i ]->release();
     }
     delete[] blocks;
+    delete[] blockIds;
 }
 
-Block *Chunk::zBlockNeighbor( Framework::Vec3<int> location )
+Framework::Either<Block*, int> Chunk::zBlockNeighbor( Framework::Vec3<int> location )
 {
     if( location.x >= 0 && location.x < CHUNK_SIZE && location.y >= 0 && location.y < CHUNK_SIZE && location.z >= 0 && location.z < WORLD_HEIGHT )
-        return blocks[ (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z ];
+    {
+        int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+        if( blocks[ index ] )
+            return blocks[ index ];
+        else
+            return (int)blockIds[ index ];
+    }
     if( location.z >= 0 && location.z < WORLD_HEIGHT )
         return zGame->zBlockAt( { location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z }, dimensionId );
     return 0;
 }
 
-void Chunk::api( Framework::StreamReader *zRequest, NetworkResponse *zResponse )
+void Chunk::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
 {
     // TODO: answer api messages
 }
 
-Block *Chunk::getBlockAt( Framework::Vec3<int> location ) const
+Framework::Either<Block*, int> Chunk::zBlockAt( Framework::Vec3<int> location ) const
 {
-    assert( (location.x * CHUNK_SIZE + location.y) * CHUNK_SIZE + location.z < CHUNK_SIZE *CHUNK_SIZE *WORLD_HEIGHT );
-    Block *result = zBlockAt( location );
-    if( result )
-        return dynamic_cast<Block *>(result->getThis());
+    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+    assert( index < CHUNK_SIZE* CHUNK_SIZE* WORLD_HEIGHT );
+    if( blocks[ index ] )
+        return blocks[ index ];
+    else
+        return (int)blockIds[ index ];
+}
+
+const Block* Chunk::zBlockConst( Framework::Vec3<int> location ) const
+{
+    Block* b = zBlockAt( location );
+    if( b )
+        return b;
+    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+    if( blockIds[ index ] )
+        return StaticRegistry<BlockType>::INSTANCE.zElement( blockIds[ index ] )->zDefault();
     return 0;
 }
 
-Block *Chunk::zBlockAt( Framework::Vec3<int> location ) const
+void Chunk::instantiateBlock( Framework::Vec3<int> location )
 {
-    assert( (location.x * CHUNK_SIZE + location.y) * CHUNK_SIZE + location.z < CHUNK_SIZE *CHUNK_SIZE *WORLD_HEIGHT );
-    return blocks[ (location.x * CHUNK_SIZE + location.y) * CHUNK_SIZE + location.z ];
+    if( zBlockAt( location ) )
+        return;
+    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+    if( !blockIds[ index ] )
+        generateBlock( location );
+    if( !zBlockAt( location ) )
+        putBlockAt( location, StaticRegistry<BlockType>::INSTANCE.zElement( blockIds[ index ] )->createBlockAt( location, zGame, 0 ) );
+}
+
+void Chunk::generateBlock( Framework::Vec3<int> location )
+{
+    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+    if( blockIds[ index ] )
+        return;
+    auto generated = zGame->zGenerator()->generateSingleBlock( location, dimensionId );
+    if( generated.isA() )
+        putBlockAt( location, generated );
+    else
+        putBlockTypeAt( location, generated );
 }
 
-void Chunk::putBlockAt( Framework::Vec3<int> location, Block *block )
+void Chunk::putBlockAt( Framework::Vec3<int> location, Block* block )
 {
     int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
-    assert( index < CHUNK_SIZE *CHUNK_SIZE *WORLD_HEIGHT );
-    Block *old = blocks[ index ];
+    assert( index < CHUNK_SIZE* CHUNK_SIZE* WORLD_HEIGHT );
+    Block* old = blocks[ index ];
+    if( block )
+        blockIds[ index ] = (unsigned short)block->zBlockType()->getId();
     blocks[ index ] = block;
-    Block *neighbor = zBlockNeighbor( location + getDirection( NORTH ) );
-    if( IS_BLOCK( neighbor ) )
+    Block* neighbor = zBlockNeighbor( location + getDirection( NORTH ) );
+    if( neighbor )
         neighbor->setNeighbour( SOUTH, block );
-    if( IS_BLOCK( block ) )
+    if( block )
         block->setNeighbour( NORTH, neighbor );
     neighbor = zBlockNeighbor( location + getDirection( EAST ) );
-    if( IS_BLOCK( neighbor ) )
+    if( neighbor )
         neighbor->setNeighbour( WEST, block );
-    if( IS_BLOCK( block ) )
+    if( block )
         block->setNeighbour( EAST, neighbor );
     neighbor = zBlockNeighbor( location + getDirection( SOUTH ) );
-    if( IS_BLOCK( neighbor ) )
+    if( neighbor )
         neighbor->setNeighbour( NORTH, block );
-    if( IS_BLOCK( block ) )
+    if( block )
         block->setNeighbour( SOUTH, neighbor );
     neighbor = zBlockNeighbor( location + getDirection( WEST ) );
-    if( IS_BLOCK( neighbor ) )
+    if( neighbor )
         neighbor->setNeighbour( EAST, block );
-    if( IS_BLOCK( block ) )
+    if( block )
         block->setNeighbour( WEST, neighbor );
     neighbor = zBlockNeighbor( location + getDirection( TOP ) );
-    if( IS_BLOCK( neighbor ) )
+    if( neighbor )
         neighbor->setNeighbour( BOTTOM, block );
-    if( IS_BLOCK( block ) )
+    if( block )
         block->setNeighbour( TOP, neighbor );
     neighbor = zBlockNeighbor( location + getDirection( BOTTOM ) );
-    if( IS_BLOCK( neighbor ) )
+    if( neighbor )
         neighbor->setNeighbour( TOP, block );
-    if( IS_BLOCK( block ) )
+    if( block )
         block->setNeighbour( BOTTOM, neighbor );
-    if( IS_BLOCK( old ) )
+    if( old )
         old->release();
 }
 
-void Chunk::setNeighbor( Direction dir, Chunk *zChunk )
+void Chunk::putBlockTypeAt( Framework::Vec3<int> location, int type )
+{
+    int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+    assert( index < CHUNK_SIZE* CHUNK_SIZE* WORLD_HEIGHT );
+    blockIds[ index ] = (unsigned short)type;
+    Block* neighbor = zBlockNeighbor( location + getDirection( NORTH ) );
+    if( neighbor )
+        neighbor->setNeighbourType( SOUTH, type );
+    neighbor = zBlockNeighbor( location + getDirection( EAST ) );
+    if( neighbor )
+        neighbor->setNeighbourType( WEST, type );
+    neighbor = zBlockNeighbor( location + getDirection( SOUTH ) );
+    if( neighbor )
+        neighbor->setNeighbourType( NORTH, type );
+    neighbor = zBlockNeighbor( location + getDirection( WEST ) );
+    if( neighbor )
+        neighbor->setNeighbourType( EAST, type );
+    neighbor = zBlockNeighbor( location + getDirection( TOP ) );
+    if( neighbor )
+        neighbor->setNeighbourType( BOTTOM, type );
+    neighbor = zBlockNeighbor( location + getDirection( BOTTOM ) );
+    if( neighbor )
+        neighbor->setNeighbourType( TOP, type );
+}
+
+void Chunk::setNeighbor( Direction dir, Chunk* zChunk )
 {
     zNeighbours[ getDirectionIndex( dir ) ] = zChunk;
     for( int i = 0; i < CHUNK_SIZE; i++ )
@@ -113,53 +178,61 @@ void Chunk::setNeighbor( Direction dir, Chunk *zChunk )
             if( dir == NORTH )
             {
                 int index = i * CHUNK_SIZE * WORLD_HEIGHT + z;
-                if( IS_BLOCK( blocks[ index ] ) )
-                    blocks[ index ]->setNeighbour( NORTH, zChunk->blocks[ (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z ] );
+                if( blocks[ index ] )
+                {
+                    int j = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
+                    if( zChunk->blocks[ j ] )
+                        blocks[ index ]->setNeighbour( NORTH, zChunk->blocks[ j ] );
+                    else
+                        blocks[ index ]->setNeighbourType( NORTH, zChunk->blockIds[ j ] );
+                }
             }
             else if( dir == EAST )
             {
                 int index = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
-                if( IS_BLOCK( blocks[ index ] ) )
+                if( blocks[ index ] )
                     blocks[ index ]->setNeighbour( EAST, zChunk->blocks[ i * WORLD_HEIGHT + z ] );
             }
             else if( dir == SOUTH )
             {
                 int index = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
-                if( IS_BLOCK( blocks[ index ] ) )
+                if( blocks[ index ] )
                     blocks[ index ]->setNeighbour( SOUTH, zChunk->blocks[ i * CHUNK_SIZE * WORLD_HEIGHT + z ] );
             }
             else if( dir == WEST )
             {
                 int index = i * WORLD_HEIGHT + z;
-                if( IS_BLOCK( blocks[ index ] ) )
+                if( blocks[ index ] )
                     blocks[ index ]->setNeighbour( WEST, zChunk->blocks[ ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z ] );
             }
         }
     }
 }
 
-void Chunk::load( Framework::StreamReader *zReader )
+void Chunk::load( Framework::StreamReader* zReader )
 {
+    zReader->lese( (char*)blockIds, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof( unsigned short ) );
     for( int x = 0; x < CHUNK_SIZE; x++ )
     {
         for( int y = 0; y < CHUNK_SIZE; y++ )
         {
             for( int z = 0; z < WORLD_HEIGHT; z++ )
             {
-                int blockType;
-                zReader->lese( (char *)&blockType, 4 );
-                if( blockType >= 0 )
-                {
-                    Block *block = StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->loadBlock( Framework::Vec3<int>( x, y, z ), zGame, zReader );
+                unsigned short blockType;
+                zReader->lese( (char*)&blockType, 2 );
+                Block* block = StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->loadBlock( Framework::Vec3<int>( x, y, z ), zGame, zReader );
+                if( block )
                     putBlockAt( { x, y, z }, block );
-                }
+                else
+                    putBlockTypeAt( { x, y, z }, blockIds[ (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z ] );
             }
         }
     }
 }
 
-void Chunk::save( Framework::StreamWriter *zWriter )
+void Chunk::save( Framework::StreamWriter* zWriter )
 {
+    zWriter->schreibe( (char*)blockIds, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof( unsigned short ) );
     for( int x = 0; x < CHUNK_SIZE; x++ )
     {
         for( int y = 0; y < CHUNK_SIZE; y++ )
@@ -167,10 +240,9 @@ void Chunk::save( Framework::StreamWriter *zWriter )
             for( int z = 0; z < WORLD_HEIGHT; z++ )
             {
                 int index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
-                int blockType = IS_BLOCK( blocks[ index ] ) ? blocks[ index ]->zBlockType()->getId() : -1;
-                zWriter->schreibe( (char *)&blockType, 4 );
-                if( blockType >= 0 )
-                    StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->saveBlock( blocks[ index ], zWriter );
+                unsigned short blockType = blocks[ index ] ? (unsigned short)blocks[ index ]->zBlockType()->getId() : (unsigned short)NoBlockBlockType::ID;
+                zWriter->schreibe( (char*)&blockType, 2 );
+                StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->saveBlock( blocks[ index ], zWriter );
             }
         }
     }
@@ -184,12 +256,13 @@ void Chunk::removeUnusedBlocks()
         removed = false;
         for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
         {
-            if( IS_BLOCK( blocks[ i ] ) && !blocks[ i ]->isVisible() )
+            if( blocks[ i ] && !blocks[ i ]->isVisible() )
             {
                 int x = (i / WORLD_HEIGHT) / CHUNK_SIZE;
                 int y = (i / WORLD_HEIGHT) % CHUNK_SIZE;
                 int z = i % WORLD_HEIGHT;
                 putBlockAt( { x,y,z }, 0 );
+                putBlockTypeAt( { x, y, z }, NoBlockBlockType::ID );
                 removed = true;
             }
         }
@@ -216,7 +289,7 @@ Framework::Vec3<int> Chunk::getMax() const
     return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
 }
 
-Game *Chunk::zGameObj() const
+Game* Chunk::zGameObj() const
 {
     return zGame;
 }

+ 19 - 14
FactoryCraft/Chunk.h

@@ -6,36 +6,41 @@
 #include <Array.h>
 #include <Datei.h>
 #include <Punkt.h>
+#include <Either.h>
 
 class Game;
 
 class Chunk : public virtual Framework::ReferenceCounter
 {
 private:
-    Game *zGame;
+    Game* zGame;
     int dimensionId;
     Framework::Punkt location;
-    Block **blocks;
-    Chunk *zNeighbours[ 4 ];
-    Block *zBlockNeighbor( Framework::Vec3<int> location );
+    Block** blocks;
+    Chunk* zNeighbours[ 4 ];
+    unsigned short* blockIds;
+    Framework::Either<Block*, int> zBlockNeighbor( Framework::Vec3<int> location );
 
 public:
-    Chunk( Framework::Punkt location, Game *zGame, int dimensionId );
-    Chunk( Framework::Punkt location, Game *zGame, int dimensionId, Framework::StreamReader *zReader );
+    Chunk( Framework::Punkt location, Game* zGame, int dimensionId );
+    Chunk( Framework::Punkt location, Game* zGame, int dimensionId, Framework::StreamReader* zReader );
     ~Chunk();
 
-    void api( Framework::StreamReader *zRequest, NetworkResponse *zResponse );
+    void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse );
 
-    Block *getBlockAt( Framework::Vec3<int> cLocation ) const;
-    Block *zBlockAt( Framework::Vec3<int> cLocation ) const;
-    void putBlockAt( Framework::Vec3<int> location, Block *block );
-    void setNeighbor( Direction dir, Chunk *zChunk );
-    void load( Framework::StreamReader *zReader );
-    void save( Framework::StreamWriter *zWriter );
+    Framework::Either<Block*, int> zBlockAt( Framework::Vec3<int> cLocation ) const;
+    const Block* zBlockConst( Framework::Vec3<int> location ) const;
+    void instantiateBlock( Framework::Vec3<int> location );
+    void generateBlock( Framework::Vec3<int> location );
+    void putBlockAt( Framework::Vec3<int> location, Block* block );
+    void putBlockTypeAt( Framework::Vec3<int> location, int type );
+    void setNeighbor( Direction dir, Chunk* zChunk );
+    void load( Framework::StreamReader* zReader );
+    void save( Framework::StreamWriter* zWriter );
     void removeUnusedBlocks();
     int getDimensionId() const;
     Framework::Punkt getCenter() const;
     Framework::Vec3<int> getMin() const;
     Framework::Vec3<int> getMax() const;
-    Game *zGameObj() const;
+    Game* zGameObj() const;
 };

+ 2 - 1
FactoryCraft/Constants.h

@@ -8,4 +8,5 @@
 #define MIN_AIR_LEVEL 100
 #define MAX_AIR_LEVEL 400
 #define NUM_TICK_WORKERS 4
-#define ITEM_CACHE_SIZE 256
+#define ITEM_CACHE_SIZE 256
+#define DEFAULT_VIEW_DISTANCE 5

+ 20 - 19
FactoryCraft/Dimension.cpp

@@ -18,34 +18,35 @@ Dimension::~Dimension()
     chunks->release();
 }
 
-void Dimension::api( Framework::StreamReader *zRequest, NetworkResponse *zResponse )
+void Dimension::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
 {
     // TODO: switch type chunck, block, entity
 }
 
-void Dimension::tickEntities( Game *zGame )
+void Dimension::tickEntities( Game* zGame )
 {
     int index = 0;
     Array<int> removed;
-    for( auto entity = entities->getIterator(); entity; entity++, index++ )
+    for( auto entity : *entities )
     {
         if( zChunk( Punkt( (int)entity->getPosition().x, (int)entity->getPosition().y ) ) )
             entity->tick( this, zGame );
         if( entity->isRemoved() )
             removed.add( index, 0 );
+        index++;
     }
-    for( auto i = removed.getIterator(); i; i++ )
+    for( int i : removed )
         entities->remove( i );
 }
 
-void Dimension::getAddrOf( Punkt cPos, char *addr ) const
+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;
     addr[ 8 ] = 0;
 }
 
-void Dimension::getAddrOfWorld( Punkt wPos, char *addr ) const
+void Dimension::getAddrOfWorld( Punkt wPos, char* addr ) const
 {
     if( wPos.x < 0 )
         wPos.x -= CHUNK_SIZE;
@@ -55,16 +56,16 @@ void Dimension::getAddrOfWorld( Punkt wPos, char *addr ) const
     getAddrOf( wPos, addr );
 }
 
-Chunk *Dimension::zChunk( Punkt wPos ) const
+Chunk* Dimension::zChunk( Punkt wPos ) const
 {
     char addr[ 9 ];
     getAddrOfWorld( wPos, addr );
     return chunks->z( addr, 9 );
 }
 
-Block *Dimension::zBlock( Vec3<int> location, const Game *zGame )
+Framework::Either<Block*, int> Dimension::zBlock( Vec3<int> location, const Game* zGame )
 {
-    Chunk *c = zChunk( zGame->getChunkCenter( location.x, location.y ) );
+    Chunk* c = zChunk( zGame->getChunkCenter( location.x, location.y ) );
     if( c )
     {
         int x = location.x % CHUNK_SIZE;
@@ -78,12 +79,12 @@ Block *Dimension::zBlock( Vec3<int> location, const Game *zGame )
     return 0;
 }
 
-void Dimension::addEntity( Entity *entity )
+void Dimension::addEntity( Entity* entity )
 {
     entities->add( entity );
 }
 
-void Dimension::addChunk( Chunk *chunk )
+void Dimension::addChunk( Chunk* chunk )
 {
     char addr[ 9 ];
     getAddrOfWorld( chunk->getCenter(), addr );
@@ -91,7 +92,7 @@ void Dimension::addChunk( Chunk *chunk )
     {
         chunks->set( addr, 9, chunk );
         getAddrOfWorld( chunk->getCenter() + Punkt( CHUNK_SIZE, 0 ), addr );
-        Chunk *zChunk = chunks->z( addr, 9 );
+        Chunk* zChunk = chunks->z( addr, 9 );
         if( zChunk )
         {
             zChunk->setNeighbor( WEST, chunk );
@@ -129,7 +130,7 @@ void Dimension::save( Text worldDir ) const
     {
         if( !chunk._ )
             continue;
-        Datei *file = new Datei();
+        Datei* file = new Datei();
         Text filePath = worldDir + "/dim/" + dimensionId + "/";
         filePath.appendHex( chunk->getCenter().x );
         filePath += "_";
@@ -142,25 +143,25 @@ void Dimension::save( Text worldDir ) const
         file->release();
     }
     Text filePath = worldDir + "/dim/" + dimensionId + "/entities";
-    Datei *file = new Datei();
+    Datei* file = new Datei();
     file->setDatei( filePath );
     if( file->open( Datei::Style::schreiben ) )
     {
-        for( auto entity = entities->getIterator(); entity; entity++ )
+        for( Entity* entity : *entities )
         {
             if( entity->zType()->getId() != PlayerEntityType::ID )
             {
                 if( !entity->isRemoved() )
                 {
                     int type = entity->zType()->getId();
-                    file->schreibe( (char *)&type, 4 );
+                    file->schreibe( (char*)&type, 4 );
                     StaticRegistry<EntityType>::INSTANCE.zElement( type )->saveEntity( entity, file );
                 }
             }
             else
             {
                 Datei pFile;
-                pFile.setDatei( worldDir + "/player/" + ( (Player *)entity.val() )->getName() );
+                pFile.setDatei( worldDir + "/player/" + ((Player*)entity)->getName() );
                 if( pFile.open( Datei::Style::schreiben ) )
                     PlayerEntityType::INSTANCE->saveEntity( entity, &pFile );
             }

+ 10 - 10
FactoryCraft/Dimension.h

@@ -10,23 +10,23 @@ class Dimension : public virtual Framework::ReferenceCounter
 {
 private:
     int dimensionId;
-    Framework::Trie<Chunk> *chunks;
-    Framework::RCArray<Entity> *entities;
-    void getAddrOf( Framework::Punkt cPos, char *addr ) const;
-    void getAddrOfWorld( Framework::Punkt wPos, char *addr ) const;
+    Framework::Trie<Chunk>* chunks;
+    Framework::RCArray<Entity>* entities;
+    void getAddrOf( Framework::Punkt cPos, char* addr ) const;
+    void getAddrOfWorld( Framework::Punkt wPos, char* addr ) const;
 
 public:
     Dimension( int id );
     ~Dimension();
 
-    void api( Framework::StreamReader *zRequest, NetworkResponse *zResponse );
-    void tickEntities( Game *zGame );
+    void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse );
+    void tickEntities( Game* zGame );
 
-    Block *zBlock( Framework::Vec3<int> location, const Game *zGame );
-    void addEntity( Entity *entity );
-    void addChunk( Chunk *chunk );
+    Framework::Either<Block*, int> zBlock( Framework::Vec3<int> location, const Game* zGame );
+    void addEntity( Entity* entity );
+    void addChunk( Chunk* chunk );
     void save( Framework::Text worldDir ) const;
     int getDimensionId() const;
     bool hasChunck( int x, int y ) const;
-    Chunk *zChunk( Framework::Punkt wPos ) const;
+    Chunk* zChunk( Framework::Punkt wPos ) const;
 };

+ 36 - 25
FactoryCraft/DimensionGenerator.cpp

@@ -1,9 +1,10 @@
 #include "DimensionGenerator.h"
 #include "Constants.h"
 #include "Noise.h"
+#include "NoBlock.h"
 
 
-DimensionGenerator::DimensionGenerator( BiomInterpolator *interpolator, int dimensionId )
+DimensionGenerator::DimensionGenerator( BiomInterpolator* interpolator, int dimensionId )
     : ReferenceCounter(),
     interpolator( interpolator ),
     dimensionId( dimensionId )
@@ -16,68 +17,78 @@ DimensionGenerator::~DimensionGenerator()
     interpolator->release();
 }
 
-void DimensionGenerator::findBiom( int x, int y, Noise *zNoise, BiomGenerator **firstChoice, BiomGenerator **secondChoice, double &firstChoiceWeight, double &secondChoiceWeight )
+void DimensionGenerator::findBiom( int x, int y, Noise* zNoise, BiomGenerator** firstChoice, BiomGenerator** secondChoice, double& firstChoiceWeight, double& secondChoiceWeight )
 {
     *firstChoice = biomGenerators.z( 0 );
     *secondChoice = biomGenerators.z( 0 );
     firstChoiceWeight = 0;
     secondChoiceWeight = 0;
     int z = BIOM_GENERATION_Z_OFFSET;
-    for( Framework::Iterator<BiomGenerator *> it = biomGenerators.getIterator(); it; it++ )
+    for( BiomGenerator* gen : biomGenerators )
     {
-        double noise = zNoise->getNoise( x * it->getBiomXMultiplier(), y * it->getBiomYMultiplier(), z ) * it->getBiomOutputMultiplier();
+        double noise = zNoise->getNoise( x * gen->getBiomXMultiplier(), y * gen->getBiomYMultiplier(), z ) * gen->getBiomOutputMultiplier();
         if( noise > firstChoiceWeight )
         {
             secondChoiceWeight = firstChoiceWeight;
             *secondChoice = *firstChoice;
             firstChoiceWeight = noise;
-            *firstChoice = it;
+            *firstChoice = gen;
         }
         else if( noise > secondChoiceWeight )
         {
             secondChoiceWeight = noise;
-            *secondChoice = it;
+            *secondChoice = gen;
         }
         z++;
     }
 }
 
-void DimensionGenerator::registerBiom( BiomGenerator *generator )
+void DimensionGenerator::registerBiom( BiomGenerator* generator )
 {
     biomGenerators.add( generator );
 }
 
-Chunk *DimensionGenerator::generateChunk( Noise *zNoise, Game *zGame, int centerX, int centerY )
+Chunk* DimensionGenerator::generateChunk( Noise* zNoise, Game* zGame, int centerX, int centerY )
 {
-    BiomGenerator *actualBiom;
-    BiomGenerator *neighborBiom;
-    double actualWeight;
-    double neighborWeight;
-    Chunk *chunk = new Chunk( Framework::Punkt( centerX, centerY ), zGame, dimensionId );
+    Chunk* chunk = new Chunk( Framework::Punkt( centerX, centerY ), zGame, dimensionId );
     for( int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++ )
     {
         for( int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++ )
         {
-            findBiom( x + centerX, y + centerY, zNoise, &actualBiom, &neighborBiom, actualWeight, neighborWeight );
-            double actualHeight = zNoise->getNoise( ( x + centerX ) * actualBiom->getAirLevelXMultiplier(), ( y + centerY ) * actualBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * actualBiom->getAirLevelOutputMultiplier();
-            double neighborHeight = zNoise->getNoise( ( x + centerX ) * neighborBiom->getAirLevelXMultiplier(), ( y + centerY ) * neighborBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * neighborBiom->getAirLevelOutputMultiplier();
-            int height = MIN_AIR_LEVEL;
-            if( actualWeight + neighborWeight > 0 )
-                height += (int)( ( ( actualHeight * actualHeight + neighborHeight * neighborWeight ) / ( actualWeight + neighborWeight ) ) * ( MAX_AIR_LEVEL - MIN_AIR_LEVEL ) );
             for( int z = 0; z < WORLD_HEIGHT; z++ )
             {
-                if( z < height )
-                {
-                    Block *actualBlock = actualBiom->getBlock( zNoise, x + centerX, y + centerY, z, zGame );
-                    Block *neighborBlock = neighborBiom->getBlock( zNoise, x + centerX, y + centerY, z, zGame );
-                    chunk->putBlockAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), interpolator->interpolateBlocks( actualBlock, neighborBlock, actualHeight, neighborWeight, zNoise ) );
-                }
+                auto generated = generateBlock( zNoise, zGame, { x + centerX, y + centerY, z } );
+                if( generated.isA() )
+                    chunk->putBlockAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), generated );
+                else
+                    chunk->putBlockTypeAt( Framework::Vec3<int>( x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z ), generated );
             }
         }
     }
     return chunk;
 }
 
+Framework::Either<Block*, int> DimensionGenerator::generateBlock( Noise* zNoise, Game* zGame, Framework::Vec3<int> location )
+{
+    BiomGenerator* actualBiom;
+    BiomGenerator* neighborBiom;
+    double actualWeight;
+    double neighborWeight;
+    findBiom( location.x, location.y, zNoise, &actualBiom, &neighborBiom, actualWeight, neighborWeight );
+    double actualHeight = zNoise->getNoise( location.x * actualBiom->getAirLevelXMultiplier(), location.y * actualBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * actualBiom->getAirLevelOutputMultiplier();
+    double neighborHeight = zNoise->getNoise( location.x * neighborBiom->getAirLevelXMultiplier(), location.y * neighborBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * neighborBiom->getAirLevelOutputMultiplier();
+    int height = MIN_AIR_LEVEL;
+    if( actualWeight + neighborWeight > 0 )
+        height += (int)(((actualHeight * actualHeight + neighborHeight * neighborWeight) / (actualWeight + neighborWeight)) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
+    if( location.z < height )
+    {
+        auto actualBlock = actualBiom->getBlock( zNoise, location.x, location.y, location.z, zGame );
+        auto neighborBlock = neighborBiom->getBlock( zNoise, location.x, location.y, location.z, zGame );
+        return interpolator->interpolateBlocks( actualBlock, neighborBlock, actualHeight, neighborWeight, zNoise );
+    }
+    return AirBlockBlockType::ID;
+}
+
 int DimensionGenerator::getDimensionId() const
 {
     return dimensionId;

+ 7 - 5
FactoryCraft/DimensionGenerator.h

@@ -2,6 +2,7 @@
 
 #include <Array.h>
 #include <ReferenceCounter.h>
+#include <Either.h>
 
 #include "BiomGenerator.h"
 #include "BiomInterpolator.h"
@@ -10,18 +11,19 @@
 class DimensionGenerator : public virtual Framework::ReferenceCounter
 {
 private:
-    BiomInterpolator *interpolator;
+    BiomInterpolator* interpolator;
     Framework::RCArray<BiomGenerator> biomGenerators;
     const int dimensionId;
 
-    void findBiom( int x, int y, Noise *zNoise, BiomGenerator **firstChoice, BiomGenerator **secondChoice, double &firstChoiceWeight, double &secondChoiceWeight );
+    void findBiom( int x, int y, Noise* zNoise, BiomGenerator** firstChoice, BiomGenerator** secondChoice, double& firstChoiceWeight, double& secondChoiceWeight );
 
 protected:
-    DimensionGenerator( BiomInterpolator *interpolator, int dimensionId );
+    DimensionGenerator( BiomInterpolator* interpolator, int dimensionId );
     ~DimensionGenerator();
-    void registerBiom( BiomGenerator *generator );
+    void registerBiom( BiomGenerator* generator );
 
 public:
-    Chunk *generateChunk( Noise *zNoise, Game *zGame, int centerX, int centerY );
+    Chunk* generateChunk( Noise* zNoise, Game* zGame, int centerX, int centerY );
+    Framework::Either<Block*, int> generateBlock( Noise* zNoise, Game* zGame, Framework::Vec3<int> location );
     int getDimensionId() const;
 };

+ 1 - 1
FactoryCraft/Effect.h

@@ -11,7 +11,7 @@ private:
     Framework::Text name;
     float duration;
 
-    Effect( Entity *zTarget );
+    Effect( Entity* zTarget );
 
 public:
     ~Effect();

+ 1 - 1
FactoryCraft/EffectFactory.h

@@ -10,5 +10,5 @@ private:
 public:
     EffectFactory( Framework::Text effectName );
 
-    virtual Effect *createEffectOn( Entity *target ) = 0;
+    virtual Effect* createEffectOn( Entity* target ) = 0;
 };

+ 4 - 4
FactoryCraft/Entity.cpp

@@ -1,6 +1,6 @@
 #include "Entity.h"
 
-Entity::Entity( const EntityType *zType, Framework::Vec3<float> location, int dimensionId, int entityId )
+Entity::Entity( const EntityType* zType, Framework::Vec3<float> location, int dimensionId, int entityId )
     : Inventory( location, true ),
     speed( 0, 0, 0 ),
     faceDir( 1, 0 ),
@@ -13,12 +13,12 @@ Entity::Entity( const EntityType *zType, Framework::Vec3<float> location, int di
 void Entity::onDeath()
 {}
 
-void Entity::tick( const Dimension *zDimension, Game *zGame )
+void Entity::tick( const Dimension* zDimension, Game* zGame )
 {
     // TODO
 }
 
-void Entity::api( Framework::StreamReader *zRequest, NetworkResponse *zResponse )
+void Entity::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
 {
     // TODO: answer api requests
 }
@@ -93,7 +93,7 @@ bool Entity::isRemoved() const
     return removed;
 }
 
-const EntityType *Entity::zType() const
+const EntityType* Entity::zType() const
 {
     return zEntityType;
 }

+ 5 - 5
FactoryCraft/Entity.h

@@ -25,18 +25,18 @@ protected:
     float maxThirst;
     Framework::Vec3<float> speed;
     Framework::Vec2<float> faceDir;
-    const EntityType *zEntityType;
+    const EntityType* zEntityType;
     int currentDimensionId;
     bool removed;
     int id;
 
     virtual void onDeath();
-    Entity( const EntityType *zType, Framework::Vec3<float> location, int dimensionId, int entityId );
+    Entity( const EntityType* zType, Framework::Vec3<float> location, int dimensionId, int entityId );
 
 public:
-    virtual void tick( const Dimension *zDimension, Game *zGame );
+    virtual void tick( const Dimension* zDimension, Game* zGame );
 
-    virtual void api( Framework::StreamReader *zRequest, NetworkResponse *zResponse );
+    virtual void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse );
 
     void setPosition( Framework::Vec3<float> pos );
     float getMaxHP() const;
@@ -53,7 +53,7 @@ public:
     int getCurrentDimensionId() const;
     bool isRemoved() const;
 
-    const EntityType *zType() const;
+    const EntityType* zType() const;
     int getId() const;
 
     friend Effect;

+ 38 - 38
FactoryCraft/EntityType.cpp

@@ -9,64 +9,64 @@ EntityType::EntityType( int id )
     StaticRegistry<EntityType>::INSTANCE.registerT( this, id );
 }
 
-void EntityType::loadSuperEntity( Entity *zEntity, Framework::StreamReader *zReader ) const
+void EntityType::loadSuperEntity( Entity* zEntity, Framework::StreamReader* zReader ) const
 {
     zEntity->loadInventory( zReader );
-    zReader->lese( (char *)&zEntity->id, 4 );
-    zReader->lese( (char *)&zEntity->maxHP, 4 );
-    zReader->lese( (char *)&zEntity->currentHP, 4 );
-    zReader->lese( (char *)&zEntity->stamina, 4 );
-    zReader->lese( (char *)&zEntity->maxStamina, 4 );
-    zReader->lese( (char *)&zEntity->hunger, 4 );
-    zReader->lese( (char *)&zEntity->maxHunger, 4 );
-    zReader->lese( (char *)&zEntity->thirst, 4 );
-    zReader->lese( (char *)&zEntity->maxThirst, 4 );
-    zReader->lese( (char *)&zEntity->speed.x, 4 );
-    zReader->lese( (char *)&zEntity->speed.y, 4 );
-    zReader->lese( (char *)&zEntity->speed.z, 4 );
-    zReader->lese( (char *)&zEntity->faceDir.x, 4 );
-    zReader->lese( (char *)&zEntity->faceDir.y, 4 );
-    zReader->lese( (char *)&zEntity->currentDimensionId, 4 );
+    zReader->lese( (char*)&zEntity->id, 4 );
+    zReader->lese( (char*)&zEntity->maxHP, 4 );
+    zReader->lese( (char*)&zEntity->currentHP, 4 );
+    zReader->lese( (char*)&zEntity->stamina, 4 );
+    zReader->lese( (char*)&zEntity->maxStamina, 4 );
+    zReader->lese( (char*)&zEntity->hunger, 4 );
+    zReader->lese( (char*)&zEntity->maxHunger, 4 );
+    zReader->lese( (char*)&zEntity->thirst, 4 );
+    zReader->lese( (char*)&zEntity->maxThirst, 4 );
+    zReader->lese( (char*)&zEntity->speed.x, 4 );
+    zReader->lese( (char*)&zEntity->speed.y, 4 );
+    zReader->lese( (char*)&zEntity->speed.z, 4 );
+    zReader->lese( (char*)&zEntity->faceDir.x, 4 );
+    zReader->lese( (char*)&zEntity->faceDir.y, 4 );
+    zReader->lese( (char*)&zEntity->currentDimensionId, 4 );
 }
 
-void EntityType::saveSuperEntity( Entity *zEntity, Framework::StreamWriter *zWriter ) const
+void EntityType::saveSuperEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const
 {
     zEntity->saveInventory( zWriter );
-    zWriter->schreibe( (char *)&zEntity->id, 4 );
-    zWriter->schreibe( (char *)&zEntity->maxHP, 4 );
-    zWriter->schreibe( (char *)&zEntity->currentHP, 4 );
-    zWriter->schreibe( (char *)&zEntity->stamina, 4 );
-    zWriter->schreibe( (char *)&zEntity->maxStamina, 4 );
-    zWriter->schreibe( (char *)&zEntity->hunger, 4 );
-    zWriter->schreibe( (char *)&zEntity->maxHunger, 4 );
-    zWriter->schreibe( (char *)&zEntity->thirst, 4 );
-    zWriter->schreibe( (char *)&zEntity->maxThirst, 4 );
-    zWriter->schreibe( (char *)&zEntity->speed.x, 4 );
-    zWriter->schreibe( (char *)&zEntity->speed.y, 4 );
-    zWriter->schreibe( (char *)&zEntity->speed.z, 4 );
-    zWriter->schreibe( (char *)&zEntity->faceDir.x, 4 );
-    zWriter->schreibe( (char *)&zEntity->faceDir.y, 4 );
-    zWriter->schreibe( (char *)&zEntity->currentDimensionId, 4 );
+    zWriter->schreibe( (char*)&zEntity->id, 4 );
+    zWriter->schreibe( (char*)&zEntity->maxHP, 4 );
+    zWriter->schreibe( (char*)&zEntity->currentHP, 4 );
+    zWriter->schreibe( (char*)&zEntity->stamina, 4 );
+    zWriter->schreibe( (char*)&zEntity->maxStamina, 4 );
+    zWriter->schreibe( (char*)&zEntity->hunger, 4 );
+    zWriter->schreibe( (char*)&zEntity->maxHunger, 4 );
+    zWriter->schreibe( (char*)&zEntity->thirst, 4 );
+    zWriter->schreibe( (char*)&zEntity->maxThirst, 4 );
+    zWriter->schreibe( (char*)&zEntity->speed.x, 4 );
+    zWriter->schreibe( (char*)&zEntity->speed.y, 4 );
+    zWriter->schreibe( (char*)&zEntity->speed.z, 4 );
+    zWriter->schreibe( (char*)&zEntity->faceDir.x, 4 );
+    zWriter->schreibe( (char*)&zEntity->faceDir.y, 4 );
+    zWriter->schreibe( (char*)&zEntity->currentDimensionId, 4 );
 }
 
-void EntityType::createSuperEntity( Entity *zEntity ) const
+void EntityType::createSuperEntity( Entity* zEntity ) const
 {}
 
-Entity *EntityType::loadEntity( Game *zTarget, Framework::StreamReader *zReader ) const
+Entity* EntityType::loadEntity( Game* zTarget, Framework::StreamReader* zReader ) const
 {
-    Entity *entity = createEntity( Framework::Vec3<float>( 0, 0, 0 ), 0, zTarget, 0 );
+    Entity* entity = createEntity( Framework::Vec3<float>( 0, 0, 0 ), 0, zTarget, 0 );
     loadSuperEntity( entity, zReader );
     return entity;
 }
 
-void EntityType::saveEntity( Entity *zEntity, Framework::StreamWriter *zWriter ) const
+void EntityType::saveEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const
 {
     saveSuperEntity( zEntity, zWriter );
 }
 
-Entity *EntityType::createEntityAt( Framework::Vec3<float> position, int dimensionId, Game *zTarget ) const
+Entity* EntityType::createEntityAt( Framework::Vec3<float> position, int dimensionId, Game* zTarget ) const
 {
-    Entity *entity = createEntity( position, dimensionId, zTarget, zTarget->getNextEntityId() );
+    Entity* entity = createEntity( position, dimensionId, zTarget, zTarget->getNextEntityId() );
     createSuperEntity( entity );
     return entity;
 }

+ 7 - 7
FactoryCraft/EntityType.h

@@ -18,15 +18,15 @@ private:
 protected:
     EntityType( int id );
 
-    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, Game *zTarget, int entityId ) const = 0;
+    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, Game* zTarget, int entityId ) const = 0;
 
 public:
-    virtual Entity *loadEntity( Game *zTarget, Framework::StreamReader *zReader ) const;
-    virtual void saveEntity( Entity *zEntity, Framework::StreamWriter *zWriter ) const;
-    virtual Entity *createEntityAt( Framework::Vec3<float> position, int dimensionId, Game *zTarget ) const;
+    virtual Entity* loadEntity( Game* zTarget, Framework::StreamReader* zReader ) const;
+    virtual void saveEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const;
+    virtual Entity* createEntityAt( Framework::Vec3<float> position, int dimensionId, Game* zTarget ) const;
 
     int getId() const;
 };

+ 2 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -118,6 +118,7 @@
     <ClInclude Include="ItemType.h" />
     <ClInclude Include="NetworkResponse.h" />
     <ClInclude Include="Noise.h" />
+    <ClInclude Include="NoBlock.h" />
     <ClInclude Include="OverworldDimension.h" />
     <ClInclude Include="PerlinNoise.h" />
     <ClInclude Include="Player.h" />
@@ -154,6 +155,7 @@
     <ClCompile Include="ItemStack.cpp" />
     <ClCompile Include="ItemType.cpp" />
     <ClCompile Include="NetworkResponse.cpp" />
+    <ClCompile Include="NoBlock.cpp" />
     <ClCompile Include="Noise.cpp" />
     <ClCompile Include="OverworldDimension.cpp" />
     <ClCompile Include="PerlinNoise.cpp" />

+ 6 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -168,6 +168,9 @@
     <ClInclude Include="NetworkResponse.h">
       <Filter>server\response</Filter>
     </ClInclude>
+    <ClInclude Include="NoBlock.h">
+      <Filter>world\blocks</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -275,5 +278,8 @@
     <ClCompile Include="NetworkResponse.cpp">
       <Filter>server\response</Filter>
     </ClCompile>
+    <ClCompile Include="NoBlock.cpp">
+      <Filter>world\blocks</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 78 - 65
FactoryCraft/Game.cpp

@@ -3,15 +3,16 @@
 #include "Player.h"
 #include "OverworldDimension.h"
 #include "AddChunkUpdate.h"
+#include "NoBlock.h"
 
 using namespace Framework;
 
-GameClient::GameClient( Player *zPlayer, FCKlient *client )
+GameClient::GameClient( Player* zPlayer, FCKlient* client )
     : ReferenceCounter(),
     zPlayer( zPlayer ),
     client( client ),
     writer( client->zClient() ),
-    viewDistance( 5 ),
+    viewDistance( DEFAULT_VIEW_DISTANCE ),
     first( 1 ),
     online( 1 )
 {}
@@ -21,7 +22,7 @@ GameClient::~GameClient()
     client->release();
 }
 
-void GameClient::sendWorldUpdate( WorldUpdate *zUpdate )
+void GameClient::sendWorldUpdate( WorldUpdate* zUpdate )
 {
     if( zPlayer->getCurrentDimensionId() == zUpdate->getAffectedDimension() )
     {
@@ -29,18 +30,18 @@ void GameClient::sendWorldUpdate( WorldUpdate *zUpdate )
         if( abs( pos.x - zUpdate->getMinAffectedPoint().x ) < viewDistance * CHUNK_SIZE || (abs( pos.x - zUpdate->getMaxAffectedPoint().x ) < viewDistance * CHUNK_SIZE) || abs( pos.y - zUpdate->getMinAffectedPoint().y ) < viewDistance * CHUNK_SIZE || (abs( pos.y - zUpdate->getMaxAffectedPoint().y ) < viewDistance * CHUNK_SIZE) )
         {
             cs.Enter();
-            writer.schreibe( (char *)&Message::INGAME_MESSAGE, 1 );
-            writer.schreibe( (char *)&Message::WORLD_UPDATE, 1 );
+            writer.schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
+            writer.schreibe( (char*)&Message::WORLD_UPDATE, 1 );
             zUpdate->write( &writer );
             cs.Leave();
         }
     }
 }
 
-void GameClient::reply( Game *zGame )
+void GameClient::reply( Game* zGame )
 {
     cs.Enter();
-    for( auto req = requests.getIterator(); req; req++ )
+    for( auto req : requests )
         zGame->api( req, this );
     requests.leeren();
     cs.Leave();
@@ -48,18 +49,18 @@ void GameClient::reply( Game *zGame )
     int y = (int)zPlayer->getPosition().y;
     int d = zPlayer->getCurrentDimensionId();
     cs.Enter();
-    writer.schreibe( (char *)&Message::INGAME_MESSAGE, 1 );
-    writer.schreibe( (char *)&Message::POSITION_UPDATE, 1 );
+    writer.schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
+    writer.schreibe( (char*)&Message::POSITION_UPDATE, 1 );
     float f = zPlayer->getPosition().x;
-    writer.schreibe( (char *)&f, 4 );
+    writer.schreibe( (char*)&f, 4 );
     f = zPlayer->getPosition().y;
-    writer.schreibe( (char *)&f, 4 );
+    writer.schreibe( (char*)&f, 4 );
     f = zPlayer->getPosition().z;
-    writer.schreibe( (char *)&f, 4 );
+    writer.schreibe( (char*)&f, 4 );
     f = zPlayer->getFaceDir().x;
-    writer.schreibe( (char *)&f, 4 );
+    writer.schreibe( (char*)&f, 4 );
     f = zPlayer->getFaceDir().y;
-    writer.schreibe( (char *)&f, 4 );
+    writer.schreibe( (char*)&f, 4 );
     cs.Leave();
     // send world to client
     if( first )
@@ -69,10 +70,10 @@ void GameClient::reply( Game *zGame )
         {
             for( int yP = y - CHUNK_SIZE * viewDistance; y <= y + CHUNK_SIZE * viewDistance; y += CHUNK_SIZE )
             {
-                Chunk *chunk = zGame->zDimension( d )->zChunk( zGame->getChunkCenter( xP, yP ) );
+                Chunk* chunk = zGame->zDimension( d )->zChunk( zGame->getChunkCenter( xP, yP ) );
                 if( chunk )
                 {
-                    AddChunkUpdate update( dynamic_cast<Chunk *>(chunk->getThis()) );
+                    AddChunkUpdate update( dynamic_cast<Chunk*>(chunk->getThis()) );
                     sendWorldUpdate( &update );
                 }
             }
@@ -91,10 +92,10 @@ void GameClient::reply( Game *zGame )
             {
                 if( xP < lastMin.x || xP > lastMax.x || yP < lastMin.y || yP > lastMax.y )
                 {
-                    Chunk *chunk = zGame->zDimension( d )->zChunk( zGame->getChunkCenter( x, y ) );
+                    Chunk* chunk = zGame->zDimension( d )->zChunk( zGame->getChunkCenter( x, y ) );
                     if( chunk )
                     {
-                        AddChunkUpdate update( dynamic_cast<Chunk *>(chunk->getThis()) );
+                        AddChunkUpdate update( dynamic_cast<Chunk*>(chunk->getThis()) );
                         sendWorldUpdate( &update );
                     }
                     else
@@ -113,12 +114,12 @@ void GameClient::logout()
     online = 0;
 }
 
-void GameClient::addMessage( StreamReader *reader )
+void GameClient::addMessage( StreamReader* reader )
 {
     short len = 0;
-    reader->lese( (char *)&len, 2 );
-    InMemoryBuffer *buffer = new InMemoryBuffer();
-    char *tmp = new char[ len ];
+    reader->lese( (char*)&len, 2 );
+    InMemoryBuffer* buffer = new InMemoryBuffer();
+    char* tmp = new char[ len ];
     reader->lese( tmp, len );
     buffer->schreibe( tmp, len );
     delete[]tmp;
@@ -132,19 +133,19 @@ bool GameClient::isOnline() const
     return online;
 }
 
-void GameClient::sendResponse( NetworkResponse *zResponse )
+void GameClient::sendResponse( NetworkResponse* zResponse )
 {
     if( zResponse->isAreaAffected( { lastPos.x - (float)CHUNK_SIZE * (float)viewDistance, lastPos.y - (float)CHUNK_SIZE * (float)viewDistance, 0.f }, { lastPos.x + (float)CHUNK_SIZE * (float)viewDistance, lastPos.y + (float)CHUNK_SIZE * (float)viewDistance, (float)WORLD_HEIGHT } ) )
     {
         cs.Leave();
-        writer.schreibe( (char *)&Message::INGAME_MESSAGE, 1 );
-        writer.schreibe( (char *)&Message::API_MESSAGE, 1 );
+        writer.schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
+        writer.schreibe( (char*)&Message::API_MESSAGE, 1 );
         zResponse->writeTo( client->zWriter() );
         cs.Leave();
     }
 }
 
-Player *GameClient::zEntity() const
+Player* GameClient::zEntity() const
 {
     return zPlayer;
 }
@@ -157,7 +158,7 @@ Game::Game( Framework::Text name, Framework::Text worldsDir )
     updates( new RCArray<WorldUpdate>() ),
     clients( new RCArray<GameClient>() ),
     ticker( new TickOrganizer() ),
-    path( (const char *)(worldsDir + "/" + name) ),
+    path( (const char*)(worldsDir + "/" + name) ),
     stop( 0 ),
     tickId( 0 ),
     nextEntityId( 0 ),
@@ -171,12 +172,12 @@ Game::Game( Framework::Text name, Framework::Text worldsDir )
     if( d.existiert() )
     {
         d.open( Datei::Style::lesen );
-        d.lese( (char *)&nextEntityId, 4 );
+        d.lese( (char*)&nextEntityId, 4 );
         d.close();
     }
     int seed = 0;
     int index = 0;
-    for( char *n = name; *n; n++ )
+    for( char* n = name; *n; n++ )
         seed += (int)pow( (float)*n * 31, (float)++index );
     generator = new WorldGenerator( seed, this );
     loader = new WorldLoader( this );
@@ -199,10 +200,10 @@ void Game::thread()
     {
         m.messungStart();
         ticker->nextTick();
-        int index = 0;
         Array<int> removed;
         cs.Enter();
-        for( auto player = clients->getIterator(); player; player++, index++ )
+        int index = 0;
+        for( auto player : *clients )
         {
             if( !player->isOnline() )
             {
@@ -210,20 +211,21 @@ void Game::thread()
                 pFile.setDatei( path + "/player/" + player->zEntity()->getName() );
                 if( pFile.open( Datei::Style::schreiben ) )
                     PlayerEntityType::INSTANCE->saveEntity( player->zEntity(), &pFile );
-                removed.add( player, 0 );
+                removed.add( index, 0 );
             }
+            index++;
         }
-        for( auto i = removed.getIterator(); i; i++ )
+        for( auto i : removed )
             clients->remove( i );
         cs.Leave();
-        for( auto dim = dimensions->getIterator(); dim; dim++ )
+        for( auto dim : *dimensions )
             dim->tickEntities( this );
         cs.Enter();
-        while( updates->z( 0 ) )
+        while( updates->hat( 0 ) )
         {
-            WorldUpdate *update = updates->z( 0 );
+            WorldUpdate* update = updates->z( 0 );
             cs.Leave();
-            for( auto client = clients->getIterator(); client; client++ )
+            for( auto client : *clients )
                 client->sendWorldUpdate( update );
             if( !zDimension( update->getAffectedDimension() ) )
                 addDimension( new Dimension( update->getAffectedDimension() ) );
@@ -232,7 +234,7 @@ void Game::thread()
             updates->remove( 0 );
         }
         cs.Leave();
-        for( auto client = clients->getIterator(); client; client++ )
+        for( auto client : *clients )
             client->reply( this );
         m.messungEnde();
         double sec = m.getSekunden();
@@ -242,7 +244,7 @@ void Game::thread()
     save();
 }
 
-void Game::api( Framework::StreamReader *zRequest, GameClient *zOrigin )
+void Game::api( Framework::StreamReader* zRequest, GameClient* zOrigin )
 {
     char type;
     zRequest->lese( &type, 1 );
@@ -252,8 +254,8 @@ void Game::api( Framework::StreamReader *zRequest, GameClient *zOrigin )
     case 1: // world
     {
         int dimensionId;
-        zRequest->lese( (char *)&dimensionId, 4 );
-        Dimension *dim = zDimension( dimensionId );
+        zRequest->lese( (char*)&dimensionId, 4 );
+        Dimension* dim = zDimension( dimensionId );
         if( !dim )
         {
             dim = new Dimension( dimensionId );
@@ -262,47 +264,53 @@ void Game::api( Framework::StreamReader *zRequest, GameClient *zOrigin )
         dim->api( zRequest, &response );
         break;
     }
+    case 2: // player
+        zOrigin->zEntity()->api( zRequest, &response );
+        break;
     default:
         std::cout << "received unknown api request in game with type " << (int)type << "\n";
     }
-    if( response.isBroadcast() )
-        distributeResponse( &response );
-    else
-        zOrigin->sendResponse( &response );
+    if( !response.isEmpty() )
+    {
+        if( response.isBroadcast() )
+            distributeResponse( &response );
+        else
+            zOrigin->sendResponse( &response );
+    }
 }
 
-void Game::distributeResponse( NetworkResponse *zResponse )
+void Game::distributeResponse( NetworkResponse* zResponse )
 {
-    for( auto client = clients->getIterator(); client; client++ )
+    for( auto client : *clients )
         client->sendResponse( zResponse );
 }
 
-void Game::requestWorldUpdate( WorldUpdate *update )
+void Game::requestWorldUpdate( WorldUpdate* update )
 {
     cs.Enter();
     updates->add( update );
     cs.Leave();
 }
 
-GameClient *Game::addPlayer( FCKlient *client, Framework::Text name )
+GameClient* Game::addPlayer( FCKlient* client, Framework::Text name )
 {
     cs.Enter();
     Datei pFile;
     pFile.setDatei( path + "/player/" + name );
-    Player *player;
+    Player* player;
     bool isNew = 0;
     if( !pFile.existiert() || !pFile.open( Datei::Style::lesen ) )
     {
-        player = (Player *)PlayerEntityType::INSTANCE->createEntityAt( Vec3<float>( 0, 0, 0 ), OverworldDimension::ID, this );
+        player = (Player*)PlayerEntityType::INSTANCE->createEntityAt( Vec3<float>( 0, 0, 0 ), OverworldDimension::ID, this );
         player->setName( name );
         isNew = 1;
     }
     else
     {
-        player = (Player *)PlayerEntityType::INSTANCE->loadEntity( this, &pFile );
+        player = (Player*)PlayerEntityType::INSTANCE->loadEntity( this, &pFile );
         pFile.close();
     }
-    requestArea( { (int)player->getPosition().x - 100, (int)player->getPosition().y - 100, (int)player->getPosition().x + 100, (int)player->getPosition().y + 100, player->getCurrentDimensionId() } );
+    requestArea( { (int)player->getPosition().x - DEFAULT_VIEW_DISTANCE * CHUNK_SIZE, (int)player->getPosition().y - DEFAULT_VIEW_DISTANCE * CHUNK_SIZE, (int)player->getPosition().x + DEFAULT_VIEW_DISTANCE * CHUNK_SIZE, (int)player->getPosition().y + DEFAULT_VIEW_DISTANCE * CHUNK_SIZE, player->getCurrentDimensionId() } );
     while( !zDimension( OverworldDimension::ID ) || (isNew && !zDimension( OverworldDimension::ID )->zChunk( getChunkCenter( (int)player->getPosition().x, (int)player->getPosition().y ) )) )
     {
         cs.Leave();
@@ -311,22 +319,22 @@ GameClient *Game::addPlayer( FCKlient *client, Framework::Text name )
     }
     if( isNew )
     {
-        Block *b = 0;
+        Either<Block*, int> b = NoBlockBlockType::ID;
         int h = WORLD_HEIGHT;
-        while( !IS_BLOCK( b ) && h > 0 )
+        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 } );
     }
     zDimension( OverworldDimension::ID )->addEntity( player );
-    GameClient *gameClient = new GameClient( player, client );
+    GameClient* gameClient = new GameClient( player, client );
     clients->add( gameClient );
     cs.Leave();
-    return dynamic_cast<GameClient *>(gameClient->getThis());
+    return dynamic_cast<GameClient*>(gameClient->getThis());
 }
 
 bool Game::isChunkLoaded( int x, int y, int dimension ) const
 {
-    Dimension *dim = zDimension( dimension );
+    Dimension* dim = zDimension( dimension );
     return (dim && dim->hasChunck( x, y ));
 }
 
@@ -335,17 +343,17 @@ bool Game::doesChunkExist( int x, int y, int dimension ) const
     return isChunkLoaded( x, y, dimension ) || loader->existsChunk( x, y, dimension );
 }
 
-Block *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 );
+    Dimension* dim = zDimension( dimension );
     if( dim )
         return dim->zBlock( location, this );
     return 0;
 }
 
-Dimension *Game::zDimension( int id ) const
+Dimension* Game::zDimension( int id ) const
 {
-    for( auto dim = dimensions->getIterator(); dim; dim++ )
+    for( auto dim : *dimensions )
     {
         if( dim->getDimensionId() == id )
             return dim;
@@ -379,9 +387,9 @@ void Game::save() const
     Datei d;
     d.setDatei( path + "/eid" );
     d.open( Datei::Style::schreiben );
-    d.schreibe( (char *)&nextEntityId, 4 );
+    d.schreibe( (char*)&nextEntityId, 4 );
     d.close();
-    for( auto dim = dimensions->getIterator(); dim; dim++ )
+    for( auto dim : *dimensions )
         dim->save( path );
 }
 
@@ -391,7 +399,7 @@ void Game::requestStop()
     warteAufThread( 1000000 );
 }
 
-void Game::addDimension( Dimension *d )
+void Game::addDimension( Dimension* d )
 {
     dimensions->add( d );
 }
@@ -402,4 +410,9 @@ int Game::getNextEntityId()
     int result = nextEntityId++;
     cs.Leave();
     return result;
+}
+
+WorldGenerator* Game::zGenerator() const
+{
+    return generator;
 }

+ 22 - 21
FactoryCraft/Game.h

@@ -20,8 +20,8 @@ class FCKlient;
 class GameClient : public virtual Framework::ReferenceCounter
 {
 private:
-    Player *zPlayer;
-    FCKlient *client;
+    Player* zPlayer;
+    FCKlient* client;
     Network::NetworkWriter writer;
     CriticalSection cs;
     RCArray<InMemoryBuffer> requests;
@@ -31,16 +31,16 @@ private:
     bool online;
 
 public:
-    GameClient( Player *zPlayer, FCKlient *client );
+    GameClient( Player* zPlayer, FCKlient* client );
     ~GameClient();
 
-    void sendWorldUpdate( WorldUpdate *zUpdate );
-    void reply( Game *zGame );
+    void sendWorldUpdate( WorldUpdate* zUpdate );
+    void reply( Game* zGame );
     void logout();
-    void addMessage( StreamReader *reader );
+    void addMessage( StreamReader* reader );
     bool isOnline() const;
-    void sendResponse( NetworkResponse *zResponse );
-    Player *zEntity() const;
+    void sendResponse( NetworkResponse* zResponse );
+    Player* zEntity() const;
 
 private:
     class Message
@@ -58,36 +58,37 @@ class Game : public virtual Framework::Thread
 {
 private:
     Framework::Text name;
-    Framework::RCArray<Dimension> *dimensions;
-    Framework::RCArray<WorldUpdate> *updates;
-    Framework::RCArray<GameClient> *clients;
-    TickOrganizer *ticker;
+    Framework::RCArray<Dimension>* dimensions;
+    Framework::RCArray<WorldUpdate>* updates;
+    Framework::RCArray<GameClient>* clients;
+    TickOrganizer* ticker;
     Framework::Text path;
     bool stop;
     __int64 tickId;
     CriticalSection cs;
     int nextEntityId;
-    WorldGenerator *generator;
-    WorldLoader *loader;
+    WorldGenerator* generator;
+    WorldLoader* loader;
 
     void thread() override;
 public:
     Game( Framework::Text name, Framework::Text worldsDir );
     ~Game();
-    void api( Framework::StreamReader *zRequest, GameClient *zOrigin );
-    void distributeResponse( NetworkResponse *zResponse );
-    void requestWorldUpdate( WorldUpdate *update );
-    GameClient *addPlayer( FCKlient *client, Framework::Text name );
+    void api( Framework::StreamReader* zRequest, GameClient* zOrigin );
+    void distributeResponse( NetworkResponse* zResponse );
+    void requestWorldUpdate( WorldUpdate* update );
+    GameClient* addPlayer( FCKlient* client, Framework::Text name );
     bool doesChunkExist( int x, int y, int dimension ) const;
     bool isChunkLoaded( int x, int y, int dimension ) const;
-    Block *zBlockAt( Framework::Vec3<int> location, int dimension ) const;
-    Dimension *zDimension( int id ) const;
+    Framework::Either<Block*, int> zBlockAt( Framework::Vec3<int> location, int dimension ) const;
+    Dimension* zDimension( int id ) const;
     Framework::Punkt getChunkCenter( int x, int y ) const;
     Area getChunckArea( Punkt center ) const;
     Framework::Text getWorldDirectory() const;
     void requestArea( Area area );
     void save() const;
     void requestStop();
-    void addDimension( Dimension *d );
+    void addDimension( Dimension* d );
     int getNextEntityId();
+    WorldGenerator* zGenerator() const;
 };

+ 2 - 2
FactoryCraft/GrasslandBiom.cpp

@@ -17,7 +17,7 @@ GrasslandBiom::GrasslandBiom( double biomXMultiplier, double biomYMultiplier, do
     this->airOutputMultiplier = airOutputMultiplier;
 }
 
-Block *GrasslandBiom::getBlock( Noise *zNoise, int x, int y, int z, Game *zGame )
+Framework::Either<Block*, int> GrasslandBiom::getBlock( Noise* zNoise, int x, int y, int z, Game* zGame )
 {
-    return StaticRegistry<BlockType>::INSTANCE.zElement( DirtBlockType::ID )->createBlockAt( Framework::Vec3<int>( x, y, z ), zGame, 0 );
+    return DirtBlockType::ID;
 }

+ 1 - 1
FactoryCraft/GrasslandBiom.h

@@ -8,5 +8,5 @@ class GrasslandBiom : public BiomGenerator
 public:
     GrasslandBiom();
     GrasslandBiom( double biomXMultiplier, double biomYMultiplier, double biomOutputMultiplier, double airXMultiplier, double airYMultiplier, double airOutputMultiplier );
-    Block *getBlock( Noise *zNoise, int x, int y, int z, Game *zGame ) override;
+    Framework::Either<Block*, int> getBlock( Noise* zNoise, int x, int y, int z, Game* zGame ) override;
 };

+ 49 - 47
FactoryCraft/Inventory.cpp

@@ -5,7 +5,7 @@
 
 using namespace Framework;
 
-InventoryInteraction::InventoryInteraction( Inventory *current, Inventory *other, Direction dir )
+InventoryInteraction::InventoryInteraction( Inventory* current, Inventory* other, Direction dir )
     : current( current ),
     other( other ),
     dir( dir )
@@ -13,7 +13,7 @@ InventoryInteraction::InventoryInteraction( Inventory *current, Inventory *other
     lock();
 }
 
-InventoryInteraction::InventoryInteraction( const InventoryInteraction &interaction )
+InventoryInteraction::InventoryInteraction( const InventoryInteraction& interaction )
     : InventoryInteraction( interaction.current, interaction.other, interaction.dir )
 {}
 
@@ -84,22 +84,22 @@ void InventoryInteraction::unlock()
     current->cs.Leave();
 }
 
-void InventoryInteraction::transaction( Inventory *zSource, Inventory *zTarget, ItemFilter *zFilter, Direction sourceView, Direction targetView, int count )
+void InventoryInteraction::transaction( Inventory* zSource, Inventory* zTarget, ItemFilter* zFilter, Direction sourceView, Direction targetView, int count )
 {
-    auto sourceSlot = zSource->pullSlotsOrder->getIterator();
-    for( auto targetSlot = zTarget->pushSlotsOrder->getIterator(); targetSlot; )
+    auto sourceSlot = zSource->pullSlotsOrder->begin();
+    for( auto targetSlot = zTarget->pushSlotsOrder->begin(); targetSlot; )
     {
         int amount = count;
         if( !targetSlot->isFull() )
         {
             if( targetSlot->zStack() )
             {
-                Array<ItemSlot *> *zSurceListe = zSource->itemCache->safeGet( targetSlot->zStack()->zItem()->zItemType()->getId(), 0 );
+                Array<ItemSlot*>* zSurceListe = zSource->itemCache->safeGet( targetSlot->zStack()->zItem()->zItemType()->getId(), 0 );
                 if( zSurceListe )
                 {
                     Array<int> toDelete;
                     int index = 0;
-                    for( auto sourceSlot = zSurceListe->getIterator(); sourceSlot; sourceSlot++, index++ )
+                    for( auto sourceSlot = zSurceListe->begin(); sourceSlot; sourceSlot++, index++ )
                     {
                         if( zFilter && !zFilter->matchItem( sourceSlot->zStack()->zItem() ) )
                             continue;
@@ -108,7 +108,7 @@ void InventoryInteraction::transaction( Inventory *zSource, Inventory *zTarget,
                         if( number > 0 && zSource->allowPullStack( sourceSlot, sourceView ) && zTarget->allowPushStack( targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp ) )
                         {
                             number = MIN( number, tmp );
-                            ItemStack *stack = sourceSlot->takeItemsOut( number, dir );
+                            ItemStack* stack = sourceSlot->takeItemsOut( number, dir );
                             if( stack )
                             {
                                 if( !sourceSlot->zStack() )
@@ -125,7 +125,7 @@ void InventoryInteraction::transaction( Inventory *zSource, Inventory *zTarget,
                             }
                         }
                     }
-                    for( auto indexToDelete = toDelete.getIterator(); indexToDelete; indexToDelete++ )
+                    for( auto indexToDelete = toDelete.begin(); indexToDelete; indexToDelete++ )
                         zSurceListe->remove( indexToDelete );
                     if( count == 0 )
                         return;
@@ -142,7 +142,7 @@ void InventoryInteraction::transaction( Inventory *zSource, Inventory *zTarget,
                 if( number > 0 && zSource->allowPullStack( sourceSlot, sourceView ) && zTarget->allowPushStack( targetSlot, targetView, sourceSlot->zStack()->zItem(), tmp ) )
                 {
                     number = MIN( number, tmp );
-                    ItemStack *stack = sourceSlot->takeItemsOut( number, dir );
+                    ItemStack* stack = sourceSlot->takeItemsOut( number, dir );
                     if( stack )
                     {
                         zSource->updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
@@ -166,7 +166,7 @@ void InventoryInteraction::transaction( Inventory *zSource, Inventory *zTarget,
 }
 
 
-InventoryInteraction &InventoryInteraction::operator=( const InventoryInteraction &data )
+InventoryInteraction& InventoryInteraction::operator=( const InventoryInteraction& data )
 {
     if( &data == this ) return *this;
     unlock();
@@ -184,13 +184,13 @@ void InventoryInteraction::endInteraction()
     other = 0;
 }
 
-void InventoryInteraction::pullItems( int count, ItemFilter *zFilter )
+void InventoryInteraction::pullItems( int count, ItemFilter* zFilter )
 {
     if( !current || !other ) return;
     transaction( other, current, zFilter, opposite( dir ), dir, count );
 }
 
-void InventoryInteraction::pushItems( int count, ItemFilter *zFilter )
+void InventoryInteraction::pushItems( int count, ItemFilter* zFilter )
 {
     if( !current || !other ) return;
     transaction( current, other, zFilter, dir, opposite( dir ), count );
@@ -205,7 +205,7 @@ Inventory::Inventory( const Framework::Vec3<float> location, bool hasInventory )
     {
         pullSlotsOrder = new Framework::RCArray<ItemSlot>();
         pushSlotsOrder = new Framework::RCArray<ItemSlot>();
-        itemCache = new Framework::HashMap<int, Framework::Array<ItemSlot *> *>( ITEM_CACHE_SIZE, std::_Identity<int>() );
+        itemCache = new Framework::HashMap<int, Framework::Array<ItemSlot*>*>( ITEM_CACHE_SIZE, std::_Identity<int>() );
     }
     else
     {
@@ -225,7 +225,7 @@ Inventory::~Inventory()
         itemCache->release();
 }
 
-void Inventory::updateCache( ItemSlot *zSlot, int beforeKey )
+void Inventory::updateCache( ItemSlot* zSlot, int beforeKey )
 {
     if( !itemCache )
         return;
@@ -243,114 +243,116 @@ void Inventory::updateCache( ItemSlot *zSlot, int beforeKey )
         auto tmp = itemCache->safeGet( key, 0 );
         if( !tmp )
         {
-            tmp = new Array<ItemSlot *>();
+            tmp = new Array<ItemSlot*>();
             itemCache->put( key, tmp );
         }
         tmp->add( zSlot, 0 );
     }
 }
 
-void Inventory::addSlot( ItemSlot *slot )
+void Inventory::addSlot( ItemSlot* slot )
 {
     cs.Enter();
     int pullPrio = slot->getPullPriority();
     int pushPrio = slot->getPushPriority();
     int index = 0;
-    for( auto iterator = pullSlotsOrder->getIterator(); iterator; iterator++, index++ )
+    for( auto stack : *pullSlotsOrder )
     {
-        if( iterator->getPullPriority() > pullPrio )
+        if( stack->getPullPriority() > pullPrio )
             break;
+        index++;
     }
-    pullSlotsOrder->add( dynamic_cast<ItemSlot *>(slot->getThis()), index );
+    pullSlotsOrder->add( dynamic_cast<ItemSlot*>(slot->getThis()), index );
     index = 0;
-    for( auto iterator = pushSlotsOrder->getIterator(); iterator; iterator++, index++ )
+    for( auto stack : *pushSlotsOrder )
     {
-        if( iterator->getPushPriority() > pushPrio )
+        if( stack->getPushPriority() > pushPrio )
             break;
+        index++;
     }
     pullSlotsOrder->add( slot, index );
     updateCache( slot, -1 );
     cs.Leave();
 }
 
-bool Inventory::allowPullStack( ItemSlot *zSlot, Direction dir )
+bool Inventory::allowPullStack( ItemSlot* zSlot, Direction dir )
 {
     return pullSlotsOrder;
 }
 
-bool Inventory::allowPushStack( ItemSlot *zSlot, Direction dir, const Item *zItem, int &count )
+bool Inventory::allowPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int& count )
 {
     return pushSlotsOrder;
 }
 
-void Inventory::afterPullStack( ItemSlot *zSlot, Direction dir, const Item *zItem, int count )
+void Inventory::afterPullStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count )
 {}
 
-void Inventory::afterPushStack( ItemSlot *zSlot, Direction dir, const Item *zItem, int count )
+void Inventory::afterPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count )
 {}
 
-void Inventory::loadInventory( Framework::StreamReader *zReader )
+void Inventory::loadInventory( Framework::StreamReader* zReader )
 {
     if( itemCache )
     {
-        for( auto iterator = pushSlotsOrder->getIterator(); iterator; iterator++ )
+        for( auto stack : *pushSlotsOrder )
         {
             int size = 0;
-            zReader->lese( (char *)&size, 4 );
+            zReader->lese( (char*)&size, 4 );
             if( size != 0 )
             {
                 int id = 0;
-                zReader->lese( (char *)&id, 4 );
-                Item *item = StaticRegistry<ItemType>::INSTANCE.zElement( id )->loadItem( zReader );
-                iterator->addItems( new ItemStack( item, size ), NO_DIRECTION );
+                zReader->lese( (char*)&id, 4 );
+                Item* item = StaticRegistry<ItemType>::INSTANCE.zElement( id )->loadItem( zReader );
+                stack->addItems( new ItemStack( item, size ), NO_DIRECTION );
             }
         }
     }
 }
 
-void Inventory::saveInventory( Framework::StreamWriter *zWriter )
+void Inventory::saveInventory( Framework::StreamWriter* zWriter )
 {
     if( itemCache )
     {
-        for( auto iterator = pushSlotsOrder->getIterator(); iterator; iterator++ )
+        for( auto slot : *pushSlotsOrder )
         {
-            const ItemStack *stack = iterator->zStack();
+            const ItemStack* stack = slot->zStack();
             int value = 0;
             if( !stack || !stack->zItem() )
             {
-                zWriter->schreibe( (char *)&value, 4 );
+                zWriter->schreibe( (char*)&value, 4 );
             }
             else
             {
                 value = stack->getSize();
-                zWriter->schreibe( (char *)&value, 4 );
+                zWriter->schreibe( (char*)&value, 4 );
                 value = stack->zItem()->zItemType()->getId();
-                zWriter->schreibe( (char *)&value, 4 );
+                zWriter->schreibe( (char*)&value, 4 );
                 stack->zItem()->zItemType()->saveItem( stack->zItem(), zWriter );
             }
         }
     }
 }
 
-void Inventory::localTransaction( Array< ItemSlot * > *zSourceSlots, Array< ItemSlot * > *zTargetSlots, ItemFilter *zFilter, int count )
+void Inventory::localTransaction( Array< ItemSlot* >* zSourceSlots, Array< ItemSlot* >* zTargetSlots, ItemFilter* zFilter, int count )
 {
     if( itemCache )
     {
         cs.Enter();
-        auto sourceSlot = zSourceSlots->getIterator();
-        for( auto targetSlot = zTargetSlots->getIterator(); targetSlot; )
+        auto sourceSlot = zSourceSlots->begin();
+        for( auto targetSlot = zTargetSlots->begin(); targetSlot; )
         {
             int amount = count;
             if( !targetSlot->isFull() )
             {
                 if( targetSlot->zStack() )
                 {
-                    Array<ItemSlot *> *zSurceListe = itemCache->safeGet( targetSlot->zStack()->zItem()->zItemType()->getId(), 0 );
+                    Array<ItemSlot*>* zSurceListe = itemCache->safeGet( targetSlot->zStack()->zItem()->zItemType()->getId(), 0 );
                     if( zSurceListe )
                     {
                         Array<int> toDelete;
                         int index = 0;
-                        for( auto sourceSlot = zSurceListe->getIterator(); sourceSlot; sourceSlot++, index++ )
+                        for( auto sourceSlot = zSurceListe->begin(); sourceSlot; sourceSlot++, index++ )
                         {
                             if( zSourceSlots->getWertIndex( sourceSlot ) < 0 )
                                 continue;
@@ -359,7 +361,7 @@ void Inventory::localTransaction( Array< ItemSlot * > *zSourceSlots, Array< Item
                             int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), NO_DIRECTION ), count );
                             if( number > 0 )
                             {
-                                ItemStack *stack = sourceSlot->takeItemsOut( number, NO_DIRECTION );
+                                ItemStack* stack = sourceSlot->takeItemsOut( number, NO_DIRECTION );
                                 if( stack )
                                 {
                                     if( !sourceSlot->zStack() )
@@ -377,7 +379,7 @@ void Inventory::localTransaction( Array< ItemSlot * > *zSourceSlots, Array< Item
                                 }
                             }
                         }
-                        for( auto indexToDelete = toDelete.getIterator(); indexToDelete; indexToDelete++ )
+                        for( auto indexToDelete = toDelete.begin(); indexToDelete; indexToDelete++ )
                             zSurceListe->remove( indexToDelete );
                         if( count == 0 )
                         {
@@ -398,7 +400,7 @@ void Inventory::localTransaction( Array< ItemSlot * > *zSourceSlots, Array< Item
                     int number = MIN( targetSlot->numberOfAddableItems( sourceSlot->zStack(), NO_DIRECTION ), count );
                     if( number > 0 )
                     {
-                        ItemStack *stack = sourceSlot->takeItemsOut( number, NO_DIRECTION );
+                        ItemStack* stack = sourceSlot->takeItemsOut( number, NO_DIRECTION );
                         if( stack )
                         {
                             updateCache( sourceSlot, targetSlot->zStack()->zItem()->zItemType()->getId() );
@@ -427,7 +429,7 @@ void Inventory::localTransaction( Array< ItemSlot * > *zSourceSlots, Array< Item
     }
 }
 
-InventoryInteraction Inventory::interactWith( Inventory *zInventory, Direction dir )
+InventoryInteraction Inventory::interactWith( Inventory* zInventory, Direction dir )
 {
     return InventoryInteraction( this, zInventory, dir );
 }

+ 21 - 21
FactoryCraft/Inventory.h

@@ -13,47 +13,47 @@ class Inventory;
 class InventoryInteraction
 {
 private:
-    Inventory *current;
-    Inventory *other;
+    Inventory* current;
+    Inventory* other;
     Direction dir;
     void lock();
     void unlock();
-    void transaction( Inventory *zSource, Inventory *zTarget, ItemFilter *zFilter, Direction sourceView, Direction targetView, int count );
+    void transaction( Inventory* zSource, Inventory* zTarget, ItemFilter* zFilter, Direction sourceView, Direction targetView, int count );
 
 public:
-    InventoryInteraction( Inventory *zCurrent, Inventory *zOther, Direction dir );
-    InventoryInteraction( const InventoryInteraction &interaction );
+    InventoryInteraction( Inventory* zCurrent, Inventory* zOther, Direction dir );
+    InventoryInteraction( const InventoryInteraction& interaction );
     ~InventoryInteraction();
-    InventoryInteraction &operator=( const InventoryInteraction &data );
+    InventoryInteraction& operator=( const InventoryInteraction& data );
     void endInteraction();
-    void pullItems( int count, ItemFilter *zFilter );
-    void pushItems( int count, ItemFilter *zFilter );
+    void pullItems( int count, ItemFilter* zFilter );
+    void pushItems( int count, ItemFilter* zFilter );
 };
 
 class Inventory : public virtual Framework::ReferenceCounter
 {
 private:
-    Framework::RCArray<ItemSlot> *pullSlotsOrder;
-    Framework::RCArray<ItemSlot> *pushSlotsOrder;
-    Framework::HashMap<int, Framework::Array<ItemSlot *> *> *itemCache;
+    Framework::RCArray<ItemSlot>* pullSlotsOrder;
+    Framework::RCArray<ItemSlot>* pushSlotsOrder;
+    Framework::HashMap<int, Framework::Array<ItemSlot*>*>* itemCache;
     CriticalSection cs;
-    void updateCache( ItemSlot *zSlot, int beforeKey );
+    void updateCache( ItemSlot* zSlot, int beforeKey );
 
 protected:
     Framework::Vec3<float> location;
-    void addSlot( ItemSlot *slot );
-    void localTransaction( Framework::Array< ItemSlot * > *zSourceSlots, Framework::Array< ItemSlot * > *zTargetSlots, ItemFilter *zFilter, int count );
-    virtual bool allowPullStack( ItemSlot *zSlot, Direction dir );
-    virtual bool allowPushStack( ItemSlot *zSlot, Direction dir, const Item *zItem, int &count );
-    virtual void afterPullStack( ItemSlot *zSlot, Direction dir, const Item *zItem, int count );
-    virtual void afterPushStack( ItemSlot *zSlot, Direction dir, const Item *zItem, int count );
-    virtual void loadInventory( Framework::StreamReader *zReader );
-    virtual void saveInventory( Framework::StreamWriter *zWriter );
+    void addSlot( ItemSlot* slot );
+    void localTransaction( Framework::Array< ItemSlot* >* zSourceSlots, Framework::Array< ItemSlot* >* zTargetSlots, ItemFilter* zFilter, int count );
+    virtual bool allowPullStack( ItemSlot* zSlot, Direction dir );
+    virtual bool allowPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int& count );
+    virtual void afterPullStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count );
+    virtual void afterPushStack( ItemSlot* zSlot, Direction dir, const Item* zItem, int count );
+    virtual void loadInventory( Framework::StreamReader* zReader );
+    virtual void saveInventory( Framework::StreamWriter* zWriter );
 
 public:
     Inventory( const Framework::Vec3<float> location, bool hasInventory );
     virtual ~Inventory();
-    InventoryInteraction interactWith( Inventory *zInventory, Direction dir );
+    InventoryInteraction interactWith( Inventory* zInventory, Direction dir );
 
     friend InventoryInteraction;
 };

+ 8 - 8
FactoryCraft/Item.cpp

@@ -1,7 +1,7 @@
 #include "Item.h"
 
 
-Item::Item( const ItemType *zType, const char *name )
+Item::Item( const ItemType* zType, const char* name )
     : ReferenceCounter(),
     zType( zType ),
     damage( 0 ),
@@ -20,7 +20,7 @@ Item::Item( const ItemType *zType, const char *name )
 void Item::tick()
 {}
 
-const ItemType *Item::zItemType() const
+const ItemType* Item::zItemType() const
 {
     return zType;
 }
@@ -75,7 +75,7 @@ float Item::getMaxDamage() const
     return maxDamage;
 }
 
-bool Item::canBeStackedWith( Item *zItem ) const
+bool Item::canBeStackedWith( Item* zItem ) const
 {
     return zType == zItem->zType && damage == 0 &&
         zItem->damage == 0 &&
@@ -91,17 +91,17 @@ bool Item::canBeStackedWith( Item *zItem ) const
         name.istGleich( zItem->name );
 }
 
-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 )
 {}

+ 9 - 9
FactoryCraft/Item.h

@@ -8,7 +8,7 @@ class ItemType;
 class Item : public virtual Framework::ReferenceCounter
 {
 protected:
-    const ItemType *zType;
+    const ItemType* zType;
     float damage;
     float maxDamage;
     float durability;
@@ -20,12 +20,12 @@ protected:
     bool usable;
     int maxStackSize;
     Framework::Text name;
-    Item( const ItemType *zType, const char *name );
+    Item( const ItemType* zType, const char* name );
 
 public:
     virtual void tick();
 
-    const ItemType *zItemType() const;
+    const ItemType* zItemType() const;
     float getDamage() const;
     float getDurability() const;
     bool isUsable() const;
@@ -36,13 +36,13 @@ public:
     float getMaxDurability() const;
     int getMaxStackSize() const;
     float getMaxDamage() const;
-    virtual bool canBeStackedWith( Item *zItem ) const;
+    virtual bool canBeStackedWith( Item* zItem ) 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;
 };

+ 5 - 5
FactoryCraft/ItemFilter.cpp

@@ -8,14 +8,14 @@ ItemFilter::ItemFilter()
 {}
 
 
-CombinedItemFilter::CombinedItemFilter( ItemFilter *filterA, ItemFilter *filterB, std::function<bool( bool, bool )> op )
+CombinedItemFilter::CombinedItemFilter( ItemFilter* filterA, ItemFilter* filterB, std::function<bool( bool, bool )> op )
     : ItemFilter(),
     filterA( filterA ),
     filterB( filterB ),
     op( op )
 {}
 
-bool CombinedItemFilter::matchItem( const Item *zItem ) const
+bool CombinedItemFilter::matchItem( const Item* zItem ) const
 {
     return op( filterA->matchItem( zItem ), filterB->matchItem( zItem ) );
 }
@@ -25,18 +25,18 @@ AnyItemFilter::AnyItemFilter()
     : ItemFilter()
 {}
 
-bool AnyItemFilter::matchItem( const Item *zItem ) const
+bool AnyItemFilter::matchItem( const Item* zItem ) const
 {
     return true;
 }
 
 
-TypeItemFilter::TypeItemFilter( const ItemType *zType )
+TypeItemFilter::TypeItemFilter( const ItemType* zType )
     : ItemFilter(),
     zType( zType )
 {}
 
-bool TypeItemFilter::matchItem( const Item *zItem ) const
+bool TypeItemFilter::matchItem( const Item* zItem ) const
 {
     return zItem->zItemType() == zType;
 }

+ 9 - 9
FactoryCraft/ItemFilter.h

@@ -10,35 +10,35 @@ class ItemFilter : public virtual Framework::ReferenceCounter
 {
 public:
     ItemFilter();
-    virtual bool matchItem( const Item *zItem ) const = 0;
+    virtual bool matchItem( const Item* zItem ) const = 0;
 };
 
 class CombinedItemFilter : public ItemFilter
 {
 private:
-    ItemFilter *filterA;
-    ItemFilter *filterB;
+    ItemFilter* filterA;
+    ItemFilter* filterB;
     std::function<bool( bool, bool )> op;
 
 public:
-    CombinedItemFilter( ItemFilter *filterA, ItemFilter *filterB, std::function<bool( bool, bool )> op );
-    bool matchItem( const Item *zItem ) const override;
+    CombinedItemFilter( ItemFilter* filterA, ItemFilter* filterB, std::function<bool( bool, bool )> op );
+    bool matchItem( const Item* zItem ) const override;
 };
 
 class AnyItemFilter : public ItemFilter
 {
 public:
     AnyItemFilter();
-    bool matchItem( const Item *zItem ) const override;
+    bool matchItem( const Item* zItem ) const override;
 };
 
 class TypeItemFilter : public ItemFilter
 {
 private:
-    const ItemType *zType;
+    const ItemType* zType;
 
 public:
-    TypeItemFilter( const ItemType *zType );
-    bool matchItem( const Item *zItem ) const override;
+    TypeItemFilter( const ItemType* zType );
+    bool matchItem( const Item* zItem ) const override;
 };
 

+ 2 - 2
FactoryCraft/ItemSkill.cpp

@@ -12,8 +12,8 @@ BasicItemSkill::BasicItemSkill( float maxXP, float durabilityModifier, float spe
     hungerModifier( hungerModifier )
 {}
 
-void BasicItemSkill::use( Entity *zActor, Block *zTarget, Dimension *zDimension )
+void BasicItemSkill::use( Entity* zActor, Block* zTarget, Dimension* zDimension )
 {}
 
-void BasicItemSkill::use( Entity *zActor, Entity *zTarget, Dimension *zDimension )
+void BasicItemSkill::use( Entity* zActor, Entity* zTarget, Dimension* zDimension )
 {}

+ 5 - 5
FactoryCraft/ItemSkill.h

@@ -14,14 +14,14 @@ class Dimension;
 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
 {
 public:
-    virtual void use( Entity *zActor, Block *zTarget, Dimension *zDimension ) = 0;
-    virtual void use( Entity *zActor, Entity *zTarget, Dimension *zDimension ) = 0;
+    virtual void use( Entity* zActor, Block* zTarget, Dimension* zDimension ) = 0;
+    virtual void use( Entity* zActor, Entity* zTarget, Dimension* zDimension ) = 0;
 };
 
 class BasicItemSkill : public ItemSkill
@@ -39,8 +39,8 @@ protected:
     BasicItemSkill( 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, Block *zTarget, Dimension *zDimension ) override;
-    virtual void use( Entity *zActor, Entity *zTarget, Dimension *zDimension ) override;
+    virtual void use( Entity* zActor, Block* zTarget, Dimension* zDimension ) override;
+    virtual void use( Entity* zActor, Entity* zTarget, Dimension* zDimension ) override;
 
     friend ItemType;
 };

+ 8 - 8
FactoryCraft/ItemSlot.cpp

@@ -18,13 +18,13 @@ ItemSlot::~ItemSlot()
         items->release();
 }
 
-ItemStack *ItemSlot::takeItemsOut( int count, Direction dir )
+ItemStack* ItemSlot::takeItemsOut( int count, Direction dir )
 {
     if( !items )
         return 0;
-    if( ( dir | allowedPullSide ) == allowedPullSide )
+    if( (dir | allowedPullSide) == allowedPullSide )
     {
-        ItemStack *result = items->split( count );
+        ItemStack* result = items->split( count );
         if( items->getSize() == 0 )
         {
             items->release();
@@ -35,9 +35,9 @@ ItemStack *ItemSlot::takeItemsOut( int count, Direction dir )
     return 0;
 }
 
-void ItemSlot::addItems( ItemStack *zStack, Direction dir )
+void ItemSlot::addItems( ItemStack* zStack, Direction dir )
 {
-    if( ( dir | allowedPushSides ) == allowedPushSides )
+    if( (dir | allowedPushSides) == allowedPushSides )
     {
         if( !items )
         {
@@ -57,9 +57,9 @@ void ItemSlot::addItems( ItemStack *zStack, Direction dir )
     }
 }
 
-int ItemSlot::numberOfAddableItems( const ItemStack *zStack, Direction dir ) const
+int ItemSlot::numberOfAddableItems( const ItemStack* zStack, Direction dir ) const
 {
-    if( ( dir | allowedPushSides ) == allowedPushSides )
+    if( (dir | allowedPushSides) == allowedPushSides )
     {
         if( !items )
         {
@@ -74,7 +74,7 @@ int ItemSlot::numberOfAddableItems( const ItemStack *zStack, Direction dir ) con
     return 0;
 }
 
-const ItemStack *ItemSlot::zStack() const
+const ItemStack* ItemSlot::zStack() const
 {
     return items;
 }

+ 5 - 5
FactoryCraft/ItemSlot.h

@@ -6,7 +6,7 @@
 class ItemSlot : public virtual Framework::ReferenceCounter
 {
 private:
-    ItemStack *items;
+    ItemStack* items;
     int maxSize;
     Directions allowedPullSide;
     Directions allowedPushSides;
@@ -18,11 +18,11 @@ public:
     ItemSlot( int maxSize, int pullPriority, int pushPriority, int allowedPullSide, int allowedPushSides, bool allowHigherStackSize );
     ~ItemSlot();
 
-    ItemStack *takeItemsOut( int count, Direction dir );
-    void addItems( ItemStack *zStack, Direction dir );
+    ItemStack* takeItemsOut( int count, Direction dir );
+    void addItems( ItemStack* zStack, Direction dir );
 
-    int numberOfAddableItems( const ItemStack *zStack, Direction dir ) const;
-    const ItemStack *zStack() const;
+    int numberOfAddableItems( const ItemStack* zStack, Direction dir ) const;
+    const ItemStack* zStack() const;
     int getPullPriority() const;
     int getPushPriority() const;
     bool isFull() const;

+ 9 - 9
FactoryCraft/ItemStack.cpp

@@ -2,14 +2,14 @@
 #include "Item.h"
 
 
-ItemStack::ItemStack( Item *item, int currentSize, int maxSize )
+ItemStack::ItemStack( Item* item, int currentSize, int maxSize )
     : ReferenceCounter(),
     item( item ),
     size( currentSize ),
     maxSize( maxSize )
 {}
 
-ItemStack::ItemStack( Item *item, int currentSize )
+ItemStack::ItemStack( Item* item, int currentSize )
     : ItemStack( item, currentSize, item->getMaxStackSize() )
 {}
 
@@ -24,14 +24,14 @@ void ItemStack::setMaxSize( int size )
     maxSize = size;
 }
 
-ItemStack *ItemStack::split( int size )
+ItemStack* ItemStack::split( int size )
 {
     size = MIN( size, this->size );
     this->size -= size;
-    return new ItemStack( dynamic_cast<Item *>( item->getThis() ), size, item->getMaxStackSize() );
+    return new ItemStack( dynamic_cast<Item*>(item->getThis()), size, item->getMaxStackSize() );
 }
 
-Item *ItemStack::extractFromStack()
+Item* ItemStack::extractFromStack()
 {
     if( size == 0 )
         return 0;
@@ -39,7 +39,7 @@ Item *ItemStack::extractFromStack()
     return item->zItemType()->cloneItem( item );
 }
 
-bool ItemStack::addToStack( Item *item )
+bool ItemStack::addToStack( Item* item )
 {
     if( size < maxSize && this->item->canBeStackedWith( item ) )
     {
@@ -51,7 +51,7 @@ bool ItemStack::addToStack( Item *item )
     return false;
 }
 
-void ItemStack::addItemStack( ItemStack *zItemStack )
+void ItemStack::addItemStack( ItemStack* zItemStack )
 {
     if( zItemStack->zItem()->canBeStackedWith( item ) )
     {
@@ -61,12 +61,12 @@ void ItemStack::addItemStack( ItemStack *zItemStack )
     }
 }
 
-bool ItemStack::isStackable( Item *zItem ) const
+bool ItemStack::isStackable( Item* zItem ) const
 {
     return item->canBeStackedWith( zItem );
 }
 
-const Item *ItemStack::zItem() const
+const Item* ItemStack::zItem() const
 {
     return item;
 }

+ 9 - 9
FactoryCraft/ItemStack.h

@@ -5,23 +5,23 @@
 class ItemStack : public virtual Framework::ReferenceCounter
 {
 private:
-    Item *item;
+    Item* item;
     int size;
     int maxSize;
 
 public:
-    ItemStack( Item *item, int currentSize, int maxSize );
-    ItemStack( Item *item, int currentSize );
+    ItemStack( Item* item, int currentSize, int maxSize );
+    ItemStack( Item* item, int currentSize );
     ~ItemStack();
 
     void setMaxSize( int size );
-    ItemStack *split( int size );
-    Item *extractFromStack();
-    bool addToStack( Item *item );
-    void addItemStack( ItemStack *zItemStack );
+    ItemStack* split( int size );
+    Item* extractFromStack();
+    bool addToStack( Item* item );
+    void addItemStack( ItemStack* zItemStack );
 
-    bool isStackable( Item *zItem ) const;
-    const Item *zItem() const;
+    bool isStackable( Item* zItem ) const;
+    const Item* zItem() const;
     int getSize() const;
     int getMaxSize() const;
 };

+ 32 - 32
FactoryCraft/ItemType.cpp

@@ -5,7 +5,7 @@
 #include "ItemSkill.h"
 #include "ItemStack.h"
 
-ItemType::ItemType( int id, ItemSkillLevelUpRule *levelUpRule, const ItemType *zBrokenType )
+ItemType::ItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType )
     : ReferenceCounter(),
     id( id ),
     levelUpRule( levelUpRule ),
@@ -20,37 +20,37 @@ ItemType::~ItemType()
         levelUpRule->release();
 }
 
-void ItemType::loadSuperItem( Item *zItem, Framework::StreamReader *zReader ) const
+void ItemType::loadSuperItem( Item* zItem, Framework::StreamReader* zReader ) const
 {
-    zReader->lese( (char *)&zItem->damage, 4 );
-    zReader->lese( (char *)&zItem->maxDamage, 4 );
-    zReader->lese( (char *)&zItem->durability, 4 );
-    zReader->lese( (char *)&zItem->maxDurability, 4 );
+    zReader->lese( (char*)&zItem->damage, 4 );
+    zReader->lese( (char*)&zItem->maxDamage, 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 );
+    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 );
+    zReader->lese( (char*)&len, 1 );
     zItem->name.fillText( ' ', len );
     zReader->lese( zItem->name, len );
 }
 
-void ItemType::saveSuperItem( const Item *zItem, Framework::StreamWriter *zWriter ) const
+void ItemType::saveSuperItem( const Item* zItem, Framework::StreamWriter* zWriter ) const
 {
-    zWriter->schreibe( (char *)&zItem->damage, 4 );
-    zWriter->schreibe( (char *)&zItem->maxDamage, 4 );
-    zWriter->schreibe( (char *)&zItem->durability, 4 );
-    zWriter->schreibe( (char *)&zItem->maxDurability, 4 );
-    unsigned char flags = (unsigned char)( ( ( ( ( zItem->usable << 1 ) | zItem->solid << 1 ) | zItem->equippable << 1 ) | zItem->placeable << 1 ) | zItem->eatable );
-    zWriter->schreibe( (char *)&flags, 1 );
-    zWriter->schreibe( (char *)&zItem->maxStackSize, 1 );
+    zWriter->schreibe( (char*)&zItem->damage, 4 );
+    zWriter->schreibe( (char*)&zItem->maxDamage, 4 );
+    zWriter->schreibe( (char*)&zItem->durability, 4 );
+    zWriter->schreibe( (char*)&zItem->maxDurability, 4 );
+    unsigned char flags = (unsigned char)(((((zItem->usable << 1) | zItem->solid << 1) | zItem->equippable << 1) | 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( (char*)&len, 1 );
     zWriter->schreibe( zItem->name, len );
 }
 
@@ -59,43 +59,43 @@ int ItemType::getId() const
     return id;
 }
 
-const ItemType *ItemType::zBrokenItemType() const
+const ItemType* ItemType::zBrokenItemType() const
 {
     return zBrokenType;
 }
 
-ItemStack *ItemType::createItemStack( int size ) const
+ItemStack* ItemType::createItemStack( int size ) const
 {
-    Item *item = createItem();
+    Item* item = createItem();
     if( !item )
         return 0;
     return new ItemStack( item, MIN( size, item->getMaxStackSize() ) );
 }
 
-ItemSkill *ItemType::createDefaultItemSkill() const
+ItemSkill* ItemType::createDefaultItemSkill() const
 {
     return 0;
 }
 
-void ItemType::levelUpItemSkill( ItemSkill *zSkill ) const
+void ItemType::levelUpItemSkill( ItemSkill* zSkill ) const
 {
     if( levelUpRule )
         levelUpRule->applyOn( zSkill );
 }
 
-Item *ItemType::loadItem( Framework::StreamReader *zReader ) const
+Item* ItemType::loadItem( Framework::StreamReader* zReader ) const
 {
-    Item *item = createItem();
+    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 );
 }
 
-Item *ItemType::cloneItem( Item *zItem ) const
+Item* ItemType::cloneItem( Item* zItem ) const
 {
     Framework::InMemoryBuffer buffer;
     saveItem( zItem, &buffer );

+ 13 - 13
FactoryCraft/ItemType.h

@@ -17,24 +17,24 @@ class ItemType : public virtual Framework::ReferenceCounter
 {
 protected:
     const int id;
-    ItemSkillLevelUpRule *levelUpRule;
-    const ItemType *zBrokenType;
+    ItemSkillLevelUpRule* levelUpRule;
+    const ItemType* zBrokenType;
 
-    ItemType( int id, ItemSkillLevelUpRule *levelUpRule, const ItemType *zBrokenType );
+    ItemType( int id, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType );
 
-    virtual void loadSuperItem( Item *zItem, Framework::StreamReader *zReader ) const;
-    virtual void saveSuperItem( const Item *zItem, Framework::StreamWriter *zWriter ) const;
+    virtual void loadSuperItem( Item* zItem, Framework::StreamReader* zReader ) const;
+    virtual void saveSuperItem( const Item* zItem, Framework::StreamWriter* zWriter ) const;
 
 public:
     ~ItemType();
 
     int getId() 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 Item *cloneItem( Item *zItem ) 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 Item* cloneItem( Item* zItem ) const;
 };

+ 20 - 15
FactoryCraft/NetworkResponse.cpp

@@ -20,48 +20,48 @@ NetworkResponse::~NetworkResponse()
     delete[] adress;
 }
 
-void NetworkResponse::adressChunck( Chunk *zChunk )
+void NetworkResponse::adressChunck( Chunk* zChunk )
 {
     adressLength = 14;
     adress = new char[ adressLength ];
     adress[ 0 ] = 1; // world response
-    *(int *)( adress + 1 ) = zChunk->getDimensionId();
+    *(int*)(adress + 1) = zChunk->getDimensionId();
     adress[ 5 ] = 1; // chunck
     Framework::Punkt center = zChunk->getCenter();
-    *(int *)( adress + 6 ) = center.x;
-    *(int *)( adress + 10 ) = center.y;
+    *(int*)(adress + 6) = center.x;
+    *(int*)(adress + 10) = center.y;
     minPosition = zChunk->getMin();
     maxPosition = zChunk->getMax();
 }
 
-void NetworkResponse::adressEntity( Entity *zEntity )
+void NetworkResponse::adressEntity( Entity* zEntity )
 {
     adressLength = 10;
     adress = new char[ adressLength ];
     adress[ 0 ] = 1; // world response
-    *(int *)( adress + 1 ) = zEntity->getCurrentDimensionId();
+    *(int*)(adress + 1) = zEntity->getCurrentDimensionId();
     adress[ 5 ] = 2; // entity
-    *(int *)( adress + 6 ) = zEntity->getId();
+    *(int*)(adress + 6) = zEntity->getId();
     minPosition = zEntity->getPosition();
     maxPosition = zEntity->getPosition();
 }
 
-void NetworkResponse::adressBlock( Block *zBlock )
+void NetworkResponse::adressBlock( Block* zBlock )
 {
     adressLength = 18;
     adress = new char[ adressLength ];
     adress[ 0 ] = 1; // world response
-    *(int *)( adress + 1 ) = zBlock->getDimensionId();
+    *(int*)(adress + 1) = zBlock->getDimensionId();
     adress[ 5 ] = 3; // block
     Framework::Vec3<int> pos = zBlock->getPos();
-    *(int *)( adress + 6 ) = pos.x;
-    *(int *)( adress + 10 ) = pos.y;
-    *(int *)( adress + 14 ) = pos.z;
+    *(int*)(adress + 6) = pos.x;
+    *(int*)(adress + 10) = pos.y;
+    *(int*)(adress + 14) = pos.z;
     minPosition = pos;
     maxPosition = pos;
 }
 
-void NetworkResponse::setMessage( char *msg, int length, bool deleteMsg )
+void NetworkResponse::setMessage( char* msg, int length, bool deleteMsg )
 {
     message = msg;
     msgLength = length;
@@ -80,12 +80,12 @@ bool NetworkResponse::isAreaAffected( Framework::Vec3<float> min, Framework::Vec
         minPosition.z <= max.z && maxPosition.z >= min.z;
 }
 
-void NetworkResponse::writeTo( Framework::StreamWriter *zWriter ) const
+void NetworkResponse::writeTo( Framework::StreamWriter* zWriter ) const
 {
     int total = msgLength + adressLength;
     if( total )
     {
-        zWriter->schreibe( (char *)&total, 4 );
+        zWriter->schreibe( (char*)&total, 4 );
         zWriter->schreibe( adress, adressLength );
         zWriter->schreibe( message, msgLength );
     }
@@ -94,4 +94,9 @@ void NetworkResponse::writeTo( Framework::StreamWriter *zWriter ) const
 bool NetworkResponse::isBroadcast() const
 {
     return broadcast;
+}
+
+bool NetworkResponse::isEmpty() const
+{
+    return msgLength + adressLength <= 0;
 }

+ 8 - 7
FactoryCraft/NetworkResponse.h

@@ -10,12 +10,12 @@ class Entity;
 class NetworkResponse
 {
 private:
-    char *adress;
+    char* adress;
     char adressLength;
     Framework::Vec3<float> minPosition;
     Framework::Vec3<float> maxPosition;
     bool broadcast;
-    char *message;
+    char* message;
     bool msgDelete;
     int msgLength;
 
@@ -23,13 +23,14 @@ public:
     NetworkResponse();
     ~NetworkResponse();
 
-    void adressChunck( Chunk *zChunk );
-    void adressEntity( Entity *zEntity );
-    void adressBlock( Block *zBlock );
-    void setMessage( char *msg, int length, bool deleteMsg );
+    void adressChunck( Chunk* zChunk );
+    void adressEntity( Entity* zEntity );
+    void adressBlock( Block* zBlock );
+    void setMessage( char* msg, int length, bool deleteMsg );
     void sendToAll();
 
     bool isAreaAffected( Framework::Vec3<float> min, Framework::Vec3<float> max ) const;
-    void writeTo( Framework::StreamWriter *zWriter ) const;
+    void writeTo( Framework::StreamWriter* zWriter ) const;
     bool isBroadcast() const;
+    bool isEmpty() const;
 };

+ 67 - 0
FactoryCraft/NoBlock.cpp

@@ -0,0 +1,67 @@
+#include "NoBlock.h"
+
+NoBlock::NoBlock()
+    : Block( NoBlockBlockType::INSTANCE, 0, { 0,0,0 }, false )
+{
+    transparent = 1;
+    passable = 1;
+    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 )
+{}
+
+NoBlockBlockType::NoBlockBlockType( int id )
+    : BlockType( id )
+{}
+
+Block* NoBlockBlockType::createBlock( Framework::Vec3<int> position, Game* zTarget )
+{
+    return 0;
+}
+
+Item* NoBlockBlockType::createItem( Game* zTarget )
+{
+    return 0;
+}
+
+Block* NoBlockBlockType::loadBlock( Framework::Vec3<int> position, Game* zTarget, Framework::StreamReader* zReader )
+{
+    return 0;
+}
+
+void NoBlockBlockType::saveBlock( Block* zBlock, Framework::StreamWriter* zWriter )
+{}
+
+Item* NoBlockBlockType::getItemFromBlock( Block* zBlock, Game* zTarget )
+{
+    return 0;
+}
+
+Block* NoBlockBlockType::createBlockAt( Framework::Vec3<int> position, Game* zTarget, Item* zUsedItem )
+{
+    return 0;
+}
+
+const Block* NoBlockBlockType::zDefault()
+{
+    return &NoBlock::INSTANCE;
+}
+
+
+AirBlockBlockType::AirBlockBlockType()
+    : NoBlockBlockType( ID )
+{}

+ 46 - 0
FactoryCraft/NoBlock.h

@@ -0,0 +1,46 @@
+#pragma once
+
+#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;
+
+    friend NoBlockBlockType;
+};
+
+class NoBlockBlockType : public BlockType
+{
+    REGISTRABLE( NoBlockBlockType )
+
+protected:
+    virtual Block* createBlock( Framework::Vec3<int> position, Game* zTarget ) override;
+    virtual Item* createItem( Game* zTarget ) override;
+    virtual Block* loadBlock( Framework::Vec3<int> position, Game* zTarget, Framework::StreamReader* zReader ) override;
+    virtual void saveBlock( Block* zBlock, Framework::StreamWriter* zWriter ) override;
+    virtual Item* getItemFromBlock( Block* zBlock, Game* zTarget ) override;
+    virtual Block* createBlockAt( Framework::Vec3<int> position, Game* zTarget, Item* zUsedItem ) override;
+    virtual const Block* zDefault() override;
+    NoBlockBlockType();
+    NoBlockBlockType( int id );
+};
+REGISTER( NoBlockBlockType, BlockType )
+
+class AirBlockBlockType : public NoBlockBlockType
+{
+    REGISTRABLE( AirBlockBlockType )
+
+protected:
+    AirBlockBlockType();
+};
+REGISTER( AirBlockBlockType, BlockType )

+ 1 - 1
FactoryCraft/Noise.cpp

@@ -5,7 +5,7 @@ Noise::Noise()
     : Framework::ReferenceCounter()
 {}
 
-double Noise::getNoise( Framework::Vec3<double> &pos ) const
+double Noise::getNoise( Framework::Vec3<double>& pos ) const
 {
     return getNoise( pos.x, pos.y, pos.z );
 }

+ 1 - 1
FactoryCraft/Noise.h

@@ -16,5 +16,5 @@ public:
     /// <param name="z">the z coord of the noice value</param>
     /// <returns>the noise value scaled to a range from 0 to 1</returns>
     virtual double getNoise( double x, double y, double z ) const = 0;
-    double getNoise( Framework::Vec3<double> &pos ) const;
+    double getNoise( Framework::Vec3<double>& pos ) const;
 };

+ 5 - 5
FactoryCraft/PerlinNoise.cpp

@@ -37,7 +37,7 @@ double PerlinNoise::getNoise( double x, double y, double z ) const
     double u = fade( x );
     double v = fade( y );
     double w = fade( z );
-    
+
     // Hash coordinates of the 8 cube corners
     int A = p[ X ] + Y;
     int AA = p[ A ] + Z;
@@ -49,17 +49,17 @@ double PerlinNoise::getNoise( double x, double y, double z ) const
     // Add blended results from 8 corners of cube
     double res = lerp( w, lerp( v, lerp( u, grad( p[ AA ], x, y, z ), grad( p[ BA ], x - 1, y, z ) ), lerp( u, grad( p[ AB ], x, y - 1, z ), grad( p[ BB ], x - 1, y - 1, z ) ) ), lerp( v, lerp( u, grad( p[ AA + 1 ], x, y, z - 1 ), grad( p[ BA + 1 ], x - 1, y, z - 1 ) ), lerp( u, grad( p[ AB + 1 ], x, y - 1, z - 1 ), grad( p[ BB + 1 ], x - 1, y - 1, z - 1 ) ) ) );
     // TODO: why is res here allways 0?
-    return ( res + 1.0 ) / 2.0;
+    return (res + 1.0) / 2.0;
 }
 
 double PerlinNoise::fade( double t ) const
 {
-    return t * t * t * ( t * ( t * 6 - 15 ) + 10 );
+    return t * t * t * (t * (t * 6 - 15) + 10);
 }
 
 double PerlinNoise::lerp( double t, double a, double b ) const
 {
-    return a + t * ( b - a );
+    return a + t * (b - a);
 }
 
 double PerlinNoise::grad( int hash, double x, double y, double z ) const
@@ -68,5 +68,5 @@ double PerlinNoise::grad( int hash, double x, double y, double z ) const
     // Convert lower 4 bits of hash into 12 gradient directions
     double u = h < 8 ? x : y,
         v = h < 4 ? y : h == 12 || h == 14 ? x : z;
-    return ( ( h & 1 ) == 0 ? u : -u ) + ( ( h & 2 ) == 0 ? v : -v );
+    return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
 }

+ 97 - 6
FactoryCraft/Player.cpp

@@ -12,6 +12,7 @@ Player::Player( Framework::Vec3<float> location, int dimensionId, int entityId )
     maxHunger = 10;
     thirst = 10;
     maxThirst = 10;
+    keyState = 0;
 }
 
 void Player::setName( Framework::Text name )
@@ -19,27 +20,117 @@ void Player::setName( Framework::Text name )
     this->name = name;
 }
 
-const char *Player::getName() const
+const char* Player::getName() const
 {
     return name;
 }
 
-void Player::api( Framework::StreamReader *zRequest, NetworkResponse *zResponse )
+void Player::tick( const Dimension* zDimension, Game* zGame )
 {
-    // TODO: answer API calls
+    if( (keyState | Key::MOVE_FRONT) == keyState )
+        location += {faceDir.x * 0.05f, faceDir.y * 0.05f, 0};
+    if( (keyState | Key::MOVE_BACK) == keyState )
+        location += {-faceDir.x * 0.05f, -faceDir.y * 0.05f, 0};
+    if( (keyState | Key::MOVE_RIGHT) == keyState )
+    {
+        Vec2<float> right = Vec2<float>( faceDir ).CW90();
+        location += {right.x * 0.05f, right.y * 0.05f, 0};
+    }
+    if( (keyState | Key::MOVE_LEFT) == keyState )
+    {
+        Vec2<float> left = Vec2<float>( faceDir ).CCW90();
+        location += {left.x * 0.05f, left.y * 0.05f, 0};
+    }
+    if( (keyState | Key::MOVE_UP) == keyState )
+        location += {0, 0, 0.05f};
+    if( (keyState | Key::MOVE_DOWN) == keyState )
+        location += {0, 0, -0.05f};
+    if( (keyState | Key::ROTATE_LEFT) == keyState )
+        faceDir = faceDir.rotation( -0.05f );
+    if( (keyState | Key::ROTATE_RIGHT) == keyState )
+        faceDir = faceDir.rotation( 0.05f );
+}
+
+void Player::api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
+{
+    char byte;
+    zRequest->lese( &byte, 1 );
+    switch( byte )
+    {
+    case 0:
+        zRequest->lese( &byte, 1 );
+        switch( byte )
+        {
+        case 0:
+            keyState = keyState & ~Key::MOVE_FRONT;
+            break;
+        case 1:
+            keyState = keyState & ~Key::MOVE_LEFT;
+            break;
+        case 2:
+            keyState = keyState & ~Key::MOVE_BACK;
+            break;
+        case 3:
+            keyState = keyState & ~Key::MOVE_RIGHT;
+            break;
+        case 4:
+            keyState = keyState & ~Key::MOVE_UP;
+            break;
+        case 5:
+            keyState = keyState & ~Key::ROTATE_LEFT;
+            break;
+        case 6:
+            keyState = keyState & ~Key::ROTATE_RIGHT;
+            break;
+        case 7:
+            keyState = keyState & ~Key::MOVE_DOWN;
+            break;
+        }
+        break;
+    case 1:
+        zRequest->lese( &byte, 1 );
+        switch( byte )
+        {
+        case 0:
+            keyState = keyState | Key::MOVE_FRONT;
+            break;
+        case 1:
+            keyState = keyState | Key::MOVE_LEFT;
+            break;
+        case 2:
+            keyState = keyState | Key::MOVE_BACK;
+            break;
+        case 3:
+            keyState = keyState | Key::MOVE_RIGHT;
+            break;
+        case 4:
+            keyState = keyState | Key::MOVE_UP;
+            break;
+        case 5:
+            keyState = keyState | Key::ROTATE_LEFT;
+            break;
+        case 6:
+            keyState = keyState | Key::ROTATE_RIGHT;
+            break;
+        case 7:
+            keyState = keyState | Key::MOVE_DOWN;
+            break;
+        }
+        break;
+    }
 }
 
 PlayerEntityType::PlayerEntityType()
     : EntityType( ID )
 {}
 
-void PlayerEntityType::loadSuperEntity( Entity *zEntity, Framework::StreamReader *zReader ) const
+void PlayerEntityType::loadSuperEntity( Entity* zEntity, Framework::StreamReader* zReader ) const
 {}
 
-void PlayerEntityType::saveSuperEntity( Entity *zEntity, Framework::StreamWriter *zWriter ) const
+void PlayerEntityType::saveSuperEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const
 {}
 
-Entity *PlayerEntityType::createEntity( Framework::Vec3<float> position, int dimensionId, Game *zTarget, int entityId ) const
+Entity* PlayerEntityType::createEntity( Framework::Vec3<float> position, int dimensionId, Game* zTarget, int entityId ) const
 {
     return new Player( position, dimensionId, entityId );
 }

+ 20 - 5
FactoryCraft/Player.h

@@ -7,15 +7,30 @@ class PlayerEntityType;
 
 class Player : public Entity
 {
+public:
+    class Key
+    {
+    public:
+        const static __int64 MOVE_FRONT = 0x1;
+        const static __int64 MOVE_BACK = 0x2;
+        const static __int64 MOVE_LEFT = 0x4;
+        const static __int64 MOVE_RIGHT = 0x8;
+        const static __int64 MOVE_UP = 0x10;
+        const static __int64 MOVE_DOWN = 0x20;
+        const static __int64 ROTATE_LEFT = 0x40;
+        const static __int64 ROTATE_RIGHT = 0x80;
+    };
 private:
     Framework::Text name;
+    __int64 keyState;
 
 public:
     Player( Framework::Vec3<float> location, int dimensionId, int entityId );
     void setName( Framework::Text name );
-    const char *getName() const;
+    const char* getName() const;
+    void tick( const Dimension* zDimension, Game* zGame ) override;
 
-    void api( Framework::StreamReader *zRequest, NetworkResponse *zResponse ) override;
+    void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse ) override;
 
     friend PlayerEntityType;
 };
@@ -25,13 +40,13 @@ 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;
+    virtual void loadSuperEntity( Entity* zEntity, Framework::StreamReader* zReader ) const override;
+    virtual void saveSuperEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const override;
 
 public:
     PlayerEntityType();
 
-    virtual Entity *createEntity( Framework::Vec3<float> position, int dimensionId, Game *zTarget, int entityId ) const override;
+    virtual Entity* createEntity( Framework::Vec3<float> position, int dimensionId, Game* zTarget, int entityId ) const override;
 };
 
 REGISTER( PlayerEntityType, EntityType )

+ 26 - 31
FactoryCraft/Server.cpp

@@ -7,15 +7,14 @@
 
 // Inhalt der LoginServer Klasse aus LoginServer.h
 // Konstruktor 
-FactoryCraftServer::FactoryCraftServer( InitDatei *zIni )
+FactoryCraftServer::FactoryCraftServer( InitDatei* zIni )
     : ReferenceCounter()
 {
     Network::Start( 100 );
-    klientAnzahl = 0;
     klients = new RCArray< FCKlient >();
     empfangen = 0;
     gesendet = 0;
-    ini = dynamic_cast<InitDatei *>( zIni->getThis() );
+    ini = dynamic_cast<InitDatei*>(zIni->getThis());
     id = *zIni->zWert( "ServerId" );
     server = new SSLServer();
     server->setPrivateKeyPassword( zIni->zWert( "SSLPasswort" )->getText() );
@@ -49,14 +48,13 @@ void FactoryCraftServer::run()
         std::cout << "Server Port: " << ini->zWert( "SSLPort" )->getText() << "\n";
     while( server->isConnected() )
     {
-        SSLSKlient *klient = server->getKlient();
+        SSLSKlient* klient = server->getKlient();
         if( !klient )
             continue;
         Framework::getThreadRegister()->cleanUpClosedThreads();
-        FCKlient *clHandle = new FCKlient( klient, dynamic_cast<FactoryCraftServer *>( getThis() ) );
+        FCKlient* clHandle = new FCKlient( klient, dynamic_cast<FactoryCraftServer*>(getThis()) );
         EnterCriticalSection( &cs );
-        klients->set( clHandle, klientAnzahl );
-        klientAnzahl++;
+        klients->add( clHandle );
         LeaveCriticalSection( &cs );
         clHandle->start();
     }
@@ -66,10 +64,9 @@ void FactoryCraftServer::close()
 {
     server->trenne();
     EnterCriticalSection( &cs );
-    for( int i = 0; i < klientAnzahl; i++ )
+    for( int i = 0; i < klients->getEintragAnzahl(); i++ )
         klients->z( i )->absturz();
-    klients = ( RCArray< FCKlient > * )klients->release();
-    klientAnzahl = 0;
+    klients = (RCArray< FCKlient > *)klients->release();
     game->save();
     LeaveCriticalSection( &cs );
 }
@@ -78,13 +75,12 @@ bool FactoryCraftServer::absturzKlient( int accountId )
 {
     bool gefunden = 0;
     EnterCriticalSection( &cs );
-    for( int i = 0; i < klientAnzahl; i++ )
+    for( int i = 0; i < klients->getEintragAnzahl(); i++ )
     {
         if( klients->z( i ) && klients->z( i )->getAccountId() == accountId )
         {
             klients->z( i )->absturz();
             klients->remove( i );
-            klientAnzahl--;
             gefunden = 1;
             break;
         }
@@ -93,16 +89,15 @@ bool FactoryCraftServer::absturzKlient( int accountId )
     return gefunden;
 }
 
-bool FactoryCraftServer::removeKlient( FCKlient *zKlient )
+bool FactoryCraftServer::removeKlient( FCKlient* zKlient )
 {
     bool gefunden = 0;
     EnterCriticalSection( &cs );
-    for( int i = 0; i < klientAnzahl; i++ )
+    for( int i = 0; i < klients->getEintragAnzahl(); i++ )
     {
         if( klients->z( i ) == zKlient )
         {
             klients->remove( i );
-            klientAnzahl--;
             gefunden = 1;
             break;
         }
@@ -123,10 +118,10 @@ void FactoryCraftServer::addEmpfangen( int bytes )
 
 bool FactoryCraftServer::hatClients() const
 {
-    return klientAnzahl > 0;
+    return klients->hat( 0 );
 }
 
-Game *FactoryCraftServer::zGame() const
+Game* FactoryCraftServer::zGame() const
 {
     return game;
 }
@@ -134,7 +129,7 @@ Game *FactoryCraftServer::zGame() const
 
 // Inhalt der LSKlient aus LoginServer.h
 // Konstruktor
-FCKlient::FCKlient( SSLSKlient *klient, FactoryCraftServer *ls )
+FCKlient::FCKlient( SSLSKlient* klient, FactoryCraftServer* ls )
     : Thread()
 {
     this->klient = klient;
@@ -150,7 +145,7 @@ FCKlient::~FCKlient()
     if( zGameClient )
     {
         zGameClient->logout();
-        zGameClient = (GameClient *)zGameClient->release();
+        zGameClient = (GameClient*)zGameClient->release();
     }
     delete reader;
     delete writer;
@@ -180,10 +175,10 @@ void FCKlient::thread()
             case 1: // Klient identifikation
             {
                 int accountId = 0;
-                klient->getNachricht( (char *)&accountId, 4 );
+                klient->getNachricht( (char*)&accountId, 4 );
                 unsigned char secretLength = 0;
-                klient->getNachricht( (char *)&secretLength, 1 );
-                char *secret = new char[ secretLength + 1 ];
+                klient->getNachricht( (char*)&secretLength, 1 );
+                char* secret = new char[ secretLength + 1 ];
                 klient->getNachricht( secret, (int)secretLength );
                 secret[ secretLength ] = 0;
                 Text data = "{\"account_id\":";
@@ -192,25 +187,25 @@ void FCKlient::thread()
                 data += secret;
                 data += "\"}";
                 bool ok = false;
-                HTTP::Answer *answer = HTTP::PostRequest( "/game_client/api/verify_client.php", "koljastrohm-games.com", data, "application/json", 443, true ).execute();
+                HTTP::Answer* answer = HTTP::PostRequest( "/game_client/api/verify_client.php", "koljastrohm-games.com", data, "application/json", 443, true ).execute();
                 if( answer->getStatusCode() == 200 )
                 {
                     JSON::JSONObject obj( answer->getData() );
                     if( obj.hasValue( "verified" ) )
                     {
-                        JSON::JSONValue *value = obj.getValue( "verified" );
-                        if( value->getType() == JSON::BOOLEAN )
+                        JSON::JSONValue* value = obj.getValue( "verified" );
+                        if( value->getType() == JSON::JSONType::BOOLEAN )
                         {
-                            if( ( (JSON::JSONBool *)value )->getBool() )
+                            if( ((JSON::JSONBool*)value)->getBool() )
                             {
                                 this->accountId = accountId;
                                 if( zGameClient )
                                 {
                                     zGameClient->logout();
-                                    zGameClient = (GameClient *)zGameClient->release();
+                                    zGameClient = (GameClient*)zGameClient->release();
                                 }
                                 klient->sende( "\1", 1 );
-                                zGameClient = ls->zGame()->addPlayer( dynamic_cast<FCKlient *>( getThis() ), Text( accountId ) );
+                                zGameClient = ls->zGame()->addPlayer( dynamic_cast<FCKlient*>(getThis()), Text( accountId ) );
                                 ok = true;
                             }
                         }
@@ -228,7 +223,7 @@ void FCKlient::thread()
                 if( zGameClient )
                 {
                     zGameClient->logout();
-                    zGameClient = (GameClient *)zGameClient->release();
+                    zGameClient = (GameClient*)zGameClient->release();
                 }
                 klient->sende( "\1", 1 );
                 break;
@@ -253,12 +248,12 @@ int FCKlient::getAccountId() const // gibt die KlientId zur
     return accountId;
 }
 
-SSLSKlient *FCKlient::zClient() const
+SSLSKlient* FCKlient::zClient() const
 {
     return klient;
 }
 
-NetworkWriter *FCKlient::zWriter() const
+NetworkWriter* FCKlient::zWriter() const
 {
     return writer;
 }

+ 15 - 16
FactoryCraft/Server.h

@@ -17,45 +17,44 @@ class GameClient;
 class FactoryCraftServer : virtual public ReferenceCounter
 {
 private:
-    SSLServer *server;
-    InitDatei *ini;
+    SSLServer* server;
+    InitDatei* ini;
     CRITICAL_SECTION cs;
-    RCArray< FCKlient > *klients;
-    Game *game;
-    int klientAnzahl;
+    RCArray< FCKlient >* klients;
+    Game* game;
     int id;
     int empfangen;
     int gesendet;
 
 public:
     // Konstruktor 
-    FactoryCraftServer( InitDatei *zIni );
+    FactoryCraftServer( InitDatei* zIni );
     // Destruktor 
     virtual ~FactoryCraftServer();
     // nicht constant
     void run();
     void close();
     bool absturzKlient( int accountId );
-    bool removeKlient( FCKlient *zKlient );
+    bool removeKlient( FCKlient* zKlient );
     void addGesendet( int bytes );
     void addEmpfangen( int bytes );
     bool hatClients() const;
-    Game *zGame() const;
+    Game* zGame() const;
 };
 
 class FCKlient : public Thread
 {
 private:
-    SSLSKlient *klient;
+    SSLSKlient* klient;
     unsigned int accountId;
-    FactoryCraftServer *ls;
-    GameClient *zGameClient;
-    NetworkReader *reader;
-    NetworkWriter *writer;
+    FactoryCraftServer* ls;
+    GameClient* zGameClient;
+    NetworkReader* reader;
+    NetworkWriter* writer;
 
 public:
     // Konstruktor 
-    FCKlient( SSLSKlient *klient, FactoryCraftServer *ls );
+    FCKlient( SSLSKlient* klient, FactoryCraftServer* ls );
     // Destruktor 
     virtual ~FCKlient();
     // nicht constant 
@@ -63,6 +62,6 @@ public:
     void thread();
     // constant
     int getAccountId() const;
-    SSLSKlient *zClient() const;
-    NetworkWriter *zWriter() const;
+    SSLSKlient* zClient() const;
+    NetworkWriter* zWriter() const;
 };

+ 7 - 7
FactoryCraft/Start.cpp

@@ -11,7 +11,7 @@
 
 #include "Server.h"
 
-FactoryCraftServer *mserver = 0;
+FactoryCraftServer* mserver = 0;
 
 void exit()
 {
@@ -27,21 +27,21 @@ int main()
     setrlimit( RLIMIT_CORE, &core_limits );
 
     Framework::initFramework();
-    Zeit *z = getZeit();
-    Text *pfad = new Text( "log/" );
+    Zeit* z = getZeit();
+    Text* pfad = new Text( "log/" );
     pfad->append( z->getZeit( "y-m-d_h-i-s.log" ) );
     z->release();
     DateiPfadErstellen( pfad->getText() );
     std::ofstream file;
     file.open( pfad->getText() );
-    std::streambuf *sbuf = std::cout.rdbuf();
+    std::streambuf* sbuf = std::cout.rdbuf();
     //std::cout.rdbuf( file.rdbuf() );
     pfad->release();
 
     std::cout << "Startet...\n";
     std::cout << "Lese init Datei fcInit.ini ...\n";
 
-    InitDatei *dat = new InitDatei( "fcInit.ini" );
+    InitDatei* dat = new InitDatei( "fcInit.ini" );
     if( !dat->laden() )
     {
         std::cout << "error: Datei konnte nicht gelesen werden. Das Programm wird geschlossen.\n";
@@ -50,8 +50,8 @@ int main()
         std::cout.rdbuf( sbuf );
         exit( 1 );
     }
-    const char *wichtig[] = { "SSLPort", "SSLCert", "SSLKey", "SSLPasswort" };
-    for( const char *w : wichtig )
+    const char* wichtig[] = { "SSLPort", "SSLCert", "SSLKey", "SSLPasswort" };
+    for( const char* w : wichtig )
     {
         if( !dat->wertExistiert( w ) )
         {

+ 1 - 0
FactoryCraft/StaticInitializerOrder.cpp

@@ -13,6 +13,7 @@ int count_EntityType = 0;
 const int c::ID = count_##typ++;       \
 const c *c::INSTANCE = new c(); 
 
+#include "NoBlock.h" // must be first
 #include "BasicBlocks.h"
 #include "OverworldDimension.h"
 #include "AddChunkUpdate.h"

+ 7 - 7
FactoryCraft/StaticRegistry.h

@@ -17,14 +17,14 @@ public:
     static StaticRegistry<T> INSTANCE;
 
 private:
-    T **registry;
+    T** registry;
     int count;
 
     StaticRegistry()
     {
         count = 100;
         registry = new T * [ count ];
-        memset( registry, 0, sizeof( T * ) * count );
+        memset( registry, 0, sizeof( T* ) * count );
     }
 
     ~StaticRegistry()
@@ -40,13 +40,13 @@ private:
         delete[]registry;
     }
 
-    void registerT( T *type, int id )
+    void registerT( T* type, int id )
     {
         if( id >= count )
         {
-            T **temp = new T * [ id + 1 ];
-            memcpy( temp, registry, sizeof( T * ) * count );
-            memset( temp + count, 0, sizeof( T * ) * ( id + 1 - count ) );
+            T** temp = new T * [ id + 1 ];
+            memcpy( temp, registry, sizeof( T* ) * count );
+            memset( temp + count, 0, sizeof( T* ) * (id + 1 - count) );
             delete[]registry;
             registry = temp;
             count = id + 1;
@@ -55,7 +55,7 @@ private:
     }
 
 public:
-    T *zElement( int id )
+    T* zElement( int id )
     {
         if( id < 0 || id >= count )
             return 0;

+ 8 - 7
FactoryCraft/TickOrganizer.cpp

@@ -32,25 +32,26 @@ void TickOrganizer::nextTick()
     do
     {
         queue->waitForEmpty();
-        for (int i = 0; i < workerCount; i++)
-            notWaiting |= !workers[i]->isWaiting();
-    } while (notWaiting);
+        for( int i = 0; i < workerCount; i++ )
+            notWaiting |= !workers[ i ]->isWaiting();
+    } while( notWaiting );
 }
 
-void TickOrganizer::addTickSource( Block *zBlock )
+void TickOrganizer::addTickSource( Block* zBlock )
 {
     tickSources.add( zBlock );
 }
 
-void TickOrganizer::removeTickSource( Block *zBlock )
+void TickOrganizer::removeTickSource( Block* zBlock )
 {
     int index = 0;
-    for( Framework::Iterator<Block *> it = tickSources.getIterator(); it; it++, index++ )
+    for( Block* block : tickSources )
     {
-        if( it == zBlock )
+        if( block == zBlock )
         {
             tickSources.remove( index );
             return;
         }
+        index++;
     }
 }

+ 5 - 5
FactoryCraft/TickOrganizer.h

@@ -8,9 +8,9 @@ class TickOrganizer : public virtual Framework::ReferenceCounter
 {
 private:
     int workerCount;
-    TickWorker **workers;
-    Framework::Array<Block *> tickSources;
-    TickQueue *queue;
+    TickWorker** workers;
+    Framework::Array<Block*> tickSources;
+    TickQueue* queue;
 
 public:
     TickOrganizer();
@@ -18,6 +18,6 @@ public:
 
     void nextTick();
 
-    void addTickSource( Block *zBlock );
-    void removeTickSource( Block *zBlock );
+    void addTickSource( Block* zBlock );
+    void removeTickSource( Block* zBlock );
 };

+ 11 - 11
FactoryCraft/TickQueue.cpp

@@ -16,7 +16,7 @@ TickQueue::~TickQueue()
     delete[] queue;
 }
 
-void TickQueue::startNextTick( Framework::Array<Block *> *zSources )
+void TickQueue::startNextTick( Framework::Array<Block*>* zSources )
 {
     std::unique_lock<std::mutex> lk( mutex );
     readPosition = 0;
@@ -24,27 +24,27 @@ void TickQueue::startNextTick( Framework::Array<Block *> *zSources )
     int count = zSources->getEintragAnzahl();
     if( count >= maxSize )
     {
-        Block **temp = new Block * [ count + 1000 ];
-        memcpy( queue, temp, sizeof( Block * ) * maxSize );
-        memset( temp + sizeof( Block * ) * maxSize, 0, sizeof( Block * ) * ( count + 1000 - maxSize ) );
+        Block** temp = new Block * [ count + 1000 ];
+        memcpy( queue, temp, sizeof( Block* ) * maxSize );
+        memset( temp + sizeof( Block* ) * maxSize, 0, sizeof( Block* ) * (count + 1000 - maxSize) );
         maxSize = count + 1000;
         delete[]queue;
         queue = temp;
     }
-    for( Framework::Iterator<Block *> it = zSources->getIterator(); it; it++ )
-        queue[ writePosition++ ] = it;
+    for( Block* block : *zSources )
+        queue[ writePosition++ ] = block;
     lk.unlock();
     hasBlocks.notify_all();
 }
 
-void TickQueue::addToQueue( Block *zBlock )
+void TickQueue::addToQueue( Block* zBlock )
 {
     std::unique_lock<std::mutex> lk( mutex );
     if( writePosition >= maxSize )
     {
-        Block **temp = new Block * [ maxSize + 1000 ];
-        memcpy( queue, temp, sizeof( Block * ) * maxSize );
-        memset( temp + sizeof( Block * ) * maxSize, 0, sizeof( Block * ) * 1000 );
+        Block** temp = new Block * [ maxSize + 1000 ];
+        memcpy( queue, temp, sizeof( Block* ) * maxSize );
+        memset( temp + sizeof( Block* ) * maxSize, 0, sizeof( Block* ) * 1000 );
         maxSize += 1000;
         delete[]queue;
         queue = temp;
@@ -54,7 +54,7 @@ void TickQueue::addToQueue( Block *zBlock )
     hasBlocks.notify_one();
 }
 
-Block *TickQueue::zNextBlock( bool &waiting )
+Block* TickQueue::zNextBlock( bool& waiting )
 {
     std::unique_lock<std::mutex> lk( mutex );
     if( readPosition == writePosition && exit )

+ 4 - 4
FactoryCraft/TickQueue.h

@@ -12,7 +12,7 @@ private:
     int maxSize;
     int readPosition;
     int writePosition;
-    Block **queue;
+    Block** queue;
     std::mutex mutex;
     std::condition_variable hasBlocks;
     std::condition_variable hasNoBlocks;
@@ -22,9 +22,9 @@ public:
     TickQueue();
     ~TickQueue();
 
-    void startNextTick( Framework::Array<Block *> *zSources );
-    void addToQueue( Block *zBlock );
-    Block *zNextBlock( bool &waiting );
+    void startNextTick( Framework::Array<Block*>* zSources );
+    void addToQueue( Block* zBlock );
+    Block* zNextBlock( bool& waiting );
     void requestExit();
     void waitForEmpty();
 };

+ 2 - 2
FactoryCraft/TickWorker.cpp

@@ -2,7 +2,7 @@
 #include "Block.h"
 
 
-TickWorker::TickWorker( TickQueue *queue )
+TickWorker::TickWorker( TickQueue* queue )
     : Thread(),
     queue( queue ),
     waiting( 0 )
@@ -17,7 +17,7 @@ TickWorker::~TickWorker()
 
 void TickWorker::thread()
 {
-    Block *zTickBlock = queue->zNextBlock( waiting );
+    Block* zTickBlock = queue->zNextBlock( waiting );
     while( zTickBlock )
     {
         zTickBlock->tick( queue );

+ 2 - 2
FactoryCraft/TickWorker.h

@@ -7,11 +7,11 @@
 class TickWorker : public Framework::Thread
 {
 private:
-    TickQueue *queue;
+    TickQueue* queue;
     bool waiting;
 
 public:
-    TickWorker( TickQueue *queue );
+    TickWorker( TickQueue* queue );
     ~TickWorker();
 
     void thread() override;

+ 9 - 4
FactoryCraft/WorldGenerator.cpp

@@ -6,7 +6,7 @@
 
 using namespace Framework;
 
-WorldGenerator::WorldGenerator( int seed, Game *zGame )
+WorldGenerator::WorldGenerator( int seed, Game* zGame )
     : Thread(),
     zGame( zGame ),
     noise( new PerlinNoise( seed ) ),
@@ -41,15 +41,15 @@ void WorldGenerator::thread()
         }
         Punkt start = zGame->getChunkCenter( next.startX, next.startY );
         Punkt end = zGame->getChunkCenter( next.endX, next.endY );
-        int xDir = start.x > end.x ? -1 : ( start.x < end.x ? 1 : 0 );
-        int yDir = start.y > end.y ? -1 : ( start.y < end.y ? 1 : 0 );
+        int xDir = start.x > end.x ? -1 : (start.x < end.x ? 1 : 0);
+        int yDir = start.y > end.y ? -1 : (start.y < end.y ? 1 : 0);
         for( int x = start.x; x != end.x; x += CHUNK_SIZE * xDir )
         {
             for( int y = start.y; y != end.y; y += CHUNK_SIZE * yDir )
             {
                 if( !zGame->doesChunkExist( x, y, next.dimensionId ) )
                 {
-                    Chunk *generatedChunk = StaticRegistry<DimensionGenerator>::INSTANCE.zElement( next.dimensionId )->generateChunk( noise, zGame, x, y );
+                    Chunk* generatedChunk = StaticRegistry<DimensionGenerator>::INSTANCE.zElement( next.dimensionId )->generateChunk( noise, zGame, x, y );
                     generatedChunk->removeUnusedBlocks();
                     zGame->requestWorldUpdate( new AddChunkUpdate( generatedChunk ) );
                 }
@@ -70,4 +70,9 @@ void WorldGenerator::exitAndWait()
     exit = 1;
     warteAufThread( 10000 );
     ende();
+}
+
+Framework::Either<Block*, int> WorldGenerator::generateSingleBlock( Framework::Vec3<int> location, int dimensionId )
+{
+    return StaticRegistry<DimensionGenerator>::INSTANCE.zElement( dimensionId )->generateBlock( noise, zGame, location );
 }

+ 4 - 3
FactoryCraft/WorldGenerator.h

@@ -12,14 +12,15 @@ class WorldGenerator : public Framework::Thread
 private:
     CriticalSection cs;
     Framework::Array<Area> requestQueue;
-    Game *zGame;
-    Noise *noise;
+    Game* zGame;
+    Noise* noise;
     bool exit;
 
 public:
-    WorldGenerator( int seed, Game *zGame );
+    WorldGenerator( int seed, Game* zGame );
     ~WorldGenerator();
     void thread() override;
     void requestGeneration( Area request );
     void exitAndWait();
+    Framework::Either<Block*, int> generateSingleBlock( Framework::Vec3<int> location, int dimensionId );
 };

+ 9 - 9
FactoryCraft/WorldLoader.cpp

@@ -7,27 +7,27 @@
 
 using namespace Framework;
 
-WorldLoader::WorldLoader( Game *zGame )
+WorldLoader::WorldLoader( Game* zGame )
     : Thread(),
     zGame( zGame ),
     exit( 0 )
 {
     Datei d;
     d.setDatei( zGame->getWorldDirectory() + "/dim" );
-    RCArray<Text> *names = d.getDateiListe();
+    RCArray<Text>* names = d.getDateiListe();
     if( names )
     {
-        for( auto name = names->getIterator(); name; name++ )
+        for( Text* name : *names )
         {
             Datei entities;
             entities.setDatei( zGame->getWorldDirectory() + "/dim/" + Text( name->getText() ) + "/entities" );
             if( entities.open( Datei::Style::lesen ) )
             {
-                Dimension *dim = new Dimension( *name.val() );
+                Dimension* dim = new Dimension( *name );
                 while( !entities.istEnde() )
                 {
                     int type = 0;
-                    entities.lese( (char *)&type, 4 );
+                    entities.lese( (char*)&type, 4 );
                     dim->addEntity( StaticRegistry<EntityType>::INSTANCE.zElement( type )->loadEntity( zGame, &entities ) );
                 }
                 zGame->addDimension( dim );
@@ -62,15 +62,15 @@ void WorldLoader::thread()
         }
         Punkt start = zGame->getChunkCenter( next.startX, next.startY );
         Punkt end = zGame->getChunkCenter( next.endX, next.endY );
-        int xDir = start.x > end.x ? -1 : ( start.x < end.x ? 1 : 0 );
-        int yDir = start.y > end.y ? -1 : ( start.y < end.y ? 1 : 0 );
+        int xDir = start.x > end.x ? -1 : (start.x < end.x ? 1 : 0);
+        int yDir = start.y > end.y ? -1 : (start.y < end.y ? 1 : 0);
         for( int x = start.x; x != end.x; x += CHUNK_SIZE * xDir )
         {
             for( int y = start.y; y != end.y; y += CHUNK_SIZE * yDir )
             {
                 if( !zGame->isChunkLoaded( x, y, next.dimensionId ) )
                 {
-                    Datei *file = new Datei();
+                    Datei* file = new Datei();
                     Text filePath = zGame->getWorldDirectory() + "/dim/" + next.dimensionId + "/";
                     filePath.appendHex( x );
                     filePath += "_";
@@ -79,7 +79,7 @@ void WorldLoader::thread()
                     file->setDatei( filePath );
                     if( file->open( Datei::Style::lesen ) )
                     {
-                        Chunk *chunk = new Chunk( Framework::Punkt( x, y ), zGame, next.dimensionId, file );
+                        Chunk* chunk = new Chunk( Framework::Punkt( x, y ), zGame, next.dimensionId, file );
                         zGame->requestWorldUpdate( new AddChunkUpdate( chunk ) );
                     }
                     file->close();

+ 2 - 2
FactoryCraft/WorldLoader.h

@@ -12,11 +12,11 @@ class WorldLoader : public Framework::Thread
 private:
     CriticalSection cs;
     Framework::Array<Area> requestQueue;
-    Game *zGame;
+    Game* zGame;
     bool exit;
 
 public:
-    WorldLoader( Game *zGame );
+    WorldLoader( Game* zGame );
     ~WorldLoader();
     void thread() override;
     void requestLoading( Area request );

+ 2 - 2
FactoryCraft/WorldUpdate.cpp

@@ -12,12 +12,12 @@ int WorldUpdate::getAffectedDimension() const
     return affectedDimensionId;
 }
 
-const Framework::Vec3<int> &WorldUpdate::getMinAffectedPoint() const
+const Framework::Vec3<int>& WorldUpdate::getMinAffectedPoint() const
 {
     return minAffected;
 }
 
-const Framework::Vec3<int> &WorldUpdate::getMaxAffectedPoint() const
+const Framework::Vec3<int>& WorldUpdate::getMaxAffectedPoint() const
 {
     return maxAffected;
 }

+ 4 - 4
FactoryCraft/WorldUpdate.h

@@ -18,12 +18,12 @@ private:
 public:
     WorldUpdate( int dimensionId, Framework::Vec3<int> minAffected, Framework::Vec3<int> maxAffected );
 
-    virtual void onUpdate( Dimension *zDimension ) = 0;
-    virtual void write( Framework::StreamWriter *zWriter ) = 0;
+    virtual void onUpdate( Dimension* zDimension ) = 0;
+    virtual void write( Framework::StreamWriter* zWriter ) = 0;
 
     int getAffectedDimension() const;
-    const Framework::Vec3<int> &getMinAffectedPoint() const;
-    const Framework::Vec3<int> &getMaxAffectedPoint() const;
+    const Framework::Vec3<int>& getMinAffectedPoint() const;
+    const Framework::Vec3<int>& getMaxAffectedPoint() const;
 };
 
 class WorldUpdateType : public Framework::ReferenceCounter