From fb03df3d06262fc31d6a56ce3966580bb2de08b4 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Wed, 6 May 2015 16:57:49 +0200 Subject: [PATCH] Calculate skylight on chunk population --- src/pocketmine/level/format/FullChunk.php | 6 ++++ src/pocketmine/level/format/anvil/Chunk.php | 11 ++++++ .../level/format/generic/BaseFullChunk.php | 36 +++++++++++++++++++ src/pocketmine/level/format/leveldb/Chunk.php | 5 ++- .../level/format/mcregion/Chunk.php | 14 ++++++-- .../level/generator/PopulationTask.php | 4 ++- 6 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/level/format/FullChunk.php b/src/pocketmine/level/format/FullChunk.php index f1406bda9..ac073e6cf 100644 --- a/src/pocketmine/level/format/FullChunk.php +++ b/src/pocketmine/level/format/FullChunk.php @@ -178,6 +178,8 @@ interface FullChunk{ public function recalculateHeightMap(); + public function populateSkyLight(); + /** * @param int $x 0-15 * @param int $z 0-15 @@ -218,6 +220,10 @@ interface FullChunk{ */ public function setBiomeColor($x, $z, $R, $G, $B); + public function isLightPopulated(); + + public function setLightPopulated($value = 1); + public function isPopulated(); public function setPopulated($value = 1); diff --git a/src/pocketmine/level/format/anvil/Chunk.php b/src/pocketmine/level/format/anvil/Chunk.php index 68de5afb4..7ad6ec951 100644 --- a/src/pocketmine/level/format/anvil/Chunk.php +++ b/src/pocketmine/level/format/anvil/Chunk.php @@ -90,6 +90,15 @@ class Chunk extends BaseChunk{ unset($this->nbt->Sections); } + public function isLightPopulated(){ + return $this->nbt["LightPopulated"] > 0; + } + + public function setLightPopulated($value = 1){ + $this->nbt->LightPopulated = new Byte("LightPopulated", $value); + $this->hasChanged = true; + } + /** * @return bool */ @@ -102,6 +111,7 @@ class Chunk extends BaseChunk{ */ public function setPopulated($value = 1){ $this->nbt->TerrainPopulated = new Byte("TerrainPopulated", $value); + $this->hasChanged = true; } /** @@ -116,6 +126,7 @@ class Chunk extends BaseChunk{ */ public function setGenerated($value = 1){ $this->nbt->TerrainGenerated = new Byte("TerrainGenerated", $value); + $this->hasChanged = true; } /** diff --git a/src/pocketmine/level/format/generic/BaseFullChunk.php b/src/pocketmine/level/format/generic/BaseFullChunk.php index bcd0bdfbe..ab1a4d56d 100644 --- a/src/pocketmine/level/format/generic/BaseFullChunk.php +++ b/src/pocketmine/level/format/generic/BaseFullChunk.php @@ -21,6 +21,7 @@ namespace pocketmine\level\format\generic; +use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\level\format\FullChunk; use pocketmine\level\format\LevelProvider; @@ -156,6 +157,12 @@ abstract class BaseFullChunk implements FullChunk{ $this->hasChanged = false; } + + if(!$this->isLightPopulated()){ + $this->recalculateHeightMap(); + $this->populateSkyLight(); + $this->setLightPopulated(); + } } public function getX(){ @@ -230,6 +237,27 @@ abstract class BaseFullChunk implements FullChunk{ } } + public function populateSkyLight(){ + for($z = 0; $z < 16; ++$z){ + for($x = 0; $x < 16; ++$x){ + $top = $this->getHeightMap($x, $z); + for($y = 127; $y > $top; --$y){ + $this->setBlockSkyLight($x, $y, $z, 15); + } + + for($y = $top; $y >= 0; --$y){ + if(Block::$solid[$this->getBlockId($x, $y, $z)]){ + break; + } + + $this->setBlockSkyLight($x, $y, $z, 15); + } + + $this->setHeightMap($x, $z, $this->getHighestBlockAt($x, $z, false)); + } + } + } + public function getHighestBlockAt($x, $z, $cache = true){ if($cache){ $h = $this->getHeightMap($x, $z); @@ -377,4 +405,12 @@ abstract class BaseFullChunk implements FullChunk{ return $this->toBinary(); } + public function isLightPopulated(){ + return true; + } + + public function setLightPopulated($value = 1){ + + } + } diff --git a/src/pocketmine/level/format/leveldb/Chunk.php b/src/pocketmine/level/format/leveldb/Chunk.php index cccff1335..9d92b8ae3 100644 --- a/src/pocketmine/level/format/leveldb/Chunk.php +++ b/src/pocketmine/level/format/leveldb/Chunk.php @@ -272,6 +272,9 @@ class Chunk extends BaseFullChunk{ if($flags & 0x02){ $chunk->setPopulated(); } + if($flags & 0x04){ + $chunk->setLightPopulated(); + } return $chunk; }catch(\Exception $e){ return null; @@ -333,7 +336,7 @@ class Chunk extends BaseFullChunk{ $this->getBlockLightArray() . $heightmap . $biomeColors . chr( - ($this->isPopulated() ? 0x02 : 0) | ($this->isGenerated() ? 0x01 : 0) + ($this->isLightPopulated() ? 0x04 : 0) | ($this->isPopulated() ? 0x02 : 0) | ($this->isGenerated() ? 0x01 : 0) ); } } diff --git a/src/pocketmine/level/format/mcregion/Chunk.php b/src/pocketmine/level/format/mcregion/Chunk.php index fce045984..81d1e6bf9 100644 --- a/src/pocketmine/level/format/mcregion/Chunk.php +++ b/src/pocketmine/level/format/mcregion/Chunk.php @@ -231,6 +231,15 @@ class Chunk extends BaseFullChunk{ return substr($this->blockLight, ($x << 10) + ($z << 6), 64); } + public function isLightPopulated(){ + return $this->nbt["LightPopulated"] > 0; + } + + public function setLightPopulated($value = 1){ + $this->nbt->LightPopulated = new Byte("LightPopulated", $value); + $this->hasChanged = true; + } + /** * @return bool */ @@ -325,7 +334,8 @@ class Chunk extends BaseFullChunk{ $flags = ord($data{$offset++}); $chunk->nbt->TerrainGenerated = new Byte("TerrainGenerated", $flags & 0b1); - $chunk->nbt->TerrainPopulated = new Byte("TerrainPopulated", $flags >> 1); + $chunk->nbt->TerrainPopulated = new Byte("TerrainPopulated", ($flags >> 1) & 0b1); + $chunk->nbt->LightPopulated = new Byte("LightPopulated", ($flags >> 2) & 0b1); return $chunk; }catch(\Exception $e){ @@ -346,7 +356,7 @@ class Chunk extends BaseFullChunk{ $this->getBlockLightArray() . $heightMap . $biomeColors . - chr(($this->isPopulated() ? 1 << 1 : 0) + ($this->isGenerated() ? 1 : 0)); + chr(($this->isLightPopulated() ? 1 << 2 : 0) + ($this->isPopulated() ? 1 << 1 : 0) + ($this->isGenerated() ? 1 : 0)); } public function toBinary(){ diff --git a/src/pocketmine/level/generator/PopulationTask.php b/src/pocketmine/level/generator/PopulationTask.php index a484f9862..22ac23e83 100644 --- a/src/pocketmine/level/generator/PopulationTask.php +++ b/src/pocketmine/level/generator/PopulationTask.php @@ -107,7 +107,9 @@ class PopulationTask extends AsyncTask{ $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->recalculateHeightMap(); - $chunk->setPopulated(true); + $chunk->populateSkyLight(); + $chunk->setLightPopulated(); + $chunk->setPopulated(); $this->chunk = $chunk->toFastBinary(); $manager->setChunk($chunk->getX(), $chunk->getZ(), null);