diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index de5b21577..833e31902 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -476,6 +476,15 @@ class Chunk{ } } + public function __clone(){ + //we don't bother cloning entities or tiles since it's impractical to do so (too many dependencies) + $this->subChunks = \SplFixedArray::fromArray(array_map(function(SubChunk $subChunk) : SubChunk{ + return clone $subChunk; + }, $this->subChunks->toArray())); + $this->heightMap = clone $this->heightMap; + $this->biomeIds = clone $this->biomeIds; + } + /** * Hashes the given chunk block coordinates into a single integer. * diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 46026b833..5328d816a 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format; +use function array_map; use function array_values; use function count; @@ -141,4 +142,13 @@ class SubChunk{ $this->skyLight->collectGarbage(); $this->blockLight->collectGarbage(); } + + public function __clone(){ + $this->blockLayers = array_map(function(PalettedBlockArray $array) : PalettedBlockArray{ + return clone $array; + }, $this->blockLayers); + + $this->skyLight = clone $this->skyLight; + $this->blockLight = clone $this->blockLight; + } } diff --git a/tests/phpunit/world/format/ChunkTest.php b/tests/phpunit/world/format/ChunkTest.php new file mode 100644 index 000000000..17d277b52 --- /dev/null +++ b/tests/phpunit/world/format/ChunkTest.php @@ -0,0 +1,45 @@ +setFullBlock(0, 0, 0, 1); + $chunk->setBiomeId(0, 0, 1); + $chunk->setHeightMap(0, 0, 1); + + $chunk2 = clone $chunk; + $chunk2->setFullBlock(0, 0, 0, 2); + $chunk2->setBiomeId(0, 0, 2); + $chunk2->setHeightMap(0, 0, 2); + + self::assertNotSame($chunk->getFullBlock(0, 0, 0), $chunk2->getFullBlock(0, 0, 0)); + self::assertNotSame($chunk->getBiomeId(0, 0), $chunk2->getBiomeId(0, 0)); + self::assertNotSame($chunk->getHeightMap(0, 0), $chunk2->getHeightMap(0, 0)); + } +} diff --git a/tests/phpunit/world/format/SubChunkTest.php b/tests/phpunit/world/format/SubChunkTest.php new file mode 100644 index 000000000..61fd9dee1 --- /dev/null +++ b/tests/phpunit/world/format/SubChunkTest.php @@ -0,0 +1,50 @@ +setFullBlock(0, 0, 0, 1); + $sub1->getBlockLightArray()->set(0, 0, 0, 1); + $sub1->getBlockSkyLightArray()->set(0, 0, 0, 1); + + $sub2 = clone $sub1; + + $sub2->setFullBlock(0, 0, 0, 2); + $sub2->getBlockLightArray()->set(0, 0, 0, 2); + $sub2->getBlockSkyLightArray()->set(0, 0, 0, 2); + + self::assertNotSame($sub1->getFullBlock(0, 0, 0), $sub2->getFullBlock(0, 0, 0)); + self::assertNotSame($sub1->getBlockLightArray()->get(0, 0, 0), $sub2->getBlockLightArray()->get(0, 0, 0)); + self::assertNotSame($sub1->getBlockSkyLightArray()->get(0, 0, 0), $sub2->getBlockSkyLightArray()->get(0, 0, 0)); + } +}