|
@@ -64,6 +64,51 @@ void Chunk::removeLightSource(int index)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void Chunk::sendLightToClient(Entity* zPlayer)
|
|
|
+{
|
|
|
+ for (int z = 0; z < WORLD_HEIGHT; z++)
|
|
|
+ {
|
|
|
+ for (int x = 0; x < CHUNK_SIZE; x++)
|
|
|
+ {
|
|
|
+ for (int y = 0; y < CHUNK_SIZE; y++)
|
|
|
+ {
|
|
|
+ bool needSend = 0;
|
|
|
+ for (int i = 0; i < 6; i++)
|
|
|
+ {
|
|
|
+ Vec3<int> pos = Vec3<int>(x, y, z) + getDirection(getDirectionFromIndex(i));
|
|
|
+ if (pos.z >= 0 && pos.z < WORLD_HEIGHT)
|
|
|
+ {
|
|
|
+ if (pos.x >= 0 && pos.x < CHUNK_SIZE && pos.y >= 0 && pos.y < CHUNK_SIZE)
|
|
|
+ {
|
|
|
+ int bi = (pos.x * CHUNK_SIZE + pos.y) * WORLD_HEIGHT + pos.z;
|
|
|
+ int type = blockIds[bi];
|
|
|
+ needSend |= type != NoBlockBlockType::ID && type != AirBlockBlockType::ID;
|
|
|
+ if (needSend)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ needSend = 1; // TODO: check if the block is visible
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (needSend)
|
|
|
+ {
|
|
|
+ NetworkMessage msg;
|
|
|
+ msg.addressChunck(this);
|
|
|
+ char message[11];
|
|
|
+ message[0] = 1;
|
|
|
+ int index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
|
|
|
+ *(int*)(message + 1) = index;
|
|
|
+ memcpy(message + 5, lightData + index * 6, 6);
|
|
|
+ msg.setMessage(message, 11, 0);
|
|
|
+ Game::INSTANCE->sendMessage(&msg, zPlayer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
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)
|
|
@@ -116,6 +161,7 @@ void Chunk::addObserver(Entity* zEntity)
|
|
|
msg.setMessage(message, (int)buffer.getSize(), 1);
|
|
|
msg.setUseBackground();
|
|
|
Game::INSTANCE->sendMessage(&msg, zEntity);
|
|
|
+ sendLightToClient(zEntity);
|
|
|
}
|
|
|
|
|
|
void Chunk::removeObserver(Entity* zEntity)
|
|
@@ -197,6 +243,7 @@ void Chunk::initializeLightning()
|
|
|
{
|
|
|
if (newLight[i] != light[i])
|
|
|
{
|
|
|
+ changes = 1;
|
|
|
memcpy(light, newLight, 6);
|
|
|
}
|
|
|
}
|
|
@@ -315,16 +362,16 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
|
|
|
}
|
|
|
if (added)
|
|
|
{
|
|
|
+ char msg[9];
|
|
|
+ msg[0] = 0; // set block
|
|
|
+ *(int*)(msg + 1) = index;
|
|
|
+ *(int*)(msg + 5) = block ? block->zBlockType()->getId() : NoBlockBlockType::ID;
|
|
|
+ NetworkMessage message;
|
|
|
+ message.addressChunck(this);
|
|
|
+ message.setMessage(msg, 9, 0);
|
|
|
+ notifyObservers(message);
|
|
|
Game::INSTANCE->updateLightning(getDimensionId(), Vec3<int>(location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z));
|
|
|
}
|
|
|
- char msg[9];
|
|
|
- msg[0] = 0; // set block
|
|
|
- *(int*)(msg + 1) = index;
|
|
|
- *(int*)(msg + 5) = block ? block->zBlockType()->getId() : NoBlockBlockType::ID;
|
|
|
- NetworkMessage message;
|
|
|
- message.addressChunck(this);
|
|
|
- message.setMessage(msg, 9, 0);
|
|
|
- notifyObservers(message);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -364,16 +411,16 @@ void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
|
|
|
}
|
|
|
if (added)
|
|
|
{
|
|
|
+ char msg[9];
|
|
|
+ msg[0] = 0; // set block
|
|
|
+ *(int*)(msg + 1) = index;
|
|
|
+ *(int*)(msg + 5) = type;
|
|
|
+ NetworkMessage message;
|
|
|
+ message.addressChunck(this);
|
|
|
+ message.setMessage(msg, 9, 0);
|
|
|
+ notifyObservers(message);
|
|
|
Game::INSTANCE->updateLightning(getDimensionId(), Vec3<int>(location.x + this->location.x - CHUNK_SIZE / 2, location.y + this->location.y - CHUNK_SIZE / 2, location.z));
|
|
|
}
|
|
|
- char msg[9];
|
|
|
- msg[0] = 0; // set block
|
|
|
- *(int*)(msg + 1) = index;
|
|
|
- *(int*)(msg + 5) = type;
|
|
|
- NetworkMessage message;
|
|
|
- message.addressChunck(this);
|
|
|
- message.setMessage(msg, 9, 0);
|
|
|
- notifyObservers(message);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -541,9 +588,7 @@ void Chunk::sendToClient(Framework::StreamWriter* zWriter)
|
|
|
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);
|
|
|
+ zWriter->schreibe((char*)&index, 4);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -651,4 +696,42 @@ unsigned char* Chunk::getLightData(Framework::Vec3<int> location) const
|
|
|
int index = ((location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z) * 6;
|
|
|
assert(index < CHUNK_SIZE* CHUNK_SIZE* WORLD_HEIGHT);
|
|
|
return lightData + index;
|
|
|
+}
|
|
|
+
|
|
|
+void Chunk::setLightData(Framework::Vec3<int> location, unsigned char* data)
|
|
|
+{
|
|
|
+ int index = ((location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT + location.z) * 6;
|
|
|
+ memcpy(lightData + index, data, 6);
|
|
|
+ // check if neighbor is a visible block and send update to clients
|
|
|
+ bool needSend = 0;
|
|
|
+ for (int i = 0; i < 6; i++)
|
|
|
+ {
|
|
|
+ Vec3<int> pos = location + getDirection(getDirectionFromIndex(i));
|
|
|
+ if (pos.z >= 0 && pos.z < WORLD_HEIGHT)
|
|
|
+ {
|
|
|
+ if (pos.x >= 0 && pos.x < CHUNK_SIZE && pos.y >= 0 && pos.y < CHUNK_SIZE)
|
|
|
+ {
|
|
|
+ int bi = (pos.x * CHUNK_SIZE + pos.y) * WORLD_HEIGHT + pos.z;
|
|
|
+ int type = blockIds[bi];
|
|
|
+ needSend |= type != NoBlockBlockType::ID && type != AirBlockBlockType::ID;
|
|
|
+ if (needSend)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ needSend = 1; // TODO: check if the block is visible
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (needSend)
|
|
|
+ {
|
|
|
+ NetworkMessage msg;
|
|
|
+ msg.addressChunck(this);
|
|
|
+ char message[11];
|
|
|
+ message[0] = 1;
|
|
|
+ *(int*)(message + 1) = index / 6;
|
|
|
+ memcpy(message + 5, data, 6);
|
|
|
+ msg.setMessage(message, 11, 0);
|
|
|
+ notifyObservers(msg);
|
|
|
+ }
|
|
|
}
|