From 31c2c3abb5badb414539c8640d6cf2868854bcaf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Oct 2020 16:25:21 +0000 Subject: [PATCH] SubChunkExplorer::moveTo() now returns a status this can be used by SubChunkExplorer subclasses to implement specialized logic. --- src/world/Explosion.php | 3 +- src/world/SimpleChunkManager.php | 5 +-- src/world/light/BlockLightUpdate.php | 3 +- src/world/light/LightUpdate.php | 9 +++--- src/world/light/SkyLightUpdate.php | 3 +- src/world/utils/SubChunkExplorer.php | 17 +++++++--- src/world/utils/SubChunkExplorerStatus.php | 37 ++++++++++++++++++++++ 7 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 src/world/utils/SubChunkExplorerStatus.php diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 49952a306..41e24ed6d 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -40,6 +40,7 @@ use pocketmine\math\Vector3; use pocketmine\world\particle\HugeExplodeSeedParticle; use pocketmine\world\sound\ExplodeSound; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; use function ceil; use function floor; use function mt_rand; @@ -123,7 +124,7 @@ class Explosion{ $pointerY += $shiftY; $pointerZ += $shiftZ; - if(!$this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ, false)){ + if($this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ, false) === SubChunkExplorerStatus::INVALID){ continue; } diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 9ffeab334..5540ad51b 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -29,6 +29,7 @@ use pocketmine\block\VanillaBlocks; use pocketmine\utils\Limits; use pocketmine\world\format\Chunk; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; class SimpleChunkManager implements ChunkManager{ @@ -50,14 +51,14 @@ class SimpleChunkManager implements ChunkManager{ } public function getBlockAt(int $x, int $y, int $z) : Block{ - if($this->terrainPointer->moveTo($x, $y, $z, false)){ + if($this->terrainPointer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ return BlockFactory::getInstance()->fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); } return VanillaBlocks::AIR(); } public function setBlockAt(int $x, int $y, int $z, Block $block) : void{ - if($this->terrainPointer->moveTo($x, $y, $z, true)){ + if($this->terrainPointer->moveTo($x, $y, $z, true) !== SubChunkExplorerStatus::INVALID){ $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); $this->terrainPointer->currentChunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); }else{ diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index 6a1fbfc73..323e5cd36 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; use function max; class BlockLightUpdate extends LightUpdate{ @@ -50,7 +51,7 @@ class BlockLightUpdate extends LightUpdate{ } public function recalculateNode(int $x, int $y, int $z) : void{ - if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ $block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); } diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index afa029ed3..639e3416a 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -25,6 +25,7 @@ namespace pocketmine\world\light; use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; use function max; @@ -65,7 +66,7 @@ abstract class LightUpdate{ abstract public function recalculateNode(int $x, int $y, int $z) : void; protected function getEffectiveLight(int $x, int $y, int $z) : int{ - if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ return $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); } return 0; @@ -95,7 +96,7 @@ abstract class LightUpdate{ private function prepareNodes() : LightPropagationContext{ $context = new LightPropagationContext(); foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ - if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ $oldLevel = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($oldLevel !== $newLevel){ @@ -131,7 +132,7 @@ abstract class LightUpdate{ ]; foreach($points as [$cx, $cy, $cz]){ - if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false)){ + if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false) !== SubChunkExplorerStatus::INVALID){ $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight, $context); }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($context->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ $context->spreadVisited[$index] = true; @@ -161,7 +162,7 @@ abstract class LightUpdate{ ]; foreach($points as [$cx, $cy, $cz]){ - if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false)){ + if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false) !== SubChunkExplorerStatus::INVALID){ $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight, $context); } } diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 02189a8e2..6927463cb 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; use function max; @@ -59,7 +60,7 @@ class SkyLightUpdate extends LightUpdate{ } public function recalculateNode(int $x, int $y, int $z) : void{ - if(!$this->subChunkExplorer->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false) === SubChunkExplorerStatus::INVALID){ return; } $chunk = $this->subChunkExplorer->currentChunk; diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index a50226bbb..18f9b3b7d 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -55,7 +55,10 @@ class SubChunkExplorer{ $this->world = $world; } - public function moveTo(int $x, int $y, int $z, bool $create) : bool{ + /** + * @phpstan-return SubChunkExplorerStatus::* + */ + public function moveTo(int $x, int $y, int $z, bool $create) : int{ if($this->currentChunk === null or $this->currentX !== ($x >> 4) or $this->currentZ !== ($z >> 4)){ $this->currentX = $x >> 4; $this->currentZ = $z >> 4; @@ -63,7 +66,7 @@ class SubChunkExplorer{ $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ, $create); if($this->currentChunk === null){ - return false; + return SubChunkExplorerStatus::INVALID; } } @@ -72,7 +75,7 @@ class SubChunkExplorer{ if($this->currentY < 0 or $this->currentY >= $this->currentChunk->getHeight()){ $this->currentSubChunk = null; - return false; + return SubChunkExplorerStatus::INVALID; } $newSubChunk = $this->currentChunk->getSubChunk($y >> 4); @@ -81,12 +84,16 @@ class SubChunkExplorer{ if($this->onSubChunkChangeFunc !== null){ ($this->onSubChunkChangeFunc)(); } + return SubChunkExplorerStatus::MOVED; } - return true; + return SubChunkExplorerStatus::OK; } - public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ, bool $create) : bool{ + /** + * @phpstan-return SubChunkExplorerStatus::* + */ + public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ, bool $create) : int{ //this is a cold path, so we don't care much if it's a bit slower (extra fcall overhead) return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4, $create); } diff --git a/src/world/utils/SubChunkExplorerStatus.php b/src/world/utils/SubChunkExplorerStatus.php new file mode 100644 index 000000000..43b32f1fa --- /dev/null +++ b/src/world/utils/SubChunkExplorerStatus.php @@ -0,0 +1,37 @@ +