فهرست منبع

blocks can now be destroyed by the player

Kolja Strohm 3 سال پیش
والد
کامیت
efcb869199

+ 1 - 1
FactoryCraft/AddChunkUpdate.cpp

@@ -21,7 +21,7 @@ void AddChunkUpdate::onUpdate( Dimension* zDimension )
 
 void AddChunkUpdate::write( Framework::StreamWriter* zWriter )
 {
-    zWriter->schreibe( (char*)&AddChunkUpdateType::ID, 4 );
+    WorldUpdate::write( zWriter );
     int dimensionID = chunk->getDimensionId();
     zWriter->schreibe( (char*)&dimensionID, 4 );
     Framework::Punkt center = chunk->getCenter();

+ 24 - 7
FactoryCraft/Block.cpp

@@ -3,6 +3,8 @@
 #include "NoBlock.h"
 #include "Game.h"
 #include "BlockChangedUpdate.h"
+#include "PlaceBlockUpdate.h"
+#include "BlockRemovedUpdate.h"
 
 Block::Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory )
     : Inventory( pos, hasInventory )
@@ -22,7 +24,7 @@ Block::Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos,
     maxTickTimeout = -1;
     tickSource = 0;
     currentTickTimeout = 0;
-    dimansionId = 0;
+    dimensionId = 0;
     interactable = 0;
     memset( zNeighbours, 0, sizeof( Block* ) * 6 );
 }
@@ -94,7 +96,7 @@ void Block::setNeighbourType( Direction dir, int type )
 
 void Block::setDimensionId( int id )
 {
-    dimansionId = id;
+    dimensionId = id;
 }
 
 void api( Framework::StreamReader* zRequest, NetworkResponse* zResponse )
@@ -154,12 +156,12 @@ float Block::getSpeedModifier() const
 
 const Framework::Vec3<int> Block::getPos() const
 {
-    return location;
+    return (Framework::Vec3<int>)location;
 }
 
 int Block::getDimensionId() const
 {
-    return dimansionId;
+    return dimensionId;
 }
 
 bool Block::isVisible() const
@@ -177,8 +179,23 @@ bool Block::isVisible() const
 
 void Block::setHP( float hp )
 {
-    this->hp = MAX( 0, hp );
-    requestTransmission();
+    bool isDead = this->hp == 0.f;
+    this->hp = MAX( 0.f, hp );
+    if( !isDead && this->hp == 0.f )
+    {
+        for( int i = 0; i < 6; i++ )
+        {
+            if( neighbourTypes[ i ] == NoBlockBlockType::ID )
+            {
+                Framework::Vec3<int> pos = getPos() + getDirection( getDirectionFromIndex( i ) );
+                Game::INSTANCE->requestWorldUpdate( new PlaceBlockUpdate( Game::INSTANCE->zGenerator()->generateSingleBlock( pos, dimensionId ), pos, dimensionId ) );
+            }
+        }
+        Game::INSTANCE->requestWorldUpdate( new BlockRemovedUpdate( getPos(), dimensionId ) );
+        // TODO: generate item stacks and drop them
+    }
+    else
+        requestTransmission();
 }
 
 void Block::onAfterTransmission()
@@ -191,7 +208,7 @@ void Block::requestTransmission()
     if( !transmissionRequested )
     {
         transmissionRequested = 1;
-        Game::INSTANCE->requestWorldUpdate( new BlockChangedUpdate( (Framework::Vec3<int>)location, getDimensionId() ) );
+        Game::INSTANCE->requestWorldUpdate( new BlockChangedUpdate( getPos(), getDimensionId() ) );
     }
 }
 

+ 1 - 1
FactoryCraft/Block.h

@@ -25,7 +25,7 @@ private:
     int currentTickTimeout;
     bool wasTicked;
     bool onTickCalled;
-    int dimansionId;
+    int dimensionId;
 
 protected:
     bool transparent;

+ 1 - 1
FactoryCraft/BlockChangedUpdate.cpp

@@ -18,7 +18,7 @@ void BlockChangedUpdate::onUpdate( Dimension* zDimension )
 
 void BlockChangedUpdate::write( Framework::StreamWriter* zWriter )
 {
-    zWriter->schreibe( (char*)&BlockChangedUpdateType::ID, 4 );
+    WorldUpdate::write( zWriter );
     int dimensionID = getAffectedDimension();
     zWriter->schreibe( (char*)&dimensionID, 4 );
     auto pos = getMinAffectedPoint();

+ 32 - 0
FactoryCraft/BlockRemovedUpdate.cpp

@@ -0,0 +1,32 @@
+#include "BlockRemovedUpdate.h"
+#include "Dimension.h"
+#include "NoBlock.h"
+
+
+BlockRemovedUpdate::BlockRemovedUpdate( Framework::Vec3<int> pos, int dimension )
+    : WorldUpdate( BlockRemovedUpdateType::ID, dimension, pos, pos )
+{}
+
+BlockRemovedUpdate::~BlockRemovedUpdate()
+{}
+
+void BlockRemovedUpdate::onUpdate( Dimension* zDimension )
+{
+    zDimension->placeBlock( getMaxAffectedPoint(), AirBlockBlockType::ID );
+}
+
+void BlockRemovedUpdate::write( Framework::StreamWriter* zWriter )
+{
+    WorldUpdate::write( 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 );
+}
+
+
+BlockRemovedUpdateType::BlockRemovedUpdateType()
+    : WorldUpdateType( ID )
+{}

+ 22 - 0
FactoryCraft/BlockRemovedUpdate.h

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

+ 13 - 7
FactoryCraft/Dimension.cpp

@@ -101,21 +101,27 @@ Block* Dimension::zRealBlockInstance( Framework::Vec3<int> location )
     return 0;
 }
 
