|
@@ -20,13 +20,11 @@ Chunk::Chunk(Framework::Punkt location, int dimensionId)
|
|
|
worldUpdated(1),
|
|
worldUpdated(1),
|
|
|
currentlyLoading(1)
|
|
currentlyLoading(1)
|
|
|
{
|
|
{
|
|
|
- blocks = new Block*[CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT];
|
|
|
|
|
- blockIds = new unsigned short[CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT];
|
|
|
|
|
|
|
+ blocks = new Block**[WORLD_HEIGHT];
|
|
|
|
|
+ blockIds = new unsigned short*[WORLD_HEIGHT];
|
|
|
lightData = new unsigned char[CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * 6];
|
|
lightData = new unsigned char[CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * 6];
|
|
|
- memset(blocks, 0, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof(Block*));
|
|
|
|
|
- memset(blockIds,
|
|
|
|
|
- 0,
|
|
|
|
|
- CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * sizeof(unsigned short));
|
|
|
|
|
|
|
+ memset(blocks, 0, WORLD_HEIGHT * sizeof(Block**));
|
|
|
|
|
+ memset(blockIds, 0, WORLD_HEIGHT * sizeof(unsigned short*));
|
|
|
memset(lightData, 0, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * 6);
|
|
memset(lightData, 0, CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * 6);
|
|
|
zNeighbours[0] = 0;
|
|
zNeighbours[0] = 0;
|
|
|
zNeighbours[1] = 0;
|
|
zNeighbours[1] = 0;
|
|
@@ -44,9 +42,16 @@ Chunk::Chunk(Framework::Punkt location,
|
|
|
|
|
|
|
|
Chunk::~Chunk()
|
|
Chunk::~Chunk()
|
|
|
{
|
|
{
|
|
|
- for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
|
|
|
|
|
|
|
+ for (int h = 0; h < WORLD_HEIGHT; h++)
|
|
|
{
|
|
{
|
|
|
- if (blocks[i]) blocks[i]->release();
|
|
|
|
|
|
|
+ for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (blocks[h] && blocks[h][i]) blocks[h][i]->release();
|
|
|
|
|
+ }
|
|
|
|
|
+ delete[] blocks[h];
|
|
|
|
|
+ blocks[h] = 0;
|
|
|
|
|
+ delete[] blockIds[h];
|
|
|
|
|
+ blockIds[h] = 0;
|
|
|
}
|
|
}
|
|
|
delete[] blocks;
|
|
delete[] blocks;
|
|
|
delete[] blockIds;
|
|
delete[] blockIds;
|
|
@@ -83,20 +88,20 @@ void Chunk::tick(TickQueue* zQueue)
|
|
|
|
|
|
|
|
void Chunk::postTick() {}
|
|
void Chunk::postTick() {}
|
|
|
|
|
|
|
|
-void Chunk::addLightSource(int index)
|
|
|
|
|
|
|
+void Chunk::addLightSource(int z, int index)
|
|
|
{
|
|
{
|
|
|
for (int i : lightSources)
|
|
for (int i : lightSources)
|
|
|
{
|
|
{
|
|
|
- if (i == index) return;
|
|
|
|
|
|
|
+ if (i == index * WORLD_HEIGHT + z) return;
|
|
|
}
|
|
}
|
|
|
- lightSources.add(index);
|
|
|
|
|
|
|
+ lightSources.add(index * WORLD_HEIGHT + z);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void Chunk::removeLightSource(int index)
|
|
|
|
|
|
|
+void Chunk::removeLightSource(int z, int index)
|
|
|
{
|
|
{
|
|
|
for (auto i = lightSources.begin(); i; i++)
|
|
for (auto i = lightSources.begin(); i; i++)
|
|
|
{
|
|
{
|
|
|
- if (i.val() == index)
|
|
|
|
|
|
|
+ if (i.val() == index * WORLD_HEIGHT + z)
|
|
|
{
|
|
{
|
|
|
i.remove();
|
|
i.remove();
|
|
|
return;
|
|
return;
|
|
@@ -112,31 +117,36 @@ void Chunk::sendToClient(Framework::StreamWriter* zWriter, bool* instanceMap)
|
|
|
{
|
|
{
|
|
|
for (int z = 0; z < WORLD_HEIGHT; z++)
|
|
for (int z = 0; z < WORLD_HEIGHT; z++)
|
|
|
{
|
|
{
|
|
|
- int index = Chunk::index({x, y, z});
|
|
|
|
|
- const BlockType* type
|
|
|
|
|
- = Game::INSTANCE->zBlockType(blockIds[index]);
|
|
|
|
|
- if (isVisible(index) && type->doesNeedClientInstance())
|
|
|
|
|
|
|
+ int index = Chunk::index(x, y);
|
|
|
|
|
+ const BlockType* type = Game::INSTANCE->zBlockType(
|
|
|
|
|
+ blockIds[z] ? blockIds[z][index] : 0);
|
|
|
|
|
+ if (isVisible(z, index) && type->doesNeedClientInstance())
|
|
|
{
|
|
{
|
|
|
- if (z > 0 && z < WORLD_HEIGHT - 1)
|
|
|
|
|
|
|
+ int mI = index * WORLD_HEIGHT + z;
|
|
|
|
|
+ if (z < WORLD_HEIGHT - 1)
|
|
|
{
|
|
{
|
|
|
- instanceMap[index + (CHUNK_SIZE + 1) * WORLD_HEIGHT + 1]
|
|
|
|
|
|
|
+ instanceMap[mI + (CHUNK_SIZE + 1) * WORLD_HEIGHT + 1]
|
|
|
= 1;
|
|
= 1;
|
|
|
- instanceMap[index + (CHUNK_SIZE + 1) * WORLD_HEIGHT - 1]
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ if (z > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ instanceMap[mI + (CHUNK_SIZE + 1) * WORLD_HEIGHT - 1]
|
|
|
= 1;
|
|
= 1;
|
|
|
}
|
|
}
|
|
|
- instanceMap[index + WORLD_HEIGHT] = 1;
|
|
|
|
|
- instanceMap[index + (2 * CHUNK_SIZE + 1) * WORLD_HEIGHT]
|
|
|
|
|
- = 1;
|
|
|
|
|
- instanceMap[index + CHUNK_SIZE * WORLD_HEIGHT] = 1;
|
|
|
|
|
- instanceMap[index + (CHUNK_SIZE + 2) * WORLD_HEIGHT] = 1;
|
|
|
|
|
- zWriter->schreibe((char*)&blockIds[index], 2);
|
|
|
|
|
- zWriter->schreibe((char*)&index, 4);
|
|
|
|
|
|
|
+ instanceMap[mI + WORLD_HEIGHT] = 1;
|
|
|
|
|
+ instanceMap[mI + (2 * CHUNK_SIZE + 1) * WORLD_HEIGHT] = 1;
|
|
|
|
|
+ instanceMap[mI + CHUNK_SIZE * WORLD_HEIGHT] = 1;
|
|
|
|
|
+ instanceMap[mI + (CHUNK_SIZE + 2) * WORLD_HEIGHT] = 1;
|
|
|
|
|
+ assert(blockIds[z]);
|
|
|
|
|
+ zWriter->schreibe((char*)&blockIds[z][index], 2);
|
|
|
|
|
+ zWriter->schreibe((char*)&mI, 4);
|
|
|
char state = 0;
|
|
char state = 0;
|
|
|
if (type->isFluid())
|
|
if (type->isFluid())
|
|
|
{
|
|
{
|
|
|
state |= 1;
|
|
state |= 1;
|
|
|
}
|
|
}
|
|
|
- if ((blocks[index] && blocks[index]->isPassable())
|
|
|
|
|
|
|
+ if ((blocks[z] && blocks[z][index]
|
|
|
|
|
+ && blocks[z][index]->isPassable())
|
|
|
|| (type->zDefault()->isPassable()))
|
|
|| (type->zDefault()->isPassable()))
|
|
|
{
|
|
{
|
|
|
state |= 2;
|
|
state |= 2;
|
|
@@ -145,7 +155,9 @@ void Chunk::sendToClient(Framework::StreamWriter* zWriter, bool* instanceMap)
|
|
|
if ((state | 1) == state)
|
|
if ((state | 1) == state)
|
|
|
{
|
|
{
|
|
|
FluidBlock* fluidBlock
|
|
FluidBlock* fluidBlock
|
|
|
- = dynamic_cast<FluidBlock*>(blocks[index]);
|
|
|
|
|
|
|
+ = blocks[z]
|
|
|
|
|
+ ? dynamic_cast<FluidBlock*>(blocks[z][index])
|
|
|
|
|
+ : 0;
|
|
|
char data
|
|
char data
|
|
|
= fluidBlock ? fluidBlock->getFlowOptions() : 0;
|
|
= fluidBlock ? fluidBlock->getFlowOptions() : 0;
|
|
|
zWriter->schreibe(&data, 1);
|
|
zWriter->schreibe(&data, 1);
|
|
@@ -156,8 +168,8 @@ void Chunk::sendToClient(Framework::StreamWriter* zWriter, bool* instanceMap)
|
|
|
if ((state | 2) == state)
|
|
if ((state | 2) == state)
|
|
|
{
|
|
{
|
|
|
float speedModifier
|
|
float speedModifier
|
|
|
- = blocks[index]
|
|
|
|
|
- ? blocks[index]->getSpeedModifier()
|
|
|
|
|
|
|
+ = blocks[z] && blocks[z][index]
|
|
|
|
|
+ ? blocks[z][index]->getSpeedModifier()
|
|
|
: type->zDefault()->getSpeedModifier();
|
|
: type->zDefault()->getSpeedModifier();
|
|
|
zWriter->schreibe((char*)&speedModifier, 4);
|
|
zWriter->schreibe((char*)&speedModifier, 4);
|
|
|
}
|
|
}
|
|
@@ -276,7 +288,7 @@ void Chunk::sendLightToClient(
|
|
|
{
|
|
{
|
|
|
if (x >= 0 && x < CHUNK_SIZE && y >= 0 && y < CHUNK_SIZE)
|
|
if (x >= 0 && x < CHUNK_SIZE && y >= 0 && y < CHUNK_SIZE)
|
|
|
{
|
|
{
|
|
|
- int index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
|
|
|
|
|
|
|
+ int index = Chunk::index(x, y) * WORLD_HEIGHT + z;
|
|
|
zWriter->schreibe((char*)&index, 4);
|
|
zWriter->schreibe((char*)&index, 4);
|
|
|
zWriter->schreibe((char*)(lightData + index * 6), 6);
|
|
zWriter->schreibe((char*)(lightData + index * 6), 6);
|
|
|
}
|
|
}
|
|
@@ -337,22 +349,18 @@ void Chunk::sendLightToClient(
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bool Chunk::isVisible(int index) const
|
|
|
|
|
|
|
+bool Chunk::isVisible(int z, int index) const
|
|
|
{
|
|
{
|
|
|
- unsigned short blockType
|
|
|
|
|
- = blocks[index] ? (unsigned short)blocks[index]->zBlockType()->getId()
|
|
|
|
|
- : blockIds[index];
|
|
|
|
|
|
|
+ unsigned short blockType = blockIds[z] ? blockIds[z][index] : 0;
|
|
|
if (blockType)
|
|
if (blockType)
|
|
|
{
|
|
{
|
|
|
- if (CONST_BLOCK(0, blockIds[index])->isTransparent()
|
|
|
|
|
- || CONST_BLOCK(0, blockIds[index])->isPassable())
|
|
|
|
|
|
|
+ if (CONST_BLOCK(0, blockType)->isTransparent()
|
|
|
|
|
+ || CONST_BLOCK(0, blockType)->isPassable())
|
|
|
return 1;
|
|
return 1;
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
Framework::Vec3<int> indexPos
|
|
Framework::Vec3<int> indexPos
|
|
|
- = {(index / WORLD_HEIGHT) / CHUNK_SIZE,
|
|
|
|
|
- (index / WORLD_HEIGHT) % CHUNK_SIZE,
|
|
|
|
|
- index % WORLD_HEIGHT};
|
|
|
|
|
|
|
+ = {(index) / CHUNK_SIZE, (index) % CHUNK_SIZE, z};
|
|
|
for (int d = 0; d < 6; d++)
|
|
for (int d = 0; d < 6; d++)
|
|
|
{
|
|
{
|
|
|
Framework::Either<Block*, int> n = BlockTypeEnum::NO_BLOCK;
|
|
Framework::Either<Block*, int> n = BlockTypeEnum::NO_BLOCK;
|
|
@@ -392,11 +400,10 @@ bool Chunk::isVisible(int index) const
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void Chunk::broadcastLightData(int index, bool foreground)
|
|
|
|
|
|
|
+void Chunk::broadcastLightData(int z, int index, bool foreground)
|
|
|
{
|
|
{
|
|
|
- int x = (index / WORLD_HEIGHT) / CHUNK_SIZE;
|
|
|
|
|
- int y = (index / WORLD_HEIGHT) % CHUNK_SIZE;
|
|
|
|
|
- int z = index % WORLD_HEIGHT;
|
|
|
|
|
|
|
+ int x = index / CHUNK_SIZE;
|
|
|
|
|
+ int y = index % CHUNK_SIZE;
|
|
|
NetworkMessage* msg = new NetworkMessage();
|
|
NetworkMessage* msg = new NetworkMessage();
|
|
|
msg->addressDimension(Game::INSTANCE->zDimension(dimensionId));
|
|
msg->addressDimension(Game::INSTANCE->zDimension(dimensionId));
|
|
|
char* message = new char[19];
|
|
char* message = new char[19];
|
|
@@ -404,7 +411,7 @@ void Chunk::broadcastLightData(int index, bool foreground)
|
|
|
*(int*)(message + 1) = x + this->location.x - CHUNK_SIZE / 2;
|
|
*(int*)(message + 1) = x + this->location.x - CHUNK_SIZE / 2;
|
|
|
*(int*)(message + 5) = y + this->location.y - 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, 6);
|
|
|
|
|
|
|
+ memcpy(message + 13, lightData + (index * WORLD_HEIGHT + z) * 6, 6);
|
|
|
msg->setMessage(message, 19);
|
|
msg->setMessage(message, 19);
|
|
|
if (!foreground) msg->setUseBackground();
|
|
if (!foreground) msg->setUseBackground();
|
|
|
notifyObservers(msg);
|
|
notifyObservers(msg);
|
|
@@ -417,16 +424,15 @@ Framework::Either<Block*, int> Chunk::zBlockNeighbor(
|
|
|
&& location.y < CHUNK_SIZE && location.z >= 0
|
|
&& location.y < CHUNK_SIZE && location.z >= 0
|
|
|
&& location.z < WORLD_HEIGHT)
|
|
&& location.z < WORLD_HEIGHT)
|
|
|
{
|
|
{
|
|
|
- int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT
|
|
|
|
|
- + location.z;
|
|
|
|
|
|
|
+ int index = Chunk::index(location.x, location.y);
|
|
|
if (zNeighborChunk)
|
|
if (zNeighborChunk)
|
|
|
{
|
|
{
|
|
|
*zNeighborChunk = this;
|
|
*zNeighborChunk = this;
|
|
|
}
|
|
}
|
|
|
- if (blocks[index])
|
|
|
|
|
- return blocks[index];
|
|
|
|
|
|
|
+ if (blocks[location.z] && blocks[location.z][index])
|
|
|
|
|
+ return blocks[location.z][index];
|
|
|
else
|
|
else
|
|
|
- return (int)blockIds[index];
|
|
|
|
|
|
|
+ return blockIds[location.z] ? (int)blockIds[location.z][index] : 0;
|
|
|
}
|
|
}
|
|
|
if (location.z >= 0 && location.z < WORLD_HEIGHT)
|
|
if (location.z >= 0 && location.z < WORLD_HEIGHT)
|
|
|
return Game::INSTANCE->zBlockAt(
|
|
return Game::INSTANCE->zBlockAt(
|
|
@@ -563,11 +569,13 @@ void Chunk::initializeLightning()
|
|
|
visited[y][z] |= 1 << x;
|
|
visited[y][z] |= 1 << x;
|
|
|
unsigned char* light
|
|
unsigned char* light
|
|
|
= getLightData(Framework::Vec3<int>(x, y, z));
|
|
= getLightData(Framework::Vec3<int>(x, y, z));
|
|
|
- int index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
|
|
|
|
|
|
|
+ int index = Chunk::index(x, y);
|
|
|
const Block* current
|
|
const Block* current
|
|
|
- = blocks[index]
|
|
|
|
|
- ? blocks[index]
|
|
|
|
|
- : Game::INSTANCE->zBlockType(blockIds[index])
|
|
|
|
|
|
|
+ = (blocks[z] && blocks[z][index])
|
|
|
|
|
+ ? blocks[z][index]
|
|
|
|
|
+ : Game::INSTANCE
|
|
|
|
|
+ ->zBlockType(
|
|
|
|
|
+ blockIds[z] ? blockIds[z][index] : 0)
|
|
|
->zDefault();
|
|
->zDefault();
|
|
|
light[0] = lightAbove[0];
|
|
light[0] = lightAbove[0];
|
|
|
light[1] = lightAbove[1];
|
|
light[1] = lightAbove[1];
|
|
@@ -598,14 +606,16 @@ void Chunk::initializeLightning()
|
|
|
{
|
|
{
|
|
|
for (int y = 0; y < CHUNK_SIZE; y++)
|
|
for (int y = 0; y < CHUNK_SIZE; y++)
|
|
|
{
|
|
{
|
|
|
- int index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
|
|
|
|
|
|
|
+ int index = Chunk::index(x, y);
|
|
|
unsigned char* light
|
|
unsigned char* light
|
|
|
= getLightData(Framework::Vec3<int>(x, y, z));
|
|
= getLightData(Framework::Vec3<int>(x, y, z));
|
|
|
const Block* current
|
|
const Block* current
|
|
|
- = blocks[index]
|
|
|
|
|
- ? blocks[index]
|
|
|
|
|
|
|
+ = (blocks[z] && blocks[z][index])
|
|
|
|
|
+ ? blocks[z][index]
|
|
|
: Game::INSTANCE
|
|
: Game::INSTANCE
|
|
|
- ->zBlockType(blockIds[index])
|
|
|
|
|
|
|
+ ->zBlockType(blockIds[z]
|
|
|
|
|
+ ? blockIds[z][index]
|
|
|
|
|
+ : 0)
|
|
|
->zDefault();
|
|
->zDefault();
|
|
|
unsigned char newLight[3] = {0, 0, 0};
|
|
unsigned char newLight[3] = {0, 0, 0};
|
|
|
for (int i = 0; i < 4; i++)
|
|
for (int i = 0; i < 4; i++)
|
|
@@ -649,11 +659,14 @@ void Chunk::initializeLightning()
|
|
|
newLight[2]
|
|
newLight[2]
|
|
|
= (unsigned char)(light[2] * 0.8f);
|
|
= (unsigned char)(light[2] * 0.8f);
|
|
|
const Block* above
|
|
const Block* above
|
|
|
- = blocks[index - 1]
|
|
|
|
|
- ? blocks[index - 1]
|
|
|
|
|
|
|
+ = blocks[z + 1] && blocks[z + 1][index]
|
|
|
|
|
+ ? blocks[z + 1][index]
|
|
|
: Game::INSTANCE
|
|
: Game::INSTANCE
|
|
|
->zBlockType(
|
|
->zBlockType(
|
|
|
- blockIds[index - 1])
|
|
|
|
|
|
|
+ blockIds[z + 1]
|
|
|
|
|
+ ? blockIds[z + 1]
|
|
|
|
|
+ [index]
|
|
|
|
|
+ : 0)
|
|
|
->zDefault();
|
|
->zDefault();
|
|
|
above->filterPassingLight(newLight);
|
|
above->filterPassingLight(newLight);
|
|
|
if (newLight[0] > lightAbove[0]
|
|
if (newLight[0] > lightAbove[0]
|
|
@@ -707,12 +720,12 @@ Framework::Either<Block*, int> Chunk::zBlockAt(
|
|
|
Framework::Vec3<int> location) const
|
|
Framework::Vec3<int> location) const
|
|
|
{
|
|
{
|
|
|
if (location.z < 0 || location.z >= WORLD_HEIGHT) return 0;
|
|
if (location.z < 0 || location.z >= WORLD_HEIGHT) return 0;
|
|
|
- int index = Chunk::index(location);
|
|
|
|
|
|
|
+ int index = Chunk::index(location.x, location.y);
|
|
|
assert(index < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
|
|
assert(index < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
|
|
|
- if (blocks[index])
|
|
|
|
|
- return blocks[index];
|
|
|
|
|
|
|
+ if (blocks[location.z] && blocks[location.z][index])
|
|
|
|
|
+ return blocks[location.z][index];
|
|
|
else
|
|
else
|
|
|
- return (int)blockIds[index];
|
|
|
|
|
|
|
+ return blockIds[location.z] ? (int)blockIds[location.z][index] : 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const Block* Chunk::zBlockConst(Framework::Vec3<int> location) const
|
|
const Block* Chunk::zBlockConst(Framework::Vec3<int> location) const
|
|
@@ -722,12 +735,13 @@ const Block* Chunk::zBlockConst(Framework::Vec3<int> location) const
|
|
|
return Game::INSTANCE->zBlockType(b.getB())->zDefault();
|
|
return Game::INSTANCE->zBlockType(b.getB())->zDefault();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const Block* Chunk::zBlockConst(int index) const
|
|
|
|
|
|
|
+const Block* Chunk::zBlockConst(int z, int index) const
|
|
|
{
|
|
{
|
|
|
- if (blocks[index])
|
|
|
|
|
- return blocks[index];
|
|
|
|
|
|
|
+ if (blocks[z] && blocks[z][index])
|
|
|
|
|
+ return blocks[z][index];
|
|
|
else
|
|
else
|
|
|
- return Game::INSTANCE->zBlockType(blockIds[index])->zDefault();
|
|
|
|
|
|
|
+ return Game::INSTANCE->zBlockType(blockIds[z] ? blockIds[z][index] : 0)
|
|
|
|
|
+ ->zDefault();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Chunk::instantiateBlock(Framework::Vec3<int> location)
|
|
void Chunk::instantiateBlock(Framework::Vec3<int> location)
|
|
@@ -748,8 +762,8 @@ void Chunk::instantiateBlock(Framework::Vec3<int> location)
|
|
|
|
|
|
|
|
void Chunk::generateBlock(Framework::Vec3<int> location)
|
|
void Chunk::generateBlock(Framework::Vec3<int> location)
|
|
|
{
|
|
{
|
|
|
- int index = Chunk::index(location);
|
|
|
|
|
- if (blockIds[index]) return;
|
|
|
|
|
|
|
+ int index = Chunk::index(location.x, location.y);
|
|
|
|
|
+ if (blockIds[location.z] && blockIds[location.z][index]) return;
|
|
|
auto generated = Game::INSTANCE->zGenerator()->generateSingleBlock(
|
|
auto generated = Game::INSTANCE->zGenerator()->generateSingleBlock(
|
|
|
{location.x + this->location.x - CHUNK_SIZE / 2,
|
|
{location.x + this->location.x - CHUNK_SIZE / 2,
|
|
|
location.y + this->location.y - CHUNK_SIZE / 2,
|
|
location.y + this->location.y - CHUNK_SIZE / 2,
|
|
@@ -763,9 +777,9 @@ void Chunk::generateBlock(Framework::Vec3<int> location)
|
|
|
|
|
|
|
|
void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
|
|
void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
|
|
|
{
|
|
{
|
|
|
- int index = Chunk::index(location);
|
|
|
|
|
- assert(index < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT && index >= 0);
|
|
|
|
|
- Block* old = blocks[index];
|
|
|
|
|
|
|
+ int index = Chunk::index(location.x, location.y);
|
|
|
|
|
+ assert(index < CHUNK_SIZE * CHUNK_SIZE && index >= 0);
|
|
|
|
|
+ Block* old = blocks[location.z] ? blocks[location.z][index] : 0;
|
|
|
if (old && old->isTickSource() != TickSourceType::NONE)
|
|
if (old && old->isTickSource() != TickSourceType::NONE)
|
|
|
{ // remove from tick sorces
|
|
{ // remove from tick sorces
|
|
|
if (old->isTickSource() == TickSourceType::EACH_TICK)
|
|
if (old->isTickSource() == TickSourceType::EACH_TICK)
|
|
@@ -797,27 +811,42 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ if (!blockIds[location.z])
|
|
|
|
|
+ {
|
|
|
|
|
+ blockIds[location.z] = new unsigned short[CHUNK_SIZE * CHUNK_SIZE];
|
|
|
|
|
+ memset(blockIds[location.z],
|
|
|
|
|
+ 0,
|
|
|
|
|
+ CHUNK_SIZE * CHUNK_SIZE * sizeof(unsigned short));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!blocks[location.z])
|
|
|
|
|
+ {
|
|
|
|
|
+ blocks[location.z] = new Block*[CHUNK_SIZE * CHUNK_SIZE];
|
|
|
|
|
+ memset(blocks[location.z], 0, CHUNK_SIZE * CHUNK_SIZE * sizeof(Block*));
|
|
|
|
|
+ }
|
|
|
bool change = 0;
|
|
bool change = 0;
|
|
|
bool wasLightSource
|
|
bool wasLightSource
|
|
|
= old ? old->zBlockType()->isLightSource()
|
|
= old ? old->zBlockType()->isLightSource()
|
|
|
- : Game::INSTANCE->zBlockType(blockIds[index])->isLightSource();
|
|
|
|
|
|
|
+ : Game::INSTANCE->zBlockType(blockIds[location.z][index])
|
|
|
|
|
+ ->isLightSource();
|
|
|
bool isLightSource = 0;
|
|
bool isLightSource = 0;
|
|
|
if (block)
|
|
if (block)
|
|
|
{
|
|
{
|
|
|
- change
|
|
|
|
|
- = blockIds[index] != (unsigned short)block->zBlockType()->getId();
|
|
|
|
|
- blockIds[index] = (unsigned short)block->zBlockType()->getId();
|
|
|
|
|
|
|
+ change = blockIds[location.z][index]
|
|
|
|
|
+ != (unsigned short)block->zBlockType()->getId();
|
|
|
|
|
+
|
|
|
|
|
+ blockIds[location.z][index]
|
|
|
|
|
+ = (unsigned short)block->zBlockType()->getId();
|
|
|
isLightSource = block->zBlockType()->isLightSource();
|
|
isLightSource = block->zBlockType()->isLightSource();
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
if (old != 0)
|
|
if (old != 0)
|
|
|
{
|
|
{
|
|
|
- blockIds[index] = BlockTypeEnum::NO_BLOCK;
|
|
|
|
|
|
|
+ blockIds[location.z][index] = BlockTypeEnum::NO_BLOCK;
|
|
|
}
|
|
}
|
|
|
change = old != 0;
|
|
change = old != 0;
|
|
|
}
|
|
}
|
|
|
- blocks[index] = block;
|
|
|
|
|
|
|
+ blocks[location.z][index] = block;
|
|
|
if (old) old->release();
|
|
if (old) old->release();
|
|
|
if (block && block->isTickSource() != TickSourceType::NONE)
|
|
if (block && block->isTickSource() != TickSourceType::NONE)
|
|
|
{ // add to tick sources
|
|
{ // add to tick sources
|
|
@@ -836,9 +865,9 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
|
|
|
if (isLightSource != wasLightSource)
|
|
if (isLightSource != wasLightSource)
|
|
|
{
|
|
{
|
|
|
if (isLightSource)
|
|
if (isLightSource)
|
|
|
- addLightSource(index);
|
|
|
|
|
|
|
+ addLightSource(location.z, index);
|
|
|
else
|
|
else
|
|
|
- removeLightSource(index);
|
|
|
|
|
|
|
+ removeLightSource(location.z, index);
|
|
|
}
|
|
}
|
|
|
if (added)
|
|
if (added)
|
|
|
{
|
|
{
|
|
@@ -864,20 +893,27 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
|
|
|
|
|
|
|
|
void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
|
|
void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
|
|
|
{
|
|
{
|
|
|
- int index = Chunk::index(location);
|
|
|
|
|
- assert(index < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
|
|
|
|
|
- bool wasLightSource
|
|
|
|
|
- = Game::INSTANCE->zBlockType(blockIds[index])->isLightSource();
|
|
|
|
|
|
|
+ int index = Chunk::index(location.x, location.y);
|
|
|
|
|
+ assert(index < CHUNK_SIZE * CHUNK_SIZE);
|
|
|
|
|
+ int oldType = blockIds[location.z] ? blockIds[location.z][index] : 0;
|
|
|
|
|
+ bool wasLightSource = Game::INSTANCE->zBlockType(oldType)->isLightSource();
|
|
|
bool isLightSource = Game::INSTANCE->zBlockType(type)->isLightSource();
|
|
bool isLightSource = Game::INSTANCE->zBlockType(type)->isLightSource();
|
|
|
- if (blockIds[index] != (unsigned short)type)
|
|
|
|
|
|
|
+ if (oldType != (unsigned short)type)
|
|
|
{
|
|
{
|
|
|
- blockIds[index] = (unsigned short)type;
|
|
|
|
|
|
|
+ if (!blockIds[location.z])
|
|
|
|
|
+ {
|
|
|
|
|
+ blockIds[location.z] = new unsigned short[CHUNK_SIZE * CHUNK_SIZE];
|
|
|
|
|
+ memset(blockIds[location.z],
|
|
|
|
|
+ 0,
|
|
|
|
|
+ CHUNK_SIZE * CHUNK_SIZE * sizeof(unsigned short));
|
|
|
|
|
+ }
|
|
|
|
|
+ blockIds[location.z][index] = (unsigned short)type;
|
|
|
if (isLightSource != wasLightSource)
|
|
if (isLightSource != wasLightSource)
|
|
|
{
|
|
{
|
|
|
if (isLightSource)
|
|
if (isLightSource)
|
|
|
- addLightSource(index);
|
|
|
|
|
|
|
+ addLightSource(location.z, index);
|
|
|
else
|
|
else
|
|
|
- removeLightSource(index);
|
|
|
|
|
|
|
+ removeLightSource(location.z, index);
|
|
|
}
|
|
}
|
|
|
if (added)
|
|
if (added)
|
|
|
{
|
|
{
|
|
@@ -898,18 +934,20 @@ void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
|
|
|
|
|
|
|
|
void Chunk::sendBlockInfo(Framework::Vec3<int> location)
|
|
void Chunk::sendBlockInfo(Framework::Vec3<int> location)
|
|
|
{
|
|
{
|
|
|
- int index = Chunk::index(location);
|
|
|
|
|
|
|
+ int index = Chunk::index(location.x, location.y);
|
|
|
char* msg = new char[14];
|
|
char* msg = new char[14];
|
|
|
msg[0] = 0; // set block
|
|
msg[0] = 0; // set block
|
|
|
- *(unsigned short*)(msg + 1) = blockIds[index];
|
|
|
|
|
|
|
+ int typeId = blockIds[location.z] ? blockIds[location.z][index] : 0;
|
|
|
|
|
+ *(unsigned short*)(msg + 1) = typeId;
|
|
|
*(int*)(msg + 3) = index;
|
|
*(int*)(msg + 3) = index;
|
|
|
char state = 0;
|
|
char state = 0;
|
|
|
- const BlockType* type = Game::INSTANCE->zBlockType(blockIds[index]);
|
|
|
|
|
|
|
+ const BlockType* type = Game::INSTANCE->zBlockType(typeId);
|
|
|
if (type->isFluid())
|
|
if (type->isFluid())
|
|
|
{
|
|
{
|
|
|
state |= 1;
|
|
state |= 1;
|
|
|
}
|
|
}
|
|
|
- if ((blocks[index] && blocks[index]->isPassable())
|
|
|
|
|
|
|
+ if ((blocks[location.z] && blocks[location.z][index]
|
|
|
|
|
+ && blocks[location.z][index]->isPassable())
|
|
|
|| (type->zDefault()->isPassable()))
|
|
|| (type->zDefault()->isPassable()))
|
|
|
{
|
|
{
|
|
|
state |= 2;
|
|
state |= 2;
|
|
@@ -917,24 +955,25 @@ void Chunk::sendBlockInfo(Framework::Vec3<int> location)
|
|
|
msg[7] = state;
|
|
msg[7] = state;
|
|
|
if ((state | 1) == state)
|
|
if ((state | 1) == state)
|
|
|
{
|
|
{
|
|
|
- FluidBlock* fluidBlock = dynamic_cast<FluidBlock*>(blocks[index]);
|
|
|
|
|
|
|
+ FluidBlock* fluidBlock = dynamic_cast<FluidBlock*>(
|
|
|
|
|
+ blocks[location.z] ? blocks[location.z][index] : 0);
|
|
|
msg[8] = fluidBlock ? fluidBlock->getFlowOptions() : 0;
|
|
msg[8] = fluidBlock ? fluidBlock->getFlowOptions() : 0;
|
|
|
msg[9] = fluidBlock ? fluidBlock->getDistanceToSource() : 0;
|
|
msg[9] = fluidBlock ? fluidBlock->getDistanceToSource() : 0;
|
|
|
}
|
|
}
|
|
|
if ((state | 2) == state)
|
|
if ((state | 2) == state)
|
|
|
{
|
|
{
|
|
|
- *(float*)(msg + 10) = blocks[index]
|
|
|
|
|
- ? blocks[index]->getSpeedModifier()
|
|
|
|
|
|
|
+ *(float*)(msg + 10) = blocks[location.z] && blocks[location.z][index]
|
|
|
|
|
+ ? blocks[location.z][index]->getSpeedModifier()
|
|
|
: type->zDefault()->getSpeedModifier();
|
|
: type->zDefault()->getSpeedModifier();
|
|
|
}
|
|
}
|
|
|
NetworkMessage* message = new NetworkMessage();
|
|
NetworkMessage* message = new NetworkMessage();
|
|
|
message->addressChunck(this);
|
|
message->addressChunck(this);
|
|
|
message->setMessage(msg, 14);
|
|
message->setMessage(msg, 14);
|
|
|
notifyObservers(message);
|
|
notifyObservers(message);
|
|
|
- if (blocks[index])
|
|
|
|
|
|
|
+ if (blocks[location.z] && blocks[location.z][index])
|
|
|
{
|
|
{
|
|
|
NetworkMessage* message = new NetworkMessage();
|
|
NetworkMessage* message = new NetworkMessage();
|
|
|
- blocks[index]->sendModelInfo(message);
|
|
|
|
|
|
|
+ blocks[location.z][index]->sendModelInfo(message);
|
|
|
if (message->isEmpty())
|
|
if (message->isEmpty())
|
|
|
{
|
|
{
|
|
|
message->release();
|
|
message->release();
|
|
@@ -952,7 +991,7 @@ void Chunk::sendBlockInfo(Framework::Vec3<int> location)
|
|
|
if (loc.x >= 0 && loc.x < CHUNK_SIZE && loc.y >= 0 && loc.y < CHUNK_SIZE
|
|
if (loc.x >= 0 && loc.x < CHUNK_SIZE && loc.y >= 0 && loc.y < CHUNK_SIZE
|
|
|
&& loc.z >= 0 && loc.z < WORLD_HEIGHT)
|
|
&& loc.z >= 0 && loc.z < WORLD_HEIGHT)
|
|
|
{
|
|
{
|
|
|
- broadcastLightData(Chunk::index(loc), true);
|
|
|
|
|
|
|
+ broadcastLightData(loc.z, Chunk::index(loc.x, loc.y), true);
|
|
|
}
|
|
}
|
|
|
else if (loc.z >= 0 && loc.z < WORLD_HEIGHT && i < 4 && zNeighbours[i])
|
|
else if (loc.z >= 0 && loc.z < WORLD_HEIGHT && i < 4 && zNeighbours[i])
|
|
|
{
|
|
{
|
|
@@ -976,68 +1015,15 @@ void Chunk::setNeighbor(Direction dir, Chunk* zChunk)
|
|
|
{
|
|
{
|
|
|
cs.lock();
|
|
cs.lock();
|
|
|
int dirIndex = getDirectionIndex(dir);
|
|
int dirIndex = getDirectionIndex(dir);
|
|
|
- Chunk* old = zNeighbours[dirIndex];
|
|
|
|
|
zNeighbours[dirIndex] = zChunk;
|
|
zNeighbours[dirIndex] = zChunk;
|
|
|
- for (int i = 0; i < CHUNK_SIZE; i++)
|
|
|
|
|
- {
|
|
|
|
|
- for (int z = 0; z < WORLD_HEIGHT; z++)
|
|
|
|
|
- {
|
|
|
|
|
- int index = 0;
|
|
|
|
|
- int j = 0;
|
|
|
|
|
- if (dir == NORTH)
|
|
|
|
|
- {
|
|
|
|
|
- index = i * CHUNK_SIZE * WORLD_HEIGHT + z;
|
|
|
|
|
- j = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
|
|
|
|
|
- }
|
|
|
|
|
- else if (dir == EAST)
|
|
|
|
|
- {
|
|
|
|
|
- index = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
|
|
|
|
|
- j = i * WORLD_HEIGHT + z;
|
|
|
|
|
- }
|
|
|
|
|
- else if (dir == SOUTH)
|
|
|
|
|
- {
|
|
|
|
|
- index = (i * CHUNK_SIZE + CHUNK_SIZE - 1) * WORLD_HEIGHT + z;
|
|
|
|
|
- j = i * CHUNK_SIZE * WORLD_HEIGHT + z;
|
|
|
|
|
- }
|
|
|
|
|
- else if (dir == WEST)
|
|
|
|
|
- {
|
|
|
|
|
- index = i * WORLD_HEIGHT + z;
|
|
|
|
|
- j = ((CHUNK_SIZE - 1) * CHUNK_SIZE + i) * WORLD_HEIGHT + z;
|
|
|
|
|
- }
|
|
|
|
|
- bool needsTransmission = 0;
|
|
|
|
|
- zNeighbours[dirIndex] = old;
|
|
|
|
|
- bool visible = isVisible(index);
|
|
|
|
|
- zNeighbours[dirIndex] = zChunk;
|
|
|
|
|
- if (!visible && isVisible(index))
|
|
|
|
|
- {
|
|
|
|
|
- needsTransmission = 1;
|
|
|
|
|
- }
|
|
|
|
|
- if (zChunk)
|
|
|
|
|
- {
|
|
|
|
|
- if (!blocks[index])
|
|
|
|
|
- {
|
|
|
|
|
- if (zChunk->zBlockConst(j)->isTransparent()
|
|
|
|
|
- && !blockIds[index])
|
|
|
|
|
- {
|
|
|
|
|
- generateBlock(Framework::Vec3<int>(
|
|
|
|
|
- (index / WORLD_HEIGHT) / CHUNK_SIZE,
|
|
|
|
|
- (index / WORLD_HEIGHT) % CHUNK_SIZE,
|
|
|
|
|
- index % WORLD_HEIGHT));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (needsTransmission && added)
|
|
|
|
|
- {
|
|
|
|
|
- sendBlockInfo(
|
|
|
|
|
- Framework::Vec3<int>((index / WORLD_HEIGHT) / CHUNK_SIZE,
|
|
|
|
|
- (index / WORLD_HEIGHT) % CHUNK_SIZE,
|
|
|
|
|
- index % WORLD_HEIGHT));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
cs.unlock();
|
|
cs.unlock();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+Chunk* Chunk::zNeighbor(Direction dir) const
|
|
|
|
|
+{
|
|
|
|
|
+ return zNeighbours[getDirectionIndex(dir)];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void Chunk::load(Framework::StreamReader* zReader)
|
|
void Chunk::load(Framework::StreamReader* zReader)
|
|
|
{
|
|
{
|
|
|
for (int index = 0; index < WORLD_HEIGHT * CHUNK_SIZE * CHUNK_SIZE; index++)
|
|
for (int index = 0; index < WORLD_HEIGHT * CHUNK_SIZE * CHUNK_SIZE; index++)
|
|
@@ -1074,26 +1060,26 @@ void Chunk::load(Framework::StreamReader* zReader)
|
|
|
|
|
|
|
|
void Chunk::save(Framework::StreamWriter* zWriter)
|
|
void Chunk::save(Framework::StreamWriter* zWriter)
|
|
|
{
|
|
{
|
|
|
- for (int index = 0; index < WORLD_HEIGHT * CHUNK_SIZE * CHUNK_SIZE; index++)
|
|
|
|
|
|
|
+ for (int index = 0; index < CHUNK_SIZE * CHUNK_SIZE; index++)
|
|
|
{
|
|
{
|
|
|
- unsigned short blockType
|
|
|
|
|
- = blocks[index]
|
|
|
|
|
- ? (unsigned short)blocks[index]->zBlockType()->getId()
|
|
|
|
|
- : blockIds[index];
|
|
|
|
|
- zWriter->schreibe((char*)&blockType, 2);
|
|
|
|
|
- if (blockType)
|
|
|
|
|
|
|
+ for (int z = 0; z < WORLD_HEIGHT; z++)
|
|
|
{
|
|
{
|
|
|
- if (blocks[index])
|
|
|
|
|
- {
|
|
|
|
|
- bool d = 1;
|
|
|
|
|
- zWriter->schreibe((char*)&d, 1);
|
|
|
|
|
- Game::INSTANCE->zBlockType(blockType)->saveBlock(
|
|
|
|
|
- blocks[index], zWriter);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
|
|
+ unsigned short blockType = blockIds[z] ? blockIds[z][index] : 0;
|
|
|
|
|
+ zWriter->schreibe((char*)&blockType, 2);
|
|
|
|
|
+ if (blockType)
|
|
|
{
|
|
{
|
|
|
- bool d = 0;
|
|
|
|
|
- zWriter->schreibe((char*)&d, 1);
|
|
|
|
|
|
|
+ if (blocks[z] && blocks[z][index])
|
|
|
|
|
+ {
|
|
|
|
|
+ bool d = 1;
|
|
|
|
|
+ zWriter->schreibe((char*)&d, 1);
|
|
|
|
|
+ Game::INSTANCE->zBlockType(blockType)->saveBlock(
|
|
|
|
|
+ blocks[z][index], zWriter);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ bool d = 0;
|
|
|
|
|
+ zWriter->schreibe((char*)&d, 1);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -1101,48 +1087,17 @@ void Chunk::save(Framework::StreamWriter* zWriter)
|
|
|
|
|
|
|
|
void Chunk::removeUnusedBlocks()
|
|
void Chunk::removeUnusedBlocks()
|
|
|
{
|
|
{
|
|
|
-/* for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
|
|
|
|
|
-{
|
|
|
|
|
- if (!blocks[i] && blockIds[i])
|
|
|
|
|
- {
|
|
|
|
|
- int x = (i / WORLD_HEIGHT) / CHUNK_SIZE;
|
|
|
|
|
- int y = (i / WORLD_HEIGHT) % CHUNK_SIZE;
|
|
|
|
|
- int z = i % WORLD_HEIGHT;
|
|
|
|
|
- bool visible = 0;
|
|
|
|
|
- if (CONST_BLOCK(0, blockIds[i])->isTransparent()
|
|
|
|
|
- || CONST_BLOCK(0, blockIds[i])->isPassable())
|
|
|
|
|
- visible = 1;
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- for (int d = 0; d < 6 && !visible; d++)
|
|
|
|
|
- {
|
|
|
|
|
- auto n = zBlockNeighbor(
|
|
|
|
|
- getDirection((Directions)getDirectionFromIndex(d))
|
|
|
|
|
- + Framework::Vec3<int>(x, y, z),
|
|
|
|
|
- 0);
|
|
|
|
|
- if (n.isA()
|
|
|
|
|
- && (((Block*)n)->isPassable()
|
|
|
|
|
- || ((Block*)n)->isTransparent()))
|
|
|
|
|
- visible = 1;
|
|
|
|
|
- if (n.isB()
|
|
|
|
|
- && (CONST_BLOCK(0, n)->isTransparent()
|
|
|
|
|
- || CONST_BLOCK(0, n)->isPassable()))
|
|
|
|
|
- visible = 1;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (!visible)
|
|
|
|
|
- {
|
|
|
|
|
- putBlockAt({x, y, z}, 0);
|
|
|
|
|
- putBlockTypeAt({x, y, z}, 0);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-}*/
|
|
|
|
|
|
|
+ // no longer needed becaus only used blocks are generated in the first place
|
|
|
#ifdef _DEBUG
|
|
#ifdef _DEBUG
|
|
|
int count = 0;
|
|
int count = 0;
|
|
|
- for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
|
|
|
|
|
|
|
+ for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++)
|
|
|
{
|
|
{
|
|
|
- if (Game::INSTANCE->zBlockType(blockIds[i])->doesNeedClientInstance())
|
|
|
|
|
- count++;
|
|
|
|
|
|
|
+ for (int z = 0; z < WORLD_HEIGHT; z++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (Game::INSTANCE->zBlockType(blockIds[z] ? blockIds[z][i] : 0)
|
|
|
|
|
+ ->doesNeedClientInstance())
|
|
|
|
|
+ count++;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
Framework::Logging::debug()
|
|
Framework::Logging::debug()
|
|
|
<< "chunk " << location.x << ", " << location.y
|
|
<< "chunk " << location.x << ", " << location.y
|
|
@@ -1157,18 +1112,24 @@ int Chunk::getDimensionId() const
|
|
|
|
|
|
|
|
void Chunk::onLoaded()
|
|
void Chunk::onLoaded()
|
|
|
{
|
|
{
|
|
|
- for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
|
|
|
|
|
|
|
+ for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++)
|
|
|
{
|
|
{
|
|
|
- if (blocks[i]) blocks[i]->onLoaded();
|
|
|
|
|
|
|
+ for (int z = 0; z < WORLD_HEIGHT; z++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (blocks[z] && blocks[z][i]) blocks[z][i]->onLoaded();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
currentlyLoading = 0;
|
|
currentlyLoading = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Chunk::onUnloaded()
|
|
void Chunk::onUnloaded()
|
|
|
{
|
|
{
|
|
|
- for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
|
|
|
|
|
|
|
+ for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE; i++)
|
|
|
{
|
|
{
|
|
|
- if (blocks[i]) blocks[i]->onUnloaded();
|
|
|
|
|
|
|
+ for (int z = 0; z < WORLD_HEIGHT; z++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (blocks[z] && blocks[z][i]) blocks[z][i]->onUnloaded();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1216,7 +1177,9 @@ bool Chunk::hasObservers() const
|
|
|
|
|
|
|
|
unsigned char* Chunk::getLightData(Framework::Vec3<int> location) const
|
|
unsigned char* Chunk::getLightData(Framework::Vec3<int> location) const
|
|
|
{
|
|
{
|
|
|
- int index = Chunk::index(location) * 6;
|
|
|
|
|
|
|
+ int index
|
|
|
|
|
+ = (Chunk::index(location.x, location.y) * WORLD_HEIGHT + location.z)
|
|
|
|
|
+ * 6;
|
|
|
assert(index < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * 6);
|
|
assert(index < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT * 6);
|
|
|
return lightData + index;
|
|
return lightData + index;
|
|
|
}
|
|
}
|
|
@@ -1224,8 +1187,8 @@ unsigned char* Chunk::getLightData(Framework::Vec3<int> location) const
|
|
|
void Chunk::setLightData(
|
|
void Chunk::setLightData(
|
|
|
Framework::Vec3<int> location, unsigned char* data, bool foreground)
|
|
Framework::Vec3<int> location, unsigned char* data, bool foreground)
|
|
|
{
|
|
{
|
|
|
- int index = Chunk::index(location);
|
|
|
|
|
- memcpy(lightData + index * 6, data, 6);
|
|
|
|
|
|
|
+ int index = Chunk::index(location.x, location.y);
|
|
|
|
|
+ memcpy(lightData + (index * WORLD_HEIGHT + location.z) * 6, data, 6);
|
|
|
// check if neighbor is a visible block and send update to clients
|
|
// check if neighbor is a visible block and send update to clients
|
|
|
bool needSend = 0;
|
|
bool needSend = 0;
|
|
|
for (int i = 0; i < 6; i++)
|
|
for (int i = 0; i < 6; i++)
|
|
@@ -1237,8 +1200,8 @@ void Chunk::setLightData(
|
|
|
if (pos.x >= 0 && pos.x < CHUNK_SIZE && pos.y >= 0
|
|
if (pos.x >= 0 && pos.x < CHUNK_SIZE && pos.y >= 0
|
|
|
&& pos.y < CHUNK_SIZE)
|
|
&& pos.y < CHUNK_SIZE)
|
|
|
{
|
|
{
|
|
|
- int bi = (pos.x * CHUNK_SIZE + pos.y) * WORLD_HEIGHT + pos.z;
|
|
|
|
|
- int type = blockIds[bi];
|
|
|
|
|
|
|
+ int bi = (pos.x * CHUNK_SIZE + pos.y);
|
|
|
|
|
+ int type = blockIds[pos.z] ? blockIds[pos.z][bi] : 0;
|
|
|
needSend |= Game::INSTANCE->zBlockType(type)
|
|
needSend |= Game::INSTANCE->zBlockType(type)
|
|
|
->doesNeedClientInstance();
|
|
->doesNeedClientInstance();
|
|
|
if (needSend) break;
|
|
if (needSend) break;
|
|
@@ -1260,18 +1223,21 @@ void Chunk::setLightData(
|
|
|
}
|
|
}
|
|
|
if (needSend)
|
|
if (needSend)
|
|
|
{
|
|
{
|
|
|
- broadcastLightData(index, foreground);
|
|
|
|
|
|
|
+ broadcastLightData(location.z, index, foreground);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int Chunk::getBlockTypeAt(Framework::Vec3<int> location) const
|
|
int Chunk::getBlockTypeAt(Framework::Vec3<int> location) const
|
|
|
{
|
|
{
|
|
|
- return blockIds[index(location)];
|
|
|
|
|
|
|
+ return blockIds[location.z]
|
|
|
|
|
+ ? blockIds[location.z][index(location.x, location.y)]
|
|
|
|
|
+ : 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int Chunk::getBlockTypeAtWC(int x, int y, int z) const
|
|
int Chunk::getBlockTypeAtWC(int x, int y, int z) const
|
|
|
{
|
|
{
|
|
|
- return blockIds[index(Dimension::chunkCoordinates({x, y, z}))];
|
|
|
|
|
|
|
+ auto pos = Dimension::chunkCoordinates({x, y, z});
|
|
|
|
|
+ return blockIds[pos.z] ? blockIds[pos.z][index(pos.x, pos.y)] : 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Chunk::onEntityEnters(Entity* zEntity, Chunk* lastChunk)
|
|
void Chunk::onEntityEnters(Entity* zEntity, Chunk* lastChunk)
|