Эх сурвалжийг харах

remove unneeded information from client

Kolja Strohm 2 жил өмнө
parent
commit
4c3a4b212d
100 өөрчлөгдсөн 5144 нэмэгдсэн , 5131 устгасан
  1. 13 15
      FactoryCraft/AddChunkUpdate.cpp
  2. 9 9
      FactoryCraft/AddChunkUpdate.h
  3. 20 11
      FactoryCraft/AddEntityUpdate.cpp
  4. 8 8
      FactoryCraft/AddEntityUpdate.h
  5. 65 65
      FactoryCraft/Area.cpp
  6. 18 18
      FactoryCraft/Area.h
  7. 26 27
      FactoryCraft/BasicBlock.cpp
  8. 92 93
      FactoryCraft/BasicBlocks.h
  9. 4 4
      FactoryCraft/BiomGenerator.cpp
  10. 7 7
      FactoryCraft/BiomGenerator.h
  11. 9 16
      FactoryCraft/Block.cpp
  12. 1 3
      FactoryCraft/Block.h
  13. 0 54
      FactoryCraft/BlockChangedUpdate.cpp
  14. 0 23
      FactoryCraft/BlockChangedUpdate.h
  15. 10 12
      FactoryCraft/BlockRemovedUpdate.cpp
  16. 7 7
      FactoryCraft/BlockRemovedUpdate.h
  17. 103 84
      FactoryCraft/BlockType.cpp
  18. 24 17
      FactoryCraft/BlockType.h
  19. 396 372
      FactoryCraft/Chunk.cpp
  20. 34 33
      FactoryCraft/Chunk.h
  21. 1 1
      FactoryCraft/Dimension.cpp
  22. 25 25
      FactoryCraft/Dimension.h
  23. 133 133
      FactoryCraft/DimensionGenerator.cpp
  24. 15 15
      FactoryCraft/DimensionGenerator.h
  25. 8 8
      FactoryCraft/Effect.h
  26. 3 3
      FactoryCraft/EffectFactory.h
  27. 19 3
      FactoryCraft/Entity.cpp
  28. 60 58
      FactoryCraft/Entity.h
  29. 0 37
      FactoryCraft/EntityChangedUpdate.cpp
  30. 0 27
      FactoryCraft/EntityChangedUpdate.h
  31. 8 8
      FactoryCraft/EntityRemovedUpdate.cpp
  32. 8 8
      FactoryCraft/EntityRemovedUpdate.h
  33. 66 60
      FactoryCraft/EntityType.cpp
  34. 13 10
      FactoryCraft/EntityType.h
  35. 2 4
      FactoryCraft/FactoryCraft.vcxproj
  36. 6 12
      FactoryCraft/FactoryCraft.vcxproj.filters
  37. 2458 2458
      FactoryCraft/FastNoiseLite.h
  38. 12 12
      FactoryCraft/FastNoiseWrapper.cpp
  39. 8 8
      FactoryCraft/FastNoiseWrapper.h
  40. 41 3
      FactoryCraft/Game.cpp
  41. 1 0
      FactoryCraft/Game.h
  42. 45 45
      FactoryCraft/GeneratedStructure.cpp
  43. 13 13
      FactoryCraft/GeneratedStructure.h
  44. 15 15
      FactoryCraft/GenerationTemplate.cpp
  45. 12 12
      FactoryCraft/GenerationTemplate.h
  46. 20 20
      FactoryCraft/GrasslandBiom.cpp
  47. 6 6
      FactoryCraft/GrasslandBiom.h
  48. 1 0
      FactoryCraft/Inventory.h
  49. 47 47
      FactoryCraft/Item.cpp
  50. 14 7
      FactoryCraft/ItemEntity.cpp
  51. 2 1
      FactoryCraft/ItemEntity.h
  52. 16 16
      FactoryCraft/ItemFilter.cpp
  53. 12 12
      FactoryCraft/ItemFilter.h
  54. 16 16
      FactoryCraft/ItemSkill.cpp
  55. 18 18
      FactoryCraft/ItemSkill.h
  56. 40 40
      FactoryCraft/ItemStack.cpp
  57. 15 15
      FactoryCraft/ItemStack.h
  58. 8 2
      FactoryCraft/ItemType.cpp
  59. 4 1
      FactoryCraft/ItemType.h
  60. 32 0
      FactoryCraft/ModelInfo.cpp
  61. 18 0
      FactoryCraft/ModelInfo.h
  62. 18 17
      FactoryCraft/NetworkResponse.cpp
  63. 2 1
      FactoryCraft/NetworkResponse.h
  64. 32 32
      FactoryCraft/NoBlock.cpp
  65. 23 23
      FactoryCraft/NoBlock.h
  66. 3 3
      FactoryCraft/Noise.cpp
  67. 11 11
      FactoryCraft/Noise.h
  68. 28 28
      FactoryCraft/NoiseInterpolator.cpp
  69. 8 8
      FactoryCraft/NoiseInterpolator.h
  70. 8 8
      FactoryCraft/OverworldDimension.h
  71. 18 31
      FactoryCraft/PlaceBlockUpdate.cpp
  72. 9 9
      FactoryCraft/PlaceBlockUpdate.h
  73. 3 3
      FactoryCraft/Player.cpp
  74. 1 1
      FactoryCraft/PlayerHand.cpp
  75. 12 12
      FactoryCraft/PlayerHand.h
  76. 17 17
      FactoryCraft/RandNoise.cpp
  77. 6 6
      FactoryCraft/RandNoise.h
  78. 46 46
      FactoryCraft/Recipie.cpp
  79. 20 20
      FactoryCraft/Recipie.h
  80. 22 22
      FactoryCraft/RecipieList.h
  81. 291 288
      FactoryCraft/Server.cpp
  82. 44 44
      FactoryCraft/Server.h
  83. 58 58
      FactoryCraft/Start.cpp
  84. 0 2
      FactoryCraft/StaticInitializerOrder.cpp
  85. 1 8
      FactoryCraft/StaticRegistry.h
  86. 2 2
      FactoryCraft/StoneTool.cpp
  87. 36 36
      FactoryCraft/TickOrganizer.cpp
  88. 9 9
      FactoryCraft/TickOrganizer.h
  89. 63 63
      FactoryCraft/TickQueue.cpp
  90. 15 15
      FactoryCraft/TickQueue.h
  91. 13 13
      FactoryCraft/TickWorker.cpp
  92. 6 6
      FactoryCraft/TickWorker.h
  93. 33 33
      FactoryCraft/TreeTemplate.cpp
  94. 6 6
      FactoryCraft/TreeTemplate.h
  95. 49 49
      FactoryCraft/WorldGenerator.cpp
  96. 10 10
      FactoryCraft/WorldGenerator.h
  97. 86 86
      FactoryCraft/WorldLoader.cpp
  98. 9 9
      FactoryCraft/WorldLoader.h
  99. 25 25
      FactoryCraft/WorldUpdate.cpp
  100. 14 14
      FactoryCraft/WorldUpdate.h

+ 13 - 15
FactoryCraft/AddChunkUpdate.cpp

@@ -4,37 +4,35 @@
 #include "Dimension.h"
 
 
-AddChunkUpdate::AddChunkUpdate( Chunk* chunk )
-    : WorldUpdate( AddChunkUpdateType::ID, 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 - 1, chunk->getCenter().y + CHUNK_SIZE / 2 - 1, WORLD_HEIGHT - 1 ) ),
-    chunk( chunk )
+AddChunkUpdate::AddChunkUpdate(Chunk* chunk)
+	: WorldUpdate(AddChunkUpdateType::ID, 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 - 1, chunk->getCenter().y + CHUNK_SIZE / 2 - 1, WORLD_HEIGHT - 1)),
+	chunk(chunk)
 {}
 
 AddChunkUpdate::~AddChunkUpdate()
 {
-    chunk->release();
+	chunk->release();
 }
 
-void AddChunkUpdate::onUpdate( Dimension* zDimension )
+void AddChunkUpdate::onUpdate(Dimension* zDimension)
 {
-    zDimension->setChunk( dynamic_cast<Chunk*>(chunk->getThis()), chunk->getCenter() );
+	zDimension->setChunk(dynamic_cast<Chunk*>(chunk->getThis()), chunk->getCenter());
 }
 
-void AddChunkUpdate::write( Framework::StreamWriter* zWriter )
+void AddChunkUpdate::write(Framework::StreamWriter* zWriter)
 {
-    int dimensionID = chunk->getDimensionId();
-    zWriter->schreibe( (char*)&dimensionID, 4 );
-    Framework::Punkt center = chunk->getCenter();
-    zWriter->schreibe( (char*)&center.x, 4 );
-    zWriter->schreibe( (char*)&center.y, 4 );
-    chunk->save( zWriter, StreamTarget::CLIENT );
+	Framework::Punkt center = chunk->getCenter();
+	zWriter->schreibe((char*)&center.x, 4);
+	zWriter->schreibe((char*)&center.y, 4);
+	chunk->sendToClient(zWriter);
 }
 
 Chunk* AddChunkUpdate::zChunk() const
 {
-    return chunk;
+	return chunk;
 }
 
 
 AddChunkUpdateType::AddChunkUpdateType()
-    : WorldUpdateType( ID )
+	: WorldUpdateType(ID)
 {}

+ 9 - 9
FactoryCraft/AddChunkUpdate.h

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

+ 20 - 11
FactoryCraft/AddEntityUpdate.cpp

@@ -4,30 +4,39 @@
 #include "StaticRegistry.h"
 
 
-AddEntityUpdate::AddEntityUpdate( Entity* entity, int dimension )
-    : WorldUpdate( AddEntityUpdateType::ID, dimension, entity->getPosition(), entity->getPosition() ),
-    entity( entity )
+AddEntityUpdate::AddEntityUpdate(Entity* entity, int dimension)
+	: WorldUpdate(AddEntityUpdateType::ID, dimension, entity->getPosition(), entity->getPosition()),
+	entity(entity)
 {}
 
 AddEntityUpdate::~AddEntityUpdate()
 {
-    entity->release();
+	entity->release();
 }
 
 
-void AddEntityUpdate::onUpdate( Dimension* zDimension )
+void AddEntityUpdate::onUpdate(Dimension* zDimension)
 {
-    zDimension->addEntity( dynamic_cast<Entity*>(entity->getThis()) );
+	zDimension->addEntity(dynamic_cast<Entity*>(entity->getThis()));
 }
 
-void AddEntityUpdate::write( Framework::StreamWriter* zWriter )
+void AddEntityUpdate::write(Framework::StreamWriter* zWriter)
 {
-    int id = entity->zType()->getId();
-    zWriter->schreibe( (char*)&id, 4 );
-    StaticRegistry<EntityType>::INSTANCE.zElement( id )->saveEntity( entity, zWriter );
+	int id = entity->zType()->getId();
+	zWriter->schreibe((char*)&id, 4);
+	id = entity->getId();
+	zWriter->schreibe((char*)&id, 4);
+	Framework::Vec3<float> pos = entity->getPosition();
+	zWriter->schreibe((char*)&pos.x, 4);
+	zWriter->schreibe((char*)&pos.y, 4);
+	zWriter->schreibe((char*)&pos.z, 4);
+	bool special = !entity->hasDefaultModel();
+	zWriter->schreibe((char*)&special, 1);
+	if (special)
+		entity->getSpecialModel().writeTo(zWriter);
 }
 
 
 AddEntityUpdateType::AddEntityUpdateType()
-    : WorldUpdateType( ID )
+	: WorldUpdateType(ID)
 {}

+ 8 - 8
FactoryCraft/AddEntityUpdate.h

@@ -5,23 +5,23 @@
 class AddEntityUpdate : public WorldUpdate
 {
 private:
-    Entity* entity;
+	Entity* entity;
 
 protected:
-    void write( Framework::StreamWriter* zWriter ) override;
+	void write(Framework::StreamWriter* zWriter) override;
 
 public:
-    AddEntityUpdate( Entity* entity, int dimension );
-    ~AddEntityUpdate();
+	AddEntityUpdate(Entity* entity, int dimension);
+	~AddEntityUpdate();
 
-    void onUpdate( Dimension* zDimension ) override;
+	void onUpdate(Dimension* zDimension) override;
 };
 
 class AddEntityUpdateType : WorldUpdateType
 {
-    REGISTRABLE( AddEntityUpdateType )
+	REGISTRABLE(AddEntityUpdateType)
 
 protected:
-    AddEntityUpdateType();
+	AddEntityUpdateType();
 };
-REGISTER( AddEntityUpdateType, WorldUpdateType )
+REGISTER(AddEntityUpdateType, WorldUpdateType)

+ 65 - 65
FactoryCraft/Area.cpp

@@ -1,81 +1,81 @@
 #include "Area.h"
 
-Direction getOppositeDirection( Direction dir )
+Direction getOppositeDirection(Direction dir)
 {
-    switch( dir )
-    {
-    case NORTH:
-        return SOUTH;
-    case EAST:
-        return WEST;
-    case SOUTH:
-        return NORTH;
-    case WEST:
-        return EAST;
-    case TOP:
-        return BOTTOM;
-    case BOTTOM:
-        return TOP;
-    default:
-        return NO_DIRECTION;
-    }
+	switch (dir)
+	{
+	case NORTH:
+		return SOUTH;
+	case EAST:
+		return WEST;
+	case SOUTH:
+		return NORTH;
+	case WEST:
+		return EAST;
+	case TOP:
+		return BOTTOM;
+	case BOTTOM:
+		return TOP;
+	default:
+		return NO_DIRECTION;
+	}
 }
 
-Directions getDirections( Framework::Vec3<float> currentPos, Framework::Vec3<float> otherPos )
+Directions getDirections(Framework::Vec3<float> currentPos, Framework::Vec3<float> otherPos)
 {
-    Directions result = NO_DIRECTION;
-    if( currentPos.x < otherPos.x )
-        result |= EAST;
-    if( currentPos.x > otherPos.x )
-        result |= WEST;
-    if( currentPos.y < otherPos.y )
-        result |= SOUTH;
-    if( currentPos.y > otherPos.y )
-        result |= NORTH;
-    if( currentPos.z < otherPos.z )
-        result |= TOP;
-    if( currentPos.z > otherPos.z )
-        result |= BOTTOM;
-    return result;
+	Directions result = NO_DIRECTION;
+	if (currentPos.x < otherPos.x)
+		result |= EAST;
+	if (currentPos.x > otherPos.x)
+		result |= WEST;
+	if (currentPos.y < otherPos.y)
+		result |= SOUTH;
+	if (currentPos.y > otherPos.y)
+		result |= NORTH;
+	if (currentPos.z < otherPos.z)
+		result |= TOP;
+	if (currentPos.z > otherPos.z)
+		result |= BOTTOM;
+	return result;
 }
 
-Framework::Vec3<int> getDirection( Directions dir )
+Framework::Vec3<int> getDirection(Directions dir)
 {
-    Framework::Vec3<int> result( 0, 0, 0 );
-    if( (dir | NORTH) == dir )
-        --result.y;
-    if( (dir | EAST) == dir )
-        ++result.x;
-    if( (dir | SOUTH) == dir )
-        ++result.y;
-    if( (dir | WEST) == dir )
-        --result.x;
-    if( (dir | TOP) == dir )
-        ++result.z;
-    if( (dir | BOTTOM) == dir )
-        --result.z;
-    return result;
+	Framework::Vec3<int> result(0, 0, 0);
+	if ((dir | NORTH) == dir)
+		--result.y;
+	if ((dir | EAST) == dir)
+		++result.x;
+	if ((dir | SOUTH) == dir)
+		++result.y;
+	if ((dir | WEST) == dir)
+		--result.x;
+	if ((dir | TOP) == dir)
+		++result.z;
+	if ((dir | BOTTOM) == dir)
+		--result.z;
+	return result;
 }
 
-int getDirectionIndex( Direction dir )
+int getDirectionIndex(Direction dir)
 {
-    if( dir == NORTH )
-        return 0;
-    if( dir == EAST )
-        return 1;
-    if( dir == SOUTH )
-        return 2;
-    if( dir == WEST )
-        return 3;
-    if( dir == TOP )
-        return 4;
-    if( dir == BOTTOM )
-        return 5;
-    assert( false );
-    return -1;
+	if (dir == NORTH)
+		return 0;
+	if (dir == EAST)
+		return 1;
+	if (dir == SOUTH)
+		return 2;
+	if (dir == WEST)
+		return 3;
+	if (dir == TOP)
+		return 4;
+	if (dir == BOTTOM)
+		return 5;
+	assert(false);
+	return -1;
 }
 
-Direction getDirectionFromIndex( int index )
+Direction getDirectionFromIndex(int index)
 {
-    return (Direction)(1 << index);
+	return (Direction)(1 << index);
 }

+ 18 - 18
FactoryCraft/Area.h

@@ -4,30 +4,30 @@
 
 struct Area
 {
-    int startX;
-    int startY;
-    int endX;
-    int endY;
-    int dimensionId;
+	int startX;
+	int startY;
+	int endX;
+	int endY;
+	int dimensionId;
 };
 
 enum Direction
 {
-    NO_DIRECTION = 0,
-    NORTH = 1,
-    EAST = 2,
-    SOUTH = 4,
-    WEST = 8,
-    TOP = 16,
-    BOTTOM = 32,
-    INSIDE = 64
+	NO_DIRECTION = 0,
+	NORTH = 1,
+	EAST = 2,
+	SOUTH = 4,
+	WEST = 8,
+	TOP = 16,
+	BOTTOM = 32,
+	INSIDE = 64
 };
 typedef int Directions;
 
 #define ANY_DIRECTION NORTH | EAST | SOUTH | WEST | TOP | BOTTOM
 
-Direction getOppositeDirection( Direction dir );
-Directions getDirections( Framework::Vec3<float> currentPos, Framework::Vec3<float> otherPos );
-Framework::Vec3<int> getDirection( Directions dir );
-int getDirectionIndex( Direction dir );
-Direction getDirectionFromIndex( int index );
+Direction getOppositeDirection(Direction dir);
+Directions getDirections(Framework::Vec3<float> currentPos, Framework::Vec3<float> otherPos);
+Framework::Vec3<int> getDirection(Directions dir);
+int getDirectionIndex(Direction dir);
+Direction getDirectionFromIndex(int index);

+ 26 - 27
FactoryCraft/BasicBlock.cpp

@@ -14,12 +14,11 @@ void BasicBlock::onPostTick()
 {}
 
 
-BasicBlockType::BasicBlockType(int typeId, int itemTypeId)
-	: BlockType(typeId, 0),
+BasicBlockType::BasicBlockType(int typeId, int itemTypeId, ModelInfo model)
+	: BlockType(typeId, 0, model, 1, 100),
 	itemType(itemTypeId),
 	transparent(0),
 	passable(0),
-	maxHp(100.f),
 	hardness(1.f),
 	zTool(0),
 	speedModifier(1.f),
@@ -37,8 +36,8 @@ void BasicBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 			throw "DirtBlockType::createSuperBlock was called with a block witch is not an instance of BasicBlock";
 		block->transparent = transparent;
 		block->passable = passable;
-		block->hp = maxHp;
-		block->maxHP = maxHp;
+		block->hp = (float)getInitialMaxHP();
+		block->maxHP = (float)getInitialMaxHP();
 		block->hardness = hardness;
 		block->zTool = zTool;
 		block->speedModifier = speedModifier;
@@ -58,14 +57,14 @@ Item* BasicBlockType::createItem() const
 
 // Dirt
 DirtBlockType::DirtBlockType()
-	: BasicBlockType(ID, DirtBlockItemType::ID)
+	: BasicBlockType(ID, DirtBlockItemType::ID, ModelInfo("cube", { "blocks.ltdb/dirt.png", "blocks.ltdb/dirt.png", "blocks.ltdb/dirt.png", "blocks.ltdb/dirt.png", "blocks.ltdb/lawn.png", "blocks.ltdb/dirt.png" }))
 {
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
 }
 
 
 DirtBlockItemType::DirtBlockItemType()
-	: BasicBlockItemType(ID, "Dirt", 0, 0)
+	: BasicBlockItemType(ID, "Dirt", 0, 0, ModelInfo("itemCube", "blocks.ltdb/dirt.png", 6))
 {}
 
 Item* DirtBlockItemType::createItem() const
@@ -77,7 +76,7 @@ Item* DirtBlockItemType::createItem() const
 
 // Stone
 StoneBlockType::StoneBlockType()
-	: BasicBlockType(ID, StoneBlockItemType::ID)
+	: BasicBlockType(ID, StoneBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/stone.png", 6))
 {
 	hardness = 2.f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -85,7 +84,7 @@ StoneBlockType::StoneBlockType()
 
 
 StoneBlockItemType::StoneBlockItemType()
-	: BasicBlockItemType(ID, "Stone", 0, 0)
+	: BasicBlockItemType(ID, "Stone", 0, 0, ModelInfo("itemCube", "blocks.ltdb/stone.png", 6))
 {}
 
 Item* StoneBlockItemType::createItem() const
@@ -97,7 +96,7 @@ Item* StoneBlockItemType::createItem() const
 
 // Sand
 SandBlockType::SandBlockType()
-	: BasicBlockType(ID, SandBlockItemType::ID)
+	: BasicBlockType(ID, SandBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/sand.png", 6))
 {
 	hardness = 0.5f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -105,7 +104,7 @@ SandBlockType::SandBlockType()
 
 
 SandBlockItemType::SandBlockItemType()
-	: BasicBlockItemType(ID, "Sand", 0, 0)
+	: BasicBlockItemType(ID, "Sand", 0, 0, ModelInfo("itemCube", "blocks.ltdb/sand.png", 6))
 {}
 
 Item* SandBlockItemType::createItem() const
@@ -117,7 +116,7 @@ Item* SandBlockItemType::createItem() const
 
 // Oak Wood
 OakBlockType::OakBlockType()
-	: BasicBlockType(ID, OakBlockItemType::ID)
+	: BasicBlockType(ID, OakBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/oak.png", 6))
 {
 	hardness = 1.5f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -125,7 +124,7 @@ OakBlockType::OakBlockType()
 
 
 OakBlockItemType::OakBlockItemType()
-	: BasicBlockItemType(ID, "Oak", 0, 0)
+	: BasicBlockItemType(ID, "Oak", 0, 0, ModelInfo("itemCube", "blocks.ltdb/oak.png", 6))
 {}
 
 Item* OakBlockItemType::createItem() const
@@ -137,7 +136,7 @@ Item* OakBlockItemType::createItem() const
 
 // Leaves Wood
 LeavesBlockType::LeavesBlockType()
-	: BasicBlockType(ID, LeavesBlockItemType::ID)
+	: BasicBlockType(ID, LeavesBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/leaves.png", 6))
 {
 	hardness = 0.1f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -145,7 +144,7 @@ LeavesBlockType::LeavesBlockType()
 
 
 LeavesBlockItemType::LeavesBlockItemType()
-	: BasicBlockItemType(ID, "Leaves", 0, 0)
+	: BasicBlockItemType(ID, "Leaves", 0, 0, ModelInfo("itemCube", "blocks.ltdb/leaves.png", 6))
 {}
 
 Item* LeavesBlockItemType::createItem() const
@@ -157,7 +156,7 @@ Item* LeavesBlockItemType::createItem() const
 
 // Gravel
 GravelBlockType::GravelBlockType()
-	: BasicBlockType(ID, GravelBlockItemType::ID)
+	: BasicBlockType(ID, GravelBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/gravel.png", 6))
 {
 	hardness = 0.75f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -165,7 +164,7 @@ GravelBlockType::GravelBlockType()
 
 
 GravelBlockItemType::GravelBlockItemType()
-	: BasicBlockItemType(ID, "Gravel", 0, 0)
+	: BasicBlockItemType(ID, "Gravel", 0, 0, ModelInfo("itemCube", "blocks.ltdb/gravel.png", 6))
 {}
 
 Item* GravelBlockItemType::createItem() const
@@ -177,7 +176,7 @@ Item* GravelBlockItemType::createItem() const
 
 // Granite
 GraniteBlockType::GraniteBlockType()
-	: BasicBlockType(ID, GraniteBlockItemType::ID)
+	: BasicBlockType(ID, GraniteBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/granite.png", 6))
 {
 	hardness = 3.f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -185,7 +184,7 @@ GraniteBlockType::GraniteBlockType()
 
 
 GraniteBlockItemType::GraniteBlockItemType()
-	: BasicBlockItemType(ID, "Granite", 0, 0)
+	: BasicBlockItemType(ID, "Granite", 0, 0, ModelInfo("itemCube", "blocks.ltdb/granite.png", 6))
 {}
 
 Item* GraniteBlockItemType::createItem() const
@@ -197,7 +196,7 @@ Item* GraniteBlockItemType::createItem() const
 
 // Cobble
 CobbleBlockType::CobbleBlockType()
-	: BasicBlockType(ID, CobbleBlockItemType::ID)
+	: BasicBlockType(ID, CobbleBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/cobble.png", 6))
 {
 	hardness = 1.f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -205,7 +204,7 @@ CobbleBlockType::CobbleBlockType()
 
 
 CobbleBlockItemType::CobbleBlockItemType()
-	: BasicBlockItemType(ID, "Cobble", 0, 0)
+	: BasicBlockItemType(ID, "Cobble", 0, 0, ModelInfo("itemCube", "blocks.ltdb/cobble.png", 6))
 {}
 
 Item* CobbleBlockItemType::createItem() const
@@ -217,7 +216,7 @@ Item* CobbleBlockItemType::createItem() const
 
 // Birch Wood
 BirchBlockType::BirchBlockType()
-	: BasicBlockType(ID, BirchBlockItemType::ID)
+	: BasicBlockType(ID, BirchBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/birch.png", 6))
 {
 	hardness = 1.5f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -225,7 +224,7 @@ BirchBlockType::BirchBlockType()
 
 
 BirchBlockItemType::BirchBlockItemType()
-	: BasicBlockItemType(ID, "Birch", 0, 0)
+	: BasicBlockItemType(ID, "Birch", 0, 0, ModelInfo("itemCube", "blocks.ltdb/birch.png", 6))
 {}
 
 Item* BirchBlockItemType::createItem() const
@@ -237,7 +236,7 @@ Item* BirchBlockItemType::createItem() const
 
 // Beech Wood
 BeechBlockType::BeechBlockType()
-	: BasicBlockType(ID, BeechBlockItemType::ID)
+	: BasicBlockType(ID, BeechBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/beech.png", 6))
 {
 	hardness = 1.5f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -245,7 +244,7 @@ BeechBlockType::BeechBlockType()
 
 
 BeechBlockItemType::BeechBlockItemType()
-	: BasicBlockItemType(ID, "Beech", 0, 0)
+	: BasicBlockItemType(ID, "Beech", 0, 0, ModelInfo("itemCube", "blocks.ltdb/beech.png", 6))
 {}
 
 Item* BeechBlockItemType::createItem() const
@@ -257,7 +256,7 @@ Item* BeechBlockItemType::createItem() const
 
 // Basalt
 BasaltBlockType::BasaltBlockType()
-	: BasicBlockType(ID, BasaltBlockItemType::ID)
+	: BasicBlockType(ID, BasaltBlockItemType::ID, ModelInfo("cube", "blocks.ltdb/basalt.png", 6))
 {
 	hardness = 2.f;
 	defaultBlock = createBlockAt({ 0, 0, 0 }, 0);
@@ -265,7 +264,7 @@ BasaltBlockType::BasaltBlockType()
 
 
 BasaltBlockItemType::BasaltBlockItemType()
-	: BasicBlockItemType(ID, "Basalt", 0, 0)
+	: BasicBlockItemType(ID, "Basalt", 0, 0, ModelInfo("itemCube", "blocks.ltdb/basalt.png", 6))
 {}
 
 Item* BasaltBlockItemType::createItem() const

+ 92 - 93
FactoryCraft/BasicBlocks.h

@@ -11,273 +11,272 @@ class BasicBlockType;
 class BasicBlock : public Block
 {
 public:
-    BasicBlock( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos );
-    virtual bool onTick( TickQueue* zQueue, int numTicks, bool& blocked ) override;
-    virtual void onPostTick() override;
+	BasicBlock(const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos);
+	virtual bool onTick(TickQueue* zQueue, int numTicks, bool& blocked) override;
+	virtual void onPostTick() override;
 
-    friend BasicBlockType;
+	friend BasicBlockType;
 };
 
 class BasicBlockType : public BlockType
 {
 private:
-    int itemType;
+	int itemType;
 
 protected:
-    bool transparent;
-    bool passable;
-    float maxHp;
-    float hardness;
-    ItemType* zTool;
-    float speedModifier;
-    bool interactable;
+	bool transparent;
+	bool passable;
+	float hardness;
+	ItemType* zTool;
+	float speedModifier;
+	bool interactable;
 
-    BasicBlockType( int typeId, int itemTypeId );
-    virtual void createSuperBlock( Block* zBlock, Item* zItem ) const override;
+	BasicBlockType(int typeId, int itemTypeId, ModelInfo model);
+	virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
 
 public:
-    virtual Block* createBlock( Framework::Vec3<int> position ) const override;
-    virtual Item* createItem() const override;
+	virtual Block* createBlock(Framework::Vec3<int> position) const override;
+	virtual Item* createItem() const override;
 };
 
 // Dirt
 class DirtBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( DirtBlockItemType )
+	REGISTRABLE(DirtBlockItemType)
 
 protected:
-    DirtBlockItemType();
+	DirtBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( DirtBlockItemType, ItemType )
+REGISTER(DirtBlockItemType, ItemType)
 
 class DirtBlockType : public BasicBlockType
 {
-    REGISTRABLE( DirtBlockType )
+	REGISTRABLE(DirtBlockType)
 
 protected:
-    DirtBlockType();
+	DirtBlockType();
 };
-REGISTER( DirtBlockType, BlockType )
+REGISTER(DirtBlockType, BlockType)
 
 // Stone
 class StoneBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( StoneBlockItemType )
+	REGISTRABLE(StoneBlockItemType)
 
 protected:
-    StoneBlockItemType();
+	StoneBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( StoneBlockItemType, ItemType )
+REGISTER(StoneBlockItemType, ItemType)
 
 class StoneBlockType : public BasicBlockType
 {
-    REGISTRABLE( StoneBlockType )
+	REGISTRABLE(StoneBlockType)
 
 protected:
-    StoneBlockType();
+	StoneBlockType();
 };
-REGISTER( StoneBlockType, BlockType )
+REGISTER(StoneBlockType, BlockType)
 
 // Sand
 class SandBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( SandBlockItemType )
+	REGISTRABLE(SandBlockItemType)
 
 protected:
-    SandBlockItemType();
+	SandBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( SandBlockItemType, ItemType )
+REGISTER(SandBlockItemType, ItemType)
 
 class SandBlockType : public BasicBlockType
 {
-    REGISTRABLE( SandBlockType )
+	REGISTRABLE(SandBlockType)
 
 protected:
-    SandBlockType();
+	SandBlockType();
 };
-REGISTER( SandBlockType, BlockType )
+REGISTER(SandBlockType, BlockType)
 
 // Oak Wood
 class OakBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( OakBlockItemType )
+	REGISTRABLE(OakBlockItemType)
 
 protected:
-    OakBlockItemType();
+	OakBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( OakBlockItemType, ItemType )
+REGISTER(OakBlockItemType, ItemType)
 
 class OakBlockType : public BasicBlockType
 {
-    REGISTRABLE( OakBlockType )
+	REGISTRABLE(OakBlockType)
 
 protected:
-    OakBlockType();
+	OakBlockType();
 };
-REGISTER( OakBlockType, BlockType )
+REGISTER(OakBlockType, BlockType)
 
 // Leaves
 class LeavesBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( LeavesBlockItemType )
+	REGISTRABLE(LeavesBlockItemType)
 
 protected:
-    LeavesBlockItemType();
+	LeavesBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( LeavesBlockItemType, ItemType )
+REGISTER(LeavesBlockItemType, ItemType)
 
 class LeavesBlockType : public BasicBlockType
 {
-    REGISTRABLE( LeavesBlockType )
+	REGISTRABLE(LeavesBlockType)
 
 protected:
-    LeavesBlockType();
+	LeavesBlockType();
 };
-REGISTER( LeavesBlockType, BlockType )
+REGISTER(LeavesBlockType, BlockType)
 
 // Gravel
 class GravelBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( GravelBlockItemType )
+	REGISTRABLE(GravelBlockItemType)
 
 protected:
-    GravelBlockItemType();
+	GravelBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( GravelBlockItemType, ItemType )
+REGISTER(GravelBlockItemType, ItemType)
 
 class GravelBlockType : public BasicBlockType
 {
-    REGISTRABLE( GravelBlockType )
+	REGISTRABLE(GravelBlockType)
 
 protected:
-    GravelBlockType();
+	GravelBlockType();
 };
-REGISTER( GravelBlockType, BlockType )
+REGISTER(GravelBlockType, BlockType)
 
 // Granite
 class GraniteBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( GraniteBlockItemType )
+	REGISTRABLE(GraniteBlockItemType)
 
 protected:
-    GraniteBlockItemType();
+	GraniteBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( GraniteBlockItemType, ItemType )
+REGISTER(GraniteBlockItemType, ItemType)
 
 class GraniteBlockType : public BasicBlockType
 {
-    REGISTRABLE( GraniteBlockType )
+	REGISTRABLE(GraniteBlockType)
 
 protected:
-    GraniteBlockType();
+	GraniteBlockType();
 };
-REGISTER( GraniteBlockType, BlockType )
+REGISTER(GraniteBlockType, BlockType)
 
 // Cobble
 class CobbleBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( CobbleBlockItemType )
+	REGISTRABLE(CobbleBlockItemType)
 
 protected:
-    CobbleBlockItemType();
+	CobbleBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( CobbleBlockItemType, ItemType )
+REGISTER(CobbleBlockItemType, ItemType)
 
 class CobbleBlockType : public BasicBlockType
 {
-    REGISTRABLE( CobbleBlockType )
+	REGISTRABLE(CobbleBlockType)
 
 protected:
-    CobbleBlockType();
+	CobbleBlockType();
 };
-REGISTER( CobbleBlockType, BlockType )
+REGISTER(CobbleBlockType, BlockType)
 
 // Birch Wood
 class BirchBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( BirchBlockItemType )
+	REGISTRABLE(BirchBlockItemType)
 
 protected:
-    BirchBlockItemType();
+	BirchBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( BirchBlockItemType, ItemType )
+REGISTER(BirchBlockItemType, ItemType)
 
 class BirchBlockType : public BasicBlockType
 {
-    REGISTRABLE( BirchBlockType )
+	REGISTRABLE(BirchBlockType)
 
 protected:
-    BirchBlockType();
+	BirchBlockType();
 };
-REGISTER( BirchBlockType, BlockType )
+REGISTER(BirchBlockType, BlockType)
 
 // Beech Wood
 class BeechBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( BeechBlockItemType )
+	REGISTRABLE(BeechBlockItemType)
 
 protected:
-    BeechBlockItemType();
+	BeechBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( BeechBlockItemType, ItemType )
+REGISTER(BeechBlockItemType, ItemType)
 
 class BeechBlockType : public BasicBlockType
 {
-    REGISTRABLE( BeechBlockType )
+	REGISTRABLE(BeechBlockType)
 
 protected:
-    BeechBlockType();
+	BeechBlockType();
 };
-REGISTER( BeechBlockType, BlockType )
+REGISTER(BeechBlockType, BlockType)
 
 // Basalt
 class BasaltBlockItemType : public BasicBlockItemType
 {
-    REGISTRABLE( BasaltBlockItemType )
+	REGISTRABLE(BasaltBlockItemType)
 
 protected:
-    BasaltBlockItemType();
+	BasaltBlockItemType();
 
 public:
-    virtual Item* createItem() const override;
+	virtual Item* createItem() const override;
 };
-REGISTER( BasaltBlockItemType, ItemType )
+REGISTER(BasaltBlockItemType, ItemType)
 
 class BasaltBlockType : public BasicBlockType
 {
-    REGISTRABLE( BasaltBlockType )
+	REGISTRABLE(BasaltBlockType)
 
 protected:
-    BasaltBlockType();
+	BasaltBlockType();
 };
-REGISTER( BasaltBlockType, BlockType )
+REGISTER(BasaltBlockType, BlockType)

+ 4 - 4
FactoryCraft/BiomGenerator.cpp

@@ -2,15 +2,15 @@
 
 
 BiomGenerator::BiomGenerator()
-    : ReferenceCounter()
+	: ReferenceCounter()
 {}
 
-void BiomGenerator::addTemplateGenerator( GenerationTemplate* gTemplate )
+void BiomGenerator::addTemplateGenerator(GenerationTemplate* gTemplate)
 {
-    templates.add( gTemplate );
+	templates.add(gTemplate);
 }
 
 const Framework::RCArray<GenerationTemplate>& BiomGenerator::getTemplates()
 {
-    return templates;
+	return templates;
 }

+ 7 - 7
FactoryCraft/BiomGenerator.h

@@ -11,15 +11,15 @@ class Noise;
 class BiomGenerator : public virtual Framework::ReferenceCounter
 {
 private:
-    Framework::RCArray<GenerationTemplate> templates;
+	Framework::RCArray<GenerationTemplate> templates;
 
 protected:
-    void addTemplateGenerator( GenerationTemplate* gTemplate );
+	void addTemplateGenerator(GenerationTemplate* gTemplate);
 
 public:
-    BiomGenerator();
-    virtual Framework::Either<Block*, int> generateSurfaceBlock( int x, int y, int z ) = 0;
-    virtual Framework::Either<Block*, int> generateBelowSurfaceBlock( int x, int y, int z ) = 0;
-    virtual Noise* zHeightMapNoise( int seed ) = 0;
-    const Framework::RCArray<GenerationTemplate>& getTemplates();
+	BiomGenerator();
+	virtual Framework::Either<Block*, int> generateSurfaceBlock(int x, int y, int z) = 0;
+	virtual Framework::Either<Block*, int> generateBelowSurfaceBlock(int x, int y, int z) = 0;
+	virtual Noise* zHeightMapNoise(int seed) = 0;
+	const Framework::RCArray<GenerationTemplate>& getTemplates();
 };

+ 9 - 16
FactoryCraft/Block.cpp

@@ -2,7 +2,6 @@
 #include "Inventory.h"
 #include "NoBlock.h"
 #include "Game.h"
-#include "BlockChangedUpdate.h"
 #include "PlaceBlockUpdate.h"
 #include "BlockRemovedUpdate.h"
 #include "ItemEntity.h"
@@ -216,20 +215,14 @@ void Block::setHP(float hp)
 		onDestroy();
 	}
 	else
-		requestTransmission();
-}
-
-void Block::onAfterTransmission()
-{
-	transmissionRequested = 0;
-}
-
-void Block::requestTransmission()
-{
-	if (!transmissionRequested)
 	{
-		transmissionRequested = 1;
-		Game::INSTANCE->requestWorldUpdate(new BlockChangedUpdate(getPos(), getDimensionId()));
+		NetworkResponse changeMsg;
+		changeMsg.adressBlock(this);
+		char msg[5];
+		msg[0] = 0; // hp changed
+		*(float*)(msg + 1) = this->hp;
+		changeMsg.setMessage(msg, 5, 0);
+		Game::INSTANCE->distributeResponse(&changeMsg);
 	}
 }
 
@@ -264,8 +257,8 @@ bool BasicBlockItem::canBeStackedWith(Item* zItem) const
 }
 
 
-BasicBlockItemType::BasicBlockItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType)
-	: ItemType(id, name, levelUpRule, zBrokenType)
+BasicBlockItemType::BasicBlockItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType, ModelInfo model)
+	: ItemType(id, name, levelUpRule, zBrokenType, model)
 {}
 
 void BasicBlockItemType::loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const

+ 1 - 3
FactoryCraft/Block.h

@@ -88,8 +88,6 @@ public:
 	int getDimensionId() const;
 	bool isVisible() const;
 	void setHP(float hp);
-	void onAfterTransmission();
-	void requestTransmission();
 	bool isDeadAndRemoved() const;
 
 	friend BlockType;
@@ -118,7 +116,7 @@ public:
 class BasicBlockItemType : public ItemType
 {
 protected:
-	BasicBlockItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType);
+	BasicBlockItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType, ModelInfo model);
 	virtual void loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const override;
 	virtual void saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const override;
 	void initializeItem(BasicBlockItem* zItem, bool transparent, bool passable, float hp, float maxHP, float hardness, int toolId, float speedModifier) const;

+ 0 - 54
FactoryCraft/BlockChangedUpdate.cpp

@@ -1,54 +0,0 @@
-#include "BlockChangedUpdate.h"
-#include "Game.h"
-
-
-BlockChangedUpdate::BlockChangedUpdate( Framework::Vec3<int> pos, int dimension )
-    : WorldUpdate( BlockChangedUpdateType::ID, dimension, pos, pos )
-{}
-
-BlockChangedUpdate::~BlockChangedUpdate()
-{
-    auto b = Game::INSTANCE->zBlockAt( getMinAffectedPoint(), getAffectedDimension() );
-    if( b.isA() && b.getA() )
-        b.getA()->onAfterTransmission();
-}
-
-void BlockChangedUpdate::onUpdate( Dimension* zDimension )
-{}
-
-void BlockChangedUpdate::write( Framework::StreamWriter* zWriter )
-{
-    int dimensionID = getAffectedDimension();
-    zWriter->schreibe( (char*)&dimensionID, 4 );
-    auto pos = getMinAffectedPoint();
-    zWriter->schreibe( (char*)&pos.x, 4 );
-    zWriter->schreibe( (char*)&pos.y, 4 );
-    zWriter->schreibe( (char*)&pos.z, 4 );
-    auto b = Game::INSTANCE->zBlockAt( pos, getAffectedDimension() );
-    unsigned short blockType = b.isA() ? (unsigned short)b.getA()->zBlockType()->getId() : (unsigned short)b.getB();
-    if( b.isA() && b.getA()->isDeadAndRemoved() )
-    {
-        blockType = 0;
-        zWriter->schreibe( (char*)&blockType, 2 );
-    }
-    else
-    {
-        zWriter->schreibe( (char*)&blockType, 2 );
-        if( b.isA() )
-        {
-            bool d = 1;
-            zWriter->schreibe( (char*)&d, 1 );
-            StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->saveBlock( b.getA(), zWriter );
-        }
-        else
-        {
-            bool d = 0;
-            zWriter->schreibe( (char*)&d, 1 );
-        }
-    }
-}
-
-
-BlockChangedUpdateType::BlockChangedUpdateType()
-    : WorldUpdateType( ID )
-{}

+ 0 - 23
FactoryCraft/BlockChangedUpdate.h

@@ -1,23 +0,0 @@
-#pragma once
-#include "WorldUpdate.h"
-
-class BlockChangedUpdate : public WorldUpdate
-{
-protected:
-    void write( Framework::StreamWriter* zWriter ) override;
-
-public:
-    BlockChangedUpdate( Framework::Vec3<int> pos, int dimension );
-    ~BlockChangedUpdate();
-
-    void onUpdate( Dimension* zDimension ) override;
-};
-
-class BlockChangedUpdateType : WorldUpdateType
-{
-    REGISTRABLE( BlockChangedUpdateType )
-
-protected:
-    BlockChangedUpdateType();
-};
-REGISTER( BlockChangedUpdateType, WorldUpdateType )

+ 10 - 12
FactoryCraft/BlockRemovedUpdate.cpp

@@ -3,29 +3,27 @@
 #include "NoBlock.h"
 
 
-BlockRemovedUpdate::BlockRemovedUpdate( Framework::Vec3<int> pos, int dimension )
-    : WorldUpdate( BlockRemovedUpdateType::ID, dimension, pos, pos )
+BlockRemovedUpdate::BlockRemovedUpdate(Framework::Vec3<int> pos, int dimension)
+	: WorldUpdate(BlockRemovedUpdateType::ID, dimension, pos, pos)
 {}
 
 BlockRemovedUpdate::~BlockRemovedUpdate()
 {}
 
-void BlockRemovedUpdate::onUpdate( Dimension* zDimension )
+void BlockRemovedUpdate::onUpdate(Dimension* zDimension)
 {
-    zDimension->placeBlock( getMaxAffectedPoint(), AirBlockBlockType::ID );
+	zDimension->placeBlock(getMaxAffectedPoint(), AirBlockBlockType::ID);
 }
 
-void BlockRemovedUpdate::write( Framework::StreamWriter* zWriter )
+void BlockRemovedUpdate::write(Framework::StreamWriter* zWriter)
 {
-    int dimensionID = getAffectedDimension();
-    zWriter->schreibe( (char*)&dimensionID, 4 );
-    auto pos = getMinAffectedPoint();
-    zWriter->schreibe( (char*)&pos.x, 4 );
-    zWriter->schreibe( (char*)&pos.y, 4 );
-    zWriter->schreibe( (char*)&pos.z, 4 );
+	auto pos = getMinAffectedPoint();
+	zWriter->schreibe((char*)&pos.x, 4);
+	zWriter->schreibe((char*)&pos.y, 4);
+	zWriter->schreibe((char*)&pos.z, 4);
 }
 
 
 BlockRemovedUpdateType::BlockRemovedUpdateType()
-    : WorldUpdateType( ID )
+	: WorldUpdateType(ID)
 {}

+ 7 - 7
FactoryCraft/BlockRemovedUpdate.h

@@ -5,20 +5,20 @@
 class BlockRemovedUpdate : public WorldUpdate
 {
 protected:
-    void write( Framework::StreamWriter* zWriter ) override;
+	void write(Framework::StreamWriter* zWriter) override;
 
 public:
-    BlockRemovedUpdate( Framework::Vec3<int> pos, int dimension );
-    ~BlockRemovedUpdate();
+	BlockRemovedUpdate(Framework::Vec3<int> pos, int dimension);
+	~BlockRemovedUpdate();
 
-    void onUpdate( Dimension* zDimension ) override;
+	void onUpdate(Dimension* zDimension) override;
 };
 
 class BlockRemovedUpdateType : WorldUpdateType
 {
-    REGISTRABLE( BlockRemovedUpdateType )
+	REGISTRABLE(BlockRemovedUpdateType)
 
 protected:
-    BlockRemovedUpdateType();
+	BlockRemovedUpdateType();
 };
-REGISTER( BlockRemovedUpdateType, WorldUpdateType )
+REGISTER(BlockRemovedUpdateType, WorldUpdateType)

+ 103 - 84
FactoryCraft/BlockType.cpp

@@ -5,125 +5,144 @@
 
 using namespace Framework;
 
-BlockType::BlockType( int id, Block* defaultBlock )
-    : ReferenceCounter(),
-    id( id ),
-    defaultBlock( defaultBlock )
+BlockType::BlockType(int id, Block* defaultBlock,
+	ModelInfo model, bool needsClientInstance, int initialMaxHP)
+	: ReferenceCounter(),
+	id(id),
+	model(model),
+	needsClientInstance(needsClientInstance),
+	initialMaxHP(initialMaxHP),
+	defaultBlock(defaultBlock)
 {
-    StaticRegistry<BlockType>::INSTANCE.registerT( this, id );
+	StaticRegistry<BlockType>::INSTANCE.registerT(this, id);
 }
 
 BlockType::~BlockType()
 {
-    if( defaultBlock )
-        defaultBlock->release();
+	if (defaultBlock)
+		defaultBlock->release();
 }
 
-void BlockType::loadSuperBlock( Block* zBlock, Framework::StreamReader* zReader ) const
-{
-    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 );
-    int effectiveToolId;
-    zReader->lese( (char*)&effectiveToolId, 4 );
-    if( effectiveToolId >= 0 )
-        zBlock->zTool = StaticRegistry<ItemType>::INSTANCE.zElement( effectiveToolId );
-    else
-        zBlock->zTool = 0;
+void BlockType::loadSuperBlock(Block* zBlock, Framework::StreamReader* zReader) const
+{
+	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);
+	int 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 ) const
-{
-    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 ? zBlock->zTool->getId() : -1;
-    zWriter->schreibe( (char*)&effectiveToolId, 4 );
+void BlockType::saveSuperBlock(Block* zBlock, Framework::StreamWriter* zWriter) const
+{
+	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 ? zBlock->zTool->getId() : -1;
+	zWriter->schreibe((char*)&effectiveToolId, 4);
 }
 
-void BlockType::createSuperBlock( Block* zBlock, Item* zItem ) const
-{
-    BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
-    if( !item )
-    {
-        throw "BlockType::createSuperBlock was called with an item witch was not an instance of BasicBlockItem";
-    }
-    zBlock->transparent = item->transparent;
-    zBlock->passable = item->passable;
-    zBlock->hp = item->hp;
-    zBlock->maxHP = item->maxHP;
-    zBlock->hardness = item->hardness;
-    zBlock->speedModifier = item->speedModifier;
-    zBlock->zTool = item->toolId >= 0 ? StaticRegistry<ItemType>::INSTANCE.zElement( item->toolId ) : 0;
-    zBlock->interactable = item->interactable;
+void BlockType::createSuperBlock(Block* zBlock, Item* zItem) const
+{
+	BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
+	if (!item)
+	{
+		throw "BlockType::createSuperBlock was called with an item witch was not an instance of BasicBlockItem";
+	}
+	zBlock->transparent = item->transparent;
+	zBlock->passable = item->passable;
+	zBlock->hp = item->hp;
+	zBlock->maxHP = item->maxHP;
+	zBlock->hardness = item->hardness;
+	zBlock->speedModifier = item->speedModifier;
+	zBlock->zTool = item->toolId >= 0 ? StaticRegistry<ItemType>::INSTANCE.zElement(item->toolId) : 0;
+	zBlock->interactable = item->interactable;
 }
 
-void BlockType::createSuperItem( Block* zBlock, Item* zItem ) const
-{
-    BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
-    if( !item )
-    {
-        throw "BlockType::createSuperItem was called with an item witch was not an instance of BasicBlockItem";
-    }
-    item->transparent = zBlock->transparent;
-    item->passable = zBlock->passable;
-    item->hp = zBlock->maxHP; // reset hp
-    item->maxHP = zBlock->maxHP;
-    item->hardness = zBlock->hardness;
-    item->speedModifier = zBlock->speedModifier;
-    item->toolId = zBlock->zTool ? zBlock->zTool->getId() : -1;
-    item->interactable = zBlock->interactable;
+void BlockType::createSuperItem(Block* zBlock, Item* zItem) const
+{
+	BasicBlockItem* item = dynamic_cast<BasicBlockItem*>(zItem);
+	if (!item)
+	{
+		throw "BlockType::createSuperItem was called with an item witch was not an instance of BasicBlockItem";
+	}
+	item->transparent = zBlock->transparent;
+	item->passable = zBlock->passable;
+	item->hp = zBlock->maxHP; // reset hp
+	item->maxHP = zBlock->maxHP;
+	item->hardness = zBlock->hardness;
+	item->speedModifier = zBlock->speedModifier;
+	item->toolId = zBlock->zTool ? zBlock->zTool->getId() : -1;
+	item->interactable = zBlock->interactable;
+}
+
+Block* BlockType::loadBlock(Framework::Vec3<int> position, Framework::StreamReader* zReader) const
+{
+	Block* result = createBlock(position);
+	loadSuperBlock(result, zReader);
+	return result;
 }
 
-Block* BlockType::loadBlock( Framework::Vec3<int> position, Framework::StreamReader* zReader ) const
+void BlockType::saveBlock(Block* zBlock, Framework::StreamWriter* zWriter) const
 {
-    Block* result = createBlock( position );
-    loadSuperBlock( result, zReader );
-    return result;
+	saveSuperBlock(zBlock, zWriter);
 }
 
-void BlockType::saveBlock( Block* zBlock, Framework::StreamWriter* zWriter ) const
+Item* BlockType::getItemFromBlock(Block* zBlock) const
 {
-    saveSuperBlock( zBlock, zWriter );
+	Item* result = createItem();
+	createSuperItem(zBlock, result);
+	return result;
 }
 
-Item* BlockType::getItemFromBlock( Block* zBlock ) const
+Block* BlockType::createBlockAt(Framework::Vec3<int> position, Item* zUsedItem) const
 {
-    Item* result = createItem();
-    createSuperItem( zBlock, result );
-    return result;
+	Block* result = createBlock(position);
+	createSuperBlock(result, zUsedItem);
+	return result;
 }
 
-Block* BlockType::createBlockAt( Framework::Vec3<int> position, Item* zUsedItem ) const
+bool BlockType::doesNeedClientInstance() const
 {
-    Block* result = createBlock( position );
-    createSuperBlock( result, zUsedItem );
-    return result;
+	return needsClientInstance;
+}
+
+const ModelInfo& BlockType::getModel() const
+{
+	return model;
 }
 
 int BlockType::getId() const
 {
-    return id;
+	return id;
 }
 
 const Block* BlockType::zDefault() const
 {
-    return defaultBlock;
+	return defaultBlock;
+}
+
+int BlockType::getInitialMaxHP() const
+{
+	return initialMaxHP;
 }
 
 
-const Block* getDefaultBlock( Either<Block*, int> b )
+const Block* getDefaultBlock(Either<Block*, int> b)
 {
-    if( b.isA() )
-        return b;
-    else
-        return StaticRegistry<BlockType>::INSTANCE.zElement( b )->zDefault();
+	if (b.isA())
+		return b;
+	else
+		return StaticRegistry<BlockType>::INSTANCE.zElement(b)->zDefault();
 }

+ 24 - 17
FactoryCraft/BlockType.h

@@ -6,6 +6,7 @@
 #include <Either.h>
 
 #include "StaticRegistry.h"
+#include "ModelInfo.h"
 
 class Item;
 class Block;
@@ -13,27 +14,33 @@ class Block;
 class BlockType : public virtual Framework::ReferenceCounter
 {
 private:
-    const int id;
+	const int id;
+	const ModelInfo model;
+	int initialMaxHP;
+	const bool needsClientInstance;
 
 protected:
-    Block* defaultBlock;
-    BlockType( int id, Block* defaultBlock );
-    virtual ~BlockType();
+	Block* defaultBlock;
+	BlockType(int id, Block* defaultBlock, ModelInfo model, bool needsClientInstance, int initialMaxHP);
+	virtual ~BlockType();
 
-    virtual void loadSuperBlock( Block* zBlock, Framework::StreamReader* zReader ) const;
-    virtual void saveSuperBlock( Block* zBlock, Framework::StreamWriter* zWriter ) const;
-    virtual void createSuperBlock( Block* zBlock, Item* zItem ) const;
-    virtual void createSuperItem( Block* zBlock, Item* zItem ) const;
-    virtual Block* createBlock( Framework::Vec3<int> position ) const = 0;
-    virtual Item* createItem() const = 0;
+	virtual void loadSuperBlock(Block* zBlock, Framework::StreamReader* zReader) const;
+	virtual void saveSuperBlock(Block* zBlock, Framework::StreamWriter* zWriter) const;
+	virtual void createSuperBlock(Block* zBlock, Item* zItem) const;
+	virtual void createSuperItem(Block* zBlock, Item* zItem) const;
+	virtual Block* createBlock(Framework::Vec3<int> position) const = 0;
+	virtual Item* createItem() const = 0;
 
 public:
-    virtual Block* loadBlock( Framework::Vec3<int> position, Framework::StreamReader* zReader ) const;
-    virtual void saveBlock( Block* zBlock, Framework::StreamWriter* zWriter ) const;
-    virtual Item* getItemFromBlock( Block* zBlock ) const;
-    virtual Block* createBlockAt( Framework::Vec3<int> position, Item* zUsedItem ) const;
-    virtual const Block* zDefault() const;
-    int getId() const;
+	virtual Block* loadBlock(Framework::Vec3<int> position, Framework::StreamReader* zReader) const;
+	virtual void saveBlock(Block* zBlock, Framework::StreamWriter* zWriter) const;
+	virtual Item* getItemFromBlock(Block* zBlock) const;
+	virtual Block* createBlockAt(Framework::Vec3<int> position, Item* zUsedItem) const;
+	virtual const Block* zDefault() const;
+	bool doesNeedClientInstance() const;
+	const ModelInfo& getModel() const;
+	int getId() const;
+	int getInitialMaxHP() const;
 };
 
-const Block* getDefaultBlock( Framework::Either<Block*, int> b );
+const Block* getDefaultBlock(Framework::Either<Block*, int> b);

+ 396 - 372
FactoryCraft/Chunk.cpp

@@ -4,459 +4,483 @@
 #include "NoBlock.h"
 
 
-Chunk::Chunk( Framework::Punkt location, int dimensionId )
-    : ReferenceCounter(),
-    dimensionId( dimensionId ),
-    location( location ),
-    added( 0 )
+Chunk::Chunk(Framework::Punkt location, int dimensionId)
+	: ReferenceCounter(),
+	dimensionId(dimensionId),
+	location(location),
+	added(0)
 {
-    blocks = new Block * [ CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ];
-    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;
+	blocks = new Block * [CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT];
+	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, int dimensionId, Framework::StreamReader* zReader )
-    : Chunk( location, dimensionId )
+Chunk::Chunk(Framework::Punkt location, int dimensionId, Framework::StreamReader* zReader)
+	: Chunk(location, dimensionId)
 {
-    load( zReader );
+	load(zReader);
 }
 
 Chunk::~Chunk()
 {
-    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
-    {
-        if( blocks[ i ] )
-            blocks[ i ]->release();
-    }
-    delete[] blocks;
-    delete[] blockIds;
+	for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
+	{
+		if (blocks[i])
+			blocks[i]->release();
+	}
+	delete[] blocks;
+	delete[] blockIds;
 }
 
-Framework::Either<Block*, int> 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 )
-    {
-        int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
-        if( blocks[ index ] )
-            return blocks[ index ];
-        else
-            return (int)blockIds[ index ];
-    }
-    if( added && location.z >= 0 && location.z < WORLD_HEIGHT )
-        return Game::INSTANCE->zBlockAt( { location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z }, dimensionId );
-    return 0;
+	if (location.x >= 0 && location.x < CHUNK_SIZE && location.y >= 0 && location.y < CHUNK_SIZE && location.z >= 0 && location.z < WORLD_HEIGHT)
+	{
+		int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+		if (blocks[index])
+			return blocks[index];
+		else
+			return (int)blockIds[index];
+	}
+	if (added && location.z >= 0 && location.z < WORLD_HEIGHT)
+		return Game::INSTANCE->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
+	// TODO: answer api messages
 }
 
-Framework::Either<Block*, int> Chunk::zBlockAt( Framework::Vec3<int> location ) const
+Framework::Either<Block*, int> Chunk::zBlockAt(Framework::Vec3<int> location) const
 {
-    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 ];
+	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
+const Block* Chunk::zBlockConst(Framework::Vec3<int> location) const
 {
-    auto b = zBlockAt( location );
-    if( b.isA() )
-        return b;
-    if( b.getB() )
-        return StaticRegistry<BlockType>::INSTANCE.zElement( b.getB() )->zDefault();
-    return 0;
+	auto b = zBlockAt(location);
+	if (b.isA())
+		return b;
+	if (b.getB())
+		return StaticRegistry<BlockType>::INSTANCE.zElement(b.getB())->zDefault();
+	return 0;
 }
 
-void Chunk::instantiateBlock( Framework::Vec3<int> location )
+void Chunk::instantiateBlock(Framework::Vec3<int> location)
 {
-    auto b = zBlockAt( location );
-    if( b.isA() )
-        return;
-    if( !b.getB() )
-        generateBlock( location );
-    b = zBlockAt( location );
-    if( b.isB() )
-        putBlockAt( location, StaticRegistry<BlockType>::INSTANCE.zElement( b.getB() )->createBlockAt( { location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z }, 0 ) );
+	auto b = zBlockAt(location);
+	if (b.isA())
+		return;
+	if (!b.getB())
+		generateBlock(location);
+	b = zBlockAt(location);
+	if (b.isB())
+		putBlockAt(location, StaticRegistry<BlockType>::INSTANCE.zElement(b.getB())->createBlockAt({ location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z }, 0));
 }
 
-void Chunk::generateBlock( Framework::Vec3<int> location )
+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 = Game::INSTANCE->zGenerator()->generateSingleBlock( { location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z }, dimensionId );
-    if( generated.isA() )
-        putBlockAt( location, generated );
-    else
-        putBlockTypeAt( location, generated );
+	int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+	if (blockIds[index])
+		return;
+	auto generated = Game::INSTANCE->zGenerator()->generateSingleBlock({ location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z }, 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 && index >= 0 );
-    Block* old = blocks[ index ];
-    if( block )
-        blockIds[ index ] = (unsigned short)block->zBlockType()->getId();
-    blocks[ index ] = block;
-    Either<Block*, int> neighbor = zBlockNeighbor( location + getDirection( NORTH ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( SOUTH, block );
-    if( block )
-        block->setNeighbour( NORTH, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( EAST ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( WEST, block );
-    if( block )
-        block->setNeighbour( EAST, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( SOUTH ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( NORTH, block );
-    if( block )
-        block->setNeighbour( SOUTH, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( WEST ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( EAST, block );
-    if( block )
-        block->setNeighbour( WEST, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( TOP ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( BOTTOM, block );
-    if( block )
-        block->setNeighbour( TOP, neighbor );
-    neighbor = zBlockNeighbor( location + getDirection( BOTTOM ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbour( TOP, block );
-    if( block )
-        block->setNeighbour( BOTTOM, neighbor );
-    if( old )
-        old->release();
+	int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+	assert(index < CHUNK_SIZE* CHUNK_SIZE* WORLD_HEIGHT&& index >= 0);
+	Block* old = blocks[index];
+	if (block)
+		blockIds[index] = (unsigned short)block->zBlockType()->getId();
+	blocks[index] = block;
+	Either<Block*, int> neighbor = zBlockNeighbor(location + getDirection(NORTH));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbour(SOUTH, block);
+	if (block)
+		block->setNeighbour(NORTH, neighbor);
+	neighbor = zBlockNeighbor(location + getDirection(EAST));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbour(WEST, block);
+	if (block)
+		block->setNeighbour(EAST, neighbor);
+	neighbor = zBlockNeighbor(location + getDirection(SOUTH));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbour(NORTH, block);
+	if (block)
+		block->setNeighbour(SOUTH, neighbor);
+	neighbor = zBlockNeighbor(location + getDirection(WEST));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbour(EAST, block);
+	if (block)
+		block->setNeighbour(WEST, neighbor);
+	neighbor = zBlockNeighbor(location + getDirection(TOP));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbour(BOTTOM, block);
+	if (block)
+		block->setNeighbour(TOP, neighbor);
+	neighbor = zBlockNeighbor(location + getDirection(BOTTOM));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbour(TOP, block);
+	if (block)
+		block->setNeighbour(BOTTOM, neighbor);
+	if (old)
+		old->release();
 }
 
-void Chunk::putBlockTypeAt( Framework::Vec3<int> location, int type )
+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;
-    Either<Block*, int> neighbor = zBlockNeighbor( location + getDirection( NORTH ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( SOUTH, type );
-    neighbor = zBlockNeighbor( location + getDirection( EAST ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( WEST, type );
-    neighbor = zBlockNeighbor( location + getDirection( SOUTH ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( NORTH, type );
-    neighbor = zBlockNeighbor( location + getDirection( WEST ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( EAST, type );
-    neighbor = zBlockNeighbor( location + getDirection( TOP ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( BOTTOM, type );
-    neighbor = zBlockNeighbor( location + getDirection( BOTTOM ) );
-    if( neighbor.isA() )
-        ((Block*)neighbor)->setNeighbourType( TOP, 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;
+	Either<Block*, int> neighbor = zBlockNeighbor(location + getDirection(NORTH));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbourType(SOUTH, type);
+	neighbor = zBlockNeighbor(location + getDirection(EAST));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbourType(WEST, type);
+	neighbor = zBlockNeighbor(location + getDirection(SOUTH));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbourType(NORTH, type);
+	neighbor = zBlockNeighbor(location + getDirection(WEST));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbourType(EAST, type);
+	neighbor = zBlockNeighbor(location + getDirection(TOP));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbourType(BOTTOM, type);
+	neighbor = zBlockNeighbor(location + getDirection(BOTTOM));
+	if (neighbor.isA())
+		((Block*)neighbor)->setNeighbourType(TOP, type);
 }
 
-void Chunk::setNeighbor( Direction dir, Chunk* zChunk )
+void Chunk::setNeighbor(Direction dir, Chunk* zChunk)
 {
-    zNeighbours[ getDirectionIndex( dir ) ] = zChunk;
-    for( int i = 0; i < CHUNK_SIZE; i++ )
-    {
-        for( int z = 0; z < WORLD_HEIGHT; z++ )
-        {
-            if( dir == NORTH )
-            {
-                int index = i * CHUNK_SIZE * WORLD_HEIGHT + z;
-                if( blocks[ index ] )
-                {
-                    int j = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
-                    if( zChunk && zChunk->blocks[ j ] )
-                        blocks[ index ]->setNeighbour( NORTH, zChunk->blocks[ j ] );
-                    else
-                    {
-                        blocks[ index ]->setNeighbour( NORTH, 0 );
-                        blocks[ index ]->setNeighbourType( NORTH, zChunk ? zChunk->blockIds[ j ] : 0 );
-                    }
-                }
-            }
-            else if( dir == EAST )
-            {
-                int index = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
-                if( blocks[ index ] )
-                {
-                    int j = i * WORLD_HEIGHT + z;
-                    if( zChunk && zChunk->blocks[ j ] )
-                        blocks[ index ]->setNeighbour( EAST, zChunk->blocks[ j ] );
-                    else
-                    {
-                        blocks[ index ]->setNeighbour( EAST, 0 );
-                        blocks[ index ]->setNeighbourType( EAST, zChunk ? zChunk->blockIds[ j ] : 0 );
-                    }
-                }
-            }
-            else if( dir == SOUTH )
-            {
-                int index = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
-                if( blocks[ index ] )
-                {
-                    int j = i * CHUNK_SIZE * WORLD_HEIGHT + z;
-                    if( zChunk && zChunk->blocks[ j ] )
-                        blocks[ index ]->setNeighbour( SOUTH, zChunk->blocks[ j ] );
-                    else
-                    {
-                        blocks[ index ]->setNeighbour( SOUTH, 0 );
-                        blocks[ index ]->setNeighbourType( SOUTH, zChunk ? zChunk->blockIds[ j ] : 0 );
-                    }
-                }
-            }
-            else if( dir == WEST )
-            {
-                int index = i * WORLD_HEIGHT + z;
-                if( blocks[ index ] )
-                {
-                    int j = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
-                    if( zChunk && zChunk->blocks[ j ] )
-                        blocks[ index ]->setNeighbour( WEST, zChunk->blocks[ j ] );
-                    else
-                    {
-                        blocks[ index ]->setNeighbour( WEST, 0 );
-                        blocks[ index ]->setNeighbourType( WEST, zChunk ? zChunk->blockIds[ j ] : 0 );
-                    }
-                }
-            }
-        }
-    }
+	zNeighbours[getDirectionIndex(dir)] = zChunk;
+	for (int i = 0; i < CHUNK_SIZE; i++)
+	{
+		for (int z = 0; z < WORLD_HEIGHT; z++)
+		{
+			if (dir == NORTH)
+			{
+				int index = i * CHUNK_SIZE * WORLD_HEIGHT + z;
+				if (blocks[index])
+				{
+					int j = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
+					if (zChunk && zChunk->blocks[j])
+						blocks[index]->setNeighbour(NORTH, zChunk->blocks[j]);
+					else
+					{
+						blocks[index]->setNeighbour(NORTH, 0);
+						blocks[index]->setNeighbourType(NORTH, zChunk ? zChunk->blockIds[j] : 0);
+					}
+				}
+			}
+			else if (dir == EAST)
+			{
+				int index = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
+				if (blocks[index])
+				{
+					int j = i * WORLD_HEIGHT + z;
+					if (zChunk && zChunk->blocks[j])
+						blocks[index]->setNeighbour(EAST, zChunk->blocks[j]);
+					else
+					{
+						blocks[index]->setNeighbour(EAST, 0);
+						blocks[index]->setNeighbourType(EAST, zChunk ? zChunk->blockIds[j] : 0);
+					}
+				}
+			}
+			else if (dir == SOUTH)
+			{
+				int index = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
+				if (blocks[index])
+				{
+					int j = i * CHUNK_SIZE * WORLD_HEIGHT + z;
+					if (zChunk && zChunk->blocks[j])
+						blocks[index]->setNeighbour(SOUTH, zChunk->blocks[j]);
+					else
+					{
+						blocks[index]->setNeighbour(SOUTH, 0);
+						blocks[index]->setNeighbourType(SOUTH, zChunk ? zChunk->blockIds[j] : 0);
+					}
+				}
+			}
+			else if (dir == WEST)
+			{
+				int index = i * WORLD_HEIGHT + z;
+				if (blocks[index])
+				{
+					int j = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
+					if (zChunk && zChunk->blocks[j])
+						blocks[index]->setNeighbour(WEST, zChunk->blocks[j]);
+					else
+					{
+						blocks[index]->setNeighbour(WEST, 0);
+						blocks[index]->setNeighbourType(WEST, zChunk ? zChunk->blockIds[j] : 0);
+					}
+				}
+			}
+		}
+	}
 }
 
-void Chunk::load( Framework::StreamReader* zReader )
+void Chunk::load(Framework::StreamReader* zReader)
 {
-    unsigned short id = 0;
-    zReader->lese( (char*)&id, 2 );
-    Framework::Vec3<int> pos;
-    bool d = 0;
-    while( id )
-    {
-        zReader->lese( (char*)&pos.x, 4 );
-        zReader->lese( (char*)&pos.y, 4 );
-        zReader->lese( (char*)&pos.z, 4 );
-        zReader->lese( (char*)&d, 1 );
-        if( d )
-            putBlockAt( pos, StaticRegistry<BlockType>::INSTANCE.zElement( id )->loadBlock( Framework::Vec3<int>( pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z ), zReader ) );
-        else
-            putBlockTypeAt( pos, id );
+	unsigned short id = 0;
+	zReader->lese((char*)&id, 2);
+	Framework::Vec3<int> pos;
+	bool d = 0;
+	while (id)
+	{
+		zReader->lese((char*)&pos.x, 4);
+		zReader->lese((char*)&pos.y, 4);
+		zReader->lese((char*)&pos.z, 4);
+		zReader->lese((char*)&d, 1);
+		if (d)
+			putBlockAt(pos, StaticRegistry<BlockType>::INSTANCE.zElement(id)->loadBlock(Framework::Vec3<int>(pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z), zReader));
+		else
+			putBlockTypeAt(pos, id);
 
-        zReader->lese( (char*)&id, 2 );
-    }
+		zReader->lese((char*)&id, 2);
+	}
 }
 
-void Chunk::save( Framework::StreamWriter* zWriter, StreamTarget target )
+void Chunk::save(Framework::StreamWriter* zWriter)
 {
-    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 index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
-                unsigned short blockType = blocks[ index ] ? (unsigned short)blocks[ index ]->zBlockType()->getId() : blockIds[ index ];
-                if( blockType )
-                {
-                    bool visible = target == StreamTarget::FULL;
-                    if( !visible )
-                    {
-                        if( !blocks[ index ] )
-                        {
-                            if( CONST_BLOCK( 0, blockIds[ index ] )->isTransparent() || CONST_BLOCK( 0, blockIds[ index ] )->isPassable() )
-                                visible = 1;
-                            else
-                            {
-                                for( int d = 0; d < 6 && !visible; d++ )
-                                {
-                                    auto n = zBlockNeighbor( getDirection( (Directions)getDirectionFromIndex( d ) ) + Framework::Vec3<int>( x, y, z ) );
-                                    if( n.isA() && (((Block*)n)->isPassable() || ((Block*)n)->isTransparent()) )
-                                        visible = 1;
-                                    if( n.isB() && (CONST_BLOCK( 0, n )->isTransparent() || CONST_BLOCK( 0, n )->isPassable()) )
-                                        visible = 1;
-                                }
-                            }
-                        }
-                        else
-                            visible = blocks[ index ]->isVisible();
-                    }
-                    if( target == StreamTarget::FULL || (visible && (blocks[ index ] || blockType != AirBlockBlockType::ID)) )
-                    {
-                        zWriter->schreibe( (char*)&blockType, 2 );
-                        zWriter->schreibe( (char*)&x, 4 );
-                        zWriter->schreibe( (char*)&y, 4 );
-                        zWriter->schreibe( (char*)&z, 4 );
-                        if( blocks[ index ] )
-                        {
-                            bool d = 1;
-                            zWriter->schreibe( (char*)&d, 1 );
-                            StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->saveBlock( blocks[ index ], zWriter );
-                        }
-                        else
-                        {
-                            bool d = 0;
-                            zWriter->schreibe( (char*)&d, 1 );
-                        }
-                    }
-                }
-            }
-        }
-    }
-    unsigned short end = 0;
-    zWriter->schreibe( (char*)&end, 2 );
+	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 index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
+				unsigned short blockType = blocks[index] ? (unsigned short)blocks[index]->zBlockType()->getId() : blockIds[index];
+				if (blockType)
+				{
+					zWriter->schreibe((char*)&blockType, 2);
+					zWriter->schreibe((char*)&x, 4);
+					zWriter->schreibe((char*)&y, 4);
+					zWriter->schreibe((char*)&z, 4);
+					if (blocks[index])
+					{
+						bool d = 1;
+						zWriter->schreibe((char*)&d, 1);
+						StaticRegistry<BlockType>::INSTANCE.zElement(blockType)->saveBlock(blocks[index], zWriter);
+					}
+					else
+					{
+						bool d = 0;
+						zWriter->schreibe((char*)&d, 1);
+					}
+				}
+			}
+		}
+	}
+	unsigned short end = 0;
+	zWriter->schreibe((char*)&end, 2);
+}
+
+void Chunk::sendToClient(Framework::StreamWriter* zWriter)
+{
+	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 index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
+				unsigned short blockType = blocks[index] ? (unsigned short)blocks[index]->zBlockType()->getId() : blockIds[index];
+				if (blockType)
+				{
+					bool visible = 0;
+					if (!visible)
+					{
+						if (!blocks[index])
+						{
+							if (CONST_BLOCK(0, blockIds[index])->isTransparent() || CONST_BLOCK(0, blockIds[index])->isPassable())
+								visible = 1;
+							else
+							{
+								for (int d = 0; d < 6 && !visible; d++)
+								{
+									auto n = zBlockNeighbor(getDirection((Directions)getDirectionFromIndex(d)) + Framework::Vec3<int>(x, y, z));
+									if (n.isA() && (((Block*)n)->isPassable() || ((Block*)n)->isTransparent()))
+										visible = 1;
+									if (n.isB() && (CONST_BLOCK(0, n)->isTransparent() || CONST_BLOCK(0, n)->isPassable()))
+										visible = 1;
+								}
+							}
+						}
+						else
+							visible = blocks[index]->isVisible();
+					}
+					if (visible && (blocks[index] || blockType != AirBlockBlockType::ID))
+					{
+						zWriter->schreibe((char*)&blockType, 2);
+						zWriter->schreibe((char*)&x, 4);
+						zWriter->schreibe((char*)&y, 4);
+						zWriter->schreibe((char*)&z, 4);
+					}
+				}
+			}
+		}
+	}
+	unsigned short end = 0;
+	zWriter->schreibe((char*)&end, 2);
 }
 
 void Chunk::removeUnusedBlocks()
 {
-    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
-    {
-        if( blocks[ i ] )
-        {
-            if( !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 );
-            }
-        }
-        else if( blockIds[ i ] )
-        {
-            int x = (i / WORLD_HEIGHT) / CHUNK_SIZE;
-            int y = (i / WORLD_HEIGHT) % CHUNK_SIZE;
-            int z = i % WORLD_HEIGHT;
-            bool visible = 0;
-            if( CONST_BLOCK( 0, blockIds[ i ] )->isTransparent() || CONST_BLOCK( 0, blockIds[ i ] )->isPassable() )
-                visible = 1;
-            else
-            {
-                for( int d = 0; d < 6 && !visible; d++ )
-                {
-                    auto n = zBlockNeighbor( getDirection( (Directions)getDirectionFromIndex( d ) ) + Framework::Vec3<int>( x, y, z ) );
-                    if( n.isA() && (((Block*)n)->isPassable() || ((Block*)n)->isTransparent()) )
-                        visible = 1;
-                    if( n.isB() && (CONST_BLOCK( 0, n )->isTransparent() || CONST_BLOCK( 0, n )->isPassable()) )
-                        visible = 1;
-                }
-            }
-            if( !visible )
-            {
-                putBlockAt( { x,y,z }, 0 );
-                putBlockTypeAt( { x, y, z }, NoBlockBlockType::ID );
-            }
-        }
-    }
-    int count = 0;
-    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
-    {
-        if( blockIds[ i ] && blockIds[ i ] != AirBlockBlockType::ID )
-            count++;
-    }
-    std::cout << "chunk " << location.x << ", " << location.y << " was generated with " << count << " blocks.\n";
+	for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
+	{
+		if (blocks[i])
+		{
+			if (!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);
+			}
+		}
+		else if (blockIds[i])
+		{
+			int x = (i / WORLD_HEIGHT) / CHUNK_SIZE;
+			int y = (i / WORLD_HEIGHT) % CHUNK_SIZE;
+			int z = i % WORLD_HEIGHT;
+			bool visible = 0;
+			if (CONST_BLOCK(0, blockIds[i])->isTransparent() || CONST_BLOCK(0, blockIds[i])->isPassable())
+				visible = 1;
+			else
+			{
+				for (int d = 0; d < 6 && !visible; d++)
+				{
+					auto n = zBlockNeighbor(getDirection((Directions)getDirectionFromIndex(d)) + Framework::Vec3<int>(x, y, z));
+					if (n.isA() && (((Block*)n)->isPassable() || ((Block*)n)->isTransparent()))
+						visible = 1;
+					if (n.isB() && (CONST_BLOCK(0, n)->isTransparent() || CONST_BLOCK(0, n)->isPassable()))
+						visible = 1;
+				}
+			}
+			if (!visible)
+			{
+				putBlockAt({ x,y,z }, 0);
+				putBlockTypeAt({ x, y, z }, NoBlockBlockType::ID);
+			}
+		}
+	}
+	int count = 0;
+	for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
+	{
+		if (blockIds[i] && blockIds[i] != AirBlockBlockType::ID)
+			count++;
+	}
+	std::cout << "chunk " << location.x << ", " << location.y << " was generated with " << count << " blocks.\n";
 }
 
 int Chunk::getDimensionId() const
 {
-    return dimensionId;
+	return dimensionId;
 }
 
 Framework::Punkt Chunk::getCenter() const
 {
-    return location;
+	return location;
 }
 
 Framework::Vec3<int> Chunk::getMin() const
 {
-    return { location.x - CHUNK_SIZE / 2, location.y - CHUNK_SIZE / 2, 0 };
+	return { location.x - CHUNK_SIZE / 2, location.y - CHUNK_SIZE / 2, 0 };
 }
 
 Framework::Vec3<int> Chunk::getMax() const
 {
-    return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
+	return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
 }
 
 void Chunk::prepareRemove()
 {
-    added = 0;
-    for( int i = 0; i < 4; i++ )
-    {
-        if( zNeighbours[ i ] )
-        {
-            zNeighbours[ i ]->setNeighbor( getOppositeDirection( getDirectionFromIndex( i ) ), 0 );
-            zNeighbours[ i ] = 0;
-        }
-    }
+	added = 0;
+	for (int i = 0; i < 4; i++)
+	{
+		if (zNeighbours[i])
+		{
+			zNeighbours[i]->setNeighbor(getOppositeDirection(getDirectionFromIndex(i)), 0);
+			zNeighbours[i] = 0;
+		}
+	}
 }
 
 void Chunk::setAdded()
 {
-    added = 1;
+	added = 1;
 }
 
-void Chunk::addView( Entity* zEntity )
+void Chunk::addView(Entity* zEntity)
 {
-    cs.lock();
-    bool found = 0;
-    for( Entity* e : views )
-    {
-        if( e == zEntity )
-        {
-            found = 1;
-            break;
-        }
-    }
-    if( !found )
-        views.add( zEntity );
-    cs.unlock();
+	cs.lock();
+	bool found = 0;
+	for (Entity* e : views)
+	{
+		if (e == zEntity)
+		{
+			found = 1;
+			break;
+		}
+	}
+	if (!found)
+		views.add(zEntity);
+	cs.unlock();
 }
 
-void Chunk::removeView( Entity* zEntity )
+void Chunk::removeView(Entity* zEntity)
 {
-    cs.lock();
-    int i = 0;
-    for( Entity* e : views )
-    {
-        if( e == zEntity )
-        {
-            views.remove( i );
-            break;
-        }
-        i++;
-    }
-    cs.unlock();
+	cs.lock();
+	int i = 0;
+	for (Entity* e : views)
+	{
+		if (e == zEntity)
+		{
+			views.remove(i);
+			break;
+		}
+		i++;
+	}
+	cs.unlock();
 }
 
-bool Chunk::hasView( Entity* zEntity )
+bool Chunk::hasView(Entity* zEntity)
 {
-    cs.lock();
-    for( Entity* e : views )
-    {
-        if( e == zEntity )
-        {
-            cs.unlock();
-            return 1;
-        }
-    }
-    cs.unlock();
-    return 0;
+	cs.lock();
+	for (Entity* e : views)
+	{
+		if (e == zEntity)
+		{
+			cs.unlock();
+			return 1;
+		}
+	}
+	cs.unlock();
+	return 0;
 }
 
 bool Chunk::hasViews() const
 {
-    return views.getEintragAnzahl() > 0;
+	return views.getEintragAnzahl() > 0;
 }

+ 34 - 33
FactoryCraft/Chunk.h

@@ -12,41 +12,42 @@
 class Chunk : public virtual Framework::ReferenceCounter
 {
 private:
-    int dimensionId;
-    Framework::Punkt location;
-    Block** blocks;
-    Chunk* zNeighbours[ 4 ];
-    unsigned short* blockIds;
-    Framework::Either<Block*, int> zBlockNeighbor( Framework::Vec3<int> location );
-    bool added;
-    Framework::Critical cs;
-    Framework::Array<Entity*> views;
+	int dimensionId;
+	Framework::Punkt location;
+	Block** blocks;
+	Chunk* zNeighbours[4];
+	unsigned short* blockIds;
+	Framework::Either<Block*, int> zBlockNeighbor(Framework::Vec3<int> location);
+	bool added;
+	Framework::Critical cs;
+	Framework::Array<Entity*> views;
 
 public:
-    Chunk( Framework::Punkt location, int dimensionId );
-    Chunk( Framework::Punkt location, int dimensionId, Framework::StreamReader* zReader );
-    ~Chunk();
+	Chunk(Framework::Punkt location, int dimensionId);
+	Chunk(Framework::Punkt location, int dimensionId, Framework::StreamReader* zReader);
+	~Chunk();
 
-    void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse );
+	void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
 
-    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, StreamTarget target );
-    void removeUnusedBlocks();
-    int getDimensionId() const;
-    Framework::Punkt getCenter() const;
-    Framework::Vec3<int> getMin() const;
-    Framework::Vec3<int> getMax() const;
-    void prepareRemove();
-    void setAdded();
-    void addView( Entity* zEntity );
-    void removeView( Entity* zEntity );
-    bool hasView( Entity* zEntity );
-    bool hasViews() const;
+	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 sendToClient(Framework::StreamWriter* zWriter);
+	void removeUnusedBlocks();
+	int getDimensionId() const;
+	Framework::Punkt getCenter() const;
+	Framework::Vec3<int> getMin() const;
+	Framework::Vec3<int> getMax() const;
+	void prepareRemove();
+	void setAdded();
+	void addView(Entity* zEntity);
+	void removeView(Entity* zEntity);
+	bool hasView(Entity* zEntity);
+	bool hasViews() const;
 };

+ 1 - 1
FactoryCraft/Dimension.cpp

@@ -194,7 +194,7 @@ void Dimension::save(Text worldDir) const
 		filePath += ".chunk";
 		file->setDatei(filePath);
 		if (file->open(Datei::Style::schreiben))
-			chunk->save(file, StreamTarget::FULL);
+			chunk->save(file);
 		file->close();
 		file->release();
 	}

+ 25 - 25
FactoryCraft/Dimension.h

@@ -9,33 +9,33 @@
 class Dimension : public virtual Framework::ReferenceCounter
 {
 private:
-    int dimensionId;
-    float gravity;
-    Framework::Trie<Chunk>* chunks;
-    Framework::Array<Chunk*> chunkList;
-    Framework::RCArray<Entity>* entities;
-    void getAddrOf( Framework::Punkt cPos, char* addr ) const;
-    void getAddrOfWorld( Framework::Punkt wPos, char* addr ) const;
+	int dimensionId;
+	float gravity;
+	Framework::Trie<Chunk>* chunks;
+	Framework::Array<Chunk*> chunkList;
+	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();
+	Dimension(int id);
+	~Dimension();
 
-    void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse );
-    void tickEntities();
+	void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
+	void tickEntities();
 
-    Framework::Either<Block*, int> zBlock( Framework::Vec3<int> location );
-    Block* zRealBlockInstance( Framework::Vec3<int> location );
-    void placeBlock( Framework::Vec3<int> location, Framework::Either<Block*, int> block );
-    void addEntity( Entity* entity );
-    void setChunk( Chunk* chunk, Framework::Punkt center );
-    void save( Framework::Text worldDir ) const;
-    int getDimensionId() const;
-    bool hasChunck( int x, int y ) const;
-    Chunk* zChunk( Framework::Punkt wPos ) const;
-    float getGravity() const;
-    void removeOldChunks();
-    Entity* zEntity( int id );
-    Entity* zNearestEntity( Framework::Vec3<float> pos, std::function<bool( Entity* )> filter );
-    void removeEntity( int id );
+	Framework::Either<Block*, int> zBlock(Framework::Vec3<int> location);
+	Block* zRealBlockInstance(Framework::Vec3<int> location);
+	void placeBlock(Framework::Vec3<int> location, Framework::Either<Block*, int> block);
+	void addEntity(Entity* entity);
+	void setChunk(Chunk* chunk, Framework::Punkt center);
+	void save(Framework::Text worldDir) const;
+	int getDimensionId() const;
+	bool hasChunck(int x, int y) const;
+	Chunk* zChunk(Framework::Punkt wPos) const;
+	float getGravity() const;
+	void removeOldChunks();
+	Entity* zEntity(int id);
+	Entity* zNearestEntity(Framework::Vec3<float> pos, std::function<bool(Entity*)> filter);
+	void removeEntity(int id);
 };

+ 133 - 133
FactoryCraft/DimensionGenerator.cpp

@@ -6,163 +6,163 @@
 #include <iostream>
 
 
-DimensionGenerator::DimensionGenerator( int dimensionId )
-    : ReferenceCounter(),
-    dimensionId( dimensionId ),
-    minTemplateAffectedPosition( 0, 0, 0 ),
-    maxTemplateAffectedPosition( 0, 0, 0 )
+DimensionGenerator::DimensionGenerator(int dimensionId)
+	: ReferenceCounter(),
+	dimensionId(dimensionId),
+	minTemplateAffectedPosition(0, 0, 0),
+	maxTemplateAffectedPosition(0, 0, 0)
 {
-    StaticRegistry<DimensionGenerator>::INSTANCE.registerT( this, dimensionId );
+	StaticRegistry<DimensionGenerator>::INSTANCE.registerT(this, dimensionId);
 }
 
 DimensionGenerator::~DimensionGenerator()
 {}
 
-BiomGenerator* DimensionGenerator::zBiomGenerator( int seed, int x, int y )
+BiomGenerator* DimensionGenerator::zBiomGenerator(int seed, int x, int y)
 {
-    double noise = zBiomNoise( seed )->getNoise( (double)x, (double)y, 0.0 );
-    double border = 0;
-    BiomGenerator* gen = 0;
-    auto genI = biomGenerators.begin();
-    auto distI = biomDistribution.begin();
-    do
-    {
-        border += (double)distI++;
-        gen = genI++;
-    } while( border < noise && (bool)distI && (bool)genI );
-    return gen;
+	double noise = zBiomNoise(seed)->getNoise((double)x, (double)y, 0.0);
+	double border = 0;
+	BiomGenerator* gen = 0;
+	auto genI = biomGenerators.begin();
+	auto distI = biomDistribution.begin();
+	do
+	{
+		border += (double)distI++;
+		gen = genI++;
+	} while (border < noise && (bool)distI && (bool)genI);
+	return gen;
 }
 
-void DimensionGenerator::registerBiom( BiomGenerator* generator, double possibility )
+void DimensionGenerator::registerBiom(BiomGenerator* generator, double possibility)
 {
-    biomGenerators.add( generator );
-    biomDistribution.add( possibility );
-    for( auto t : generator->getTemplates() )
-    {
-        minTemplateAffectedPosition.x = MIN( minTemplateAffectedPosition.x, t->getMinAffectedOffset().x );
-        minTemplateAffectedPosition.y = MIN( minTemplateAffectedPosition.y, t->getMinAffectedOffset().y );
-        minTemplateAffectedPosition.z = MIN( minTemplateAffectedPosition.z, t->getMinAffectedOffset().z );
-        maxTemplateAffectedPosition.x = MAX( maxTemplateAffectedPosition.x, t->getMaxAffectedOffset().x );
-        maxTemplateAffectedPosition.y = MAX( maxTemplateAffectedPosition.y, t->getMaxAffectedOffset().y );
-        maxTemplateAffectedPosition.z = MAX( maxTemplateAffectedPosition.z, t->getMaxAffectedOffset().z );
-    }
+	biomGenerators.add(generator);
+	biomDistribution.add(possibility);
+	for (auto t : generator->getTemplates())
+	{
+		minTemplateAffectedPosition.x = MIN(minTemplateAffectedPosition.x, t->getMinAffectedOffset().x);
+		minTemplateAffectedPosition.y = MIN(minTemplateAffectedPosition.y, t->getMinAffectedOffset().y);
+		minTemplateAffectedPosition.z = MIN(minTemplateAffectedPosition.z, t->getMinAffectedOffset().z);
+		maxTemplateAffectedPosition.x = MAX(maxTemplateAffectedPosition.x, t->getMaxAffectedOffset().x);
+		maxTemplateAffectedPosition.y = MAX(maxTemplateAffectedPosition.y, t->getMaxAffectedOffset().y);
+		maxTemplateAffectedPosition.z = MAX(maxTemplateAffectedPosition.z, t->getMaxAffectedOffset().z);
+	}
 }
 
-Framework::RCArray<GeneratedStructure>* DimensionGenerator::getGeneratedStructoresForArea( int seed, Framework::Vec3<int> minPos, Framework::Vec3<int> maxPos )
+Framework::RCArray<GeneratedStructure>* DimensionGenerator::getGeneratedStructoresForArea(int seed, Framework::Vec3<int> minPos, Framework::Vec3<int> maxPos)
 {
-    Framework::RCArray<GeneratedStructure>* result = new Framework::RCArray<GeneratedStructure>();
+	Framework::RCArray<GeneratedStructure>* result = new Framework::RCArray<GeneratedStructure>();
 
-    int minSearchX = minPos.x - maxTemplateAffectedPosition.x;
-    int minSearchY = minPos.y - maxTemplateAffectedPosition.y;
-    int minSearchZ = MAX( minPos.z - maxTemplateAffectedPosition.z, 0 );
-    int maxSearchX = maxPos.x - minTemplateAffectedPosition.x;
-    int maxSearchY = maxPos.y - minTemplateAffectedPosition.y;
-    int maxSearchZ = MIN( maxPos.z - minTemplateAffectedPosition.z, WORLD_HEIGHT - 1 );
+	int minSearchX = minPos.x - maxTemplateAffectedPosition.x;
+	int minSearchY = minPos.y - maxTemplateAffectedPosition.y;
+	int minSearchZ = MAX(minPos.z - maxTemplateAffectedPosition.z, 0);
+	int maxSearchX = maxPos.x - minTemplateAffectedPosition.x;
+	int maxSearchY = maxPos.y - minTemplateAffectedPosition.y;
+	int maxSearchZ = MIN(maxPos.z - minTemplateAffectedPosition.z, WORLD_HEIGHT - 1);
 
-    Noise* structureNoise = zStructureNoise( seed + dimensionId );
-    for( int x = minSearchX; x <= maxSearchX; x++ )
-    {
-        for( int y = minSearchY; y <= maxSearchY; y++ )
-        {
-            BiomGenerator* biom = zBiomGenerator( seed + dimensionId, x, y );
-            int height = MIN_AIR_LEVEL + (int)(biom->zHeightMapNoise( seed + dimensionId )->getNoise( (double)(x), (double)(y), 0.0 ) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
-            for( int z = minSearchZ; z <= maxSearchZ; z++ )
-            {
-                if( z < height )
-                {
-                    double rValue = structureNoise->getNoise( (double)x, (double)y, (double)z );
-                    double probSum = 0;
-                    for( auto t : biom->getTemplates() )
-                    {
-                        if( t->isGenerationPossable( Framework::Vec3<int>( x, y, z ), height - z ) )
-                        {
-                            if( rValue - probSum <= t->getPropability() )
-                            {
-                                result->add( t->generateAt( Framework::Vec3<int>( x, y, z ), structureNoise ) );
-                                break;
-                            }
-                        }
-                        probSum += t->getPropability();
-                    }
-                }
-            }
-        }
-    }
+	Noise* structureNoise = zStructureNoise(seed + dimensionId);
+	for (int x = minSearchX; x <= maxSearchX; x++)
+	{
+		for (int y = minSearchY; y <= maxSearchY; y++)
+		{
+			BiomGenerator* biom = zBiomGenerator(seed + dimensionId, x, y);
+			int height = MIN_AIR_LEVEL + (int)(biom->zHeightMapNoise(seed + dimensionId)->getNoise((double)(x), (double)(y), 0.0) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
+			for (int z = minSearchZ; z <= maxSearchZ; z++)
+			{
+				if (z < height)
+				{
+					double rValue = structureNoise->getNoise((double)x, (double)y, (double)z);
+					double probSum = 0;
+					for (auto t : biom->getTemplates())
+					{
+						if (t->isGenerationPossable(Framework::Vec3<int>(x, y, z), height - z))
+						{
+							if (rValue - probSum <= t->getPropability())
+							{
+								result->add(t->generateAt(Framework::Vec3<int>(x, y, z), structureNoise));
+								break;
+							}
+						}
+						probSum += t->getPropability();
+					}
+				}
+			}
+		}
+	}
 
-    return result;
+	return result;
 }
 
-Chunk* DimensionGenerator::generateChunk( int seed, int centerX, int centerY )
+Chunk* DimensionGenerator::generateChunk(int seed, int centerX, int centerY)
 {
-    Framework::RCArray<GeneratedStructure>* structures = getGeneratedStructoresForArea( seed, Framework::Vec3<int>( centerX - CHUNK_SIZE / 2, centerY - CHUNK_SIZE / 2, 0 ), Framework::Vec3<int>( centerX + CHUNK_SIZE / 2, centerY + CHUNK_SIZE / 2, WORLD_HEIGHT - 1 ) );
-    std::cout << "generating chunk " << centerX << ", " << centerY << "\n";
-    Chunk* chunk = new Chunk( Framework::Punkt( centerX, centerY ), dimensionId );
-    for( int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++ )
-    {
-        for( int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++ )
-        {
-            BiomGenerator* biom = zBiomGenerator( seed + dimensionId, x + centerX, y + centerY );
-            // TODO: use Noise interpolator for height map between different bioms
-            int height = MIN_AIR_LEVEL + (int)(biom->zHeightMapNoise( seed + dimensionId )->getNoise( (double)(x + centerX), (double)(y + centerY), 0.0 ) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
-            int maxSurfaceHeight = (int)(MAX_SURFACE_HEIGHT * (1.f - (float)(height - MIN_AIR_LEVEL) / (float)(MAX_AIR_LEVEL - MIN_AIR_LEVEL)));
-            int actualSurfaceHeight = (int)((float)maxSurfaceHeight * (1.f - VARIABLE_SURFACE_PART) + ((float)maxSurfaceHeight * VARIABLE_SURFACE_PART * (float)biom->zHeightMapNoise( seed + dimensionId )->getNoise( (double)(x + centerX), (double)(y + centerY), 10.0 )));
-            for( int z = 0; z < WORLD_HEIGHT; z++ )
-            {
-                Framework::Either<Block*, int> generated = AirBlockBlockType::ID;
-                bool structureAffected = 0;
-                for( auto structure : *structures )
-                {
-                    if( structure->isBlockAffected( Framework::Vec3<int>( x + centerX, y + centerY, z ) ) )
-                    {
-                        generated = structure->generateBlockAt( Framework::Vec3<int>( x + centerX, y + centerY, z ) );
-                        structureAffected = 1;
-                        break;
-                    }
-                }
-                if( !structureAffected )
-                {
-                    if( z < height && z >= height - actualSurfaceHeight )
-                        generated = biom->generateSurfaceBlock( x + centerX, y + centerY, z );
-                    else if( z < height )
-                        generated = biom->generateBelowSurfaceBlock( 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 );
-            }
-        }
-    }
-    structures->release();
-    return chunk;
+	Framework::RCArray<GeneratedStructure>* structures = getGeneratedStructoresForArea(seed, Framework::Vec3<int>(centerX - CHUNK_SIZE / 2, centerY - CHUNK_SIZE / 2, 0), Framework::Vec3<int>(centerX + CHUNK_SIZE / 2, centerY + CHUNK_SIZE / 2, WORLD_HEIGHT - 1));
+	std::cout << "generating chunk " << centerX << ", " << centerY << "\n";
+	Chunk* chunk = new Chunk(Framework::Punkt(centerX, centerY), dimensionId);
+	for (int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++)
+	{
+		for (int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++)
+		{
+			BiomGenerator* biom = zBiomGenerator(seed + dimensionId, x + centerX, y + centerY);
+			// TODO: use Noise interpolator for height map between different bioms
+			int height = MIN_AIR_LEVEL + (int)(biom->zHeightMapNoise(seed + dimensionId)->getNoise((double)(x + centerX), (double)(y + centerY), 0.0) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
+			int maxSurfaceHeight = (int)(MAX_SURFACE_HEIGHT * (1.f - (float)(height - MIN_AIR_LEVEL) / (float)(MAX_AIR_LEVEL - MIN_AIR_LEVEL)));
+			int actualSurfaceHeight = (int)((float)maxSurfaceHeight * (1.f - VARIABLE_SURFACE_PART) + ((float)maxSurfaceHeight * VARIABLE_SURFACE_PART * (float)biom->zHeightMapNoise(seed + dimensionId)->getNoise((double)(x + centerX), (double)(y + centerY), 10.0)));
+			for (int z = 0; z < WORLD_HEIGHT; z++)
+			{
+				Framework::Either<Block*, int> generated = AirBlockBlockType::ID;
+				bool structureAffected = 0;
+				for (auto structure : *structures)
+				{
+					if (structure->isBlockAffected(Framework::Vec3<int>(x + centerX, y + centerY, z)))
+					{
+						generated = structure->generateBlockAt(Framework::Vec3<int>(x + centerX, y + centerY, z));
+						structureAffected = 1;
+						break;
+					}
+				}
+				if (!structureAffected)
+				{
+					if (z < height && z >= height - actualSurfaceHeight)
+						generated = biom->generateSurfaceBlock(x + centerX, y + centerY, z);
+					else if (z < height)
+						generated = biom->generateBelowSurfaceBlock(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);
+			}
+		}
+	}
+	structures->release();
+	return chunk;
 }
 
-Framework::Either<Block*, int> DimensionGenerator::generateBlock( int seed, Framework::Vec3<int> location )
+Framework::Either<Block*, int> DimensionGenerator::generateBlock(int seed, Framework::Vec3<int> location)
 {
-    Framework::RCArray<GeneratedStructure>* structures = getGeneratedStructoresForArea( seed, location, location );
-    BiomGenerator* biom = zBiomGenerator( seed + dimensionId, location.x, location.y );
-    // TODO: use Noise interpolator for height map between different bioms
-    int height = MIN_AIR_LEVEL + (int)(biom->zHeightMapNoise( seed + dimensionId )->getNoise( (double)(location.x), (double)(location.y), 0.0 ) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
-    int maxSurfaceHeight = (int)(MAX_SURFACE_HEIGHT * (1.f - (float)(height - MIN_AIR_LEVEL) / (float)(MAX_AIR_LEVEL - MIN_AIR_LEVEL)));
-    int actualSurfaceHeight = (int)((float)maxSurfaceHeight * (1.f - VARIABLE_SURFACE_PART) + ((float)maxSurfaceHeight * VARIABLE_SURFACE_PART * (float)biom->zHeightMapNoise( seed + dimensionId )->getNoise( (double)(location.x), (double)(location.y), 10.0 )));
-    for( auto structure : *structures )
-    {
-        if( structure->isBlockAffected( location ) )
-        {
-            auto generated = structure->generateBlockAt( location );
-            structures->release();
-            return generated;
-        }
-    }
-    structures->release();
-    if( location.z < height && location.z >= height - actualSurfaceHeight )
-        return biom->generateSurfaceBlock( location.x, location.y, location.z );
-    else if( location.z < height )
-        return biom->generateBelowSurfaceBlock( location.x, location.y, location.z );
-    return AirBlockBlockType::ID;
+	Framework::RCArray<GeneratedStructure>* structures = getGeneratedStructoresForArea(seed, location, location);
+	BiomGenerator* biom = zBiomGenerator(seed + dimensionId, location.x, location.y);
+	// TODO: use Noise interpolator for height map between different bioms
+	int height = MIN_AIR_LEVEL + (int)(biom->zHeightMapNoise(seed + dimensionId)->getNoise((double)(location.x), (double)(location.y), 0.0) * (MAX_AIR_LEVEL - MIN_AIR_LEVEL));
+	int maxSurfaceHeight = (int)(MAX_SURFACE_HEIGHT * (1.f - (float)(height - MIN_AIR_LEVEL) / (float)(MAX_AIR_LEVEL - MIN_AIR_LEVEL)));
+	int actualSurfaceHeight = (int)((float)maxSurfaceHeight * (1.f - VARIABLE_SURFACE_PART) + ((float)maxSurfaceHeight * VARIABLE_SURFACE_PART * (float)biom->zHeightMapNoise(seed + dimensionId)->getNoise((double)(location.x), (double)(location.y), 10.0)));
+	for (auto structure : *structures)
+	{
+		if (structure->isBlockAffected(location))
+		{
+			auto generated = structure->generateBlockAt(location);
+			structures->release();
+			return generated;
+		}
+	}
+	structures->release();
+	if (location.z < height && location.z >= height - actualSurfaceHeight)
+		return biom->generateSurfaceBlock(location.x, location.y, location.z);
+	else if (location.z < height)
+		return biom->generateBelowSurfaceBlock(location.x, location.y, location.z);
+	return AirBlockBlockType::ID;
 }
 
 int DimensionGenerator::getDimensionId() const
 {
-    return dimensionId;
+	return dimensionId;
 }

+ 15 - 15
FactoryCraft/DimensionGenerator.h

@@ -10,24 +10,24 @@
 class DimensionGenerator : public virtual Framework::ReferenceCounter
 {
 private:
-    Framework::RCArray<BiomGenerator> biomGenerators;
-    Framework::Array<double> biomDistribution;
-    const int dimensionId;
-    Framework::Vec3<int> minTemplateAffectedPosition;
-    Framework::Vec3<int> maxTemplateAffectedPosition;
+	Framework::RCArray<BiomGenerator> biomGenerators;
+	Framework::Array<double> biomDistribution;
+	const int dimensionId;
+	Framework::Vec3<int> minTemplateAffectedPosition;
+	Framework::Vec3<int> maxTemplateAffectedPosition;
 
-    BiomGenerator* zBiomGenerator( int seed, int x, int y );
+	BiomGenerator* zBiomGenerator(int seed, int x, int y);
 
 protected:
-    DimensionGenerator( int dimensionId );
-    ~DimensionGenerator();
-    void registerBiom( BiomGenerator* generator, double possibility );
-    Framework::RCArray<GeneratedStructure>* getGeneratedStructoresForArea( int seed, Framework::Vec3<int> minPos, Framework::Vec3<int> maxPos );
+	DimensionGenerator(int dimensionId);
+	~DimensionGenerator();
+	void registerBiom(BiomGenerator* generator, double possibility);
+	Framework::RCArray<GeneratedStructure>* getGeneratedStructoresForArea(int seed, Framework::Vec3<int> minPos, Framework::Vec3<int> maxPos);
 
 public:
-    Chunk* generateChunk( int seed, int centerX, int centerY );
-    Framework::Either<Block*, int> generateBlock( int seed, Framework::Vec3<int> location );
-    int getDimensionId() const;
-    virtual Noise* zBiomNoise( int seed ) = 0;
-    virtual Noise* zStructureNoise( int seed ) = 0;
+	Chunk* generateChunk(int seed, int centerX, int centerY);
+	Framework::Either<Block*, int> generateBlock(int seed, Framework::Vec3<int> location);
+	int getDimensionId() const;
+	virtual Noise* zBiomNoise(int seed) = 0;
+	virtual Noise* zStructureNoise(int seed) = 0;
 };

+ 8 - 8
FactoryCraft/Effect.h

@@ -8,18 +8,18 @@ class EffectFactory;
 class Effect : public virtual Framework::ReferenceCounter
 {
 private:
-    Framework::Text name;
-    float duration;
+	Framework::Text name;
+	float duration;
 
-    Effect( Entity* zTarget );
+	Effect(Entity* zTarget);
 
 public:
-    ~Effect();
+	~Effect();
 
-    virtual void tick();
+	virtual void tick();
 
-    Framework::Text getName() const;
-    float getDuration() const;
+	Framework::Text getName() const;
+	float getDuration() const;
 
-    friend EffectFactory;
+	friend EffectFactory;
 };

+ 3 - 3
FactoryCraft/EffectFactory.h

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

+ 19 - 3
FactoryCraft/Entity.cpp

@@ -5,7 +5,6 @@
 #include "ItemSkill.h"
 #include "PlaceBlockUpdate.h"
 #include "EntityRemovedUpdate.h"
-#include "EntityChangedUpdate.h"
 
 
 ActionTarget::ActionTarget(Vec3<int> blockPos, Direction blockSide)
@@ -381,8 +380,15 @@ void Entity::tick(const Dimension* zDimension)
 	location += frameSpeed;
 	if (oldPos != location || needUpdate)
 	{
-		needUpdate = 0;
-		Game::INSTANCE->requestWorldUpdate(new EntityChangedUpdate(id, location, currentDimensionId));
+		NetworkResponse changeMsg;
+		changeMsg.adressEntity(this);
+		char msg[13];
+		msg[0] = 0; // position changed
+		*(float*)(msg + 1) = this->location.x;
+		*(float*)(msg + 5) = this->location.y;
+		*(float*)(msg + 9) = this->location.z;
+		changeMsg.setMessage(msg, 13, 0);
+		Game::INSTANCE->distributeResponse(&changeMsg);
 	}
 }
 
@@ -540,3 +546,13 @@ int Entity::getId() const
 {
 	return id;
 }
+
+bool Entity::hasDefaultModel() const
+{
+	return 1;
+}
+
+ModelInfo Entity::getSpecialModel() const
+{
+	return ModelInfo("", "", 0);
+}

+ 60 - 58
FactoryCraft/Entity.h

@@ -17,78 +17,80 @@ class Dimension;
 class ActionTarget
 {
 private:
-    Framework::Vec3<int> blockPos;
-    Direction targetBlockSide;
-    int entityId;
+	Framework::Vec3<int> blockPos;
+	Direction targetBlockSide;
+	int entityId;
 
 public:
-    ActionTarget( Framework::Vec3<int> blockPos, Direction blockSide );
-    ActionTarget( int entityId );
+	ActionTarget(Framework::Vec3<int> blockPos, Direction blockSide);
+	ActionTarget(int entityId);
 
-    bool isBlock( Framework::Vec3<int> blockPos, Direction blockSide ) const;
-    bool isEntity( int entityId ) const;
+	bool isBlock(Framework::Vec3<int> blockPos, Direction blockSide) const;
+	bool isEntity(int entityId) const;
 
-    void applyItemSkillOnTarget( Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem );
-    void placeBlock( Entity* zActor, Item* zItem );
-    static void save( ActionTarget* zTarget, Framework::StreamWriter* zWriter );
-    static ActionTarget* load( Framework::StreamReader* zReader );
+	void applyItemSkillOnTarget(Entity* zActor, ItemSkill* zItemSkill, Item* zUsedItem);
+	void placeBlock(Entity* zActor, Item* zItem);
+	static void save(ActionTarget* zTarget, Framework::StreamWriter* zWriter);
+	static ActionTarget* load(Framework::StreamReader* zReader);
 };
 
 class Entity : public Inventory
 {
 protected:
-    float maxHP;
-    float currentHP;
-    float stamina;
-    float maxStamina;
-    float hunger;
-    float maxHunger;
-    float thirst;
-    float maxThirst;
-    float targetDistanceLimit;
-    Framework::Vec3<float> speed;
-    Framework::Vec3<float> faceDir;
-    Framework::Vec3<float> faceOffset;
-    Framework::RCArray<ItemSkill> skills;
-    ActionTarget* target;
-    const EntityType* zEntityType;
-    int currentDimensionId;
-    bool removed;
-    float gravityMultiplier;
-    bool needUpdate;
-    int id;
+	float maxHP;
+	float currentHP;
+	float stamina;
+	float maxStamina;
+	float hunger;
+	float maxHunger;
+	float thirst;
+	float maxThirst;
+	float targetDistanceLimit;
+	Framework::Vec3<float> speed;
+	Framework::Vec3<float> faceDir;
+	Framework::Vec3<float> faceOffset;
+	Framework::RCArray<ItemSkill> skills;
+	ActionTarget* target;
+	const EntityType* zEntityType;
+	int currentDimensionId;
+	bool removed;
+	float gravityMultiplier;
+	bool needUpdate;
+	int id;
 
-    virtual void onDeath();
-    virtual void useItem( const ItemType* zType, Item* zItem );
-    Entity( const EntityType* zType, Framework::Vec3<float> location, int dimensionId, int entityId );
+	virtual void onDeath();
+	virtual void useItem(const ItemType* zType, Item* zItem);
+	Entity(const EntityType* zType, Framework::Vec3<float> location, int dimensionId, int entityId);
 
 public:
-    void prepareTick( const Dimension* zDimension );
-    virtual void tick( const Dimension* zDimension );
+	void prepareTick(const Dimension* zDimension);
+	virtual void tick(const Dimension* zDimension);
 
-    virtual void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse );
+	virtual void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse);
 
-    virtual void onFall( float collisionSpeed );
-    void setPosition( Framework::Vec3<float> pos );
-    float getMaxHP() const;
-    float getCurrentHP() const;
-    float getStamina() const;
-    float getMaxStamina() const;
-    float getHunger() const;
-    float getMaxHunger() const;
-    float getThirst() const;
-    float getMaxThirst() const;
-    Framework::Vec3<float> getSpeed() const;
-    Framework::Vec3<float> getFaceDir() const;
-    Framework::Vec3<float> getPosition() const;
-    float getGravityMultiplier() const;
-    int getCurrentDimensionId() const;
-    bool isRemoved() const;
+	virtual void onFall(float collisionSpeed);
+	void setPosition(Framework::Vec3<float> pos);
+	float getMaxHP() const;
+	float getCurrentHP() const;
+	float getStamina() const;
+	float getMaxStamina() const;
+	float getHunger() const;
+	float getMaxHunger() const;
+	float getThirst() const;
+	float getMaxThirst() const;
+	Framework::Vec3<float> getSpeed() const;
+	Framework::Vec3<float> getFaceDir() const;
+	Framework::Vec3<float> getPosition() const;
+	float getGravityMultiplier() const;
+	int getCurrentDimensionId() const;
+	bool isRemoved() const;
 
-    const EntityType* zType() const;
-    const ActionTarget* zTarget() const;
-    int getId() const;
+	const EntityType* zType() const;
+	const ActionTarget* zTarget() const;
+	int getId() const;
+	virtual bool hasDefaultModel() const;
+	virtual ModelInfo getSpecialModel() const;
 
-    friend Effect;
-    friend EntityType;
+	friend Effect;
+	friend EntityType;
 };

+ 0 - 37
FactoryCraft/EntityChangedUpdate.cpp

@@ -1,37 +0,0 @@
-#include "EntityChangedUpdate.h"
-#include "Game.h"
-#include "EntityType.h"
-
-
-EntityChangedUpdate::EntityChangedUpdate( int entityId, Framework::Vec3<int> pos, int dimension )
-    : WorldUpdate( EntityChangedUpdateType::ID, dimension, pos, pos ),
-    entityId( entityId )
-{}
-
-EntityChangedUpdate::~EntityChangedUpdate()
-{}
-
-void EntityChangedUpdate::onUpdate( Dimension* zDimension )
-{}
-
-void EntityChangedUpdate::write( Framework::StreamWriter* zWriter )
-{
-    Entity* entity = Game::INSTANCE->zEntity( entityId, getAffectedDimension() );
-    if( entity )
-    {
-        int type = entity->zType()->getId();
-        zWriter->schreibe( (char*)&entityId, 4 );
-        zWriter->schreibe( (char*)&type, 4 );
-        StaticRegistry<EntityType>::INSTANCE.zElement( type )->saveEntity( entity, zWriter );
-    }
-    else
-    {
-        int id = -1;
-        zWriter->schreibe( (char*)&id, 4 );
-    }
-}
-
-
-EntityChangedUpdateType::EntityChangedUpdateType()
-    : WorldUpdateType( ID )
-{}

+ 0 - 27
FactoryCraft/EntityChangedUpdate.h

@@ -1,27 +0,0 @@
-#pragma once
-
-#include "WorldUpdate.h"
-
-class EntityChangedUpdate : public WorldUpdate
-{
-private:
-    int entityId;
-
-protected:
-    void write( Framework::StreamWriter* zWriter ) override;
-
-public:
-    EntityChangedUpdate( int entityId, Framework::Vec3<int> pos, int dimension );
-    ~EntityChangedUpdate();
-
-    void onUpdate( Dimension* zDimension ) override;
-};
-
-class EntityChangedUpdateType : WorldUpdateType
-{
-    REGISTRABLE( EntityChangedUpdateType )
-
-protected:
-    EntityChangedUpdateType();
-};
-REGISTER( EntityChangedUpdateType, WorldUpdateType )

+ 8 - 8
FactoryCraft/EntityRemovedUpdate.cpp

@@ -2,25 +2,25 @@
 #include "Dimension.h"
 
 
-EntityRemovedUpdate::EntityRemovedUpdate( int entityId, int dimensionId, Framework::Vec3<int> pos )
-    : WorldUpdate( EntityRemovedUpdateType::ID, dimensionId, pos, pos ),
-    entityId( entityId )
+EntityRemovedUpdate::EntityRemovedUpdate(int entityId, int dimensionId, Framework::Vec3<int> pos)
+	: WorldUpdate(EntityRemovedUpdateType::ID, dimensionId, pos, pos),
+	entityId(entityId)
 {}
 
 EntityRemovedUpdate::~EntityRemovedUpdate()
 {}
 
-void EntityRemovedUpdate::onUpdate( Dimension* zDimension )
+void EntityRemovedUpdate::onUpdate(Dimension* zDimension)
 {
-    zDimension->removeEntity( entityId );
+	zDimension->removeEntity(entityId);
 }
 
-void EntityRemovedUpdate::write( Framework::StreamWriter* zWriter )
+void EntityRemovedUpdate::write(Framework::StreamWriter* zWriter)
 {
-    zWriter->schreibe( (char*)&entityId, 4 );
+	zWriter->schreibe((char*)&entityId, 4);
 }
 
 
 EntityRemovedUpdateType::EntityRemovedUpdateType()
-    : WorldUpdateType( ID )
+	: WorldUpdateType(ID)
 {}

+ 8 - 8
FactoryCraft/EntityRemovedUpdate.h

@@ -5,23 +5,23 @@
 class EntityRemovedUpdate : public WorldUpdate
 {
 private:
-    int entityId;
+	int entityId;
 
 protected:
-    void write( Framework::StreamWriter* zWriter ) override;
+	void write(Framework::StreamWriter* zWriter) override;
 
 public:
-    EntityRemovedUpdate( int entityId, int dimensionId, Framework::Vec3<int> pos );
-    ~EntityRemovedUpdate();
+	EntityRemovedUpdate(int entityId, int dimensionId, Framework::Vec3<int> pos);
+	~EntityRemovedUpdate();
 
-    void onUpdate( Dimension* zDimension ) override;
+	void onUpdate(Dimension* zDimension) override;
 };
 
 class EntityRemovedUpdateType : WorldUpdateType
 {
-    REGISTRABLE( EntityRemovedUpdateType )
+	REGISTRABLE(EntityRemovedUpdateType)
 
 protected:
-    EntityRemovedUpdateType();
+	EntityRemovedUpdateType();
 };
-REGISTER( EntityRemovedUpdateType, WorldUpdateType )
+REGISTER(EntityRemovedUpdateType, WorldUpdateType)

+ 66 - 60
FactoryCraft/EntityType.cpp

@@ -2,86 +2,92 @@
 #include "Entity.h"
 #include "Game.h"
 
-EntityType::EntityType( int id )
-    : ReferenceCounter(),
-    id( id )
+EntityType::EntityType(int id, ModelInfo model)
+	: ReferenceCounter(),
+	id(id),
+	model(model)
 {
-    StaticRegistry<EntityType>::INSTANCE.registerT( this, 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->location.x, 4 );
-    zReader->lese( (char*)&zEntity->location.y, 4 );
-    zReader->lese( (char*)&zEntity->location.z, 4 );
-    if( zEntity->target )
-        delete zEntity->target;
-    zEntity->target = ActionTarget::load( zReader );
+	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->location.x, 4);
+	zReader->lese((char*)&zEntity->location.y, 4);
+	zReader->lese((char*)&zEntity->location.z, 4);
+	if (zEntity->target)
+		delete zEntity->target;
+	zEntity->target = ActionTarget::load(zReader);
 }
 
-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->location.x, 4 );
-    zWriter->schreibe( (char*)&zEntity->location.y, 4 );
-    zWriter->schreibe( (char*)&zEntity->location.z, 4 );
-    ActionTarget::save( zEntity->target, zWriter );
+	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->location.x, 4);
+	zWriter->schreibe((char*)&zEntity->location.y, 4);
+	zWriter->schreibe((char*)&zEntity->location.z, 4);
+	ActionTarget::save(zEntity->target, zWriter);
 }
 
-void EntityType::createSuperEntity( Entity* zEntity ) const
+void EntityType::createSuperEntity(Entity* zEntity) const
 {}
 
-Entity* EntityType::loadEntity( Framework::StreamReader* zReader ) const
+Entity* EntityType::loadEntity(Framework::StreamReader* zReader) const
 {
-    Entity* entity = createEntity( Framework::Vec3<float>( 0, 0, 0 ), 0, 0 );
-    loadSuperEntity( entity, zReader );
-    return entity;
+	Entity* entity = createEntity(Framework::Vec3<float>(0, 0, 0), 0, 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 );
+	saveSuperEntity(zEntity, zWriter);
 }
 
-Entity* EntityType::createEntityAt( Framework::Vec3<float> position, int dimensionId ) const
+Entity* EntityType::createEntityAt(Framework::Vec3<float> position, int dimensionId) const
 {
-    Entity* entity = createEntity( position, dimensionId, Game::INSTANCE->getNextEntityId() );
-    createSuperEntity( entity );
-    return entity;
+	Entity* entity = createEntity(position, dimensionId, Game::INSTANCE->getNextEntityId());
+	createSuperEntity(entity);
+	return entity;
 }
 
 int EntityType::getId() const
 {
-    return id;
+	return id;
+}
+
+const ModelInfo& EntityType::getModel() const
+{
+	return model;
 }

+ 13 - 10
FactoryCraft/EntityType.h

@@ -6,26 +6,29 @@
 #include <Vec3.h>
 
 #include "StaticRegistry.h"
+#include "ModelInfo.h"
 
 class Entity;
 
 class EntityType : public virtual Framework::ReferenceCounter
 {
 private:
-    const int id;
+	const int id;
+	const ModelInfo model;
 
 protected:
-    EntityType( int id );
+	EntityType(int id, ModelInfo model);
 
-    virtual void loadSuperEntity( Entity* zEntity, Framework::StreamReader* zReader ) const;
-    virtual void saveSuperEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const;
-    virtual void createSuperEntity( Entity* zEntity ) const;
-    virtual Entity* createEntity( Framework::Vec3<float> position, int dimensionId, int entityId ) const = 0;
+	virtual void loadSuperEntity(Entity* zEntity, Framework::StreamReader* zReader) const;
+	virtual void saveSuperEntity(Entity* zEntity, Framework::StreamWriter* zWriter) const;
+	virtual void createSuperEntity(Entity* zEntity) const;
+	virtual Entity* createEntity(Framework::Vec3<float> position, int dimensionId, int entityId) const = 0;
 
 public:
-    virtual Entity* loadEntity( Framework::StreamReader* zReader ) const;
-    virtual void saveEntity( Entity* zEntity, Framework::StreamWriter* zWriter ) const;
-    virtual Entity* createEntityAt( Framework::Vec3<float> position, int dimensionId ) const;
+	virtual Entity* loadEntity(Framework::StreamReader* zReader) const;
+	virtual void saveEntity(Entity* zEntity, Framework::StreamWriter* zWriter) const;
+	virtual Entity* createEntityAt(Framework::Vec3<float> position, int dimensionId) const;
 
-    int getId() const;
+	int getId() const;
+	const ModelInfo& getModel() const;
 };

+ 2 - 4
FactoryCraft/FactoryCraft.vcxproj

@@ -98,7 +98,6 @@
     <ClInclude Include="BasicBlocks.h" />
     <ClInclude Include="BiomGenerator.h" />
     <ClInclude Include="Block.h" />
-    <ClInclude Include="BlockChangedUpdate.h" />
     <ClInclude Include="BlockRemovedUpdate.h" />
     <ClInclude Include="BlockType.h" />
     <ClInclude Include="Chunk.h" />
@@ -108,7 +107,6 @@
     <ClInclude Include="Effect.h" />
     <ClInclude Include="EffectFactory.h" />
     <ClInclude Include="Entity.h" />
-    <ClInclude Include="EntityChangedUpdate.h" />
     <ClInclude Include="EntityRemovedUpdate.h" />
     <ClInclude Include="EntityType.h" />
     <ClInclude Include="FastNoiseLite.h" />
@@ -125,6 +123,7 @@
     <ClInclude Include="ItemSlot.h" />
     <ClInclude Include="ItemStack.h" />
     <ClInclude Include="ItemType.h" />
+    <ClInclude Include="ModelInfo.h" />
     <ClInclude Include="NetworkResponse.h" />
     <ClInclude Include="Noise.h" />
     <ClInclude Include="NoBlock.h" />
@@ -156,7 +155,6 @@
     <ClCompile Include="BasicBlock.cpp" />
     <ClCompile Include="BiomGenerator.cpp" />
     <ClCompile Include="Block.cpp" />
-    <ClCompile Include="BlockChangedUpdate.cpp" />
     <ClCompile Include="BlockRemovedUpdate.cpp" />
     <ClCompile Include="BlockType.cpp" />
     <ClCompile Include="Chunk.cpp" />
@@ -164,7 +162,6 @@
     <ClCompile Include="Dimension.cpp" />
     <ClCompile Include="DimensionGenerator.cpp" />
     <ClCompile Include="Entity.cpp" />
-    <ClCompile Include="EntityChangedUpdate.cpp" />
     <ClCompile Include="EntityRemovedUpdate.cpp" />
     <ClCompile Include="EntityType.cpp" />
     <ClCompile Include="FastNoiseWrapper.cpp" />
@@ -180,6 +177,7 @@
     <ClCompile Include="ItemSlot.cpp" />
     <ClCompile Include="ItemStack.cpp" />
     <ClCompile Include="ItemType.cpp" />
+    <ClCompile Include="ModelInfo.cpp" />
     <ClCompile Include="NetworkResponse.cpp" />
     <ClCompile Include="NoBlock.cpp" />
     <ClCompile Include="Noise.cpp" />

+ 6 - 12
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -186,9 +186,6 @@
     <ClInclude Include="PlaceBlockUpdate.h">
       <Filter>world\update</Filter>
     </ClInclude>
-    <ClInclude Include="BlockChangedUpdate.h">
-      <Filter>world\update</Filter>
-    </ClInclude>
     <ClInclude Include="BlockRemovedUpdate.h">
       <Filter>world\update</Filter>
     </ClInclude>
@@ -198,9 +195,6 @@
     <ClInclude Include="AddEntityUpdate.h">
       <Filter>world\update</Filter>
     </ClInclude>
-    <ClInclude Include="EntityChangedUpdate.h">
-      <Filter>world\update</Filter>
-    </ClInclude>
     <ClInclude Include="EntityRemovedUpdate.h">
       <Filter>world\update</Filter>
     </ClInclude>
@@ -231,6 +225,9 @@
     <ClInclude Include="StoneTool.h">
       <Filter>inventory\items</Filter>
     </ClInclude>
+    <ClInclude Include="ModelInfo.h">
+      <Filter>static</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -347,9 +344,6 @@
     <ClCompile Include="PlayerHand.cpp">
       <Filter>inventory\items</Filter>
     </ClCompile>
-    <ClCompile Include="BlockChangedUpdate.cpp">
-      <Filter>world\update</Filter>
-    </ClCompile>
     <ClCompile Include="BlockRemovedUpdate.cpp">
       <Filter>world\update</Filter>
     </ClCompile>
@@ -359,9 +353,6 @@
     <ClCompile Include="AddEntityUpdate.cpp">
       <Filter>world\update</Filter>
     </ClCompile>
-    <ClCompile Include="EntityChangedUpdate.cpp">
-      <Filter>world\update</Filter>
-    </ClCompile>
     <ClCompile Include="EntityRemovedUpdate.cpp">
       <Filter>world\update</Filter>
     </ClCompile>
@@ -389,5 +380,8 @@
     <ClCompile Include="StoneTool.cpp">
       <Filter>inventory\items</Filter>
     </ClCompile>
+    <ClCompile Include="ModelInfo.cpp">
+      <Filter>static</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 2458 - 2458
FactoryCraft/FastNoiseLite.h

@@ -55,2393 +55,2393 @@
 class FastNoiseLite
 {
 public:
-    enum NoiseType
-    {
-        NoiseType_OpenSimplex2,
-        NoiseType_OpenSimplex2S,
-        NoiseType_Cellular,
-        NoiseType_Perlin,
-        NoiseType_ValueCubic,
-        NoiseType_Value
-    };
-
-    enum RotationType3D
-    {
-        RotationType3D_None,
-        RotationType3D_ImproveXYPlanes,
-        RotationType3D_ImproveXZPlanes
-    };
-
-    enum FractalType
-    {
-        FractalType_None,
-        FractalType_FBm,
-        FractalType_Ridged,
-        FractalType_PingPong,
-        FractalType_DomainWarpProgressive,
-        FractalType_DomainWarpIndependent
-    };
-
-    enum CellularDistanceFunction
-    {
-        CellularDistanceFunction_Euclidean,
-        CellularDistanceFunction_EuclideanSq,
-        CellularDistanceFunction_Manhattan,
-        CellularDistanceFunction_Hybrid
-    };
-
-    enum CellularReturnType
-    {
-        CellularReturnType_CellValue,
-        CellularReturnType_Distance,
-        CellularReturnType_Distance2,
-        CellularReturnType_Distance2Add,
-        CellularReturnType_Distance2Sub,
-        CellularReturnType_Distance2Mul,
-        CellularReturnType_Distance2Div
-    };
-
-    enum DomainWarpType
-    {
-        DomainWarpType_OpenSimplex2,
-        DomainWarpType_OpenSimplex2Reduced,
-        DomainWarpType_BasicGrid
-    };
-
-    /// <summary>
-    /// Create new FastNoise object with optional seed
-    /// </summary>
-    FastNoiseLite( int seed = 1337 )
-    {
-        mSeed = seed;
-        mFrequency = 0.01f;
-        mNoiseType = NoiseType_OpenSimplex2;
-        mRotationType3D = RotationType3D_None;
-        mTransformType3D = TransformType3D_DefaultOpenSimplex2;
-
-        mFractalType = FractalType_None;
-        mOctaves = 3;
-        mLacunarity = 2.0f;
-        mGain = 0.5f;
-        mWeightedStrength = 0.0f;
-        mPingPongStength = 2.0f;
-
-        mFractalBounding = 1 / 1.75f;
-
-        mCellularDistanceFunction = CellularDistanceFunction_EuclideanSq;
-        mCellularReturnType = CellularReturnType_Distance;
-        mCellularJitterModifier = 1.0f;
-
-        mDomainWarpType = DomainWarpType_OpenSimplex2;
-        mWarpTransformType3D = TransformType3D_DefaultOpenSimplex2;
-        mDomainWarpAmp = 1.0f;
-    }
-
-    /// <summary>
-    /// Sets seed used for all noise types
-    /// </summary>
-    /// <remarks>
-    /// Default: 1337
-    /// </remarks>
-    void SetSeed( int seed ) { mSeed = seed; }
-
-    /// <summary>
-    /// Sets frequency for all noise types
-    /// </summary>
-    /// <remarks>
-    /// Default: 0.01
-    /// </remarks>
-    void SetFrequency( float frequency ) { mFrequency = frequency; }
-
-    /// <summary>
-    /// Sets noise algorithm used for GetNoise(...)
-    /// </summary>
-    /// <remarks>
-    /// Default: OpenSimplex2
-    /// </remarks>
-    void SetNoiseType( NoiseType noiseType )
-    {
-        mNoiseType = noiseType;
-        UpdateTransformType3D();
-    }
-
-    /// <summary>
-    /// Sets domain rotation type for 3D Noise and 3D DomainWarp.
-    /// Can aid in reducing directional artifacts when sampling a 2D plane in 3D
-    /// </summary>
-    /// <remarks>
-    /// Default: None
-    /// </remarks>
-    void SetRotationType3D( RotationType3D rotationType3D )
-    {
-        mRotationType3D = rotationType3D;
-        UpdateTransformType3D();
-        UpdateWarpTransformType3D();
-    }
-
-    /// <summary>
-    /// Sets method for combining octaves in all fractal noise types
-    /// </summary>
-    /// <remarks>
-    /// Default: None
-    /// Note: FractalType_DomainWarp... only affects DomainWarp(...)
-    /// </remarks>
-    void SetFractalType( FractalType fractalType ) { mFractalType = fractalType; }
-
-    /// <summary>
-    /// Sets octave count for all fractal noise types 
-    /// </summary>
-    /// <remarks>
-    /// Default: 3
-    /// </remarks>
-    void SetFractalOctaves( int octaves )
-    {
-        mOctaves = octaves;
-        CalculateFractalBounding();
-    }
-
-    /// <summary>
-    /// Sets octave lacunarity for all fractal noise types
-    /// </summary>
-    /// <remarks>
-    /// Default: 2.0
-    /// </remarks>
-    void SetFractalLacunarity( float lacunarity ) { mLacunarity = lacunarity; }
-
-    /// <summary>
-    /// Sets octave gain for all fractal noise types
-    /// </summary>
-    /// <remarks>
-    /// Default: 0.5
-    /// </remarks>
-    void SetFractalGain( float gain )
-    {
-        mGain = gain;
-        CalculateFractalBounding();
-    }
-
-    /// <summary>
-    /// Sets octave weighting for all none DomainWarp fratal types
-    /// </summary>
-    /// <remarks>
-    /// Default: 0.0
-    /// Note: Keep between 0...1 to maintain -1...1 output bounding
-    /// </remarks>
-    void SetFractalWeightedStrength( float weightedStrength ) { mWeightedStrength = weightedStrength; }
-
-    /// <summary>
-    /// Sets strength of the fractal ping pong effect
-    /// </summary>
-    /// <remarks>
-    /// Default: 2.0
-    /// </remarks>
-    void SetFractalPingPongStrength( float pingPongStrength ) { mPingPongStength = pingPongStrength; }
-
-
-    /// <summary>
-    /// Sets distance function used in cellular noise calculations
-    /// </summary>
-    /// <remarks>
-    /// Default: Distance
-    /// </remarks>
-    void SetCellularDistanceFunction( CellularDistanceFunction cellularDistanceFunction ) { mCellularDistanceFunction = cellularDistanceFunction; }
-
-    /// <summary>
-    /// Sets return type from cellular noise calculations
-    /// </summary>
-    /// <remarks>
-    /// Default: EuclideanSq
-    /// </remarks>
-    void SetCellularReturnType( CellularReturnType cellularReturnType ) { mCellularReturnType = cellularReturnType; }
-
-    /// <summary>
-    /// Sets the maximum distance a cellular point can move from it's grid position
-    /// </summary>
-    /// <remarks>
-    /// Default: 1.0
-    /// Note: Setting this higher than 1 will cause artifacts
-    /// </remarks> 
-    void SetCellularJitter( float cellularJitter ) { mCellularJitterModifier = cellularJitter; }
-
-
-    /// <summary>
-    /// Sets the warp algorithm when using DomainWarp(...)
-    /// </summary>
-    /// <remarks>
-    /// Default: OpenSimplex2
-    /// </remarks>
-    void SetDomainWarpType( DomainWarpType domainWarpType )
-    {
-        mDomainWarpType = domainWarpType;
-        UpdateWarpTransformType3D();
-    }
-
-
-    /// <summary>
-    /// Sets the maximum warp distance from original position when using DomainWarp(...)
-    /// </summary>
-    /// <remarks>
-    /// Default: 1.0
-    /// </remarks>
-    void SetDomainWarpAmp( float domainWarpAmp ) { mDomainWarpAmp = domainWarpAmp; }
-
-
-    /// <summary>
-    /// 2D noise at given position using current settings
-    /// </summary>
-    /// <returns>
-    /// Noise output bounded between -1...1
-    /// </returns>
-    template <typename FNfloat>
-    float GetNoise( FNfloat x, FNfloat y )
-    {
-        Arguments_must_be_floating_point_values<FNfloat>();
-
-        TransformNoiseCoordinate( x, y );
-
-        switch( mFractalType )
-        {
-        default:
-            return GenNoiseSingle( mSeed, x, y );
-        case FractalType_FBm:
-            return GenFractalFBm( x, y );
-        case FractalType_Ridged:
-            return GenFractalRidged( x, y );
-        case FractalType_PingPong:
-            return GenFractalPingPong( x, y );
-        }
-    }
-
-    /// <summary>
-    /// 3D noise at given position using current settings
-    /// </summary>
-    /// <returns>
-    /// Noise output bounded between -1...1
-    /// </returns>
-    template <typename FNfloat>
-    float GetNoise( FNfloat x, FNfloat y, FNfloat z )
-    {
-        Arguments_must_be_floating_point_values<FNfloat>();
-
-        TransformNoiseCoordinate( x, y, z );
-
-        switch( mFractalType )
-        {
-        default:
-            return GenNoiseSingle( mSeed, x, y, z );
-        case FractalType_FBm:
-            return GenFractalFBm( x, y, z );
-        case FractalType_Ridged:
-            return GenFractalRidged( x, y, z );
-        case FractalType_PingPong:
-            return GenFractalPingPong( x, y, z );
-        }
-    }
-
-
-    /// <summary>
-    /// 2D warps the input position using current domain warp settings
-    /// </summary>
-    /// <example>
-    /// Example usage with GetNoise
-    /// <code>DomainWarp(x, y)
-    /// noise = GetNoise(x, y)</code>
-    /// </example>
-    template <typename FNfloat>
-    void DomainWarp( FNfloat& x, FNfloat& y )
-    {
-        Arguments_must_be_floating_point_values<FNfloat>();
-
-        switch( mFractalType )
-        {
-        default:
-            DomainWarpSingle( x, y );
-            break;
-        case FractalType_DomainWarpProgressive:
-            DomainWarpFractalProgressive( x, y );
-            break;
-        case FractalType_DomainWarpIndependent:
-            DomainWarpFractalIndependent( x, y );
-            break;
-        }
-    }
-
-    /// <summary>
-    /// 3D warps the input position using current domain warp settings
-    /// </summary>
-    /// <example>
-    /// Example usage with GetNoise
-    /// <code>DomainWarp(x, y, z)
-    /// noise = GetNoise(x, y, z)</code>
-    /// </example>
-    template <typename FNfloat>
-    void DomainWarp( FNfloat& x, FNfloat& y, FNfloat& z )
-    {
-        Arguments_must_be_floating_point_values<FNfloat>();
-
-        switch( mFractalType )
-        {
-        default:
-            DomainWarpSingle( x, y, z );
-            break;
-        case FractalType_DomainWarpProgressive:
-            DomainWarpFractalProgressive( x, y, z );
-            break;
-        case FractalType_DomainWarpIndependent:
-            DomainWarpFractalIndependent( x, y, z );
-            break;
-        }
-    }
+	enum NoiseType
+	{
+		NoiseType_OpenSimplex2,
+		NoiseType_OpenSimplex2S,
+		NoiseType_Cellular,
+		NoiseType_Perlin,
+		NoiseType_ValueCubic,
+		NoiseType_Value
+	};
+
+	enum RotationType3D
+	{
+		RotationType3D_None,
+		RotationType3D_ImproveXYPlanes,
+		RotationType3D_ImproveXZPlanes
+	};
+
+	enum FractalType
+	{
+		FractalType_None,
+		FractalType_FBm,
+		FractalType_Ridged,
+		FractalType_PingPong,
+		FractalType_DomainWarpProgressive,
+		FractalType_DomainWarpIndependent
+	};
+
+	enum CellularDistanceFunction
+	{
+		CellularDistanceFunction_Euclidean,
+		CellularDistanceFunction_EuclideanSq,
+		CellularDistanceFunction_Manhattan,
+		CellularDistanceFunction_Hybrid
+	};
+
+	enum CellularReturnType
+	{
+		CellularReturnType_CellValue,
+		CellularReturnType_Distance,
+		CellularReturnType_Distance2,
+		CellularReturnType_Distance2Add,
+		CellularReturnType_Distance2Sub,
+		CellularReturnType_Distance2Mul,
+		CellularReturnType_Distance2Div
+	};
+
+	enum DomainWarpType
+	{
+		DomainWarpType_OpenSimplex2,
+		DomainWarpType_OpenSimplex2Reduced,
+		DomainWarpType_BasicGrid
+	};
+
+	/// <summary>
+	/// Create new FastNoise object with optional seed
+	/// </summary>
+	FastNoiseLite(int seed = 1337)
+	{
+		mSeed = seed;
+		mFrequency = 0.01f;
+		mNoiseType = NoiseType_OpenSimplex2;
+		mRotationType3D = RotationType3D_None;
+		mTransformType3D = TransformType3D_DefaultOpenSimplex2;
+
+		mFractalType = FractalType_None;
+		mOctaves = 3;
+		mLacunarity = 2.0f;
+		mGain = 0.5f;
+		mWeightedStrength = 0.0f;
+		mPingPongStength = 2.0f;
+
+		mFractalBounding = 1 / 1.75f;
+
+		mCellularDistanceFunction = CellularDistanceFunction_EuclideanSq;
+		mCellularReturnType = CellularReturnType_Distance;
+		mCellularJitterModifier = 1.0f;
+
+		mDomainWarpType = DomainWarpType_OpenSimplex2;
+		mWarpTransformType3D = TransformType3D_DefaultOpenSimplex2;
+		mDomainWarpAmp = 1.0f;
+	}
+
+	/// <summary>
+	/// Sets seed used for all noise types
+	/// </summary>
+	/// <remarks>
+	/// Default: 1337
+	/// </remarks>
+	void SetSeed(int seed) { mSeed = seed; }
+
+	/// <summary>
+	/// Sets frequency for all noise types
+	/// </summary>
+	/// <remarks>
+	/// Default: 0.01
+	/// </remarks>
+	void SetFrequency(float frequency) { mFrequency = frequency; }
+
+	/// <summary>
+	/// Sets noise algorithm used for GetNoise(...)
+	/// </summary>
+	/// <remarks>
+	/// Default: OpenSimplex2
+	/// </remarks>
+	void SetNoiseType(NoiseType noiseType)
+	{
+		mNoiseType = noiseType;
+		UpdateTransformType3D();
+	}
+
+	/// <summary>
+	/// Sets domain rotation type for 3D Noise and 3D DomainWarp.
+	/// Can aid in reducing directional artifacts when sampling a 2D plane in 3D
+	/// </summary>
+	/// <remarks>
+	/// Default: None
+	/// </remarks>
+	void SetRotationType3D(RotationType3D rotationType3D)
+	{
+		mRotationType3D = rotationType3D;
+		UpdateTransformType3D();
+		UpdateWarpTransformType3D();
+	}
+
+	/// <summary>
+	/// Sets method for combining octaves in all fractal noise types
+	/// </summary>
+	/// <remarks>
+	/// Default: None
+	/// Note: FractalType_DomainWarp... only affects DomainWarp(...)
+	/// </remarks>
+	void SetFractalType(FractalType fractalType) { mFractalType = fractalType; }
+
+	/// <summary>
+	/// Sets octave count for all fractal noise types 
+	/// </summary>
+	/// <remarks>
+	/// Default: 3
+	/// </remarks>
+	void SetFractalOctaves(int octaves)
+	{
+		mOctaves = octaves;
+		CalculateFractalBounding();
+	}
+
+	/// <summary>
+	/// Sets octave lacunarity for all fractal noise types
+	/// </summary>
+	/// <remarks>
+	/// Default: 2.0
+	/// </remarks>
+	void SetFractalLacunarity(float lacunarity) { mLacunarity = lacunarity; }
+
+	/// <summary>
+	/// Sets octave gain for all fractal noise types
+	/// </summary>
+	/// <remarks>
+	/// Default: 0.5
+	/// </remarks>
+	void SetFractalGain(float gain)
+	{
+		mGain = gain;
+		CalculateFractalBounding();
+	}
+
+	/// <summary>
+	/// Sets octave weighting for all none DomainWarp fratal types
+	/// </summary>
+	/// <remarks>
+	/// Default: 0.0
+	/// Note: Keep between 0...1 to maintain -1...1 output bounding
+	/// </remarks>
+	void SetFractalWeightedStrength(float weightedStrength) { mWeightedStrength = weightedStrength; }
+
+	/// <summary>
+	/// Sets strength of the fractal ping pong effect
+	/// </summary>
+	/// <remarks>
+	/// Default: 2.0
+	/// </remarks>
+	void SetFractalPingPongStrength(float pingPongStrength) { mPingPongStength = pingPongStrength; }
+
+
+	/// <summary>
+	/// Sets distance function used in cellular noise calculations
+	/// </summary>
+	/// <remarks>
+	/// Default: Distance
+	/// </remarks>
+	void SetCellularDistanceFunction(CellularDistanceFunction cellularDistanceFunction) { mCellularDistanceFunction = cellularDistanceFunction; }
+
+	/// <summary>
+	/// Sets return type from cellular noise calculations
+	/// </summary>
+	/// <remarks>
+	/// Default: EuclideanSq
+	/// </remarks>
+	void SetCellularReturnType(CellularReturnType cellularReturnType) { mCellularReturnType = cellularReturnType; }
+
+	/// <summary>
+	/// Sets the maximum distance a cellular point can move from it's grid position
+	/// </summary>
+	/// <remarks>
+	/// Default: 1.0
+	/// Note: Setting this higher than 1 will cause artifacts
+	/// </remarks> 
+	void SetCellularJitter(float cellularJitter) { mCellularJitterModifier = cellularJitter; }
+
+
+	/// <summary>
+	/// Sets the warp algorithm when using DomainWarp(...)
+	/// </summary>
+	/// <remarks>
+	/// Default: OpenSimplex2
+	/// </remarks>
+	void SetDomainWarpType(DomainWarpType domainWarpType)
+	{
+		mDomainWarpType = domainWarpType;
+		UpdateWarpTransformType3D();
+	}
+
+
+	/// <summary>
+	/// Sets the maximum warp distance from original position when using DomainWarp(...)
+	/// </summary>
+	/// <remarks>
+	/// Default: 1.0
+	/// </remarks>
+	void SetDomainWarpAmp(float domainWarpAmp) { mDomainWarpAmp = domainWarpAmp; }
+
+
+	/// <summary>
+	/// 2D noise at given position using current settings
+	/// </summary>
+	/// <returns>
+	/// Noise output bounded between -1...1
+	/// </returns>
+	template <typename FNfloat>
+	float GetNoise(FNfloat x, FNfloat y)
+	{
+		Arguments_must_be_floating_point_values<FNfloat>();
+
+		TransformNoiseCoordinate(x, y);
+
+		switch (mFractalType)
+		{
+		default:
+			return GenNoiseSingle(mSeed, x, y);
+		case FractalType_FBm:
+			return GenFractalFBm(x, y);
+		case FractalType_Ridged:
+			return GenFractalRidged(x, y);
+		case FractalType_PingPong:
+			return GenFractalPingPong(x, y);
+		}
+	}
+
+	/// <summary>
+	/// 3D noise at given position using current settings
+	/// </summary>
+	/// <returns>
+	/// Noise output bounded between -1...1
+	/// </returns>
+	template <typename FNfloat>
+	float GetNoise(FNfloat x, FNfloat y, FNfloat z)
+	{
+		Arguments_must_be_floating_point_values<FNfloat>();
+
+		TransformNoiseCoordinate(x, y, z);
+
+		switch (mFractalType)
+		{
+		default:
+			return GenNoiseSingle(mSeed, x, y, z);
+		case FractalType_FBm:
+			return GenFractalFBm(x, y, z);
+		case FractalType_Ridged:
+			return GenFractalRidged(x, y, z);
+		case FractalType_PingPong:
+			return GenFractalPingPong(x, y, z);
+		}
+	}
+
+
+	/// <summary>
+	/// 2D warps the input position using current domain warp settings
+	/// </summary>
+	/// <example>
+	/// Example usage with GetNoise
+	/// <code>DomainWarp(x, y)
+	/// noise = GetNoise(x, y)</code>
+	/// </example>
+	template <typename FNfloat>
+	void DomainWarp(FNfloat& x, FNfloat& y)
+	{
+		Arguments_must_be_floating_point_values<FNfloat>();
+
+		switch (mFractalType)
+		{
+		default:
+			DomainWarpSingle(x, y);
+			break;
+		case FractalType_DomainWarpProgressive:
+			DomainWarpFractalProgressive(x, y);
+			break;
+		case FractalType_DomainWarpIndependent:
+			DomainWarpFractalIndependent(x, y);
+			break;
+		}
+	}
+
+	/// <summary>
+	/// 3D warps the input position using current domain warp settings
+	/// </summary>
+	/// <example>
+	/// Example usage with GetNoise
+	/// <code>DomainWarp(x, y, z)
+	/// noise = GetNoise(x, y, z)</code>
+	/// </example>
+	template <typename FNfloat>
+	void DomainWarp(FNfloat& x, FNfloat& y, FNfloat& z)
+	{
+		Arguments_must_be_floating_point_values<FNfloat>();
+
+		switch (mFractalType)
+		{
+		default:
+			DomainWarpSingle(x, y, z);
+			break;
+		case FractalType_DomainWarpProgressive:
+			DomainWarpFractalProgressive(x, y, z);
+			break;
+		case FractalType_DomainWarpIndependent:
+			DomainWarpFractalIndependent(x, y, z);
+			break;
+		}
+	}
 
 private:
-    template <typename T>
-    struct Arguments_must_be_floating_point_values;
+	template <typename T>
+	struct Arguments_must_be_floating_point_values;
 
-    enum TransformType3D
-    {
-        TransformType3D_None,
-        TransformType3D_ImproveXYPlanes,
-        TransformType3D_ImproveXZPlanes,
-        TransformType3D_DefaultOpenSimplex2
-    };
+	enum TransformType3D
+	{
+		TransformType3D_None,
+		TransformType3D_ImproveXYPlanes,
+		TransformType3D_ImproveXZPlanes,
+		TransformType3D_DefaultOpenSimplex2
+	};
 
-    int mSeed;
-    float mFrequency;
-    NoiseType mNoiseType;
-    RotationType3D mRotationType3D;
-    TransformType3D mTransformType3D;
+	int mSeed;
+	float mFrequency;
+	NoiseType mNoiseType;
+	RotationType3D mRotationType3D;
+	TransformType3D mTransformType3D;
 
-    FractalType mFractalType;
-    int mOctaves;
-    float mLacunarity;
-    float mGain;
-    float mWeightedStrength;
-    float mPingPongStength;
+	FractalType mFractalType;
+	int mOctaves;
+	float mLacunarity;
+	float mGain;
+	float mWeightedStrength;
+	float mPingPongStength;
 
-    float mFractalBounding;
+	float mFractalBounding;
 
-    CellularDistanceFunction mCellularDistanceFunction;
-    CellularReturnType mCellularReturnType;
-    float mCellularJitterModifier;
+	CellularDistanceFunction mCellularDistanceFunction;
+	CellularReturnType mCellularReturnType;
+	float mCellularJitterModifier;
 
-    DomainWarpType mDomainWarpType;
-    TransformType3D mWarpTransformType3D;
-    float mDomainWarpAmp;
+	DomainWarpType mDomainWarpType;
+	TransformType3D mWarpTransformType3D;
+	float mDomainWarpAmp;
 
 
-    template <typename T>
-    struct Lookup
-    {
-        static const T Gradients2D[];
-        static const T Gradients3D[];
-        static const T RandVecs2D[];
-        static const T RandVecs3D[];
-    };
+	template <typename T>
+	struct Lookup
+	{
+		static const T Gradients2D[];
+		static const T Gradients3D[];
+		static const T RandVecs2D[];
+		static const T RandVecs3D[];
+	};
 
-    static float FastMin( float a, float b ) { return a < b ? a : b; }
+	static float FastMin(float a, float b) { return a < b ? a : b; }
 
-    static float FastMax( float a, float b ) { return a > b ? a : b; }
+	static float FastMax(float a, float b) { return a > b ? a : b; }
 
-    static float FastAbs( float f ) { return f < 0 ? -f : f; }
+	static float FastAbs(float f) { return f < 0 ? -f : f; }
 
-    static float FastSqrt( float f ) { return sqrtf( f ); }
+	static float FastSqrt(float f) { return sqrtf(f); }
 
-    template <typename FNfloat>
-    static int FastFloor( FNfloat f ) { return f >= 0 ? (int)f : (int)f - 1; }
+	template <typename FNfloat>
+	static int FastFloor(FNfloat f) { return f >= 0 ? (int)f : (int)f - 1; }
 
-    template <typename FNfloat>
-    static int FastRound( FNfloat f ) { return f >= 0 ? (int)(f + 0.5f) : (int)(f - 0.5f); }
+	template <typename FNfloat>
+	static int FastRound(FNfloat f) { return f >= 0 ? (int)(f + 0.5f) : (int)(f - 0.5f); }
 
-    static float Lerp( float a, float b, float t ) { return a + t * (b - a); }
+	static float Lerp(float a, float b, float t) { return a + t * (b - a); }
 
-    static float InterpHermite( float t ) { return t * t * (3 - 2 * t); }
+	static float InterpHermite(float t) { return t * t * (3 - 2 * t); }
 
-    static float InterpQuintic( float t ) { return t * t * t * (t * (t * 6 - 15) + 10); }
+	static float InterpQuintic(float t) { return t * t * t * (t * (t * 6 - 15) + 10); }
 
-    static float CubicLerp( float a, float b, float c, float d, float t )
-    {
-        float p = (d - c) - (a - b);
-        return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b;
-    }
+	static float CubicLerp(float a, float b, float c, float d, float t)
+	{
+		float p = (d - c) - (a - b);
+		return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b;
+	}
 
-    static float PingPong( float t )
-    {
-        t -= (float)(int)(t * 0.5f) * 2.f;
-        return t < 1 ? t : 2 - t;
-    }
+	static float PingPong(float t)
+	{
+		t -= (float)(int)(t * 0.5f) * 2.f;
+		return t < 1 ? t : 2 - t;
+	}
 
-    void CalculateFractalBounding()
-    {
-        float gain = FastAbs( mGain );
-        float amp = gain;
-        float ampFractal = 1.0f;
-        for( int i = 1; i < mOctaves; i++ )
-        {
-            ampFractal += amp;
-            amp *= gain;
-        }
-        mFractalBounding = 1 / ampFractal;
-    }
+	void CalculateFractalBounding()
+	{
+		float gain = FastAbs(mGain);
+		float amp = gain;
+		float ampFractal = 1.0f;
+		for (int i = 1; i < mOctaves; i++)
+		{
+			ampFractal += amp;
+			amp *= gain;
+		}
+		mFractalBounding = 1 / ampFractal;
+	}
 
-    // Hashing
-    static const int PrimeX = 501125321;
-    static const int PrimeY = 1136930381;
-    static const int PrimeZ = 1720413743;
+	// Hashing
+	static const int PrimeX = 501125321;
+	static const int PrimeY = 1136930381;
+	static const int PrimeZ = 1720413743;
 
-    static int Hash( int seed, int xPrimed, int yPrimed )
-    {
-        int hash = seed ^ xPrimed ^ yPrimed;
+	static int Hash(int seed, int xPrimed, int yPrimed)
+	{
+		int hash = seed ^ xPrimed ^ yPrimed;
 
-        hash *= 0x27d4eb2d;
-        return hash;
-    }
+		hash *= 0x27d4eb2d;
+		return hash;
+	}
 
 
-    static int Hash( int seed, int xPrimed, int yPrimed, int zPrimed )
-    {
-        int hash = seed ^ xPrimed ^ yPrimed ^ zPrimed;
+	static int Hash(int seed, int xPrimed, int yPrimed, int zPrimed)
+	{
+		int hash = seed ^ xPrimed ^ yPrimed ^ zPrimed;
 
-        hash *= 0x27d4eb2d;
-        return hash;
-    }
+		hash *= 0x27d4eb2d;
+		return hash;
+	}
 
 
-    static float ValCoord( int seed, int xPrimed, int yPrimed )
-    {
-        int hash = Hash( seed, xPrimed, yPrimed );
+	static float ValCoord(int seed, int xPrimed, int yPrimed)
+	{
+		int hash = Hash(seed, xPrimed, yPrimed);
 
-        hash *= hash;
-        hash ^= hash << 19;
-        return (float)hash * (1.f / 2147483648.0f);
-    }
+		hash *= hash;
+		hash ^= hash << 19;
+		return (float)hash * (1.f / 2147483648.0f);
+	}
 
 
-    static float ValCoord( int seed, int xPrimed, int yPrimed, int zPrimed )
-    {
-        int hash = Hash( seed, xPrimed, yPrimed, zPrimed );
+	static float ValCoord(int seed, int xPrimed, int yPrimed, int zPrimed)
+	{
+		int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
 
-        hash *= hash;
-        hash ^= hash << 19;
-        return (float)hash * (1.f / 2147483648.0f);
-    }
+		hash *= hash;
+		hash ^= hash << 19;
+		return (float)hash * (1.f / 2147483648.0f);
+	}
 
 
-    float GradCoord( int seed, int xPrimed, int yPrimed, float xd, float yd )
-    {
-        int hash = Hash( seed, xPrimed, yPrimed );
-        hash ^= hash >> 15;
-        hash &= 127 << 1;
+	float GradCoord(int seed, int xPrimed, int yPrimed, float xd, float yd)
+	{
+		int hash = Hash(seed, xPrimed, yPrimed);
+		hash ^= hash >> 15;
+		hash &= 127 << 1;
 
-        float xg = Lookup<float>::Gradients2D[ hash ];
-        float yg = Lookup<float>::Gradients2D[ hash | 1 ];
+		float xg = Lookup<float>::Gradients2D[hash];
+		float yg = Lookup<float>::Gradients2D[hash | 1];
 
-        return xd * xg + yd * yg;
-    }
+		return xd * xg + yd * yg;
+	}
 
 
-    float GradCoord( int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd )
-    {
-        int hash = Hash( seed, xPrimed, yPrimed, zPrimed );
-        hash ^= hash >> 15;
-        hash &= 63 << 2;
-
-        float xg = Lookup<float>::Gradients3D[ hash ];
-        float yg = Lookup<float>::Gradients3D[ hash | 1 ];
-        float zg = Lookup<float>::Gradients3D[ hash | 2 ];
-
-        return xd * xg + yd * yg + zd * zg;
-    }
-
-
-    void GradCoordOut( int seed, int xPrimed, int yPrimed, float& xo, float& yo )
-    {
-        int hash = Hash( seed, xPrimed, yPrimed ) & (255 << 1);
-
-        xo = Lookup<float>::RandVecs2D[ hash ];
-        yo = Lookup<float>::RandVecs2D[ hash | 1 ];
-    }
-
-
-    void GradCoordOut( int seed, int xPrimed, int yPrimed, int zPrimed, float& xo, float& yo, float& zo )
-    {
-        int hash = Hash( seed, xPrimed, yPrimed, zPrimed ) & (255 << 2);
-
-        xo = Lookup<float>::RandVecs3D[ hash ];
-        yo = Lookup<float>::RandVecs3D[ hash | 1 ];
-        zo = Lookup<float>::RandVecs3D[ hash | 2 ];
-    }
-
-
-    void GradCoordDual( int seed, int xPrimed, int yPrimed, float xd, float yd, float& xo, float& yo )
-    {
-        int hash = Hash( seed, xPrimed, yPrimed );
-        int index1 = hash & (127 << 1);
-        int index2 = (hash >> 7) & (255 << 1);
-
-        float xg = Lookup<float>::Gradients2D[ index1 ];
-        float yg = Lookup<float>::Gradients2D[ index1 | 1 ];
-        float value = xd * xg + yd * yg;
-
-        float xgo = Lookup<float>::RandVecs2D[ index2 ];
-        float ygo = Lookup<float>::RandVecs2D[ index2 | 1 ];
-
-        xo = value * xgo;
-        yo = value * ygo;
-    }
-
-
-    void GradCoordDual( int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd, float& xo, float& yo, float& zo )
-    {
-        int hash = Hash( seed, xPrimed, yPrimed, zPrimed );
-        int index1 = hash & (63 << 2);
-        int index2 = (hash >> 6) & (255 << 2);
-
-        float xg = Lookup<float>::Gradients3D[ index1 ];
-        float yg = Lookup<float>::Gradients3D[ index1 | 1 ];
-        float zg = Lookup<float>::Gradients3D[ index1 | 2 ];
-        float value = xd * xg + yd * yg + zd * zg;
-
-        float xgo = Lookup<float>::RandVecs3D[ index2 ];
-        float ygo = Lookup<float>::RandVecs3D[ index2 | 1 ];
-        float zgo = Lookup<float>::RandVecs3D[ index2 | 2 ];
-
-        xo = value * xgo;
-        yo = value * ygo;
-        zo = value * zgo;
-    }
-
-
-    // Generic noise gen
-
-    template <typename FNfloat>
-    float GenNoiseSingle( int seed, FNfloat x, FNfloat y )
-    {
-        switch( mNoiseType )
-        {
-        case NoiseType_OpenSimplex2:
-            return SingleSimplex( seed, x, y );
-        case NoiseType_OpenSimplex2S:
-            return SingleOpenSimplex2S( seed, x, y );
-        case NoiseType_Cellular:
-            return SingleCellular( seed, x, y );
-        case NoiseType_Perlin:
-            return SinglePerlin( seed, x, y );
-        case NoiseType_ValueCubic:
-            return SingleValueCubic( seed, x, y );
-        case NoiseType_Value:
-            return SingleValue( seed, x, y );
-        default:
-            return 0;
-        }
-    }
-
-    template <typename FNfloat>
-    float GenNoiseSingle( int seed, FNfloat x, FNfloat y, FNfloat z )
-    {
-        switch( mNoiseType )
-        {
-        case NoiseType_OpenSimplex2:
-            return SingleOpenSimplex2( seed, x, y, z );
-        case NoiseType_OpenSimplex2S:
-            return SingleOpenSimplex2S( seed, x, y, z );
-        case NoiseType_Cellular:
-            return SingleCellular( seed, x, y, z );
-        case NoiseType_Perlin:
-            return SinglePerlin( seed, x, y, z );
-        case NoiseType_ValueCubic:
-            return SingleValueCubic( seed, x, y, z );
-        case NoiseType_Value:
-            return SingleValue( seed, x, y, z );
-        default:
-            return 0;
-        }
-    }
-
-
-    // Noise Coordinate Transforms (frequency, and possible skew or rotation)
-
-    template <typename FNfloat>
-    void TransformNoiseCoordinate( FNfloat& x, FNfloat& y )
-    {
-        x *= mFrequency;
-        y *= mFrequency;
-
-        switch( mNoiseType )
-        {
-        case NoiseType_OpenSimplex2:
-        case NoiseType_OpenSimplex2S:
-        {
-            const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
-            const FNfloat F2 = 0.5f * (SQRT3 - 1);
-            FNfloat t = (x + y) * F2;
-            x += t;
-            y += t;
-        }
-        break;
-        default:
-            break;
-        }
-    }
-
-    template <typename FNfloat>
-    void TransformNoiseCoordinate( FNfloat& x, FNfloat& y, FNfloat& z )
-    {
-        x *= mFrequency;
-        y *= mFrequency;
-        z *= mFrequency;
-
-        switch( mTransformType3D )
-        {
-        case TransformType3D_ImproveXYPlanes:
-        {
-            FNfloat xy = x + y;
-            FNfloat s2 = xy * -(FNfloat)0.211324865405187;
-            z *= (FNfloat)0.577350269189626;
-            x += s2 - z;
-            y = y + s2 - z;
-            z += xy * (FNfloat)0.577350269189626;
-        }
-        break;
-        case TransformType3D_ImproveXZPlanes:
-        {
-            FNfloat xz = x + z;
-            FNfloat s2 = xz * -(FNfloat)0.211324865405187;
-            y *= (FNfloat)0.577350269189626;
-            x += s2 - y;
-            z += s2 - y;
-            y += xz * (FNfloat)0.577350269189626;
-        }
-        break;
-        case TransformType3D_DefaultOpenSimplex2:
-        {
-            const FNfloat R3 = (FNfloat)(2.0 / 3.0);
-            FNfloat r = (x + y + z) * R3; // Rotation, not skew
-            x = r - x;
-            y = r - y;
-            z = r - z;
-        }
-        break;
-        default:
-            break;
-        }
-    }
-
-    void UpdateTransformType3D()
-    {
-        switch( mRotationType3D )
-        {
-        case RotationType3D_ImproveXYPlanes:
-            mTransformType3D = TransformType3D_ImproveXYPlanes;
-            break;
-        case RotationType3D_ImproveXZPlanes:
-            mTransformType3D = TransformType3D_ImproveXZPlanes;
-            break;
-        default:
-            switch( mNoiseType )
-            {
-            case NoiseType_OpenSimplex2:
-            case NoiseType_OpenSimplex2S:
-                mTransformType3D = TransformType3D_DefaultOpenSimplex2;
-                break;
-            default:
-                mTransformType3D = TransformType3D_None;
-                break;
-            }
-            break;
-        }
-    }
-
-
-    // Domain Warp Coordinate Transforms
-
-    template <typename FNfloat>
-    void TransformDomainWarpCoordinate( FNfloat& x, FNfloat& y )
-    {
-        switch( mDomainWarpType )
-        {
-        case DomainWarpType_OpenSimplex2:
-        case DomainWarpType_OpenSimplex2Reduced:
-        {
-            const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
-            const FNfloat F2 = 0.5f * (SQRT3 - 1);
-            FNfloat t = (x + y) * F2;
-            x += t;
-            y += t;
-        }
-        break;
-        default:
-            break;
-        }
-    }
-
-    template <typename FNfloat>
-    void TransformDomainWarpCoordinate( FNfloat& x, FNfloat& y, FNfloat& z )
-    {
-        switch( mWarpTransformType3D )
-        {
-        case TransformType3D_ImproveXYPlanes:
-        {
-            FNfloat xy = x + y;
-            FNfloat s2 = xy * -(FNfloat)0.211324865405187;
-            z *= (FNfloat)0.577350269189626;
-            x += s2 - z;
-            y = y + s2 - z;
-            z += xy * (FNfloat)0.577350269189626;
-        }
-        break;
-        case TransformType3D_ImproveXZPlanes:
-        {
-            FNfloat xz = x + z;
-            FNfloat s2 = xz * -(FNfloat)0.211324865405187;
-            y *= (FNfloat)0.577350269189626;
-            x += s2 - y;
-            z += s2 - y;
-            y += xz * (FNfloat)0.577350269189626;
-        }
-        break;
-        case TransformType3D_DefaultOpenSimplex2:
-        {
-            const FNfloat R3 = (FNfloat)(2.0 / 3.0);
-            FNfloat r = (x + y + z) * R3; // Rotation, not skew
-            x = r - x;
-            y = r - y;
-            z = r - z;
-        }
-        break;
-        default:
-            break;
-        }
-    }
-
-    void UpdateWarpTransformType3D()
-    {
-        switch( mRotationType3D )
-        {
-        case RotationType3D_ImproveXYPlanes:
-            mWarpTransformType3D = TransformType3D_ImproveXYPlanes;
-            break;
-        case RotationType3D_ImproveXZPlanes:
-            mWarpTransformType3D = TransformType3D_ImproveXZPlanes;
-            break;
-        default:
-            switch( mDomainWarpType )
-            {
-            case DomainWarpType_OpenSimplex2:
-            case DomainWarpType_OpenSimplex2Reduced:
-                mWarpTransformType3D = TransformType3D_DefaultOpenSimplex2;
-                break;
-            default:
-                mWarpTransformType3D = TransformType3D_None;
-                break;
-            }
-            break;
-        }
-    }
-
-
-    // Fractal FBm
-
-    template <typename FNfloat>
-    float GenFractalFBm( FNfloat x, FNfloat y )
-    {
-        int seed = mSeed;
-        float sum = 0;
-        float amp = mFractalBounding;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            float noise = GenNoiseSingle( seed++, x, y );
-            sum += noise * amp;
-            amp *= Lerp( 1.0f, FastMin( noise + 1, 2 ) * 0.5f, mWeightedStrength );
-
-            x *= mLacunarity;
-            y *= mLacunarity;
-            amp *= mGain;
-        }
-
-        return sum;
-    }
-
-    template <typename FNfloat>
-    float GenFractalFBm( FNfloat x, FNfloat y, FNfloat z )
-    {
-        int seed = mSeed;
-        float sum = 0;
-        float amp = mFractalBounding;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            float noise = GenNoiseSingle( seed++, x, y, z );
-            sum += noise * amp;
-            amp *= Lerp( 1.0f, (noise + 1) * 0.5f, mWeightedStrength );
-
-            x *= mLacunarity;
-            y *= mLacunarity;
-            z *= mLacunarity;
-            amp *= mGain;
-        }
-
-        return sum;
-    }
-
-
-    // Fractal Ridged
-
-    template <typename FNfloat>
-    float GenFractalRidged( FNfloat x, FNfloat y )
-    {
-        int seed = mSeed;
-        float sum = 0;
-        float amp = mFractalBounding;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            float noise = FastAbs( GenNoiseSingle( seed++, x, y ) );
-            sum += (noise * -2 + 1) * amp;
-            amp *= Lerp( 1.0f, 1 - noise, mWeightedStrength );
-
-            x *= mLacunarity;
-            y *= mLacunarity;
-            amp *= mGain;
-        }
-
-        return sum;
-    }
-
-    template <typename FNfloat>
-    float GenFractalRidged( FNfloat x, FNfloat y, FNfloat z )
-    {
-        int seed = mSeed;
-        float sum = 0;
-        float amp = mFractalBounding;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            float noise = FastAbs( GenNoiseSingle( seed++, x, y, z ) );
-            sum += (noise * -2 + 1) * amp;
-            amp *= Lerp( 1.0f, 1 - noise, mWeightedStrength );
-
-            x *= mLacunarity;
-            y *= mLacunarity;
-            z *= mLacunarity;
-            amp *= mGain;
-        }
-
-        return sum;
-    }
-
-
-    // Fractal PingPong 
-
-    template <typename FNfloat>
-    float GenFractalPingPong( FNfloat x, FNfloat y )
-    {
-        int seed = mSeed;
-        float sum = 0;
-        float amp = mFractalBounding;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            float noise = PingPong( (GenNoiseSingle( seed++, x, y ) + 1) * mPingPongStength );
-            sum += (noise - 0.5f) * 2 * amp;
-            amp *= Lerp( 1.0f, noise, mWeightedStrength );
-
-            x *= mLacunarity;
-            y *= mLacunarity;
-            amp *= mGain;
-        }
-
-        return sum;
-    }
-
-    template <typename FNfloat>
-    float GenFractalPingPong( FNfloat x, FNfloat y, FNfloat z )
-    {
-        int seed = mSeed;
-        float sum = 0;
-        float amp = mFractalBounding;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            float noise = PingPong( (GenNoiseSingle( seed++, x, y, z ) + 1) * mPingPongStength );
-            sum += (noise - 0.5f) * 2 * amp;
-            amp *= Lerp( 1.0f, noise, mWeightedStrength );
-
-            x *= mLacunarity;
-            y *= mLacunarity;
-            z *= mLacunarity;
-            amp *= mGain;
-        }
-
-        return sum;
-    }
-
-
-    // Simplex/OpenSimplex2 Noise
-
-    template <typename FNfloat>
-    float SingleSimplex( int seed, FNfloat x, FNfloat y )
-    {
-        // 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
-
-        const float SQRT3 = 1.7320508075688772935274463415059f;
-        const float G2 = (3 - SQRT3) / 6;
-
-        /*
-         * --- Skew moved to TransformNoiseCoordinate method ---
-         * const FNfloat F2 = 0.5f * (SQRT3 - 1);
-         * FNfloat s = (x + y) * F2;
-         * x += s; y += s;
-        */
-
-        int i = FastFloor( x );
-        int j = FastFloor( y );
-        float xi = (float)(x - i);
-        float yi = (float)(y - j);
-
-        float t = (xi + yi) * G2;
-        float x0 = (float)(xi - t);
-        float y0 = (float)(yi - t);
-
-        i *= PrimeX;
-        j *= PrimeY;
-
-        float n0, n1, n2;
-
-        float a = 0.5f - x0 * x0 - y0 * y0;
-        if( a <= 0 ) n0 = 0;
-        else
-        {
-            n0 = (a * a) * (a * a) * GradCoord( seed, i, j, x0, y0 );
-        }
-
-        float c = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
-        if( c <= 0 ) n2 = 0;
-        else
-        {
-            float x2 = x0 + (2 * (float)G2 - 1);
-            float y2 = y0 + (2 * (float)G2 - 1);
-            n2 = (c * c) * (c * c) * GradCoord( seed, i + PrimeX, j + PrimeY, x2, y2 );
-        }
-
-        if( y0 > x0 )
-        {
-            float x1 = x0 + (float)G2;
-            float y1 = y0 + ((float)G2 - 1);
-            float b = 0.5f - x1 * x1 - y1 * y1;
-            if( b <= 0 ) n1 = 0;
-            else
-            {
-                n1 = (b * b) * (b * b) * GradCoord( seed, i, j + PrimeY, x1, y1 );
-            }
-        }
-        else
-        {
-            float x1 = x0 + ((float)G2 - 1);
-            float y1 = y0 + (float)G2;
-            float b = 0.5f - x1 * x1 - y1 * y1;
-            if( b <= 0 ) n1 = 0;
-            else
-            {
-                n1 = (b * b) * (b * b) * GradCoord( seed, i + PrimeX, j, x1, y1 );
-            }
-        }
-
-        return (n0 + n1 + n2) * 99.83685446303647f;
-    }
-
-    template <typename FNfloat>
-    float SingleOpenSimplex2( int seed, FNfloat x, FNfloat y, FNfloat z )
-    {
-        // 3D OpenSimplex2 case uses two offset rotated cube grids.
-
-        /*
-         * --- Rotation moved to TransformNoiseCoordinate method ---
-         * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
-         * FNfloat r = (x + y + z) * R3; // Rotation, not skew
-         * x = r - x; y = r - y; z = r - z;
-        */
-
-        int i = FastRound( x );
-        int j = FastRound( y );
-        int k = FastRound( z );
-        float x0 = (float)(x - i);
-        float y0 = (float)(y - j);
-        float z0 = (float)(z - k);
-
-        int xNSign = (int)(-1.0f - x0) | 1;
-        int yNSign = (int)(-1.0f - y0) | 1;
-        int zNSign = (int)(-1.0f - z0) | 1;
-
-        float ax0 = (float)xNSign * -x0;
-        float ay0 = (float)yNSign * -y0;
-        float az0 = (float)zNSign * -z0;
-
-        i *= PrimeX;
-        j *= PrimeY;
-        k *= PrimeZ;
-
-        float value = 0;
-        float a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
-
-        for( int l = 0; ; l++ )
-        {
-            if( a > 0 )
-            {
-                value += (a * a) * (a * a) * GradCoord( seed, i, j, k, x0, y0, z0 );
-            }
-
-            float b = a + 1;
-            int i1 = i;
-            int j1 = j;
-            int k1 = k;
-            float x1 = x0;
-            float y1 = y0;
-            float z1 = z0;
-
-            if( ax0 >= ay0 && ax0 >= az0 )
-            {
-                x1 += (float)xNSign;
-                b -= (float)(xNSign * 2) * x1;
-                i1 -= xNSign * PrimeX;
-            }
-            else if( ay0 > ax0 && ay0 >= az0 )
-            {
-                y1 += (float)yNSign;
-                b -= (float)(yNSign * 2) * y1;
-                j1 -= yNSign * PrimeY;
-            }
-            else
-            {
-                z1 += (float)zNSign;
-                b -= (float)(zNSign * 2) * z1;
-                k1 -= zNSign * PrimeZ;
-            }
-
-            if( b > 0 )
-            {
-                value += (b * b) * (b * b) * GradCoord( seed, i1, j1, k1, x1, y1, z1 );
-            }
-
-            if( l == 1 ) break;
-
-            ax0 = 0.5f - ax0;
-            ay0 = 0.5f - ay0;
-            az0 = 0.5f - az0;
-
-            x0 = (float)xNSign * ax0;
-            y0 = (float)yNSign * ay0;
-            z0 = (float)zNSign * az0;
-
-            a += (0.75f - ax0) - (ay0 + az0);
-
-            i += (xNSign >> 1) & PrimeX;
-            j += (yNSign >> 1) & PrimeY;
-            k += (zNSign >> 1) & PrimeZ;
-
-            xNSign = -xNSign;
-            yNSign = -yNSign;
-            zNSign = -zNSign;
-
-            seed = ~seed;
-        }
-
-        return value * 32.69428253173828125f;
-    }
-
-
-    // OpenSimplex2S Noise
-
-    template <typename FNfloat>
-    float SingleOpenSimplex2S( int seed, FNfloat x, FNfloat y )
-    {
-        // 2D OpenSimplex2S case is a modified 2D simplex noise.
-
-        const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
-        const FNfloat G2 = (3 - SQRT3) / 6;
-
-        /*
-         * --- Skew moved to TransformNoiseCoordinate method ---
-         * const FNfloat F2 = 0.5f * (SQRT3 - 1);
-         * FNfloat s = (x + y) * F2;
-         * x += s; y += s;
-        */
-
-        int i = FastFloor( x );
-        int j = FastFloor( y );
-        float xi = (float)(x - i);
-        float yi = (float)(y - j);
-
-        i *= PrimeX;
-        j *= PrimeY;
-        int i1 = i + PrimeX;
-        int j1 = j + PrimeY;
-
-        float t = (xi + yi) * (float)G2;
-        float x0 = xi - t;
-        float y0 = yi - t;
-
-        float a0 = (2.0f / 3.0f) - x0 * x0 - y0 * y0;
-        float value = (a0 * a0) * (a0 * a0) * GradCoord( seed, i, j, x0, y0 );
-
-        float a1 = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
-        float x1 = x0 - (float)(1 - 2 * G2);
-        float y1 = y0 - (float)(1 - 2 * G2);
-        value += (a1 * a1) * (a1 * a1) * GradCoord( seed, i1, j1, x1, y1 );
-
-        // Nested conditionals were faster than compact bit logic/arithmetic.
-        float xmyi = xi - yi;
-        if( t > G2 )
-        {
-            if( xi + xmyi > 1 )
-            {
-                float x2 = x0 + (float)(3 * G2 - 2);
-                float y2 = y0 + (float)(3 * G2 - 1);
-                float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
-                if( a2 > 0 )
-                {
-                    value += (a2 * a2) * (a2 * a2) * GradCoord( seed, i + (PrimeX << 1), j + PrimeY, x2, y2 );
-                }
-            }
-            else
-            {
-                float x2 = x0 + (float)G2;
-                float y2 = y0 + (float)(G2 - 1);
-                float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
-                if( a2 > 0 )
-                {
-                    value += (a2 * a2) * (a2 * a2) * GradCoord( seed, i, j + PrimeY, x2, y2 );
-                }
-            }
-
-            if( yi - xmyi > 1 )
-            {
-                float x3 = x0 + (float)(3 * G2 - 1);
-                float y3 = y0 + (float)(3 * G2 - 2);
-                float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
-                if( a3 > 0 )
-                {
-                    value += (a3 * a3) * (a3 * a3) * GradCoord( seed, i + PrimeX, j + (PrimeY << 1), x3, y3 );
-                }
-            }
-            else
-            {
-                float x3 = x0 + (float)(G2 - 1);
-                float y3 = y0 + (float)G2;
-                float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
-                if( a3 > 0 )
-                {
-                    value += (a3 * a3) * (a3 * a3) * GradCoord( seed, i + PrimeX, j, x3, y3 );
-                }
-            }
-        }
-        else
-        {
-            if( xi + xmyi < 0 )
-            {
-                float x2 = x0 + (float)(1 - G2);
-                float y2 = y0 - (float)G2;
-                float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
-                if( a2 > 0 )
-                {
-                    value += (a2 * a2) * (a2 * a2) * GradCoord( seed, i - PrimeX, j, x2, y2 );
-                }
-            }
-            else
-            {
-                float x2 = x0 + (float)(G2 - 1);
-                float y2 = y0 + (float)G2;
-                float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
-                if( a2 > 0 )
-                {
-                    value += (a2 * a2) * (a2 * a2) * GradCoord( seed, i + PrimeX, j, x2, y2 );
-                }
-            }
-
-            if( yi < xmyi )
-            {
-                float x2 = x0 - (float)G2;
-                float y2 = y0 - (float)(G2 - 1);
-                float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
-                if( a2 > 0 )
-                {
-                    value += (a2 * a2) * (a2 * a2) * GradCoord( seed, i, j - PrimeY, x2, y2 );
-                }
-            }
-            else
-            {
-                float x2 = x0 + (float)G2;
-                float y2 = y0 + (float)(G2 - 1);
-                float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
-                if( a2 > 0 )
-                {
-                    value += (a2 * a2) * (a2 * a2) * GradCoord( seed, i, j + PrimeY, x2, y2 );
-                }
-            }
-        }
-
-        return value * 18.24196194486065f;
-    }
-
-    template <typename FNfloat>
-    float SingleOpenSimplex2S( int seed, FNfloat x, FNfloat y, FNfloat z )
-    {
-        // 3D OpenSimplex2S case uses two offset rotated cube grids.
-
-        /*
-         * --- Rotation moved to TransformNoiseCoordinate method ---
-         * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
-         * FNfloat r = (x + y + z) * R3; // Rotation, not skew
-         * x = r - x; y = r - y; z = r - z;
-        */
-
-        int i = FastFloor( x );
-        int j = FastFloor( y );
-        int k = FastFloor( z );
-        float xi = (float)(x - i);
-        float yi = (float)(y - j);
-        float zi = (float)(z - k);
-
-        i *= PrimeX;
-        j *= PrimeY;
-        k *= PrimeZ;
-        int seed2 = seed + 1293373;
-
-        int xNMask = (int)(-0.5f - xi);
-        int yNMask = (int)(-0.5f - yi);
-        int zNMask = (int)(-0.5f - zi);
-
-        float x0 = xi + (float)xNMask;
-        float y0 = yi + (float)yNMask;
-        float z0 = zi + (float)zNMask;
-        float a0 = 0.75f - x0 * x0 - y0 * y0 - z0 * z0;
-        float value = (a0 * a0) * (a0 * a0) * GradCoord( seed,
-                                                         i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x0, y0, z0 );
-
-        float x1 = xi - 0.5f;
-        float y1 = yi - 0.5f;
-        float z1 = zi - 0.5f;
-        float a1 = 0.75f - x1 * x1 - y1 * y1 - z1 * z1;
-        value += (a1 * a1) * (a1 * a1) * GradCoord( seed2,
-                                                    i + PrimeX, j + PrimeY, k + PrimeZ, x1, y1, z1 );
-
-        float xAFlipMask0 = (float)((xNMask | 1) << 1) * x1;
-        float yAFlipMask0 = (float)((yNMask | 1) << 1) * y1;
-        float zAFlipMask0 = (float)((zNMask | 1) << 1) * z1;
-        float xAFlipMask1 = (float)(-2 - (xNMask << 2)) * x1 - 1.0f;
-        float yAFlipMask1 = (float)(-2 - (yNMask << 2)) * y1 - 1.0f;
-        float zAFlipMask1 = (float)(-2 - (zNMask << 2)) * z1 - 1.0f;
-
-        bool skip5 = false;
-        float a2 = xAFlipMask0 + a0;
-        if( a2 > 0 )
-        {
-            float x2 = x0 - (float)(xNMask | 1);
-            float y2 = y0;
-            float z2 = z0;
-            value += (a2 * a2) * (a2 * a2) * GradCoord( seed,
-                                                        i + (~xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x2, y2, z2 );
-        }
-        else
-        {
-            float a3 = yAFlipMask0 + zAFlipMask0 + a0;
-            if( a3 > 0 )
-            {
-                float x3 = x0;
-                float y3 = y0 - (float)(yNMask | 1);
-                float z3 = z0 - (float)(zNMask | 1);
-                value += (a3 * a3) * (a3 * a3) * GradCoord( seed,
-                                                            i + (xNMask & PrimeX), j + (~yNMask & PrimeY), k + (~zNMask & PrimeZ), x3, y3, z3 );
-            }
-
-            float a4 = xAFlipMask1 + a1;
-            if( a4 > 0 )
-            {
-                float x4 = (float)(xNMask | 1) + x1;
-                float y4 = y1;
-                float z4 = z1;
-                value += (a4 * a4) * (a4 * a4) * GradCoord( seed2,
-                                                            i + (xNMask & (PrimeX * 2)), j + PrimeY, k + PrimeZ, x4, y4, z4 );
-                skip5 = true;
-            }
-        }
-
-        bool skip9 = false;
-        float a6 = yAFlipMask0 + a0;
-        if( a6 > 0 )
-        {
-            float x6 = x0;
-            float y6 = y0 - (float)(yNMask | 1);
-            float z6 = z0;
-            value += (a6 * a6) * (a6 * a6) * GradCoord( seed,
-                                                        i + (xNMask & PrimeX), j + (~yNMask & PrimeY), k + (zNMask & PrimeZ), x6, y6, z6 );
-        }
-        else
-        {
-            float a7 = xAFlipMask0 + zAFlipMask0 + a0;
-            if( a7 > 0 )
-            {
-                float x7 = x0 - (float)(xNMask | 1);
-                float y7 = y0;
-                float z7 = z0 - (float)(zNMask | 1);
-                value += (a7 * a7) * (a7 * a7) * GradCoord( seed,
-                                                            i + (~xNMask & PrimeX), j + (yNMask & PrimeY), k + (~zNMask & PrimeZ), x7, y7, z7 );
-            }
-
-            float a8 = yAFlipMask1 + a1;
-            if( a8 > 0 )
-            {
-                float x8 = x1;
-                float y8 = (float)(yNMask | 1) + y1;
-                float z8 = z1;
-                value += (a8 * a8) * (a8 * a8) * GradCoord( seed2,
-                                                            i + PrimeX, j + (yNMask & (PrimeY << 1)), k + PrimeZ, x8, y8, z8 );
-                skip9 = true;
-            }
-        }
-
-        bool skipD = false;
-        float aA = zAFlipMask0 + a0;
-        if( aA > 0 )
-        {
-            float xA = x0;
-            float yA = y0;
-            float zA = z0 - (float)(zNMask | 1);
-            value += (aA * aA) * (aA * aA) * GradCoord( seed,
-                                                        i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (~zNMask & PrimeZ), xA, yA, zA );
-        }
-        else
-        {
-            float aB = xAFlipMask0 + yAFlipMask0 + a0;
-            if( aB > 0 )
-            {
-                float xB = x0 - (float)(xNMask | 1);
-                float yB = y0 - (float)(yNMask | 1);
-                float zB = z0;
-                value += (aB * aB) * (aB * aB) * GradCoord( seed,
-                                                            i + (~xNMask & PrimeX), j + (~yNMask & PrimeY), k + (zNMask & PrimeZ), xB, yB, zB );
-            }
-
-            float aC = zAFlipMask1 + a1;
-            if( aC > 0 )
-            {
-                float xC = x1;
-                float yC = y1;
-                float zC = (float)(zNMask | 1) + z1;
-                value += (aC * aC) * (aC * aC) * GradCoord( seed2,
-                                                            i + PrimeX, j + PrimeY, k + (zNMask & (PrimeZ << 1)), xC, yC, zC );
-                skipD = true;
-            }
-        }
-
-        if( !skip5 )
-        {
-            float a5 = yAFlipMask1 + zAFlipMask1 + a1;
-            if( a5 > 0 )
-            {
-                float x5 = x1;
-                float y5 = (float)(yNMask | 1) + y1;
-                float z5 = (float)(zNMask | 1) + z1;
-                value += (a5 * a5) * (a5 * a5) * GradCoord( seed2,
-                                                            i + PrimeX, j + (yNMask & (PrimeY << 1)), k + (zNMask & (PrimeZ << 1)), x5, y5, z5 );
-            }
-        }
-
-        if( !skip9 )
-        {
-            float a9 = xAFlipMask1 + zAFlipMask1 + a1;
-            if( a9 > 0 )
-            {
-                float x9 = (float)(xNMask | 1) + x1;
-                float y9 = y1;
-                float z9 = (float)(zNMask | 1) + z1;
-                value += (a9 * a9) * (a9 * a9) * GradCoord( seed2,
-                                                            i + (xNMask & (PrimeX * 2)), j + PrimeY, k + (zNMask & (PrimeZ << 1)), x9, y9, z9 );
-            }
-        }
-
-        if( !skipD )
-        {
-            float aD = xAFlipMask1 + yAFlipMask1 + a1;
-            if( aD > 0 )
-            {
-                float xD = (float)(xNMask | 1) + x1;
-                float yD = (float)(yNMask | 1) + y1;
-                float zD = z1;
-                value += (aD * aD) * (aD * aD) * GradCoord( seed2,
-                                                            i + (xNMask & (PrimeX << 1)), j + (yNMask & (PrimeY << 1)), k + PrimeZ, xD, yD, zD );
-            }
-        }
-
-        return value * 9.046026385208288f;
-    }
-
-
-    // Cellular Noise
-
-    template <typename FNfloat>
-    float SingleCellular( int seed, FNfloat x, FNfloat y )
-    {
-        int xr = FastRound( x );
-        int yr = FastRound( y );
-
-        float distance0 = 1e10f;
-        float distance1 = 1e10f;
-        int closestHash = 0;
-
-        float cellularJitter = 0.43701595f * mCellularJitterModifier;
-
-        int xPrimed = (xr - 1) * PrimeX;
-        int yPrimedBase = (yr - 1) * PrimeY;
-
-        switch( mCellularDistanceFunction )
-        {
-        default:
-        case CellularDistanceFunction_Euclidean:
-        case CellularDistanceFunction_EuclideanSq:
-            for( int xi = xr - 1; xi <= xr + 1; xi++ )
-            {
-                int yPrimed = yPrimedBase;
-
-                for( int yi = yr - 1; yi <= yr + 1; yi++ )
-                {
-                    int hash = Hash( seed, xPrimed, yPrimed );
-                    int idx = hash & (255 << 1);
-
-                    float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[ idx ] * cellularJitter;
-                    float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[ idx | 1 ] * cellularJitter;
-
-                    float newDistance = vecX * vecX + vecY * vecY;
-
-                    distance1 = FastMax( FastMin( distance1, newDistance ), distance0 );
-                    if( newDistance < distance0 )
-                    {
-                        distance0 = newDistance;
-                        closestHash = hash;
-                    }
-                    yPrimed += PrimeY;
-                }
-                xPrimed += PrimeX;
-            }
-            break;
-        case CellularDistanceFunction_Manhattan:
-            for( int xi = xr - 1; xi <= xr + 1; xi++ )
-            {
-                int yPrimed = yPrimedBase;
-
-                for( int yi = yr - 1; yi <= yr + 1; yi++ )
-                {
-                    int hash = Hash( seed, xPrimed, yPrimed );
-                    int idx = hash & (255 << 1);
-
-                    float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[ idx ] * cellularJitter;
-                    float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[ idx | 1 ] * cellularJitter;
-
-                    float newDistance = FastAbs( vecX ) + FastAbs( vecY );
-
-                    distance1 = FastMax( FastMin( distance1, newDistance ), distance0 );
-                    if( newDistance < distance0 )
-                    {
-                        distance0 = newDistance;
-                        closestHash = hash;
-                    }
-                    yPrimed += PrimeY;
-                }
-                xPrimed += PrimeX;
-            }
-            break;
-        case CellularDistanceFunction_Hybrid:
-            for( int xi = xr - 1; xi <= xr + 1; xi++ )
-            {
-                int yPrimed = yPrimedBase;
-
-                for( int yi = yr - 1; yi <= yr + 1; yi++ )
-                {
-                    int hash = Hash( seed, xPrimed, yPrimed );
-                    int idx = hash & (255 << 1);
-
-                    float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[ idx ] * cellularJitter;
-                    float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[ idx | 1 ] * cellularJitter;
-
-                    float newDistance = (FastAbs( vecX ) + FastAbs( vecY )) + (vecX * vecX + vecY * vecY);
-
-                    distance1 = FastMax( FastMin( distance1, newDistance ), distance0 );
-                    if( newDistance < distance0 )
-                    {
-                        distance0 = newDistance;
-                        closestHash = hash;
-                    }
-                    yPrimed += PrimeY;
-                }
-                xPrimed += PrimeX;
-            }
-            break;
-        }
-
-        if( mCellularDistanceFunction == CellularDistanceFunction_Euclidean && mCellularReturnType >= CellularReturnType_Distance )
-        {
-            distance0 = FastSqrt( distance0 );
-
-            if( mCellularReturnType >= CellularReturnType_Distance2 )
-            {
-                distance1 = FastSqrt( distance1 );
-            }
-        }
-
-        switch( mCellularReturnType )
-        {
-        case CellularReturnType_CellValue:
-            return closestHash * (1 / 2147483648.0f);
-        case CellularReturnType_Distance:
-            return distance0 - 1;
-        case CellularReturnType_Distance2:
-            return distance1 - 1;
-        case CellularReturnType_Distance2Add:
-            return (distance1 + distance0) * 0.5f - 1;
-        case CellularReturnType_Distance2Sub:
-            return distance1 - distance0 - 1;
-        case CellularReturnType_Distance2Mul:
-            return distance1 * distance0 * 0.5f - 1;
-        case CellularReturnType_Distance2Div:
-            return distance0 / distance1 - 1;
-        default:
-            return 0;
-        }
-    }
-
-    template <typename FNfloat>
-    float SingleCellular( int seed, FNfloat x, FNfloat y, FNfloat z )
-    {
-        int xr = FastRound( x );
-        int yr = FastRound( y );
-        int zr = FastRound( z );
-
-        float distance0 = 1e10f;
-        float distance1 = 1e10f;
-        int closestHash = 0;
-
-        float cellularJitter = 0.39614353f * mCellularJitterModifier;
-
-        int xPrimed = (xr - 1) * PrimeX;
-        int yPrimedBase = (yr - 1) * PrimeY;
-        int zPrimedBase = (zr - 1) * PrimeZ;
-
-        switch( mCellularDistanceFunction )
-        {
-        case CellularDistanceFunction_Euclidean:
-        case CellularDistanceFunction_EuclideanSq:
-            for( int xi = xr - 1; xi <= xr + 1; xi++ )
-            {
-                int yPrimed = yPrimedBase;
-
-                for( int yi = yr - 1; yi <= yr + 1; yi++ )
-                {
-                    int zPrimed = zPrimedBase;
-
-                    for( int zi = zr - 1; zi <= zr + 1; zi++ )
-                    {
-                        int hash = Hash( seed, xPrimed, yPrimed, zPrimed );
-                        int idx = hash & (255 << 2);
-
-                        float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[ idx ] * cellularJitter;
-                        float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[ idx | 1 ] * cellularJitter;
-                        float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[ idx | 2 ] * cellularJitter;
-
-                        float newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
-
-                        distance1 = FastMax( FastMin( distance1, newDistance ), distance0 );
-                        if( newDistance < distance0 )
-                        {
-                            distance0 = newDistance;
-                            closestHash = hash;
-                        }
-                        zPrimed += PrimeZ;
-                    }
-                    yPrimed += PrimeY;
-                }
-                xPrimed += PrimeX;
-            }
-            break;
-        case CellularDistanceFunction_Manhattan:
-            for( int xi = xr - 1; xi <= xr + 1; xi++ )
-            {
-                int yPrimed = yPrimedBase;
-
-                for( int yi = yr - 1; yi <= yr + 1; yi++ )
-                {
-                    int zPrimed = zPrimedBase;
-
-                    for( int zi = zr - 1; zi <= zr + 1; zi++ )
-                    {
-                        int hash = Hash( seed, xPrimed, yPrimed, zPrimed );
-                        int idx = hash & (255 << 2);
-
-                        float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[ idx ] * cellularJitter;
-                        float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[ idx | 1 ] * cellularJitter;
-                        float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[ idx | 2 ] * cellularJitter;
-
-                        float newDistance = FastAbs( vecX ) + FastAbs( vecY ) + FastAbs( vecZ );
-
-                        distance1 = FastMax( FastMin( distance1, newDistance ), distance0 );
-                        if( newDistance < distance0 )
-                        {
-                            distance0 = newDistance;
-                            closestHash = hash;
-                        }
-                        zPrimed += PrimeZ;
-                    }
-                    yPrimed += PrimeY;
-                }
-                xPrimed += PrimeX;
-            }
-            break;
-        case CellularDistanceFunction_Hybrid:
-            for( int xi = xr - 1; xi <= xr + 1; xi++ )
-            {
-                int yPrimed = yPrimedBase;
-
-                for( int yi = yr - 1; yi <= yr + 1; yi++ )
-                {
-                    int zPrimed = zPrimedBase;
-
-                    for( int zi = zr - 1; zi <= zr + 1; zi++ )
-                    {
-                        int hash = Hash( seed, xPrimed, yPrimed, zPrimed );
-                        int idx = hash & (255 << 2);
-
-                        float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[ idx ] * cellularJitter;
-                        float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[ idx | 1 ] * cellularJitter;
-                        float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[ idx | 2 ] * cellularJitter;
-
-                        float newDistance = (FastAbs( vecX ) + FastAbs( vecY ) + FastAbs( vecZ )) + (vecX * vecX + vecY * vecY + vecZ * vecZ);
-
-                        distance1 = FastMax( FastMin( distance1, newDistance ), distance0 );
-                        if( newDistance < distance0 )
-                        {
-                            distance0 = newDistance;
-                            closestHash = hash;
-                        }
-                        zPrimed += PrimeZ;
-                    }
-                    yPrimed += PrimeY;
-                }
-                xPrimed += PrimeX;
-            }
-            break;
-        default:
-            break;
-        }
-
-        if( mCellularDistanceFunction == CellularDistanceFunction_Euclidean && mCellularReturnType >= CellularReturnType_Distance )
-        {
-            distance0 = FastSqrt( distance0 );
-
-            if( mCellularReturnType >= CellularReturnType_Distance2 )
-            {
-                distance1 = FastSqrt( distance1 );
-            }
-        }
-
-        switch( mCellularReturnType )
-        {
-        case CellularReturnType_CellValue:
-            return (float)closestHash * (1.f / 2147483648.0f);
-        case CellularReturnType_Distance:
-            return distance0 - 1;
-        case CellularReturnType_Distance2:
-            return distance1 - 1;
-        case CellularReturnType_Distance2Add:
-            return (distance1 + distance0) * 0.5f - 1;
-        case CellularReturnType_Distance2Sub:
-            return distance1 - distance0 - 1;
-        case CellularReturnType_Distance2Mul:
-            return distance1 * distance0 * 0.5f - 1;
-        case CellularReturnType_Distance2Div:
-            return distance0 / distance1 - 1;
-        default:
-            return 0;
-        }
-    }
-
-
-    // Perlin Noise
-
-    template <typename FNfloat>
-    float SinglePerlin( int seed, FNfloat x, FNfloat y )
-    {
-        int x0 = FastFloor( x );
-        int y0 = FastFloor( y );
-
-        float xd0 = (float)(x - x0);
-        float yd0 = (float)(y - y0);
-        float xd1 = xd0 - 1;
-        float yd1 = yd0 - 1;
-
-        float xs = InterpQuintic( xd0 );
-        float ys = InterpQuintic( yd0 );
-
-        x0 *= PrimeX;
-        y0 *= PrimeY;
-        int x1 = x0 + PrimeX;
-        int y1 = y0 + PrimeY;
-
-        float xf0 = Lerp( GradCoord( seed, x0, y0, xd0, yd0 ), GradCoord( seed, x1, y0, xd1, yd0 ), xs );
-        float xf1 = Lerp( GradCoord( seed, x0, y1, xd0, yd1 ), GradCoord( seed, x1, y1, xd1, yd1 ), xs );
-
-        return Lerp( xf0, xf1, ys ) * 1.4247691104677813f;
-    }
-
-    template <typename FNfloat>
-    float SinglePerlin( int seed, FNfloat x, FNfloat y, FNfloat z )
-    {
-        int x0 = FastFloor( x );
-        int y0 = FastFloor( y );
-        int z0 = FastFloor( z );
-
-        float xd0 = (float)(x - x0);
-        float yd0 = (float)(y - y0);
-        float zd0 = (float)(z - z0);
-        float xd1 = xd0 - 1;
-        float yd1 = yd0 - 1;
-        float zd1 = zd0 - 1;
-
-        float xs = InterpQuintic( xd0 );
-        float ys = InterpQuintic( yd0 );
-        float zs = InterpQuintic( zd0 );
-
-        x0 *= PrimeX;
-        y0 *= PrimeY;
-        z0 *= PrimeZ;
-        int x1 = x0 + PrimeX;
-        int y1 = y0 + PrimeY;
-        int z1 = z0 + PrimeZ;
-
-        float xf00 = Lerp( GradCoord( seed, x0, y0, z0, xd0, yd0, zd0 ), GradCoord( seed, x1, y0, z0, xd1, yd0, zd0 ), xs );
-        float xf10 = Lerp( GradCoord( seed, x0, y1, z0, xd0, yd1, zd0 ), GradCoord( seed, x1, y1, z0, xd1, yd1, zd0 ), xs );
-        float xf01 = Lerp( GradCoord( seed, x0, y0, z1, xd0, yd0, zd1 ), GradCoord( seed, x1, y0, z1, xd1, yd0, zd1 ), xs );
-        float xf11 = Lerp( GradCoord( seed, x0, y1, z1, xd0, yd1, zd1 ), GradCoord( seed, x1, y1, z1, xd1, yd1, zd1 ), xs );
-
-        float yf0 = Lerp( xf00, xf10, ys );
-        float yf1 = Lerp( xf01, xf11, ys );
-
-        return Lerp( yf0, yf1, zs ) * 0.964921414852142333984375f;
-    }
-
-
-    // Value Cubic Noise
-
-    template <typename FNfloat>
-    float SingleValueCubic( int seed, FNfloat x, FNfloat y )
-    {
-        int x1 = FastFloor( x );
-        int y1 = FastFloor( y );
-
-        float xs = (float)(x - x1);
-        float ys = (float)(y - y1);
-
-        x1 *= PrimeX;
-        y1 *= PrimeY;
-        int x0 = x1 - PrimeX;
-        int y0 = y1 - PrimeY;
-        int x2 = x1 + PrimeX;
-        int y2 = y1 + PrimeY;
-        int x3 = x1 + (int)((long)PrimeX << 1);
-        int y3 = y1 + (int)((long)PrimeY << 1);
-
-        return CubicLerp(
-            CubicLerp( ValCoord( seed, x0, y0 ), ValCoord( seed, x1, y0 ), ValCoord( seed, x2, y0 ), ValCoord( seed, x3, y0 ),
-                       xs ),
-            CubicLerp( ValCoord( seed, x0, y1 ), ValCoord( seed, x1, y1 ), ValCoord( seed, x2, y1 ), ValCoord( seed, x3, y1 ),
-                       xs ),
-            CubicLerp( ValCoord( seed, x0, y2 ), ValCoord( seed, x1, y2 ), ValCoord( seed, x2, y2 ), ValCoord( seed, x3, y2 ),
-                       xs ),
-            CubicLerp( ValCoord( seed, x0, y3 ), ValCoord( seed, x1, y3 ), ValCoord( seed, x2, y3 ), ValCoord( seed, x3, y3 ),
-                       xs ),
-            ys ) * (1 / (1.5f * 1.5f));
-    }
-
-    template <typename FNfloat>
-    float SingleValueCubic( int seed, FNfloat x, FNfloat y, FNfloat z )
-    {
-        int x1 = FastFloor( x );
-        int y1 = FastFloor( y );
-        int z1 = FastFloor( z );
-
-        float xs = (float)(x - x1);
-        float ys = (float)(y - y1);
-        float zs = (float)(z - z1);
-
-        x1 *= PrimeX;
-        y1 *= PrimeY;
-        z1 *= PrimeZ;
-
-        int x0 = x1 - PrimeX;
-        int y0 = y1 - PrimeY;
-        int z0 = z1 - PrimeZ;
-        int x2 = x1 + PrimeX;
-        int y2 = y1 + PrimeY;
-        int z2 = z1 + PrimeZ;
-        int x3 = x1 + (int)((long)PrimeX << 1);
-        int y3 = y1 + (int)((long)PrimeY << 1);
-        int z3 = z1 + (int)((long)PrimeZ << 1);
-
-
-        return CubicLerp(
-            CubicLerp(
-                CubicLerp( ValCoord( seed, x0, y0, z0 ), ValCoord( seed, x1, y0, z0 ), ValCoord( seed, x2, y0, z0 ), ValCoord( seed, x3, y0, z0 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y1, z0 ), ValCoord( seed, x1, y1, z0 ), ValCoord( seed, x2, y1, z0 ), ValCoord( seed, x3, y1, z0 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y2, z0 ), ValCoord( seed, x1, y2, z0 ), ValCoord( seed, x2, y2, z0 ), ValCoord( seed, x3, y2, z0 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y3, z0 ), ValCoord( seed, x1, y3, z0 ), ValCoord( seed, x2, y3, z0 ), ValCoord( seed, x3, y3, z0 ), xs ),
-                ys ),
-            CubicLerp(
-                CubicLerp( ValCoord( seed, x0, y0, z1 ), ValCoord( seed, x1, y0, z1 ), ValCoord( seed, x2, y0, z1 ), ValCoord( seed, x3, y0, z1 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y1, z1 ), ValCoord( seed, x1, y1, z1 ), ValCoord( seed, x2, y1, z1 ), ValCoord( seed, x3, y1, z1 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y2, z1 ), ValCoord( seed, x1, y2, z1 ), ValCoord( seed, x2, y2, z1 ), ValCoord( seed, x3, y2, z1 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y3, z1 ), ValCoord( seed, x1, y3, z1 ), ValCoord( seed, x2, y3, z1 ), ValCoord( seed, x3, y3, z1 ), xs ),
-                ys ),
-            CubicLerp(
-                CubicLerp( ValCoord( seed, x0, y0, z2 ), ValCoord( seed, x1, y0, z2 ), ValCoord( seed, x2, y0, z2 ), ValCoord( seed, x3, y0, z2 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y1, z2 ), ValCoord( seed, x1, y1, z2 ), ValCoord( seed, x2, y1, z2 ), ValCoord( seed, x3, y1, z2 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y2, z2 ), ValCoord( seed, x1, y2, z2 ), ValCoord( seed, x2, y2, z2 ), ValCoord( seed, x3, y2, z2 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y3, z2 ), ValCoord( seed, x1, y3, z2 ), ValCoord( seed, x2, y3, z2 ), ValCoord( seed, x3, y3, z2 ), xs ),
-                ys ),
-            CubicLerp(
-                CubicLerp( ValCoord( seed, x0, y0, z3 ), ValCoord( seed, x1, y0, z3 ), ValCoord( seed, x2, y0, z3 ), ValCoord( seed, x3, y0, z3 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y1, z3 ), ValCoord( seed, x1, y1, z3 ), ValCoord( seed, x2, y1, z3 ), ValCoord( seed, x3, y1, z3 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y2, z3 ), ValCoord( seed, x1, y2, z3 ), ValCoord( seed, x2, y2, z3 ), ValCoord( seed, x3, y2, z3 ), xs ),
-                CubicLerp( ValCoord( seed, x0, y3, z3 ), ValCoord( seed, x1, y3, z3 ), ValCoord( seed, x2, y3, z3 ), ValCoord( seed, x3, y3, z3 ), xs ),
-                ys ),
-            zs ) * (1 / (1.5f * 1.5f * 1.5f));
-    }
-
-
-    // Value Noise
-
-    template <typename FNfloat>
-    float SingleValue( int seed, FNfloat x, FNfloat y )
-    {
-        int x0 = FastFloor( x );
-        int y0 = FastFloor( y );
-
-        float xs = InterpHermite( (float)(x - x0) );
-        float ys = InterpHermite( (float)(y - y0) );
-
-        x0 *= PrimeX;
-        y0 *= PrimeY;
-        int x1 = x0 + PrimeX;
-        int y1 = y0 + PrimeY;
-
-        float xf0 = Lerp( ValCoord( seed, x0, y0 ), ValCoord( seed, x1, y0 ), xs );
-        float xf1 = Lerp( ValCoord( seed, x0, y1 ), ValCoord( seed, x1, y1 ), xs );
-
-        return Lerp( xf0, xf1, ys );
-    }
-
-    template <typename FNfloat>
-    float SingleValue( int seed, FNfloat x, FNfloat y, FNfloat z )
-    {
-        int x0 = FastFloor( x );
-        int y0 = FastFloor( y );
-        int z0 = FastFloor( z );
-
-        float xs = InterpHermite( (float)(x - x0) );
-        float ys = InterpHermite( (float)(y - y0) );
-        float zs = InterpHermite( (float)(z - z0) );
-
-        x0 *= PrimeX;
-        y0 *= PrimeY;
-        z0 *= PrimeZ;
-        int x1 = x0 + PrimeX;
-        int y1 = y0 + PrimeY;
-        int z1 = z0 + PrimeZ;
-
-        float xf00 = Lerp( ValCoord( seed, x0, y0, z0 ), ValCoord( seed, x1, y0, z0 ), xs );
-        float xf10 = Lerp( ValCoord( seed, x0, y1, z0 ), ValCoord( seed, x1, y1, z0 ), xs );
-        float xf01 = Lerp( ValCoord( seed, x0, y0, z1 ), ValCoord( seed, x1, y0, z1 ), xs );
-        float xf11 = Lerp( ValCoord( seed, x0, y1, z1 ), ValCoord( seed, x1, y1, z1 ), xs );
-
-        float yf0 = Lerp( xf00, xf10, ys );
-        float yf1 = Lerp( xf01, xf11, ys );
-
-        return Lerp( yf0, yf1, zs );
-    }
-
-
-    // Domain Warp
-
-    template <typename FNfloat>
-    void DoSingleDomainWarp( int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr )
-    {
-        switch( mDomainWarpType )
-        {
-        case DomainWarpType_OpenSimplex2:
-            SingleDomainWarpSimplexGradient( seed, amp * 38.283687591552734375f, freq, x, y, xr, yr, false );
-            break;
-        case DomainWarpType_OpenSimplex2Reduced:
-            SingleDomainWarpSimplexGradient( seed, amp * 16.0f, freq, x, y, xr, yr, true );
-            break;
-        case DomainWarpType_BasicGrid:
-            SingleDomainWarpBasicGrid( seed, amp, freq, x, y, xr, yr );
-            break;
-        }
-    }
-
-    template <typename FNfloat>
-    void DoSingleDomainWarp( int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr )
-    {
-        switch( mDomainWarpType )
-        {
-        case DomainWarpType_OpenSimplex2:
-            SingleDomainWarpOpenSimplex2Gradient( seed, amp * 32.69428253173828125f, freq, x, y, z, xr, yr, zr, false );
-            break;
-        case DomainWarpType_OpenSimplex2Reduced:
-            SingleDomainWarpOpenSimplex2Gradient( seed, amp * 7.71604938271605f, freq, x, y, z, xr, yr, zr, true );
-            break;
-        case DomainWarpType_BasicGrid:
-            SingleDomainWarpBasicGrid( seed, amp, freq, x, y, z, xr, yr, zr );
-            break;
-        }
-    }
-
-
-    // Domain Warp Single Wrapper
-
-    template <typename FNfloat>
-    void DomainWarpSingle( FNfloat& x, FNfloat& y )
-    {
-        int seed = mSeed;
-        float amp = mDomainWarpAmp * mFractalBounding;
-        float freq = mFrequency;
-
-        FNfloat xs = x;
-        FNfloat ys = y;
-        TransformDomainWarpCoordinate( xs, ys );
-
-        DoSingleDomainWarp( seed, amp, freq, xs, ys, x, y );
-    }
-
-    template <typename FNfloat>
-    void DomainWarpSingle( FNfloat& x, FNfloat& y, FNfloat& z )
-    {
-        int seed = mSeed;
-        float amp = mDomainWarpAmp * mFractalBounding;
-        float freq = mFrequency;
-
-        FNfloat xs = x;
-        FNfloat ys = y;
-        FNfloat zs = z;
-        TransformDomainWarpCoordinate( xs, ys, zs );
-
-        DoSingleDomainWarp( seed, amp, freq, xs, ys, zs, x, y, z );
-    }
-
-
-    // Domain Warp Fractal Progressive
-
-    template <typename FNfloat>
-    void DomainWarpFractalProgressive( FNfloat& x, FNfloat& y )
-    {
-        int seed = mSeed;
-        float amp = mDomainWarpAmp * mFractalBounding;
-        float freq = mFrequency;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            FNfloat xs = x;
-            FNfloat ys = y;
-            TransformDomainWarpCoordinate( xs, ys );
-
-            DoSingleDomainWarp( seed, amp, freq, xs, ys, x, y );
-
-            seed++;
-            amp *= mGain;
-            freq *= mLacunarity;
-        }
-    }
-
-    template <typename FNfloat>
-    void DomainWarpFractalProgressive( FNfloat& x, FNfloat& y, FNfloat& z )
-    {
-        int seed = mSeed;
-        float amp = mDomainWarpAmp * mFractalBounding;
-        float freq = mFrequency;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            FNfloat xs = x;
-            FNfloat ys = y;
-            FNfloat zs = z;
-            TransformDomainWarpCoordinate( xs, ys, zs );
-
-            DoSingleDomainWarp( seed, amp, freq, xs, ys, zs, x, y, z );
-
-            seed++;
-            amp *= mGain;
-            freq *= mLacunarity;
-        }
-    }
-
-
-    // Domain Warp Fractal Independant
-
-    template <typename FNfloat>
-    void DomainWarpFractalIndependent( FNfloat& x, FNfloat& y )
-    {
-        FNfloat xs = x;
-        FNfloat ys = y;
-        TransformDomainWarpCoordinate( xs, ys );
-
-        int seed = mSeed;
-        float amp = mDomainWarpAmp * mFractalBounding;
-        float freq = mFrequency;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            DoSingleDomainWarp( seed, amp, freq, xs, ys, x, y );
-
-            seed++;
-            amp *= mGain;
-            freq *= mLacunarity;
-        }
-    }
-
-    template <typename FNfloat>
-    void DomainWarpFractalIndependent( FNfloat& x, FNfloat& y, FNfloat& z )
-    {
-        FNfloat xs = x;
-        FNfloat ys = y;
-        FNfloat zs = z;
-        TransformDomainWarpCoordinate( xs, ys, zs );
-
-        int seed = mSeed;
-        float amp = mDomainWarpAmp * mFractalBounding;
-        float freq = mFrequency;
-
-        for( int i = 0; i < mOctaves; i++ )
-        {
-            DoSingleDomainWarp( seed, amp, freq, xs, ys, zs, x, y, z );
-
-            seed++;
-            amp *= mGain;
-            freq *= mLacunarity;
-        }
-    }
+	float GradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd)
+	{
+		int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
+		hash ^= hash >> 15;
+		hash &= 63 << 2;
+
+		float xg = Lookup<float>::Gradients3D[hash];
+		float yg = Lookup<float>::Gradients3D[hash | 1];
+		float zg = Lookup<float>::Gradients3D[hash | 2];
+
+		return xd * xg + yd * yg + zd * zg;
+	}
+
+
+	void GradCoordOut(int seed, int xPrimed, int yPrimed, float& xo, float& yo)
+	{
+		int hash = Hash(seed, xPrimed, yPrimed) & (255 << 1);
+
+		xo = Lookup<float>::RandVecs2D[hash];
+		yo = Lookup<float>::RandVecs2D[hash | 1];
+	}
+
+
+	void GradCoordOut(int seed, int xPrimed, int yPrimed, int zPrimed, float& xo, float& yo, float& zo)
+	{
+		int hash = Hash(seed, xPrimed, yPrimed, zPrimed) & (255 << 2);
+
+		xo = Lookup<float>::RandVecs3D[hash];
+		yo = Lookup<float>::RandVecs3D[hash | 1];
+		zo = Lookup<float>::RandVecs3D[hash | 2];
+	}
+
+
+	void GradCoordDual(int seed, int xPrimed, int yPrimed, float xd, float yd, float& xo, float& yo)
+	{
+		int hash = Hash(seed, xPrimed, yPrimed);
+		int index1 = hash & (127 << 1);
+		int index2 = (hash >> 7) & (255 << 1);
+
+		float xg = Lookup<float>::Gradients2D[index1];
+		float yg = Lookup<float>::Gradients2D[index1 | 1];
+		float value = xd * xg + yd * yg;
+
+		float xgo = Lookup<float>::RandVecs2D[index2];
+		float ygo = Lookup<float>::RandVecs2D[index2 | 1];
+
+		xo = value * xgo;
+		yo = value * ygo;
+	}
+
+
+	void GradCoordDual(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd, float& xo, float& yo, float& zo)
+	{
+		int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
+		int index1 = hash & (63 << 2);
+		int index2 = (hash >> 6) & (255 << 2);
+
+		float xg = Lookup<float>::Gradients3D[index1];
+		float yg = Lookup<float>::Gradients3D[index1 | 1];
+		float zg = Lookup<float>::Gradients3D[index1 | 2];
+		float value = xd * xg + yd * yg + zd * zg;
+
+		float xgo = Lookup<float>::RandVecs3D[index2];
+		float ygo = Lookup<float>::RandVecs3D[index2 | 1];
+		float zgo = Lookup<float>::RandVecs3D[index2 | 2];
+
+		xo = value * xgo;
+		yo = value * ygo;
+		zo = value * zgo;
+	}
+
+
+	// Generic noise gen
+
+	template <typename FNfloat>
+	float GenNoiseSingle(int seed, FNfloat x, FNfloat y)
+	{
+		switch (mNoiseType)
+		{
+		case NoiseType_OpenSimplex2:
+			return SingleSimplex(seed, x, y);
+		case NoiseType_OpenSimplex2S:
+			return SingleOpenSimplex2S(seed, x, y);
+		case NoiseType_Cellular:
+			return SingleCellular(seed, x, y);
+		case NoiseType_Perlin:
+			return SinglePerlin(seed, x, y);
+		case NoiseType_ValueCubic:
+			return SingleValueCubic(seed, x, y);
+		case NoiseType_Value:
+			return SingleValue(seed, x, y);
+		default:
+			return 0;
+		}
+	}
+
+	template <typename FNfloat>
+	float GenNoiseSingle(int seed, FNfloat x, FNfloat y, FNfloat z)
+	{
+		switch (mNoiseType)
+		{
+		case NoiseType_OpenSimplex2:
+			return SingleOpenSimplex2(seed, x, y, z);
+		case NoiseType_OpenSimplex2S:
+			return SingleOpenSimplex2S(seed, x, y, z);
+		case NoiseType_Cellular:
+			return SingleCellular(seed, x, y, z);
+		case NoiseType_Perlin:
+			return SinglePerlin(seed, x, y, z);
+		case NoiseType_ValueCubic:
+			return SingleValueCubic(seed, x, y, z);
+		case NoiseType_Value:
+			return SingleValue(seed, x, y, z);
+		default:
+			return 0;
+		}
+	}
+
+
+	// Noise Coordinate Transforms (frequency, and possible skew or rotation)
+
+	template <typename FNfloat>
+	void TransformNoiseCoordinate(FNfloat& x, FNfloat& y)
+	{
+		x *= mFrequency;
+		y *= mFrequency;
+
+		switch (mNoiseType)
+		{
+		case NoiseType_OpenSimplex2:
+		case NoiseType_OpenSimplex2S:
+		{
+			const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
+			const FNfloat F2 = 0.5f * (SQRT3 - 1);
+			FNfloat t = (x + y) * F2;
+			x += t;
+			y += t;
+		}
+		break;
+		default:
+			break;
+		}
+	}
+
+	template <typename FNfloat>
+	void TransformNoiseCoordinate(FNfloat& x, FNfloat& y, FNfloat& z)
+	{
+		x *= mFrequency;
+		y *= mFrequency;
+		z *= mFrequency;
+
+		switch (mTransformType3D)
+		{
+		case TransformType3D_ImproveXYPlanes:
+		{
+			FNfloat xy = x + y;
+			FNfloat s2 = xy * -(FNfloat)0.211324865405187;
+			z *= (FNfloat)0.577350269189626;
+			x += s2 - z;
+			y = y + s2 - z;
+			z += xy * (FNfloat)0.577350269189626;
+		}
+		break;
+		case TransformType3D_ImproveXZPlanes:
+		{
+			FNfloat xz = x + z;
+			FNfloat s2 = xz * -(FNfloat)0.211324865405187;
+			y *= (FNfloat)0.577350269189626;
+			x += s2 - y;
+			z += s2 - y;
+			y += xz * (FNfloat)0.577350269189626;
+		}
+		break;
+		case TransformType3D_DefaultOpenSimplex2:
+		{
+			const FNfloat R3 = (FNfloat)(2.0 / 3.0);
+			FNfloat r = (x + y + z) * R3; // Rotation, not skew
+			x = r - x;
+			y = r - y;
+			z = r - z;
+		}
+		break;
+		default:
+			break;
+		}
+	}
+
+	void UpdateTransformType3D()
+	{
+		switch (mRotationType3D)
+		{
+		case RotationType3D_ImproveXYPlanes:
+			mTransformType3D = TransformType3D_ImproveXYPlanes;
+			break;
+		case RotationType3D_ImproveXZPlanes:
+			mTransformType3D = TransformType3D_ImproveXZPlanes;
+			break;
+		default:
+			switch (mNoiseType)
+			{
+			case NoiseType_OpenSimplex2:
+			case NoiseType_OpenSimplex2S:
+				mTransformType3D = TransformType3D_DefaultOpenSimplex2;
+				break;
+			default:
+				mTransformType3D = TransformType3D_None;
+				break;
+			}
+			break;
+		}
+	}
+
+
+	// Domain Warp Coordinate Transforms
+
+	template <typename FNfloat>
+	void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y)
+	{
+		switch (mDomainWarpType)
+		{
+		case DomainWarpType_OpenSimplex2:
+		case DomainWarpType_OpenSimplex2Reduced:
+		{
+			const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
+			const FNfloat F2 = 0.5f * (SQRT3 - 1);
+			FNfloat t = (x + y) * F2;
+			x += t;
+			y += t;
+		}
+		break;
+		default:
+			break;
+		}
+	}
+
+	template <typename FNfloat>
+	void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y, FNfloat& z)
+	{
+		switch (mWarpTransformType3D)
+		{
+		case TransformType3D_ImproveXYPlanes:
+		{
+			FNfloat xy = x + y;
+			FNfloat s2 = xy * -(FNfloat)0.211324865405187;
+			z *= (FNfloat)0.577350269189626;
+			x += s2 - z;
+			y = y + s2 - z;
+			z += xy * (FNfloat)0.577350269189626;
+		}
+		break;
+		case TransformType3D_ImproveXZPlanes:
+		{
+			FNfloat xz = x + z;
+			FNfloat s2 = xz * -(FNfloat)0.211324865405187;
+			y *= (FNfloat)0.577350269189626;
+			x += s2 - y;
+			z += s2 - y;
+			y += xz * (FNfloat)0.577350269189626;
+		}
+		break;
+		case TransformType3D_DefaultOpenSimplex2:
+		{
+			const FNfloat R3 = (FNfloat)(2.0 / 3.0);
+			FNfloat r = (x + y + z) * R3; // Rotation, not skew
+			x = r - x;
+			y = r - y;
+			z = r - z;
+		}
+		break;
+		default:
+			break;
+		}
+	}
+
+	void UpdateWarpTransformType3D()
+	{
+		switch (mRotationType3D)
+		{
+		case RotationType3D_ImproveXYPlanes:
+			mWarpTransformType3D = TransformType3D_ImproveXYPlanes;
+			break;
+		case RotationType3D_ImproveXZPlanes:
+			mWarpTransformType3D = TransformType3D_ImproveXZPlanes;
+			break;
+		default:
+			switch (mDomainWarpType)
+			{
+			case DomainWarpType_OpenSimplex2:
+			case DomainWarpType_OpenSimplex2Reduced:
+				mWarpTransformType3D = TransformType3D_DefaultOpenSimplex2;
+				break;
+			default:
+				mWarpTransformType3D = TransformType3D_None;
+				break;
+			}
+			break;
+		}
+	}
+
+
+	// Fractal FBm
+
+	template <typename FNfloat>
+	float GenFractalFBm(FNfloat x, FNfloat y)
+	{
+		int seed = mSeed;
+		float sum = 0;
+		float amp = mFractalBounding;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			float noise = GenNoiseSingle(seed++, x, y);
+			sum += noise * amp;
+			amp *= Lerp(1.0f, FastMin(noise + 1, 2) * 0.5f, mWeightedStrength);
+
+			x *= mLacunarity;
+			y *= mLacunarity;
+			amp *= mGain;
+		}
+
+		return sum;
+	}
+
+	template <typename FNfloat>
+	float GenFractalFBm(FNfloat x, FNfloat y, FNfloat z)
+	{
+		int seed = mSeed;
+		float sum = 0;
+		float amp = mFractalBounding;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			float noise = GenNoiseSingle(seed++, x, y, z);
+			sum += noise * amp;
+			amp *= Lerp(1.0f, (noise + 1) * 0.5f, mWeightedStrength);
+
+			x *= mLacunarity;
+			y *= mLacunarity;
+			z *= mLacunarity;
+			amp *= mGain;
+		}
+
+		return sum;
+	}
+
+
+	// Fractal Ridged
+
+	template <typename FNfloat>
+	float GenFractalRidged(FNfloat x, FNfloat y)
+	{
+		int seed = mSeed;
+		float sum = 0;
+		float amp = mFractalBounding;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			float noise = FastAbs(GenNoiseSingle(seed++, x, y));
+			sum += (noise * -2 + 1) * amp;
+			amp *= Lerp(1.0f, 1 - noise, mWeightedStrength);
+
+			x *= mLacunarity;
+			y *= mLacunarity;
+			amp *= mGain;
+		}
+
+		return sum;
+	}
+
+	template <typename FNfloat>
+	float GenFractalRidged(FNfloat x, FNfloat y, FNfloat z)
+	{
+		int seed = mSeed;
+		float sum = 0;
+		float amp = mFractalBounding;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			float noise = FastAbs(GenNoiseSingle(seed++, x, y, z));
+			sum += (noise * -2 + 1) * amp;
+			amp *= Lerp(1.0f, 1 - noise, mWeightedStrength);
+
+			x *= mLacunarity;
+			y *= mLacunarity;
+			z *= mLacunarity;
+			amp *= mGain;
+		}
+
+		return sum;
+	}
+
+
+	// Fractal PingPong 
+
+	template <typename FNfloat>
+	float GenFractalPingPong(FNfloat x, FNfloat y)
+	{
+		int seed = mSeed;
+		float sum = 0;
+		float amp = mFractalBounding;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			float noise = PingPong((GenNoiseSingle(seed++, x, y) + 1) * mPingPongStength);
+			sum += (noise - 0.5f) * 2 * amp;
+			amp *= Lerp(1.0f, noise, mWeightedStrength);
+
+			x *= mLacunarity;
+			y *= mLacunarity;
+			amp *= mGain;
+		}
+
+		return sum;
+	}
+
+	template <typename FNfloat>
+	float GenFractalPingPong(FNfloat x, FNfloat y, FNfloat z)
+	{
+		int seed = mSeed;
+		float sum = 0;
+		float amp = mFractalBounding;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			float noise = PingPong((GenNoiseSingle(seed++, x, y, z) + 1) * mPingPongStength);
+			sum += (noise - 0.5f) * 2 * amp;
+			amp *= Lerp(1.0f, noise, mWeightedStrength);
+
+			x *= mLacunarity;
+			y *= mLacunarity;
+			z *= mLacunarity;
+			amp *= mGain;
+		}
+
+		return sum;
+	}
+
+
+	// Simplex/OpenSimplex2 Noise
+
+	template <typename FNfloat>
+	float SingleSimplex(int seed, FNfloat x, FNfloat y)
+	{
+		// 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
+
+		const float SQRT3 = 1.7320508075688772935274463415059f;
+		const float G2 = (3 - SQRT3) / 6;
+
+		/*
+		 * --- Skew moved to TransformNoiseCoordinate method ---
+		 * const FNfloat F2 = 0.5f * (SQRT3 - 1);
+		 * FNfloat s = (x + y) * F2;
+		 * x += s; y += s;
+		*/
+
+		int i = FastFloor(x);
+		int j = FastFloor(y);
+		float xi = (float)(x - i);
+		float yi = (float)(y - j);
+
+		float t = (xi + yi) * G2;
+		float x0 = (float)(xi - t);
+		float y0 = (float)(yi - t);
+
+		i *= PrimeX;
+		j *= PrimeY;
+
+		float n0, n1, n2;
+
+		float a = 0.5f - x0 * x0 - y0 * y0;
+		if (a <= 0) n0 = 0;
+		else
+		{
+			n0 = (a * a) * (a * a) * GradCoord(seed, i, j, x0, y0);
+		}
+
+		float c = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
+		if (c <= 0) n2 = 0;
+		else
+		{
+			float x2 = x0 + (2 * (float)G2 - 1);
+			float y2 = y0 + (2 * (float)G2 - 1);
+			n2 = (c * c) * (c * c) * GradCoord(seed, i + PrimeX, j + PrimeY, x2, y2);
+		}
+
+		if (y0 > x0)
+		{
+			float x1 = x0 + (float)G2;
+			float y1 = y0 + ((float)G2 - 1);
+			float b = 0.5f - x1 * x1 - y1 * y1;
+			if (b <= 0) n1 = 0;
+			else
+			{
+				n1 = (b * b) * (b * b) * GradCoord(seed, i, j + PrimeY, x1, y1);
+			}
+		}
+		else
+		{
+			float x1 = x0 + ((float)G2 - 1);
+			float y1 = y0 + (float)G2;
+			float b = 0.5f - x1 * x1 - y1 * y1;
+			if (b <= 0) n1 = 0;
+			else
+			{
+				n1 = (b * b) * (b * b) * GradCoord(seed, i + PrimeX, j, x1, y1);
+			}
+		}
+
+		return (n0 + n1 + n2) * 99.83685446303647f;
+	}
+
+	template <typename FNfloat>
+	float SingleOpenSimplex2(int seed, FNfloat x, FNfloat y, FNfloat z)
+	{
+		// 3D OpenSimplex2 case uses two offset rotated cube grids.
+
+		/*
+		 * --- Rotation moved to TransformNoiseCoordinate method ---
+		 * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
+		 * FNfloat r = (x + y + z) * R3; // Rotation, not skew
+		 * x = r - x; y = r - y; z = r - z;
+		*/
+
+		int i = FastRound(x);
+		int j = FastRound(y);
+		int k = FastRound(z);
+		float x0 = (float)(x - i);
+		float y0 = (float)(y - j);
+		float z0 = (float)(z - k);
+
+		int xNSign = (int)(-1.0f - x0) | 1;
+		int yNSign = (int)(-1.0f - y0) | 1;
+		int zNSign = (int)(-1.0f - z0) | 1;
+
+		float ax0 = (float)xNSign * -x0;
+		float ay0 = (float)yNSign * -y0;
+		float az0 = (float)zNSign * -z0;
+
+		i *= PrimeX;
+		j *= PrimeY;
+		k *= PrimeZ;
+
+		float value = 0;
+		float a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
+
+		for (int l = 0; ; l++)
+		{
+			if (a > 0)
+			{
+				value += (a * a) * (a * a) * GradCoord(seed, i, j, k, x0, y0, z0);
+			}
+
+			float b = a + 1;
+			int i1 = i;
+			int j1 = j;
+			int k1 = k;
+			float x1 = x0;
+			float y1 = y0;
+			float z1 = z0;
+
+			if (ax0 >= ay0 && ax0 >= az0)
+			{
+				x1 += (float)xNSign;
+				b -= (float)(xNSign * 2) * x1;
+				i1 -= xNSign * PrimeX;
+			}
+			else if (ay0 > ax0 && ay0 >= az0)
+			{
+				y1 += (float)yNSign;
+				b -= (float)(yNSign * 2) * y1;
+				j1 -= yNSign * PrimeY;
+			}
+			else
+			{
+				z1 += (float)zNSign;
+				b -= (float)(zNSign * 2) * z1;
+				k1 -= zNSign * PrimeZ;
+			}
+
+			if (b > 0)
+			{
+				value += (b * b) * (b * b) * GradCoord(seed, i1, j1, k1, x1, y1, z1);
+			}
+
+			if (l == 1) break;
+
+			ax0 = 0.5f - ax0;
+			ay0 = 0.5f - ay0;
+			az0 = 0.5f - az0;
+
+			x0 = (float)xNSign * ax0;
+			y0 = (float)yNSign * ay0;
+			z0 = (float)zNSign * az0;
+
+			a += (0.75f - ax0) - (ay0 + az0);
+
+			i += (xNSign >> 1) & PrimeX;
+			j += (yNSign >> 1) & PrimeY;
+			k += (zNSign >> 1) & PrimeZ;
+
+			xNSign = -xNSign;
+			yNSign = -yNSign;
+			zNSign = -zNSign;
+
+			seed = ~seed;
+		}
+
+		return value * 32.69428253173828125f;
+	}
+
+
+	// OpenSimplex2S Noise
+
+	template <typename FNfloat>
+	float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y)
+	{
+		// 2D OpenSimplex2S case is a modified 2D simplex noise.
+
+		const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059;
+		const FNfloat G2 = (3 - SQRT3) / 6;
+
+		/*
+		 * --- Skew moved to TransformNoiseCoordinate method ---
+		 * const FNfloat F2 = 0.5f * (SQRT3 - 1);
+		 * FNfloat s = (x + y) * F2;
+		 * x += s; y += s;
+		*/
+
+		int i = FastFloor(x);
+		int j = FastFloor(y);
+		float xi = (float)(x - i);
+		float yi = (float)(y - j);
+
+		i *= PrimeX;
+		j *= PrimeY;
+		int i1 = i + PrimeX;
+		int j1 = j + PrimeY;
+
+		float t = (xi + yi) * (float)G2;
+		float x0 = xi - t;
+		float y0 = yi - t;
+
+		float a0 = (2.0f / 3.0f) - x0 * x0 - y0 * y0;
+		float value = (a0 * a0) * (a0 * a0) * GradCoord(seed, i, j, x0, y0);
+
+		float a1 = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
+		float x1 = x0 - (float)(1 - 2 * G2);
+		float y1 = y0 - (float)(1 - 2 * G2);
+		value += (a1 * a1) * (a1 * a1) * GradCoord(seed, i1, j1, x1, y1);
+
+		// Nested conditionals were faster than compact bit logic/arithmetic.
+		float xmyi = xi - yi;
+		if (t > G2)
+		{
+			if (xi + xmyi > 1)
+			{
+				float x2 = x0 + (float)(3 * G2 - 2);
+				float y2 = y0 + (float)(3 * G2 - 1);
+				float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
+				if (a2 > 0)
+				{
+					value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i + (PrimeX << 1), j + PrimeY, x2, y2);
+				}
+			}
+			else
+			{
+				float x2 = x0 + (float)G2;
+				float y2 = y0 + (float)(G2 - 1);
+				float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
+				if (a2 > 0)
+				{
+					value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j + PrimeY, x2, y2);
+				}
+			}
+
+			if (yi - xmyi > 1)
+			{
+				float x3 = x0 + (float)(3 * G2 - 1);
+				float y3 = y0 + (float)(3 * G2 - 2);
+				float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
+				if (a3 > 0)
+				{
+					value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + PrimeX, j + (PrimeY << 1), x3, y3);
+				}
+			}
+			else
+			{
+				float x3 = x0 + (float)(G2 - 1);
+				float y3 = y0 + (float)G2;
+				float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
+				if (a3 > 0)
+				{
+					value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + PrimeX, j, x3, y3);
+				}
+			}
+		}
+		else
+		{
+			if (xi + xmyi < 0)
+			{
+				float x2 = x0 + (float)(1 - G2);
+				float y2 = y0 - (float)G2;
+				float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
+				if (a2 > 0)
+				{
+					value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i - PrimeX, j, x2, y2);
+				}
+			}
+			else
+			{
+				float x2 = x0 + (float)(G2 - 1);
+				float y2 = y0 + (float)G2;
+				float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
+				if (a2 > 0)
+				{
+					value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i + PrimeX, j, x2, y2);
+				}
+			}
+
+			if (yi < xmyi)
+			{
+				float x2 = x0 - (float)G2;
+				float y2 = y0 - (float)(G2 - 1);
+				float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
+				if (a2 > 0)
+				{
+					value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j - PrimeY, x2, y2);
+				}
+			}
+			else
+			{
+				float x2 = x0 + (float)G2;
+				float y2 = y0 + (float)(G2 - 1);
+				float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
+				if (a2 > 0)
+				{
+					value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j + PrimeY, x2, y2);
+				}
+			}
+		}
+
+		return value * 18.24196194486065f;
+	}
+
+	template <typename FNfloat>
+	float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y, FNfloat z)
+	{
+		// 3D OpenSimplex2S case uses two offset rotated cube grids.
+
+		/*
+		 * --- Rotation moved to TransformNoiseCoordinate method ---
+		 * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
+		 * FNfloat r = (x + y + z) * R3; // Rotation, not skew
+		 * x = r - x; y = r - y; z = r - z;
+		*/
+
+		int i = FastFloor(x);
+		int j = FastFloor(y);
+		int k = FastFloor(z);
+		float xi = (float)(x - i);
+		float yi = (float)(y - j);
+		float zi = (float)(z - k);
+
+		i *= PrimeX;
+		j *= PrimeY;
+		k *= PrimeZ;
+		int seed2 = seed + 1293373;
+
+		int xNMask = (int)(-0.5f - xi);
+		int yNMask = (int)(-0.5f - yi);
+		int zNMask = (int)(-0.5f - zi);
+
+		float x0 = xi + (float)xNMask;
+		float y0 = yi + (float)yNMask;
+		float z0 = zi + (float)zNMask;
+		float a0 = 0.75f - x0 * x0 - y0 * y0 - z0 * z0;
+		float value = (a0 * a0) * (a0 * a0) * GradCoord(seed,
+			i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x0, y0, z0);
+
+		float x1 = xi - 0.5f;
+		float y1 = yi - 0.5f;
+		float z1 = zi - 0.5f;
+		float a1 = 0.75f - x1 * x1 - y1 * y1 - z1 * z1;
+		value += (a1 * a1) * (a1 * a1) * GradCoord(seed2,
+			i + PrimeX, j + PrimeY, k + PrimeZ, x1, y1, z1);
+
+		float xAFlipMask0 = (float)((xNMask | 1) << 1) * x1;
+		float yAFlipMask0 = (float)((yNMask | 1) << 1) * y1;
+		float zAFlipMask0 = (float)((zNMask | 1) << 1) * z1;
+		float xAFlipMask1 = (float)(-2 - (xNMask << 2)) * x1 - 1.0f;
+		float yAFlipMask1 = (float)(-2 - (yNMask << 2)) * y1 - 1.0f;
+		float zAFlipMask1 = (float)(-2 - (zNMask << 2)) * z1 - 1.0f;
+
+		bool skip5 = false;
+		float a2 = xAFlipMask0 + a0;
+		if (a2 > 0)
+		{
+			float x2 = x0 - (float)(xNMask | 1);
+			float y2 = y0;
+			float z2 = z0;
+			value += (a2 * a2) * (a2 * a2) * GradCoord(seed,
+				i + (~xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x2, y2, z2);
+		}
+		else
+		{
+			float a3 = yAFlipMask0 + zAFlipMask0 + a0;
+			if (a3 > 0)
+			{
+				float x3 = x0;
+				float y3 = y0 - (float)(yNMask | 1);
+				float z3 = z0 - (float)(zNMask | 1);
+				value += (a3 * a3) * (a3 * a3) * GradCoord(seed,
+					i + (xNMask & PrimeX), j + (~yNMask & PrimeY), k + (~zNMask & PrimeZ), x3, y3, z3);
+			}
+
+			float a4 = xAFlipMask1 + a1;
+			if (a4 > 0)
+			{
+				float x4 = (float)(xNMask | 1) + x1;
+				float y4 = y1;
+				float z4 = z1;
+				value += (a4 * a4) * (a4 * a4) * GradCoord(seed2,
+					i + (xNMask & (PrimeX * 2)), j + PrimeY, k + PrimeZ, x4, y4, z4);
+				skip5 = true;
+			}
+		}
+
+		bool skip9 = false;
+		float a6 = yAFlipMask0 + a0;
+		if (a6 > 0)
+		{
+			float x6 = x0;
+			float y6 = y0 - (float)(yNMask | 1);
+			float z6 = z0;
+			value += (a6 * a6) * (a6 * a6) * GradCoord(seed,
+				i + (xNMask & PrimeX), j + (~yNMask & PrimeY), k + (zNMask & PrimeZ), x6, y6, z6);
+		}
+		else
+		{
+			float a7 = xAFlipMask0 + zAFlipMask0 + a0;
+			if (a7 > 0)
+			{
+				float x7 = x0 - (float)(xNMask | 1);
+				float y7 = y0;
+				float z7 = z0 - (float)(zNMask | 1);
+				value += (a7 * a7) * (a7 * a7) * GradCoord(seed,
+					i + (~xNMask & PrimeX), j + (yNMask & PrimeY), k + (~zNMask & PrimeZ), x7, y7, z7);
+			}
+
+			float a8 = yAFlipMask1 + a1;
+			if (a8 > 0)
+			{
+				float x8 = x1;
+				float y8 = (float)(yNMask | 1) + y1;
+				float z8 = z1;
+				value += (a8 * a8) * (a8 * a8) * GradCoord(seed2,
+					i + PrimeX, j + (yNMask & (PrimeY << 1)), k + PrimeZ, x8, y8, z8);
+				skip9 = true;
+			}
+		}
+
+		bool skipD = false;
+		float aA = zAFlipMask0 + a0;
+		if (aA > 0)
+		{
+			float xA = x0;
+			float yA = y0;
+			float zA = z0 - (float)(zNMask | 1);
+			value += (aA * aA) * (aA * aA) * GradCoord(seed,
+				i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (~zNMask & PrimeZ), xA, yA, zA);
+		}
+		else
+		{
+			float aB = xAFlipMask0 + yAFlipMask0 + a0;
+			if (aB > 0)
+			{
+				float xB = x0 - (float)(xNMask | 1);
+				float yB = y0 - (float)(yNMask | 1);
+				float zB = z0;
+				value += (aB * aB) * (aB * aB) * GradCoord(seed,
+					i + (~xNMask & PrimeX), j + (~yNMask & PrimeY), k + (zNMask & PrimeZ), xB, yB, zB);
+			}
+
+			float aC = zAFlipMask1 + a1;
+			if (aC > 0)
+			{
+				float xC = x1;
+				float yC = y1;
+				float zC = (float)(zNMask | 1) + z1;
+				value += (aC * aC) * (aC * aC) * GradCoord(seed2,
+					i + PrimeX, j + PrimeY, k + (zNMask & (PrimeZ << 1)), xC, yC, zC);
+				skipD = true;
+			}
+		}
+
+		if (!skip5)
+		{
+			float a5 = yAFlipMask1 + zAFlipMask1 + a1;
+			if (a5 > 0)
+			{
+				float x5 = x1;
+				float y5 = (float)(yNMask | 1) + y1;
+				float z5 = (float)(zNMask | 1) + z1;
+				value += (a5 * a5) * (a5 * a5) * GradCoord(seed2,
+					i + PrimeX, j + (yNMask & (PrimeY << 1)), k + (zNMask & (PrimeZ << 1)), x5, y5, z5);
+			}
+		}
+
+		if (!skip9)
+		{
+			float a9 = xAFlipMask1 + zAFlipMask1 + a1;
+			if (a9 > 0)
+			{
+				float x9 = (float)(xNMask | 1) + x1;
+				float y9 = y1;
+				float z9 = (float)(zNMask | 1) + z1;
+				value += (a9 * a9) * (a9 * a9) * GradCoord(seed2,
+					i + (xNMask & (PrimeX * 2)), j + PrimeY, k + (zNMask & (PrimeZ << 1)), x9, y9, z9);
+			}
+		}
+
+		if (!skipD)
+		{
+			float aD = xAFlipMask1 + yAFlipMask1 + a1;
+			if (aD > 0)
+			{
+				float xD = (float)(xNMask | 1) + x1;
+				float yD = (float)(yNMask | 1) + y1;
+				float zD = z1;
+				value += (aD * aD) * (aD * aD) * GradCoord(seed2,
+					i + (xNMask & (PrimeX << 1)), j + (yNMask & (PrimeY << 1)), k + PrimeZ, xD, yD, zD);
+			}
+		}
+
+		return value * 9.046026385208288f;
+	}
+
+
+	// Cellular Noise
+
+	template <typename FNfloat>
+	float SingleCellular(int seed, FNfloat x, FNfloat y)
+	{
+		int xr = FastRound(x);
+		int yr = FastRound(y);
+
+		float distance0 = 1e10f;
+		float distance1 = 1e10f;
+		int closestHash = 0;
+
+		float cellularJitter = 0.43701595f * mCellularJitterModifier;
+
+		int xPrimed = (xr - 1) * PrimeX;
+		int yPrimedBase = (yr - 1) * PrimeY;
+
+		switch (mCellularDistanceFunction)
+		{
+		default:
+		case CellularDistanceFunction_Euclidean:
+		case CellularDistanceFunction_EuclideanSq:
+			for (int xi = xr - 1; xi <= xr + 1; xi++)
+			{
+				int yPrimed = yPrimedBase;
+
+				for (int yi = yr - 1; yi <= yr + 1; yi++)
+				{
+					int hash = Hash(seed, xPrimed, yPrimed);
+					int idx = hash & (255 << 1);
+
+					float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[idx] * cellularJitter;
+					float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[idx | 1] * cellularJitter;
+
+					float newDistance = vecX * vecX + vecY * vecY;
+
+					distance1 = FastMax(FastMin(distance1, newDistance), distance0);
+					if (newDistance < distance0)
+					{
+						distance0 = newDistance;
+						closestHash = hash;
+					}
+					yPrimed += PrimeY;
+				}
+				xPrimed += PrimeX;
+			}
+			break;
+		case CellularDistanceFunction_Manhattan:
+			for (int xi = xr - 1; xi <= xr + 1; xi++)
+			{
+				int yPrimed = yPrimedBase;
+
+				for (int yi = yr - 1; yi <= yr + 1; yi++)
+				{
+					int hash = Hash(seed, xPrimed, yPrimed);
+					int idx = hash & (255 << 1);
+
+					float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[idx] * cellularJitter;
+					float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[idx | 1] * cellularJitter;
+
+					float newDistance = FastAbs(vecX) + FastAbs(vecY);
+
+					distance1 = FastMax(FastMin(distance1, newDistance), distance0);
+					if (newDistance < distance0)
+					{
+						distance0 = newDistance;
+						closestHash = hash;
+					}
+					yPrimed += PrimeY;
+				}
+				xPrimed += PrimeX;
+			}
+			break;
+		case CellularDistanceFunction_Hybrid:
+			for (int xi = xr - 1; xi <= xr + 1; xi++)
+			{
+				int yPrimed = yPrimedBase;
+
+				for (int yi = yr - 1; yi <= yr + 1; yi++)
+				{
+					int hash = Hash(seed, xPrimed, yPrimed);
+					int idx = hash & (255 << 1);
+
+					float vecX = (float)(xi - x) + Lookup<float>::RandVecs2D[idx] * cellularJitter;
+					float vecY = (float)(yi - y) + Lookup<float>::RandVecs2D[idx | 1] * cellularJitter;
+
+					float newDistance = (FastAbs(vecX) + FastAbs(vecY)) + (vecX * vecX + vecY * vecY);
+
+					distance1 = FastMax(FastMin(distance1, newDistance), distance0);
+					if (newDistance < distance0)
+					{
+						distance0 = newDistance;
+						closestHash = hash;
+					}
+					yPrimed += PrimeY;
+				}
+				xPrimed += PrimeX;
+			}
+			break;
+		}
+
+		if (mCellularDistanceFunction == CellularDistanceFunction_Euclidean && mCellularReturnType >= CellularReturnType_Distance)
+		{
+			distance0 = FastSqrt(distance0);
+
+			if (mCellularReturnType >= CellularReturnType_Distance2)
+			{
+				distance1 = FastSqrt(distance1);
+			}
+		}
+
+		switch (mCellularReturnType)
+		{
+		case CellularReturnType_CellValue:
+			return closestHash * (1 / 2147483648.0f);
+		case CellularReturnType_Distance:
+			return distance0 - 1;
+		case CellularReturnType_Distance2:
+			return distance1 - 1;
+		case CellularReturnType_Distance2Add:
+			return (distance1 + distance0) * 0.5f - 1;
+		case CellularReturnType_Distance2Sub:
+			return distance1 - distance0 - 1;
+		case CellularReturnType_Distance2Mul:
+			return distance1 * distance0 * 0.5f - 1;
+		case CellularReturnType_Distance2Div:
+			return distance0 / distance1 - 1;
+		default:
+			return 0;
+		}
+	}
+
+	template <typename FNfloat>
+	float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z)
+	{
+		int xr = FastRound(x);
+		int yr = FastRound(y);
+		int zr = FastRound(z);
+
+		float distance0 = 1e10f;
+		float distance1 = 1e10f;
+		int closestHash = 0;
+
+		float cellularJitter = 0.39614353f * mCellularJitterModifier;
+
+		int xPrimed = (xr - 1) * PrimeX;
+		int yPrimedBase = (yr - 1) * PrimeY;
+		int zPrimedBase = (zr - 1) * PrimeZ;
+
+		switch (mCellularDistanceFunction)
+		{
+		case CellularDistanceFunction_Euclidean:
+		case CellularDistanceFunction_EuclideanSq:
+			for (int xi = xr - 1; xi <= xr + 1; xi++)
+			{
+				int yPrimed = yPrimedBase;
+
+				for (int yi = yr - 1; yi <= yr + 1; yi++)
+				{
+					int zPrimed = zPrimedBase;
+
+					for (int zi = zr - 1; zi <= zr + 1; zi++)
+					{
+						int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
+						int idx = hash & (255 << 2);
+
+						float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[idx] * cellularJitter;
+						float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[idx | 1] * cellularJitter;
+						float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[idx | 2] * cellularJitter;
+
+						float newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
+
+						distance1 = FastMax(FastMin(distance1, newDistance), distance0);
+						if (newDistance < distance0)
+						{
+							distance0 = newDistance;
+							closestHash = hash;
+						}
+						zPrimed += PrimeZ;
+					}
+					yPrimed += PrimeY;
+				}
+				xPrimed += PrimeX;
+			}
+			break;
+		case CellularDistanceFunction_Manhattan:
+			for (int xi = xr - 1; xi <= xr + 1; xi++)
+			{
+				int yPrimed = yPrimedBase;
+
+				for (int yi = yr - 1; yi <= yr + 1; yi++)
+				{
+					int zPrimed = zPrimedBase;
+
+					for (int zi = zr - 1; zi <= zr + 1; zi++)
+					{
+						int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
+						int idx = hash & (255 << 2);
+
+						float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[idx] * cellularJitter;
+						float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[idx | 1] * cellularJitter;
+						float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[idx | 2] * cellularJitter;
+
+						float newDistance = FastAbs(vecX) + FastAbs(vecY) + FastAbs(vecZ);
+
+						distance1 = FastMax(FastMin(distance1, newDistance), distance0);
+						if (newDistance < distance0)
+						{
+							distance0 = newDistance;
+							closestHash = hash;
+						}
+						zPrimed += PrimeZ;
+					}
+					yPrimed += PrimeY;
+				}
+				xPrimed += PrimeX;
+			}
+			break;
+		case CellularDistanceFunction_Hybrid:
+			for (int xi = xr - 1; xi <= xr + 1; xi++)
+			{
+				int yPrimed = yPrimedBase;
+
+				for (int yi = yr - 1; yi <= yr + 1; yi++)
+				{
+					int zPrimed = zPrimedBase;
+
+					for (int zi = zr - 1; zi <= zr + 1; zi++)
+					{
+						int hash = Hash(seed, xPrimed, yPrimed, zPrimed);
+						int idx = hash & (255 << 2);
+
+						float vecX = (float)(xi - x) + Lookup<float>::RandVecs3D[idx] * cellularJitter;
+						float vecY = (float)(yi - y) + Lookup<float>::RandVecs3D[idx | 1] * cellularJitter;
+						float vecZ = (float)(zi - z) + Lookup<float>::RandVecs3D[idx | 2] * cellularJitter;
+
+						float newDistance = (FastAbs(vecX) + FastAbs(vecY) + FastAbs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ);
+
+						distance1 = FastMax(FastMin(distance1, newDistance), distance0);
+						if (newDistance < distance0)
+						{
+							distance0 = newDistance;
+							closestHash = hash;
+						}
+						zPrimed += PrimeZ;
+					}
+					yPrimed += PrimeY;
+				}
+				xPrimed += PrimeX;
+			}
+			break;
+		default:
+			break;
+		}
+
+		if (mCellularDistanceFunction == CellularDistanceFunction_Euclidean && mCellularReturnType >= CellularReturnType_Distance)
+		{
+			distance0 = FastSqrt(distance0);
+
+			if (mCellularReturnType >= CellularReturnType_Distance2)
+			{
+				distance1 = FastSqrt(distance1);
+			}
+		}
+
+		switch (mCellularReturnType)
+		{
+		case CellularReturnType_CellValue:
+			return (float)closestHash * (1.f / 2147483648.0f);
+		case CellularReturnType_Distance:
+			return distance0 - 1;
+		case CellularReturnType_Distance2:
+			return distance1 - 1;
+		case CellularReturnType_Distance2Add:
+			return (distance1 + distance0) * 0.5f - 1;
+		case CellularReturnType_Distance2Sub:
+			return distance1 - distance0 - 1;
+		case CellularReturnType_Distance2Mul:
+			return distance1 * distance0 * 0.5f - 1;
+		case CellularReturnType_Distance2Div:
+			return distance0 / distance1 - 1;
+		default:
+			return 0;
+		}
+	}
+
+
+	// Perlin Noise
+
+	template <typename FNfloat>
+	float SinglePerlin(int seed, FNfloat x, FNfloat y)
+	{
+		int x0 = FastFloor(x);
+		int y0 = FastFloor(y);
+
+		float xd0 = (float)(x - x0);
+		float yd0 = (float)(y - y0);
+		float xd1 = xd0 - 1;
+		float yd1 = yd0 - 1;
+
+		float xs = InterpQuintic(xd0);
+		float ys = InterpQuintic(yd0);
+
+		x0 *= PrimeX;
+		y0 *= PrimeY;
+		int x1 = x0 + PrimeX;
+		int y1 = y0 + PrimeY;
+
+		float xf0 = Lerp(GradCoord(seed, x0, y0, xd0, yd0), GradCoord(seed, x1, y0, xd1, yd0), xs);
+		float xf1 = Lerp(GradCoord(seed, x0, y1, xd0, yd1), GradCoord(seed, x1, y1, xd1, yd1), xs);
+
+		return Lerp(xf0, xf1, ys) * 1.4247691104677813f;
+	}
+
+	template <typename FNfloat>
+	float SinglePerlin(int seed, FNfloat x, FNfloat y, FNfloat z)
+	{
+		int x0 = FastFloor(x);
+		int y0 = FastFloor(y);
+		int z0 = FastFloor(z);
+
+		float xd0 = (float)(x - x0);
+		float yd0 = (float)(y - y0);
+		float zd0 = (float)(z - z0);
+		float xd1 = xd0 - 1;
+		float yd1 = yd0 - 1;
+		float zd1 = zd0 - 1;
+
+		float xs = InterpQuintic(xd0);
+		float ys = InterpQuintic(yd0);
+		float zs = InterpQuintic(zd0);
+
+		x0 *= PrimeX;
+		y0 *= PrimeY;
+		z0 *= PrimeZ;
+		int x1 = x0 + PrimeX;
+		int y1 = y0 + PrimeY;
+		int z1 = z0 + PrimeZ;
+
+		float xf00 = Lerp(GradCoord(seed, x0, y0, z0, xd0, yd0, zd0), GradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs);
+		float xf10 = Lerp(GradCoord(seed, x0, y1, z0, xd0, yd1, zd0), GradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs);
+		float xf01 = Lerp(GradCoord(seed, x0, y0, z1, xd0, yd0, zd1), GradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs);
+		float xf11 = Lerp(GradCoord(seed, x0, y1, z1, xd0, yd1, zd1), GradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs);
+
+		float yf0 = Lerp(xf00, xf10, ys);
+		float yf1 = Lerp(xf01, xf11, ys);
+
+		return Lerp(yf0, yf1, zs) * 0.964921414852142333984375f;
+	}
+
+
+	// Value Cubic Noise
+
+	template <typename FNfloat>
+	float SingleValueCubic(int seed, FNfloat x, FNfloat y)
+	{
+		int x1 = FastFloor(x);
+		int y1 = FastFloor(y);
+
+		float xs = (float)(x - x1);
+		float ys = (float)(y - y1);
+
+		x1 *= PrimeX;
+		y1 *= PrimeY;
+		int x0 = x1 - PrimeX;
+		int y0 = y1 - PrimeY;
+		int x2 = x1 + PrimeX;
+		int y2 = y1 + PrimeY;
+		int x3 = x1 + (int)((long)PrimeX << 1);
+		int y3 = y1 + (int)((long)PrimeY << 1);
+
+		return CubicLerp(
+			CubicLerp(ValCoord(seed, x0, y0), ValCoord(seed, x1, y0), ValCoord(seed, x2, y0), ValCoord(seed, x3, y0),
+				xs),
+			CubicLerp(ValCoord(seed, x0, y1), ValCoord(seed, x1, y1), ValCoord(seed, x2, y1), ValCoord(seed, x3, y1),
+				xs),
+			CubicLerp(ValCoord(seed, x0, y2), ValCoord(seed, x1, y2), ValCoord(seed, x2, y2), ValCoord(seed, x3, y2),
+				xs),
+			CubicLerp(ValCoord(seed, x0, y3), ValCoord(seed, x1, y3), ValCoord(seed, x2, y3), ValCoord(seed, x3, y3),
+				xs),
+			ys) * (1 / (1.5f * 1.5f));
+	}
+
+	template <typename FNfloat>
+	float SingleValueCubic(int seed, FNfloat x, FNfloat y, FNfloat z)
+	{
+		int x1 = FastFloor(x);
+		int y1 = FastFloor(y);
+		int z1 = FastFloor(z);
+
+		float xs = (float)(x - x1);
+		float ys = (float)(y - y1);
+		float zs = (float)(z - z1);
+
+		x1 *= PrimeX;
+		y1 *= PrimeY;
+		z1 *= PrimeZ;
+
+		int x0 = x1 - PrimeX;
+		int y0 = y1 - PrimeY;
+		int z0 = z1 - PrimeZ;
+		int x2 = x1 + PrimeX;
+		int y2 = y1 + PrimeY;
+		int z2 = z1 + PrimeZ;
+		int x3 = x1 + (int)((long)PrimeX << 1);
+		int y3 = y1 + (int)((long)PrimeY << 1);
+		int z3 = z1 + (int)((long)PrimeZ << 1);
+
+
+		return CubicLerp(
+			CubicLerp(
+				CubicLerp(ValCoord(seed, x0, y0, z0), ValCoord(seed, x1, y0, z0), ValCoord(seed, x2, y0, z0), ValCoord(seed, x3, y0, z0), xs),
+				CubicLerp(ValCoord(seed, x0, y1, z0), ValCoord(seed, x1, y1, z0), ValCoord(seed, x2, y1, z0), ValCoord(seed, x3, y1, z0), xs),
+				CubicLerp(ValCoord(seed, x0, y2, z0), ValCoord(seed, x1, y2, z0), ValCoord(seed, x2, y2, z0), ValCoord(seed, x3, y2, z0), xs),
+				CubicLerp(ValCoord(seed, x0, y3, z0), ValCoord(seed, x1, y3, z0), ValCoord(seed, x2, y3, z0), ValCoord(seed, x3, y3, z0), xs),
+				ys),
+			CubicLerp(
+				CubicLerp(ValCoord(seed, x0, y0, z1), ValCoord(seed, x1, y0, z1), ValCoord(seed, x2, y0, z1), ValCoord(seed, x3, y0, z1), xs),
+				CubicLerp(ValCoord(seed, x0, y1, z1), ValCoord(seed, x1, y1, z1), ValCoord(seed, x2, y1, z1), ValCoord(seed, x3, y1, z1), xs),
+				CubicLerp(ValCoord(seed, x0, y2, z1), ValCoord(seed, x1, y2, z1), ValCoord(seed, x2, y2, z1), ValCoord(seed, x3, y2, z1), xs),
+				CubicLerp(ValCoord(seed, x0, y3, z1), ValCoord(seed, x1, y3, z1), ValCoord(seed, x2, y3, z1), ValCoord(seed, x3, y3, z1), xs),
+				ys),
+			CubicLerp(
+				CubicLerp(ValCoord(seed, x0, y0, z2), ValCoord(seed, x1, y0, z2), ValCoord(seed, x2, y0, z2), ValCoord(seed, x3, y0, z2), xs),
+				CubicLerp(ValCoord(seed, x0, y1, z2), ValCoord(seed, x1, y1, z2), ValCoord(seed, x2, y1, z2), ValCoord(seed, x3, y1, z2), xs),
+				CubicLerp(ValCoord(seed, x0, y2, z2), ValCoord(seed, x1, y2, z2), ValCoord(seed, x2, y2, z2), ValCoord(seed, x3, y2, z2), xs),
+				CubicLerp(ValCoord(seed, x0, y3, z2), ValCoord(seed, x1, y3, z2), ValCoord(seed, x2, y3, z2), ValCoord(seed, x3, y3, z2), xs),
+				ys),
+			CubicLerp(
+				CubicLerp(ValCoord(seed, x0, y0, z3), ValCoord(seed, x1, y0, z3), ValCoord(seed, x2, y0, z3), ValCoord(seed, x3, y0, z3), xs),
+				CubicLerp(ValCoord(seed, x0, y1, z3), ValCoord(seed, x1, y1, z3), ValCoord(seed, x2, y1, z3), ValCoord(seed, x3, y1, z3), xs),
+				CubicLerp(ValCoord(seed, x0, y2, z3), ValCoord(seed, x1, y2, z3), ValCoord(seed, x2, y2, z3), ValCoord(seed, x3, y2, z3), xs),
+				CubicLerp(ValCoord(seed, x0, y3, z3), ValCoord(seed, x1, y3, z3), ValCoord(seed, x2, y3, z3), ValCoord(seed, x3, y3, z3), xs),
+				ys),
+			zs) * (1 / (1.5f * 1.5f * 1.5f));
+	}
+
+
+	// Value Noise
+
+	template <typename FNfloat>
+	float SingleValue(int seed, FNfloat x, FNfloat y)
+	{
+		int x0 = FastFloor(x);
+		int y0 = FastFloor(y);
+
+		float xs = InterpHermite((float)(x - x0));
+		float ys = InterpHermite((float)(y - y0));
+
+		x0 *= PrimeX;
+		y0 *= PrimeY;
+		int x1 = x0 + PrimeX;
+		int y1 = y0 + PrimeY;
+
+		float xf0 = Lerp(ValCoord(seed, x0, y0), ValCoord(seed, x1, y0), xs);
+		float xf1 = Lerp(ValCoord(seed, x0, y1), ValCoord(seed, x1, y1), xs);
+
+		return Lerp(xf0, xf1, ys);
+	}
+
+	template <typename FNfloat>
+	float SingleValue(int seed, FNfloat x, FNfloat y, FNfloat z)
+	{
+		int x0 = FastFloor(x);
+		int y0 = FastFloor(y);
+		int z0 = FastFloor(z);
+
+		float xs = InterpHermite((float)(x - x0));
+		float ys = InterpHermite((float)(y - y0));
+		float zs = InterpHermite((float)(z - z0));
+
+		x0 *= PrimeX;
+		y0 *= PrimeY;
+		z0 *= PrimeZ;
+		int x1 = x0 + PrimeX;
+		int y1 = y0 + PrimeY;
+		int z1 = z0 + PrimeZ;
+
+		float xf00 = Lerp(ValCoord(seed, x0, y0, z0), ValCoord(seed, x1, y0, z0), xs);
+		float xf10 = Lerp(ValCoord(seed, x0, y1, z0), ValCoord(seed, x1, y1, z0), xs);
+		float xf01 = Lerp(ValCoord(seed, x0, y0, z1), ValCoord(seed, x1, y0, z1), xs);
+		float xf11 = Lerp(ValCoord(seed, x0, y1, z1), ValCoord(seed, x1, y1, z1), xs);
+
+		float yf0 = Lerp(xf00, xf10, ys);
+		float yf1 = Lerp(xf01, xf11, ys);
+
+		return Lerp(yf0, yf1, zs);
+	}
+
+
+	// Domain Warp
+
+	template <typename FNfloat>
+	void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr)
+	{
+		switch (mDomainWarpType)
+		{
+		case DomainWarpType_OpenSimplex2:
+			SingleDomainWarpSimplexGradient(seed, amp * 38.283687591552734375f, freq, x, y, xr, yr, false);
+			break;
+		case DomainWarpType_OpenSimplex2Reduced:
+			SingleDomainWarpSimplexGradient(seed, amp * 16.0f, freq, x, y, xr, yr, true);
+			break;
+		case DomainWarpType_BasicGrid:
+			SingleDomainWarpBasicGrid(seed, amp, freq, x, y, xr, yr);
+			break;
+		}
+	}
+
+	template <typename FNfloat>
+	void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr)
+	{
+		switch (mDomainWarpType)
+		{
+		case DomainWarpType_OpenSimplex2:
+			SingleDomainWarpOpenSimplex2Gradient(seed, amp * 32.69428253173828125f, freq, x, y, z, xr, yr, zr, false);
+			break;
+		case DomainWarpType_OpenSimplex2Reduced:
+			SingleDomainWarpOpenSimplex2Gradient(seed, amp * 7.71604938271605f, freq, x, y, z, xr, yr, zr, true);
+			break;
+		case DomainWarpType_BasicGrid:
+			SingleDomainWarpBasicGrid(seed, amp, freq, x, y, z, xr, yr, zr);
+			break;
+		}
+	}
+
+
+	// Domain Warp Single Wrapper
+
+	template <typename FNfloat>
+	void DomainWarpSingle(FNfloat& x, FNfloat& y)
+	{
+		int seed = mSeed;
+		float amp = mDomainWarpAmp * mFractalBounding;
+		float freq = mFrequency;
+
+		FNfloat xs = x;
+		FNfloat ys = y;
+		TransformDomainWarpCoordinate(xs, ys);
+
+		DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y);
+	}
+
+	template <typename FNfloat>
+	void DomainWarpSingle(FNfloat& x, FNfloat& y, FNfloat& z)
+	{
+		int seed = mSeed;
+		float amp = mDomainWarpAmp * mFractalBounding;
+		float freq = mFrequency;
+
+		FNfloat xs = x;
+		FNfloat ys = y;
+		FNfloat zs = z;
+		TransformDomainWarpCoordinate(xs, ys, zs);
+
+		DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z);
+	}
+
+
+	// Domain Warp Fractal Progressive
+
+	template <typename FNfloat>
+	void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y)
+	{
+		int seed = mSeed;
+		float amp = mDomainWarpAmp * mFractalBounding;
+		float freq = mFrequency;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			FNfloat xs = x;
+			FNfloat ys = y;
+			TransformDomainWarpCoordinate(xs, ys);
+
+			DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y);
+
+			seed++;
+			amp *= mGain;
+			freq *= mLacunarity;
+		}
+	}
+
+	template <typename FNfloat>
+	void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y, FNfloat& z)
+	{
+		int seed = mSeed;
+		float amp = mDomainWarpAmp * mFractalBounding;
+		float freq = mFrequency;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			FNfloat xs = x;
+			FNfloat ys = y;
+			FNfloat zs = z;
+			TransformDomainWarpCoordinate(xs, ys, zs);
+
+			DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z);
+
+			seed++;
+			amp *= mGain;
+			freq *= mLacunarity;
+		}
+	}
+
+
+	// Domain Warp Fractal Independant
+
+	template <typename FNfloat>
+	void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y)
+	{
+		FNfloat xs = x;
+		FNfloat ys = y;
+		TransformDomainWarpCoordinate(xs, ys);
+
+		int seed = mSeed;
+		float amp = mDomainWarpAmp * mFractalBounding;
+		float freq = mFrequency;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y);
+
+			seed++;
+			amp *= mGain;
+			freq *= mLacunarity;
+		}
+	}
+
+	template <typename FNfloat>
+	void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y, FNfloat& z)
+	{
+		FNfloat xs = x;
+		FNfloat ys = y;
+		FNfloat zs = z;
+		TransformDomainWarpCoordinate(xs, ys, zs);
+
+		int seed = mSeed;
+		float amp = mDomainWarpAmp * mFractalBounding;
+		float freq = mFrequency;
+
+		for (int i = 0; i < mOctaves; i++)
+		{
+			DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z);
+
+			seed++;
+			amp *= mGain;
+			freq *= mLacunarity;
+		}
+	}
 
-
-    // Domain Warp Basic Grid
-
-    template <typename FNfloat>
-    void SingleDomainWarpBasicGrid( int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr )
-    {
-        FNfloat xf = x * frequency;
-        FNfloat yf = y * frequency;
-
-        int x0 = FastFloor( xf );
-        int y0 = FastFloor( yf );
-
-        float xs = InterpHermite( (float)(xf - x0) );
-        float ys = InterpHermite( (float)(yf - y0) );
-
-        x0 *= PrimeX;
-        y0 *= PrimeY;
-        int x1 = x0 + PrimeX;
-        int y1 = y0 + PrimeY;
-
-        int hash0 = Hash( seed, x0, y0 ) & (255 << 1);
-        int hash1 = Hash( seed, x1, y0 ) & (255 << 1);
-
-        float lx0x = Lerp( Lookup<float>::RandVecs2D[ hash0 ], Lookup<float>::RandVecs2D[ hash1 ], xs );
-        float ly0x = Lerp( Lookup<float>::RandVecs2D[ hash0 | 1 ], Lookup<float>::RandVecs2D[ hash1 | 1 ], xs );
-
-        hash0 = Hash( seed, x0, y1 ) & (255 << 1);
-        hash1 = Hash( seed, x1, y1 ) & (255 << 1);
-
-        float lx1x = Lerp( Lookup<float>::RandVecs2D[ hash0 ], Lookup<float>::RandVecs2D[ hash1 ], xs );
-        float ly1x = Lerp( Lookup<float>::RandVecs2D[ hash0 | 1 ], Lookup<float>::RandVecs2D[ hash1 | 1 ], xs );
-
-        xr += Lerp( lx0x, lx1x, ys ) * warpAmp;
-        yr += Lerp( ly0x, ly1x, ys ) * warpAmp;
-    }
-
-    template <typename FNfloat>
-    void SingleDomainWarpBasicGrid( int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr )
-    {
-        FNfloat xf = x * frequency;
-        FNfloat yf = y * frequency;
-        FNfloat zf = z * frequency;
-
-        int x0 = FastFloor( xf );
-        int y0 = FastFloor( yf );
-        int z0 = FastFloor( zf );
-
-        float xs = InterpHermite( (float)(xf - x0) );
-        float ys = InterpHermite( (float)(yf - y0) );
-        float zs = InterpHermite( (float)(zf - z0) );
-
-        x0 *= PrimeX;
-        y0 *= PrimeY;
-        z0 *= PrimeZ;
-        int x1 = x0 + PrimeX;
-        int y1 = y0 + PrimeY;
-        int z1 = z0 + PrimeZ;
-
-        int hash0 = Hash( seed, x0, y0, z0 ) & (255 << 2);
-        int hash1 = Hash( seed, x1, y0, z0 ) & (255 << 2);
-
-        float lx0x = Lerp( Lookup<float>::RandVecs3D[ hash0 ], Lookup<float>::RandVecs3D[ hash1 ], xs );
-        float ly0x = Lerp( Lookup<float>::RandVecs3D[ hash0 | 1 ], Lookup<float>::RandVecs3D[ hash1 | 1 ], xs );
-        float lz0x = Lerp( Lookup<float>::RandVecs3D[ hash0 | 2 ], Lookup<float>::RandVecs3D[ hash1 | 2 ], xs );
-
-        hash0 = Hash( seed, x0, y1, z0 ) & (255 << 2);
-        hash1 = Hash( seed, x1, y1, z0 ) & (255 << 2);
-
-        float lx1x = Lerp( Lookup<float>::RandVecs3D[ hash0 ], Lookup<float>::RandVecs3D[ hash1 ], xs );
-        float ly1x = Lerp( Lookup<float>::RandVecs3D[ hash0 | 1 ], Lookup<float>::RandVecs3D[ hash1 | 1 ], xs );
-        float lz1x = Lerp( Lookup<float>::RandVecs3D[ hash0 | 2 ], Lookup<float>::RandVecs3D[ hash1 | 2 ], xs );
-
-        float lx0y = Lerp( lx0x, lx1x, ys );
-        float ly0y = Lerp( ly0x, ly1x, ys );
-        float lz0y = Lerp( lz0x, lz1x, ys );
-
-        hash0 = Hash( seed, x0, y0, z1 ) & (255 << 2);
-        hash1 = Hash( seed, x1, y0, z1 ) & (255 << 2);
-
-        lx0x = Lerp( Lookup<float>::RandVecs3D[ hash0 ], Lookup<float>::RandVecs3D[ hash1 ], xs );
-        ly0x = Lerp( Lookup<float>::RandVecs3D[ hash0 | 1 ], Lookup<float>::RandVecs3D[ hash1 | 1 ], xs );
-        lz0x = Lerp( Lookup<float>::RandVecs3D[ hash0 | 2 ], Lookup<float>::RandVecs3D[ hash1 | 2 ], xs );
-
-        hash0 = Hash( seed, x0, y1, z1 ) & (255 << 2);
-        hash1 = Hash( seed, x1, y1, z1 ) & (255 << 2);
-
-        lx1x = Lerp( Lookup<float>::RandVecs3D[ hash0 ], Lookup<float>::RandVecs3D[ hash1 ], xs );
-        ly1x = Lerp( Lookup<float>::RandVecs3D[ hash0 | 1 ], Lookup<float>::RandVecs3D[ hash1 | 1 ], xs );
-        lz1x = Lerp( Lookup<float>::RandVecs3D[ hash0 | 2 ], Lookup<float>::RandVecs3D[ hash1 | 2 ], xs );
-
-        xr += Lerp( lx0y, Lerp( lx0x, lx1x, ys ), zs ) * warpAmp;
-        yr += Lerp( ly0y, Lerp( ly0x, ly1x, ys ), zs ) * warpAmp;
-        zr += Lerp( lz0y, Lerp( lz0x, lz1x, ys ), zs ) * warpAmp;
-    }
-
-
-    // Domain Warp Simplex/OpenSimplex2
-
-    template <typename FNfloat>
-    void SingleDomainWarpSimplexGradient( int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr, bool outGradOnly )
-    {
-        const float SQRT3 = 1.7320508075688772935274463415059f;
-        const float G2 = (3 - SQRT3) / 6;
-
-        x *= frequency;
-        y *= frequency;
-
-        /*
-         * --- Skew moved to TransformNoiseCoordinate method ---
-         * const FNfloat F2 = 0.5f * (SQRT3 - 1);
-         * FNfloat s = (x + y) * F2;
-         * x += s; y += s;
-        */
-
-        int i = FastFloor( x );
-        int j = FastFloor( y );
-        float xi = (float)(x - i);
-        float yi = (float)(y - j);
-
-        float t = (xi + yi) * G2;
-        float x0 = (float)(xi - t);
-        float y0 = (float)(yi - t);
-
-        i *= PrimeX;
-        j *= PrimeY;
-
-        float vx, vy;
-        vx = vy = 0;
-
-        float a = 0.5f - x0 * x0 - y0 * y0;
-        if( a > 0 )
-        {
-            float aaaa = (a * a) * (a * a);
-            float xo, yo;
-            if( outGradOnly )
-                GradCoordOut( seed, i, j, xo, yo );
-            else
-                GradCoordDual( seed, i, j, x0, y0, xo, yo );
-            vx += aaaa * xo;
-            vy += aaaa * yo;
-        }
-
-        float c = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
-        if( c > 0 )
-        {
-            float x2 = x0 + (2 * (float)G2 - 1);
-            float y2 = y0 + (2 * (float)G2 - 1);
-            float cccc = (c * c) * (c * c);
-            float xo, yo;
-            if( outGradOnly )
-                GradCoordOut( seed, i + PrimeX, j + PrimeY, xo, yo );
-            else
-                GradCoordDual( seed, i + PrimeX, j + PrimeY, x2, y2, xo, yo );
-            vx += cccc * xo;
-            vy += cccc * yo;
-        }
-
-        if( y0 > x0 )
-        {
-            float x1 = x0 + (float)G2;
-            float y1 = y0 + ((float)G2 - 1);
-            float b = 0.5f - x1 * x1 - y1 * y1;
-            if( b > 0 )
-            {
-                float bbbb = (b * b) * (b * b);
-                float xo, yo;
-                if( outGradOnly )
-                    GradCoordOut( seed, i, j + PrimeY, xo, yo );
-                else
-                    GradCoordDual( seed, i, j + PrimeY, x1, y1, xo, yo );
-                vx += bbbb * xo;
-                vy += bbbb * yo;
-            }
-        }
-        else
-        {
-            float x1 = x0 + ((float)G2 - 1);
-            float y1 = y0 + (float)G2;
-            float b = 0.5f - x1 * x1 - y1 * y1;
-            if( b > 0 )
-            {
-                float bbbb = (b * b) * (b * b);
-                float xo, yo;
-                if( outGradOnly )
-                    GradCoordOut( seed, i + PrimeX, j, xo, yo );
-                else
-                    GradCoordDual( seed, i + PrimeX, j, x1, y1, xo, yo );
-                vx += bbbb * xo;
-                vy += bbbb * yo;
-            }
-        }
-
-        xr += vx * warpAmp;
-        yr += vy * warpAmp;
-    }
-
-    template <typename FNfloat>
-    void SingleDomainWarpOpenSimplex2Gradient( int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr, bool outGradOnly )
-    {
-        x *= frequency;
-        y *= frequency;
-        z *= frequency;
-
-        /*
-         * --- Rotation moved to TransformDomainWarpCoordinate method ---
-         * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
-         * FNfloat r = (x + y + z) * R3; // Rotation, not skew
-         * x = r - x; y = r - y; z = r - z;
-        */
-
-        int i = FastRound( x );
-        int j = FastRound( y );
-        int k = FastRound( z );
-        float x0 = (float)x - i;
-        float y0 = (float)y - j;
-        float z0 = (float)z - k;
-
-        int xNSign = (int)(-x0 - 1.0f) | 1;
-        int yNSign = (int)(-y0 - 1.0f) | 1;
-        int zNSign = (int)(-z0 - 1.0f) | 1;
-
-        float ax0 = xNSign * -x0;
-        float ay0 = yNSign * -y0;
-        float az0 = zNSign * -z0;
-
-        i *= PrimeX;
-        j *= PrimeY;
-        k *= PrimeZ;
-
-        float vx, vy, vz;
-        vx = vy = vz = 0;
-
-        float a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
-        for( int l = 0; l < 2; l++ )
-        {
-            if( a > 0 )
-            {
-                float aaaa = (a * a) * (a * a);
-                float xo, yo, zo;
-                if( outGradOnly )
-                    GradCoordOut( seed, i, j, k, xo, yo, zo );
-                else
-                    GradCoordDual( seed, i, j, k, x0, y0, z0, xo, yo, zo );
-                vx += aaaa * xo;
-                vy += aaaa * yo;
-                vz += aaaa * zo;
-            }
-
-            float b = a + 1;
-            int i1 = i;
-            int j1 = j;
-            int k1 = k;
-            float x1 = x0;
-            float y1 = y0;
-            float z1 = z0;
-
-            if( ax0 >= ay0 && ax0 >= az0 )
-            {
-                x1 += xNSign;
-                b -= xNSign * 2 * x1;
-                i1 -= xNSign * PrimeX;
-            }
-            else if( ay0 > ax0 && ay0 >= az0 )
-            {
-                y1 += yNSign;
-                b -= yNSign * 2 * y1;
-                j1 -= yNSign * PrimeY;
-            }
-            else
-            {
-                z1 += zNSign;
-                b -= zNSign * 2 * z1;
-                k1 -= zNSign * PrimeZ;
-            }
-
-            if( b > 0 )
-            {
-                float bbbb = (b * b) * (b * b);
-                float xo, yo, zo;
-                if( outGradOnly )
-                    GradCoordOut( seed, i1, j1, k1, xo, yo, zo );
-                else
-                    GradCoordDual( seed, i1, j1, k1, x1, y1, z1, xo, yo, zo );
-                vx += bbbb * xo;
-                vy += bbbb * yo;
-                vz += bbbb * zo;
-            }
-
-            if( l == 1 ) break;
-
-            ax0 = 0.5f - ax0;
-            ay0 = 0.5f - ay0;
-            az0 = 0.5f - az0;
-
-            x0 = xNSign * ax0;
-            y0 = yNSign * ay0;
-            z0 = zNSign * az0;
-
-            a += (0.75f - ax0) - (ay0 + az0);
-
-            i += (xNSign >> 1) & PrimeX;
-            j += (yNSign >> 1) & PrimeY;
-            k += (zNSign >> 1) & PrimeZ;
-
-            xNSign = -xNSign;
-            yNSign = -yNSign;
-            zNSign = -zNSign;
-
-            seed += 1293373;
-        }
-
-        xr += vx * warpAmp;
-        yr += vy * warpAmp;
-        zr += vz * warpAmp;
-    }
+
+	// Domain Warp Basic Grid
+
+	template <typename FNfloat>
+	void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr)
+	{
+		FNfloat xf = x * frequency;
+		FNfloat yf = y * frequency;
+
+		int x0 = FastFloor(xf);
+		int y0 = FastFloor(yf);
+
+		float xs = InterpHermite((float)(xf - x0));
+		float ys = InterpHermite((float)(yf - y0));
+
+		x0 *= PrimeX;
+		y0 *= PrimeY;
+		int x1 = x0 + PrimeX;
+		int y1 = y0 + PrimeY;
+
+		int hash0 = Hash(seed, x0, y0) & (255 << 1);
+		int hash1 = Hash(seed, x1, y0) & (255 << 1);
+
+		float lx0x = Lerp(Lookup<float>::RandVecs2D[hash0], Lookup<float>::RandVecs2D[hash1], xs);
+		float ly0x = Lerp(Lookup<float>::RandVecs2D[hash0 | 1], Lookup<float>::RandVecs2D[hash1 | 1], xs);
+
+		hash0 = Hash(seed, x0, y1) & (255 << 1);
+		hash1 = Hash(seed, x1, y1) & (255 << 1);
+
+		float lx1x = Lerp(Lookup<float>::RandVecs2D[hash0], Lookup<float>::RandVecs2D[hash1], xs);
+		float ly1x = Lerp(Lookup<float>::RandVecs2D[hash0 | 1], Lookup<float>::RandVecs2D[hash1 | 1], xs);
+
+		xr += Lerp(lx0x, lx1x, ys) * warpAmp;
+		yr += Lerp(ly0x, ly1x, ys) * warpAmp;
+	}
+
+	template <typename FNfloat>
+	void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr)
+	{
+		FNfloat xf = x * frequency;
+		FNfloat yf = y * frequency;
+		FNfloat zf = z * frequency;
+
+		int x0 = FastFloor(xf);
+		int y0 = FastFloor(yf);
+		int z0 = FastFloor(zf);
+
+		float xs = InterpHermite((float)(xf - x0));
+		float ys = InterpHermite((float)(yf - y0));
+		float zs = InterpHermite((float)(zf - z0));
+
+		x0 *= PrimeX;
+		y0 *= PrimeY;
+		z0 *= PrimeZ;
+		int x1 = x0 + PrimeX;
+		int y1 = y0 + PrimeY;
+		int z1 = z0 + PrimeZ;
+
+		int hash0 = Hash(seed, x0, y0, z0) & (255 << 2);
+		int hash1 = Hash(seed, x1, y0, z0) & (255 << 2);
+
+		float lx0x = Lerp(Lookup<float>::RandVecs3D[hash0], Lookup<float>::RandVecs3D[hash1], xs);
+		float ly0x = Lerp(Lookup<float>::RandVecs3D[hash0 | 1], Lookup<float>::RandVecs3D[hash1 | 1], xs);
+		float lz0x = Lerp(Lookup<float>::RandVecs3D[hash0 | 2], Lookup<float>::RandVecs3D[hash1 | 2], xs);
+
+		hash0 = Hash(seed, x0, y1, z0) & (255 << 2);
+		hash1 = Hash(seed, x1, y1, z0) & (255 << 2);
+
+		float lx1x = Lerp(Lookup<float>::RandVecs3D[hash0], Lookup<float>::RandVecs3D[hash1], xs);
+		float ly1x = Lerp(Lookup<float>::RandVecs3D[hash0 | 1], Lookup<float>::RandVecs3D[hash1 | 1], xs);
+		float lz1x = Lerp(Lookup<float>::RandVecs3D[hash0 | 2], Lookup<float>::RandVecs3D[hash1 | 2], xs);
+
+		float lx0y = Lerp(lx0x, lx1x, ys);
+		float ly0y = Lerp(ly0x, ly1x, ys);
+		float lz0y = Lerp(lz0x, lz1x, ys);
+
+		hash0 = Hash(seed, x0, y0, z1) & (255 << 2);
+		hash1 = Hash(seed, x1, y0, z1) & (255 << 2);
+
+		lx0x = Lerp(Lookup<float>::RandVecs3D[hash0], Lookup<float>::RandVecs3D[hash1], xs);
+		ly0x = Lerp(Lookup<float>::RandVecs3D[hash0 | 1], Lookup<float>::RandVecs3D[hash1 | 1], xs);
+		lz0x = Lerp(Lookup<float>::RandVecs3D[hash0 | 2], Lookup<float>::RandVecs3D[hash1 | 2], xs);
+
+		hash0 = Hash(seed, x0, y1, z1) & (255 << 2);
+		hash1 = Hash(seed, x1, y1, z1) & (255 << 2);
+
+		lx1x = Lerp(Lookup<float>::RandVecs3D[hash0], Lookup<float>::RandVecs3D[hash1], xs);
+		ly1x = Lerp(Lookup<float>::RandVecs3D[hash0 | 1], Lookup<float>::RandVecs3D[hash1 | 1], xs);
+		lz1x = Lerp(Lookup<float>::RandVecs3D[hash0 | 2], Lookup<float>::RandVecs3D[hash1 | 2], xs);
+
+		xr += Lerp(lx0y, Lerp(lx0x, lx1x, ys), zs) * warpAmp;
+		yr += Lerp(ly0y, Lerp(ly0x, ly1x, ys), zs) * warpAmp;
+		zr += Lerp(lz0y, Lerp(lz0x, lz1x, ys), zs) * warpAmp;
+	}
+
+
+	// Domain Warp Simplex/OpenSimplex2
+
+	template <typename FNfloat>
+	void SingleDomainWarpSimplexGradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr, bool outGradOnly)
+	{
+		const float SQRT3 = 1.7320508075688772935274463415059f;
+		const float G2 = (3 - SQRT3) / 6;
+
+		x *= frequency;
+		y *= frequency;
+
+		/*
+		 * --- Skew moved to TransformNoiseCoordinate method ---
+		 * const FNfloat F2 = 0.5f * (SQRT3 - 1);
+		 * FNfloat s = (x + y) * F2;
+		 * x += s; y += s;
+		*/
+
+		int i = FastFloor(x);
+		int j = FastFloor(y);
+		float xi = (float)(x - i);
+		float yi = (float)(y - j);
+
+		float t = (xi + yi) * G2;
+		float x0 = (float)(xi - t);
+		float y0 = (float)(yi - t);
+
+		i *= PrimeX;
+		j *= PrimeY;
+
+		float vx, vy;
+		vx = vy = 0;
+
+		float a = 0.5f - x0 * x0 - y0 * y0;
+		if (a > 0)
+		{
+			float aaaa = (a * a) * (a * a);
+			float xo, yo;
+			if (outGradOnly)
+				GradCoordOut(seed, i, j, xo, yo);
+			else
+				GradCoordDual(seed, i, j, x0, y0, xo, yo);
+			vx += aaaa * xo;
+			vy += aaaa * yo;
+		}
+
+		float c = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
+		if (c > 0)
+		{
+			float x2 = x0 + (2 * (float)G2 - 1);
+			float y2 = y0 + (2 * (float)G2 - 1);
+			float cccc = (c * c) * (c * c);
+			float xo, yo;
+			if (outGradOnly)
+				GradCoordOut(seed, i + PrimeX, j + PrimeY, xo, yo);
+			else
+				GradCoordDual(seed, i + PrimeX, j + PrimeY, x2, y2, xo, yo);
+			vx += cccc * xo;
+			vy += cccc * yo;
+		}
+
+		if (y0 > x0)
+		{
+			float x1 = x0 + (float)G2;
+			float y1 = y0 + ((float)G2 - 1);
+			float b = 0.5f - x1 * x1 - y1 * y1;
+			if (b > 0)
+			{
+				float bbbb = (b * b) * (b * b);
+				float xo, yo;
+				if (outGradOnly)
+					GradCoordOut(seed, i, j + PrimeY, xo, yo);
+				else
+					GradCoordDual(seed, i, j + PrimeY, x1, y1, xo, yo);
+				vx += bbbb * xo;
+				vy += bbbb * yo;
+			}
+		}
+		else
+		{
+			float x1 = x0 + ((float)G2 - 1);
+			float y1 = y0 + (float)G2;
+			float b = 0.5f - x1 * x1 - y1 * y1;
+			if (b > 0)
+			{
+				float bbbb = (b * b) * (b * b);
+				float xo, yo;
+				if (outGradOnly)
+					GradCoordOut(seed, i + PrimeX, j, xo, yo);
+				else
+					GradCoordDual(seed, i + PrimeX, j, x1, y1, xo, yo);
+				vx += bbbb * xo;
+				vy += bbbb * yo;
+			}
+		}
+
+		xr += vx * warpAmp;
+		yr += vy * warpAmp;
+	}
+
+	template <typename FNfloat>
+	void SingleDomainWarpOpenSimplex2Gradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr, bool outGradOnly)
+	{
+		x *= frequency;
+		y *= frequency;
+		z *= frequency;
+
+		/*
+		 * --- Rotation moved to TransformDomainWarpCoordinate method ---
+		 * const FNfloat R3 = (FNfloat)(2.0 / 3.0);
+		 * FNfloat r = (x + y + z) * R3; // Rotation, not skew
+		 * x = r - x; y = r - y; z = r - z;
+		*/
+
+		int i = FastRound(x);
+		int j = FastRound(y);
+		int k = FastRound(z);
+		float x0 = (float)x - i;
+		float y0 = (float)y - j;
+		float z0 = (float)z - k;
+
+		int xNSign = (int)(-x0 - 1.0f) | 1;
+		int yNSign = (int)(-y0 - 1.0f) | 1;
+		int zNSign = (int)(-z0 - 1.0f) | 1;
+
+		float ax0 = xNSign * -x0;
+		float ay0 = yNSign * -y0;
+		float az0 = zNSign * -z0;
+
+		i *= PrimeX;
+		j *= PrimeY;
+		k *= PrimeZ;
+
+		float vx, vy, vz;
+		vx = vy = vz = 0;
+
+		float a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
+		for (int l = 0; l < 2; l++)
+		{
+			if (a > 0)
+			{
+				float aaaa = (a * a) * (a * a);
+				float xo, yo, zo;
+				if (outGradOnly)
+					GradCoordOut(seed, i, j, k, xo, yo, zo);
+				else
+					GradCoordDual(seed, i, j, k, x0, y0, z0, xo, yo, zo);
+				vx += aaaa * xo;
+				vy += aaaa * yo;
+				vz += aaaa * zo;
+			}
+
+			float b = a + 1;
+			int i1 = i;
+			int j1 = j;
+			int k1 = k;
+			float x1 = x0;
+			float y1 = y0;
+			float z1 = z0;
+
+			if (ax0 >= ay0 && ax0 >= az0)
+			{
+				x1 += xNSign;
+				b -= xNSign * 2 * x1;
+				i1 -= xNSign * PrimeX;
+			}
+			else if (ay0 > ax0 && ay0 >= az0)
+			{
+				y1 += yNSign;
+				b -= yNSign * 2 * y1;
+				j1 -= yNSign * PrimeY;
+			}
+			else
+			{
+				z1 += zNSign;
+				b -= zNSign * 2 * z1;
+				k1 -= zNSign * PrimeZ;
+			}
+
+			if (b > 0)
+			{
+				float bbbb = (b * b) * (b * b);
+				float xo, yo, zo;
+				if (outGradOnly)
+					GradCoordOut(seed, i1, j1, k1, xo, yo, zo);
+				else
+					GradCoordDual(seed, i1, j1, k1, x1, y1, z1, xo, yo, zo);
+				vx += bbbb * xo;
+				vy += bbbb * yo;
+				vz += bbbb * zo;
+			}
+
+			if (l == 1) break;
+
+			ax0 = 0.5f - ax0;
+			ay0 = 0.5f - ay0;
+			az0 = 0.5f - az0;
+
+			x0 = xNSign * ax0;
+			y0 = yNSign * ay0;
+			z0 = zNSign * az0;
+
+			a += (0.75f - ax0) - (ay0 + az0);
+
+			i += (xNSign >> 1) & PrimeX;
+			j += (yNSign >> 1) & PrimeY;
+			k += (zNSign >> 1) & PrimeZ;
+
+			xNSign = -xNSign;
+			yNSign = -yNSign;
+			zNSign = -zNSign;
+
+			seed += 1293373;
+		}
+
+		xr += vx * warpAmp;
+		yr += vy * warpAmp;
+		zr += vz * warpAmp;
+	}
 };
 
 template <>
@@ -2454,133 +2454,133 @@ struct FastNoiseLite::Arguments_must_be_floating_point_values<long double> {};
 template <typename T>
 const T FastNoiseLite::Lookup<T>::Gradients2D[] =
 {
-    0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
-    0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
-    0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
-    -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
-    -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
-    -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
-    0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
-    0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
-    0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
-    -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
-    -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
-    -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
-    0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
-    0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
-    0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
-    -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
-    -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
-    -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
-    0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
-    0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
-    0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
-    -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
-    -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
-    -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
-    0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
-    0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
-    0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
-    -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
-    -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
-    -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
-    0.38268343236509f, 0.923879532511287f, 0.923879532511287f, 0.38268343236509f, 0.923879532511287f, -0.38268343236509f, 0.38268343236509f, -0.923879532511287f,
-    -0.38268343236509f, -0.923879532511287f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, 0.38268343236509f, -0.38268343236509f, 0.923879532511287f,
+	0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
+	0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
+	0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
+	-0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
+	-0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
+	-0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
+	0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
+	0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
+	0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
+	-0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
+	-0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
+	-0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
+	0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
+	0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
+	0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
+	-0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
+	-0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
+	-0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
+	0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
+	0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
+	0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
+	-0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
+	-0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
+	-0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
+	0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f,
+	0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f,
+	0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f,
+	-0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f,
+	-0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f,
+	-0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f,
+	0.38268343236509f, 0.923879532511287f, 0.923879532511287f, 0.38268343236509f, 0.923879532511287f, -0.38268343236509f, 0.38268343236509f, -0.923879532511287f,
+	-0.38268343236509f, -0.923879532511287f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, 0.38268343236509f, -0.38268343236509f, 0.923879532511287f,
 };
 
 template <typename T>
 const T FastNoiseLite::Lookup<T>::RandVecs2D[] =
 {
-    -0.2700222198f, -0.9628540911f, 0.3863092627f, -0.9223693152f, 0.04444859006f, -0.999011673f, -0.5992523158f, -0.8005602176f, -0.7819280288f, 0.6233687174f, 0.9464672271f, 0.3227999196f, -0.6514146797f, -0.7587218957f, 0.9378472289f, 0.347048376f,
-    -0.8497875957f, -0.5271252623f, -0.879042592f, 0.4767432447f, -0.892300288f, -0.4514423508f, -0.379844434f, -0.9250503802f, -0.9951650832f, 0.0982163789f, 0.7724397808f, -0.6350880136f, 0.7573283322f, -0.6530343002f, -0.9928004525f, -0.119780055f,
-    -0.0532665713f, 0.9985803285f, 0.9754253726f, -0.2203300762f, -0.7665018163f, 0.6422421394f, 0.991636706f, 0.1290606184f, -0.994696838f, 0.1028503788f, -0.5379205513f, -0.84299554f, 0.5022815471f, -0.8647041387f, 0.4559821461f, -0.8899889226f,
-    -0.8659131224f, -0.5001944266f, 0.0879458407f, -0.9961252577f, -0.5051684983f, 0.8630207346f, 0.7753185226f, -0.6315704146f, -0.6921944612f, 0.7217110418f, -0.5191659449f, -0.8546734591f, 0.8978622882f, -0.4402764035f, -0.1706774107f, 0.9853269617f,
-    -0.9353430106f, -0.3537420705f, -0.9992404798f, 0.03896746794f, -0.2882064021f, -0.9575683108f, -0.9663811329f, 0.2571137995f, -0.8759714238f, -0.4823630009f, -0.8303123018f, -0.5572983775f, 0.05110133755f, -0.9986934731f, -0.8558373281f, -0.5172450752f,
-    0.09887025282f, 0.9951003332f, 0.9189016087f, 0.3944867976f, -0.2439375892f, -0.9697909324f, -0.8121409387f, -0.5834613061f, -0.9910431363f, 0.1335421355f, 0.8492423985f, -0.5280031709f, -0.9717838994f, -0.2358729591f, 0.9949457207f, 0.1004142068f,
-    0.6241065508f, -0.7813392434f, 0.662910307f, 0.7486988212f, -0.7197418176f, 0.6942418282f, -0.8143370775f, -0.5803922158f, 0.104521054f, -0.9945226741f, -0.1065926113f, -0.9943027784f, 0.445799684f, -0.8951327509f, 0.105547406f, 0.9944142724f,
-    -0.992790267f, 0.1198644477f, -0.8334366408f, 0.552615025f, 0.9115561563f, -0.4111755999f, 0.8285544909f, -0.5599084351f, 0.7217097654f, -0.6921957921f, 0.4940492677f, -0.8694339084f, -0.3652321272f, -0.9309164803f, -0.9696606758f, 0.2444548501f,
-    0.08925509731f, -0.996008799f, 0.5354071276f, -0.8445941083f, -0.1053576186f, 0.9944343981f, -0.9890284586f, 0.1477251101f, 0.004856104961f, 0.9999882091f, 0.9885598478f, 0.1508291331f, 0.9286129562f, -0.3710498316f, -0.5832393863f, -0.8123003252f,
-    0.3015207509f, 0.9534596146f, -0.9575110528f, 0.2883965738f, 0.9715802154f, -0.2367105511f, 0.229981792f, 0.9731949318f, 0.955763816f, -0.2941352207f, 0.740956116f, 0.6715534485f, -0.9971513787f, -0.07542630764f, 0.6905710663f, -0.7232645452f,
-    -0.290713703f, -0.9568100872f, 0.5912777791f, -0.8064679708f, -0.9454592212f, -0.325740481f, 0.6664455681f, 0.74555369f, 0.6236134912f, 0.7817328275f, 0.9126993851f, -0.4086316587f, -0.8191762011f, 0.5735419353f, -0.8812745759f, -0.4726046147f,
-    0.9953313627f, 0.09651672651f, 0.9855650846f, -0.1692969699f, -0.8495980887f, 0.5274306472f, 0.6174853946f, -0.7865823463f, 0.8508156371f, 0.52546432f, 0.9985032451f, -0.05469249926f, 0.1971371563f, -0.9803759185f, 0.6607855748f, -0.7505747292f,
-    -0.03097494063f, 0.9995201614f, -0.6731660801f, 0.739491331f, -0.7195018362f, -0.6944905383f, 0.9727511689f, 0.2318515979f, 0.9997059088f, -0.0242506907f, 0.4421787429f, -0.8969269532f, 0.9981350961f, -0.061043673f, -0.9173660799f, -0.3980445648f,
-    -0.8150056635f, -0.5794529907f, -0.8789331304f, 0.4769450202f, 0.0158605829f, 0.999874213f, -0.8095464474f, 0.5870558317f, -0.9165898907f, -0.3998286786f, -0.8023542565f, 0.5968480938f, -0.5176737917f, 0.8555780767f, -0.8154407307f, -0.5788405779f,
-    0.4022010347f, -0.9155513791f, -0.9052556868f, -0.4248672045f, 0.7317445619f, 0.6815789728f, -0.5647632201f, -0.8252529947f, -0.8403276335f, -0.5420788397f, -0.9314281527f, 0.363925262f, 0.5238198472f, 0.8518290719f, 0.7432803869f, -0.6689800195f,
-    -0.985371561f, -0.1704197369f, 0.4601468731f, 0.88784281f, 0.825855404f, 0.5638819483f, 0.6182366099f, 0.7859920446f, 0.8331502863f, -0.553046653f, 0.1500307506f, 0.9886813308f, -0.662330369f, -0.7492119075f, -0.668598664f, 0.743623444f,
-    0.7025606278f, 0.7116238924f, -0.5419389763f, -0.8404178401f, -0.3388616456f, 0.9408362159f, 0.8331530315f, 0.5530425174f, -0.2989720662f, -0.9542618632f, 0.2638522993f, 0.9645630949f, 0.124108739f, -0.9922686234f, -0.7282649308f, -0.6852956957f,
-    0.6962500149f, 0.7177993569f, -0.9183535368f, 0.3957610156f, -0.6326102274f, -0.7744703352f, -0.9331891859f, -0.359385508f, -0.1153779357f, -0.9933216659f, 0.9514974788f, -0.3076565421f, -0.08987977445f, -0.9959526224f, 0.6678496916f, 0.7442961705f,
-    0.7952400393f, -0.6062947138f, -0.6462007402f, -0.7631674805f, -0.2733598753f, 0.9619118351f, 0.9669590226f, -0.254931851f, -0.9792894595f, 0.2024651934f, -0.5369502995f, -0.8436138784f, -0.270036471f, -0.9628500944f, -0.6400277131f, 0.7683518247f,
-    -0.7854537493f, -0.6189203566f, 0.06005905383f, -0.9981948257f, -0.02455770378f, 0.9996984141f, -0.65983623f, 0.751409442f, -0.6253894466f, -0.7803127835f, -0.6210408851f, -0.7837781695f, 0.8348888491f, 0.5504185768f, -0.1592275245f, 0.9872419133f,
-    0.8367622488f, 0.5475663786f, -0.8675753916f, -0.4973056806f, -0.2022662628f, -0.9793305667f, 0.9399189937f, 0.3413975472f, 0.9877404807f, -0.1561049093f, -0.9034455656f, 0.4287028224f, 0.1269804218f, -0.9919052235f, -0.3819600854f, 0.924178821f,
-    0.9754625894f, 0.2201652486f, -0.3204015856f, -0.9472818081f, -0.9874760884f, 0.1577687387f, 0.02535348474f, -0.9996785487f, 0.4835130794f, -0.8753371362f, -0.2850799925f, -0.9585037287f, -0.06805516006f, -0.99768156f, -0.7885244045f, -0.6150034663f,
-    0.3185392127f, -0.9479096845f, 0.8880043089f, 0.4598351306f, 0.6476921488f, -0.7619021462f, 0.9820241299f, 0.1887554194f, 0.9357275128f, -0.3527237187f, -0.8894895414f, 0.4569555293f, 0.7922791302f, 0.6101588153f, 0.7483818261f, 0.6632681526f,
-    -0.7288929755f, -0.6846276581f, 0.8729032783f, -0.4878932944f, 0.8288345784f, 0.5594937369f, 0.08074567077f, 0.9967347374f, 0.9799148216f, -0.1994165048f, -0.580730673f, -0.8140957471f, -0.4700049791f, -0.8826637636f, 0.2409492979f, 0.9705377045f,
-    0.9437816757f, -0.3305694308f, -0.8927998638f, -0.4504535528f, -0.8069622304f, 0.5906030467f, 0.06258973166f, 0.9980393407f, -0.9312597469f, 0.3643559849f, 0.5777449785f, 0.8162173362f, -0.3360095855f, -0.941858566f, 0.697932075f, -0.7161639607f,
-    -0.002008157227f, -0.9999979837f, -0.1827294312f, -0.9831632392f, -0.6523911722f, 0.7578824173f, -0.4302626911f, -0.9027037258f, -0.9985126289f, -0.05452091251f, -0.01028102172f, -0.9999471489f, -0.4946071129f, 0.8691166802f, -0.2999350194f, 0.9539596344f,
-    0.8165471961f, 0.5772786819f, 0.2697460475f, 0.962931498f, -0.7306287391f, -0.6827749597f, -0.7590952064f, -0.6509796216f, -0.907053853f, 0.4210146171f, -0.5104861064f, -0.8598860013f, 0.8613350597f, 0.5080373165f, 0.5007881595f, -0.8655698812f,
-    -0.654158152f, 0.7563577938f, -0.8382755311f, -0.545246856f, 0.6940070834f, 0.7199681717f, 0.06950936031f, 0.9975812994f, 0.1702942185f, -0.9853932612f, 0.2695973274f, 0.9629731466f, 0.5519612192f, -0.8338697815f, 0.225657487f, -0.9742067022f,
-    0.4215262855f, -0.9068161835f, 0.4881873305f, -0.8727388672f, -0.3683854996f, -0.9296731273f, -0.9825390578f, 0.1860564427f, 0.81256471f, 0.5828709909f, 0.3196460933f, -0.9475370046f, 0.9570913859f, 0.2897862643f, -0.6876655497f, -0.7260276109f,
-    -0.9988770922f, -0.047376731f, -0.1250179027f, 0.992154486f, -0.8280133617f, 0.560708367f, 0.9324863769f, -0.3612051451f, 0.6394653183f, 0.7688199442f, -0.01623847064f, -0.9998681473f, -0.9955014666f, -0.09474613458f, -0.81453315f, 0.580117012f,
-    0.4037327978f, -0.9148769469f, 0.9944263371f, 0.1054336766f, -0.1624711654f, 0.9867132919f, -0.9949487814f, -0.100383875f, -0.6995302564f, 0.7146029809f, 0.5263414922f, -0.85027327f, -0.5395221479f, 0.841971408f, 0.6579370318f, 0.7530729462f,
-    0.01426758847f, -0.9998982128f, -0.6734383991f, 0.7392433447f, 0.639412098f, -0.7688642071f, 0.9211571421f, 0.3891908523f, -0.146637214f, -0.9891903394f, -0.782318098f, 0.6228791163f, -0.5039610839f, -0.8637263605f, -0.7743120191f, -0.6328039957f,
+	-0.2700222198f, -0.9628540911f, 0.3863092627f, -0.9223693152f, 0.04444859006f, -0.999011673f, -0.5992523158f, -0.8005602176f, -0.7819280288f, 0.6233687174f, 0.9464672271f, 0.3227999196f, -0.6514146797f, -0.7587218957f, 0.9378472289f, 0.347048376f,
+	-0.8497875957f, -0.5271252623f, -0.879042592f, 0.4767432447f, -0.892300288f, -0.4514423508f, -0.379844434f, -0.9250503802f, -0.9951650832f, 0.0982163789f, 0.7724397808f, -0.6350880136f, 0.7573283322f, -0.6530343002f, -0.9928004525f, -0.119780055f,
+	-0.0532665713f, 0.9985803285f, 0.9754253726f, -0.2203300762f, -0.7665018163f, 0.6422421394f, 0.991636706f, 0.1290606184f, -0.994696838f, 0.1028503788f, -0.5379205513f, -0.84299554f, 0.5022815471f, -0.8647041387f, 0.4559821461f, -0.8899889226f,
+	-0.8659131224f, -0.5001944266f, 0.0879458407f, -0.9961252577f, -0.5051684983f, 0.8630207346f, 0.7753185226f, -0.6315704146f, -0.6921944612f, 0.7217110418f, -0.5191659449f, -0.8546734591f, 0.8978622882f, -0.4402764035f, -0.1706774107f, 0.9853269617f,
+	-0.9353430106f, -0.3537420705f, -0.9992404798f, 0.03896746794f, -0.2882064021f, -0.9575683108f, -0.9663811329f, 0.2571137995f, -0.8759714238f, -0.4823630009f, -0.8303123018f, -0.5572983775f, 0.05110133755f, -0.9986934731f, -0.8558373281f, -0.5172450752f,
+	0.09887025282f, 0.9951003332f, 0.9189016087f, 0.3944867976f, -0.2439375892f, -0.9697909324f, -0.8121409387f, -0.5834613061f, -0.9910431363f, 0.1335421355f, 0.8492423985f, -0.5280031709f, -0.9717838994f, -0.2358729591f, 0.9949457207f, 0.1004142068f,
+	0.6241065508f, -0.7813392434f, 0.662910307f, 0.7486988212f, -0.7197418176f, 0.6942418282f, -0.8143370775f, -0.5803922158f, 0.104521054f, -0.9945226741f, -0.1065926113f, -0.9943027784f, 0.445799684f, -0.8951327509f, 0.105547406f, 0.9944142724f,
+	-0.992790267f, 0.1198644477f, -0.8334366408f, 0.552615025f, 0.9115561563f, -0.4111755999f, 0.8285544909f, -0.5599084351f, 0.7217097654f, -0.6921957921f, 0.4940492677f, -0.8694339084f, -0.3652321272f, -0.9309164803f, -0.9696606758f, 0.2444548501f,
+	0.08925509731f, -0.996008799f, 0.5354071276f, -0.8445941083f, -0.1053576186f, 0.9944343981f, -0.9890284586f, 0.1477251101f, 0.004856104961f, 0.9999882091f, 0.9885598478f, 0.1508291331f, 0.9286129562f, -0.3710498316f, -0.5832393863f, -0.8123003252f,
+	0.3015207509f, 0.9534596146f, -0.9575110528f, 0.2883965738f, 0.9715802154f, -0.2367105511f, 0.229981792f, 0.9731949318f, 0.955763816f, -0.2941352207f, 0.740956116f, 0.6715534485f, -0.9971513787f, -0.07542630764f, 0.6905710663f, -0.7232645452f,
+	-0.290713703f, -0.9568100872f, 0.5912777791f, -0.8064679708f, -0.9454592212f, -0.325740481f, 0.6664455681f, 0.74555369f, 0.6236134912f, 0.7817328275f, 0.9126993851f, -0.4086316587f, -0.8191762011f, 0.5735419353f, -0.8812745759f, -0.4726046147f,
+	0.9953313627f, 0.09651672651f, 0.9855650846f, -0.1692969699f, -0.8495980887f, 0.5274306472f, 0.6174853946f, -0.7865823463f, 0.8508156371f, 0.52546432f, 0.9985032451f, -0.05469249926f, 0.1971371563f, -0.9803759185f, 0.6607855748f, -0.7505747292f,
+	-0.03097494063f, 0.9995201614f, -0.6731660801f, 0.739491331f, -0.7195018362f, -0.6944905383f, 0.9727511689f, 0.2318515979f, 0.9997059088f, -0.0242506907f, 0.4421787429f, -0.8969269532f, 0.9981350961f, -0.061043673f, -0.9173660799f, -0.3980445648f,
+	-0.8150056635f, -0.5794529907f, -0.8789331304f, 0.4769450202f, 0.0158605829f, 0.999874213f, -0.8095464474f, 0.5870558317f, -0.9165898907f, -0.3998286786f, -0.8023542565f, 0.5968480938f, -0.5176737917f, 0.8555780767f, -0.8154407307f, -0.5788405779f,
+	0.4022010347f, -0.9155513791f, -0.9052556868f, -0.4248672045f, 0.7317445619f, 0.6815789728f, -0.5647632201f, -0.8252529947f, -0.8403276335f, -0.5420788397f, -0.9314281527f, 0.363925262f, 0.5238198472f, 0.8518290719f, 0.7432803869f, -0.6689800195f,
+	-0.985371561f, -0.1704197369f, 0.4601468731f, 0.88784281f, 0.825855404f, 0.5638819483f, 0.6182366099f, 0.7859920446f, 0.8331502863f, -0.553046653f, 0.1500307506f, 0.9886813308f, -0.662330369f, -0.7492119075f, -0.668598664f, 0.743623444f,
+	0.7025606278f, 0.7116238924f, -0.5419389763f, -0.8404178401f, -0.3388616456f, 0.9408362159f, 0.8331530315f, 0.5530425174f, -0.2989720662f, -0.9542618632f, 0.2638522993f, 0.9645630949f, 0.124108739f, -0.9922686234f, -0.7282649308f, -0.6852956957f,
+	0.6962500149f, 0.7177993569f, -0.9183535368f, 0.3957610156f, -0.6326102274f, -0.7744703352f, -0.9331891859f, -0.359385508f, -0.1153779357f, -0.9933216659f, 0.9514974788f, -0.3076565421f, -0.08987977445f, -0.9959526224f, 0.6678496916f, 0.7442961705f,
+	0.7952400393f, -0.6062947138f, -0.6462007402f, -0.7631674805f, -0.2733598753f, 0.9619118351f, 0.9669590226f, -0.254931851f, -0.9792894595f, 0.2024651934f, -0.5369502995f, -0.8436138784f, -0.270036471f, -0.9628500944f, -0.6400277131f, 0.7683518247f,
+	-0.7854537493f, -0.6189203566f, 0.06005905383f, -0.9981948257f, -0.02455770378f, 0.9996984141f, -0.65983623f, 0.751409442f, -0.6253894466f, -0.7803127835f, -0.6210408851f, -0.7837781695f, 0.8348888491f, 0.5504185768f, -0.1592275245f, 0.9872419133f,
+	0.8367622488f, 0.5475663786f, -0.8675753916f, -0.4973056806f, -0.2022662628f, -0.9793305667f, 0.9399189937f, 0.3413975472f, 0.9877404807f, -0.1561049093f, -0.9034455656f, 0.4287028224f, 0.1269804218f, -0.9919052235f, -0.3819600854f, 0.924178821f,
+	0.9754625894f, 0.2201652486f, -0.3204015856f, -0.9472818081f, -0.9874760884f, 0.1577687387f, 0.02535348474f, -0.9996785487f, 0.4835130794f, -0.8753371362f, -0.2850799925f, -0.9585037287f, -0.06805516006f, -0.99768156f, -0.7885244045f, -0.6150034663f,
+	0.3185392127f, -0.9479096845f, 0.8880043089f, 0.4598351306f, 0.6476921488f, -0.7619021462f, 0.9820241299f, 0.1887554194f, 0.9357275128f, -0.3527237187f, -0.8894895414f, 0.4569555293f, 0.7922791302f, 0.6101588153f, 0.7483818261f, 0.6632681526f,
+	-0.7288929755f, -0.6846276581f, 0.8729032783f, -0.4878932944f, 0.8288345784f, 0.5594937369f, 0.08074567077f, 0.9967347374f, 0.9799148216f, -0.1994165048f, -0.580730673f, -0.8140957471f, -0.4700049791f, -0.8826637636f, 0.2409492979f, 0.9705377045f,
+	0.9437816757f, -0.3305694308f, -0.8927998638f, -0.4504535528f, -0.8069622304f, 0.5906030467f, 0.06258973166f, 0.9980393407f, -0.9312597469f, 0.3643559849f, 0.5777449785f, 0.8162173362f, -0.3360095855f, -0.941858566f, 0.697932075f, -0.7161639607f,
+	-0.002008157227f, -0.9999979837f, -0.1827294312f, -0.9831632392f, -0.6523911722f, 0.7578824173f, -0.4302626911f, -0.9027037258f, -0.9985126289f, -0.05452091251f, -0.01028102172f, -0.9999471489f, -0.4946071129f, 0.8691166802f, -0.2999350194f, 0.9539596344f,
+	0.8165471961f, 0.5772786819f, 0.2697460475f, 0.962931498f, -0.7306287391f, -0.6827749597f, -0.7590952064f, -0.6509796216f, -0.907053853f, 0.4210146171f, -0.5104861064f, -0.8598860013f, 0.8613350597f, 0.5080373165f, 0.5007881595f, -0.8655698812f,
+	-0.654158152f, 0.7563577938f, -0.8382755311f, -0.545246856f, 0.6940070834f, 0.7199681717f, 0.06950936031f, 0.9975812994f, 0.1702942185f, -0.9853932612f, 0.2695973274f, 0.9629731466f, 0.5519612192f, -0.8338697815f, 0.225657487f, -0.9742067022f,
+	0.4215262855f, -0.9068161835f, 0.4881873305f, -0.8727388672f, -0.3683854996f, -0.9296731273f, -0.9825390578f, 0.1860564427f, 0.81256471f, 0.5828709909f, 0.3196460933f, -0.9475370046f, 0.9570913859f, 0.2897862643f, -0.6876655497f, -0.7260276109f,
+	-0.9988770922f, -0.047376731f, -0.1250179027f, 0.992154486f, -0.8280133617f, 0.560708367f, 0.9324863769f, -0.3612051451f, 0.6394653183f, 0.7688199442f, -0.01623847064f, -0.9998681473f, -0.9955014666f, -0.09474613458f, -0.81453315f, 0.580117012f,
+	0.4037327978f, -0.9148769469f, 0.9944263371f, 0.1054336766f, -0.1624711654f, 0.9867132919f, -0.9949487814f, -0.100383875f, -0.6995302564f, 0.7146029809f, 0.5263414922f, -0.85027327f, -0.5395221479f, 0.841971408f, 0.6579370318f, 0.7530729462f,
+	0.01426758847f, -0.9998982128f, -0.6734383991f, 0.7392433447f, 0.639412098f, -0.7688642071f, 0.9211571421f, 0.3891908523f, -0.146637214f, -0.9891903394f, -0.782318098f, 0.6228791163f, -0.5039610839f, -0.8637263605f, -0.7743120191f, -0.6328039957f,
 };
 
 template <typename T>
 const T FastNoiseLite::Lookup<T>::Gradients3D[] =
 {
-    0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
-    1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
-    1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
-    0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
-    1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
-    1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
-    0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
-    1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
-    1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
-    0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
-    1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
-    1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
-    0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
-    1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
-    1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
-    1, 1, 0, 0,  0,-1, 1, 0, -1, 1, 0, 0,  0,-1,-1, 0
+	0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
+	1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
+	1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
+	0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
+	1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
+	1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
+	0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
+	1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
+	1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
+	0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
+	1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
+	1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
+	0, 1, 1, 0,  0,-1, 1, 0,  0, 1,-1, 0,  0,-1,-1, 0,
+	1, 0, 1, 0, -1, 0, 1, 0,  1, 0,-1, 0, -1, 0,-1, 0,
+	1, 1, 0, 0, -1, 1, 0, 0,  1,-1, 0, 0, -1,-1, 0, 0,
+	1, 1, 0, 0,  0,-1, 1, 0, -1, 1, 0, 0,  0,-1,-1, 0
 };
 
 template <typename T>
 const T FastNoiseLite::Lookup<T>::RandVecs3D[] =
 {
-    -0.7292736885f, -0.6618439697f, 0.1735581948f, 0, 0.790292081f, -0.5480887466f, -0.2739291014f, 0, 0.7217578935f, 0.6226212466f, -0.3023380997f, 0, 0.565683137f, -0.8208298145f, -0.0790000257f, 0, 0.760049034f, -0.5555979497f, -0.3370999617f, 0, 0.3713945616f, 0.5011264475f, 0.7816254623f, 0, -0.1277062463f, -0.4254438999f, -0.8959289049f, 0, -0.2881560924f, -0.5815838982f, 0.7607405838f, 0,
-    0.5849561111f, -0.662820239f, -0.4674352136f, 0, 0.3307171178f, 0.0391653737f, 0.94291689f, 0, 0.8712121778f, -0.4113374369f, -0.2679381538f, 0, 0.580981015f, 0.7021915846f, 0.4115677815f, 0, 0.503756873f, 0.6330056931f, -0.5878203852f, 0, 0.4493712205f, 0.601390195f, 0.6606022552f, 0, -0.6878403724f, 0.09018890807f, -0.7202371714f, 0, -0.5958956522f, -0.6469350577f, 0.475797649f, 0,
-    -0.5127052122f, 0.1946921978f, -0.8361987284f, 0, -0.9911507142f, -0.05410276466f, -0.1212153153f, 0, -0.2149721042f, 0.9720882117f, -0.09397607749f, 0, -0.7518650936f, -0.5428057603f, 0.3742469607f, 0, 0.5237068895f, 0.8516377189f, -0.02107817834f, 0, 0.6333504779f, 0.1926167129f, -0.7495104896f, 0, -0.06788241606f, 0.3998305789f, 0.9140719259f, 0, -0.5538628599f, -0.4729896695f, -0.6852128902f, 0,
-    -0.7261455366f, -0.5911990757f, 0.3509933228f, 0, -0.9229274737f, -0.1782808786f, 0.3412049336f, 0, -0.6968815002f, 0.6511274338f, 0.3006480328f, 0, 0.9608044783f, -0.2098363234f, -0.1811724921f, 0, 0.06817146062f, -0.9743405129f, 0.2145069156f, 0, -0.3577285196f, -0.6697087264f, -0.6507845481f, 0, -0.1868621131f, 0.7648617052f, -0.6164974636f, 0, -0.6541697588f, 0.3967914832f, 0.6439087246f, 0,
-    0.6993340405f, -0.6164538506f, 0.3618239211f, 0, -0.1546665739f, 0.6291283928f, 0.7617583057f, 0, -0.6841612949f, -0.2580482182f, -0.6821542638f, 0, 0.5383980957f, 0.4258654885f, 0.7271630328f, 0, -0.5026987823f, -0.7939832935f, -0.3418836993f, 0, 0.3202971715f, 0.2834415347f, 0.9039195862f, 0, 0.8683227101f, -0.0003762656404f, -0.4959995258f, 0, 0.791120031f, -0.08511045745f, 0.6057105799f, 0,
-    -0.04011016052f, -0.4397248749f, 0.8972364289f, 0, 0.9145119872f, 0.3579346169f, -0.1885487608f, 0, -0.9612039066f, -0.2756484276f, 0.01024666929f, 0, 0.6510361721f, -0.2877799159f, -0.7023778346f, 0, -0.2041786351f, 0.7365237271f, 0.644859585f, 0, -0.7718263711f, 0.3790626912f, 0.5104855816f, 0, -0.3060082741f, -0.7692987727f, 0.5608371729f, 0, 0.454007341f, -0.5024843065f, 0.7357899537f, 0,
-    0.4816795475f, 0.6021208291f, -0.6367380315f, 0, 0.6961980369f, -0.3222197429f, 0.641469197f, 0, -0.6532160499f, -0.6781148932f, 0.3368515753f, 0, 0.5089301236f, -0.6154662304f, -0.6018234363f, 0, -0.1635919754f, -0.9133604627f, -0.372840892f, 0, 0.52408019f, -0.8437664109f, 0.1157505864f, 0, 0.5902587356f, 0.4983817807f, -0.6349883666f, 0, 0.5863227872f, 0.494764745f, 0.6414307729f, 0,
-    0.6779335087f, 0.2341345225f, 0.6968408593f, 0, 0.7177054546f, -0.6858979348f, 0.120178631f, 0, -0.5328819713f, -0.5205125012f, 0.6671608058f, 0, -0.8654874251f, -0.0700727088f, -0.4960053754f, 0, -0.2861810166f, 0.7952089234f, 0.5345495242f, 0, -0.04849529634f, 0.9810836427f, -0.1874115585f, 0, -0.6358521667f, 0.6058348682f, 0.4781800233f, 0, 0.6254794696f, -0.2861619734f, 0.7258696564f, 0,
-    -0.2585259868f, 0.5061949264f, -0.8227581726f, 0, 0.02136306781f, 0.5064016808f, -0.8620330371f, 0, 0.200111773f, 0.8599263484f, 0.4695550591f, 0, 0.4743561372f, 0.6014985084f, -0.6427953014f, 0, 0.6622993731f, -0.5202474575f, -0.5391679918f, 0, 0.08084972818f, -0.6532720452f, 0.7527940996f, 0, -0.6893687501f, 0.0592860349f, 0.7219805347f, 0, -0.1121887082f, -0.9673185067f, 0.2273952515f, 0,
-    0.7344116094f, 0.5979668656f, -0.3210532909f, 0, 0.5789393465f, -0.2488849713f, 0.7764570201f, 0, 0.6988182827f, 0.3557169806f, -0.6205791146f, 0, -0.8636845529f, -0.2748771249f, -0.4224826141f, 0, -0.4247027957f, -0.4640880967f, 0.777335046f, 0, 0.5257722489f, -0.8427017621f, 0.1158329937f, 0, 0.9343830603f, 0.316302472f, -0.1639543925f, 0, -0.1016836419f, -0.8057303073f, -0.5834887393f, 0,
-    -0.6529238969f, 0.50602126f, -0.5635892736f, 0, -0.2465286165f, -0.9668205684f, -0.06694497494f, 0, -0.9776897119f, -0.2099250524f, -0.007368825344f, 0, 0.7736893337f, 0.5734244712f, 0.2694238123f, 0, -0.6095087895f, 0.4995678998f, 0.6155736747f, 0, 0.5794535482f, 0.7434546771f, 0.3339292269f, 0, -0.8226211154f, 0.08142581855f, 0.5627293636f, 0, -0.510385483f, 0.4703667658f, 0.7199039967f, 0,
-    -0.5764971849f, -0.07231656274f, -0.8138926898f, 0, 0.7250628871f, 0.3949971505f, -0.5641463116f, 0, -0.1525424005f, 0.4860840828f, -0.8604958341f, 0, -0.5550976208f, -0.4957820792f, 0.667882296f, 0, -0.1883614327f, 0.9145869398f, 0.357841725f, 0, 0.7625556724f, -0.5414408243f, -0.3540489801f, 0, -0.5870231946f, -0.3226498013f, -0.7424963803f, 0, 0.3051124198f, 0.2262544068f, -0.9250488391f, 0,
-    0.6379576059f, 0.577242424f, -0.5097070502f, 0, -0.5966775796f, 0.1454852398f, -0.7891830656f, 0, -0.658330573f, 0.6555487542f, -0.3699414651f, 0, 0.7434892426f, 0.2351084581f, 0.6260573129f, 0, 0.5562114096f, 0.8264360377f, -0.0873632843f, 0, -0.3028940016f, -0.8251527185f, 0.4768419182f, 0, 0.1129343818f, -0.985888439f, -0.1235710781f, 0, 0.5937652891f, -0.5896813806f, 0.5474656618f, 0,
-    0.6757964092f, -0.5835758614f, -0.4502648413f, 0, 0.7242302609f, -0.1152719764f, 0.6798550586f, 0, -0.9511914166f, 0.0753623979f, -0.2992580792f, 0, 0.2539470961f, -0.1886339355f, 0.9486454084f, 0, 0.571433621f, -0.1679450851f, -0.8032795685f, 0, -0.06778234979f, 0.3978269256f, 0.9149531629f, 0, 0.6074972649f, 0.733060024f, -0.3058922593f, 0, -0.5435478392f, 0.1675822484f, 0.8224791405f, 0,
-    -0.5876678086f, -0.3380045064f, -0.7351186982f, 0, -0.7967562402f, 0.04097822706f, -0.6029098428f, 0, -0.1996350917f, 0.8706294745f, 0.4496111079f, 0, -0.02787660336f, -0.9106232682f, -0.4122962022f, 0, -0.7797625996f, -0.6257634692f, 0.01975775581f, 0, -0.5211232846f, 0.7401644346f, -0.4249554471f, 0, 0.8575424857f, 0.4053272873f, -0.3167501783f, 0, 0.1045223322f, 0.8390195772f, -0.5339674439f, 0,
-    0.3501822831f, 0.9242524096f, -0.1520850155f, 0, 0.1987849858f, 0.07647613266f, 0.9770547224f, 0, 0.7845996363f, 0.6066256811f, -0.1280964233f, 0, 0.09006737436f, -0.9750989929f, -0.2026569073f, 0, -0.8274343547f, -0.542299559f, 0.1458203587f, 0, -0.3485797732f, -0.415802277f, 0.840000362f, 0, -0.2471778936f, -0.7304819962f, -0.6366310879f, 0, -0.3700154943f, 0.8577948156f, 0.3567584454f, 0,
-    0.5913394901f, -0.548311967f, -0.5913303597f, 0, 0.1204873514f, -0.7626472379f, -0.6354935001f, 0, 0.616959265f, 0.03079647928f, 0.7863922953f, 0, 0.1258156836f, -0.6640829889f, -0.7369967419f, 0, -0.6477565124f, -0.1740147258f, -0.7417077429f, 0, 0.6217889313f, -0.7804430448f, -0.06547655076f, 0, 0.6589943422f, -0.6096987708f, 0.4404473475f, 0, -0.2689837504f, -0.6732403169f, -0.6887635427f, 0,
-    -0.3849775103f, 0.5676542638f, 0.7277093879f, 0, 0.5754444408f, 0.8110471154f, -0.1051963504f, 0, 0.9141593684f, 0.3832947817f, 0.131900567f, 0, -0.107925319f, 0.9245493968f, 0.3654593525f, 0, 0.377977089f, 0.3043148782f, 0.8743716458f, 0, -0.2142885215f, -0.8259286236f, 0.5214617324f, 0, 0.5802544474f, 0.4148098596f, -0.7008834116f, 0, -0.1982660881f, 0.8567161266f, -0.4761596756f, 0,
-    -0.03381553704f, 0.3773180787f, -0.9254661404f, 0, -0.6867922841f, -0.6656597827f, 0.2919133642f, 0, 0.7731742607f, -0.2875793547f, -0.5652430251f, 0, -0.09655941928f, 0.9193708367f, -0.3813575004f, 0, 0.2715702457f, -0.9577909544f, -0.09426605581f, 0, 0.2451015704f, -0.6917998565f, -0.6792188003f, 0, 0.977700782f, -0.1753855374f, 0.1155036542f, 0, -0.5224739938f, 0.8521606816f, 0.02903615945f, 0,
-    -0.7734880599f, -0.5261292347f, 0.3534179531f, 0, -0.7134492443f, -0.269547243f, 0.6467878011f, 0, 0.1644037271f, 0.5105846203f, -0.8439637196f, 0, 0.6494635788f, 0.05585611296f, 0.7583384168f, 0, -0.4711970882f, 0.5017280509f, -0.7254255765f, 0, -0.6335764307f, -0.2381686273f, -0.7361091029f, 0, -0.9021533097f, -0.270947803f, -0.3357181763f, 0, -0.3793711033f, 0.872258117f, 0.3086152025f, 0,
-    -0.6855598966f, -0.3250143309f, 0.6514394162f, 0, 0.2900942212f, -0.7799057743f, -0.5546100667f, 0, -0.2098319339f, 0.85037073f, 0.4825351604f, 0, -0.4592603758f, 0.6598504336f, -0.5947077538f, 0, 0.8715945488f, 0.09616365406f, -0.4807031248f, 0, -0.6776666319f, 0.7118504878f, -0.1844907016f, 0, 0.7044377633f, 0.312427597f, 0.637304036f, 0, -0.7052318886f, -0.2401093292f, -0.6670798253f, 0,
-    0.081921007f, -0.7207336136f, -0.6883545647f, 0, -0.6993680906f, -0.5875763221f, -0.4069869034f, 0, -0.1281454481f, 0.6419895885f, 0.7559286424f, 0, -0.6337388239f, -0.6785471501f, -0.3714146849f, 0, 0.5565051903f, -0.2168887573f, -0.8020356851f, 0, -0.5791554484f, 0.7244372011f, -0.3738578718f, 0, 0.1175779076f, -0.7096451073f, 0.6946792478f, 0, -0.6134619607f, 0.1323631078f, 0.7785527795f, 0,
-    0.6984635305f, -0.02980516237f, -0.715024719f, 0, 0.8318082963f, -0.3930171956f, 0.3919597455f, 0, 0.1469576422f, 0.05541651717f, -0.9875892167f, 0, 0.708868575f, -0.2690503865f, 0.6520101478f, 0, 0.2726053183f, 0.67369766f, -0.68688995f, 0, -0.6591295371f, 0.3035458599f, -0.6880466294f, 0, 0.4815131379f, -0.7528270071f, 0.4487723203f, 0, 0.9430009463f, 0.1675647412f, -0.2875261255f, 0,
-    0.434802957f, 0.7695304522f, -0.4677277752f, 0, 0.3931996188f, 0.594473625f, 0.7014236729f, 0, 0.7254336655f, -0.603925654f, 0.3301814672f, 0, 0.7590235227f, -0.6506083235f, 0.02433313207f, 0, -0.8552768592f, -0.3430042733f, 0.3883935666f, 0, -0.6139746835f, 0.6981725247f, 0.3682257648f, 0, -0.7465905486f, -0.5752009504f, 0.3342849376f, 0, 0.5730065677f, 0.810555537f, -0.1210916791f, 0,
-    -0.9225877367f, -0.3475211012f, -0.167514036f, 0, -0.7105816789f, -0.4719692027f, -0.5218416899f, 0, -0.08564609717f, 0.3583001386f, 0.929669703f, 0, -0.8279697606f, -0.2043157126f, 0.5222271202f, 0, 0.427944023f, 0.278165994f, 0.8599346446f, 0, 0.5399079671f, -0.7857120652f, -0.3019204161f, 0, 0.5678404253f, -0.5495413974f, -0.6128307303f, 0, -0.9896071041f, 0.1365639107f, -0.04503418428f, 0,
-    -0.6154342638f, -0.6440875597f, 0.4543037336f, 0, 0.1074204368f, -0.7946340692f, 0.5975094525f, 0, -0.3595449969f, -0.8885529948f, 0.28495784f, 0, -0.2180405296f, 0.1529888965f, 0.9638738118f, 0, -0.7277432317f, -0.6164050508f, -0.3007234646f, 0, 0.7249729114f, -0.00669719484f, 0.6887448187f, 0, -0.5553659455f, -0.5336586252f, 0.6377908264f, 0, 0.5137558015f, 0.7976208196f, -0.3160000073f, 0,
-    -0.3794024848f, 0.9245608561f, -0.03522751494f, 0, 0.8229248658f, 0.2745365933f, -0.4974176556f, 0, -0.5404114394f, 0.6091141441f, 0.5804613989f, 0, 0.8036581901f, -0.2703029469f, 0.5301601931f, 0, 0.6044318879f, 0.6832968393f, 0.4095943388f, 0, 0.06389988817f, 0.9658208605f, -0.2512108074f, 0, 0.1087113286f, 0.7402471173f, -0.6634877936f, 0, -0.713427712f, -0.6926784018f, 0.1059128479f, 0,
-    0.6458897819f, -0.5724548511f, -0.5050958653f, 0, -0.6553931414f, 0.7381471625f, 0.159995615f, 0, 0.3910961323f, 0.9188871375f, -0.05186755998f, 0, -0.4879022471f, -0.5904376907f, 0.6429111375f, 0, 0.6014790094f, 0.7707441366f, -0.2101820095f, 0, -0.5677173047f, 0.7511360995f, 0.3368851762f, 0, 0.7858573506f, 0.226674665f, 0.5753666838f, 0, -0.4520345543f, -0.604222686f, -0.6561857263f, 0,
-    0.002272116345f, 0.4132844051f, -0.9105991643f, 0, -0.5815751419f, -0.5162925989f, 0.6286591339f, 0, -0.03703704785f, 0.8273785755f, 0.5604221175f, 0, -0.5119692504f, 0.7953543429f, -0.3244980058f, 0, -0.2682417366f, -0.9572290247f, -0.1084387619f, 0, -0.2322482736f, -0.9679131102f, -0.09594243324f, 0, 0.3554328906f, -0.8881505545f, 0.2913006227f, 0, 0.7346520519f, -0.4371373164f, 0.5188422971f, 0,
-    0.9985120116f, 0.04659011161f, -0.02833944577f, 0, -0.3727687496f, -0.9082481361f, 0.1900757285f, 0, 0.91737377f, -0.3483642108f, 0.1925298489f, 0, 0.2714911074f, 0.4147529736f, -0.8684886582f, 0, 0.5131763485f, -0.7116334161f, 0.4798207128f, 0, -0.8737353606f, 0.18886992f, -0.4482350644f, 0, 0.8460043821f, -0.3725217914f, 0.3814499973f, 0, 0.8978727456f, -0.1780209141f, -0.4026575304f, 0,
-    0.2178065647f, -0.9698322841f, -0.1094789531f, 0, -0.1518031304f, -0.7788918132f, -0.6085091231f, 0, -0.2600384876f, -0.4755398075f, -0.8403819825f, 0, 0.572313509f, -0.7474340931f, -0.3373418503f, 0, -0.7174141009f, 0.1699017182f, -0.6756111411f, 0, -0.684180784f, 0.02145707593f, -0.7289967412f, 0, -0.2007447902f, 0.06555605789f, -0.9774476623f, 0, -0.1148803697f, -0.8044887315f, 0.5827524187f, 0,
-    -0.7870349638f, 0.03447489231f, 0.6159443543f, 0, -0.2015596421f, 0.6859872284f, 0.6991389226f, 0, -0.08581082512f, -0.10920836f, -0.9903080513f, 0, 0.5532693395f, 0.7325250401f, -0.396610771f, 0, -0.1842489331f, -0.9777375055f, -0.1004076743f, 0, 0.0775473789f, -0.9111505856f, 0.4047110257f, 0, 0.1399838409f, 0.7601631212f, -0.6344734459f, 0, 0.4484419361f, -0.845289248f, 0.2904925424f, 0
+	-0.7292736885f, -0.6618439697f, 0.1735581948f, 0, 0.790292081f, -0.5480887466f, -0.2739291014f, 0, 0.7217578935f, 0.6226212466f, -0.3023380997f, 0, 0.565683137f, -0.8208298145f, -0.0790000257f, 0, 0.760049034f, -0.5555979497f, -0.3370999617f, 0, 0.3713945616f, 0.5011264475f, 0.7816254623f, 0, -0.1277062463f, -0.4254438999f, -0.8959289049f, 0, -0.2881560924f, -0.5815838982f, 0.7607405838f, 0,
+	0.5849561111f, -0.662820239f, -0.4674352136f, 0, 0.3307171178f, 0.0391653737f, 0.94291689f, 0, 0.8712121778f, -0.4113374369f, -0.2679381538f, 0, 0.580981015f, 0.7021915846f, 0.4115677815f, 0, 0.503756873f, 0.6330056931f, -0.5878203852f, 0, 0.4493712205f, 0.601390195f, 0.6606022552f, 0, -0.6878403724f, 0.09018890807f, -0.7202371714f, 0, -0.5958956522f, -0.6469350577f, 0.475797649f, 0,
+	-0.5127052122f, 0.1946921978f, -0.8361987284f, 0, -0.9911507142f, -0.05410276466f, -0.1212153153f, 0, -0.2149721042f, 0.9720882117f, -0.09397607749f, 0, -0.7518650936f, -0.5428057603f, 0.3742469607f, 0, 0.5237068895f, 0.8516377189f, -0.02107817834f, 0, 0.6333504779f, 0.1926167129f, -0.7495104896f, 0, -0.06788241606f, 0.3998305789f, 0.9140719259f, 0, -0.5538628599f, -0.4729896695f, -0.6852128902f, 0,
+	-0.7261455366f, -0.5911990757f, 0.3509933228f, 0, -0.9229274737f, -0.1782808786f, 0.3412049336f, 0, -0.6968815002f, 0.6511274338f, 0.3006480328f, 0, 0.9608044783f, -0.2098363234f, -0.1811724921f, 0, 0.06817146062f, -0.9743405129f, 0.2145069156f, 0, -0.3577285196f, -0.6697087264f, -0.6507845481f, 0, -0.1868621131f, 0.7648617052f, -0.6164974636f, 0, -0.6541697588f, 0.3967914832f, 0.6439087246f, 0,
+	0.6993340405f, -0.6164538506f, 0.3618239211f, 0, -0.1546665739f, 0.6291283928f, 0.7617583057f, 0, -0.6841612949f, -0.2580482182f, -0.6821542638f, 0, 0.5383980957f, 0.4258654885f, 0.7271630328f, 0, -0.5026987823f, -0.7939832935f, -0.3418836993f, 0, 0.3202971715f, 0.2834415347f, 0.9039195862f, 0, 0.8683227101f, -0.0003762656404f, -0.4959995258f, 0, 0.791120031f, -0.08511045745f, 0.6057105799f, 0,
+	-0.04011016052f, -0.4397248749f, 0.8972364289f, 0, 0.9145119872f, 0.3579346169f, -0.1885487608f, 0, -0.9612039066f, -0.2756484276f, 0.01024666929f, 0, 0.6510361721f, -0.2877799159f, -0.7023778346f, 0, -0.2041786351f, 0.7365237271f, 0.644859585f, 0, -0.7718263711f, 0.3790626912f, 0.5104855816f, 0, -0.3060082741f, -0.7692987727f, 0.5608371729f, 0, 0.454007341f, -0.5024843065f, 0.7357899537f, 0,
+	0.4816795475f, 0.6021208291f, -0.6367380315f, 0, 0.6961980369f, -0.3222197429f, 0.641469197f, 0, -0.6532160499f, -0.6781148932f, 0.3368515753f, 0, 0.5089301236f, -0.6154662304f, -0.6018234363f, 0, -0.1635919754f, -0.9133604627f, -0.372840892f, 0, 0.52408019f, -0.8437664109f, 0.1157505864f, 0, 0.5902587356f, 0.4983817807f, -0.6349883666f, 0, 0.5863227872f, 0.494764745f, 0.6414307729f, 0,
+	0.6779335087f, 0.2341345225f, 0.6968408593f, 0, 0.7177054546f, -0.6858979348f, 0.120178631f, 0, -0.5328819713f, -0.5205125012f, 0.6671608058f, 0, -0.8654874251f, -0.0700727088f, -0.4960053754f, 0, -0.2861810166f, 0.7952089234f, 0.5345495242f, 0, -0.04849529634f, 0.9810836427f, -0.1874115585f, 0, -0.6358521667f, 0.6058348682f, 0.4781800233f, 0, 0.6254794696f, -0.2861619734f, 0.7258696564f, 0,
+	-0.2585259868f, 0.5061949264f, -0.8227581726f, 0, 0.02136306781f, 0.5064016808f, -0.8620330371f, 0, 0.200111773f, 0.8599263484f, 0.4695550591f, 0, 0.4743561372f, 0.6014985084f, -0.6427953014f, 0, 0.6622993731f, -0.5202474575f, -0.5391679918f, 0, 0.08084972818f, -0.6532720452f, 0.7527940996f, 0, -0.6893687501f, 0.0592860349f, 0.7219805347f, 0, -0.1121887082f, -0.9673185067f, 0.2273952515f, 0,
+	0.7344116094f, 0.5979668656f, -0.3210532909f, 0, 0.5789393465f, -0.2488849713f, 0.7764570201f, 0, 0.6988182827f, 0.3557169806f, -0.6205791146f, 0, -0.8636845529f, -0.2748771249f, -0.4224826141f, 0, -0.4247027957f, -0.4640880967f, 0.777335046f, 0, 0.5257722489f, -0.8427017621f, 0.1158329937f, 0, 0.9343830603f, 0.316302472f, -0.1639543925f, 0, -0.1016836419f, -0.8057303073f, -0.5834887393f, 0,
+	-0.6529238969f, 0.50602126f, -0.5635892736f, 0, -0.2465286165f, -0.9668205684f, -0.06694497494f, 0, -0.9776897119f, -0.2099250524f, -0.007368825344f, 0, 0.7736893337f, 0.5734244712f, 0.2694238123f, 0, -0.6095087895f, 0.4995678998f, 0.6155736747f, 0, 0.5794535482f, 0.7434546771f, 0.3339292269f, 0, -0.8226211154f, 0.08142581855f, 0.5627293636f, 0, -0.510385483f, 0.4703667658f, 0.7199039967f, 0,
+	-0.5764971849f, -0.07231656274f, -0.8138926898f, 0, 0.7250628871f, 0.3949971505f, -0.5641463116f, 0, -0.1525424005f, 0.4860840828f, -0.8604958341f, 0, -0.5550976208f, -0.4957820792f, 0.667882296f, 0, -0.1883614327f, 0.9145869398f, 0.357841725f, 0, 0.7625556724f, -0.5414408243f, -0.3540489801f, 0, -0.5870231946f, -0.3226498013f, -0.7424963803f, 0, 0.3051124198f, 0.2262544068f, -0.9250488391f, 0,
+	0.6379576059f, 0.577242424f, -0.5097070502f, 0, -0.5966775796f, 0.1454852398f, -0.7891830656f, 0, -0.658330573f, 0.6555487542f, -0.3699414651f, 0, 0.7434892426f, 0.2351084581f, 0.6260573129f, 0, 0.5562114096f, 0.8264360377f, -0.0873632843f, 0, -0.3028940016f, -0.8251527185f, 0.4768419182f, 0, 0.1129343818f, -0.985888439f, -0.1235710781f, 0, 0.5937652891f, -0.5896813806f, 0.5474656618f, 0,
+	0.6757964092f, -0.5835758614f, -0.4502648413f, 0, 0.7242302609f, -0.1152719764f, 0.6798550586f, 0, -0.9511914166f, 0.0753623979f, -0.2992580792f, 0, 0.2539470961f, -0.1886339355f, 0.9486454084f, 0, 0.571433621f, -0.1679450851f, -0.8032795685f, 0, -0.06778234979f, 0.3978269256f, 0.9149531629f, 0, 0.6074972649f, 0.733060024f, -0.3058922593f, 0, -0.5435478392f, 0.1675822484f, 0.8224791405f, 0,
+	-0.5876678086f, -0.3380045064f, -0.7351186982f, 0, -0.7967562402f, 0.04097822706f, -0.6029098428f, 0, -0.1996350917f, 0.8706294745f, 0.4496111079f, 0, -0.02787660336f, -0.9106232682f, -0.4122962022f, 0, -0.7797625996f, -0.6257634692f, 0.01975775581f, 0, -0.5211232846f, 0.7401644346f, -0.4249554471f, 0, 0.8575424857f, 0.4053272873f, -0.3167501783f, 0, 0.1045223322f, 0.8390195772f, -0.5339674439f, 0,
+	0.3501822831f, 0.9242524096f, -0.1520850155f, 0, 0.1987849858f, 0.07647613266f, 0.9770547224f, 0, 0.7845996363f, 0.6066256811f, -0.1280964233f, 0, 0.09006737436f, -0.9750989929f, -0.2026569073f, 0, -0.8274343547f, -0.542299559f, 0.1458203587f, 0, -0.3485797732f, -0.415802277f, 0.840000362f, 0, -0.2471778936f, -0.7304819962f, -0.6366310879f, 0, -0.3700154943f, 0.8577948156f, 0.3567584454f, 0,
+	0.5913394901f, -0.548311967f, -0.5913303597f, 0, 0.1204873514f, -0.7626472379f, -0.6354935001f, 0, 0.616959265f, 0.03079647928f, 0.7863922953f, 0, 0.1258156836f, -0.6640829889f, -0.7369967419f, 0, -0.6477565124f, -0.1740147258f, -0.7417077429f, 0, 0.6217889313f, -0.7804430448f, -0.06547655076f, 0, 0.6589943422f, -0.6096987708f, 0.4404473475f, 0, -0.2689837504f, -0.6732403169f, -0.6887635427f, 0,
+	-0.3849775103f, 0.5676542638f, 0.7277093879f, 0, 0.5754444408f, 0.8110471154f, -0.1051963504f, 0, 0.9141593684f, 0.3832947817f, 0.131900567f, 0, -0.107925319f, 0.9245493968f, 0.3654593525f, 0, 0.377977089f, 0.3043148782f, 0.8743716458f, 0, -0.2142885215f, -0.8259286236f, 0.5214617324f, 0, 0.5802544474f, 0.4148098596f, -0.7008834116f, 0, -0.1982660881f, 0.8567161266f, -0.4761596756f, 0,
+	-0.03381553704f, 0.3773180787f, -0.9254661404f, 0, -0.6867922841f, -0.6656597827f, 0.2919133642f, 0, 0.7731742607f, -0.2875793547f, -0.5652430251f, 0, -0.09655941928f, 0.9193708367f, -0.3813575004f, 0, 0.2715702457f, -0.9577909544f, -0.09426605581f, 0, 0.2451015704f, -0.6917998565f, -0.6792188003f, 0, 0.977700782f, -0.1753855374f, 0.1155036542f, 0, -0.5224739938f, 0.8521606816f, 0.02903615945f, 0,
+	-0.7734880599f, -0.5261292347f, 0.3534179531f, 0, -0.7134492443f, -0.269547243f, 0.6467878011f, 0, 0.1644037271f, 0.5105846203f, -0.8439637196f, 0, 0.6494635788f, 0.05585611296f, 0.7583384168f, 0, -0.4711970882f, 0.5017280509f, -0.7254255765f, 0, -0.6335764307f, -0.2381686273f, -0.7361091029f, 0, -0.9021533097f, -0.270947803f, -0.3357181763f, 0, -0.3793711033f, 0.872258117f, 0.3086152025f, 0,
+	-0.6855598966f, -0.3250143309f, 0.6514394162f, 0, 0.2900942212f, -0.7799057743f, -0.5546100667f, 0, -0.2098319339f, 0.85037073f, 0.4825351604f, 0, -0.4592603758f, 0.6598504336f, -0.5947077538f, 0, 0.8715945488f, 0.09616365406f, -0.4807031248f, 0, -0.6776666319f, 0.7118504878f, -0.1844907016f, 0, 0.7044377633f, 0.312427597f, 0.637304036f, 0, -0.7052318886f, -0.2401093292f, -0.6670798253f, 0,
+	0.081921007f, -0.7207336136f, -0.6883545647f, 0, -0.6993680906f, -0.5875763221f, -0.4069869034f, 0, -0.1281454481f, 0.6419895885f, 0.7559286424f, 0, -0.6337388239f, -0.6785471501f, -0.3714146849f, 0, 0.5565051903f, -0.2168887573f, -0.8020356851f, 0, -0.5791554484f, 0.7244372011f, -0.3738578718f, 0, 0.1175779076f, -0.7096451073f, 0.6946792478f, 0, -0.6134619607f, 0.1323631078f, 0.7785527795f, 0,
+	0.6984635305f, -0.02980516237f, -0.715024719f, 0, 0.8318082963f, -0.3930171956f, 0.3919597455f, 0, 0.1469576422f, 0.05541651717f, -0.9875892167f, 0, 0.708868575f, -0.2690503865f, 0.6520101478f, 0, 0.2726053183f, 0.67369766f, -0.68688995f, 0, -0.6591295371f, 0.3035458599f, -0.6880466294f, 0, 0.4815131379f, -0.7528270071f, 0.4487723203f, 0, 0.9430009463f, 0.1675647412f, -0.2875261255f, 0,
+	0.434802957f, 0.7695304522f, -0.4677277752f, 0, 0.3931996188f, 0.594473625f, 0.7014236729f, 0, 0.7254336655f, -0.603925654f, 0.3301814672f, 0, 0.7590235227f, -0.6506083235f, 0.02433313207f, 0, -0.8552768592f, -0.3430042733f, 0.3883935666f, 0, -0.6139746835f, 0.6981725247f, 0.3682257648f, 0, -0.7465905486f, -0.5752009504f, 0.3342849376f, 0, 0.5730065677f, 0.810555537f, -0.1210916791f, 0,
+	-0.9225877367f, -0.3475211012f, -0.167514036f, 0, -0.7105816789f, -0.4719692027f, -0.5218416899f, 0, -0.08564609717f, 0.3583001386f, 0.929669703f, 0, -0.8279697606f, -0.2043157126f, 0.5222271202f, 0, 0.427944023f, 0.278165994f, 0.8599346446f, 0, 0.5399079671f, -0.7857120652f, -0.3019204161f, 0, 0.5678404253f, -0.5495413974f, -0.6128307303f, 0, -0.9896071041f, 0.1365639107f, -0.04503418428f, 0,
+	-0.6154342638f, -0.6440875597f, 0.4543037336f, 0, 0.1074204368f, -0.7946340692f, 0.5975094525f, 0, -0.3595449969f, -0.8885529948f, 0.28495784f, 0, -0.2180405296f, 0.1529888965f, 0.9638738118f, 0, -0.7277432317f, -0.6164050508f, -0.3007234646f, 0, 0.7249729114f, -0.00669719484f, 0.6887448187f, 0, -0.5553659455f, -0.5336586252f, 0.6377908264f, 0, 0.5137558015f, 0.7976208196f, -0.3160000073f, 0,
+	-0.3794024848f, 0.9245608561f, -0.03522751494f, 0, 0.8229248658f, 0.2745365933f, -0.4974176556f, 0, -0.5404114394f, 0.6091141441f, 0.5804613989f, 0, 0.8036581901f, -0.2703029469f, 0.5301601931f, 0, 0.6044318879f, 0.6832968393f, 0.4095943388f, 0, 0.06389988817f, 0.9658208605f, -0.2512108074f, 0, 0.1087113286f, 0.7402471173f, -0.6634877936f, 0, -0.713427712f, -0.6926784018f, 0.1059128479f, 0,
+	0.6458897819f, -0.5724548511f, -0.5050958653f, 0, -0.6553931414f, 0.7381471625f, 0.159995615f, 0, 0.3910961323f, 0.9188871375f, -0.05186755998f, 0, -0.4879022471f, -0.5904376907f, 0.6429111375f, 0, 0.6014790094f, 0.7707441366f, -0.2101820095f, 0, -0.5677173047f, 0.7511360995f, 0.3368851762f, 0, 0.7858573506f, 0.226674665f, 0.5753666838f, 0, -0.4520345543f, -0.604222686f, -0.6561857263f, 0,
+	0.002272116345f, 0.4132844051f, -0.9105991643f, 0, -0.5815751419f, -0.5162925989f, 0.6286591339f, 0, -0.03703704785f, 0.8273785755f, 0.5604221175f, 0, -0.5119692504f, 0.7953543429f, -0.3244980058f, 0, -0.2682417366f, -0.9572290247f, -0.1084387619f, 0, -0.2322482736f, -0.9679131102f, -0.09594243324f, 0, 0.3554328906f, -0.8881505545f, 0.2913006227f, 0, 0.7346520519f, -0.4371373164f, 0.5188422971f, 0,
+	0.9985120116f, 0.04659011161f, -0.02833944577f, 0, -0.3727687496f, -0.9082481361f, 0.1900757285f, 0, 0.91737377f, -0.3483642108f, 0.1925298489f, 0, 0.2714911074f, 0.4147529736f, -0.8684886582f, 0, 0.5131763485f, -0.7116334161f, 0.4798207128f, 0, -0.8737353606f, 0.18886992f, -0.4482350644f, 0, 0.8460043821f, -0.3725217914f, 0.3814499973f, 0, 0.8978727456f, -0.1780209141f, -0.4026575304f, 0,
+	0.2178065647f, -0.9698322841f, -0.1094789531f, 0, -0.1518031304f, -0.7788918132f, -0.6085091231f, 0, -0.2600384876f, -0.4755398075f, -0.8403819825f, 0, 0.572313509f, -0.7474340931f, -0.3373418503f, 0, -0.7174141009f, 0.1699017182f, -0.6756111411f, 0, -0.684180784f, 0.02145707593f, -0.7289967412f, 0, -0.2007447902f, 0.06555605789f, -0.9774476623f, 0, -0.1148803697f, -0.8044887315f, 0.5827524187f, 0,
+	-0.7870349638f, 0.03447489231f, 0.6159443543f, 0, -0.2015596421f, 0.6859872284f, 0.6991389226f, 0, -0.08581082512f, -0.10920836f, -0.9903080513f, 0, 0.5532693395f, 0.7325250401f, -0.396610771f, 0, -0.1842489331f, -0.9777375055f, -0.1004076743f, 0, 0.0775473789f, -0.9111505856f, 0.4047110257f, 0, 0.1399838409f, 0.7601631212f, -0.6344734459f, 0, 0.4484419361f, -0.845289248f, 0.2904925424f, 0
 };
 
 #endif

+ 12 - 12
FactoryCraft/FastNoiseWrapper.cpp

@@ -1,30 +1,30 @@
 #include "FastNoiseWrapper.h"
 
-FastNoiseWrapper::FastNoiseWrapper( FastNoiseLite* noise, int seed )
+FastNoiseWrapper::FastNoiseWrapper(FastNoiseLite* noise, int seed)
 {
-    this->noise = noise;
-    this->seed = seed;
-    this->multiplier = 1.f;
+	this->noise = noise;
+	this->seed = seed;
+	this->multiplier = 1.f;
 }
 
 FastNoiseWrapper::~FastNoiseWrapper()
 {
-    delete noise;
+	delete noise;
 }
 
-void FastNoiseWrapper::setMultiplier( float multiplier )
+void FastNoiseWrapper::setMultiplier(float multiplier)
 {
-    assert( multiplier > 0 );
-    this->multiplier = multiplier;
+	assert(multiplier > 0);
+	this->multiplier = multiplier;
 }
 
 int FastNoiseWrapper::getSeed() const
 {
-    return seed;
+	return seed;
 }
 
-double FastNoiseWrapper::getNoise( double x, double y, double z )
+double FastNoiseWrapper::getNoise(double x, double y, double z)
 {
-    // scale the noise from 0 to 1
-    return (noise->GetNoise( x, y, z ) * multiplier + 1) / 2;
+	// scale the noise from 0 to 1
+	return (noise->GetNoise(x, y, z) * multiplier + 1) / 2;
 }

+ 8 - 8
FactoryCraft/FastNoiseWrapper.h

@@ -5,14 +5,14 @@
 class FastNoiseWrapper : public Noise
 {
 private:
-    int seed;
-    float multiplier;
-    FastNoiseLite* noise;
+	int seed;
+	float multiplier;
+	FastNoiseLite* noise;
 
 public:
-    FastNoiseWrapper( FastNoiseLite* noise, int seed );
-    ~FastNoiseWrapper();
-    void setMultiplier( float multiplier );
-    int getSeed() const;
-    double getNoise( double x, double y, double z );
+	FastNoiseWrapper(FastNoiseLite* noise, int seed);
+	~FastNoiseWrapper();
+	void setMultiplier(float multiplier);
+	int getSeed() const;
+	double getNoise(double x, double y, double z);
 };

+ 41 - 3
FactoryCraft/Game.cpp

@@ -184,18 +184,18 @@ bool GameClient::isOnline() const
 
 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 }))
+	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 }, zPlayer->getCurrentDimensionId()))
 	{
 		if (zResponse->isUseBackground())
 		{
-			background.unlock();
+			background.lock();
 			client->zBackgroundWriter()->schreibe((char*)&Message::API_MESSAGE, 1);
 			zResponse->writeTo(client->zBackgroundWriter());
 			background.unlock();
 		}
 		else
 		{
-			foreground.unlock();
+			foreground.lock();
 			client->zForegroundWriter()->schreibe((char*)&Message::API_MESSAGE, 1);
 			zResponse->writeTo(client->zForegroundWriter());
 			foreground.unlock();
@@ -208,6 +208,43 @@ Player* GameClient::zEntity() const
 	return zPlayer;
 }
 
+void GameClient::sendTypes()
+{
+	foreground.lock();
+	int count = StaticRegistry<BlockType>::INSTANCE.getCount();
+	client->zForegroundWriter()->schreibe((char*)&count, 4);
+	for (int i = 0; i < count; i++)
+	{
+		BlockType* t = StaticRegistry<BlockType>::INSTANCE.zElement(i);
+		int id = t->getId();
+		client->zForegroundWriter()->schreibe((char*)&id, 4);
+		bool inst = t->doesNeedClientInstance();
+		client->zForegroundWriter()->schreibe((char*)&inst, 1);
+		int maxHp = t->getInitialMaxHP();
+		client->zForegroundWriter()->schreibe((char*)&maxHp, 4);
+		t->getModel().writeTo(client->zForegroundWriter());
+	}
+	count = StaticRegistry<ItemType>::INSTANCE.getCount();
+	client->zForegroundWriter()->schreibe((char*)&count, 4);
+	for (int i = 0; i < count; i++)
+	{
+		ItemType* t = StaticRegistry<ItemType>::INSTANCE.zElement(i);
+		int id = t->getId();
+		client->zForegroundWriter()->schreibe((char*)&id, 4);
+		t->getModel().writeTo(client->zForegroundWriter());
+	}
+	count = StaticRegistry<EntityType>::INSTANCE.getCount();
+	client->zForegroundWriter()->schreibe((char*)&count, 4);
+	for (int i = 0; i < count; i++)
+	{
+		EntityType* t = StaticRegistry<EntityType>::INSTANCE.zElement(i);
+		int id = t->getId();
+		client->zForegroundWriter()->schreibe((char*)&id, 4);
+		t->getModel().writeTo(client->zForegroundWriter());
+	}
+	foreground.unlock();
+}
+
 
 Game::Game(Framework::Text name, Framework::Text worldsDir)
 	: Thread(),
@@ -407,6 +444,7 @@ GameClient* Game::addPlayer(FCKlient* client, Framework::Text name)
 		pFile.close();
 	}
 	GameClient* gameClient = new GameClient(player, client);
+	gameClient->sendTypes();
 	clients->add(gameClient);
 	requestArea(getChunckArea(getChunkCenter((int)player->getPosition().x, (int)player->getPosition().y)));
 	while (!zDimension(player->getCurrentDimensionId()) || (isNew && !zDimension(player->getCurrentDimensionId())->zChunk(getChunkCenter((int)player->getPosition().x, (int)player->getPosition().y))))

+ 1 - 0
FactoryCraft/Game.h

@@ -47,6 +47,7 @@ public:
 	bool isOnline() const;
 	void sendResponse(NetworkResponse* zResponse);
 	Player* zEntity() const;
+	void sendTypes();
 
 private:
 	class Message

+ 45 - 45
FactoryCraft/GeneratedStructure.cpp

@@ -2,71 +2,71 @@
 #include "GenerationTemplate.h"
 
 
-GeneratedStructure::GeneratedStructure( GenerationTemplate* t, Framework::Vec3<int> originPos, Framework::Vec3<int> size, Framework::Vec3<int> minAffectedPos )
-    : ReferenceCounter(),
-    size( size ),
-    minAffectedPos( minAffectedPos ),
-    originPos( originPos ),
-    t( t )
+GeneratedStructure::GeneratedStructure(GenerationTemplate* t, Framework::Vec3<int> originPos, Framework::Vec3<int> size, Framework::Vec3<int> minAffectedPos)
+	: ReferenceCounter(),
+	size(size),
+	minAffectedPos(minAffectedPos),
+	originPos(originPos),
+	t(t)
 {
-    blockIds = new int[ size.x * size.y * size.z ];
-    blocks = new Block * [ size.x * size.y * size.z ];
-    memset( blockIds, 0, sizeof( int ) * size.x * size.y * size.z );
-    memset( blocks, 0, sizeof( Block* ) * size.x * size.y * size.z );
+	blockIds = new int[size.x * size.y * size.z];
+	blocks = new Block * [size.x * size.y * size.z];
+	memset(blockIds, 0, sizeof(int) * size.x * size.y * size.z);
+	memset(blocks, 0, sizeof(Block*) * size.x * size.y * size.z);
 }
 
 GeneratedStructure::~GeneratedStructure()
 {
-    for( int i = 0; i < size.x * size.y * size.z; i++ )
-    {
-        if( blocks[ i ] )
-            blocks[ i ]->release();
-    }
-    delete[] blockIds;
-    delete[] blocks;
-    t->release();
+	for (int i = 0; i < size.x * size.y * size.z; i++)
+	{
+		if (blocks[i])
+			blocks[i]->release();
+	}
+	delete[] blockIds;
+	delete[] blocks;
+	t->release();
 }
 
-void GeneratedStructure::setBlockAt( Framework::Either<Block*, int> block, Framework::Vec3<int> localPos )
+void GeneratedStructure::setBlockAt(Framework::Either<Block*, int> block, Framework::Vec3<int> localPos)
 {
-    assert( localPos.x >= 0 && localPos.y >= 0 && localPos.z >= 0 && localPos.x < size.x&& localPos.y < size.y&& localPos.z < size.z );
-    int index = ((localPos.x * size.y) + localPos.y) * size.z + localPos.z;
-    if( block.isA() )
-        blocks[ index ] = block;
-    else
-        blockIds[ index ] = block;
+	assert(localPos.x >= 0 && localPos.y >= 0 && localPos.z >= 0 && localPos.x < size.x&& localPos.y < size.y&& localPos.z < size.z);
+	int index = ((localPos.x * size.y) + localPos.y) * size.z + localPos.z;
+	if (block.isA())
+		blocks[index] = block;
+	else
+		blockIds[index] = block;
 }
 
-bool GeneratedStructure::isBlockAffected( Framework::Vec3<int> location ) const
+bool GeneratedStructure::isBlockAffected(Framework::Vec3<int> location) const
 {
-    Framework::Vec3<int> localPos = location - minAffectedPos;
-    if( localPos.x >= 0 && localPos.y >= 0 && localPos.z >= 0 && localPos.x < size.x && localPos.y < size.y && localPos.z < size.z )
-    {
-        int index = ((localPos.x * size.y) + localPos.y) * size.z + localPos.z;
-        return blocks[ index ] || blockIds[ index ];
-    }
-    return 0;
+	Framework::Vec3<int> localPos = location - minAffectedPos;
+	if (localPos.x >= 0 && localPos.y >= 0 && localPos.z >= 0 && localPos.x < size.x && localPos.y < size.y && localPos.z < size.z)
+	{
+		int index = ((localPos.x * size.y) + localPos.y) * size.z + localPos.z;
+		return blocks[index] || blockIds[index];
+	}
+	return 0;
 }
 
-Framework::Either<Block*, int> GeneratedStructure::generateBlockAt( Framework::Vec3<int> location ) const
+Framework::Either<Block*, int> GeneratedStructure::generateBlockAt(Framework::Vec3<int> location) const
 {
-    Framework::Vec3<int> localPos = location - minAffectedPos;
-    if( localPos.x >= 0 && localPos.y >= 0 && localPos.z >= 0 && localPos.x < size.x && localPos.y < size.y && localPos.z < size.z )
-    {
-        int index = ((localPos.x * size.y) + localPos.y) * size.z + localPos.z;
-        if( blocks[ index ] )
-            return blocks[ index ];
-        return blockIds[ index ];
-    }
-    return 0;
+	Framework::Vec3<int> localPos = location - minAffectedPos;
+	if (localPos.x >= 0 && localPos.y >= 0 && localPos.z >= 0 && localPos.x < size.x && localPos.y < size.y && localPos.z < size.z)
+	{
+		int index = ((localPos.x * size.y) + localPos.y) * size.z + localPos.z;
+		if (blocks[index])
+			return blocks[index];
+		return blockIds[index];
+	}
+	return 0;
 }
 
 Framework::Vec3<int> GeneratedStructure::getOriginPos() const
 {
-    return originPos;
+	return originPos;
 }
 
 GenerationTemplate* GeneratedStructure::zTemplate() const
 {
-    return t;
+	return t;
 }

+ 13 - 13
FactoryCraft/GeneratedStructure.h

@@ -11,20 +11,20 @@ class GenerationTemplate;
 class GeneratedStructure : public Framework::ReferenceCounter
 {
 private:
-    int* blockIds;
-    Block** blocks;
-    Framework::Vec3<int> size;
-    Framework::Vec3<int> minAffectedPos;
-    Framework::Vec3<int> originPos;
-    GenerationTemplate* t;
+	int* blockIds;
+	Block** blocks;
+	Framework::Vec3<int> size;
+	Framework::Vec3<int> minAffectedPos;
+	Framework::Vec3<int> originPos;
+	GenerationTemplate* t;
 
 public:
-    GeneratedStructure( GenerationTemplate* t, Framework::Vec3<int> originPos, Framework::Vec3<int> size, Framework::Vec3<int> minAffectedPos );
-    ~GeneratedStructure();
-    void setBlockAt( Framework::Either<Block*, int> block, Framework::Vec3<int> localPos );
-    bool isBlockAffected( Framework::Vec3<int> location ) const;
-    Framework::Either<Block*, int> generateBlockAt( Framework::Vec3<int> location ) const;
+	GeneratedStructure(GenerationTemplate* t, Framework::Vec3<int> originPos, Framework::Vec3<int> size, Framework::Vec3<int> minAffectedPos);
+	~GeneratedStructure();
+	void setBlockAt(Framework::Either<Block*, int> block, Framework::Vec3<int> localPos);
+	bool isBlockAffected(Framework::Vec3<int> location) const;
+	Framework::Either<Block*, int> generateBlockAt(Framework::Vec3<int> location) const;
 
-    Framework::Vec3<int> getOriginPos() const;
-    GenerationTemplate* zTemplate() const;
+	Framework::Vec3<int> getOriginPos() const;
+	GenerationTemplate* zTemplate() const;
 };

+ 15 - 15
FactoryCraft/GenerationTemplate.cpp

@@ -1,37 +1,37 @@
 #include "GenerationTemplate.h"
 
 
-GenerationTemplate::GenerationTemplate( float propability, int minSurfaceDist, int maxSurfaceDist, Framework::Vec3<int> minPosOffset, Framework::Vec3<int> maxSize )
-    : ReferenceCounter(),
-    propability( propability ),
-    minSurfaceDist( minSurfaceDist ),
-    maxSurfaceDist( maxSurfaceDist ),
-    minPosOffset( minPosOffset ),
-    maxSize( maxSize )
+GenerationTemplate::GenerationTemplate(float propability, int minSurfaceDist, int maxSurfaceDist, Framework::Vec3<int> minPosOffset, Framework::Vec3<int> maxSize)
+	: ReferenceCounter(),
+	propability(propability),
+	minSurfaceDist(minSurfaceDist),
+	maxSurfaceDist(maxSurfaceDist),
+	minPosOffset(minPosOffset),
+	maxSize(maxSize)
 {}
 
-bool GenerationTemplate::canEffect( Framework::Vec3<int> location, Framework::Vec3<int> affectedLocation ) const
+bool GenerationTemplate::canEffect(Framework::Vec3<int> location, Framework::Vec3<int> affectedLocation) const
 {
-    Framework::Vec3<int> localPos = affectedLocation - (location + minPosOffset);
-    return localPos.x >= 0 && localPos.y >= 0 && localPos.z >= 0 && localPos.x < maxSize.x&& localPos.y < maxSize.y&& localPos.z < maxSize.z;
+	Framework::Vec3<int> localPos = affectedLocation - (location + minPosOffset);
+	return localPos.x >= 0 && localPos.y >= 0 && localPos.z >= 0 && localPos.x < maxSize.x&& localPos.y < maxSize.y&& localPos.z < maxSize.z;
 }
 
-bool GenerationTemplate::isGenerationPossable( Framework::Vec3<int> location, int distToSurface ) const
+bool GenerationTemplate::isGenerationPossable(Framework::Vec3<int> location, int distToSurface) const
 {
-    return distToSurface >= minSurfaceDist && distToSurface <= maxSurfaceDist;
+	return distToSurface >= minSurfaceDist && distToSurface <= maxSurfaceDist;
 }
 
 float GenerationTemplate::getPropability() const
 {
-    return propability;
+	return propability;
 }
 
 Framework::Vec3<int> GenerationTemplate::getMinAffectedOffset() const
 {
-    return minPosOffset;
+	return minPosOffset;
 }
 
 Framework::Vec3<int> GenerationTemplate::getMaxAffectedOffset() const
 {
-    return minPosOffset + maxSize;
+	return minPosOffset + maxSize;
 }

+ 12 - 12
FactoryCraft/GenerationTemplate.h

@@ -9,20 +9,20 @@
 class GenerationTemplate : public Framework::ReferenceCounter
 {
 private:
-    float propability;
-    int minSurfaceDist;
-    int maxSurfaceDist;
-    Framework::Vec3<int> minPosOffset;
-    Framework::Vec3<int> maxSize;
+	float propability;
+	int minSurfaceDist;
+	int maxSurfaceDist;
+	Framework::Vec3<int> minPosOffset;
+	Framework::Vec3<int> maxSize;
 
 public:
-    GenerationTemplate( float propability, int minSurfaceDist, int maxSurfaceDist, Framework::Vec3<int> minPosOffset, Framework::Vec3<int> maxSize );
+	GenerationTemplate(float propability, int minSurfaceDist, int maxSurfaceDist, Framework::Vec3<int> minPosOffset, Framework::Vec3<int> maxSize);
 
-    virtual bool canEffect( Framework::Vec3<int> location, Framework::Vec3<int> affectedLocation ) const;
-    virtual bool isGenerationPossable( Framework::Vec3<int> location, int distToSurface ) const;
-    virtual GeneratedStructure* generateAt( Framework::Vec3<int> location, Noise* zNoise ) = 0;
+	virtual bool canEffect(Framework::Vec3<int> location, Framework::Vec3<int> affectedLocation) const;
+	virtual bool isGenerationPossable(Framework::Vec3<int> location, int distToSurface) const;
+	virtual GeneratedStructure* generateAt(Framework::Vec3<int> location, Noise* zNoise) = 0;
 
-    float getPropability() const;
-    Framework::Vec3<int> getMinAffectedOffset() const;
-    Framework::Vec3<int> getMaxAffectedOffset() const;
+	float getPropability() const;
+	Framework::Vec3<int> getMinAffectedOffset() const;
+	Framework::Vec3<int> getMaxAffectedOffset() const;
 };

+ 20 - 20
FactoryCraft/GrasslandBiom.cpp

@@ -7,38 +7,38 @@
 
 
 GrasslandBiom::GrasslandBiom()
-    : BiomGenerator()
+	: BiomGenerator()
 {
-    addTemplateGenerator( new TreeTemplate( 0.02f, BirchBlockType::INSTANCE, LeavesBlockType::INSTANCE, 8, 15 ) );
-    addTemplateGenerator( new TreeTemplate( 0.01f, BeechBlockType::INSTANCE, LeavesBlockType::INSTANCE, 8, 13 ) );
-    addTemplateGenerator( new TreeTemplate( 0.005f, OakBlockType::INSTANCE, LeavesBlockType::INSTANCE, 10, 15 ) );
-    heightNoise = 0;
+	addTemplateGenerator(new TreeTemplate(0.02f, BirchBlockType::INSTANCE, LeavesBlockType::INSTANCE, 8, 15));
+	addTemplateGenerator(new TreeTemplate(0.01f, BeechBlockType::INSTANCE, LeavesBlockType::INSTANCE, 8, 13));
+	addTemplateGenerator(new TreeTemplate(0.005f, OakBlockType::INSTANCE, LeavesBlockType::INSTANCE, 10, 15));
+	heightNoise = 0;
 }
 
 GrasslandBiom::~GrasslandBiom()
 {
-    if( heightNoise )
-        heightNoise->release();
+	if (heightNoise)
+		heightNoise->release();
 }
 
-Framework::Either<Block*, int> GrasslandBiom::generateSurfaceBlock( int x, int y, int z )
+Framework::Either<Block*, int> GrasslandBiom::generateSurfaceBlock(int x, int y, int z)
 {
-    return DirtBlockType::ID;
+	return DirtBlockType::ID;
 }
 
-Framework::Either<Block*, int> GrasslandBiom::generateBelowSurfaceBlock( int x, int y, int z )
+Framework::Either<Block*, int> GrasslandBiom::generateBelowSurfaceBlock(int x, int y, int z)
 {
-    return StoneBlockType::ID;
+	return StoneBlockType::ID;
 }
 
-Noise* GrasslandBiom::zHeightMapNoise( int seed )
+Noise* GrasslandBiom::zHeightMapNoise(int seed)
 {
-    if( heightNoise )
-        return heightNoise;
-    FastNoiseLite* noise = new FastNoiseLite( seed );
-    noise->SetNoiseType( FastNoiseLite::NoiseType::NoiseType_ValueCubic );
-    FastNoiseWrapper* wrapper = new FastNoiseWrapper( noise, seed );
-    wrapper->setMultiplier( 0.2f );
-    heightNoise = wrapper;
-    return heightNoise;
+	if (heightNoise)
+		return heightNoise;
+	FastNoiseLite* noise = new FastNoiseLite(seed);
+	noise->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_ValueCubic);
+	FastNoiseWrapper* wrapper = new FastNoiseWrapper(noise, seed);
+	wrapper->setMultiplier(0.2f);
+	heightNoise = wrapper;
+	return heightNoise;
 }

+ 6 - 6
FactoryCraft/GrasslandBiom.h

@@ -5,12 +5,12 @@
 
 class GrasslandBiom : public BiomGenerator
 {
-    Noise* heightNoise;
+	Noise* heightNoise;
 
 public:
-    GrasslandBiom();
-    ~GrasslandBiom();
-    Framework::Either<Block*, int> generateSurfaceBlock( int x, int y, int z ) override;
-    Framework::Either<Block*, int> generateBelowSurfaceBlock( int x, int y, int z ) override;
-    Noise* zHeightMapNoise( int seed ) override;
+	GrasslandBiom();
+	~GrasslandBiom();
+	Framework::Either<Block*, int> generateSurfaceBlock(int x, int y, int z) override;
+	Framework::Either<Block*, int> generateBelowSurfaceBlock(int x, int y, int z) override;
+	Noise* zHeightMapNoise(int seed) override;
 };

+ 1 - 0
FactoryCraft/Inventory.h

@@ -51,6 +51,7 @@ protected:
 	virtual void afterPushStack(ItemSlot* zSlot, Direction dir, const Item* zItem, int count);
 	virtual void loadInventory(Framework::StreamReader* zReader);
 	virtual void saveInventory(Framework::StreamWriter* zWriter);
+	ItemSlot* zSlot(int id);
 
 public:
 	Inventory(const Framework::Vec3<float> location, bool hasInventory);

+ 47 - 47
FactoryCraft/Item.cpp

@@ -1,21 +1,21 @@
 #include "Item.h"
 
 
-Item::Item( const ItemType* zType, const char* name )
-    : ReferenceCounter(),
-    zType( zType ),
-    zBlockType( 0 ),
-    damage( 0 ),
-    maxDamage( 0 ),
-    durability( 0 ),
-    maxDurability( 0 ),
-    eatable( 0 ),
-    placeable( 0 ),
-    equippable( 0 ),
-    solid( 1 ),
-    usable( 0 ),
-    maxStackSize( 50 ),
-    name( name )
+Item::Item(const ItemType* zType, const char* name)
+	: ReferenceCounter(),
+	zType(zType),
+	zBlockType(0),
+	damage(0),
+	maxDamage(0),
+	durability(0),
+	maxDurability(0),
+	eatable(0),
+	placeable(0),
+	equippable(0),
+	solid(1),
+	usable(0),
+	maxStackSize(50),
+	name(name)
 {}
 
 void Item::tick()
@@ -23,97 +23,97 @@ void Item::tick()
 
 const ItemType* Item::zItemType() const
 {
-    return zType;
+	return zType;
 }
 
 const BlockType* Item::zPlacedBlockType() const
 {
-    return zBlockType;
+	return zBlockType;
 }
 
 float Item::getDamage() const
 {
-    return damage;
+	return damage;
 }
 
 float Item::getDurability() const
 {
-    return durability;
+	return durability;
 }
 
 bool Item::isUsable() const
 {
-    return usable;
+	return usable;
 }
 
 bool Item::isEatable() const
 {
-    return eatable;
+	return eatable;
 }
 
 bool Item::isPlaceable() const
 {
-    return placeable;
+	return placeable;
 }
 
 bool Item::isEquippable() const
 {
-    return equippable;
+	return equippable;
 }
 
 bool Item::isSolid() const
 {
-    return solid;
+	return solid;
 }
 
 float Item::getMaxDurability() const
 {
-    return maxDurability;
+	return maxDurability;
 }
 
 int Item::getMaxStackSize() const
 {
-    return maxStackSize;
+	return maxStackSize;
 }
 
 float Item::getMaxDamage() const
 {
-    return maxDamage;
+	return maxDamage;
 }
 
-bool Item::canBeStackedWith( Item* zItem ) const
+bool Item::canBeStackedWith(Item* zItem) const
 {
-    return zType == zItem->zType && damage == 0 &&
-        zItem->damage == 0 &&
-        durability == maxDurability &&
-        zItem->durability == zItem->maxDurability &&
-        maxDamage == zItem->maxDamage &&
-        eatable == zItem->eatable &&
-        placeable == zItem->placeable &&
-        equippable == zItem->eatable &&
-        solid == zItem->solid &&
-        usable == zItem->usable &&
-        maxStackSize == zItem->maxStackSize &&
-        name.istGleich( zItem->name );
+	return zType == zItem->zType && damage == 0 &&
+		zItem->damage == 0 &&
+		durability == maxDurability &&
+		zItem->durability == zItem->maxDurability &&
+		maxDamage == zItem->maxDamage &&
+		eatable == zItem->eatable &&
+		placeable == zItem->placeable &&
+		equippable == zItem->eatable &&
+		solid == zItem->solid &&
+		usable == zItem->usable &&
+		maxStackSize == zItem->maxStackSize &&
+		name.istGleich(zItem->name);
 }
 
 void Item::onPlaced()
 {
-    damage = maxDamage;
-    durability = 0;
+	damage = maxDamage;
+	durability = 0;
 }
 
-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)
 {}

+ 14 - 7
FactoryCraft/ItemEntity.cpp

@@ -1,6 +1,5 @@
 #include "ItemEntity.h"
 #include "Game.h"
-#include "EntityChangedUpdate.h"
 
 
 ItemEntity::ItemEntity(Framework::Vec3<float> location, int dimensionId, int entityId)
@@ -59,23 +58,31 @@ void ItemEntity::tick(const Dimension* zDimension)
 	Entity::tick(zDimension);
 }
 
-void ItemEntity::api(Framework::StreamReader* zRequest, NetworkResponse* zResponse)
+void ItemEntity::onFall(float collisionSpeed)
 {
+	if (collisionSpeed >= 50.f)
+		this->currentHP = 0;
+}
 
+bool ItemEntity::hasDefaultModel() const
+{
+	return 0;
 }
 
-void ItemEntity::onFall(float collisionSpeed)
+ModelInfo ItemEntity::getSpecialModel() const
 {
-	if (collisionSpeed >= 50.f)
-		this->currentHP = 0;
+	const ItemType* zItemType = 0;
+	if (!slot->isEmpty())
+		zItemType = slot->zStack()->zItem()->zItemType();
+	return !zItemType ? ModelInfo("", "", 0) : zItemType->getModel();
 }
 
 
 ItemEntityType::ItemEntityType()
-	: EntityType(ID)
+	: EntityType(ID, ModelInfo("", "", 0))
 {}
 
 Entity* ItemEntityType::createEntity(Framework::Vec3<float> position, int dimensionId, int entityId) const
 {
 	return new ItemEntity(position, dimensionId, entityId);
-}
+}

+ 2 - 1
FactoryCraft/ItemEntity.h

@@ -15,8 +15,9 @@ private:
 public:
 	void tick(const Dimension* zDimension) override;
 
-	void api(Framework::StreamReader* zRequest, NetworkResponse* zResponse) override;
 	void onFall(float collisionSpeed) override;
+	bool hasDefaultModel() const override;
+	ModelInfo getSpecialModel() const override;
 
 	friend ItemEntityType;
 };

+ 16 - 16
FactoryCraft/ItemFilter.cpp

@@ -4,39 +4,39 @@
 
 
 ItemFilter::ItemFilter()
-    : ReferenceCounter()
+	: ReferenceCounter()
 {}
 
 
-CombinedItemFilter::CombinedItemFilter( ItemFilter* filterA, ItemFilter* filterB, std::function<bool( bool, bool )> op )
-    : ItemFilter(),
-    filterA( filterA ),
-    filterB( filterB ),
-    op( 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 ) );
+	return op(filterA->matchItem(zItem), filterB->matchItem(zItem));
 }
 
 
 AnyItemFilter::AnyItemFilter()
-    : ItemFilter()
+	: ItemFilter()
 {}
 
-bool AnyItemFilter::matchItem( const Item* zItem ) const
+bool AnyItemFilter::matchItem(const Item* zItem) const
 {
-    return true;
+	return true;
 }
 
 
-TypeItemFilter::TypeItemFilter( const ItemType* zType )
-    : ItemFilter(),
-    zType( 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;
+	return zItem->zItemType() == zType;
 }

+ 12 - 12
FactoryCraft/ItemFilter.h

@@ -9,36 +9,36 @@ class ItemType;
 class ItemFilter : public virtual Framework::ReferenceCounter
 {
 public:
-    ItemFilter();
-    virtual bool matchItem( const Item* zItem ) const = 0;
+	ItemFilter();
+	virtual bool matchItem(const Item* zItem) const = 0;
 };
 
 class CombinedItemFilter : public ItemFilter
 {
 private:
-    ItemFilter* filterA;
-    ItemFilter* filterB;
-    std::function<bool( bool, bool )> op;
+	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;
+	AnyItemFilter();
+	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;
 };
 

+ 16 - 16
FactoryCraft/ItemSkill.cpp

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

+ 18 - 18
FactoryCraft/ItemSkill.h

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

+ 40 - 40
FactoryCraft/ItemStack.cpp

@@ -2,81 +2,81 @@
 #include "Item.h"
 
 
-ItemStack::ItemStack( Item* item, int currentSize, int maxSize )
-    : ReferenceCounter(),
-    item( item ),
-    size( currentSize ),
-    maxSize( maxSize )
+ItemStack::ItemStack(Item* item, int currentSize, int maxSize)
+	: ReferenceCounter(),
+	item(item),
+	size(currentSize),
+	maxSize(maxSize)
 {}
 
-ItemStack::ItemStack( Item* item, int currentSize )
-    : ItemStack( item, currentSize, item->getMaxStackSize() )
+ItemStack::ItemStack(Item* item, int currentSize)
+	: ItemStack(item, currentSize, item->getMaxStackSize())
 {}
 
 ItemStack::~ItemStack()
 {
-    if( item )
-        item->release();
+	if (item)
+		item->release();
 }
 
-void ItemStack::setMaxSize( int size )
+void ItemStack::setMaxSize(int size)
 {
-    maxSize = 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() );
+	size = MIN(size, this->size);
+	this->size -= size;
+	return new ItemStack(dynamic_cast<Item*>(item->getThis()), size, item->getMaxStackSize());
 }
 
 Item* ItemStack::extractFromStack()
 {
-    if( size == 0 )
-        return 0;
-    --size;
-    return item->zItemType()->cloneItem( item );
+	if (size == 0)
+		return 0;
+	--size;
+	return item->zItemType()->cloneItem(item);
 }
 
-bool ItemStack::addToStack( Item* item )
+bool ItemStack::addToStack(Item* item)
 {
-    if( size < maxSize && this->item->canBeStackedWith( item ) )
-    {
-        ++size;
-        item->release();
-        return true;
-    }
-    item->release();
-    return false;
+	if (size < maxSize && this->item->canBeStackedWith(item))
+	{
+		++size;
+		item->release();
+		return true;
+	}
+	item->release();
+	return false;
 }
 
-void ItemStack::addItemStack( ItemStack* zItemStack )
+void ItemStack::addItemStack(ItemStack* zItemStack)
 {
-    if( zItemStack->zItem()->canBeStackedWith( item ) )
-    {
-        int numToAdd = MIN( zItemStack->getSize(), maxSize - size );
-        size += numToAdd;
-        zItemStack->size -= numToAdd;
-    }
+	if (zItemStack->zItem()->canBeStackedWith(item))
+	{
+		int numToAdd = MIN(zItemStack->getSize(), maxSize - size);
+		size += numToAdd;
+		zItemStack->size -= numToAdd;
+	}
 }
 
-bool ItemStack::isStackable( Item* zItem ) const
+bool ItemStack::isStackable(Item* zItem) const
 {
-    return item->canBeStackedWith( zItem );
+	return item->canBeStackedWith(zItem);
 }
 
 const Item* ItemStack::zItem() const
 {
-    return item;
+	return item;
 }
 
 int ItemStack::getSize() const
 {
-    return size;
+	return size;
 }
 
 int ItemStack::getMaxSize() const
 {
-    return maxSize;
+	return maxSize;
 }

+ 15 - 15
FactoryCraft/ItemStack.h

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

+ 8 - 2
FactoryCraft/ItemType.cpp

@@ -5,12 +5,13 @@
 #include "ItemSkill.h"
 #include "ItemStack.h"
 
-ItemType::ItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType)
+ItemType::ItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType, ModelInfo model)
 	: ReferenceCounter(),
 	id(id),
 	name(name),
 	levelUpRule(levelUpRule),
-	zBrokenType(zBrokenType)
+	zBrokenType(zBrokenType),
+	model(model)
 {
 	StaticRegistry<ItemType>::INSTANCE.registerT(this, id);
 }
@@ -149,4 +150,9 @@ void ItemType::saveItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* z
 Item* ItemType::breakItem(Item* zItem) const
 {
 	return 0;
+}
+
+const ModelInfo& ItemType::getModel() const
+{
+	return model;
 }

+ 4 - 1
FactoryCraft/ItemType.h

@@ -7,6 +7,7 @@
 
 #include "Effect.h"
 #include "StaticRegistry.h"
+#include "ModelInfo.h"
 
 class Item;
 class ItemStack;
@@ -20,8 +21,9 @@ protected:
 	const Framework::Text name;
 	ItemSkillLevelUpRule* levelUpRule;
 	const ItemType* zBrokenType;
+	const ModelInfo model;
 
-	ItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType);
+	ItemType(int id, const char* name, ItemSkillLevelUpRule* levelUpRule, const ItemType* zBrokenType, ModelInfo model);
 
 	virtual void loadSuperItem(Item* zItem, Framework::StreamReader* zReader) const;
 	virtual void saveSuperItem(const Item* zItem, Framework::StreamWriter* zWriter) const;
@@ -45,4 +47,5 @@ public:
 	virtual void saveItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const;
 	virtual Item* cloneItem(Item* zItem) const;
 	virtual Item* breakItem(Item* zItem) const;
+	const ModelInfo& getModel() const;
 };

+ 32 - 0
FactoryCraft/ModelInfo.cpp

@@ -0,0 +1,32 @@
+#include "ModelInfo.h"
+
+using namespace Framework;
+
+ModelInfo::ModelInfo(const char* modelPath, const char* texturPath, int textureCount)
+	: modelPath(modelPath)
+{
+	for (int i = 0; i < textureCount; i++)
+		texturePaths.add(new Text(texturPath));
+}
+
+ModelInfo::ModelInfo(const char* modelPath, std::initializer_list<const char*> texturePaths)
+	: modelPath(modelPath)
+{
+	for (const char* texturPath : texturePaths)
+		this->texturePaths.add(new Text(texturPath));
+}
+
+void ModelInfo::writeTo(Framework::StreamWriter* zWriter) const
+{
+	char len = (char)modelPath.getLength();
+	zWriter->schreibe(&len, 1);
+	zWriter->schreibe(modelPath.getText(), (int)len);
+	short count = (short)texturePaths.getEintragAnzahl();
+	zWriter->schreibe((char*)&count, 2);
+	for (Text* t : texturePaths)
+	{
+		len = (char)t->getLength();
+		zWriter->schreibe(&len, 1);
+		zWriter->schreibe(t->getText(), (int)len);
+	}
+}

+ 18 - 0
FactoryCraft/ModelInfo.h

@@ -0,0 +1,18 @@
+#pragma once
+
+#include <Text.h>
+#include <Array.h>
+#include <Writer.h>
+
+
+class ModelInfo
+{
+private:
+	const Framework::Text modelPath;
+	Framework::RCArray<Framework::Text> texturePaths;
+
+public:
+	ModelInfo(const char* modelPath, const char* texturPath, int textureCount);
+	ModelInfo(const char* modelPath, std::initializer_list<const char*> texturePaths);
+	void writeTo(Framework::StreamWriter* zWriter) const;
+};

+ 18 - 17
FactoryCraft/NetworkResponse.cpp

@@ -12,6 +12,7 @@ NetworkResponse::NetworkResponse()
 	msgDelete = 0;
 	msgLength = 0;
 	useBackground = 0;
+	affectedDimension = -1;
 }
 
 NetworkResponse::~NetworkResponse()
@@ -23,43 +24,43 @@ NetworkResponse::~NetworkResponse()
 
 void NetworkResponse::adressChunck(Chunk* zChunk)
 {
-	adressLength = 14;
+	adressLength = 10;
 	adress = new char[adressLength];
 	adress[0] = 1; // dimension response
-	*(int*)(adress + 1) = zChunk->getDimensionId();
-	adress[5] = 1; // chunck
+	adress[1] = 1; // chunck
 	Framework::Punkt center = zChunk->getCenter();
-	*(int*)(adress + 6) = center.x;
-	*(int*)(adress + 10) = center.y;
+	*(int*)(adress + 2) = center.x;
+	*(int*)(adress + 6) = center.y;
 	minPosition = zChunk->getMin();
 	maxPosition = zChunk->getMax();
+	affectedDimension = zChunk->getDimensionId();
 }
 
 void NetworkResponse::adressEntity(Entity* zEntity)
 {
-	adressLength = 10;
+	adressLength = 6;
 	adress = new char[adressLength];
 	adress[0] = 1; // dimension response
-	*(int*)(adress + 1) = zEntity->getCurrentDimensionId();
-	adress[5] = 2; // entity
-	*(int*)(adress + 6) = zEntity->getId();
+	adress[1] = 2; // entity
+	*(int*)(adress + 2) = zEntity->getId();
 	minPosition = zEntity->getPosition();
 	maxPosition = zEntity->getPosition();
+	affectedDimension = zEntity->getCurrentDimensionId();
 }
 
 void NetworkResponse::adressBlock(Block* zBlock)
 {
-	adressLength = 18;
+	adressLength = 14;
 	adress = new char[adressLength];
 	adress[0] = 1; // dimension response
-	*(int*)(adress + 1) = zBlock->getDimensionId();
-	adress[5] = 3; // block
+	adress[1] = 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 + 2) = pos.x;
+	*(int*)(adress + 6) = pos.y;
+	*(int*)(adress + 10) = pos.z;
 	minPosition = pos;
 	maxPosition = pos;
+	affectedDimension = zBlock->getDimensionId();
 }
 
 void NetworkResponse::openDialog(Framework::Text dialogName)
@@ -111,11 +112,11 @@ void NetworkResponse::sendToAll()
 	broadcast = true;
 }
 
-bool NetworkResponse::isAreaAffected(Framework::Vec3<float> min, Framework::Vec3<float> max) const
+bool NetworkResponse::isAreaAffected(Framework::Vec3<float> min, Framework::Vec3<float> max, int affectedDimension) const
 {
 	return minPosition.x <= max.x && maxPosition.x >= min.x &&
 		minPosition.y <= max.y && maxPosition.y >= min.y &&
-		minPosition.z <= max.z && maxPosition.z >= min.z;
+		minPosition.z <= max.z && maxPosition.z >= min.z && (this->affectedDimension < 0 || this->affectedDimension == affectedDimension);
 }
 
 void NetworkResponse::writeTo(Framework::StreamWriter* zWriter) const

+ 2 - 1
FactoryCraft/NetworkResponse.h

@@ -19,6 +19,7 @@ private:
 	bool msgDelete;
 	int msgLength;
 	bool useBackground;
+	int affectedDimension;
 
 public:
 	NetworkResponse();
@@ -33,7 +34,7 @@ public:
 	void setUseBackground();
 	void sendToAll();
 
-	bool isAreaAffected(Framework::Vec3<float> min, Framework::Vec3<float> max) const;
+	bool isAreaAffected(Framework::Vec3<float> min, Framework::Vec3<float> max, int dimensionId) const;
 	void writeTo(Framework::StreamWriter* zWriter) const;
 	bool isBroadcast() const;
 	bool isEmpty() const;

+ 32 - 32
FactoryCraft/NoBlock.cpp

@@ -1,18 +1,18 @@
 #include "NoBlock.h"
 
 NoBlock::NoBlock()
-    : Block( NoBlockBlockType::INSTANCE, 0, { 0,0,0 }, false )
+	: Block(NoBlockBlockType::INSTANCE, 0, { 0,0,0 }, false)
 {
-    transparent = 0;
-    passable = 0;
-    hp = 0;
-    maxHP = 0;
-    hardness = 0;
+	transparent = 0;
+	passable = 0;
+	hp = 0;
+	maxHP = 0;
+	hardness = 0;
 }
 
-bool NoBlock::onTick( TickQueue* zQueue, int numTicks, bool& blocked )
+bool NoBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
 {
-    return 0;
+	return 0;
 }
 
 void NoBlock::onPostTick() {}
@@ -21,59 +21,59 @@ const NoBlock NoBlock::INSTANCE;
 
 
 NoBlockBlockType::NoBlockBlockType()
-    : BlockType( ID, 0 )
+	: BlockType(ID, 0, ModelInfo("", "", 0), 0, 1)
 {}
 
-NoBlockBlockType::NoBlockBlockType( int id )
-    : BlockType( id, 0 )
+NoBlockBlockType::NoBlockBlockType(int id)
+	: BlockType(id, 0, ModelInfo("", "", 0), 0, 1)
 {}
 
-Block* NoBlockBlockType::createBlock( Framework::Vec3<int> position ) const
+Block* NoBlockBlockType::createBlock(Framework::Vec3<int> position) const
 {
-    return 0;
+	return 0;
 }
 
 Item* NoBlockBlockType::createItem() const
 {
-    return 0;
+	return 0;
 }
 
-Block* NoBlockBlockType::loadBlock( Framework::Vec3<int> position, Framework::StreamReader* zReader ) const
+Block* NoBlockBlockType::loadBlock(Framework::Vec3<int> position, Framework::StreamReader* zReader) const
 {
-    return 0;
+	return 0;
 }
 
-void NoBlockBlockType::saveBlock( Block* zBlock, Framework::StreamWriter* zWriter ) const
+void NoBlockBlockType::saveBlock(Block* zBlock, Framework::StreamWriter* zWriter) const
 {}
 
-Item* NoBlockBlockType::getItemFromBlock( Block* zBlock ) const
+Item* NoBlockBlockType::getItemFromBlock(Block* zBlock) const
 {
-    return 0;
+	return 0;
 }
 
-Block* NoBlockBlockType::createBlockAt( Framework::Vec3<int> position, Item* zUsedItem ) const
+Block* NoBlockBlockType::createBlockAt(Framework::Vec3<int> position, Item* zUsedItem) const
 {
-    return 0;
+	return 0;
 }
 
 const Block* NoBlockBlockType::zDefault() const
 {
-    return &NoBlock::INSTANCE;
+	return &NoBlock::INSTANCE;
 }
 
 AirBlock::AirBlock()
-    : Block( AirBlockBlockType::INSTANCE, 0, { 0,0,0 }, false )
+	: Block(AirBlockBlockType::INSTANCE, 0, { 0,0,0 }, false)
 {
-    transparent = 1;
-    passable = 1;
-    hp = 0;
-    maxHP = 0;
-    hardness = 0;
+	transparent = 1;
+	passable = 1;
+	hp = 0;
+	maxHP = 0;
+	hardness = 0;
 }
 
-bool AirBlock::onTick( TickQueue* zQueue, int numTicks, bool& blocked )
+bool AirBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
 {
-    return 0;
+	return 0;
 }
 
 void AirBlock::onPostTick()
@@ -83,10 +83,10 @@ const AirBlock AirBlock::INSTANCE;
 
 
 AirBlockBlockType::AirBlockBlockType()
-    : NoBlockBlockType( ID )
+	: NoBlockBlockType(ID)
 {}
 
 const Block* AirBlockBlockType::zDefault() const
 {
-    return &AirBlock::INSTANCE;
+	return &AirBlock::INSTANCE;
 }

+ 23 - 23
FactoryCraft/NoBlock.h

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

+ 3 - 3
FactoryCraft/Noise.cpp

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

+ 11 - 11
FactoryCraft/Noise.h

@@ -6,15 +6,15 @@
 class Noise : public virtual Framework::ReferenceCounter
 {
 public:
-    Noise();
-    virtual int getSeed() const = 0;
-    /// <summary>
-    /// get the noise value at a certain destination
-    /// </summary>
-    /// <param name="x">the x coord of the noice value</param>
-    /// <param name="y">the y coord of the noice value</param>
-    /// <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 ) = 0;
-    double getNoise( Framework::Vec3<double>& pos );
+	Noise();
+	virtual int getSeed() const = 0;
+	/// <summary>
+	/// get the noise value at a certain destination
+	/// </summary>
+	/// <param name="x">the x coord of the noice value</param>
+	/// <param name="y">the y coord of the noice value</param>
+	/// <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) = 0;
+	double getNoise(Framework::Vec3<double>& pos);
 };

+ 28 - 28
FactoryCraft/NoiseInterpolator.cpp

@@ -3,42 +3,42 @@
 
 using namespace Framework;
 
-NoiseInterpolator::NoiseInterpolator( int seed, std::function<Noise* (int)> noiseSupplier, int width, int height )
-    : Noise(),
-    noiseSize( width, height ),
-    cache( 10, []( int k ) {return k; }, CacheCleanupStrategy::LONGEST_NOT_USED ),
-    noiseSupplier( noiseSupplier ),
-    seed( seed )
+NoiseInterpolator::NoiseInterpolator(int seed, std::function<Noise* (int)> noiseSupplier, int width, int height)
+	: Noise(),
+	noiseSize(width, height),
+	cache(10, [](int k) { return k; }, CacheCleanupStrategy::LONGEST_NOT_USED),
+	noiseSupplier(noiseSupplier),
+	seed(seed)
 {}
 
-double NoiseInterpolator::getRealNoise( double x, double y, double z )
+double NoiseInterpolator::getRealNoise(double x, double y, double z)
 {
-    int ix = (int)ceil( x ), iy = (int)ceil( y );
-    int xOff = ix % noiseSize.x, yOff = iy % noiseSize.y;
-    int xI = ix / noiseSize.x, yI = iy / noiseSize.y;
-    if( ix < 0 )
-        xI--;
-    if( iy < 0 )
-        yI--;
-    int key = ((xI & 0xFFFF) << 16) | (yI & 0xFFFF);
-    if( !cache.has( key ) )
-        cache.put( key, RCPointer<Noise>::of( noiseSupplier( key + seed ) ) );
-    return cache.get( key )->getNoise( (xOff + 1 - (ix - x)), (yOff + 1 - (iy - y)), z );
+	int ix = (int)ceil(x), iy = (int)ceil(y);
+	int xOff = ix % noiseSize.x, yOff = iy % noiseSize.y;
+	int xI = ix / noiseSize.x, yI = iy / noiseSize.y;
+	if (ix < 0)
+		xI--;
+	if (iy < 0)
+		yI--;
+	int key = ((xI & 0xFFFF) << 16) | (yI & 0xFFFF);
+	if (!cache.has(key))
+		cache.put(key, RCPointer<Noise>::of(noiseSupplier(key + seed)));
+	return cache.get(key)->getNoise((xOff + 1 - (ix - x)), (yOff + 1 - (iy - y)), z);
 }
 
-double NoiseInterpolator::getNoise( double x, double y, double z )
+double NoiseInterpolator::getNoise(double x, double y, double z)
 {
-    const double weights[ 6 ] = { 0.32, 0.17, 0.09, 0.05, 0.03, 0.02 };
-    double sum = 0;
-    for( int xi = -5; xi <= 5; xi++ )
-    {
-        for( int yi = -5; yi <= 5; yi++ )
-            sum += getRealNoise( x + xi, y + yi, z ) * weights[ abs( xi ) ] * weights[ abs( yi ) ];
-    }
-    return sum;
+	const double weights[6] = { 0.32, 0.17, 0.09, 0.05, 0.03, 0.02 };
+	double sum = 0;
+	for (int xi = -5; xi <= 5; xi++)
+	{
+		for (int yi = -5; yi <= 5; yi++)
+			sum += getRealNoise(x + xi, y + yi, z) * weights[abs(xi)] * weights[abs(yi)];
+	}
+	return sum;
 }
 
 int NoiseInterpolator::getSeed() const
 {
-    return seed;
+	return seed;
 }

+ 8 - 8
FactoryCraft/NoiseInterpolator.h

@@ -7,15 +7,15 @@
 
 class NoiseInterpolator : public Noise
 {
-    Framework::Punkt noiseSize;
-    Framework::Cache<int, Framework::RCPointer<Noise>> cache;
-    std::function<Noise* (int)> noiseSupplier;
-    int seed;
+	Framework::Punkt noiseSize;
+	Framework::Cache<int, Framework::RCPointer<Noise>> cache;
+	std::function<Noise* (int)> noiseSupplier;
+	int seed;
 
-    double getRealNoise( double x, double y, double z );
+	double getRealNoise(double x, double y, double z);
 
 public:
-    NoiseInterpolator( int seed, std::function<Noise* (int)> noiseSupplier, int width, int height );
-    double getNoise( double x, double y, double z ) override;
-    int getSeed() const override;
+	NoiseInterpolator(int seed, std::function<Noise* (int)> noiseSupplier, int width, int height);
+	double getNoise(double x, double y, double z) override;
+	int getSeed() const override;
 };

+ 8 - 8
FactoryCraft/OverworldDimension.h

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

+ 18 - 31
FactoryCraft/PlaceBlockUpdate.cpp

@@ -3,53 +3,40 @@
 #include "Dimension.h"
 
 
-PlaceBlockUpdate::PlaceBlockUpdate( Framework::Either<Block*, int> block, Framework::Vec3<int> location, int dimensionId )
-    : WorldUpdate( PlaceBlockUpdateType::ID, dimensionId, location, location ),
-    block( block )
+PlaceBlockUpdate::PlaceBlockUpdate(Framework::Either<Block*, int> block, Framework::Vec3<int> location, int dimensionId)
+	: WorldUpdate(PlaceBlockUpdateType::ID, dimensionId, location, location),
+	block(block)
 {}
 
 PlaceBlockUpdate::~PlaceBlockUpdate()
 {
-    if( block.isA() )
-        block.getA()->release();
+	if (block.isA())
+		block.getA()->release();
 }
 
-void PlaceBlockUpdate::onUpdate( Dimension* zDimension )
+void PlaceBlockUpdate::onUpdate(Dimension* zDimension)
 {
-    if( block.isA() )
-        block.getA()->getThis();
-    zDimension->placeBlock( getMaxAffectedPoint(), block );
+	if (block.isA())
+		block.getA()->getThis();
+	zDimension->placeBlock(getMaxAffectedPoint(), block);
 }
 
-void PlaceBlockUpdate::write( Framework::StreamWriter* zWriter )
+void PlaceBlockUpdate::write(Framework::StreamWriter* zWriter)
 {
-    int dimensionID = getAffectedDimension();
-    zWriter->schreibe( (char*)&dimensionID, 4 );
-    auto pos = getMinAffectedPoint();
-    zWriter->schreibe( (char*)&pos.x, 4 );
-    zWriter->schreibe( (char*)&pos.y, 4 );
-    zWriter->schreibe( (char*)&pos.z, 4 );
-    unsigned short blockType = block.isA() ? (unsigned short)block.getA()->zBlockType()->getId() : (unsigned short)block.getB();
-    zWriter->schreibe( (char*)&blockType, 2 );
-    if( block.isA() )
-    {
-        bool d = 1;
-        zWriter->schreibe( (char*)&d, 1 );
-        StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->saveBlock( block, zWriter );
-    }
-    else
-    {
-        bool d = 0;
-        zWriter->schreibe( (char*)&d, 1 );
-    }
+	auto pos = getMinAffectedPoint();
+	zWriter->schreibe((char*)&pos.x, 4);
+	zWriter->schreibe((char*)&pos.y, 4);
+	zWriter->schreibe((char*)&pos.z, 4);
+	unsigned short blockType = block.isA() ? (unsigned short)block.getA()->zBlockType()->getId() : (unsigned short)block.getB();
+	zWriter->schreibe((char*)&blockType, 2);
 }
 
 Block* PlaceBlockUpdate::zBlock() const
 {
-    return block;
+	return block;
 }
 
 
 PlaceBlockUpdateType::PlaceBlockUpdateType()
-    : WorldUpdateType( ID )
+	: WorldUpdateType(ID)
 {}

+ 9 - 9
FactoryCraft/PlaceBlockUpdate.h

@@ -9,24 +9,24 @@ class Block;
 class PlaceBlockUpdate : public WorldUpdate
 {
 private:
-    Framework::Either<Block*, int> block;
+	Framework::Either<Block*, int> block;
 
 protected:
-    void write( Framework::StreamWriter* zWriter ) override;
+	void write(Framework::StreamWriter* zWriter) override;
 
 public:
-    PlaceBlockUpdate( Framework::Either<Block*, int> block, Framework::Vec3<int> location, int dimensionId );
-    ~PlaceBlockUpdate();
+	PlaceBlockUpdate(Framework::Either<Block*, int> block, Framework::Vec3<int> location, int dimensionId);
+	~PlaceBlockUpdate();
 
-    void onUpdate( Dimension* zDimension ) override;
-    Block* zBlock() const;
+	void onUpdate(Dimension* zDimension) override;
+	Block* zBlock() const;
 };
 
 class PlaceBlockUpdateType : WorldUpdateType
 {
-    REGISTRABLE( PlaceBlockUpdateType )
+	REGISTRABLE(PlaceBlockUpdateType)
 
 protected:
-    PlaceBlockUpdateType();
+	PlaceBlockUpdateType();
 };
-REGISTER( PlaceBlockUpdateType, WorldUpdateType )
+REGISTER(PlaceBlockUpdateType, WorldUpdateType)

+ 3 - 3
FactoryCraft/Player.cpp

@@ -192,7 +192,7 @@ void Player::playerApi(Framework::StreamReader* zRequest, NetworkResponse* zResp
 	switch (byte)
 	{
 	case 0:
-		// begin action
+		// stop action
 		zRequest->lese(&byte, 1);
 		switch (byte)
 		{
@@ -233,7 +233,7 @@ void Player::playerApi(Framework::StreamReader* zRequest, NetworkResponse* zResp
 		}
 		break;
 	case 1:
-		// stop action
+		// begin action
 		zRequest->lese(&byte, 1);
 		switch (byte)
 		{
@@ -327,7 +327,7 @@ void Player::onFall(float collisionSpeed)
 
 
 PlayerEntityType::PlayerEntityType()
-	: EntityType(ID)
+	: EntityType(ID, ModelInfo("player", "player.ltdb/player.png", 6))
 {}
 
 void PlayerEntityType::loadSuperEntity(Entity* zEntity, Framework::StreamReader* zReader) const

+ 1 - 1
FactoryCraft/PlayerHand.cpp

@@ -3,7 +3,7 @@
 
 
 PlayerHandItemType::PlayerHandItemType()
-	: ItemType(ID, "PlayerHand", new PlayerHandLevelUpRule(), 0)
+	: ItemType(ID, "PlayerHand", new PlayerHandLevelUpRule(), 0, ModelInfo("", "", 0))
 {}
 
 void PlayerHandItemType::loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const

+ 12 - 12
FactoryCraft/PlayerHand.h

@@ -5,30 +5,30 @@
 
 class PlayerHandItemType : public ItemType
 {
-    REGISTRABLE( PlayerHandItemType )
+	REGISTRABLE(PlayerHandItemType)
 
 protected:
-    void loadSuperItemSkill( ItemSkill* zSkill, Framework::StreamReader* zReader ) const override;
-    void saveSuperItemSkill( const ItemSkill* zSkill, Framework::StreamWriter* zWriter ) const override;
+	void loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const override;
+	void saveSuperItemSkill(const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const override;
 
 public:
-    PlayerHandItemType();
-    Item* createItem() const override;
-    ItemSkill* createDefaultItemSkill() const override;
+	PlayerHandItemType();
+	Item* createItem() const override;
+	ItemSkill* createDefaultItemSkill() const override;
 };
-REGISTER( PlayerHandItemType, ItemType )
+REGISTER(PlayerHandItemType, ItemType)
 
 class PlayerHandLevelUpRule : public ItemSkillLevelUpRule
 {
 public:
-    PlayerHandLevelUpRule();
-    void applyOn( ItemSkill* zSkill ) override;
+	PlayerHandLevelUpRule();
+	void applyOn(ItemSkill* zSkill) override;
 };
 
 class PlayerHandSkill : public ItemSkill
 {
 public:
-    PlayerHandSkill();
-    void use( Entity* zActor, Item* zUsedItem, Block* zTarget ) override;
-    void use( Entity* zActor, Item* zUsedItem, Entity* zTarget ) override;
+	PlayerHandSkill();
+	void use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
+	void use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
 };

+ 17 - 17
FactoryCraft/RandNoise.cpp

@@ -7,33 +7,33 @@
 #include "FastNoiseWrapper.h"
 
 
-RandNoise::RandNoise( int seed )
-    : Noise(),
-    seed( seed )
+RandNoise::RandNoise(int seed)
+	: Noise(),
+	seed(seed)
 {
-    FastNoiseLite* n = new FastNoiseLite( seed );
-    n->SetNoiseType( FastNoiseLite::NoiseType::NoiseType_OpenSimplex2S );
-    n->SetRotationType3D( FastNoiseLite::RotationType3D::RotationType3D_None );
-    n->SetFrequency( 0.333f );
-    n->SetFractalOctaves( 1 );
-    n->SetFractalType( FastNoiseLite::FractalType::FractalType_None );
-    n->SetDomainWarpAmp( 30.f );
-    noise = new FastNoiseWrapper( n, seed );
+	FastNoiseLite* n = new FastNoiseLite(seed);
+	n->SetNoiseType(FastNoiseLite::NoiseType::NoiseType_OpenSimplex2S);
+	n->SetRotationType3D(FastNoiseLite::RotationType3D::RotationType3D_None);
+	n->SetFrequency(0.333f);
+	n->SetFractalOctaves(1);
+	n->SetFractalType(FastNoiseLite::FractalType::FractalType_None);
+	n->SetDomainWarpAmp(30.f);
+	noise = new FastNoiseWrapper(n, seed);
 }
 
 RandNoise::~RandNoise()
 {
-    delete noise;
+	delete noise;
 }
 
 int RandNoise::getSeed() const
 {
-    return seed;
+	return seed;
 }
 
-double RandNoise::getNoise( double x, double y, double z )
+double RandNoise::getNoise(double x, double y, double z)
 {
-    double n = noise->getNoise( x * 4 + y + z * 7, 7 * x + 4 * y + z, x + 7 * y + 4 * z );
-    assert( n >= 0 && n <= 1 );
-    return n;
+	double n = noise->getNoise(x * 4 + y + z * 7, 7 * x + 4 * y + z, x + 7 * y + 4 * z);
+	assert(n >= 0 && n <= 1);
+	return n;
 }

+ 6 - 6
FactoryCraft/RandNoise.h

@@ -7,13 +7,13 @@ class FastNoiseWrapper;
 class RandNoise : public Noise
 {
 private:
-    int seed;
-    FastNoiseWrapper* noise;
+	int seed;
+	FastNoiseWrapper* noise;
 
 public:
-    RandNoise( int seed );
-    ~RandNoise();
+	RandNoise(int seed);
+	~RandNoise();
 
-    int getSeed() const override;
-    double getNoise( double x, double y, double z ) override;
+	int getSeed() const override;
+	double getNoise(double x, double y, double z) override;
 };

+ 46 - 46
FactoryCraft/Recipie.cpp

@@ -1,82 +1,82 @@
 #include "Recipie.h"
 
 Recipie::Recipie()
-    : ReferenceCounter()
+	: ReferenceCounter()
 {}
 
-void Recipie::addIngredient( ItemFilter* filter, int amount )
+void Recipie::addIngredient(ItemFilter* filter, int amount)
 {
-    filters.add( filter );
-    inputAmount.add( amount );
+	filters.add(filter);
+	inputAmount.add(amount);
 }
 
-void Recipie::addOutput( Item* item, int amount )
+void Recipie::addOutput(Item* item, int amount)
 {
-    outputs.add( item );
-    outputAmount.add( amount );
+	outputs.add(item);
+	outputAmount.add(amount);
 }
 
-bool Recipie::testApplicability( CraftingStorage* zStorage )
+bool Recipie::testApplicability(CraftingStorage* zStorage)
 {
-    for( int i = 0; i < outputs.getEintragAnzahl(); i++ )
-    {
-        if( !zStorage->hasFreeSpace( outputs.z( i ), outputAmount.get( i ) ) )
-            return 0;
-    }
-    return zStorage->isAllAvailable( filters, inputAmount );
+	for (int i = 0; i < outputs.getEintragAnzahl(); i++)
+	{
+		if (!zStorage->hasFreeSpace(outputs.z(i), outputAmount.get(i)))
+			return 0;
+	}
+	return zStorage->isAllAvailable(filters, inputAmount);
 }
 
-void Recipie::apply( CraftingStorage* zStorage )
+void Recipie::apply(CraftingStorage* zStorage)
 {
-    zStorage->consume( filters, inputAmount );
-    for( int i = 0; i < outputs.getEintragAnzahl(); i++ )
-    {
-        ItemStack* stack = new ItemStack( outputs.z( i )->zItemType()->cloneItem( outputs.z( i ) ), outputAmount.get( i ) );
-        zStorage->addCraftingResult( stack );
-        stack->release();
-    }
+	zStorage->consume(filters, inputAmount);
+	for (int i = 0; i < outputs.getEintragAnzahl(); i++)
+	{
+		ItemStack* stack = new ItemStack(outputs.z(i)->zItemType()->cloneItem(outputs.z(i)), outputAmount.get(i));
+		zStorage->addCraftingResult(stack);
+		stack->release();
+	}
 }
 
 
-ShapedRecipie::ShapedRecipie( int width, int height )
-    :ReferenceCounter(),
-    width( width ),
-    height( height ),
-    output( 0 ),
-    outputAmount( 0 )
+ShapedRecipie::ShapedRecipie(int width, int height)
+	:ReferenceCounter(),
+	width(width),
+	height(height),
+	output(0),
+	outputAmount(0)
 {
-    for( int i = 0; i < width * height; i++ )
-        filters.add( 0 );
+	for (int i = 0; i < width * height; i++)
+		filters.add(0);
 }
 
 ShapedRecipie::~ShapedRecipie()
 {
-    if( output )
-        output->release();
+	if (output)
+		output->release();
 }
 
-void ShapedRecipie::setIngredient( int x, int y, ItemFilter* filter )
+void ShapedRecipie::setIngredient(int x, int y, ItemFilter* filter)
 {
-    filters.set( filter, width * x + y );
+	filters.set(filter, width * x + y);
 }
 
-void ShapedRecipie::setOutput( Item* item, int amount )
+void ShapedRecipie::setOutput(Item* item, int amount)
 {
-    if( output )
-        output->release();
-    output = item;
-    outputAmount = amount;
+	if (output)
+		output->release();
+	output = item;
+	outputAmount = amount;
 }
 
-bool ShapedRecipie::testApplicability( ShapedCraftingStorage* zStorage )
+bool ShapedRecipie::testApplicability(ShapedCraftingStorage* zStorage)
 {
-    return zStorage->isAllAvailable( filters, width, height ) && zStorage->hasFreeSpace( output, outputAmount );
+	return zStorage->isAllAvailable(filters, width, height) && zStorage->hasFreeSpace(output, outputAmount);
 }
 
-void ShapedRecipie::apply( ShapedCraftingStorage* zStorage )
+void ShapedRecipie::apply(ShapedCraftingStorage* zStorage)
 {
-    zStorage->consume( filters, width, height );
-    ItemStack* stack = new ItemStack( output->zItemType()->cloneItem( output ), outputAmount );
-    zStorage->addCraftingResult( stack );
-    stack->release();
+	zStorage->consume(filters, width, height);
+	ItemStack* stack = new ItemStack(output->zItemType()->cloneItem(output), outputAmount);
+	zStorage->addCraftingResult(stack);
+	stack->release();
 }

+ 20 - 20
FactoryCraft/Recipie.h

@@ -8,33 +8,33 @@
 class Recipie : public virtual Framework::ReferenceCounter
 {
 private:
-    Framework::RCArray<ItemFilter> filters;
-    Framework::Array<int> inputAmount;
-    Framework::RCArray<Item> outputs;
-    Framework::Array<int> outputAmount;
+	Framework::RCArray<ItemFilter> filters;
+	Framework::Array<int> inputAmount;
+	Framework::RCArray<Item> outputs;
+	Framework::Array<int> outputAmount;
 
 public:
-    Recipie();
-    void addIngredient( ItemFilter* filter, int amount );
-    void addOutput( Item* item, int amount );
-    bool testApplicability( CraftingStorage* zStorage );
-    void apply( CraftingStorage* zStorage );
+	Recipie();
+	void addIngredient(ItemFilter* filter, int amount);
+	void addOutput(Item* item, int amount);
+	bool testApplicability(CraftingStorage* zStorage);
+	void apply(CraftingStorage* zStorage);
 };
 
 class ShapedRecipie : public virtual Framework::ReferenceCounter
 {
 private:
-    Framework::RCArray<ItemFilter> filters;
-    int width;
-    int height;
-    Item* output;
-    int outputAmount;
+	Framework::RCArray<ItemFilter> filters;
+	int width;
+	int height;
+	Item* output;
+	int outputAmount;
 
 public:
-    ShapedRecipie( int width, int height );
-    ~ShapedRecipie();
-    void setIngredient( int x, int y, ItemFilter* filter );
-    void setOutput( Item* item, int amount );
-    bool testApplicability( ShapedCraftingStorage* zStorage );
-    void apply( ShapedCraftingStorage* zStorage );
+	ShapedRecipie(int width, int height);
+	~ShapedRecipie();
+	void setIngredient(int x, int y, ItemFilter* filter);
+	void setOutput(Item* item, int amount);
+	bool testApplicability(ShapedCraftingStorage* zStorage);
+	void apply(ShapedCraftingStorage* zStorage);
 };

+ 22 - 22
FactoryCraft/RecipieList.h

@@ -6,33 +6,33 @@ template <typename T, typename S>
 class RecipieListType : public virtual Framework::ReferenceCounter
 {
 private:
-    Framework::RCArray<T> recipies;
-    Framework::Text name;
+	Framework::RCArray<T> recipies;
+	Framework::Text name;
 
 public:
-    RecipieListType( const char* name )
-        : ReferenceCounter(),
-        name( name )
-    {}
+	RecipieListType(const char* name)
+		: ReferenceCounter(),
+		name(name)
+	{}
 
-    void addRecipie( T* recipie )
-    {
-        recipies.add( recipie );
-    }
+	void addRecipie(T* recipie)
+	{
+		recipies.add(recipie);
+	}
 
-    T* zFirstRecipie( S* zStorage )
-    {
-        for( T* recipie : recipies )
-        {
-            if( recipie->testApplicability( zStorage ) )
-                return recipie;
-        }
-    }
+	T* zFirstRecipie(S* zStorage)
+	{
+		for (T* recipie : recipies)
+		{
+			if (recipie->testApplicability(zStorage))
+				return recipie;
+		}
+	}
 
-    const Framework::Text& getName() const
-    {
-        return name;
-    }
+	const Framework::Text& getName() const
+	{
+		return name;
+	}
 };
 
 typedef RecipieListType<Recipie, CraftingStorage> RecipieList;

+ 291 - 288
FactoryCraft/Server.cpp

@@ -8,364 +8,367 @@
 
 // Inhalt der LoginServer Klasse aus LoginServer.h
 // Konstruktor 
-FactoryCraftServer::FactoryCraftServer( InitDatei* zIni )
-    : ReferenceCounter()
+FactoryCraftServer::FactoryCraftServer(InitDatei* zIni)
+	: ReferenceCounter()
 {
-    Network::Start( 100 );
-    runningThreads = 0;
-    klients = new RCArray< FCKlient >();
-    ini = dynamic_cast<InitDatei*>(zIni->getThis());
-    id = *zIni->zWert( "ServerId" );
-    sslServer = new SSLServer();
-    sslServer->setPrivateKeyPassword( zIni->zWert( "SSLPasswort" )->getText() );
-    sslServer->setCertificateFile( zIni->zWert( "SSLCert" )->getText() );
-    std::cout << "using cert file " << zIni->zWert( "SSLCert" )->getText() << "\n";
-    sslServer->setPrivateKeyFile( zIni->zWert( "SSLKey" )->getText() );
-    std::cout << "using private key " << zIni->zWert( "SSLKey" )->getText() << "\n";
-    server = new Server();
-    std::cout << "Server Port: " << ini->zWert( "Port" )->getText() << "\n";
-    if( !server->verbinde( (unsigned short)TextZuInt( ini->zWert( "Port" )->getText(), 10 ), 10 ) )
-    {
-        std::cout << "Der Server konnte nicht gestartet werden.\n";
-        exit( 1 );
-    }
-    std::cout << "SSL Server Port: " << ini->zWert( "SSLPort" )->getText() << "\n";
-    if( !sslServer->verbinde( (unsigned short)TextZuInt( ini->zWert( "SSLPort" )->getText(), 10 ), 10 ) )
-    {
-        std::cout << "Der SSL Server konnte nicht gestartet werden.\n";
-        exit( 2 );
-    }
-    Game::initialize( zIni->zWert( "World" )->getText(), zIni->zWert( "SaveDir" )->getText() );
-    new Framework::AsynchronCall( "Server", [this]() {
-        runningThreads++;
-        while( server->isConnected() )
-        {
-            SKlient* klient = server->getKlient();
-            if( !klient )
-                continue;
-            unsigned short len;
-            klient->setEmpfangTimeout( 5000 );
-            klient->getNachricht( (char*)&len, 2 );
-            char* key = new char[ len ];
-            klient->getNachricht( (char*)key, len );
-            bool bg;
-            klient->getNachricht( (char*)&bg, 1 );
-            klient->setEmpfangTimeout( 0 );
-            bool found = 0;
-            EnterCriticalSection( &cs );
-            for( FCKlient* client : *klients )
-            {
-                if( client->matchAuthKey( key, len ) )
-                {
-                    if( bg )
-                        client->setBackgroundClient( klient );
-                    else
-                        client->setForegroundClient( klient );
-                    found = 1;
-                    break;
-                }
-            }
-            LeaveCriticalSection( &cs );
-            if( !found )
-                klient->release();
-        }
-        runningThreads--;
-    } );
-    InitializeCriticalSection( &cs );
+	Network::Start(100);
+	runningThreads = 0;
+	klients = new RCArray< FCKlient >();
+	ini = dynamic_cast<InitDatei*>(zIni->getThis());
+	id = *zIni->zWert("ServerId");
+	sslServer = new SSLServer();
+	sslServer->setPrivateKeyPassword(zIni->zWert("SSLPasswort")->getText());
+	sslServer->setCertificateFile(zIni->zWert("SSLCert")->getText());
+	std::cout << "using cert file " << zIni->zWert("SSLCert")->getText() << "\n";
+	sslServer->setPrivateKeyFile(zIni->zWert("SSLKey")->getText());
+	std::cout << "using private key " << zIni->zWert("SSLKey")->getText() << "\n";
+	server = new Server();
+	std::cout << "Server Port: " << ini->zWert("Port")->getText() << "\n";
+	if (!server->verbinde((unsigned short)TextZuInt(ini->zWert("Port")->getText(), 10), 10))
+	{
+		std::cout << "Der Server konnte nicht gestartet werden.\n";
+		exit(1);
+	}
+	std::cout << "SSL Server Port: " << ini->zWert("SSLPort")->getText() << "\n";
+	if (!sslServer->verbinde((unsigned short)TextZuInt(ini->zWert("SSLPort")->getText(), 10), 10))
+	{
+		std::cout << "Der SSL Server konnte nicht gestartet werden.\n";
+		exit(2);
+	}
+	Game::initialize(zIni->zWert("World")->getText(), zIni->zWert("SaveDir")->getText());
+	new Framework::AsynchronCall("Server", [this]()
+		{
+			runningThreads++;
+			while (server->isConnected())
+			{
+				SKlient* klient = server->getKlient();
+				if (!klient)
+					continue;
+				unsigned short len;
+				klient->setEmpfangTimeout(5000);
+				klient->getNachricht((char*)&len, 2);
+				char* key = new char[len];
+				klient->getNachricht((char*)key, len);
+				bool bg;
+				klient->getNachricht((char*)&bg, 1);
+				klient->setEmpfangTimeout(0);
+				bool found = 0;
+				EnterCriticalSection(&cs);
+				for (FCKlient* client : *klients)
+				{
+					if (client->matchAuthKey(key, len))
+					{
+						if (bg)
+							client->setBackgroundClient(klient);
+						else
+							client->setForegroundClient(klient);
+						found = 1;
+						break;
+					}
+				}
+				LeaveCriticalSection(&cs);
+				if (!found)
+					klient->release();
+			}
+			runningThreads--;
+		});
+	InitializeCriticalSection(&cs);
 }
 
 // Destruktor 
 FactoryCraftServer::~FactoryCraftServer()
 {
-    sslServer->trenne();
-    server->trenne();
-    while( runningThreads > 0 )
-        Sleep( 100 );
-    sslServer->release();
-    server->release();
-    if( klients )
-        klients->release();
-    ini->release();
-    Game::INSTANCE->requestStop();
-    Game::INSTANCE->release();
-    DeleteCriticalSection( &cs );
+	sslServer->trenne();
+	server->trenne();
+	while (runningThreads > 0)
+		Sleep(100);
+	sslServer->release();
+	server->release();
+	if (klients)
+		klients->release();
+	ini->release();
+	Game::INSTANCE->requestStop();
+	Game::INSTANCE->release();
+	DeleteCriticalSection(&cs);
 }
 
 // nicht constant 
 void FactoryCraftServer::run()
 {
-    runningThreads++;
-    while( sslServer->isConnected() )
-    {
-        SSLSKlient* klient = sslServer->getKlient();
-        if( !klient )
-            continue;
-        Framework::getThreadRegister()->cleanUpClosedThreads();
-        FCKlient* clHandle = new FCKlient( klient, dynamic_cast<FactoryCraftServer*>(getThis()) );
-        EnterCriticalSection( &cs );
-        klients->add( clHandle );
-        LeaveCriticalSection( &cs );
-        clHandle->start();
-    }
-    runningThreads--;
+	runningThreads++;
+	while (sslServer->isConnected())
+	{
+		SSLSKlient* klient = sslServer->getKlient();
+		if (!klient)
+			continue;
+		Framework::getThreadRegister()->cleanUpClosedThreads();
+		FCKlient* clHandle = new FCKlient(klient, dynamic_cast<FactoryCraftServer*>(getThis()));
+		EnterCriticalSection(&cs);
+		klients->add(clHandle);
+		LeaveCriticalSection(&cs);
+		clHandle->start();
+	}
+	runningThreads--;
 }
 
 void FactoryCraftServer::close()
 {
-    sslServer->trenne();
-    EnterCriticalSection( &cs );
-    for( int i = 0; i < klients->getEintragAnzahl(); i++ )
-        klients->z( i )->absturz();
-    klients = (RCArray< FCKlient > *)klients->release();
-    Game::INSTANCE->save();
-    LeaveCriticalSection( &cs );
+	sslServer->trenne();
+	EnterCriticalSection(&cs);
+	for (int i = 0; i < klients->getEintragAnzahl(); i++)
+		klients->z(i)->absturz();
+	klients = (RCArray< FCKlient > *)klients->release();
+	Game::INSTANCE->save();
+	LeaveCriticalSection(&cs);
 }
 
-bool FactoryCraftServer::absturzKlient( int accountId )
+bool FactoryCraftServer::absturzKlient(int accountId)
 {
-    bool gefunden = 0;
-    EnterCriticalSection( &cs );
-    for( int i = 0; i < klients->getEintragAnzahl(); i++ )
-    {
-        if( klients->z( i ) && klients->z( i )->getAccountId() == accountId )
-        {
-            klients->z( i )->absturz();
-            klients->remove( i );
-            gefunden = 1;
-            break;
-        }
-    }
-    LeaveCriticalSection( &cs );
-    return gefunden;
+	bool gefunden = 0;
+	EnterCriticalSection(&cs);
+	for (int i = 0; i < klients->getEintragAnzahl(); i++)
+	{
+		if (klients->z(i) && klients->z(i)->getAccountId() == accountId)
+		{
+			klients->z(i)->absturz();
+			klients->remove(i);
+			gefunden = 1;
+			break;
+		}
+	}
+	LeaveCriticalSection(&cs);
+	return gefunden;
 }
 
-bool FactoryCraftServer::removeKlient( FCKlient* zKlient )
+bool FactoryCraftServer::removeKlient(FCKlient* zKlient)
 {
-    bool gefunden = 0;
-    EnterCriticalSection( &cs );
-    for( int i = 0; i < klients->getEintragAnzahl(); i++ )
-    {
-        if( klients->z( i ) == zKlient )
-        {
-            klients->remove( i );
-            gefunden = 1;
-            break;
-        }
-    }
-    LeaveCriticalSection( &cs );
-    return gefunden;
+	bool gefunden = 0;
+	EnterCriticalSection(&cs);
+	for (int i = 0; i < klients->getEintragAnzahl(); i++)
+	{
+		if (klients->z(i) == zKlient)
+		{
+			klients->remove(i);
+			gefunden = 1;
+			break;
+		}
+	}
+	LeaveCriticalSection(&cs);
+	return gefunden;
 }
 
 bool FactoryCraftServer::hatClients() const
 {
-    return klients->hat( 0 );
+	return klients->hat(0);
 }
 
 int FactoryCraftServer::getUnencryptedPort() const
 {
-    return server->getPort();
+	return server->getPort();
 }
 
-char* randomKey( int& len )
+char* randomKey(int& len)
 {
-    len = 1024 + (int)(((double)rand() / RAND_MAX - 0.5) * 512);
-    char* key = new char[ len ];
-    for( int i = 0; i < len; i++ )
-        key[ i ] = (char)(((double)rand() / RAND_MAX) * 256);
-    return key;
+	len = 1024 + (int)(((double)rand() / RAND_MAX - 0.5) * 512);
+	char* key = new char[len];
+	for (int i = 0; i < len; i++)
+		key[i] = (char)(((double)rand() / RAND_MAX) * 256);
+	return key;
 }
 
 // Inhalt der LSKlient aus LoginServer.h
 // Konstruktor
-FCKlient::FCKlient( SSLSKlient* klient, FactoryCraftServer* ls )
-    : Thread()
+FCKlient::FCKlient(SSLSKlient* klient, FactoryCraftServer* ls)
+	: Thread()
 {
-    this->klient = klient;
-    background = 0;
-    foreground = 0;
-    accountId = 0;
-    this->ls = ls;
-    zGameClient = 0;
-    backgroundReader = 0;
-    foregroundReader = 0;
-    backgroundWriter = 0;
-    foregroundWriter = 0;
-    authKey = randomKey( authKeyLen );
+	this->klient = klient;
+	background = 0;
+	foreground = 0;
+	accountId = 0;
+	this->ls = ls;
+	zGameClient = 0;
+	backgroundReader = 0;
+	foregroundReader = 0;
+	backgroundWriter = 0;
+	foregroundWriter = 0;
+	authKey = randomKey(authKeyLen);
 }
 
 // Destruktor 
 FCKlient::~FCKlient()
 {
-    if( zGameClient )
-    {
-        zGameClient->logout();
-        zGameClient = (GameClient*)zGameClient->release();
-    }
-    if( background )
-        background->release();
-    if( foreground )
-        foreground->release();
-    delete backgroundReader;
-    delete foregroundReader;
-    delete backgroundWriter;
-    delete foregroundWriter;
-    klient->release();
-    ls->release();
-    delete[] authKey;
+	if (zGameClient)
+	{
+		zGameClient->logout();
+		zGameClient = (GameClient*)zGameClient->release();
+	}
+	if (background)
+		background->release();
+	if (foreground)
+		foreground->release();
+	delete backgroundReader;
+	delete foregroundReader;
+	delete backgroundWriter;
+	delete foregroundWriter;
+	klient->release();
+	ls->release();
+	delete[] authKey;
 }
 
 // nicht constant 
-void FCKlient::setForegroundClient( SKlient* foreground )
+void FCKlient::setForegroundClient(SKlient* foreground)
 {
-    this->foreground = foreground;
-    foregroundReader = new NetworkReader( foreground );
-    foregroundWriter = new NetworkWriter( foreground );
-    if( foreground && background )
-        zGameClient = Game::INSTANCE->addPlayer( dynamic_cast<FCKlient*>(getThis()), Framework::Text( (int)accountId ) );
-    new AsynchronCall( [this]() {
-        while( this->foreground->waitForNextMessage() )
-        {
-            if( zGameClient )
-                zGameClient->addMessage( foregroundReader );
-            if( !zGameClient )
-                Sleep( 100 );
-        }
-        zGameClient->logout();
-        ls->removeKlient( this );
-    } );
+	this->foreground = foreground;
+	foregroundReader = new NetworkReader(foreground);
+	foregroundWriter = new NetworkWriter(foreground);
+	if (foreground && background)
+		zGameClient = Game::INSTANCE->addPlayer(dynamic_cast<FCKlient*>(getThis()), Framework::Text((int)accountId));
+	new AsynchronCall([this]()
+		{
+			while (this->foreground->waitForNextMessage())
+			{
+				if (zGameClient)
+					zGameClient->addMessage(foregroundReader);
+				if (!zGameClient)
+					Sleep(100);
+			}
+			zGameClient->logout();
+			ls->removeKlient(this);
+		});
 }
 
-void FCKlient::setBackgroundClient( SKlient* background )
+void FCKlient::setBackgroundClient(SKlient* background)
 {
-    this->background = background;
-    backgroundReader = new NetworkReader( background );
-    backgroundWriter = new NetworkWriter( background );
-    if( foreground && background )
-        zGameClient = Game::INSTANCE->addPlayer( dynamic_cast<FCKlient*>(getThis()), Framework::Text( (int)accountId ) );
-    new AsynchronCall( [this]() {
-        while( this->background->waitForNextMessage() )
-        {
-            if( zGameClient )
-                zGameClient->addMessage( backgroundReader );
-            if( !zGameClient )
-                Sleep( 100 );
-        }
-        zGameClient->logout();
-        ls->removeKlient( this );
-    } );
+	this->background = background;
+	backgroundReader = new NetworkReader(background);
+	backgroundWriter = new NetworkWriter(background);
+	if (foreground && background)
+		zGameClient = Game::INSTANCE->addPlayer(dynamic_cast<FCKlient*>(getThis()), Framework::Text((int)accountId));
+	new AsynchronCall([this]()
+		{
+			while (this->background->waitForNextMessage())
+			{
+				if (zGameClient)
+					zGameClient->addMessage(backgroundReader);
+				if (!zGameClient)
+					Sleep(100);
+			}
+			zGameClient->logout();
+			ls->removeKlient(this);
+		});
 }
 
 void FCKlient::absturz()
 {
-    ende();
-    klient->trenne();
+	ende();
+	klient->trenne();
 }
 
 void FCKlient::thread()
 {
-    while( 1 )
-    {
-        char c = 0;
-        if( !klient->getNachricht( &c, 1 ) )
-            break;
-        else
-        {
-            bool br = 0;
-            switch( c )
-            {
-            case 1: // Klient identifikation
-            {
-                int accountId = 0;
-                klient->getNachricht( (char*)&accountId, 4 );
-                unsigned char secretLength = 0;
-                klient->getNachricht( (char*)&secretLength, 1 );
-                char* secret = new char[ secretLength + 1 ];
-                klient->getNachricht( secret, (int)secretLength );
-                secret[ secretLength ] = 0;
-                Text data = "{\"account_id\":";
-                data += accountId;
-                data += ", \"secret\": \"";
-                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();
-                if( answer->getStatusCode() == 200 )
-                {
-                    JSON::JSONObject obj( answer->getData() );
-                    if( obj.hasValue( "verified" ) )
-                    {
-                        JSON::JSONValue* value = obj.getValue( "verified" );
-                        if( value->getType() == JSON::JSONType::BOOLEAN )
-                        {
-                            if( ((JSON::JSONBool*)value)->getBool() )
-                            {
-                                this->accountId = accountId;
-                                if( zGameClient )
-                                {
-                                    zGameClient->logout();
-                                    zGameClient = (GameClient*)zGameClient->release();
-                                }
-                                klient->sende( "\1", 1 );
-                                klient->sende( (char*)&authKeyLen, 4 );
-                                klient->sende( authKey, authKeyLen );
-                                int port = ls->getUnencryptedPort();
-                                klient->sende( (char*)&port, 4 );
-                                ok = true;
-                            }
-                        }
-                        value->release();
-                    }
-                }
-                answer->release();
-                delete[]secret;
-                if( !ok )
-                    klient->sende( "\0", 1 );
-                break;
-            }
-            case 2: // Verbindungsende
-                br = 1;
-                if( zGameClient )
-                {
-                    zGameClient->logout();
-                    zGameClient = (GameClient*)zGameClient->release();
-                }
-                klient->sende( "\1", 1 );
-                break;
-            default:
-                br = 1;
-                break;
-            }
-            if( br )
-                break;
-        }
-    }
+	while (1)
+	{
+		char c = 0;
+		if (!klient->getNachricht(&c, 1))
+			break;
+		else
+		{
+			bool br = 0;
+			switch (c)
+			{
+			case 1: // Klient identifikation
+			{
+				int accountId = 0;
+				klient->getNachricht((char*)&accountId, 4);
+				unsigned char secretLength = 0;
+				klient->getNachricht((char*)&secretLength, 1);
+				char* secret = new char[secretLength + 1];
+				klient->getNachricht(secret, (int)secretLength);
+				secret[secretLength] = 0;
+				Text data = "{\"account_id\":";
+				data += accountId;
+				data += ", \"secret\": \"";
+				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();
+				if (answer->getStatusCode() == 200)
+				{
+					JSON::JSONObject obj(answer->getData());
+					if (obj.hasValue("verified"))
+					{
+						JSON::JSONValue* value = obj.getValue("verified");
+						if (value->getType() == JSON::JSONType::BOOLEAN)
+						{
+							if (((JSON::JSONBool*)value)->getBool())
+							{
+								this->accountId = accountId;
+								if (zGameClient)
+								{
+									zGameClient->logout();
+									zGameClient = (GameClient*)zGameClient->release();
+								}
+								klient->sende("\1", 1);
+								klient->sende((char*)&authKeyLen, 4);
+								klient->sende(authKey, authKeyLen);
+								int port = ls->getUnencryptedPort();
+								klient->sende((char*)&port, 4);
+								ok = true;
+							}
+						}
+						value->release();
+					}
+				}
+				answer->release();
+				delete[]secret;
+				if (!ok)
+					klient->sende("\0", 1);
+				break;
+			}
+			case 2: // Verbindungsende
+				br = 1;
+				if (zGameClient)
+				{
+					zGameClient->logout();
+					zGameClient = (GameClient*)zGameClient->release();
+				}
+				klient->sende("\1", 1);
+				break;
+			default:
+				br = 1;
+				break;
+			}
+			if (br)
+				break;
+		}
+	}
 }
 
 int FCKlient::getAccountId() const // gibt die KlientId zurück
 {
-    return accountId;
+	return accountId;
 }
 
 NetworkWriter* FCKlient::zBackgroundWriter() const
 {
-    return backgroundWriter;
+	return backgroundWriter;
 }
 
 NetworkWriter* FCKlient::zForegroundWriter() const
 {
-    return foregroundWriter;
+	return foregroundWriter;
 }
 
-bool FCKlient::matchAuthKey( char* key, int len ) const
+bool FCKlient::matchAuthKey(char* key, int len) const
 {
-    if( foreground && background )
-        return 0;
-    if( len != authKeyLen )
-        return 0;
-    for( int i = 0; i < len; i++ )
-    {
-        if( key[ i ] != authKey[ i ] )
-            return 0;
-    }
-    return 1;
+	if (foreground && background)
+		return 0;
+	if (len != authKeyLen)
+		return 0;
+	for (int i = 0; i < len; i++)
+	{
+		if (key[i] != authKey[i])
+			return 0;
+	}
+	return 1;
 }

+ 44 - 44
FactoryCraft/Server.h

@@ -17,57 +17,57 @@ class GameClient;
 class FactoryCraftServer : virtual public ReferenceCounter
 {
 private:
-    SSLServer* sslServer;
-    Server* server;
-    InitDatei* ini;
-    CRITICAL_SECTION cs;
-    RCArray< FCKlient >* klients;
-    int runningThreads;
-    int id;
+	SSLServer* sslServer;
+	Server* server;
+	InitDatei* ini;
+	CRITICAL_SECTION cs;
+	RCArray< FCKlient >* klients;
+	int runningThreads;
+	int id;
 
 public:
-    // Konstruktor 
-    FactoryCraftServer( InitDatei* zIni );
-    // Destruktor 
-    virtual ~FactoryCraftServer();
-    // nicht constant
-    void run();
-    void close();
-    bool absturzKlient( int accountId );
-    bool removeKlient( FCKlient* zKlient );
-    bool hatClients() const;
-    int getUnencryptedPort() const;
+	// Konstruktor 
+	FactoryCraftServer(InitDatei* zIni);
+	// Destruktor 
+	virtual ~FactoryCraftServer();
+	// nicht constant
+	void run();
+	void close();
+	bool absturzKlient(int accountId);
+	bool removeKlient(FCKlient* zKlient);
+	bool hatClients() const;
+	int getUnencryptedPort() const;
 };
 
 class FCKlient : public Thread
 {
 private:
-    SSLSKlient* klient;
-    SKlient* background;
-    SKlient* foreground;
-    unsigned int accountId;
-    FactoryCraftServer* ls;
-    GameClient* zGameClient;
-    NetworkReader* backgroundReader;
-    NetworkReader* foregroundReader;
-    NetworkWriter* backgroundWriter;
-    NetworkWriter* foregroundWriter;
-    char* authKey;
-    int authKeyLen;
+	SSLSKlient* klient;
+	SKlient* background;
+	SKlient* foreground;
+	unsigned int accountId;
+	FactoryCraftServer* ls;
+	GameClient* zGameClient;
+	NetworkReader* backgroundReader;
+	NetworkReader* foregroundReader;
+	NetworkWriter* backgroundWriter;
+	NetworkWriter* foregroundWriter;
+	char* authKey;
+	int authKeyLen;
 
 public:
-    // Konstruktor 
-    FCKlient( SSLSKlient* klient, FactoryCraftServer* ls );
-    // Destruktor 
-    virtual ~FCKlient();
-    void setForegroundClient( SKlient* foreground );
-    void setBackgroundClient( SKlient* background );
-    // nicht constant 
-    void absturz();
-    void thread();
-    // constant
-    int getAccountId() const;
-    NetworkWriter* zBackgroundWriter() const;
-    NetworkWriter* zForegroundWriter() const;
-    bool matchAuthKey( char* key, int len ) const;
+	// Konstruktor 
+	FCKlient(SSLSKlient* klient, FactoryCraftServer* ls);
+	// Destruktor 
+	virtual ~FCKlient();
+	void setForegroundClient(SKlient* foreground);
+	void setBackgroundClient(SKlient* background);
+	// nicht constant 
+	void absturz();
+	void thread();
+	// constant
+	int getAccountId() const;
+	NetworkWriter* zBackgroundWriter() const;
+	NetworkWriter* zForegroundWriter() const;
+	bool matchAuthKey(char* key, int len) const;
 };

+ 58 - 58
FactoryCraft/Start.cpp

@@ -15,71 +15,71 @@ FactoryCraftServer* mserver = 0;
 
 void exit()
 {
-    std::cout << "Der Server wird beendet...\n";
-    if( mserver )
-        mserver->close();
+	std::cout << "Der Server wird beendet...\n";
+	if (mserver)
+		mserver->close();
 }
 
 int main()
 {
-    struct rlimit core_limits;
-    core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
-    setrlimit( RLIMIT_CORE, &core_limits );
+	struct rlimit core_limits;
+	core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
+	setrlimit(RLIMIT_CORE, &core_limits);
 
-    Framework::initFramework();
-    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::cout.rdbuf( file.rdbuf() );
-    pfad->release();
+	Framework::initFramework();
+	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::cout.rdbuf( file.rdbuf() );
+	pfad->release();
 
-    std::cout << "Startet...\n";
-    std::cout << "Lese init Datei fcInit.ini ...\n";
+	std::cout << "Startet...\n";
+	std::cout << "Lese init Datei fcInit.ini ...\n";
 
-    InitDatei* dat = new InitDatei( "fcInit.ini" );
-    if( !dat->laden() )
-    {
-        std::cout << "error: Datei konnte nicht gelesen werden. Das Programm wird geschlossen.\n";
-        dat->release();
-        file.close();
-        std::cout.rdbuf( sbuf );
-        exit( 1 );
-    }
-    const char* wichtig[] = { "SSLPort", "SSLCert", "SSLKey", "SSLPasswort", "Port" };
-    for( const char* w : wichtig )
-    {
-        if( !dat->wertExistiert( w ) )
-        {
-            std::cout << "error: Der Wert '" << w << "' wurde nicht gefunden. Das Programm wird geschlossen.\n";
-            dat->release();
-            file.close();
-            std::cout.rdbuf( sbuf );
-            exit( 1 );
-        }
-    }
+	InitDatei* dat = new InitDatei("fcInit.ini");
+	if (!dat->laden())
+	{
+		std::cout << "error: Datei konnte nicht gelesen werden. Das Programm wird geschlossen.\n";
+		dat->release();
+		file.close();
+		std::cout.rdbuf(sbuf);
+		exit(1);
+	}
+	const char* wichtig[] = { "SSLPort", "SSLCert", "SSLKey", "SSLPasswort", "Port" };
+	for (const char* w : wichtig)
+	{
+		if (!dat->wertExistiert(w))
+		{
+			std::cout << "error: Der Wert '" << w << "' wurde nicht gefunden. Das Programm wird geschlossen.\n";
+			dat->release();
+			file.close();
+			std::cout.rdbuf(sbuf);
+			exit(1);
+		}
+	}
 
-    mserver = new FactoryCraftServer( dat );
-    std::atexit( exit );
-    signal( SIGTERM, exit );
-    signal( SIGSEGV, exit );
-    signal( SIGILL, exit );
-    signal( SIGABRT, exit );
-    signal( SIGFPE, exit );
-    signal( SIGINT, exit );
+	mserver = new FactoryCraftServer(dat);
+	std::atexit(exit);
+	signal(SIGTERM, exit);
+	signal(SIGSEGV, exit);
+	signal(SIGILL, exit);
+	signal(SIGABRT, exit);
+	signal(SIGFPE, exit);
+	signal(SIGINT, exit);
 
-    std::cout << "Der Server läuft. Startforgang beendet.\n";
-    mserver->run();
-    mserver->release();
-    mserver = 0;
-    dat->release();
-    std::cout << "Der Server ist heruntergefahren.\n";
-    file.close();
-    std::cout.rdbuf( sbuf );
-    Framework::releaseFramework();
-    return 0;
+	std::cout << "Der Server läuft. Startforgang beendet.\n";
+	mserver->run();
+	mserver->release();
+	mserver = 0;
+	dat->release();
+	std::cout << "Der Server ist heruntergefahren.\n";
+	file.close();
+	std::cout.rdbuf(sbuf);
+	Framework::releaseFramework();
+	return 0;
 }

+ 0 - 2
FactoryCraft/StaticInitializerOrder.cpp

@@ -30,8 +30,6 @@ bool initialized_##c##_##typ = StaticRegistry<typ>::INSTANCE.info(c::ID);
 // world updates
 #include "AddChunkUpdate.h"
 #include "PlaceBlockUpdate.h"
-#include "BlockChangedUpdate.h"
 #include "BlockRemovedUpdate.h"
 #include "AddEntityUpdate.h"
-#include "EntityChangedUpdate.h"
 #include "EntityRemovedUpdate.h"

+ 1 - 8
FactoryCraft/StaticRegistry.h

@@ -79,11 +79,4 @@ public:
 };
 
 template <typename T>
-StaticRegistry<T> StaticRegistry<T>::INSTANCE;
-
-
-enum class StreamTarget
-{
-	FULL,
-	CLIENT
-};
+StaticRegistry<T> StaticRegistry<T>::INSTANCE;

+ 2 - 2
FactoryCraft/StoneTool.cpp

@@ -3,7 +3,7 @@
 
 
 BrokenStoneToolItemType::BrokenStoneToolItemType()
-	: ItemType(ID, "BrokenStoneTool", 0, 0)
+	: ItemType(ID, "BrokenStoneTool", 0, 0, ModelInfo("itemCube", "player.ltdb/player.png", 6)) // TODO: correct model
 {}
 
 Item* BrokenStoneToolItemType::createItem() const
@@ -13,7 +13,7 @@ Item* BrokenStoneToolItemType::createItem() const
 
 
 StoneToolItemType::StoneToolItemType()
-	: ItemType(ID, "StoneTool", new StoneToolLevelUpRule(), BrokenStoneToolItemType::INSTANCE)
+	: ItemType(ID, "StoneTool", new StoneToolLevelUpRule(), BrokenStoneToolItemType::INSTANCE, ModelInfo("itemCube", "player.ltdb/player.png", 6)) // TODO: correct model
 {}
 
 void StoneToolItemType::loadSuperItemSkill(ItemSkill* zSkill, Framework::StreamReader* zReader) const

+ 36 - 36
FactoryCraft/TickOrganizer.cpp

@@ -3,55 +3,55 @@
 
 
 TickOrganizer::TickOrganizer()
-    : ReferenceCounter()
+	: ReferenceCounter()
 {
-    queue = new TickQueue();
-    workerCount = NUM_TICK_WORKERS;
-    workers = new TickWorker * [ workerCount ];
-    for( int i = 0; i < workerCount; i++ )
-        workers[ i ] = new TickWorker( queue );
+	queue = new TickQueue();
+	workerCount = NUM_TICK_WORKERS;
+	workers = new TickWorker * [workerCount];
+	for (int i = 0; i < workerCount; i++)
+		workers[i] = new TickWorker(queue);
 }
 
 TickOrganizer::~TickOrganizer()
 {
-    queue->requestExit();
-    for( int i = 0; i < workerCount; i++ )
-    {
-        workers[ i ]->warteAufThread( 10000 );
-        workers[ i ]->ende();
-        workers[ i ]->release();
-    }
-    queue->release();
-    delete[] workers;
+	queue->requestExit();
+	for (int i = 0; i < workerCount; i++)
+	{
+		workers[i]->warteAufThread(10000);
+		workers[i]->ende();
+		workers[i]->release();
+	}
+	queue->release();
+	delete[] workers;
 }
 
 void TickOrganizer::nextTick()
 {
-    queue->startNextTick( &tickSources );
-    bool notWaiting = 0;
-    do
-    {
-        queue->waitForEmpty();
-        for( int i = 0; i < workerCount; i++ )
-            notWaiting |= !workers[ i ]->isWaiting();
-    } while( notWaiting );
+	queue->startNextTick(&tickSources);
+	bool notWaiting = 0;
+	do
+	{
+		queue->waitForEmpty();
+		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 );
+	tickSources.add(zBlock);
 }
 
-void TickOrganizer::removeTickSource( Block* zBlock )
+void TickOrganizer::removeTickSource(Block* zBlock)
 {
-    int index = 0;
-    for( Block* block : tickSources )
-    {
-        if( block == zBlock )
-        {
-            tickSources.remove( index );
-            return;
-        }
-        index++;
-    }
+	int index = 0;
+	for (Block* block : tickSources)
+	{
+		if (block == zBlock)
+		{
+			tickSources.remove(index);
+			return;
+		}
+		index++;
+	}
 }

+ 9 - 9
FactoryCraft/TickOrganizer.h

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

+ 63 - 63
FactoryCraft/TickQueue.cpp

@@ -2,89 +2,89 @@
 
 
 TickQueue::TickQueue()
-    : ReferenceCounter()
+	: ReferenceCounter()
 {
-    maxSize = 0;
-    readPosition = 0;
-    writePosition = 0;
-    queue = 0;
-    exit = 0;
+	maxSize = 0;
+	readPosition = 0;
+	writePosition = 0;
+	queue = 0;
+	exit = 0;
 }
 
 TickQueue::~TickQueue()
 {
-    delete[] queue;
+	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;
-    writePosition = 0;
-    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) );
-        maxSize = count + 1000;
-        delete[]queue;
-        queue = temp;
-    }
-    for( Block* block : *zSources )
-        queue[ writePosition++ ] = block;
-    lk.unlock();
-    hasBlocks.notify_all();
+	std::unique_lock<std::mutex> lk(mutex);
+	readPosition = 0;
+	writePosition = 0;
+	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));
+		maxSize = count + 1000;
+		delete[]queue;
+		queue = temp;
+	}
+	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 );
-        maxSize += 1000;
-        delete[]queue;
-        queue = temp;
-    }
-    queue[ writePosition++ ] = zBlock;
-    lk.unlock();
-    hasBlocks.notify_one();
+	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);
+		maxSize += 1000;
+		delete[]queue;
+		queue = temp;
+	}
+	queue[writePosition++] = zBlock;
+	lk.unlock();
+	hasBlocks.notify_one();
 }
 
-Block* TickQueue::zNextBlock( bool& waiting )
+Block* TickQueue::zNextBlock(bool& waiting)
 {
-    std::unique_lock<std::mutex> lk( mutex );
-    if( readPosition == writePosition && exit )
-        return 0;
-    if( readPosition == writePosition )
-    {
-        lk.unlock();
-        hasNoBlocks.notify_all();
-        lk.lock();
-        waiting = 1;
-        hasBlocks.wait( lk, [this] { return readPosition < writePosition || exit; } );
-        waiting = 0;
-    }
-    if( readPosition < writePosition )
-        return queue[ readPosition++ ];
-    return 0;
+	std::unique_lock<std::mutex> lk(mutex);
+	if (readPosition == writePosition && exit)
+		return 0;
+	if (readPosition == writePosition)
+	{
+		lk.unlock();
+		hasNoBlocks.notify_all();
+		lk.lock();
+		waiting = 1;
+		hasBlocks.wait(lk, [this] { return readPosition < writePosition || exit; });
+		waiting = 0;
+	}
+	if (readPosition < writePosition)
+		return queue[readPosition++];
+	return 0;
 }
 
 void TickQueue::requestExit()
 {
-    std::unique_lock<std::mutex> lk( mutex );
-    exit = 1;
-    lk.unlock();
-    hasBlocks.notify_all();
-    hasNoBlocks.notify_all();
+	std::unique_lock<std::mutex> lk(mutex);
+	exit = 1;
+	lk.unlock();
+	hasBlocks.notify_all();
+	hasNoBlocks.notify_all();
 }
 
 void TickQueue::waitForEmpty()
 {
-    std::unique_lock<std::mutex> lk( mutex );
-    if( readPosition != writePosition )
-        hasNoBlocks.wait( lk, [this] { return readPosition == writePosition || exit; } );
+	std::unique_lock<std::mutex> lk(mutex);
+	if (readPosition != writePosition)
+		hasNoBlocks.wait(lk, [this] { return readPosition == writePosition || exit; });
 }

+ 15 - 15
FactoryCraft/TickQueue.h

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

+ 13 - 13
FactoryCraft/TickWorker.cpp

@@ -2,30 +2,30 @@
 #include "Block.h"
 
 
-TickWorker::TickWorker( TickQueue* queue )
-    : Thread(),
-    queue( queue ),
-    waiting( 0 )
+TickWorker::TickWorker(TickQueue* queue)
+	: Thread(),
+	queue(queue),
+	waiting(0)
 {
-    start();
+	start();
 }
 
 TickWorker::~TickWorker()
 {
-    queue->release();
+	queue->release();
 }
 
 void TickWorker::thread()
 {
-    Block* zTickBlock = queue->zNextBlock( waiting );
-    while( zTickBlock )
-    {
-        zTickBlock->tick( queue );
-        zTickBlock = queue->zNextBlock( waiting );
-    }
+	Block* zTickBlock = queue->zNextBlock(waiting);
+	while (zTickBlock)
+	{
+		zTickBlock->tick(queue);
+		zTickBlock = queue->zNextBlock(waiting);
+	}
 }
 
 bool TickWorker::isWaiting() const
 {
-    return waiting;
+	return waiting;
 }

+ 6 - 6
FactoryCraft/TickWorker.h

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

+ 33 - 33
FactoryCraft/TreeTemplate.cpp

@@ -1,40 +1,40 @@
 #include "TreeTemplate.h"
 
 
-TreeTemplate::TreeTemplate( float propability, const BlockType* zWoodType, const BlockType* zLeaveType, int minHeight, int maxHeight )
-    : GenerationTemplate( propability, 0, 1, Framework::Vec3<int>( -2, -2, 0 ), Framework::Vec3<int>( 5, 5, maxHeight ) ),
-    zWoodType( zWoodType ),
-    zLeaveType( zLeaveType ),
-    minHeight( minHeight ),
-    maxHeight( maxHeight )
+TreeTemplate::TreeTemplate(float propability, const BlockType* zWoodType, const BlockType* zLeaveType, int minHeight, int maxHeight)
+	: GenerationTemplate(propability, 0, 1, Framework::Vec3<int>(-2, -2, 0), Framework::Vec3<int>(5, 5, maxHeight)),
+	zWoodType(zWoodType),
+	zLeaveType(zLeaveType),
+	minHeight(minHeight),
+	maxHeight(maxHeight)
 {}
 
-GeneratedStructure* TreeTemplate::generateAt( Framework::Vec3<int> location, Noise* zNoise )
+GeneratedStructure* TreeTemplate::generateAt(Framework::Vec3<int> location, Noise* zNoise)
 {
-    double noise = zNoise->getNoise( (double)location.x + 40, (double)location.y + 70, (double)location.z - 20 );
-    int height = (int)(minHeight + (noise * (maxHeight - minHeight)));
-    GeneratedStructure* generated = new GeneratedStructure( dynamic_cast<GenerationTemplate*>(getThis()), location, Framework::Vec3<int>( 5, 5, height ), Framework::Vec3<int>( -2, -2, 0 ) + location );
-    for( int x = 1; x < 4; x++ )
-    {
-        for( int y = 1; y < 4; y++ )
-        {
-            generated->setBlockAt( zLeaveType->getId(), Framework::Vec3<int>( x, y, height - 1 ) );
-            generated->setBlockAt( zLeaveType->getId(), Framework::Vec3<int>( x, y, height - 5 ) );
-        }
-    }
-    for( int z = height - 2; z >= height - 4; z-- )
-    {
-        for( int x = 1; x < 4; x++ )
-        {
-            generated->setBlockAt( zLeaveType->getId(), Framework::Vec3<int>( x, 0, z ) );
-            generated->setBlockAt( zLeaveType->getId(), Framework::Vec3<int>( 0, x, z ) );
-            generated->setBlockAt( zLeaveType->getId(), Framework::Vec3<int>( x, 4, z ) );
-            generated->setBlockAt( zLeaveType->getId(), Framework::Vec3<int>( 4, x, z ) );
-            for( int y = 1; y < 4; y++ )
-                generated->setBlockAt( zLeaveType->getId(), Framework::Vec3<int>( x, y, z ) );
-        }
-    }
-    for( int i = 0; i < height - 1; i++ )
-        generated->setBlockAt( zWoodType->getId(), Framework::Vec3<int>( 2, 2, i ) );
-    return generated;
+	double noise = zNoise->getNoise((double)location.x + 40, (double)location.y + 70, (double)location.z - 20);
+	int height = (int)(minHeight + (noise * (maxHeight - minHeight)));
+	GeneratedStructure* generated = new GeneratedStructure(dynamic_cast<GenerationTemplate*>(getThis()), location, Framework::Vec3<int>(5, 5, height), Framework::Vec3<int>(-2, -2, 0) + location);
+	for (int x = 1; x < 4; x++)
+	{
+		for (int y = 1; y < 4; y++)
+		{
+			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, y, height - 1));
+			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, y, height - 5));
+		}
+	}
+	for (int z = height - 2; z >= height - 4; z--)
+	{
+		for (int x = 1; x < 4; x++)
+		{
+			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, 0, z));
+			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(0, x, z));
+			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, 4, z));
+			generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(4, x, z));
+			for (int y = 1; y < 4; y++)
+				generated->setBlockAt(zLeaveType->getId(), Framework::Vec3<int>(x, y, z));
+		}
+	}
+	for (int i = 0; i < height - 1; i++)
+		generated->setBlockAt(zWoodType->getId(), Framework::Vec3<int>(2, 2, i));
+	return generated;
 }

+ 6 - 6
FactoryCraft/TreeTemplate.h

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

+ 49 - 49
FactoryCraft/WorldGenerator.cpp

@@ -6,13 +6,13 @@
 
 using namespace Framework;
 
-WorldGenerator::WorldGenerator( int seed )
-    : Thread(),
-    exit( 0 ),
-    seed( seed )
+WorldGenerator::WorldGenerator(int seed)
+	: Thread(),
+	exit(0),
+	seed(seed)
 {
-    setName( "World Generator" );
-    start();
+	setName("World Generator");
+	start();
 }
 
 WorldGenerator::~WorldGenerator()
@@ -20,57 +20,57 @@ WorldGenerator::~WorldGenerator()
 
 void WorldGenerator::thread()
 {
-    while( !exit )
-    {
-        cs.lock();
-        Area next;
-        bool hasNext = 0;
-        if( requestQueue.getEintragAnzahl() > 0 )
-        {
-            next = requestQueue.get( 0 );
-            requestQueue.remove( 0 );
-            hasNext = 1;
-        }
-        cs.unlock();
-        if( !hasNext )
-        {
-            sleep( 1 );
-            continue;
-        }
-        Punkt start = Game::INSTANCE->getChunkCenter( next.startX, next.startY );
-        Punkt end = Game::INSTANCE->getChunkCenter( next.endX, next.endY );
-        int xDir = start.x > end.x ? -1 : 1;
-        int yDir = start.y > end.y ? -1 : 1;
-        for( int x = start.x; xDir < 0 ? x >= end.x : x <= end.x; x += CHUNK_SIZE * xDir )
-        {
-            for( int y = start.y; yDir < 0 ? y >= end.y : y <= end.y; y += CHUNK_SIZE * yDir )
-            {
-                if( !Game::INSTANCE->doesChunkExist( x, y, next.dimensionId ) )
-                {
-                    Chunk* generatedChunk = StaticRegistry<DimensionGenerator>::INSTANCE.zElement( next.dimensionId )->generateChunk( seed, x, y );
-                    generatedChunk->removeUnusedBlocks();
-                    Game::INSTANCE->requestWorldUpdate( new AddChunkUpdate( generatedChunk ) );
-                }
-            }
-        }
-    }
+	while (!exit)
+	{
+		cs.lock();
+		Area next;
+		bool hasNext = 0;
+		if (requestQueue.getEintragAnzahl() > 0)
+		{
+			next = requestQueue.get(0);
+			requestQueue.remove(0);
+			hasNext = 1;
+		}
+		cs.unlock();
+		if (!hasNext)
+		{
+			sleep(1);
+			continue;
+		}
+		Punkt start = Game::INSTANCE->getChunkCenter(next.startX, next.startY);
+		Punkt end = Game::INSTANCE->getChunkCenter(next.endX, next.endY);
+		int xDir = start.x > end.x ? -1 : 1;
+		int yDir = start.y > end.y ? -1 : 1;
+		for (int x = start.x; xDir < 0 ? x >= end.x : x <= end.x; x += CHUNK_SIZE * xDir)
+		{
+			for (int y = start.y; yDir < 0 ? y >= end.y : y <= end.y; y += CHUNK_SIZE * yDir)
+			{
+				if (!Game::INSTANCE->doesChunkExist(x, y, next.dimensionId))
+				{
+					Chunk* generatedChunk = StaticRegistry<DimensionGenerator>::INSTANCE.zElement(next.dimensionId)->generateChunk(seed, x, y);
+					generatedChunk->removeUnusedBlocks();
+					Game::INSTANCE->requestWorldUpdate(new AddChunkUpdate(generatedChunk));
+				}
+			}
+		}
+	}
 }
 
-void WorldGenerator::requestGeneration( Area request )
+void WorldGenerator::requestGeneration(Area request)
 {
-    cs.lock();
-    requestQueue.add( request );
-    cs.unlock();
+	cs.lock();
+	requestQueue.add(request);
+	cs.unlock();
 }
 
 void WorldGenerator::exitAndWait()
 {
-    exit = 1;
-    warteAufThread( 10000 );
-    ende();
+	exit = 1;
+	warteAufThread(10000);
+	ende();
 }
 
-Framework::Either<Block*, int> WorldGenerator::generateSingleBlock( Framework::Vec3<int> location, int dimensionId )
+Framework::Either<Block*, int> WorldGenerator::generateSingleBlock(Framework::Vec3<int> location, int dimensionId)
 {
-    return StaticRegistry<DimensionGenerator>::INSTANCE.zElement( dimensionId )->generateBlock( seed, location );
+	return StaticRegistry<DimensionGenerator>::INSTANCE.zElement(dimensionId)->generateBlock(seed, location);
 }

+ 10 - 10
FactoryCraft/WorldGenerator.h

@@ -10,16 +10,16 @@
 class WorldGenerator : public Framework::Thread
 {
 private:
-    Framework::Critical cs;
-    Framework::Array<Area> requestQueue;
-    bool exit;
-    int seed;
+	Framework::Critical cs;
+	Framework::Array<Area> requestQueue;
+	bool exit;
+	int seed;
 
 public:
-    WorldGenerator( int seed );
-    ~WorldGenerator();
-    void thread() override;
-    void requestGeneration( Area request );
-    void exitAndWait();
-    Framework::Either<Block*, int> generateSingleBlock( Framework::Vec3<int> location, int dimensionId );
+	WorldGenerator(int seed);
+	~WorldGenerator();
+	void thread() override;
+	void requestGeneration(Area request);
+	void exitAndWait();
+	Framework::Either<Block*, int> generateSingleBlock(Framework::Vec3<int> location, int dimensionId);
 };

+ 86 - 86
FactoryCraft/WorldLoader.cpp

@@ -8,34 +8,34 @@
 using namespace Framework;
 
 WorldLoader::WorldLoader()
-    : Thread(),
-    exit( 0 )
+	: Thread(),
+	exit(0)
 {
-    setName( "World Loader" );
-    Datei d;
-    d.setDatei( Game::INSTANCE->getWorldDirectory() + "/dim" );
-    RCArray<Text>* names = d.getDateiListe();
-    if( names )
-    {
-        for( Text* name : *names )
-        {
-            Datei entities;
-            entities.setDatei( Game::INSTANCE->getWorldDirectory() + "/dim/" + Text( name->getText() ) + "/entities" );
-            if( entities.open( Datei::Style::lesen ) )
-            {
-                Dimension* dim = new Dimension( *name );
-                while( !entities.istEnde() )
-                {
-                    int type = 0;
-                    entities.lese( (char*)&type, 4 );
-                    dim->addEntity( StaticRegistry<EntityType>::INSTANCE.zElement( type )->loadEntity( &entities ) );
-                }
-                Game::INSTANCE->addDimension( dim );
-            }
-        }
-        names->release();
-    }
-    start();
+	setName("World Loader");
+	Datei d;
+	d.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim");
+	RCArray<Text>* names = d.getDateiListe();
+	if (names)
+	{
+		for (Text* name : *names)
+		{
+			Datei entities;
+			entities.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim/" + Text(name->getText()) + "/entities");
+			if (entities.open(Datei::Style::lesen))
+			{
+				Dimension* dim = new Dimension(*name);
+				while (!entities.istEnde())
+				{
+					int type = 0;
+					entities.lese((char*)&type, 4);
+					dim->addEntity(StaticRegistry<EntityType>::INSTANCE.zElement(type)->loadEntity(&entities));
+				}
+				Game::INSTANCE->addDimension(dim);
+			}
+		}
+		names->release();
+	}
+	start();
 }
 
 WorldLoader::~WorldLoader()
@@ -43,73 +43,73 @@ WorldLoader::~WorldLoader()
 
 void WorldLoader::thread()
 {
-    while( !exit )
-    {
-        cs.lock();
-        Area next;
-        bool hasNext = 0;
-        if( requestQueue.getEintragAnzahl() > 0 )
-        {
-            next = requestQueue.get( 0 );
-            requestQueue.remove( 0 );
-            hasNext = 1;
-        }
-        cs.unlock();
-        if( !hasNext )
-        {
-            Sleep( 1000 );
-            continue;
-        }
-        Punkt start = Game::INSTANCE->getChunkCenter( next.startX, next.startY );
-        Punkt end = Game::INSTANCE->getChunkCenter( next.endX, next.endY );
-        int xDir = start.x > end.x ? -1 : 1;
-        int yDir = start.y > end.y ? -1 : 1;
-        for( int x = start.x; xDir < 0 ? x >= end.x : x <= end.x; x += CHUNK_SIZE * xDir )
-        {
-            for( int y = start.y; yDir < 0 ? y >= end.y : y <= end.y; y += CHUNK_SIZE * yDir )
-            {
-                if( !Game::INSTANCE->isChunkLoaded( x, y, next.dimensionId ) )
-                {
-                    Datei* file = new Datei();
-                    Text filePath = Game::INSTANCE->getWorldDirectory() + "/dim/" + next.dimensionId + "/";
-                    filePath.appendHex( x );
-                    filePath += "_";
-                    filePath.appendHex( y );
-                    filePath += ".chunk";
-                    file->setDatei( filePath );
-                    if( file->open( Datei::Style::lesen ) )
-                    {
-                        Chunk* chunk = new Chunk( Framework::Punkt( x, y ), next.dimensionId, file );
-                        Game::INSTANCE->requestWorldUpdate( new AddChunkUpdate( chunk ) );
-                    }
-                    file->close();
-                    file->release();
-                }
-            }
-        }
-    }
+	while (!exit)
+	{
+		cs.lock();
+		Area next;
+		bool hasNext = 0;
+		if (requestQueue.getEintragAnzahl() > 0)
+		{
+			next = requestQueue.get(0);
+			requestQueue.remove(0);
+			hasNext = 1;
+		}
+		cs.unlock();
+		if (!hasNext)
+		{
+			Sleep(1000);
+			continue;
+		}
+		Punkt start = Game::INSTANCE->getChunkCenter(next.startX, next.startY);
+		Punkt end = Game::INSTANCE->getChunkCenter(next.endX, next.endY);
+		int xDir = start.x > end.x ? -1 : 1;
+		int yDir = start.y > end.y ? -1 : 1;
+		for (int x = start.x; xDir < 0 ? x >= end.x : x <= end.x; x += CHUNK_SIZE * xDir)
+		{
+			for (int y = start.y; yDir < 0 ? y >= end.y : y <= end.y; y += CHUNK_SIZE * yDir)
+			{
+				if (!Game::INSTANCE->isChunkLoaded(x, y, next.dimensionId))
+				{
+					Datei* file = new Datei();
+					Text filePath = Game::INSTANCE->getWorldDirectory() + "/dim/" + next.dimensionId + "/";
+					filePath.appendHex(x);
+					filePath += "_";
+					filePath.appendHex(y);
+					filePath += ".chunk";
+					file->setDatei(filePath);
+					if (file->open(Datei::Style::lesen))
+					{
+						Chunk* chunk = new Chunk(Framework::Punkt(x, y), next.dimensionId, file);
+						Game::INSTANCE->requestWorldUpdate(new AddChunkUpdate(chunk));
+					}
+					file->close();
+					file->release();
+				}
+			}
+		}
+	}
 }
 
-void WorldLoader::requestLoading( Area request )
+void WorldLoader::requestLoading(Area request)
 {
-    cs.lock();
-    requestQueue.add( request );
-    cs.unlock();
+	cs.lock();
+	requestQueue.add(request);
+	cs.unlock();
 }
 
 void WorldLoader::exitAndWait()
 {
-    exit = 1;
-    warteAufThread( 10000 );
-    ende();
+	exit = 1;
+	warteAufThread(10000);
+	ende();
 }
 
-bool WorldLoader::existsChunk( int x, int y, int dimension ) const
+bool WorldLoader::existsChunk(int x, int y, int dimension) const
 {
-    Text filePath = Game::INSTANCE->getWorldDirectory() + "/dim/" + dimension + "/";
-    filePath.appendHex( x );
-    filePath += "_";
-    filePath.appendHex( y );
-    filePath += ".chunk";
-    return DateiExistiert( filePath );
+	Text filePath = Game::INSTANCE->getWorldDirectory() + "/dim/" + dimension + "/";
+	filePath.appendHex(x);
+	filePath += "_";
+	filePath.appendHex(y);
+	filePath += ".chunk";
+	return DateiExistiert(filePath);
 }

+ 9 - 9
FactoryCraft/WorldLoader.h

@@ -10,15 +10,15 @@
 class WorldLoader : public Framework::Thread
 {
 private:
-    Framework::Critical cs;
-    Framework::Array<Area> requestQueue;
-    bool exit;
+	Framework::Critical cs;
+	Framework::Array<Area> requestQueue;
+	bool exit;
 
 public:
-    WorldLoader();
-    ~WorldLoader();
-    void thread() override;
-    void requestLoading( Area request );
-    void exitAndWait();
-    bool existsChunk( int x, int y, int dimension ) const;
+	WorldLoader();
+	~WorldLoader();
+	void thread() override;
+	void requestLoading(Area request);
+	void exitAndWait();
+	bool existsChunk(int x, int y, int dimension) const;
 };

+ 25 - 25
FactoryCraft/WorldUpdate.cpp

@@ -1,54 +1,54 @@
 #include "WorldUpdate.h"
 
-WorldUpdate::WorldUpdate( int type, int dimensionId, Framework::Vec3<int> minAffected, Framework::Vec3<int> maxAffected )
-    : ReferenceCounter(),
-    affectedDimensionId( dimensionId ),
-    minAffected( minAffected ),
-    maxAffected( maxAffected ),
-    type( type )
+WorldUpdate::WorldUpdate(int type, int dimensionId, Framework::Vec3<int> minAffected, Framework::Vec3<int> maxAffected)
+	: ReferenceCounter(),
+	affectedDimensionId(dimensionId),
+	minAffected(minAffected),
+	maxAffected(maxAffected),
+	type(type)
 {}
 
-void WorldUpdate::writeAndCheck( Framework::StreamWriter* zWriter )
+void WorldUpdate::writeAndCheck(Framework::StreamWriter* zWriter)
 {
-    zWriter->schreibe( (char*)&type, 4 );
-    this->write( zWriter );
-    zWriter->schreibe( (char*)&type, 4 );
+	zWriter->schreibe((char*)&type, 4);
+	this->write(zWriter);
+	zWriter->schreibe((char*)&type, 4);
 }
 
 int WorldUpdate::getAffectedDimension() const
 {
-    return affectedDimensionId;
+	return affectedDimensionId;
 }
 
 const Framework::Vec3<int>& WorldUpdate::getMinAffectedPoint() const
 {
-    return minAffected;
+	return minAffected;
 }
 
 const Framework::Vec3<int>& WorldUpdate::getMaxAffectedPoint() const
 {
-    return maxAffected;
+	return maxAffected;
 }
 
 int WorldUpdate::getType() const
 {
-    return type;
+	return type;
 }
 
-int WorldUpdate::distanceTo( int x, int y ) const
+int WorldUpdate::distanceTo(int x, int y) const
 {
-    int xDist = MIN( abs( x - minAffected.x ), abs( x - maxAffected.x ) );
-    int yDist = MIN( abs( y - minAffected.y ), abs( y - maxAffected.y ) );
-    if( x >= minAffected.x && x <= maxAffected.x )
-        xDist = 0;
-    if( y >= minAffected.y && y <= maxAffected.y )
-        yDist = 0;
-    return MIN( xDist, yDist );
+	int xDist = MIN(abs(x - minAffected.x), abs(x - maxAffected.x));
+	int yDist = MIN(abs(y - minAffected.y), abs(y - maxAffected.y));
+	if (x >= minAffected.x && x <= maxAffected.x)
+		xDist = 0;
+	if (y >= minAffected.y && y <= maxAffected.y)
+		yDist = 0;
+	return MIN(xDist, yDist);
 }
 
 
-WorldUpdateType::WorldUpdateType( int id )
-    : ReferenceCounter()
+WorldUpdateType::WorldUpdateType(int id)
+	: ReferenceCounter()
 {
-    StaticRegistry<WorldUpdateType>::INSTANCE.registerT( this, id );
+	StaticRegistry<WorldUpdateType>::INSTANCE.registerT(this, id);
 }

+ 14 - 14
FactoryCraft/WorldUpdate.h

@@ -11,29 +11,29 @@ class Dimension;
 class WorldUpdate : public Framework::ReferenceCounter
 {
 private:
-    int affectedDimensionId;
-    Framework::Vec3<int> minAffected;
-    Framework::Vec3<int> maxAffected;
-    int type;
+	int affectedDimensionId;
+	Framework::Vec3<int> minAffected;
+	Framework::Vec3<int> maxAffected;
+	int type;
 
 protected:
-    virtual void write( Framework::StreamWriter* zWriter ) = 0;
+	virtual void write(Framework::StreamWriter* zWriter) = 0;
 
 public:
-    WorldUpdate( int type, int dimensionId, Framework::Vec3<int> minAffected, Framework::Vec3<int> maxAffected );
+	WorldUpdate(int type, int dimensionId, Framework::Vec3<int> minAffected, Framework::Vec3<int> maxAffected);
 
-    virtual void onUpdate( Dimension* zDimension ) = 0;
-    void writeAndCheck( Framework::StreamWriter* zWriter );
+	virtual void onUpdate(Dimension* zDimension) = 0;
+	void writeAndCheck(Framework::StreamWriter* zWriter);
 
-    int getAffectedDimension() const;
-    const Framework::Vec3<int>& getMinAffectedPoint() const;
-    const Framework::Vec3<int>& getMaxAffectedPoint() const;
-    int getType() const;
-    int distanceTo( int x, int y ) const;
+	int getAffectedDimension() const;
+	const Framework::Vec3<int>& getMinAffectedPoint() const;
+	const Framework::Vec3<int>& getMaxAffectedPoint() const;
+	int getType() const;
+	int distanceTo(int x, int y) const;
 };
 
 class WorldUpdateType : public Framework::ReferenceCounter
 {
 protected:
-    WorldUpdateType( int id );
+	WorldUpdateType(int id);
 };