-void Dimension::placeBlock( Block* block )
+void Dimension::placeBlock( Framework::Vec3<int> location, Framework::Either<Block*, int> block )
 {
-    Chunk* c = zChunk( Game::getChunkCenter( block->getPos().x, block->getPos().y ) );
+    Chunk* c = zChunk( Game::getChunkCenter( location.x, location.y ) );
     if( c )
     {
-        int x = block->getPos().x % CHUNK_SIZE;
-        int y = block->getPos().y % CHUNK_SIZE;
+        int x = location.x % CHUNK_SIZE;
+        int y = location.y % CHUNK_SIZE;
         if( x < 0 )
             x += CHUNK_SIZE;
         if( y < 0 )
             y += CHUNK_SIZE;
-        c->putBlockAt( block->getPos(), block );
+        if( block.isA() )
+            c->putBlockAt( location, block );
+        else
+        {
+            c->putBlockAt( location, 0 );
+            c->putBlockTypeAt( location, block );
+        }
     }
-    else
-        block->release();
+    else if( block.isA() )
+        block.getA()->release();
 }
 
 void Dimension::addEntity( Entity* entity )

+ 1 - 1
FactoryCraft/Dimension.h

@@ -26,7 +26,7 @@ public:
 
     Framework::Either<Block*, int> zBlock( Framework::Vec3<int> location );
     Block* zRealBlockInstance( Framework::Vec3<int> location );
-    void placeBlock( Block* block );
+    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;

+ 1 - 1
FactoryCraft/Entity.cpp

