mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 16:00:20 +00:00
Fixed empty block handling after blockstate ID XOR change
This commit is contained in:
parent
5a9cdef40c
commit
8744032ab6
@ -58,6 +58,11 @@ class Block{
|
||||
public const INTERNAL_STATE_DATA_BITS = 8;
|
||||
public const INTERNAL_STATE_DATA_MASK = ~(~0 << self::INTERNAL_STATE_DATA_BITS);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public const EMPTY_STATE_ID = (BlockTypeIds::AIR << self::INTERNAL_STATE_DATA_BITS) | (BlockTypeIds::AIR & self::INTERNAL_STATE_DATA_MASK);
|
||||
|
||||
protected BlockIdentifier $idInfo;
|
||||
protected string $fallbackName;
|
||||
protected BlockTypeInfo $typeInfo;
|
||||
|
@ -27,7 +27,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\world\format;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockTypeIds;
|
||||
use pocketmine\block\tile\Tile;
|
||||
use pocketmine\data\bedrock\BiomeIds;
|
||||
use function array_map;
|
||||
@ -71,7 +70,7 @@ class Chunk{
|
||||
|
||||
foreach($this->subChunks as $y => $null){
|
||||
//TODO: we should probably require all subchunks to be provided here
|
||||
$this->subChunks[$y] = $subChunks[$y + self::MIN_SUBCHUNK_INDEX] ?? new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [], new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
$this->subChunks[$y] = $subChunks[$y + self::MIN_SUBCHUNK_INDEX] ?? new SubChunk(Block::EMPTY_STATE_ID, [], new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
}
|
||||
|
||||
$val = (self::MAX_SUBCHUNK_INDEX + 1) * SubChunk::EDGE_LENGTH;
|
||||
@ -293,8 +292,8 @@ class Chunk{
|
||||
throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y");
|
||||
}
|
||||
|
||||
$this->subChunks[$y - self::MIN_SUBCHUNK_INDEX] = $subChunk ?? new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [], new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
$this->setTerrainDirtyFlag(self::DIRTY_FLAG_BLOCKS, true);
|
||||
$this->subChunks[$y - self::MIN_SUBCHUNK_INDEX] = $subChunk ?? new SubChunk(Block::EMPTY_STATE_ID, [], new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
$this->terrainDirtyFlags |= self::DIRTY_FLAG_BLOCKS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\world\format\io\leveldb;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockTypeIds;
|
||||
use pocketmine\data\bedrock\BiomeIds;
|
||||
use pocketmine\data\bedrock\block\BlockStateDeserializeException;
|
||||
use pocketmine\nbt\LittleEndianNbtSerializer;
|
||||
@ -355,7 +354,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
$blockStateId = $this->blockStateDeserializer->deserialize($blockStateData);
|
||||
|
||||
if(!isset($extraDataLayers[$ySub])){
|
||||
$extraDataLayers[$ySub] = new PalettedBlockArray(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS);
|
||||
$extraDataLayers[$ySub] = new PalettedBlockArray(Block::EMPTY_STATE_ID);
|
||||
}
|
||||
$extraDataLayers[$ySub]->set($x, $y, $z, $blockStateId);
|
||||
}
|
||||
@ -417,13 +416,13 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
if(isset($convertedLegacyExtraData[$yy])){
|
||||
$storages[] = $convertedLegacyExtraData[$yy];
|
||||
}
|
||||
$subChunks[$yy] = new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, $storages, clone $biomes3d);
|
||||
$subChunks[$yy] = new SubChunk(Block::EMPTY_STATE_ID, $storages, clone $biomes3d);
|
||||
}
|
||||
|
||||
//make sure extrapolated biomes get filled in correctly
|
||||
for($yy = Chunk::MIN_SUBCHUNK_INDEX; $yy <= Chunk::MAX_SUBCHUNK_INDEX; ++$yy){
|
||||
if(!isset($subChunks[$yy])){
|
||||
$subChunks[$yy] = new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [], clone $biomes3d);
|
||||
$subChunks[$yy] = new SubChunk(Block::EMPTY_STATE_ID, [], clone $biomes3d);
|
||||
}
|
||||
}
|
||||
|
||||
@ -457,7 +456,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
$storages[] = $convertedLegacyExtraData;
|
||||
}
|
||||
|
||||
return new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, $storages, $biomePalette);
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $storages, $biomePalette);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -481,7 +480,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
if($convertedLegacyExtraData !== null){
|
||||
$storages[] = $convertedLegacyExtraData;
|
||||
}
|
||||
return new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, $storages, $biomePalette);
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $storages, $biomePalette);
|
||||
case SubChunkVersion::PALETTED_MULTI:
|
||||
case SubChunkVersion::PALETTED_MULTI_WITH_OFFSET:
|
||||
//legacy extradata layers intentionally ignored because they aren't supposed to exist in v8
|
||||
@ -496,7 +495,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
for($k = 0; $k < $storageCount; ++$k){
|
||||
$storages[] = $this->deserializeBlockPalette($binaryStream, $logger);
|
||||
}
|
||||
return new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, $storages, $biomePalette);
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $storages, $biomePalette);
|
||||
default:
|
||||
//this should never happen - an unsupported chunk appearing in a supported world is a sign of corruption
|
||||
throw new CorruptedChunkException("don't know how to decode LevelDB subchunk format version $subChunkVersion");
|
||||
@ -526,7 +525,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
$subChunkKeyOffset = self::hasOffsetCavesAndCliffsSubChunks($chunkVersion) ? self::CAVES_CLIFFS_EXPERIMENTAL_SUBCHUNK_KEY_OFFSET : 0;
|
||||
for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){
|
||||
if(($data = $this->db->get($index . ChunkDataKey::SUBCHUNK . chr($y + $subChunkKeyOffset))) === false){
|
||||
$subChunks[$y] = new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [], $biomeArrays[$y]);
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, [], $biomeArrays[$y]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\world\format\io\region;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockTypeIds;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\world\format\PalettedBlockArray;
|
||||
use pocketmine\world\format\SubChunk;
|
||||
@ -33,7 +32,7 @@ class Anvil extends RegionWorldProvider{
|
||||
use LegacyAnvilChunkTrait;
|
||||
|
||||
protected function deserializeSubChunk(CompoundTag $subChunk, PalettedBlockArray $biomes3d) : SubChunk{
|
||||
return new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [$this->palettizeLegacySubChunkYZX(
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, [$this->palettizeLegacySubChunkYZX(
|
||||
self::readFixedSizeByteArray($subChunk, "Blocks", 4096),
|
||||
self::readFixedSizeByteArray($subChunk, "Data", 2048)
|
||||
)], $biomes3d);
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\world\format\io\region;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockTypeIds;
|
||||
use pocketmine\data\bedrock\BiomeIds;
|
||||
use pocketmine\nbt\BigEndianNbtSerializer;
|
||||
use pocketmine\nbt\NbtDataException;
|
||||
@ -96,7 +95,7 @@ trait LegacyAnvilChunkTrait{
|
||||
}
|
||||
for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){
|
||||
if(!isset($subChunks[$y])){
|
||||
$subChunks[$y] = new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [], clone $biomes3d);
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, [], clone $biomes3d);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\world\format\io\region;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockTypeIds;
|
||||
use pocketmine\data\bedrock\BiomeIds;
|
||||
use pocketmine\nbt\BigEndianNbtSerializer;
|
||||
use pocketmine\nbt\NbtDataException;
|
||||
@ -91,11 +90,11 @@ class McRegion extends RegionWorldProvider{
|
||||
$fullData = self::readFixedSizeByteArray($chunk, "Data", 16384);
|
||||
|
||||
for($y = 0; $y < 8; ++$y){
|
||||
$subChunks[$y] = new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [$this->palettizeLegacySubChunkFromColumn($fullIds, $fullData, $y)], clone $biomes3d);
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, [$this->palettizeLegacySubChunkFromColumn($fullIds, $fullData, $y)], clone $biomes3d);
|
||||
}
|
||||
for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){
|
||||
if(!isset($subChunks[$y])){
|
||||
$subChunks[$y] = new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [], clone $biomes3d);
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, [], clone $biomes3d);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\world\format\io\region;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockTypeIds;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\world\format\PalettedBlockArray;
|
||||
use pocketmine\world\format\SubChunk;
|
||||
@ -37,7 +36,7 @@ class PMAnvil extends RegionWorldProvider{
|
||||
use LegacyAnvilChunkTrait;
|
||||
|
||||
protected function deserializeSubChunk(CompoundTag $subChunk, PalettedBlockArray $biomes3d) : SubChunk{
|
||||
return new SubChunk(BlockTypeIds::AIR << Block::INTERNAL_STATE_DATA_BITS, [$this->palettizeLegacySubChunkXZY(
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, [$this->palettizeLegacySubChunkXZY(
|
||||
self::readFixedSizeByteArray($subChunk, "Blocks", 4096),
|
||||
self::readFixedSizeByteArray($subChunk, "Data", 2048)
|
||||
)], $biomes3d);
|
||||
|
@ -119,4 +119,9 @@ class BlockTest extends TestCase{
|
||||
self::assertSame($name, $states[$k]->getName());
|
||||
}
|
||||
}
|
||||
|
||||
public function testEmptyStateId() : void{
|
||||
$block = $this->blockFactory->fromStateId(Block::EMPTY_STATE_ID);
|
||||
self::assertInstanceOf(Air::class, $block);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user