mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
Removed the need for subchunks to know their Y coordinates
This commit is contained in:
parent
e85d6d134e
commit
69061ba4ad
@ -914,9 +914,8 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
|
||||
|
||||
foreach($chunk->getSubChunks() as $subChunk){
|
||||
foreach($chunk->getSubChunks() as $Y => $subChunk){
|
||||
if(!$subChunk->isEmpty()){
|
||||
$Y = $subChunk->getY();
|
||||
$k = mt_rand(0, 0x7fffffff);
|
||||
for($i = 0; $i < 3; ++$i, $k >>= 10){
|
||||
$x = $k & 0x0f;
|
||||
|
@ -76,7 +76,7 @@ interface Chunk{
|
||||
* @param int $x 0-15
|
||||
* @param int $y 0-255
|
||||
* @param int $z 0-15
|
||||
* @param int $blockId , if null, do not change
|
||||
* @param int $blockId 0-255, if null, do not change
|
||||
* @param int $meta 0-15, if null, do not change
|
||||
*
|
||||
* @return bool
|
||||
@ -301,16 +301,8 @@ interface Chunk{
|
||||
*/
|
||||
public function getHeightMapArray() : array;
|
||||
|
||||
public function getBlockIdArray() : string;
|
||||
|
||||
public function getBlockDataArray() : string;
|
||||
|
||||
public function getBlockExtraDataArray() : array;
|
||||
|
||||
public function getBlockSkyLightArray() : string;
|
||||
|
||||
public function getBlockLightArray() : string;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -26,10 +26,9 @@ namespace pocketmine\level\format\generic;
|
||||
use pocketmine\utils\ChunkException;
|
||||
|
||||
class EmptySubChunk extends SubChunk{
|
||||
protected $y;
|
||||
|
||||
public function __construct(int $y){
|
||||
$this->y = $y;
|
||||
public function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public function isEmpty() : bool{
|
||||
@ -109,7 +108,7 @@ class EmptySubChunk extends SubChunk{
|
||||
}
|
||||
|
||||
public function networkSerialize() : string{
|
||||
return "\x00" . str_repeat("\x00", 10240);
|
||||
return str_repeat("\x00", 10240);
|
||||
}
|
||||
|
||||
public function fastSerialize() : string{
|
||||
|
@ -97,13 +97,12 @@ class GenericChunk implements Chunk{
|
||||
|
||||
$this->height = $provider !== null ? ($provider->getWorldHeight() >> 4) : 16;
|
||||
|
||||
foreach($subChunks as $subChunk){
|
||||
$y = $subChunk->getY();
|
||||
foreach($subChunks as $y => $subChunk){
|
||||
if($y < 0 or $y >= $this->height){
|
||||
throw new ChunkException("Invalid subchunk index $y!");
|
||||
}
|
||||
if($subChunk->isEmpty()){
|
||||
$this->subChunks[$y] = new EmptySubChunk($y);
|
||||
$this->subChunks[$y] = new EmptySubChunk(); //TODO: point to a single object instead of creating many for each chunk
|
||||
}else{
|
||||
$this->subChunks[$y] = $subChunk;
|
||||
}
|
||||
@ -111,7 +110,7 @@ class GenericChunk implements Chunk{
|
||||
|
||||
for($i = 0; $i < $this->height; ++$i){
|
||||
if(!isset($this->subChunks[$i])){
|
||||
$this->subChunks[$i] = new EmptySubChunk($i);
|
||||
$this->subChunks[$i] = new EmptySubChunk(); //TODO: todo above
|
||||
}
|
||||
}
|
||||
|
||||
@ -511,42 +510,10 @@ class GenericChunk implements Chunk{
|
||||
return $this->heightMap;
|
||||
}
|
||||
|
||||
public function getBlockIdArray() : string{
|
||||
$result = "";
|
||||
foreach($this->subChunks as $subChunk){
|
||||
$result .= $subChunk->getBlockIdArray();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getBlockDataArray() : string{
|
||||
$result = "";
|
||||
foreach($this->subChunks as $subChunk){
|
||||
$result .= $subChunk->getBlockDataArray();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getBlockExtraDataArray() : array{
|
||||
return $this->extraData;
|
||||
}
|
||||
|
||||
public function getBlockSkyLightArray() : string{
|
||||
$result = "";
|
||||
foreach($this->subChunks as $subChunk){
|
||||
$result .= $subChunk->getSkyLightArray();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getBlockLightArray() : string{
|
||||
$result = "";
|
||||
foreach($this->subChunks as $subChunk){
|
||||
$result .= $subChunk->getBlockLightArray();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function hasChanged() : bool{
|
||||
return $this->hasChanged;
|
||||
}
|
||||
@ -555,13 +522,13 @@ class GenericChunk implements Chunk{
|
||||
$this->hasChanged = $value;
|
||||
}
|
||||
|
||||
public function getSubChunk(int $fY, bool $generateNew = false) : SubChunk{
|
||||
if($fY < 0 or $fY >= $this->height){
|
||||
return new EmptySubChunk($fY);
|
||||
}elseif($generateNew and $this->subChunks[$fY] instanceof EmptySubChunk){
|
||||
$this->subChunks[$fY] = new SubChunk($fY);
|
||||
public function getSubChunk(int $y, bool $generateNew = false) : SubChunk{
|
||||
if($y < 0 or $y >= $this->height){
|
||||
return new EmptySubChunk();
|
||||
}elseif($generateNew and $this->subChunks[$y] instanceof EmptySubChunk){
|
||||
$this->subChunks[$y] = new SubChunk();
|
||||
}
|
||||
return $this->subChunks[$fY];
|
||||
return $this->subChunks[$y];
|
||||
}
|
||||
|
||||
public function setSubChunk(int $fY, SubChunk $subChunk = null, bool $allowEmpty = false) : bool{
|
||||
@ -654,12 +621,12 @@ class GenericChunk implements Chunk{
|
||||
$stream->putInt($chunk->z);
|
||||
$count = 0;
|
||||
$subChunks = "";
|
||||
foreach($chunk->subChunks as $subChunk){
|
||||
foreach($chunk->subChunks as $y => $subChunk){
|
||||
if($subChunk->isEmpty()){
|
||||
continue;
|
||||
}
|
||||
++$count;
|
||||
$subChunks .= $subChunk->fastSerialize();
|
||||
$subChunks .= chr($y) . $subChunk->fastSerialize();
|
||||
}
|
||||
$stream->putByte($count);
|
||||
$stream->put($subChunks);
|
||||
@ -679,8 +646,7 @@ class GenericChunk implements Chunk{
|
||||
$subChunks = [];
|
||||
$count = $stream->getByte();
|
||||
for($y = 0; $y < $count; ++$y){
|
||||
$subChunks[] = new SubChunk(
|
||||
$stream->getByte(), //y
|
||||
$subChunks[$stream->getByte()] = new SubChunk(
|
||||
$stream->get(4096), //blockIds
|
||||
$stream->get(2048), //blockData
|
||||
$stream->get(2048), //skyLight
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types = 1);
|
||||
namespace pocketmine\level\format\generic;
|
||||
|
||||
class SubChunk{
|
||||
protected $y;
|
||||
|
||||
protected $ids;
|
||||
protected $data;
|
||||
@ -40,18 +39,13 @@ class SubChunk{
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct(int $y, string $ids = "", string $data = "", string $blockLight = "", string $skyLight = ""){
|
||||
$this->y = $y;
|
||||
public function __construct(string $ids = "", string $data = "", string $blockLight = "", string $skyLight = ""){
|
||||
self::assignData($this->ids, $ids, 4096);
|
||||
self::assignData($this->data, $data, 2048);
|
||||
self::assignData($this->blockLight, $blockLight, 2048);
|
||||
self::assignData($this->skyLight, $skyLight, 2048);
|
||||
}
|
||||
|
||||
public function getY() : int{
|
||||
return $this->y;
|
||||
}
|
||||
|
||||
public function isEmpty() : bool{
|
||||
assert(strlen($this->ids) === 4096, "Wrong length of ID array, expecting 4096 bytes, got " . strlen($this->ids));
|
||||
return substr_count($this->ids, "\x00") === 4096;
|
||||
@ -213,7 +207,7 @@ class SubChunk{
|
||||
}
|
||||
|
||||
public function fastSerialize() : string{
|
||||
// y, ids, data, skylight, blocklight
|
||||
return chr($this->y) . $this->ids . $this->data . $this->skyLight . $this->blockLight;
|
||||
// ids, data, skylight, blocklight
|
||||
return $this->ids . $this->data . $this->skyLight . $this->blockLight;
|
||||
}
|
||||
}
|
@ -53,12 +53,12 @@ class Anvil extends McRegion{
|
||||
$nbt->Sections = new ListTag("Sections", []);
|
||||
$nbt->Sections->setTagType(NBT::TAG_Compound);
|
||||
$subChunks = -1;
|
||||
foreach($chunk->getSubChunks() as $subChunk){
|
||||
foreach($chunk->getSubChunks() as $y => $subChunk){
|
||||
if($subChunk->isEmpty()){
|
||||
continue;
|
||||
}
|
||||
$nbt->Sections[++$subChunks] = new CompoundTag(null, [
|
||||
"Y" => new ByteTag("Y", $subChunk->getY()),
|
||||
"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())),
|
||||
@ -116,8 +116,7 @@ class Anvil extends McRegion{
|
||||
if($chunk->Sections instanceof ListTag){
|
||||
foreach($chunk->Sections as $subChunk){
|
||||
if($subChunk instanceof CompoundTag){
|
||||
$subChunks[] = new SubChunk(
|
||||
$subChunk->Y->getValue(),
|
||||
$subChunks[$subChunk->Y->getValue()] = new SubChunk(
|
||||
GenericChunk::reorderByteArray($subChunk->Blocks->getValue()),
|
||||
GenericChunk::reorderNibbleArray($subChunk->Data->getValue()),
|
||||
GenericChunk::reorderNibbleArray($subChunk->BlockLight->getValue()),
|
||||
|
@ -66,10 +66,11 @@ class McRegion extends BaseLevelProvider{
|
||||
$data = "";
|
||||
$blockLight = "";
|
||||
$skyLight = "";
|
||||
$subChunks = $chunk->getSubChunks();
|
||||
for($x = 0; $x < 16; ++$x){
|
||||
for($z = 0; $z < 16; ++$z){
|
||||
for($y = 0; $y < 8; ++$y){
|
||||
$subChunk = $chunk->getSubChunk($y);
|
||||
$subChunk = $subChunks[$y];
|
||||
$ids .= $subChunk->getBlockIdColumn($x, $z);
|
||||
$data .= $subChunk->getBlockDataColumn($x, $z);
|
||||
$blockLight .= $subChunk->getBlockLightColumn($x, $z);
|
||||
@ -165,7 +166,7 @@ class McRegion extends BaseLevelProvider{
|
||||
$skyLight .= substr($fullSkyLight, $offset, 8);
|
||||
$offset += 64;
|
||||
}
|
||||
$subChunks[] = new SubChunk($y, $ids, $data, $blockLight, $skyLight);
|
||||
$subChunks[$y] = new SubChunk($ids, $data, $blockLight, $skyLight);
|
||||
}
|
||||
|
||||
if(isset($chunk->BiomeColors)){
|
||||
|
@ -57,12 +57,12 @@ class PMAnvil extends Anvil{
|
||||
$nbt->Sections = new ListTag("Sections", []);
|
||||
$nbt->Sections->setTagType(NBT::TAG_Compound);
|
||||
$subChunks = -1;
|
||||
foreach($chunk->getSubChunks() as $subChunk){
|
||||
foreach($chunk->getSubChunks() as $y => $subChunk){
|
||||
if($subChunk->isEmpty()){
|
||||
continue;
|
||||
}
|
||||
$nbt->Sections[++$subChunks] = new CompoundTag(null, [
|
||||
"Y" => new ByteTag("Y", $subChunk->getY()),
|
||||
"Y" => new ByteTag("Y", $y),
|
||||
"Blocks" => new ByteArrayTag("Blocks", $subChunk->getBlockIdArray()),
|
||||
"Data" => new ByteArrayTag("Data", $subChunk->getBlockDataArray()),
|
||||
"BlockLight" => new ByteArrayTag("BlockLight", $subChunk->getBlockLightArray()),
|
||||
@ -120,8 +120,7 @@ class PMAnvil extends Anvil{
|
||||
if($chunk->Sections instanceof ListTag){
|
||||
foreach($chunk->Sections as $subChunk){
|
||||
if($subChunk instanceof CompoundTag){
|
||||
$subChunks[] = new SubChunk(
|
||||
$subChunk->Y->getValue(),
|
||||
$subChunks[$subChunk->Y->getValue()] = new SubChunk(
|
||||
$subChunk->Blocks->getValue(),
|
||||
$subChunk->Data->getValue(),
|
||||
$subChunk->BlockLight->getValue(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user