|
@@ -17,6 +17,7 @@ Chunk::Chunk(Framework::Punkt location, int dimensionId)
|
|
|
dimensionId(dimensionId),
|
|
|
location(location),
|
|
|
added(0),
|
|
|
+ worldUpdated(1),
|
|
|
currentlyLoading(1)
|
|
|
{
|
|
|
blocks = new Block*[CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT];
|
|
@@ -64,8 +65,20 @@ void Chunk::unlock()
|
|
|
|
|
|
void Chunk::tick(TickQueue* zQueue)
|
|
|
{
|
|
|
- for (Block* source : tickSources)
|
|
|
+ for (Block* source : tickSourcesEachTick)
|
|
|
zQueue->addToQueue(source);
|
|
|
+ if (worldUpdated)
|
|
|
+ {
|
|
|
+ worldUpdated = 0;
|
|
|
+ for (Block* source : tickSourcesAfterUpdate)
|
|
|
+ {
|
|
|
+ if (source->needsTick())
|
|
|
+ {
|
|
|
+ zQueue->addToQueue(source);
|
|
|
+ worldUpdated = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void Chunk::postTick() {}
|
|
@@ -287,7 +300,7 @@ void Chunk::broadcastLightData(int index, bool foreground)
|
|
|
}
|
|
|
|
|
|
Framework::Either<Block*, int> Chunk::zBlockNeighbor(
|
|
|
- Framework::Vec3<int> location)
|
|
|
+ Framework::Vec3<int> location, OUT Chunk** zNeighborChunk)
|
|
|
{
|
|
|
if (location.x >= 0 && location.x < CHUNK_SIZE && location.y >= 0
|
|
|
&& location.y < CHUNK_SIZE && location.z >= 0
|
|
@@ -295,6 +308,10 @@ Framework::Either<Block*, int> Chunk::zBlockNeighbor(
|
|
|
{
|
|
|
int index = (location.x * CHUNK_SIZE + location.y) * WORLD_HEIGHT
|
|
|
+ location.z;
|
|
|
+ if (zNeighborChunk)
|
|
|
+ {
|
|
|
+ *zNeighborChunk = this;
|
|
|
+ }
|
|
|
if (blocks[index])
|
|
|
return blocks[index];
|
|
|
else
|
|
@@ -305,7 +322,8 @@ Framework::Either<Block*, int> Chunk::zBlockNeighbor(
|
|
|
{location.x + this->location.x - CHUNK_SIZE / 2,
|
|
|
location.y + this->location.y - CHUNK_SIZE / 2,
|
|
|
location.z},
|
|
|
- dimensionId);
|
|
|
+ dimensionId,
|
|
|
+ zNeighborChunk);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -541,15 +559,34 @@ 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];
|
|
|
- if (old && old->isTickSource())
|
|
|
+ if (old && old->isTickSource() != TickSourceType::NONE)
|
|
|
{ // remove from tick sorces
|
|
|
- for (Framework::ArrayIterator<Block*> obj = tickSources.begin(); obj;
|
|
|
- obj++)
|
|
|
+ if (old->isTickSource() == TickSourceType::EACH_TICK)
|
|
|
+ {
|
|
|
+ for (Framework::ArrayIterator<Block*> obj
|
|
|
+ = tickSourcesEachTick.begin();
|
|
|
+ obj;
|
|
|
+ obj++)
|
|
|
+ {
|
|
|
+ if (obj.val() == old)
|
|
|
+ {
|
|
|
+ obj.remove();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (old->isTickSource() == TickSourceType::AFTER_WORLD_UPDATE)
|
|
|
{
|
|
|
- if (obj.val() == old)
|
|
|
+ for (Framework::ArrayIterator<Block*> obj
|
|
|
+ = tickSourcesAfterUpdate.begin();
|
|
|
+ obj;
|
|
|
+ obj++)
|
|
|
{
|
|
|
- obj.remove();
|
|
|
- break;
|
|
|
+ if (obj.val() == old)
|
|
|
+ {
|
|
|
+ obj.remove();
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -577,8 +614,9 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
{
|
|
|
Direction d = getDirectionFromIndex(i);
|
|
|
+ Chunk* zNeighborChunk = 0;
|
|
|
Framework::Either<Block*, int> neighbor
|
|
|
- = zBlockNeighbor(location + getDirection(d));
|
|
|
+ = zBlockNeighbor(location + getDirection(d), &zNeighborChunk);
|
|
|
if (neighbor.isA())
|
|
|
{
|
|
|
if (block)
|
|
@@ -593,12 +631,24 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
|
|
|
}
|
|
|
}
|
|
|
if (block) block->setNeighbour(d, neighbor);
|
|
|
+ if (zNeighborChunk && zNeighborChunk != this)
|
|
|
+ {
|
|
|
+ zNeighborChunk->worldUpdated = 1;
|
|
|
+ }
|
|
|
}
|
|
|
if (old) old->release();
|
|
|
- if (block && block->isTickSource())
|
|
|
+ if (block && block->isTickSource() != TickSourceType::NONE)
|
|
|
{ // add to tick sources
|
|
|
- tickSources.add(block);
|
|
|
+ if (block->isTickSource() == TickSourceType::EACH_TICK)
|
|
|
+ {
|
|
|
+ tickSourcesEachTick.add(block);
|
|
|
+ }
|
|
|
+ else if (block->isTickSource() == TickSourceType::AFTER_WORLD_UPDATE)
|
|
|
+ {
|
|
|
+ tickSourcesAfterUpdate.add(block);
|
|
|
+ }
|
|
|
}
|
|
|
+ worldUpdated = 1;
|
|
|
if (change)
|
|
|
{
|
|
|
if (isLightSource != wasLightSource)
|
|
@@ -643,11 +693,16 @@ void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
{
|
|
|
Direction d = getDirectionFromIndex(i);
|
|
|
+ Chunk* zNeighborChunk = 0;
|
|
|
Framework::Either<Block*, int> neighbor
|
|
|
- = zBlockNeighbor(location + getDirection(d));
|
|
|
+ = zBlockNeighbor(location + getDirection(d), &zNeighborChunk);
|
|
|
if (neighbor.isA())
|
|
|
((Block*)neighbor)
|
|
|
->setNeighbourType(getOppositeDirection(d), type);
|
|
|
+ if (zNeighborChunk && zNeighborChunk != this)
|
|
|
+ {
|
|
|
+ zNeighborChunk->worldUpdated = 1;
|
|
|
+ }
|
|
|
}
|
|
|
if (isLightSource != wasLightSource)
|
|
|
{
|
|
@@ -669,6 +724,7 @@ void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
|
|
|
location.y + this->location.y - CHUNK_SIZE / 2,
|
|
|
location.z);
|
|
|
}
|
|
|
+ worldUpdated = 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -966,7 +1022,8 @@ void Chunk::removeUnusedBlocks()
|
|
|
{
|
|
|
auto n = zBlockNeighbor(
|
|
|
getDirection((Directions)getDirectionFromIndex(d))
|
|
|
- + Framework::Vec3<int>(x, y, z));
|
|
|
+ + Framework::Vec3<int>(x, y, z),
|
|
|
+ 0);
|
|
|
if (n.isA()
|
|
|
&& (((Block*)n)->isPassable()
|
|
|
|| ((Block*)n)->isTransparent()))
|