diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/pocketmine/block/GlowingObsidian.php index e3ee02ba8..26b55cfd2 100644 --- a/src/pocketmine/block/GlowingObsidian.php +++ b/src/pocketmine/block/GlowingObsidian.php @@ -22,7 +22,7 @@ namespace pocketmine\block; -class GlowingObsidian extends Transparent{ +class GlowingObsidian extends Solid{ protected $id = self::GLOWING_OBSIDIAN; diff --git a/src/pocketmine/block/RedstoneTorch.php b/src/pocketmine/block/RedstoneTorch.php index ca7f7f352..32e4bb77a 100644 --- a/src/pocketmine/block/RedstoneTorch.php +++ b/src/pocketmine/block/RedstoneTorch.php @@ -32,4 +32,8 @@ class RedstoneTorch extends Torch{ public function getName(){ return "Redstone Torch"; } + + public function getLightLevel(){ + return 7; + } } diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index c71bd957a..78cf35e82 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -34,7 +34,7 @@ class Torch extends Flowable{ } public function getLightLevel(){ - return 15; + return 14; } public function getName(){ diff --git a/src/pocketmine/event/LevelTimings.php b/src/pocketmine/event/LevelTimings.php index ef78dcbd2..52a0ce6fb 100644 --- a/src/pocketmine/event/LevelTimings.php +++ b/src/pocketmine/event/LevelTimings.php @@ -25,6 +25,13 @@ use pocketmine\level\Level; class LevelTimings{ + /** @var TimingsHandler */ + public $setBlock; + /** @var TimingsHandler */ + public $doBlockLightUpdates; + /** @var TimingsHandler */ + public $doBlockSkyLightUpdates; + /** @var TimingsHandler */ public $mobSpawn; /** @var TimingsHandler */ @@ -79,6 +86,10 @@ class LevelTimings{ public function __construct(Level $level){ $name = $level->getFolderName() . " - "; + $this->setBlock = new TimingsHandler("** " . $name . "setBlock"); + $this->doBlockLightUpdates = new TimingsHandler("** " . $name . "doBlockLightUpdates"); + $this->doBlockSkyLightUpdates = new TimingsHandler("** " . $name . "doBlockSkyLightUpdates"); + $this->mobSpawn = new TimingsHandler("** " . $name . "mobSpawn"); $this->doChunkUnload = new TimingsHandler("** " . $name . "doChunkUnload"); $this->doTickPending = new TimingsHandler("** " . $name . "doTickPending"); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 8641622b4..a5178d3e6 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1286,17 +1286,42 @@ class Level implements ChunkManager, Metadatable{ } public function updateBlockSkyLight(int $x, int $y, int $z){ + $this->timings->doBlockSkyLightUpdates->startTiming(); //TODO + $this->timings->doBlockSkyLightUpdates->stopTiming(); + } + + /** + * Returns the highest light level available in the positions adjacent to the specified block coordinates. + * + * @param int $x + * @param int $y + * @param int $z + * + * @return int + */ + public function getHighestAdjacentBlockLight(int $x, int $y, int $z) : int{ + return max([ + $this->getBlockLightAt($x + 1, $y, $z), + $this->getBlockLightAt($x - 1, $y, $z), + $this->getBlockLightAt($x, $y + 1, $z), + $this->getBlockLightAt($x, $y - 1, $z), + $this->getBlockLightAt($x, $y, $z + 1), + $this->getBlockLightAt($x, $y, $z - 1) + ]); } public function updateBlockLight(int $x, int $y, int $z){ + $this->timings->doBlockLightUpdates->startTiming(); + $lightPropagationQueue = new \SplQueue(); $lightRemovalQueue = new \SplQueue(); $visited = []; $removalVisited = []; + $id = $this->getBlockIdAt($x, $y, $z); $oldLevel = $this->getBlockLightAt($x, $y, $z); - $newLevel = (int) Block::$light[$this->getBlockIdAt($x, $y, $z)]; + $newLevel = max(Block::$light[$id], $this->getHighestAdjacentBlockLight($x, $y, $z) - Block::$lightFilter[$id]); if($oldLevel !== $newLevel){ $this->setBlockLightAt($x, $y, $z, $newLevel); @@ -1328,7 +1353,7 @@ class Level implements ChunkManager, Metadatable{ /** @var Vector3 $node */ $node = $lightPropagationQueue->dequeue(); - $lightLevel = $this->getBlockLightAt($node->x, $node->y, $node->z) - (int) Block::$lightFilter[$this->getBlockIdAt($node->x, $node->y, $node->z)]; + $lightLevel = $this->getBlockLightAt($node->x, $node->y, $node->z); if($lightLevel >= 1){ $this->computeSpreadBlockLight($node->x - 1, $node->y, $node->z, $lightLevel, $lightPropagationQueue, $visited); @@ -1339,6 +1364,8 @@ class Level implements ChunkManager, Metadatable{ $this->computeSpreadBlockLight($node->x, $node->y, $node->z + 1, $lightLevel, $lightPropagationQueue, $visited); } } + + $this->timings->doBlockLightUpdates->stopTiming(); } private function computeRemoveBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, \SplQueue $spreadQueue, array &$visited, array &$spreadVisited){ @@ -1365,6 +1392,7 @@ class Level implements ChunkManager, Metadatable{ private function computeSpreadBlockLight(int $x, int $y, int $z, int $currentLight, \SplQueue $queue, array &$visited){ if($y < 0) return; $current = $this->getBlockLightAt($x, $y, $z); + $currentLight -= Block::$lightFilter[$this->getBlockIdAt($x, $y, $z)]; if($current < $currentLight){ $this->setBlockLightAt($x, $y, $z, $currentLight); @@ -1402,6 +1430,8 @@ class Level implements ChunkManager, Metadatable{ return false; } + $this->timings->setBlock->startTiming(); + if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & Level::Y_MASK, $pos->z & 0x0f, $block->getId(), $block->getDamage())){ if(!($pos instanceof Position)){ $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); @@ -1441,9 +1471,13 @@ class Level implements ChunkManager, Metadatable{ $this->updateAround($pos); } + $this->timings->setBlock->stopTiming(); + return true; } + $this->timings->setBlock->stopTiming(); + return false; }