Browse Source

fix tree leaves not spawning behind removed leaves

Kolja Strohm 1 year ago
parent
commit
b6dbff17e7

+ 6 - 2
FactoryCraft/Block.cpp

@@ -43,15 +43,19 @@ void Block::onDestroy()
     {
     {
         for (int i = 0; i < 6; i++)
         for (int i = 0; i < 6; i++)
         {
         {
+            Framework::Vec3<int> pos
+                = getPos() + getDirection(getDirectionFromIndex(i));
             if (neighbourTypes[i] == BlockTypeEnum::NO_BLOCK)
             if (neighbourTypes[i] == BlockTypeEnum::NO_BLOCK)
             {
             {
-                Framework::Vec3<int> pos
-                    = getPos() + getDirection(getDirectionFromIndex(i));
                 Game::INSTANCE->zDimension(dimensionId)
                 Game::INSTANCE->zDimension(dimensionId)
                     ->placeBlock(pos,
                     ->placeBlock(pos,
                         Game::INSTANCE->zGenerator()->generateSingleBlock(
                         Game::INSTANCE->zGenerator()->generateSingleBlock(
                             pos, dimensionId));
                             pos, dimensionId));
             }
             }
+            else
+            {
+                Game::INSTANCE->zDimension(dimensionId)->sendBlockInfo(pos);
+            }
         }
         }
         Item* blockItem = zBlockType()->getItemFromBlock(this);
         Item* blockItem = zBlockType()->getItemFromBlock(this);
         if (blockItem)
         if (blockItem)

+ 5 - 2
FactoryCraft/BlockType.cpp

@@ -60,8 +60,11 @@ void BlockType::loadSuperBlock(
         zReader->lese((char*)&id, 8);
         zReader->lese((char*)&id, 8);
         MultiblockStructure* str
         MultiblockStructure* str
             = Game::INSTANCE->zDimension(dimensionId)->zStructureById(id);
             = Game::INSTANCE->zDimension(dimensionId)->zStructureById(id);
-        zBlock->structures.add(
-            dynamic_cast<MultiblockStructure*>(str->getThis()));
+        if (str)
+        {
+            zBlock->structures.add(
+                dynamic_cast<MultiblockStructure*>(str->getThis()));
+        }
     }
     }
 }
 }
 
 

+ 87 - 100
FactoryCraft/Chunk.cpp

@@ -46,6 +46,16 @@ Chunk::~Chunk()
     delete[] lightData;
     delete[] lightData;
 }
 }
 
 
+void Chunk::lock()
+{
+    cs.lock();
+}
+
+void Chunk::unlock()
+{
+    cs.unlock();
+}
+
 void Chunk::tick(TickQueue* zQueue)
 void Chunk::tick(TickQueue* zQueue)
 {
 {
     for (Block* source : tickSources)
     for (Block* source : tickSources)
@@ -192,10 +202,10 @@ void Chunk::broadcastLightData(int index, bool foreground)
     msg->addressDimension(Game::INSTANCE->zDimension(dimensionId));
     msg->addressDimension(Game::INSTANCE->zDimension(dimensionId));
     char* message = new char[19];
     char* message = new char[19];
     message[0] = 5;
     message[0] = 5;
-    *(int*)(message + 1) = x;
-    *(int*)(message + 5) = y;
+    *(int*)(message + 1) = x + this->location.x - CHUNK_SIZE / 2;
+    *(int*)(message + 5) = y + this->location.y - CHUNK_SIZE / 2;
     *(int*)(message + 9) = z;
     *(int*)(message + 9) = z;
-    memcpy(message + 13, lightData + index, 6);
+    memcpy(message + 13, lightData + index * 6, 6);
     msg->setMessage(message, 19);
     msg->setMessage(message, 19);
     if (!foreground) msg->setUseBackground();
     if (!foreground) msg->setUseBackground();
     notifyObservers(msg);
     notifyObservers(msg);
@@ -469,6 +479,10 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
     }
     }
     else
     else
     {
     {
+        if (old != 0)
+        {
+            blockIds[index] = BlockTypeEnum::NO_BLOCK;
+        }
         change = old != 0;
         change = old != 0;
     }
     }
     blocks[index] = block;
     blocks[index] = block;
@@ -478,7 +492,18 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
         Either<Block*, int> neighbor
         Either<Block*, int> neighbor
             = zBlockNeighbor(location + getDirection(d));
             = zBlockNeighbor(location + getDirection(d));
         if (neighbor.isA())
         if (neighbor.isA())
