diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index ce8394914..5d9d4a1d4 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -247,6 +247,11 @@ class Level implements ChunkManager, Metadatable{ /** @var bool */ private $closed = false; + /** @var BlockLightUpdate|null */ + private $blockLightUpdate = null; + /** @var SkyLightUpdate|null */ + private $skyLightUpdate = null; + public static function chunkHash(int $x, int $z) : int{ return (($x & 0xFFFFFFFF) << 32) | ($z & 0xFFFFFFFF); } @@ -764,6 +769,8 @@ class Level implements ChunkManager, Metadatable{ $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); + $this->executeQueuedLightUpdates(); + if(count($this->changedBlocks) > 0){ if(count($this->players) > 0){ foreach($this->changedBlocks as $index => $blocks){ @@ -1417,22 +1424,21 @@ class Level implements ChunkManager, Metadatable{ $newHeightMap = $oldHeightMap; } - $update = new SkyLightUpdate($this); - + if($this->skyLightUpdate === null){ + $this->skyLightUpdate = new SkyLightUpdate($this); + } if($newHeightMap > $oldHeightMap){ //Heightmap increase, block placed, remove sky light for($i = $y; $i >= $oldHeightMap; --$i){ - $update->setAndUpdateLight($x, $i, $z, 0); //Remove all light beneath, adjacent recalculation will handle the rest. + $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 0); //Remove all light beneath, adjacent recalculation will handle the rest. } }elseif($newHeightMap < $oldHeightMap){ //Heightmap decrease, block changed or removed, add sky light for($i = $y; $i >= $newHeightMap; --$i){ - $update->setAndUpdateLight($x, $i, $z, 15); + $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 15); } }else{ //No heightmap change, block changed "underground" - $update->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[$sourceId])); + $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[$sourceId])); } - $update->execute(); - $this->timings->doBlockSkyLightUpdates->stopTiming(); } @@ -1462,13 +1468,30 @@ class Level implements ChunkManager, Metadatable{ $id = $this->getBlockIdAt($x, $y, $z); $newLevel = max(BlockFactory::$light[$id], $this->getHighestAdjacentBlockLight($x, $y, $z) - BlockFactory::$lightFilter[$id]); - $update = new BlockLightUpdate($this); - $update->setAndUpdateLight($x, $y, $z, $newLevel); - $update->execute(); + if($this->blockLightUpdate === null){ + $this->blockLightUpdate = new BlockLightUpdate($this); + } + $this->blockLightUpdate->setAndUpdateLight($x, $y, $z, $newLevel); $this->timings->doBlockLightUpdates->stopTiming(); } + public function executeQueuedLightUpdates() : void{ + if($this->blockLightUpdate !== null){ + $this->timings->doBlockLightUpdates->startTiming(); + $this->blockLightUpdate->execute(); + $this->blockLightUpdate = null; + $this->timings->doBlockLightUpdates->stopTiming(); + } + + if($this->skyLightUpdate !== null){ + $this->timings->doBlockSkyLightUpdates->startTiming(); + $this->skyLightUpdate->execute(); + $this->skyLightUpdate = null; + $this->timings->doBlockSkyLightUpdates->stopTiming(); + } + } + /** * Sets on Vector3 the data from a Block object, * does block updates and puts the changes to the send queue.