Browse Source

finished basic implementation of the world

Kolja Strohm 3 years ago
parent
commit
ab42ad176e

+ 36 - 0
FactoryCraft/AddChunkUpdate.cpp

@@ -0,0 +1,36 @@
+#include "AddChunkUpdate.h"
+#include "Chunk.h"
+#include "Constants.h"
+#include "Dimension.h"
+
+
+AddChunkUpdate::AddChunkUpdate( Chunk *chunk )
+    : WorldUpdate( chunk->getDimensionId(), Framework::Vec3<int>( chunk->getCenter().x - CHUNK_SIZE / 2, chunk->getCenter().y - CHUNK_SIZE / 2, 0 ), Framework::Vec3<int>( chunk->getCenter().x + CHUNK_SIZE / 2, chunk->getCenter().y + CHUNK_SIZE / 2, WORLD_HEIGHT - 1 ) ),
+    chunk( chunk )
+{}
+
+AddChunkUpdate::~AddChunkUpdate()
+{
+    chunk->release();
+}
+
+void AddChunkUpdate::onUpdate( Dimension *zDimension )
+{
+    zDimension->addChunk( dynamic_cast<Chunk *>( chunk->getThis() ) );
+}
+
+void AddChunkUpdate::write( Framework::Writer *zWriter )
+{
+    zWriter->schreibe( (char *)&AddChunkUpdateType::ID, 4 );
+    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 );
+}
+
+
+AddChunkUpdateType::AddChunkUpdateType()
+    : WorldUpdateType( ID )
+{}

+ 11 - 1
FactoryCraft/AddChunkUpdate.h

@@ -15,4 +15,14 @@ public:
 
     void onUpdate( Dimension *zDimension ) override;
     void write( Framework::Writer *zWriter ) override;
-};
+};
+
+class AddChunkUpdateType : WorldUpdateType
+{
+    REGISTRABLE( AddChunkUpdateType )
+
+protected:
+    AddChunkUpdateType();
+};
+
+REGISTER( AddChunkUpdateType, WorldUpdateType )

+ 26 - 3
FactoryCraft/Chunk.cpp

@@ -17,6 +17,12 @@ Chunk::Chunk( Framework::Punkt location, Game *zGame, int dimensionId )
     zNeighbours[ 3 ] = 0;
 }
 
+Chunk::Chunk( Framework::Punkt location, Game *zGame, int dimensionId, Framework::Reader *zReader )
+    : Chunk( location, zGame, dimensionId )
+{
+    load( zReader );
+}
+
 Chunk::~Chunk()
 {
     for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
@@ -27,14 +33,21 @@ Chunk::~Chunk()
     delete[] blocks;
 }
 
-Block *Chunk::getBlockAt( Framework::Vec3<int> location )
+Block *Chunk::getBlockAt( Framework::Vec3<int> location ) const
 {
-    location.x -= this->location.x - CHUNK_SIZE / 2;
-    location.y -= this->location.x - CHUNK_SIZE / 2;
+    location.x += CHUNK_SIZE / 2;
+    location.y += CHUNK_SIZE / 2;
     Block *result = dynamic_cast<Block *>( blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ]->getThis() );
     return result;
 }
 
+Block *Chunk::zBlockAt( Framework::Vec3<int> location ) const
+{
+    location.x += CHUNK_SIZE / 2;
+    location.y += CHUNK_SIZE / 2;
+    return blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ];
+}
+
 void Chunk::putBlockAt( Framework::Vec3<int> location, Block *block )
 {
     location.x -= this->location.x - CHUNK_SIZE / 2;
@@ -140,4 +153,14 @@ void Chunk::save( Framework::Writer *zWriter )
 int Chunk::getDimensionId() const
 {
     return dimensionId;
+}
+
+Framework::Punkt Chunk::getCenter() const
+{
+    return location;
+}
+
+Game *Chunk::zGameObj() const
+{
+    return zGame;
 }

+ 4 - 1
FactoryCraft/Chunk.h

@@ -23,10 +23,13 @@ public:
     Chunk( Framework::Punkt location, Game *zGame, int dimensionId );
     Chunk( Framework::Punkt location, Game *zGame, int dimensionId, Framework::Reader *zReader );
     ~Chunk();
-    Block *getBlockAt( Framework::Vec3<int> location );
+    Block *getBlockAt( Framework::Vec3<int> cLocation ) const;
+    Block *zBlockAt( Framework::Vec3<int> cLocation ) const;
     void putBlockAt( Framework::Vec3<int> location, Block *block );
     void setNeighbor( Direction dir, Chunk *zChunk );
     void load( Framework::Reader *zReader );
     void save( Framework::Writer *zWriter );
     int getDimensionId() const;
+    Framework::Punkt getCenter() const;
+    Game *zGameObj() const;
 };

+ 73 - 0
FactoryCraft/Dimension.cpp