-            ((Block*)neighbor)->setNeighbour(getOppositeDirection(d), block);
+        {
+            if (block)
+            {
+                ((Block*)neighbor)
+                    ->setNeighbour(getOppositeDirection(d), block);
+            }
+            else
+            {
+                ((Block*)neighbor)
+                    ->setNeighbour(getOppositeDirection(d), blockIds[index]);
+            }
+        }
         if (block) block->setNeighbour(d, neighbor);
         if (block) block->setNeighbour(d, neighbor);
     }
     }
     if (old) old->release();
     if (old) old->release();
@@ -497,55 +522,14 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
         }
         }
         if (added)
         if (added)
         {
         {
-            char* msg = new char[9];
-            msg[0] = 0; // set block
-            *(int*)(msg + 1) = index;
-            *(int*)(msg + 5) = block ? block->zBlockType()->getId()
-                                     : BlockTypeEnum::NO_BLOCK;
-            NetworkMessage* message = new NetworkMessage();
-            message->addressChunck(this);
-            message->setMessage(msg, 9);
-            notifyObservers(message);
-            for (int i = 0; i < 6; i++)
+            sendBlockInfo(location);
+            if (block)
             {
             {
-                Direction d = getDirectionFromIndex(i);
-                Framework::Vec3<int> loc = location + getDirection(d);
-                if (loc.x >= 0 && loc.x < CHUNK_SIZE && loc.y >= 0
-                    && loc.y < CHUNK_SIZE && loc.z >= 0 && loc.z < WORLD_HEIGHT)
-                {
-                    NetworkMessage* msg = new NetworkMessage();
-                    msg->addressChunck(this);
-                    char* message = new char[11];
-                    message[0] = 1;
-                    int index
-                        = ((loc.x * CHUNK_SIZE + loc.y) * WORLD_HEIGHT + loc.z)
-                        * 6;
-                    *(int*)(message + 1) = index / 6;
-                    memcpy(message + 5, lightData + index, 6);
-                    msg->setMessage(message, 11);
-                    notifyObservers(msg);
-                }
-                else if (loc.z >= 0 && loc.z < WORLD_HEIGHT && i < 4
-                         && zNeighbours[i])
-                {
-                    NetworkMessage* msg = new NetworkMessage();
-                    msg->addressChunck(zNeighbours[i]);
-                    char* message = new char[11];
-                    message[0] = 1;
-                    loc -= getDirection(d) * CHUNK_SIZE;
-                    int index
-                        = ((loc.x * CHUNK_SIZE + loc.y) * WORLD_HEIGHT + loc.z)
-                        * 6;
-                    *(int*)(message + 1) = index / 6;
-                    memcpy(message + 5, zNeighbours[i]->getLightData(loc), 6);
-                    msg->setMessage(message, 11);
-                    notifyObservers(msg);
-                }
+                Game::INSTANCE->updateLightningWithoutWait(getDimensionId(),
+                    Vec3<int>(location.x + this->location.x - CHUNK_SIZE / 2,
+                        location.y + this->location.y - CHUNK_SIZE / 2,
+                        location.z));
             }
             }
-            Game::INSTANCE->updateLightningWithoutWait(getDimensionId(),
-                Vec3<int>(location.x + this->location.x - CHUNK_SIZE / 2,
-                    location.y + this->location.y - CHUNK_SIZE / 2,
-                    location.z));
         }
         }
     }
     }
 }
 }
