Chunks no longer exist in un-generated state

a non-generated chunk is now always represented by NULL. This forces the case of ungenerated chunks to be handled by all code, which is necessary because ungenerated chunks cannot be interacted with or modified in any meaningful way.
This commit is contained in:
Dylan K. Taylor
2020-12-03 22:28:43 +00:00
parent 05ab44f768
commit b9cd633cee
10 changed files with 59 additions and 97 deletions

View File

@ -63,44 +63,42 @@ final class FastChunkSerializer{
$stream = new BinaryStream();
$stream->putByte(
($includeLight ? self::FLAG_HAS_LIGHT : 0) |
($chunk->isPopulated() ? self::FLAG_POPULATED : 0) |
($chunk->isGenerated() ? self::FLAG_GENERATED : 0)
($chunk->isPopulated() ? self::FLAG_POPULATED : 0)
);
if($chunk->isGenerated()){
//subchunks
$subChunks = $chunk->getSubChunks();
$count = $subChunks->count();
$stream->putByte($count);
foreach($subChunks as $y => $subChunk){
$stream->putByte($y);
$stream->putInt($subChunk->getEmptyBlockId());
$layers = $subChunk->getBlockLayers();
$stream->putByte(count($layers));
foreach($layers as $blocks){
$wordArray = $blocks->getWordArray();
$palette = $blocks->getPalette();
//subchunks
$subChunks = $chunk->getSubChunks();
$count = $subChunks->count();
$stream->putByte($count);
$stream->putByte($blocks->getBitsPerBlock());
$stream->put($wordArray);
$serialPalette = pack("L*", ...$palette);
$stream->putInt(strlen($serialPalette));
$stream->put($serialPalette);
}
foreach($subChunks as $y => $subChunk){
$stream->putByte($y);
$stream->putInt($subChunk->getEmptyBlockId());
$layers = $subChunk->getBlockLayers();
$stream->putByte(count($layers));
foreach($layers as $blocks){
$wordArray = $blocks->getWordArray();
$palette = $blocks->getPalette();
if($includeLight){
$stream->put($subChunk->getBlockSkyLightArray()->getData());
$stream->put($subChunk->getBlockLightArray()->getData());
}
$stream->putByte($blocks->getBitsPerBlock());
$stream->put($wordArray);
$serialPalette = pack("L*", ...$palette);
$stream->putInt(strlen($serialPalette));
$stream->put($serialPalette);
}
//biomes
$stream->put($chunk->getBiomeIdArray());
if($includeLight){
$stream->put(pack("S*", ...$chunk->getHeightMapArray()));
$stream->put($subChunk->getBlockSkyLightArray()->getData());
$stream->put($subChunk->getBlockLightArray()->getData());
}
}
//biomes
$stream->put($chunk->getBiomeIdArray());
if($includeLight){
$stream->put(pack("S*", ...$chunk->getHeightMapArray()));
}
return $stream->getBuffer();
}
@ -113,39 +111,36 @@ final class FastChunkSerializer{
$flags = $stream->getByte();
$lightPopulated = (bool) ($flags & self::FLAG_HAS_LIGHT);
$terrainPopulated = (bool) ($flags & self::FLAG_POPULATED);
$terrainGenerated = (bool) ($flags & self::FLAG_GENERATED);
$subChunks = [];
$biomeIds = null;
$heightMap = null;
if($terrainGenerated){
$count = $stream->getByte();
for($subCount = 0; $subCount < $count; ++$subCount){
$y = $stream->getByte();
$airBlockId = $stream->getInt();
/** @var PalettedBlockArray[] $layers */
$layers = [];
for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){
$bitsPerBlock = $stream->getByte();
$words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock));
$palette = array_values(unpack("L*", $stream->get($stream->getInt())));
$count = $stream->getByte();
for($subCount = 0; $subCount < $count; ++$subCount){
$y = $stream->getByte();
$airBlockId = $stream->getInt();
$layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette);
}
$subChunks[$y] = new SubChunk(
$airBlockId, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null
);
/** @var PalettedBlockArray[] $layers */
$layers = [];
for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){
$bitsPerBlock = $stream->getByte();
$words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock));
$palette = array_values(unpack("L*", $stream->get($stream->getInt())));
$layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette);
}
$subChunks[$y] = new SubChunk(
$airBlockId, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null
);
}
$biomeIds = new BiomeArray($stream->get(256));
if($lightPopulated){
$heightMap = new HeightArray(array_values(unpack("S*", $stream->get(512))));
}
$biomeIds = new BiomeArray($stream->get(256));
if($lightPopulated){
$heightMap = new HeightArray(array_values(unpack("S*", $stream->get(512))));
}
$chunk = new Chunk($subChunks, null, null, $biomeIds, $heightMap);
$chunk->setGenerated($terrainGenerated);
$chunk->setPopulated($terrainPopulated);
$chunk->setLightPopulated($lightPopulated);
$chunk->clearDirtyFlags();