Răsfoiți Sursa

fix issue with light transmission

Kolja Strohm 1 an în urmă
părinte
comite
7347b12f13

+ 123 - 109
FactoryCraft/Chunk.cpp

@@ -1,8 +1,7 @@
-#include "Chunk.h"
-
 #include <AsynchronCall.h>
 #include <InMemoryBuffer.h>
 
+#include "Chunk.h"
 #include "Constants.h"
 #include "Game.h"
 #include "NoBlock.h"
@@ -80,10 +79,14 @@ void Chunk::sendLightToClient(Framework::StreamWriter* zWriter)
 {
     for (int z = 0; z < WORLD_HEIGHT; z++)
     {
-        for (int x = 0; x < CHUNK_SIZE; x++)
+        for (int x = -1; x <= CHUNK_SIZE; x++)
         {
-            for (int y = 0; y < CHUNK_SIZE; y++)
+            for (int y = -1; y <= CHUNK_SIZE; y++)
             {
+                if ((x < 0 || x == CHUNK_SIZE) && (y < 0 || y > CHUNK_SIZE))
+                {
+                    continue;
+                }
                 bool needSend = 0;
                 for (int i = 0; i < 6; i++)
                 {
@@ -102,18 +105,22 @@ void Chunk::sendLightToClient(Framework::StreamWriter* zWriter)
                         }
                         else
                         {
-                            if (i < 4 && zNeighbours[i])
+                            if (x >= 0 && x < CHUNK_SIZE && y >= 0
+                                && y < CHUNK_SIZE)
                             {
-                                Vec3<int> offset
-                                    = getDirection(getDirectionFromIndex(i))
-                                    * 16;
-                                int bi = ((pos.x - offset.x) * CHUNK_SIZE
-                                             + (pos.y - offset.y))
-                                           * WORLD_HEIGHT
-                                       + (pos.z - offset.z);
-                                int type = zNeighbours[i]->blockIds[bi];
-                                needSend |= type != BlockTypeEnum::NO_BLOCK
-                                         && type != BlockTypeEnum::AIR;
+                                if (i < 4 && zNeighbours[i])
+                                {
+                                    Vec3<int> offset
+                                        = getDirection(getDirectionFromIndex(i))
+                                        * 16;
+                                    int bi = ((pos.x - offset.x) * CHUNK_SIZE
+                                                 + (pos.y - offset.y))
+                                               * WORLD_HEIGHT
+                                           + (pos.z - offset.z);
+                                    int type = zNeighbours[i]->blockIds[bi];
+                                    needSend |= type != BlockTypeEnum::NO_BLOCK
+                                             && type != BlockTypeEnum::AIR;
+                                }
                             }
                         }
                         if (needSend) break;
@@ -121,17 +128,79 @@ void Chunk::sendLightToClient(Framework::StreamWriter* zWriter)
                 }
                 if (needSend)
                 {
-                    int index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
-                    zWriter->schreibe((char*)&index, 4);
-                    zWriter->schreibe((char*)(lightData + index * 6), 6);
+                    if (x >= 0 && x < CHUNK_SIZE && y >= 0 && y < CHUNK_SIZE)
+                    {
+                        int index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
+                        zWriter->schreibe((char*)&index, 4);
+                        zWriter->schreibe((char*)(lightData + index * 6), 6);
+                    }
+                    else
+                    {
+                        int dir;
+                        int index = 0;
+                        if (x == -1)
+                        {
+                            dir = getDirectionIndex(WEST);
+                            index = ((CHUNK_SIZE - 1) * CHUNK_SIZE + y)
+                                      * WORLD_HEIGHT
+                                  + z;
+                        }
+                        else if (y == -1)
+                        {
+                            dir = getDirectionIndex(NORTH);
+                            index = (x * CHUNK_SIZE + CHUNK_SIZE - 1)
+
+                                      * WORLD_HEIGHT
+                                  + z;
+                        }
+                        else if (x == CHUNK_SIZE)
+                        {
+                            dir = getDirectionIndex(EAST);
+                            index = y * WORLD_HEIGHT + z;
+                        }
+                        else if (y == CHUNK_SIZE)
+                        {
+                            dir = getDirectionIndex(SOUTH);
+                            index = (x * CHUNK_SIZE) * WORLD_HEIGHT + z;
+                        }
+                        if (zNeighbours[dir])
+                        {
+                            int i = -1;
+                            zWriter->schreibe((char*)&i, 4);
+                            zWriter->schreibe((char*)&x, 4);
+                            zWriter->schreibe((char*)&y, 4);
+                            zWriter->schreibe((char*)&z, 4);
+                            zWriter->schreibe(
+                                (char*)(zNeighbours[dir]->lightData + index * 6),
+                                6);
+                        }
+                    }
                 }
             }
         }
     }