@@ -35,7 +35,7 @@ void ActionTarget::placeBlock( Entity* zActor, Item* zItem )
     Block* block = zItem->zPlacedBlockType()->createBlockAt( blockPos + getDirection( targetBlockSide ), zItem );
     if( block )
     {
-        if( Game::INSTANCE->requestWorldUpdate( new PlaceBlockUpdate( block, zActor->getCurrentDimensionId() ) ) )
+        if( Game::INSTANCE->requestWorldUpdate( new PlaceBlockUpdate( block, block->getPos(), zActor->getCurrentDimensionId() ) ) )
         {
             zItem->onPlaced();
             // TODO: decrese stamina of actor

+ 2 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -99,6 +99,7 @@
     <ClInclude Include="BiomGenerator.h" />
     <ClInclude Include="Block.h" />
     <ClInclude Include="BlockChangedUpdate.h" />
+    <ClInclude Include="BlockRemovedUpdate.h" />
     <ClInclude Include="BlockType.h" />
     <ClInclude Include="Chunk.h" />
     <ClInclude Include="Constants.h" />
@@ -144,6 +145,7 @@
     <ClCompile Include="BiomGenerator.cpp" />
     <ClCompile Include="Block.cpp" />
     <ClCompile Include="BlockChangedUpdate.cpp" />
+    <ClCompile Include="BlockRemovedUpdate.cpp" />
     <ClCompile Include="BlockType.cpp" />
     <ClCompile Include="Chunk.cpp" />
     <ClCompile Include="Dimension.cpp" />

+ 6 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -186,6 +186,9 @@
     <ClInclude Include="BlockChangedUpdate.h">
       <Filter>world\update</Filter>
     </ClInclude>
+    <ClInclude Include="BlockRemovedUpdate.h">
+      <Filter>world\update</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -308,5 +311,8 @@
     <ClCompile Include="BlockChangedUpdate.cpp">
       <Filter>world\update</Filter>
     </ClCompile>
+    <ClCompile Include="BlockRemovedUpdate.cpp">
+      <Filter>world\update</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 1
FactoryCraft/Game.cpp

@@ -378,7 +378,7 @@ bool Game::requestWorldUpdate( WorldUpdate* update )
     {
         if( u->getMaxAffectedPoint().x >= update->getMinAffectedPoint().x && u->getMinAffectedPoint().x <= update->getMaxAffectedPoint().x &&
             u->getMaxAffectedPoint().y >= update->getMinAffectedPoint().y && u->getMinAffectedPoint().y <= update->getMaxAffectedPoint().y &&
-            u->getMaxAffectedPoint().z >= update->getMinAffectedPoint().z && u->getMinAffectedPoint().z <= update->getMaxAffectedPoint().z )
+            u->getMaxAffectedPoint().z >= update->getMinAffectedPoint().z && u->getMinAffectedPoint().z <= update->getMaxAffectedPoint().z && u->getType() == update->getType() )
         {
             cs.unlock();
             update->release();

+ 22 - 9
FactoryCraft/PlaceBlockUpdate.cpp

@@ -3,33 +3,46 @@
 #include "Dimension.h"
 
 
-PlaceBlockUpdate::PlaceBlockUpdate( Block* block, int dimensionId )
-    : WorldUpdate( PlaceBlockUpdateType::ID, dimensionId, block->getPos(), block->getPos() ),
+PlaceBlockUpdate::PlaceBlockUpdate( Framework::Either<Block*, int> block, Framework::Vec3<int> location, int dimensionId )
+    : WorldUpdate( PlaceBlockUpdateType::ID, dimensionId, location, location ),
     block( block )
 {}
 
 PlaceBlockUpdate::~PlaceBlockUpdate()
 {
-    block->release();
+    if( block.isA() )
+        block.getA()->release();
 }
 
 void PlaceBlockUpdate::onUpdate( Dimension* zDimension )
 {
-    zDimension->placeBlock( dynamic_cast<Block*>(block->getThis()) );
+    if( block.isA() )
+        block.getA()->getThis();
+    zDimension->placeBlock( getMaxAffectedPoint(), block );
 }
 
 void PlaceBlockUpdate::write( Framework::StreamWriter* zWriter )
 {
-    zWriter->schreibe( (char*)&PlaceBlockUpdateType::ID, 4 );
+    WorldUpdate::write( zWriter );
     int dimensionID = getAffectedDimension();
     zWriter->schreibe( (char*)&dimensionID, 4 );
-    auto pos = block->getPos();
+    auto pos = getMinAffectedPoint();
     zWriter->schreibe( (char*)&pos.x, 4 );
     zWriter->schreibe( (char*)&pos.y, 4 );
     zWriter->schreibe( (char*)&pos.z, 4 );
-    unsigned char id = (unsigned char)block->zBlockType()->getId();
-    zWriter->schreibe( (char*)&id, 2 );
-    block->zBlockType()->saveBlock( block, zWriter );
+    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 );
+    }
 }
 
 Block* PlaceBlockUpdate::zBlock() const

+ 4 - 2
FactoryCraft/PlaceBlockUpdate.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include <Either.h>
+#include <Vec3.h>
 #include "WorldUpdate.h"
 
 class Block;
@@ -7,10 +9,10 @@ class Block;
 class PlaceBlockUpdate : public WorldUpdate
 {
 private:
-    Block* block;
+    Framework::Either<Block*, int> block;
 
 public:
-    PlaceBlockUpdate( Block* block, int dimensionId );
+    PlaceBlockUpdate( Framework::Either<Block*, int> block, Framework::Vec3<int> location, int dimensionId );
     ~PlaceBlockUpdate();
 
     void onUpdate( Dimension* zDimension ) override;

+ 9 - 3
FactoryCraft/StaticInitializerOrder.cpp

@@ -15,11 +15,17 @@ const c *c::INSTANCE = new c();
 
 // order of includes determines the ids
 
+// block types
 #include "NoBlock.h" // must be first
 #include "BasicBlocks.h"
+// dimensions
 #include "OverworldDimension.h"
-#include "AddChunkUpdate.h"
+// entities
 #include "Player.h"
-#include "PlaceBlockUpdate.h"
+// item skills
 #include "PlayerHand.h"
-#include "BlockChangedUpdate.h"
+// world updates
+#include "AddChunkUpdate.h"
+#include "PlaceBlockUpdate.h"
+#include "BlockChangedUpdate.h"
+#include "BlockRemovedUpdate.h"

+ 5 - 0
FactoryCraft/WorldUpdate.cpp

@@ -8,6 +8,11 @@ WorldUpdate::WorldUpdate( int type, int dimensionId, Framework::Vec3<int> minAff
     type( type )
 {}
 
+void WorldUpdate::write( Framework::StreamWriter* zWriter )
+{
+    zWriter->schreibe( (char*)&type, 4 );
+}
+
 int WorldUpdate::getAffectedDimension() const
 {
     return affectedDimensionId;

+ 1 - 1
FactoryCraft/WorldUpdate.h

@@ -20,7 +20,7 @@ public:
     WorldUpdate( int type, int dimensionId, Framework::Vec3<int> minAffected, Framework::Vec3<int> maxAffected );
 
     virtual void onUpdate( Dimension* zDimension ) = 0;
-    virtual void write( Framework::StreamWriter* zWriter ) = 0;
+    virtual void write( Framework::StreamWriter* zWriter );
 
     int getAffectedDimension() const;
     const Framework::Vec3<int>& getMinAffectedPoint() const;