*/ private $lightEmitters; /** * @param \SplFixedArray|int[] $lightFilters * @param \SplFixedArray|int[] $lightEmitters * @phpstan-param \SplFixedArray $lightFilters * @phpstan-param \SplFixedArray $lightEmitters */ public function __construct(SubChunkExplorer $subChunkExplorer, \SplFixedArray $lightFilters, \SplFixedArray $lightEmitters){ parent::__construct($subChunkExplorer, $lightFilters); $this->lightEmitters = $lightEmitters; } protected function getCurrentLightArray() : LightArray{ return $this->subChunkExplorer->currentSubChunk->getBlockLightArray(); } public function recalculateNode(int $x, int $y, int $z) : void{ if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ $block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & SubChunk::COORD_MASK, $y & SubChunk::COORD_MASK, $z & SubChunk::COORD_MASK); $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); } } public function recalculateChunk(int $chunkX, int $chunkZ) : int{ if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ) === SubChunkExplorerStatus::INVALID){ throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist"); } $chunk = $this->subChunkExplorer->currentChunk; $lightSources = 0; foreach($chunk->getSubChunks() as $subChunkY => $subChunk){ $subChunk->setBlockLightArray(LightArray::fill(0)); foreach($subChunk->getBlockLayers() as $layer){ foreach($layer->getPalette() as $state){ if($this->lightEmitters[$state] > 0){ $lightSources += $this->scanForLightEmittingBlocks($subChunk, $chunkX << SubChunk::COORD_BIT_SIZE, $subChunkY << SubChunk::COORD_BIT_SIZE, $chunkZ << SubChunk::COORD_BIT_SIZE); break 2; } } } } return $lightSources; } private function scanForLightEmittingBlocks(SubChunk $subChunk, int $baseX, int $baseY, int $baseZ) : int{ $lightSources = 0; for($x = 0; $x < SubChunk::EDGE_LENGTH; ++$x){ for($z = 0; $z < SubChunk::EDGE_LENGTH; ++$z){ for($y = 0; $y < SubChunk::EDGE_LENGTH; ++$y){ $light = $this->lightEmitters[$subChunk->getFullBlock($x, $y, $z)]; if($light > 0){ $this->setAndUpdateLight( $baseX + $x, $baseY + $y, $baseZ + $z, $light ); $lightSources++; } } } } return $lightSources; } }