-    int end = -1;
+    int end = -2;
     zWriter->schreibe((char*)&end, 4);
 }
 
+void Chunk::broadcastLightData(int index, bool foreground)
+{
+    int x = (index / WORLD_HEIGHT) / CHUNK_SIZE;
+    int y = (index / WORLD_HEIGHT) % CHUNK_SIZE;
+    int z = index % WORLD_HEIGHT;
+    NetworkMessage* msg = new NetworkMessage();
+    msg->addressDimension(Game::INSTANCE->zDimension(dimensionId));
+    char* message = new char[19];
+    message[0] = 5;
+    *(int*)(message + 1) = x;
+    *(int*)(message + 5) = y;
+    *(int*)(message + 9) = z;
+    memcpy(message + 13, lightData + index, 6);
+    msg->setMessage(message, 19);
+    if (!foreground) msg->setUseBackground();
+    notifyObservers(msg);
+}
+
 Framework::Either<Block*, int> Chunk::zBlockNeighbor(
     Framework::Vec3<int> location)
 {
@@ -190,7 +259,7 @@ void Chunk::addObserver(Entity* zEntity, DoLaterHandler& laterHandler)
         sendToClient(&buffer);
         sendLightToClient(&buffer);
         NetworkMessage* msg = new NetworkMessage();
-        msg->addressDimension();
+        msg->addressDimension(Game::INSTANCE->zDimension(dimensionId));
         std::cout << "chunk size: " << buffer.getSize() << "b\n";
         char* message = new char[buffer.getSize()];
         buffer.lese(message, (int)buffer.getSize());
@@ -376,8 +445,7 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
     Block* old = blocks[index];
     if (old && old->isTickSource())
     { // remove from tick sorces
-        for (Framework::Iterator<Block*> obj = tickSources.begin(); obj;
-             obj++)
+        for (Framework::Iterator<Block*> obj = tickSources.begin(); obj; obj++)
         {
             if (obj.val() == old)
             {
@@ -572,103 +640,57 @@ void Chunk::setNeighbor(Direction dir, Chunk* zChunk)
     {
         for (int z = 0; z < WORLD_HEIGHT; z++)
         {
+            int index = 0;
+            int j = 0;
             if (dir == NORTH)
             {
-                int index = i * CHUNK_SIZE * WORLD_HEIGHT + z;
-                int j = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
-                if (blocks[index])
-                {
-                    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 (zChunk)
-                {
-                    if (zChunk->blockIds[j] == BlockTypeEnum::AIR
-                        && !blockIds[index])
-                    {
-                        generateBlock(Vec3<int>(i, 0, z));
-                    }
-                }
+                index = i * CHUNK_SIZE * WORLD_HEIGHT + z;
+                j = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
             }
             else if (dir == EAST)
             {
-                int index
-                    = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
-                int j = i * WORLD_HEIGHT + z;
-                if (blocks[index])
-                {
-                    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 (zChunk)
-                {
-                    if (zChunk->blockIds[j] == BlockTypeEnum::AIR
-                        && !blockIds[index])
-                    {
-                        generateBlock(Vec3<int>(CHUNK_SIZE - 1, i, z));
-                    }
-                }
+                index = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
+                j = i * WORLD_HEIGHT + z;
             }
             else if (dir == SOUTH)
             {
-                int index
-                    = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
-                int j = i * CHUNK_SIZE * WORLD_HEIGHT + z;
-                if (blocks[index])
-                {
-                    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 (zChunk)
-                {
-                    if (zChunk->blockIds[j] == BlockTypeEnum::AIR
-                        && !blockIds[index])
-                    {
-                        generateBlock(Vec3<int>(i, CHUNK_SIZE - 1, z));
-                    }
-                }
+                index = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
+                j = i * CHUNK_SIZE * WORLD_HEIGHT + z;
             }
             else if (dir == WEST)
             {
-                int index = i * WORLD_HEIGHT + z;
-                int j = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
-                if (blocks[index])
+                index = i * WORLD_HEIGHT + z;
+                j = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
+            }
+            if (blocks[index])
+            {
+                if (zChunk && zChunk->blocks[j])
+                    blocks[index]->setNeighbour(dir, zChunk->blocks[j]);
+                else
                 {
-                    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);
-                    }
+                    blocks[index]->setNeighbour(dir, 0);
+                    blocks[index]->setNeighbourType(
+                        dir, zChunk ? zChunk->blockIds[j] : 0);
                 }
-                else if (zChunk)
+            }
+            if (zChunk)
+            {
+                if (!blocks[index])
                 {
                     if (zChunk->blockIds[j] == BlockTypeEnum::AIR
                         && !blockIds[index])
                     {
-                        generateBlock(Vec3<int>(0, i, z));
+                        generateBlock(
+                            Vec3<int>((index / WORLD_HEIGHT) / CHUNK_SIZE,
+                                (index / WORLD_HEIGHT) % CHUNK_SIZE,
+                                index % WORLD_HEIGHT));
                     }
                 }
+                if (blockIds[index] != BlockTypeEnum::AIR
+                    && blockIds[index] != BlockTypeEnum::NO_BLOCK)
+                {
+                    zChunk->broadcastLightData(j, true);
+                }
             }
         }
     }
@@ -943,14 +965,6 @@ void Chunk::setLightData(
     }
     if (needSend)
     {
-        NetworkMessage* msg = new NetworkMessage();
-        msg->addressChunck(this);
-        char* message = new char[11];
-        message[0] = 1;
-        *(int*)(message + 1) = index / 6;
-        memcpy(message + 5, data, 6);
-        msg->setMessage(message, 11);
-        if (!foreground) msg->setUseBackground();
-        notifyObservers(msg);
+        broadcastLightData(index, foreground);
     }
 }

+ 1 - 0
FactoryCraft/Chunk.h

@@ -31,6 +31,7 @@ private:
     void addLightSource(int index);
     void removeLightSource(int index);
     void sendLightToClient(Framework::StreamWriter* zWriter);
+    void broadcastLightData(int index, bool foreground);
 
 public:
     Chunk(Framework::Punkt location, int dimensionId);

+ 16 - 16
FactoryCraft/Dimension.cpp

@@ -687,29 +687,29 @@ void Dimension::updateLightAtChunkBorders(Punkt chunkCenter)
     {
         for (int j = 0; j < CHUNK_SIZE; j++)
         {
-            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 - 1,
-                chunkCenter.y - CHUNK_SIZE / 8 + j,
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 2 - 1,
+                chunkCenter.y - CHUNK_SIZE / 2 + j,
                 i));
-            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8,
-                chunkCenter.y - CHUNK_SIZE / 8 + j,
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 2,
+                chunkCenter.y - CHUNK_SIZE / 2 + j,
                 i));
-            updateLightning(Vec3<int>(chunkCenter.x + CHUNK_SIZE / 8 - 1,
-                chunkCenter.y - CHUNK_SIZE / 8 + j,
+            updateLightning(Vec3<int>(chunkCenter.x + CHUNK_SIZE / 2 - 1,
+                chunkCenter.y - CHUNK_SIZE / 2 + j,
                 i));
-            updateLightning(Vec3<int>(chunkCenter.x + CHUNK_SIZE / 8,
-                chunkCenter.y - CHUNK_SIZE / 8 + j,
+            updateLightning(Vec3<int>(chunkCenter.x + CHUNK_SIZE / 2,
+                chunkCenter.y - CHUNK_SIZE / 2 + j,
                 i));
-            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j,
-                chunkCenter.y - CHUNK_SIZE / 8 - 1,
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 2 + j,
+                chunkCenter.y - CHUNK_SIZE / 2 - 1,
                 i));
-            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j,
-                chunkCenter.y - CHUNK_SIZE / 8,
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 2 + j,
+                chunkCenter.y - CHUNK_SIZE / 2,
                 i));
-            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j,
-                chunkCenter.y + CHUNK_SIZE / 8 - 1,
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 2 + j,
+                chunkCenter.y + CHUNK_SIZE / 2 - 1,
                 i));
