Some consistency would be nice... fixed inconsistency between block light and sky light, always use Mojang order

This commit is contained in:
Dylan K. Taylor 2017-01-03 19:15:23 +00:00
parent 8a29e77f5e
commit e2dc1a3bc6
6 changed files with 69 additions and 62 deletions

View File

@ -59,14 +59,6 @@ class EmptySubChunk extends SubChunk{
return false;
}
public function getBlockSkyLight(int $x, int $y, int $z) : int{
return 15;
}
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
return false;
}
public function getBlockLight(int $x, int $y, int $z) : int{
return 0;
}
@ -75,6 +67,14 @@ class EmptySubChunk extends SubChunk{
return false;
}
public function getBlockSkyLight(int $x, int $y, int $z) : int{
return 15;
}
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
return false;
}
public function getBlockIdColumn(int $x, int $z) : string{
return "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
}

View File

@ -281,7 +281,7 @@ class GenericChunk implements Chunk{
for($z = 0; $z < 16; ++$z){
$heightMap = $this->getHeightMap($x, $z);
$y = min($this->getHighestSubChunkIndex() << 4, $heightMap);
$y = min(($this->getHighestSubChunkIndex() + 1) << 4, $heightMap);
for(; $y > $heightMap; --$y){
$this->setBlockSkyLight($x, $y, $z, 15);
@ -652,12 +652,7 @@ class GenericChunk implements Chunk{
$subChunks = [];
$count = $stream->getByte();
for($y = 0; $y < $count; ++$y){
$subChunks[$stream->getByte()] = new SubChunk(
$stream->get(4096), //blockIds
$stream->get(2048), //blockData
$stream->get(2048), //skyLight
$stream->get(2048) //blockLight
);
$subChunks[$stream->getByte()] = SubChunk::fastDeserialize($stream->get(10240));
}
$heightMap = array_values(unpack("C*", $stream->get(256)));
$biomeIds = $stream->get(256);

View File

@ -39,11 +39,11 @@ class SubChunk{
}
}
public function __construct(string $ids = "", string $data = "", string $blockLight = "", string $skyLight = ""){
public function __construct(string $ids = "", string $data = "", string $skyLight = "", string $blockLight = ""){
self::assignData($this->ids, $ids, 4096);
self::assignData($this->data, $data, 2048);
self::assignData($this->blockLight, $blockLight, 2048);
self::assignData($this->skyLight, $skyLight, 2048);
self::assignData($this->blockLight, $blockLight, 2048);
}
public function isEmpty() : bool{
@ -115,26 +115,6 @@ class SubChunk{
return $changed;
}
public function getBlockSkyLight(int $x, int $y, int $z) : int{
$byte = ord($this->skyLight{($x << 7) + ($z << 3) + ($y >> 1)});
if(($y & 1) === 0){
return $byte & 0x0f;
}else{
return $byte >> 4;
}
}
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
$i = ($x << 7) + ($z << 3) + ($y >> 1);
$byte = ord($this->skyLight{$i});
if(($y & 1) === 0){
$this->skyLight{$i} = chr(($byte & 0xf0) | ($level & 0x0f));
}else{
$this->skyLight{$i} = chr((($level & 0x0f) << 4) | ($byte & 0x0f));
}
return true;
}
public function getBlockLight(int $x, int $y, int $z) : int{
$byte = ord($this->blockLight{($x << 7) + ($z << 3) + ($y >> 1)});
if(($y & 1) === 0){
@ -155,6 +135,26 @@ class SubChunk{
return true;
}
public function getBlockSkyLight(int $x, int $y, int $z) : int{
$byte = ord($this->skyLight{($x << 7) + ($z << 3) + ($y >> 1)});
if(($y & 1) === 0){
return $byte & 0x0f;
}else{
return $byte >> 4;
}
}
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
$i = ($x << 7) + ($z << 3) + ($y >> 1);
$byte = ord($this->skyLight{$i});
if(($y & 1) === 0){
$this->skyLight{$i} = chr(($byte & 0xf0) | ($level & 0x0f));
}else{
$this->skyLight{$i} = chr((($level & 0x0f) << 4) | ($byte & 0x0f));
}
return true;
}
public function getHighestBlockAt(int $x, int $z) : int{
for($y = 15; $y >= 0; --$y){
if($this->ids{($x << 8) | ($z << 4) | $y} !== "\x00"){
@ -191,23 +191,35 @@ class SubChunk{
return $this->data;
}
public function getBlockLightArray() : string{
assert(strlen($this->blockLight) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($this->blockLight));
return $this->blockLight;
}
public function getSkyLightArray() : string{
assert(strlen($this->skyLight) === 2048, "Wrong length of skylight array, expecting 2048 bytes, got " . strlen($this->skyLight));
return $this->skyLight;
}
public function getBlockLightArray() : string{
assert(strlen($this->blockLight) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($this->blockLight));
return $this->blockLight;
}
public function networkSerialize() : string{
// storage version, ids, data, skylight, blocklight
return "\x00" . $this->ids . $this->data . $this->skyLight . $this->blockLight;
}
public function fastSerialize() : string{
// ids, data, skylight, blocklight
return $this->ids . $this->data . $this->skyLight . $this->blockLight;
return
$this->ids .
$this->data .
$this->skyLight .
$this->blockLight;
}
public static function fastDeserialize(string $data) : SubChunk{
return new SubChunk(
substr($data, 0, 4096), //ids
substr($data, 4096, 2048), //data
substr($data, 6144, 2048), //sky light
substr($data, 8192, 2048) //block light
);
}
}

View File

@ -61,8 +61,8 @@ class Anvil extends McRegion{
"Y" => new ByteTag("Y", $y),
"Blocks" => new ByteArrayTag("Blocks", GenericChunk::reorderByteArray($subChunk->getBlockIdArray())), //Generic in-memory chunks are currrently always XZY
"Data" => new ByteArrayTag("Data", GenericChunk::reorderNibbleArray($subChunk->getBlockDataArray())),
"BlockLight" => new ByteArrayTag("BlockLight", GenericChunk::reorderNibbleArray($subChunk->getBlockLightArray())),
"SkyLight" => new ByteArrayTag("SkyLight", GenericChunk::reorderNibbleArray($subChunk->getSkyLightArray()))
"SkyLight" => new ByteArrayTag("SkyLight", GenericChunk::reorderNibbleArray($subChunk->getSkyLightArray())),
"BlockLight" => new ByteArrayTag("BlockLight", GenericChunk::reorderNibbleArray($subChunk->getBlockLightArray()))
]);
}
@ -119,8 +119,8 @@ class Anvil extends McRegion{
$subChunks[$subChunk->Y->getValue()] = new SubChunk(
GenericChunk::reorderByteArray($subChunk->Blocks->getValue()),
GenericChunk::reorderNibbleArray($subChunk->Data->getValue()),
GenericChunk::reorderNibbleArray($subChunk->BlockLight->getValue()),
GenericChunk::reorderNibbleArray($subChunk->SkyLight->getValue())
GenericChunk::reorderNibbleArray($subChunk->SkyLight->getValue()),
GenericChunk::reorderNibbleArray($subChunk->BlockLight->getValue())
);
}
}

View File

@ -64,8 +64,8 @@ class McRegion extends BaseLevelProvider{
$ids = "";
$data = "";
$blockLight = "";
$skyLight = "";
$blockLight = "";
$subChunks = $chunk->getSubChunks();
for($x = 0; $x < 16; ++$x){
for($z = 0; $z < 16; ++$z){
@ -73,8 +73,8 @@ class McRegion extends BaseLevelProvider{
$subChunk = $subChunks[$y];
$ids .= $subChunk->getBlockIdColumn($x, $z);
$data .= $subChunk->getBlockDataColumn($x, $z);
$blockLight .= $subChunk->getBlockLightColumn($x, $z);
$skyLight .= $subChunk->getSkyLightColumn($x, $z);
$blockLight .= $subChunk->getBlockLightColumn($x, $z);
}
}
}
@ -138,8 +138,8 @@ class McRegion extends BaseLevelProvider{
$subChunks = [];
$fullIds = isset($chunk->Blocks) ? $chunk->Blocks->getValue() : str_repeat("\x00", 32768);
$fullData = isset($chunk->Data) ? $chunk->Data->getValue() : ($half = str_repeat("\x00", 16384));
$fullBlockLight = isset($chunk->BlockLight) ? $chunk->BlockLight->getValue() : $half;
$fullSkyLight = isset($chunk->SkyLight) ? $chunk->SkyLight->getValue() : str_repeat("\xff", 16384);
$fullBlockLight = isset($chunk->BlockLight) ? $chunk->BlockLight->getValue() : $half;
for($y = 0; $y < 8; ++$y){
$offset = ($y << 4);
@ -154,19 +154,19 @@ class McRegion extends BaseLevelProvider{
$data .= substr($fullData, $offset, 8);
$offset += 64;
}
$blockLight = "";
$offset = ($y << 3);
for($i = 0; $i < 256; ++$i){
$blockLight .= substr($fullBlockLight, $offset, 8);
$offset += 64;
}
$skyLight = "";
$offset = ($y << 3);
for($i = 0; $i < 256; ++$i){
$skyLight .= substr($fullSkyLight, $offset, 8);
$offset += 64;
}
$subChunks[$y] = new SubChunk($ids, $data, $blockLight, $skyLight);
$blockLight = "";
$offset = ($y << 3);
for($i = 0; $i < 256; ++$i){
$blockLight .= substr($fullBlockLight, $offset, 8);
$offset += 64;
}
$subChunks[$y] = new SubChunk($ids, $data, $skyLight, $blockLight);
}
if(isset($chunk->BiomeColors)){

View File

@ -65,8 +65,8 @@ class PMAnvil extends Anvil{
"Y" => new ByteTag("Y", $y),
"Blocks" => new ByteArrayTag("Blocks", $subChunk->getBlockIdArray()),
"Data" => new ByteArrayTag("Data", $subChunk->getBlockDataArray()),
"BlockLight" => new ByteArrayTag("BlockLight", $subChunk->getBlockLightArray()),
"SkyLight" => new ByteArrayTag("SkyLight", $subChunk->getSkyLightArray())
"SkyLight" => new ByteArrayTag("SkyLight", $subChunk->getSkyLightArray()),
"BlockLight" => new ByteArrayTag("BlockLight", $subChunk->getBlockLightArray())
]);
}
@ -123,8 +123,8 @@ class PMAnvil extends Anvil{
$subChunks[$subChunk->Y->getValue()] = new SubChunk(
$subChunk->Blocks->getValue(),
$subChunk->Data->getValue(),
$subChunk->BlockLight->getValue(),
$subChunk->SkyLight->getValue()
$subChunk->SkyLight->getValue(),
$subChunk->BlockLight->getValue()
);
}
}