diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 6951c52a2..b3283f2aa 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -69,6 +69,11 @@ class BlockFactory{ */ private $fullList; + /** + * @var \SplFixedArray|int[] + * @phpstan-var \SplFixedArray + */ + public $light; /** * @var \SplFixedArray|int[] * @phpstan-var \SplFixedArray @@ -88,6 +93,7 @@ class BlockFactory{ public function __construct(){ $this->fullList = new \SplFixedArray(16384); + $this->light = \SplFixedArray::fromArray(array_fill(0, 16384, 0)); $this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 16384, 1)); $this->diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 16384, false)); $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 16384, 0.0)); @@ -850,6 +856,7 @@ class BlockFactory{ private function fillStaticArrays(int $index, Block $block) : void{ $this->fullList[$index] = $block; + $this->light[$index] = $block->getLightLevel(); $this->lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter $this->diffusesSkyLight[$index] = $block->diffusesSkyLight(); $this->blastResistance[$index] = $block->getBreakInfo()->getBlastResistance(); diff --git a/src/world/World.php b/src/world/World.php index eed6459f6..04d19825c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1162,16 +1162,17 @@ class World implements ChunkManager{ } public function updateAllLight(int $x, int $y, int $z) : void{ + $blockFactory = BlockFactory::getInstance(); $this->timings->doBlockSkyLightUpdates->startTiming(); if($this->skyLightUpdate === null){ - $this->skyLightUpdate = new SkyLightUpdate($this); + $this->skyLightUpdate = new SkyLightUpdate($this, $blockFactory->lightFilter, $blockFactory->diffusesSkyLight); } $this->skyLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockSkyLightUpdates->stopTiming(); $this->timings->doBlockLightUpdates->startTiming(); if($this->blockLightUpdate === null){ - $this->blockLightUpdate = new BlockLightUpdate($this); + $this->blockLightUpdate = new BlockLightUpdate($this, $blockFactory->lightFilter, $blockFactory->light); } $this->blockLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockLightUpdates->stopTiming(); diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index 266e84f4b..d1e2273b7 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -23,16 +23,34 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\block\BlockFactory; +use pocketmine\world\ChunkManager; use function max; class BlockLightUpdate extends LightUpdate{ + + /** + * @var \SplFixedArray|int[] + * @phpstan-var \SplFixedArray + */ + private $lightEmitters; + + /** + * @param \SplFixedArray|int[] $lightFilters + * @param \SplFixedArray|int[] $lightEmitters + * @phpstan-param \SplFixedArray $lightFilters + * @phpstan-param \SplFixedArray $lightEmitters + */ + public function __construct(ChunkManager $world, \SplFixedArray $lightFilters, \SplFixedArray $lightEmitters){ + parent::__construct($world, $lightFilters); + $this->lightEmitters = $lightEmitters; + } + protected function updateLightArrayRef() : void{ $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockLightArray(); } public function recalculateNode(int $x, int $y, int $z) : void{ $block = $this->world->getBlockAt($x, $y, $z); - $this->setAndUpdateLight($x, $y, $z, max($block->getLightLevel(), $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::getInstance()->lightFilter[$block->getFullId()])); + $this->setAndUpdateLight($x, $y, $z, max($block->getLightLevel(), $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block->getFullId()])); } } diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 03a70ad5c..e1159bea5 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\block\BlockFactory; use pocketmine\world\ChunkManager; use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkIteratorManager; @@ -36,6 +35,12 @@ abstract class LightUpdate{ /** @var ChunkManager */ protected $world; + /** + * @var \SplFixedArray|int[] + * @phpstan-var \SplFixedArray + */ + protected $lightFilters; + /** * @var int[][] blockhash => [x, y, z, new light level] * @phpstan-var array @@ -69,8 +74,14 @@ abstract class LightUpdate{ /** @var LightArray|null */ protected $currentLightArray = null; - public function __construct(ChunkManager $world){ + /** + * @param \SplFixedArray|int[] $lightFilters + * @phpstan-param \SplFixedArray $lightFilters + */ + public function __construct(ChunkManager $world, \SplFixedArray $lightFilters){ $this->world = $world; + $this->lightFilters = $lightFilters; + $this->removalQueue = new \SplQueue(); $this->spreadQueue = new \SplQueue(); @@ -208,7 +219,7 @@ abstract class LightUpdate{ protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel) : void{ $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); - $potentialLight = $newAdjacentLevel - BlockFactory::getInstance()->lightFilter[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; + $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; if($current < $potentialLight){ $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 290537da9..7c1d5634e 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -23,11 +23,29 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\block\BlockFactory; +use pocketmine\world\ChunkManager; use pocketmine\world\World; use function max; class SkyLightUpdate extends LightUpdate{ + + /** + * @var \SplFixedArray|bool[] + * @phpstan-var \SplFixedArray + */ + private $lightDiffusers; + + /** + * @param \SplFixedArray|int[] $lightFilters + * @param \SplFixedArray|bool[] $lightDiffusers + * @phpstan-param \SplFixedArray $lightFilters + * @phpstan-param \SplFixedArray $lightDiffusers + */ + public function __construct(ChunkManager $world, \SplFixedArray $lightFilters, \SplFixedArray $lightDiffusers){ + parent::__construct($world, $lightFilters); + $this->lightDiffusers = $lightDiffusers; + } + protected function updateLightArrayRef() : void{ $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockSkyLightArray(); } @@ -51,7 +69,7 @@ class SkyLightUpdate extends LightUpdate{ $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, BlockFactory::getInstance()->lightFilter, BlockFactory::getInstance()->diffusesSkyLight); + $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, $this->lightFilters, $this->lightDiffusers); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. if($source->getLightFilter() > 0 or $source->diffusesSkyLight()){ $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); @@ -72,7 +90,7 @@ class SkyLightUpdate extends LightUpdate{ $this->setAndUpdateLight($x, $i, $z, 15); } }else{ //No heightmap change, block changed "underground" - $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::getInstance()->lightFilter[$source->getFullId()])); + $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$source->getFullId()])); } } }