-            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 8 + j,
-                chunkCenter.y + CHUNK_SIZE / 8,
+            updateLightning(Vec3<int>(chunkCenter.x - CHUNK_SIZE / 2 + j,
+                chunkCenter.y + CHUNK_SIZE / 2,
                 i));
         }
     }

+ 2 - 0
FactoryCraft/Game.cpp

@@ -160,6 +160,8 @@ void GameClient::reply()
         client->zForegroundWriter()->schreibe(
             (char*)&Message::POSITION_UPDATE, 1);
         client->zForegroundWriter()->schreibe((char*)&id, 4);
+        id = zPlayer->getCurrentDimensionId();
+        client->zForegroundWriter()->schreibe((char*)&id, 4);
         foreground.unlock();
         first = 0;
     }

+ 19 - 15
FactoryCraft/NetworkMessage.cpp

@@ -24,44 +24,48 @@ NetworkMessage::~NetworkMessage()
 void NetworkMessage::addressChunck(const Chunk* zChunk)
 {
     delete[] address;
-    addressLength = 10;
+    addressLength = 14;
     address = new char[addressLength];
     address[0] = 1; // dimension response
-    address[1] = 1; // chunck
+    *(int*)(address + 1) = zChunk->getDimensionId();
+    address[5] = 1; // chunck
     Framework::Punkt center = zChunk->getCenter();
-    *(int*)(address + 2) = center.x;
-    *(int*)(address + 6) = center.y;
+    *(int*)(address + 6) = center.x;
+    *(int*)(address + 10) = center.y;
 }
 
 void NetworkMessage::addressEntity(const Entity* zEntity)
 {
     delete[] address;
-    addressLength = 6;
+    addressLength = 10;
     address = new char[addressLength];
     address[0] = 1; // dimension response
-    address[1] = 2; // entity
-    *(int*)(address + 2) = zEntity->getId();
+    *(int*)(address + 1) = zEntity->getCurrentDimensionId();
+    address[5] = 2; // entity
+    *(int*)(address + 6) = zEntity->getId();
 }
 