@@ -581,50 +565,7 @@ void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
         }
         }
         if (added)
         if (added)
         {
         {
-            char* msg = new char[9];
-            msg[0] = 0; // set block
-            *(int*)(msg + 1) = index;
-            *(int*)(msg + 5) = type;
-            NetworkMessage* message = new NetworkMessage();
-            message->addressChunck(this);
-            message->setMessage(msg, 9);
-            notifyObservers(message);
-            for (int i = 0; i < 6; i++)
-            {
-                Direction d = getDirectionFromIndex(i);
-                Framework::Vec3<int> loc = location + getDirection(d);
-                if (loc.x >= 0 && loc.x < CHUNK_SIZE && loc.y >= 0
-                    && loc.y < CHUNK_SIZE && loc.z >= 0 && loc.z < WORLD_HEIGHT)
-                {
-                    NetworkMessage* msg = new NetworkMessage();
-                    msg->addressChunck(this);
-                    char* message = new char[11];
-                    message[0] = 1;
-                    int index
-                        = ((loc.x * CHUNK_SIZE + loc.y) * WORLD_HEIGHT + loc.z)
-                        * 6;
-                    *(int*)(message + 1) = index / 6;
-                    memcpy(message + 5, lightData + index, 6);
-                    msg->setMessage(message, 11);
-                    notifyObservers(msg);
-                }
-                else if (loc.z >= 0 && loc.z < WORLD_HEIGHT && i < 4
-                         && zNeighbours[i])
-                {
-                    NetworkMessage* msg = new NetworkMessage();
-                    msg->addressChunck(zNeighbours[i]);
-                    char* message = new char[11];
-                    message[0] = 1;
-                    loc -= getDirection(d) * CHUNK_SIZE;
-                    int index
-                        = ((loc.x * CHUNK_SIZE + loc.y) * WORLD_HEIGHT + loc.z)
-                        * 6;
-                    *(int*)(message + 1) = index / 6;
-                    memcpy(message + 5, zNeighbours[i]->getLightData(loc), 6);
-                    msg->setMessage(message, 11);
-                    notifyObservers(msg);
-                }
-            }
+            sendBlockInfo(location);
             Game::INSTANCE->updateLightningWithoutWait(getDimensionId(),
             Game::INSTANCE->updateLightningWithoutWait(getDimensionId(),
                 Vec3<int>(location.x + this->location.x - CHUNK_SIZE / 2,
                 Vec3<int>(location.x + this->location.x - CHUNK_SIZE / 2,
                     location.y + this->location.y - CHUNK_SIZE / 2,
                     location.y + this->location.y - CHUNK_SIZE / 2,
@@ -633,6 +574,46 @@ void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
     }
     }
 }
 }
 
 
+void Chunk::sendBlockInfo(Framework::Vec3<int> location)
+{
+    int index
+        = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z;
+    char* msg = new char[9];
+    msg[0] = 0; // set block
+    *(int*)(msg + 1) = index;
+    *(int*)(msg + 5) = blockIds[index];
+    NetworkMessage* message = new NetworkMessage();
+    message->addressChunck(this);
+    message->setMessage(msg, 9);
+    notifyObservers(message);
+    for (int i = 0; i < 6; i++)
+    {
+        Direction d = getDirectionFromIndex(i);
+        Framework::Vec3<int> loc = location + getDirection(d);
+        if (loc.x >= 0 && loc.x < CHUNK_SIZE && loc.y >= 0 && loc.y < CHUNK_SIZE
+            && loc.z >= 0 && loc.z < WORLD_HEIGHT)
+        {
+            int index
+                = (loc.x * CHUNK_SIZE + loc.y) * WORLD_HEIGHT + loc.z;
+            broadcastLightData(index, true);
+        }
+        else if (loc.z >= 0 && loc.z < WORLD_HEIGHT && i < 4 && zNeighbours[i])
+        {
+            NetworkMessage* msg = new NetworkMessage();
+            msg->addressDimension(Game::INSTANCE->zDimension(dimensionId));
+            char* message = new char[19];
+            message[0] = 5;
+            *(int*)(message + 1) = loc.x + this->location.x - CHUNK_SIZE / 2;
+            *(int*)(message + 5) = loc.y + this->location.y - CHUNK_SIZE / 2;
+            *(int*)(message + 9) = loc.z;
+            loc -= getDirection(d) * CHUNK_SIZE;
+            memcpy(message + 13, zNeighbours[i]->getLightData(loc), 6);
+            msg->setMessage(message, 19);
+            notifyObservers(msg);
+        }
+    }
+}
+
 void Chunk::setNeighbor(Direction dir, Chunk* zChunk)
 void Chunk::setNeighbor(Direction dir, Chunk* zChunk)
 {
 {
     zNeighbours[getDirectionIndex(dir)] = zChunk;
     zNeighbours[getDirectionIndex(dir)] = zChunk;
@@ -785,10 +766,12 @@ void Chunk::sendToClient(Framework::StreamWriter* zWriter)
                             {
                             {
                                 for (int d = 0; d < 6 && !visible; d++)
                                 for (int d = 0; d < 6 && !visible; d++)
                                 {
                                 {
-                                    auto n = zBlockNeighbor(
-                                        getDirection((
-                                            Directions)getDirectionFromIndex(d))
-                                        + Framework::Vec3<int>(x, y, z));
+                                    Vec3<int> pos
+                                        = getDirection(
+                                              (Directions)getDirectionFromIndex(
+                                                  d))
+                                        + Framework::Vec3<int>(x, y, z);
+                                    auto n = zBlockNeighbor(pos);
                                     if (n.isA()
                                     if (n.isA()
                                         && (((Block*)n)->isPassable()
                                         && (((Block*)n)->isPassable()
                                             || ((Block*)n)->isTransparent()))
                                             || ((Block*)n)->isTransparent()))
@@ -797,6 +780,11 @@ void Chunk::sendToClient(Framework::StreamWriter* zWriter)
                                         && (CONST_BLOCK(0, n)->isTransparent()
                                         && (CONST_BLOCK(0, n)->isTransparent()
                                             || CONST_BLOCK(0, n)->isPassable()))
                                             || CONST_BLOCK(0, n)->isPassable()))
                                         visible = 1;
                                         visible = 1;
+                                    if (pos.x < 0 || pos.y < 0 || pos.z < 0
+                                        || pos.x >= CHUNK_SIZE
+                                        || pos.y >= CHUNK_SIZE
+                                        || pos.z >= WORLD_HEIGHT)
+                                        visible = 1;
                                 }
                                 }
                             }
                             }
                         }
                         }
