From 98efd275432f74f010af48649b2dd8839cc558ff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Nov 2018 16:53:22 +0000 Subject: [PATCH] Remove ability to set blockID and blockdata independently This was the cause of many inconsistency and broken world bugs. In the future (once we switch to paletted chunks) this won't be possible anyway. For now, some temporary API is provided to allow modifying chunkdata directly, but it is required that **both** must be provided. --- src/pocketmine/level/ChunkManager.php | 20 +-------- src/pocketmine/level/Explosion.php | 3 +- src/pocketmine/level/Level.php | 33 +------------- src/pocketmine/level/SimpleChunkManager.php | 28 ++---------- src/pocketmine/level/format/Chunk.php | 32 +------------- src/pocketmine/level/format/EmptySubChunk.php | 10 +---- src/pocketmine/level/format/SubChunk.php | 44 +++++-------------- .../level/format/SubChunkInterface.php | 32 +++----------- .../level/generator/hell/Nether.php | 6 +-- .../level/generator/normal/Normal.php | 6 +-- src/pocketmine/level/generator/object/Ore.php | 5 +-- .../level/generator/object/SpruceTree.php | 3 +- .../level/generator/object/TallGrass.php | 3 +- .../level/generator/object/Tree.php | 8 ++-- .../level/generator/populator/GroundCover.php | 7 +-- .../level/generator/populator/TallGrass.php | 3 +- 16 files changed, 43 insertions(+), 200 deletions(-) diff --git a/src/pocketmine/level/ChunkManager.php b/src/pocketmine/level/ChunkManager.php index 373b6cbef..dd9fa341f 100644 --- a/src/pocketmine/level/ChunkManager.php +++ b/src/pocketmine/level/ChunkManager.php @@ -37,16 +37,6 @@ interface ChunkManager{ */ public function getBlockIdAt(int $x, int $y, int $z) : int; - /** - * Sets the raw block id. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $id 0-255 - */ - public function setBlockIdAt(int $x, int $y, int $z, int $id); - /** * Gets the raw block metadata * @@ -58,15 +48,7 @@ interface ChunkManager{ */ public function getBlockDataAt(int $x, int $y, int $z) : int; - /** - * Sets the raw block metadata. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $data 0-15 - */ - public function setBlockDataAt(int $x, int $y, int $z, int $data); + public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void; /** * Returns the raw block light level diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index e0dd86508..3d1a96391 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -212,8 +212,7 @@ class Explosion{ } } - $this->level->setBlockIdAt($block->x, $block->y, $block->z, 0); - $this->level->setBlockDataAt($block->x, $block->y, $block->z, 0); + $this->level->setBlockIdAndDataAt($block->x, $block->y, $block->z, 0, 0); $t = $this->level->getTileAt($block->x, $block->y, $block->z); if($t instanceof Tile){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 149309342..65610a025 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2098,27 +2098,6 @@ class Level implements ChunkManager, Metadatable{ return $this->getChunk($x >> 4, $z >> 4, true)->getBlockId($x & 0x0f, $y, $z & 0x0f); } - /** - * Sets the raw block id. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $id 0-255 - */ - public function setBlockIdAt(int $x, int $y, int $z, int $id){ - unset($this->blockCache[$chunkHash = Level::chunkHash($x >> 4, $z >> 4)][$blockHash = Level::blockHash($x, $y, $z)]); - $this->getChunk($x >> 4, $z >> 4, true)->setBlockId($x & 0x0f, $y, $z & 0x0f, $id & 0xff); - - if(!isset($this->changedBlocks[$chunkHash])){ - $this->changedBlocks[$chunkHash] = []; - } - $this->changedBlocks[$chunkHash][$blockHash] = $v = new Vector3($x, $y, $z); - foreach($this->getChunkLoaders($x >> 4, $z >> 4) as $loader){ - $loader->onBlockChanged($v); - } - } - /** * Gets the raw block metadata * @@ -2132,18 +2111,10 @@ class Level implements ChunkManager, Metadatable{ return $this->getChunk($x >> 4, $z >> 4, true)->getBlockData($x & 0x0f, $y, $z & 0x0f); } - /** - * Sets the raw block metadata. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $data 0-15 - */ - public function setBlockDataAt(int $x, int $y, int $z, int $data){ + public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{ unset($this->blockCache[$chunkHash = Level::chunkHash($x >> 4, $z >> 4)][$blockHash = Level::blockHash($x, $y, $z)]); - $this->getChunk($x >> 4, $z >> 4, true)->setBlockData($x & 0x0f, $y, $z & 0x0f, $data & 0x0f); + $this->getChunk($x >> 4, $z >> 4, true)->setBlock($x & 0x0f, $y, $z & 0x0f, $id, $data); if(!isset($this->changedBlocks[$chunkHash])){ $this->changedBlocks[$chunkHash] = []; diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index e240e23ee..724388178 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -57,20 +57,6 @@ class SimpleChunkManager implements ChunkManager{ return 0; } - /** - * Sets the raw block id. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $id 0-255 - */ - public function setBlockIdAt(int $x, int $y, int $z, int $id){ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - $chunk->setBlockId($x & 0xf, $y, $z & 0xf, $id); - } - } - /** * Gets the raw block metadata * @@ -87,17 +73,9 @@ class SimpleChunkManager implements ChunkManager{ return 0; } - /** - * Sets the raw block metadata. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $data 0-15 - */ - public function setBlockDataAt(int $x, int $y, int $z, int $data){ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - $chunk->setBlockData($x & 0xf, $y, $z & 0xf, $data); + public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ + $chunk->setBlock($x & 0xf, $y & 0xf, $z & 0xf, $id, $data); } } diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 927149cd3..e66d7e3de 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -184,8 +184,8 @@ class Chunk{ * * @return bool */ - public function setBlock(int $x, int $y, int $z, ?int $blockId = null, ?int $meta = null) : bool{ - if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId !== null ? ($blockId & 0xff) : null, $meta !== null ? ($meta & 0x0f) : null)){ + public function setBlock(int $x, int $y, int $z, int $blockId, int $meta) : bool{ + if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f)){ $this->hasChanged = true; return true; } @@ -205,20 +205,6 @@ class Chunk{ return $this->getSubChunk($y >> 4)->getBlockId($x, $y & 0x0f, $z); } - /** - * Sets the block ID at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y - * @param int $z 0-15 - * @param int $id 0-255 - */ - public function setBlockId(int $x, int $y, int $z, int $id){ - if($this->getSubChunk($y >> 4, true)->setBlockId($x, $y & 0x0f, $z, $id)){ - $this->hasChanged = true; - } - } - /** * Returns the block meta value at the specified chunk block coordinates * @@ -232,20 +218,6 @@ class Chunk{ return $this->getSubChunk($y >> 4)->getBlockData($x, $y & 0x0f, $z); } - /** - * Sets the block meta value at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y - * @param int $z 0-15 - * @param int $data 0-15 - */ - public function setBlockData(int $x, int $y, int $z, int $data){ - if($this->getSubChunk($y >> 4, true)->setBlockData($x, $y & 0x0f, $z, $data)){ - $this->hasChanged = true; - } - } - /** * Returns the sky light level at the specified chunk block coordinates * diff --git a/src/pocketmine/level/format/EmptySubChunk.php b/src/pocketmine/level/format/EmptySubChunk.php index 1e137ae05..6fb4d8d11 100644 --- a/src/pocketmine/level/format/EmptySubChunk.php +++ b/src/pocketmine/level/format/EmptySubChunk.php @@ -43,23 +43,15 @@ class EmptySubChunk implements SubChunkInterface{ return 0; } - public function setBlockId(int $x, int $y, int $z, int $id) : bool{ - return false; - } - public function getBlockData(int $x, int $y, int $z) : int{ return 0; } - public function setBlockData(int $x, int $y, int $z, int $data) : bool{ - return false; - } - public function getFullBlock(int $x, int $y, int $z) : int{ return 0; } - public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool{ + public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool{ return false; } diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index af6343684..32b62e472 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -64,51 +64,31 @@ class SubChunk implements SubChunkInterface{ return ord($this->ids{($x << 8) | ($z << 4) | $y}); } - public function setBlockId(int $x, int $y, int $z, int $id) : bool{ - $this->ids{($x << 8) | ($z << 4) | $y} = chr($id); - return true; - } - public function getBlockData(int $x, int $y, int $z) : int{ return (ord($this->data{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; } - public function setBlockData(int $x, int $y, int $z, int $data) : bool{ - $i = ($x << 7) | ($z << 3) | ($y >> 1); - - $shift = ($y & 1) << 2; - $byte = ord($this->data{$i}); - $this->data{$i} = chr(($byte & ~(0xf << $shift)) | (($data & 0xf) << $shift)); - - return true; - } - public function getFullBlock(int $x, int $y, int $z) : int{ $i = ($x << 8) | ($z << 4) | $y; return (ord($this->ids{$i}) << 4) | ((ord($this->data{$i >> 1}) >> (($y & 1) << 2)) & 0xf); } - public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool{ + public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool{ $i = ($x << 8) | ($z << 4) | $y; $changed = false; - if($id !== null){ - $block = chr($id); - if($this->ids{$i} !== $block){ - $this->ids{$i} = $block; - $changed = true; - } + + $block = chr($id); + if($this->ids{$i} !== $block){ + $this->ids{$i} = $block; + $changed = true; } - if($data !== null){ - $i >>= 1; - - $shift = ($y & 1) << 2; - $oldPair = ord($this->data{$i}); - $newPair = ($oldPair & ~(0xf << $shift)) | (($data & 0xf) << $shift); - if($newPair !== $oldPair){ - $this->data{$i} = chr($newPair); - $changed = true; - } + $shift = ($y & 1) << 2; + $oldPair = ord($this->data{$i}); + $newPair = ($oldPair & ~(0xf << $shift)) | (($data & 0xf) << $shift); + if($newPair !== $oldPair){ + $this->data{$i} = chr($newPair); + $changed = true; } return $changed; diff --git a/src/pocketmine/level/format/SubChunkInterface.php b/src/pocketmine/level/format/SubChunkInterface.php index e7d4cde8b..71226db90 100644 --- a/src/pocketmine/level/format/SubChunkInterface.php +++ b/src/pocketmine/level/format/SubChunkInterface.php @@ -41,16 +41,6 @@ interface SubChunkInterface{ */ public function getBlockId(int $x, int $y, int $z) : int; - /** - * @param int $x - * @param int $y - * @param int $z - * @param int $id - * - * @return bool - */ - public function setBlockId(int $x, int $y, int $z, int $id) : bool; - /** * @param int $x * @param int $y @@ -60,16 +50,6 @@ interface SubChunkInterface{ */ public function getBlockData(int $x, int $y, int $z) : int; - /** - * @param int $x - * @param int $y - * @param int $z - * @param int $data - * - * @return bool - */ - public function setBlockData(int $x, int $y, int $z, int $data) : bool; - /** * @param int $x * @param int $y @@ -80,15 +60,15 @@ interface SubChunkInterface{ public function getFullBlock(int $x, int $y, int $z) : int; /** - * @param int $x - * @param int $y - * @param int $z - * @param int|null $id - * @param int|null $data + * @param int $x + * @param int $y + * @param int $z + * @param int $id + * @param int $data * * @return bool */ - public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool; + public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool; /** * @param int $x diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index 121522691..838fa4db2 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -88,16 +88,16 @@ class Nether extends Generator{ for($y = 0; $y < 128; ++$y){ if($y === 0 or $y === 127){ - $chunk->setBlockId($x, $y, $z, Block::BEDROCK); + $chunk->setBlock($x, $y, $z, Block::BEDROCK, 0); continue; } $noiseValue = (abs($this->emptyHeight - $y) / $this->emptyHeight) * $this->emptyAmplitude - $noise[$x][$z][$y]; $noiseValue -= 1 - $this->density; if($noiseValue > 0){ - $chunk->setBlockId($x, $y, $z, Block::NETHERRACK); + $chunk->setBlock($x, $y, $z, Block::NETHERRACK, 0); }elseif($y <= $this->waterHeight){ - $chunk->setBlockId($x, $y, $z, Block::STILL_LAVA); + $chunk->setBlock($x, $y, $z, Block::STILL_LAVA, 0); } } } diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index 79e3a6e1f..14c52e412 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -208,15 +208,15 @@ class Normal extends Generator{ for($y = 0; $y < 128; ++$y){ if($y === 0){ - $chunk->setBlockId($x, $y, $z, Block::BEDROCK); + $chunk->setBlock($x, $y, $z, Block::BEDROCK, 0); continue; } $noiseValue = $noise[$x][$z][$y] - 1 / $smoothHeight * ($y - $smoothHeight - $minSum); if($noiseValue > 0){ - $chunk->setBlockId($x, $y, $z, Block::STONE); + $chunk->setBlock($x, $y, $z, Block::STONE, 0); }elseif($y <= $this->waterHeight){ - $chunk->setBlockId($x, $y, $z, Block::STILL_WATER); + $chunk->setBlock($x, $y, $z, Block::STILL_WATER, 0); } } } diff --git a/src/pocketmine/level/generator/object/Ore.php b/src/pocketmine/level/generator/object/Ore.php index 27e7a15f9..048bd212e 100644 --- a/src/pocketmine/level/generator/object/Ore.php +++ b/src/pocketmine/level/generator/object/Ore.php @@ -85,10 +85,7 @@ class Ore{ $sizeZ *= $sizeZ; if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockIdAt($x, $y, $z) === Block::STONE){ - $level->setBlockIdAt($x, $y, $z, $this->type->material->getId()); - if($this->type->material->getDamage() !== 0){ - $level->setBlockDataAt($x, $y, $z, $this->type->material->getDamage()); - } + $level->setBlockIdAndDataAt($x, $y, $z, $this->type->material->getId(), $this->type->material->getDamage()); } } } diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index 2ff0304ac..cb7346cb7 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -59,8 +59,7 @@ class SpruceTree extends Tree{ } if(!BlockFactory::get($level->getBlockIdAt($xx, $yyy, $zz))->isSolid()){ - $level->setBlockIdAt($xx, $yyy, $zz, $this->leafBlock); - $level->setBlockDataAt($xx, $yyy, $zz, $this->blockMeta); + $level->setBlockIdAndDataAt($xx, $yyy, $zz, $this->leafBlock, $this->blockMeta); } } } diff --git a/src/pocketmine/level/generator/object/TallGrass.php b/src/pocketmine/level/generator/object/TallGrass.php index cfa8098b1..ce1aee00f 100644 --- a/src/pocketmine/level/generator/object/TallGrass.php +++ b/src/pocketmine/level/generator/object/TallGrass.php @@ -45,8 +45,7 @@ class TallGrass{ $z = $random->nextRange($pos->z - $radius, $pos->z + $radius); if($level->getBlockIdAt($x, $pos->y + 1, $z) === Block::AIR and $level->getBlockIdAt($x, $pos->y, $z) === Block::GRASS){ $t = $arr[$random->nextRange(0, $arrC)]; - $level->setBlockIdAt($x, $pos->y + 1, $z, $t[0]); - $level->setBlockDataAt($x, $pos->y + 1, $z, $t[1]); + $level->setBlockIdAndDataAt($x, $pos->y + 1, $z, $t[0], $t[1]); } } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 5d3367bdb..f0dced5a6 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -115,8 +115,7 @@ abstract class Tree{ continue; } if(!BlockFactory::get($level->getBlockIdAt($xx, $yy, $zz))->isSolid()){ - $level->setBlockIdAt($xx, $yy, $zz, $this->leafBlock); - $level->setBlockDataAt($xx, $yy, $zz, $this->blockMeta); + $level->setBlockIdAndDataAt($xx, $yy, $zz, $this->leafBlock, $this->blockMeta); } } } @@ -125,13 +124,12 @@ abstract class Tree{ protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight) : void{ // The base dirt block - $level->setBlockIdAt($x, $y - 1, $z, Block::DIRT); + $level->setBlockIdAndDataAt($x, $y - 1, $z, Block::DIRT, 0); for($yy = 0; $yy < $trunkHeight; ++$yy){ $blockId = $level->getBlockIdAt($x, $y + $yy, $z); if($this->canOverride(BlockFactory::get($blockId))){ - $level->setBlockIdAt($x, $y + $yy, $z, $this->trunkBlock); - $level->setBlockDataAt($x, $y + $yy, $z, $this->blockMeta); + $level->setBlockIdAndDataAt($x, $y + $yy, $z, $this->trunkBlock, $this->blockMeta); } } } diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 1218b449a..2dd9109fc 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -61,11 +61,8 @@ class GroundCover extends Populator{ if($b->canBeFlowedInto() and BlockFactory::get($id) instanceof Liquid){ continue; } - if($b->getDamage() === 0){ - $chunk->setBlockId($x, $y, $z, $b->getId()); - }else{ - $chunk->setBlock($x, $y, $z, $b->getId(), $b->getDamage()); - } + + $chunk->setBlock($x, $y, $z, $b->getId(), $b->getDamage()); } } } diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/level/generator/populator/TallGrass.php index 3532bc568..6a16870a6 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/level/generator/populator/TallGrass.php @@ -50,8 +50,7 @@ class TallGrass extends Populator{ $y = $this->getHighestWorkableBlock($x, $z); if($y !== -1 and $this->canTallGrassStay($x, $y, $z)){ - $this->level->setBlockIdAt($x, $y, $z, Block::TALL_GRASS); - $this->level->setBlockDataAt($x, $y, $z, 1); + $this->level->setBlockIdAndDataAt($x, $y, $z, Block::TALL_GRASS, 1); } } }