-void NetworkMessage::addressDimension()
+void NetworkMessage::addressDimension(const Dimension *zDim)
 {
     delete[] address;
-    addressLength = 1;
-    address = new char[1];
+    addressLength = 5;
+    address = new char[5];
     address[0] = 1; // dimension response
+    *(int*)(address + 1) = zDim->getDimensionId();
 }
 
 void NetworkMessage::addressBlock(const Block* zBlock)
 {
     delete[] address;
-    addressLength = 14;
+    addressLength = 18;
     address = new char[addressLength];
     address[0] = 1; // dimension response
-    address[1] = 3; // block
+    *(int*)(address + 1) = zBlock->getDimensionId();
+    address[5] = 3; // block
     Framework::Vec3<int> pos = zBlock->getPos();
-    *(int*)(address + 2) = pos.x;
-    *(int*)(address + 6) = pos.y;
-    *(int*)(address + 10) = pos.z;
+    *(int*)(address + 6) = pos.x;
+    *(int*)(address + 10) = pos.y;
+    *(int*)(address + 14) = pos.z;
 }
 
 void NetworkMessage::openDialog(Framework::Text dialogName)

+ 2 - 1
FactoryCraft/NetworkMessage.h

@@ -7,6 +7,7 @@
 class Chunk;
 class Block;
 class Entity;
+class Dimension;
 
 class NetworkMessage : public virtual Framework::ReferenceCounter
 {
@@ -25,7 +26,7 @@ public:
     void addressChunck(const Chunk* zChunk);
     void addressEntity(const Entity* zEntity);
     void addressBlock(const Block* zBlock);
-    void addressDimension();
+    void addressDimension(const Dimension* zDim);
     void openDialog(Framework::Text dialogName);
     void addressGui(Framework::Text elementId);
     void setMessage(char* msg, int length);