mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 19:02:59 +00:00
Compare commits
12 Commits
major-next
...
block-laye
Author | SHA1 | Date | |
---|---|---|---|
a0f5ad1669 | |||
0f932f7cc0 | |||
f01d87474d | |||
7472c5b73d | |||
941632bed9 | |||
e5a38f270c | |||
7c651928ea | |||
48cc87d066 | |||
72781f4042 | |||
30d13508b4 | |||
ba2a7cceaf | |||
8005c74681 |
@ -112,7 +112,14 @@ final class ChunkSerializer{
|
||||
}
|
||||
|
||||
public static function serializeSubChunk(SubChunk $subChunk, BlockTranslator $blockTranslator, PacketSerializer $stream, bool $persistentBlockStates) : void{
|
||||
$layers = $subChunk->getBlockLayers();
|
||||
$layers = [];
|
||||
if(!$subChunk->isBlockLayerEmpty()){
|
||||
$layers[] = $subChunk->getBlockLayer();
|
||||
}
|
||||
if(!$subChunk->isLiquidLayerEmpty()){
|
||||
$layers[] = $subChunk->getLiquidLayer();
|
||||
}
|
||||
|
||||
$stream->putByte(8); //version
|
||||
|
||||
$stream->putByte(count($layers));
|
||||
|
@ -2607,7 +2607,7 @@ class World implements ChunkManager{
|
||||
|
||||
public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{
|
||||
foreach($chunk->getSubChunks() as $subChunk){
|
||||
foreach($subChunk->getBlockLayers() as $blockLayer){
|
||||
foreach([$subChunk->getBlockLayer(), $subChunk->getLiquidLayer()] as $blockLayer){
|
||||
foreach($blockLayer->getPalette() as $blockStateId){
|
||||
if(!$this->blockStateRegistry->hasStateId($blockStateId)){
|
||||
throw new \InvalidArgumentException("Provided chunk contains unknown/unregistered blocks (found unknown state ID $blockStateId)");
|
||||
|
@ -73,7 +73,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(Block::EMPTY_STATE_ID, [], new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
$this->subChunks[$y] = $subChunks[$y + self::MIN_SUBCHUNK_INDEX] ?? new SubChunk(Block::EMPTY_STATE_ID, null, null, new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
}
|
||||
|
||||
$val = (self::MAX_SUBCHUNK_INDEX + 1) * SubChunk::EDGE_LENGTH;
|
||||
@ -298,7 +298,7 @@ class Chunk{
|
||||
throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y");
|
||||
}
|
||||
|
||||
$this->subChunks[$y - self::MIN_SUBCHUNK_INDEX] = $subChunk ?? new SubChunk(Block::EMPTY_STATE_ID, [], new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
$this->subChunks[$y - self::MIN_SUBCHUNK_INDEX] = $subChunk ?? new SubChunk(Block::EMPTY_STATE_ID, null, null, new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
$this->terrainDirtyFlags |= self::DIRTY_FLAG_BLOCKS;
|
||||
}
|
||||
|
||||
|
@ -23,27 +23,36 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\world\format;
|
||||
|
||||
use function array_map;
|
||||
use function count;
|
||||
|
||||
class SubChunk{
|
||||
public const COORD_BIT_SIZE = 4;
|
||||
public const COORD_MASK = ~(~0 << self::COORD_BIT_SIZE);
|
||||
public const EDGE_LENGTH = 1 << self::COORD_BIT_SIZE;
|
||||
|
||||
private int $emptyBlockId;
|
||||
private PalettedBlockArray $blockLayer;
|
||||
private PalettedBlockArray $liquidLayer;
|
||||
private PalettedBlockArray $biomes;
|
||||
private ?LightArray $skyLight;
|
||||
private ?LightArray $blockLight;
|
||||
|
||||
/**
|
||||
* SubChunk constructor.
|
||||
*
|
||||
* @param PalettedBlockArray[] $blockLayers
|
||||
* @phpstan-param list<PalettedBlockArray> $blockLayers
|
||||
*/
|
||||
public function __construct(
|
||||
private int $emptyBlockId,
|
||||
private array $blockLayers,
|
||||
private PalettedBlockArray $biomes,
|
||||
private ?LightArray $skyLight = null,
|
||||
private ?LightArray $blockLight = null
|
||||
){}
|
||||
int $emptyBlockId,
|
||||
?PalettedBlockArray $blockLayer,
|
||||
?PalettedBlockArray $liquidLayer,
|
||||
PalettedBlockArray $biomes,
|
||||
?LightArray $skyLight = null,
|
||||
?LightArray $blockLight = null
|
||||
){
|
||||
$this->emptyBlockId = $emptyBlockId;
|
||||
$this->blockLayer = $blockLayer ?? new PalettedBlockArray($emptyBlockId);
|
||||
$this->liquidLayer = $liquidLayer ?? new PalettedBlockArray($emptyBlockId);
|
||||
$this->biomes = $biomes;
|
||||
$this->skyLight = $skyLight;
|
||||
$this->blockLight = $blockLight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this subchunk contains any non-air blocks.
|
||||
@ -60,7 +69,22 @@ class SubChunk{
|
||||
* This may report non-empty erroneously if the chunk has been modified and not garbage-collected.
|
||||
*/
|
||||
public function isEmptyFast() : bool{
|
||||
return count($this->blockLayers) === 0;
|
||||
return $this->blockLayer->getBitsPerBlock() === 0 && $this->blockLayer->get(0, 0, 0) === $this->emptyBlockId &&
|
||||
$this->liquidLayer->getBitsPerBlock() === 0 && $this->liquidLayer->get(0, 0, 0) === $this->emptyBlockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the block layer is empty (contains only empty blocks).
|
||||
*/
|
||||
public function isBlockLayerEmpty() : bool{
|
||||
return $this->blockLayer->getBitsPerBlock() === 0 && $this->blockLayer->get(0, 0, 0) === $this->emptyBlockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the liquid layer is empty (contains only empty blocks).
|
||||
*/
|
||||
public function isLiquidLayerEmpty() : bool{
|
||||
return $this->liquidLayer->getBitsPerBlock() === 0 && $this->liquidLayer->get(0, 0, 0) === $this->emptyBlockId;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,33 +94,24 @@ class SubChunk{
|
||||
public function getEmptyBlockId() : int{ return $this->emptyBlockId; }
|
||||
|
||||
public function getBlockStateId(int $x, int $y, int $z) : int{
|
||||
if(count($this->blockLayers) === 0){
|
||||
return $this->emptyBlockId;
|
||||
}
|
||||
return $this->blockLayers[0]->get($x, $y, $z);
|
||||
return $this->blockLayer->get($x, $y, $z);
|
||||
}
|
||||
|
||||
public function setBlockStateId(int $x, int $y, int $z, int $block) : void{
|
||||
if(count($this->blockLayers) === 0){
|
||||
$this->blockLayers[] = new PalettedBlockArray($this->emptyBlockId);
|
||||
}
|
||||
$this->blockLayers[0]->set($x, $y, $z, $block);
|
||||
$this->blockLayer->set($x, $y, $z, $block);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PalettedBlockArray[]
|
||||
* @phpstan-return list<PalettedBlockArray>
|
||||
*/
|
||||
public function getBlockLayers() : array{
|
||||
return $this->blockLayers;
|
||||
public function getBlockLayer() : PalettedBlockArray{
|
||||
return $this->blockLayer;
|
||||
}
|
||||
|
||||
public function getLiquidLayer() : PalettedBlockArray{
|
||||
return $this->liquidLayer;
|
||||
}
|
||||
|
||||
public function getHighestBlockAt(int $x, int $z) : ?int{
|
||||
if(count($this->blockLayers) === 0){
|
||||
return null;
|
||||
}
|
||||
for($y = self::EDGE_LENGTH - 1; $y >= 0; --$y){
|
||||
if($this->blockLayers[0]->get($x, $y, $z) !== $this->emptyBlockId){
|
||||
if($this->blockLayer->get($x, $y, $z) !== $this->emptyBlockId){
|
||||
return $y;
|
||||
}
|
||||
}
|
||||
@ -130,15 +145,8 @@ class SubChunk{
|
||||
}
|
||||
|
||||
public function collectGarbage() : void{
|
||||
$cleanedLayers = [];
|
||||
foreach($this->blockLayers as $layer){
|
||||
$layer->collectGarbage();
|
||||
|
||||
if($layer->getBitsPerBlock() !== 0 || $layer->get(0, 0, 0) !== $this->emptyBlockId){
|
||||
$cleanedLayers[] = $layer;
|
||||
}
|
||||
}
|
||||
$this->blockLayers = $cleanedLayers;
|
||||
$this->blockLayer->collectGarbage();
|
||||
$this->liquidLayer->collectGarbage();
|
||||
$this->biomes->collectGarbage();
|
||||
|
||||
if($this->skyLight !== null && $this->skyLight->isUniform(0)){
|
||||
@ -150,9 +158,8 @@ class SubChunk{
|
||||
}
|
||||
|
||||
public function __clone(){
|
||||
$this->blockLayers = array_map(function(PalettedBlockArray $array) : PalettedBlockArray{
|
||||
return clone $array;
|
||||
}, $this->blockLayers);
|
||||
$this->blockLayer = clone $this->blockLayer;
|
||||
$this->liquidLayer = clone $this->liquidLayer;
|
||||
$this->biomes = clone $this->biomes;
|
||||
|
||||
if($this->skyLight !== null){
|
||||
|
@ -74,13 +74,11 @@ final class FastChunkSerializer{
|
||||
foreach($subChunks as $y => $subChunk){
|
||||
$stream->putByte($y);
|
||||
$stream->putInt($subChunk->getEmptyBlockId());
|
||||
$layers = $subChunk->getBlockLayers();
|
||||
$stream->putByte(count($layers));
|
||||
foreach($layers as $blocks){
|
||||
self::serializePalettedArray($stream, $blocks);
|
||||
}
|
||||
self::serializePalettedArray($stream, $subChunk->getBiomeArray());
|
||||
|
||||
// Write block and liquid layers (always present)
|
||||
self::serializePalettedArray($stream, $subChunk->getBlockLayer());
|
||||
self::serializePalettedArray($stream, $subChunk->getLiquidLayer());
|
||||
self::serializePalettedArray($stream, $subChunk->getBiomeArray());
|
||||
}
|
||||
|
||||
return $stream->getBuffer();
|
||||
@ -112,12 +110,12 @@ final class FastChunkSerializer{
|
||||
$y = Binary::signByte($stream->getByte());
|
||||
$airBlockId = $stream->getInt();
|
||||
|
||||
$layers = [];
|
||||
for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){
|
||||
$layers[] = self::deserializePalettedArray($stream);
|
||||
}
|
||||
// Read block and liquid layers (always present)
|
||||
$blockLayer = self::deserializePalettedArray($stream);
|
||||
$liquidLayer = self::deserializePalettedArray($stream);
|
||||
$biomeArray = self::deserializePalettedArray($stream);
|
||||
$subChunks[$y] = new SubChunk($airBlockId, $layers, $biomeArray);
|
||||
|
||||
$subChunks[$y] = new SubChunk($airBlockId, $blockLayer, $liquidLayer, $biomeArray);
|
||||
}
|
||||
|
||||
return new Chunk($subChunks, $terrainPopulated);
|
||||
|
@ -462,17 +462,15 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
|
||||
$subChunks = [];
|
||||
for($yy = 0; $yy < 8; ++$yy){
|
||||
$storages = [$this->palettizeLegacySubChunkFromColumn($fullIds, $fullData, $yy, new \PrefixedLogger($logger, "Subchunk y=$yy"))];
|
||||
if(isset($convertedLegacyExtraData[$yy])){
|
||||
$storages[] = $convertedLegacyExtraData[$yy];
|
||||
}
|
||||
$subChunks[$yy] = new SubChunk(Block::EMPTY_STATE_ID, $storages, clone $biomes3d);
|
||||
$blockLayer = $this->palettizeLegacySubChunkFromColumn($fullIds, $fullData, $yy, new \PrefixedLogger($logger, "Subchunk y=$yy"));
|
||||
$liquidLayer = $convertedLegacyExtraData[$yy] ?? null;
|
||||
$subChunks[$yy] = new SubChunk(Block::EMPTY_STATE_ID, $blockLayer, $liquidLayer, 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(Block::EMPTY_STATE_ID, [], clone $biomes3d);
|
||||
$subChunks[$yy] = new SubChunk(Block::EMPTY_STATE_ID, null, null, clone $biomes3d);
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,12 +499,10 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
}
|
||||
}
|
||||
|
||||
$storages = [$this->palettizeLegacySubChunkXZY($blocks, $blockData, $logger)];
|
||||
if($convertedLegacyExtraData !== null){
|
||||
$storages[] = $convertedLegacyExtraData;
|
||||
}
|
||||
$blockLayer = $this->palettizeLegacySubChunkXZY($blocks, $blockData, $logger);
|
||||
$liquidLayer = $convertedLegacyExtraData;
|
||||
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $storages, $biomePalette);
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $blockLayer, $liquidLayer, $biomePalette);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -526,11 +522,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
case SubChunkVersion::CLASSIC_BUG_7:
|
||||
return $this->deserializeNonPalettedSubChunkData($binaryStream, $chunkVersion, $convertedLegacyExtraData, $biomePalette, $logger);
|
||||
case SubChunkVersion::PALETTED_SINGLE:
|
||||
$storages = [$this->deserializeBlockPalette($binaryStream, $logger)];
|
||||
if($convertedLegacyExtraData !== null){
|
||||
$storages[] = $convertedLegacyExtraData;
|
||||
}
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $storages, $biomePalette);
|
||||
$blockLayer = $this->deserializeBlockPalette($binaryStream, $logger);
|
||||
$liquidLayer = $convertedLegacyExtraData;
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $blockLayer, $liquidLayer, $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
|
||||
@ -541,11 +535,18 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
$binaryStream->getByte();
|
||||
}
|
||||
|
||||
$storages = [];
|
||||
$blockLayer = null;
|
||||
$liquidLayer = null;
|
||||
for($k = 0; $k < $storageCount; ++$k){
|
||||
$storages[] = $this->deserializeBlockPalette($binaryStream, $logger);
|
||||
$layer = $this->deserializeBlockPalette($binaryStream, $logger);
|
||||
if($k === 0){
|
||||
$blockLayer = $layer;
|
||||
}elseif($k === 1){
|
||||
$liquidLayer = $layer;
|
||||
}
|
||||
// Ignore additional layers beyond the first two
|
||||
}
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $storages, $biomePalette);
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $blockLayer, $liquidLayer, $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");
|
||||
@ -575,7 +576,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(Block::EMPTY_STATE_ID, [], $biomeArrays[$y]);
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, null, null, $biomeArrays[$y]);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -774,10 +775,18 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
$subStream = new BinaryStream();
|
||||
$subStream->putByte(self::CURRENT_LEVEL_SUBCHUNK_VERSION);
|
||||
|
||||
$layers = $subChunk->getBlockLayers();
|
||||
$layers = [];
|
||||
if(!$subChunk->isBlockLayerEmpty()){
|
||||
$layers[] = $subChunk->getBlockLayer();
|
||||
}
|
||||
if(!$subChunk->isLiquidLayerEmpty()){
|
||||
$layers[] = $subChunk->getLiquidLayer();
|
||||
}
|
||||
|
||||
$subStream->putByte(count($layers));
|
||||
foreach($layers as $blocks){
|
||||
$this->serializeBlockPalette($subStream, $blocks);
|
||||
|
||||
foreach($layers as $layer){
|
||||
$this->serializeBlockPalette($subStream, $layer);
|
||||
}
|
||||
|
||||
$write->put($key, $subStream->getBuffer());
|
||||
|
@ -32,11 +32,12 @@ class Anvil extends RegionWorldProvider{
|
||||
use LegacyAnvilChunkTrait;
|
||||
|
||||
protected function deserializeSubChunk(CompoundTag $subChunk, PalettedBlockArray $biomes3d, \Logger $logger) : SubChunk{
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, [$this->palettizeLegacySubChunkYZX(
|
||||
$blockLayer = $this->palettizeLegacySubChunkYZX(
|
||||
self::readFixedSizeByteArray($subChunk, "Blocks", 4096),
|
||||
self::readFixedSizeByteArray($subChunk, "Data", 2048),
|
||||
$logger
|
||||
)], $biomes3d);
|
||||
);
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $blockLayer, null, $biomes3d);
|
||||
//ignore legacy light information
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ trait LegacyAnvilChunkTrait{
|
||||
}
|
||||
for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){
|
||||
if(!isset($subChunks[$y])){
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, [], clone $biomes3d);
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, null, null, clone $biomes3d);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,16 +90,17 @@ class McRegion extends RegionWorldProvider{
|
||||
$fullData = self::readFixedSizeByteArray($chunk, "Data", 16384);
|
||||
|
||||
for($y = 0; $y < 8; ++$y){
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, [$this->palettizeLegacySubChunkFromColumn(
|
||||
$blockLayer = $this->palettizeLegacySubChunkFromColumn(
|
||||
$fullIds,
|
||||
$fullData,
|
||||
$y,
|
||||
new \PrefixedLogger($logger, "Subchunk y=$y"),
|
||||
)], clone $biomes3d);
|
||||
);
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, $blockLayer, null, clone $biomes3d);
|
||||
}
|
||||
for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){
|
||||
if(!isset($subChunks[$y])){
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, [], clone $biomes3d);
|
||||
$subChunks[$y] = new SubChunk(Block::EMPTY_STATE_ID, null, null, clone $biomes3d);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,12 @@ class PMAnvil extends RegionWorldProvider{
|
||||
use LegacyAnvilChunkTrait;
|
||||
|
||||
protected function deserializeSubChunk(CompoundTag $subChunk, PalettedBlockArray $biomes3d, \Logger $logger) : SubChunk{
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, [$this->palettizeLegacySubChunkXZY(
|
||||
$blockLayer = $this->palettizeLegacySubChunkXZY(
|
||||
self::readFixedSizeByteArray($subChunk, "Blocks", 4096),
|
||||
self::readFixedSizeByteArray($subChunk, "Data", 2048),
|
||||
$logger
|
||||
)], $biomes3d);
|
||||
);
|
||||
return new SubChunk(Block::EMPTY_STATE_ID, $blockLayer, null, $biomes3d);
|
||||
}
|
||||
|
||||
protected static function getRegionFileExtension() : string{
|
||||
|
@ -65,14 +65,19 @@ class BlockLightUpdate extends LightUpdate{
|
||||
foreach($chunk->getSubChunks() as $subChunkY => $subChunk){
|
||||
$subChunk->setBlockLightArray(LightArray::fill(0));
|
||||
|
||||
foreach($subChunk->getBlockLayers() as $layer){
|
||||
$hasLightEmitter = false;
|
||||
foreach([$subChunk->getBlockLayer(), $subChunk->getLiquidLayer()] as $layer){
|
||||
foreach($layer->getPalette() as $state){
|
||||
if(($this->lightEmitters[$state] ?? 0) > 0){
|
||||
$lightSources += $this->scanForLightEmittingBlocks($subChunk, $chunkX << SubChunk::COORD_BIT_SIZE, $subChunkY << SubChunk::COORD_BIT_SIZE, $chunkZ << SubChunk::COORD_BIT_SIZE);
|
||||
$hasLightEmitter = true;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($hasLightEmitter){
|
||||
$lightSources += $this->scanForLightEmittingBlocks($subChunk, $chunkX << SubChunk::COORD_BIT_SIZE, $subChunkY << SubChunk::COORD_BIT_SIZE, $chunkZ << SubChunk::COORD_BIT_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
return $lightSources;
|
||||
|
@ -32,7 +32,7 @@ class SubChunkTest extends TestCase{
|
||||
* Test that a cloned SubChunk instance doesn't influence the original
|
||||
*/
|
||||
public function testClone() : void{
|
||||
$sub1 = new SubChunk(0, [], new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
$sub1 = new SubChunk(0, null, null, new PalettedBlockArray(BiomeIds::OCEAN));
|
||||
|
||||
$sub1->setBlockStateId(0, 0, 0, 1);
|
||||
$sub1->getBlockLightArray()->set(0, 0, 0, 1);
|
||||
|
Reference in New Issue
Block a user