@@ -0,0 +1,73 @@
+#include "Dimension.h"
+#include "Constants.h"
+#include "Datei.h"
+#include "Game.h"
+
+using namespace Framework;
+
+
+Dimension::Dimension( int id )
+    : dimensionId( id ),
+    chunks( new Trie<Chunk>() )
+{}
+
+Dimension::~Dimension()
+{
+    chunks->release();
+}
+
+void Dimension::getAddrOf( Punkt cPos, char *addr )
+{
+    *(int *)addr = cPos.x;
+    *( (int *)addr + 1 ) = cPos.y;
+    addr[ 8 ] = 0;
+}
+
+void Dimension::getAddrOfWorld( Punkt wPos, char *addr )
+{
+    wPos.x = (int)floor( ( (float)wPos.x + CHUNK_SIZE / 2 ) / CHUNK_SIZE );
+    wPos.y = (int)floor( ( (float)wPos.y + CHUNK_SIZE / 2 ) / CHUNK_SIZE );
+    getAddrOf( wPos, addr );
+}
+
+Chunk *Dimension::zChunk( Punkt wPos )
+{
+    char addr[ 9 ];
+    getAddrOfWorld( wPos, addr );
+    return chunks->z( addr );
+}
+
+Block *Dimension::zBlock( Vec3<int> location )
+{
+    return zChunk( Punkt( location.x, location.y ) )->zBlockAt( Vec3<int>( ( location.x + CHUNK_SIZE / 2 ) % CHUNK_SIZE, ( location.y + CHUNK_SIZE / 2 ) % CHUNK_SIZE, location.z ) );
+}
+
+void Dimension::addChunk( Chunk *chunk )
+{
+    char addr[ 9 ];
+    getAddrOf( chunk->getCenter(), addr );
+    if( !chunks->z( addr ) )
+        chunks->set( addr, chunk );
+    else
+        chunk->release();
+}
+
+void Dimension::save( Framework::Writer *zWriter )
+{
+    for( auto chunk = chunks->getIterator(); chunk; chunk++ )
+    {
+        if( !chunk._ )
+            continue;
+        Datei *file = new Datei();
+        Text filePath = chunk->zGameObj()->getWorldDirectory() + "/dim/" + chunk->getDimensionId() + "/";
+        filePath.appendHex( chunk->getCenter().x );
+        filePath += "_";
+        filePath.appendHex( chunk->getCenter().y );
+        filePath += ".chunk";
+        file->setDatei( filePath );
+        if( file->open( Datei::Style::schreiben ) )
+            chunk->save( file );
+        file->close();
+        file->release();
+    }
+}

+ 8 - 0
FactoryCraft/Dimension.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include <Punkt.h>
+
 #include "Chunk.h"
 
 class Dimension : public virtual Framework::ReferenceCounter
@@ -7,9 +9,15 @@ class Dimension : public virtual Framework::ReferenceCounter
 private:
     int dimensionId;
     Framework::Trie<Chunk> *chunks;
+    void getAddrOf( Framework::Punkt cPos, char *addr );
+    void getAddrOfWorld( Framework::Punkt wPos, char *addr );
+    Chunk *zChunk( Framework::Punkt wPos );
 
 public:
     Dimension( int id );
+    ~Dimension();
 
     Block *zBlock( Framework::Vec3<int> location );
+    void addChunk( Chunk *chunk );
+    void save( Framework::Writer *zWriter );
 };

+ 2 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -139,6 +139,7 @@
     <ClInclude Include="WorldUpdate.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="AddChunkUpdate.cpp" />
     <ClCompile Include="BasicBlock.cpp" />
     <ClCompile Include="BasicInterpolator.cpp" />
     <ClCompile Include="BiomGenerator.cpp" />
@@ -146,6 +147,7 @@
     <ClCompile Include="BlockType.cpp" />
     <ClCompile Include="Chunk.cpp" />
     <ClCompile Include="Datenbank.cpp" />
+    <ClCompile Include="Dimension.cpp" />
     <ClCompile Include="DimensionGenerator.cpp" />
     <ClCompile Include="GrasslandBiom.cpp" />
     <ClCompile Include="Item.cpp" />

+ 6 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -266,5 +266,11 @@
     <ClCompile Include="WorldUpdate.cpp">
       <Filter>world\update</Filter>
     </ClCompile>
+    <ClCompile Include="Dimension.cpp">
+      <Filter>world</Filter>
+    </ClCompile>
+    <ClCompile Include="AddChunkUpdate.cpp">
+      <Filter>world\update</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 1
FactoryCraft/Game.h

@@ -30,7 +30,7 @@ public:
     bool doesChunkExist( int x, int y, int dimension ) const;
     Block *zBlockAt( Framework::Vec3<int> location, int dimension ) const;
     Framework::Punkt getChunkCenter( int x, int y ) const;
-    Text getWorldDirectory() const;
+    Framework::Text getWorldDirectory() const;
     void requestArea( Area area );
     void save();
 };

+ 3 - 1
FactoryCraft/StaticInitializerOrder.cpp

@@ -5,11 +5,13 @@
 int count_DimensionGenerator = 0;
 int count_ItemType = 0;
 int count_BlockType = 0;
+int count_WorldUpdateType = 0;
 
+#undef REGISTER
 #define REGISTER(c, typ)               \
 const int c::ID = count_##typ++;       \
 const c *c::INSTANCE = new c(); 
 
 #include "BasicBlocks.h"
 #include "OverworldDimension.h"
-
+#include "AddChunkUpdate.h"

+ 7 - 0
FactoryCraft/WorldUpdate.cpp

@@ -21,3 +21,10 @@ const Framework::Vec3<int> &WorldUpdate::getMaxAffectedPoint() const
 {
     return maxAffected;
 }
+
+
+WorldUpdateType::WorldUpdateType( int id )
+    : ReferenceCounter()
+{
+    StaticRegistry<WorldUpdateType>::INSTANCE.registerT( this, id );
+}

+ 7 - 0
FactoryCraft/WorldUpdate.h

@@ -4,6 +4,8 @@
 #include <Vec3.h>
 #include <Writer.h>
 
+#include "StaticRegistry.h"
+
 class Dimension;
 
 class WorldUpdate : public Framework::ReferenceCounter
@@ -24,3 +26,8 @@ public:
     const Framework::Vec3<int> &getMaxAffectedPoint() const;
 };
 
+class WorldUpdateType : public Framework::ReferenceCounter
+{
+protected:
+    WorldUpdateType( int id );
+};