@@ -850,7 +838,6 @@ void Chunk::removeUnusedBlocks()
             if (!visible)
             if (!visible)
             {
             {
                 putBlockAt({x, y, z}, 0);
                 putBlockAt({x, y, z}, 0);
-                putBlockTypeAt({x, y, z}, BlockTypeEnum::NO_BLOCK);
             }
             }
         }
         }
     }
     }

+ 4 - 0
FactoryCraft/Chunk.h

@@ -40,6 +40,9 @@ public:
         Framework::StreamReader* zReader);
         Framework::StreamReader* zReader);
     ~Chunk();
     ~Chunk();
 
 
+    void lock();
+    void unlock();
+
     void tick(TickQueue* zQueue) override;
     void tick(TickQueue* zQueue) override;
     void postTick() override;
     void postTick() override;
 	
 	
@@ -58,6 +61,7 @@ public:
     void generateBlock(Framework::Vec3<int> location);
     void generateBlock(Framework::Vec3<int> location);
     void putBlockAt(Framework::Vec3<int> location, Block* block);
     void putBlockAt(Framework::Vec3<int> location, Block* block);
     void putBlockTypeAt(Framework::Vec3<int> location, int type);
     void putBlockTypeAt(Framework::Vec3<int> location, int type);
+    void sendBlockInfo(Framework::Vec3<int> location);
     void setNeighbor(Direction dir, Chunk* zChunk);
     void setNeighbor(Direction dir, Chunk* zChunk);
     void load(Framework::StreamReader* zReader);
     void load(Framework::StreamReader* zReader);
     void save(Framework::StreamWriter* zWriter);
     void save(Framework::StreamWriter* zWriter);

+ 15 - 0
FactoryCraft/Dimension.cpp

@@ -348,6 +348,7 @@ void Dimension::placeBlock(
             c->putBlockAt(Vec3<int>(x, y, location.z), block);
             c->putBlockAt(Vec3<int>(x, y, location.z), block);
         else
         else
         {
         {
+            
             c->putBlockAt(Vec3<int>(x, y, location.z), 0);
             c->putBlockAt(Vec3<int>(x, y, location.z), 0);
             c->putBlockTypeAt(Vec3<int>(x, y, location.z), block);
             c->putBlockTypeAt(Vec3<int>(x, y, location.z), block);
         }
         }
@@ -356,6 +357,19 @@ void Dimension::placeBlock(
         block.getA()->release();
         block.getA()->release();
 }
 }
 
 
+void Dimension::sendBlockInfo(Framework::Vec3<int> location)
+{
+    Chunk* c = zChunk(Game::getChunkCenter(location.x, location.y));
+    if (c)
+    {
+        int x = location.x % CHUNK_SIZE;
+        int y = location.y % CHUNK_SIZE;
+        if (x < 0) x += CHUNK_SIZE;
+        if (y < 0) y += CHUNK_SIZE;
+        c->sendBlockInfo(Vec3<int>(x, y, location.z));
+    }
+}
+
 void Dimension::addEntity(Entity* entity)
 void Dimension::addEntity(Entity* entity)
 {
 {
     entities->add(entity);
     entities->add(entity);
@@ -815,6 +829,7 @@ MultiblockStructure* Dimension::zStructureById(__int64 id)
         structurCs.unlock();
         structurCs.unlock();
         return str;
         return str;
     }
     }
+    std::cout << "WARNING: did not find Structure information file '" << path << "'.";
     structurCs.unlock();
     structurCs.unlock();
     return 0;
     return 0;
 }
 }

+ 1 - 0
FactoryCraft/Dimension.h

@@ -55,6 +55,7 @@ public:
     const Block* zBlockOrDefault(Framework::Vec3<int> location);
     const Block* zBlockOrDefault(Framework::Vec3<int> location);
     void placeBlock(
     void placeBlock(
         Framework::Vec3<int> location, Framework::Either<Block*, int> block);
         Framework::Vec3<int> location, Framework::Either<Block*, int> block);
+    void sendBlockInfo(Framework::Vec3<int> location);
     void addEntity(Entity* entity);
     void addEntity(Entity* entity);
     void setChunk(Chunk* chunk, Framework::Punkt center);
     void setChunk(Chunk* chunk, Framework::Punkt center);
     void save(Framework::Text worldDir) const;
     void save(Framework::Text worldDir) const;