Calculate skylight on chunk population

This commit is contained in:
Shoghi Cervantes 2015-05-06 16:57:49 +02:00
parent 44b5c23ee1
commit fb03df3d06
6 changed files with 72 additions and 4 deletions

View File

@ -178,6 +178,8 @@ interface FullChunk{
public function recalculateHeightMap(); public function recalculateHeightMap();
public function populateSkyLight();
/** /**
* @param int $x 0-15 * @param int $x 0-15
* @param int $z 0-15 * @param int $z 0-15
@ -218,6 +220,10 @@ interface FullChunk{
*/ */
public function setBiomeColor($x, $z, $R, $G, $B); public function setBiomeColor($x, $z, $R, $G, $B);
public function isLightPopulated();
public function setLightPopulated($value = 1);
public function isPopulated(); public function isPopulated();
public function setPopulated($value = 1); public function setPopulated($value = 1);

View File

@ -90,6 +90,15 @@ class Chunk extends BaseChunk{
unset($this->nbt->Sections); 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 * @return bool
*/ */
@ -102,6 +111,7 @@ class Chunk extends BaseChunk{
*/ */
public function setPopulated($value = 1){ public function setPopulated($value = 1){
$this->nbt->TerrainPopulated = new Byte("TerrainPopulated", $value); $this->nbt->TerrainPopulated = new Byte("TerrainPopulated", $value);
$this->hasChanged = true;
} }
/** /**
@ -116,6 +126,7 @@ class Chunk extends BaseChunk{
*/ */
public function setGenerated($value = 1){ public function setGenerated($value = 1){
$this->nbt->TerrainGenerated = new Byte("TerrainGenerated", $value); $this->nbt->TerrainGenerated = new Byte("TerrainGenerated", $value);
$this->hasChanged = true;
} }
/** /**

View File

@ -21,6 +21,7 @@
namespace pocketmine\level\format\generic; namespace pocketmine\level\format\generic;
use pocketmine\block\Block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\level\format\LevelProvider; use pocketmine\level\format\LevelProvider;
@ -156,6 +157,12 @@ abstract class BaseFullChunk implements FullChunk{
$this->hasChanged = false; $this->hasChanged = false;
} }
if(!$this->isLightPopulated()){
$this->recalculateHeightMap();
$this->populateSkyLight();
$this->setLightPopulated();
}
} }
public function getX(){ 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){ public function getHighestBlockAt($x, $z, $cache = true){
if($cache){ if($cache){
$h = $this->getHeightMap($x, $z); $h = $this->getHeightMap($x, $z);
@ -377,4 +405,12 @@ abstract class BaseFullChunk implements FullChunk{
return $this->toBinary(); return $this->toBinary();
} }
public function isLightPopulated(){
return true;
}
public function setLightPopulated($value = 1){
}
} }

View File

@ -272,6 +272,9 @@ class Chunk extends BaseFullChunk{
if($flags & 0x02){ if($flags & 0x02){
$chunk->setPopulated(); $chunk->setPopulated();
} }
if($flags & 0x04){
$chunk->setLightPopulated();
}
return $chunk; return $chunk;
}catch(\Exception $e){ }catch(\Exception $e){
return null; return null;
@ -333,7 +336,7 @@ class Chunk extends BaseFullChunk{
$this->getBlockLightArray() . $this->getBlockLightArray() .
$heightmap . $heightmap .
$biomeColors . chr( $biomeColors . chr(
($this->isPopulated() ? 0x02 : 0) | ($this->isGenerated() ? 0x01 : 0) ($this->isLightPopulated() ? 0x04 : 0) | ($this->isPopulated() ? 0x02 : 0) | ($this->isGenerated() ? 0x01 : 0)
); );
} }
} }

View File

@ -231,6 +231,15 @@ class Chunk extends BaseFullChunk{
return substr($this->blockLight, ($x << 10) + ($z << 6), 64); 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 * @return bool
*/ */
@ -325,7 +334,8 @@ class Chunk extends BaseFullChunk{
$flags = ord($data{$offset++}); $flags = ord($data{$offset++});
$chunk->nbt->TerrainGenerated = new Byte("TerrainGenerated", $flags & 0b1); $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; return $chunk;
}catch(\Exception $e){ }catch(\Exception $e){
@ -346,7 +356,7 @@ class Chunk extends BaseFullChunk{
$this->getBlockLightArray() . $this->getBlockLightArray() .
$heightMap . $heightMap .
$biomeColors . $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(){ public function toBinary(){

View File

@ -107,7 +107,9 @@ class PopulationTask extends AsyncTask{
$chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ());
$chunk->recalculateHeightMap(); $chunk->recalculateHeightMap();
$chunk->setPopulated(true); $chunk->populateSkyLight();
$chunk->setLightPopulated();
$chunk->setPopulated();
$this->chunk = $chunk->toFastBinary(); $this->chunk = $chunk->toFastBinary();
$manager->setChunk($chunk->getX(), $chunk->getZ(), null); $manager->setChunk($chunk->getX(), $chunk->getZ(), null);