ChunkManager: Remove getBlockIdAt()/setBlockIdAt()/getBlockDataAt()/setBlockDataAt(), add getBlockAt() and setBlockAt()

This commit is contained in:
Dylan K. Taylor 2018-12-04 22:27:00 +00:00
parent 8dd2ea22b8
commit cd5b81bdb9
15 changed files with 69 additions and 127 deletions

View File

@ -98,8 +98,7 @@ class Farmland extends Transparent{
for($y = $start->y; $y <= $end->y; ++$y){ for($y = $start->y; $y <= $end->y; ++$y){
for($z = $start->z; $z <= $end->z; ++$z){ for($z = $start->z; $z <= $end->z; ++$z){
for($x = $start->x; $x <= $end->x; ++$x){ for($x = $start->x; $x <= $end->x; ++$x){
$id = $this->level->getBlockIdAt($x, $y, $z); if($this->level->getBlockAt($x, $y, $z) instanceof Water){
if($id === Block::STILL_WATER or $id === Block::FLOWING_WATER){
return true; return true;
} }
} }

View File

@ -78,16 +78,18 @@ class Grass extends Solid{
$x = mt_rand($this->x - 1, $this->x + 1); $x = mt_rand($this->x - 1, $this->x + 1);
$y = mt_rand($this->y - 3, $this->y + 1); $y = mt_rand($this->y - 3, $this->y + 1);
$z = mt_rand($this->z - 1, $this->z + 1); $z = mt_rand($this->z - 1, $this->z + 1);
$b = $this->level->getBlockAt($x, $y, $z);
if( if(
$this->level->getBlockIdAt($x, $y, $z) !== Block::DIRT or $b->getId() !== Block::DIRT or
$this->level->getBlockDataAt($x, $y, $z) === 1 or $b->getDamage() === 1 or //coarse dirt
$this->level->getFullLightAt($x, $y + 1, $z) < 4 or $this->level->getFullLightAt($x, $y + 1, $z) < 4 or
BlockFactory::$lightFilter[$this->level->getFullBlock($x, $y + 1, $z)] >= 3 BlockFactory::$lightFilter[$this->level->getFullBlock($x, $y + 1, $z)] >= 3
){ ){
continue; continue;
} }
$ev = new BlockSpreadEvent($b = $this->level->getBlockAt($x, $y, $z), $this, BlockFactory::get(Block::GRASS)); $ev = new BlockSpreadEvent($b, $this, BlockFactory::get(Block::GRASS));
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->level->setBlock($b, $ev->getNewState(), false); $this->level->setBlock($b, $ev->getNewState(), false);

View File

@ -23,32 +23,33 @@ declare(strict_types=1);
namespace pocketmine\level; namespace pocketmine\level;
use pocketmine\block\Block;
use pocketmine\level\format\Chunk; use pocketmine\level\format\Chunk;
interface ChunkManager{ interface ChunkManager{
/** /**
* Gets the raw block id. * Returns a Block object representing the block state at the given coordinates.
* *
* @param int $x * @param int $x
* @param int $y * @param int $y
* @param int $z * @param int $z
* *
* @return int 0-255 * @return Block
*/ */
public function getBlockIdAt(int $x, int $y, int $z) : int; public function getBlockAt(int $x, int $y, int $z) : Block;
/** /**
* Gets the raw block metadata * Sets the block at the given coordinates to the block state specified.
* *
* @param int $x * @param int $x
* @param int $y * @param int $y
* @param int $z * @param int $z
* @param Block $block
* *
* @return int 0-15 * @return bool TODO: remove
*/ */
public function getBlockDataAt(int $x, int $y, int $z) : int; public function setBlockAt(int $x, int $y, int $z, Block $block) : bool;
public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void;
/** /**
* Returns the raw block light level * Returns the raw block light level

View File

@ -200,6 +200,7 @@ class Explosion{
$air = ItemFactory::get(Item::AIR); $air = ItemFactory::get(Item::AIR);
$airBlock = BlockFactory::get(Block::AIR);
foreach($this->affectedBlocks as $block){ foreach($this->affectedBlocks as $block){
$yieldDrops = false; $yieldDrops = false;
@ -212,7 +213,7 @@ class Explosion{
} }
} }
$this->level->setBlockIdAndDataAt($block->x, $block->y, $block->z, 0, 0); $this->level->setBlockAt($block->x, $block->y, $block->z, $airBlock, false); //TODO: should updating really be disabled here?
$t = $this->level->getTileAt($block->x, $block->y, $block->z); $t = $this->level->getTileAt($block->x, $block->y, $block->z);
if($t instanceof Tile){ if($t instanceof Tile){

View File

@ -2100,49 +2100,6 @@ class Level implements ChunkManager, Metadatable{
return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getTiles() : []; return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getTiles() : [];
} }
/**
* Gets the raw block id.
*
* @param int $x
* @param int $y
* @param int $z
*
* @return int 0-255
*/
public function getBlockIdAt(int $x, int $y, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockId($x & 0x0f, $y, $z & 0x0f);
}
/**
* Gets the raw block metadata
*
* @param int $x
* @param int $y
* @param int $z
*
* @return int 0-15
*/
public function getBlockDataAt(int $x, int $y, int $z) : int{
return $this->getChunk($x >> 4, $z >> 4, true)->getBlockData($x & 0x0f, $y, $z & 0x0f);
}
public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{
if(!$this->isInWorld($x, $y, $z)){ //TODO: bad hack but fixing this requires BC breaks to do properly :(
return;
}
unset($this->blockCache[$chunkHash = Level::chunkHash($x >> 4, $z >> 4)][$blockHash = Level::blockHash($x, $y, $z)]);
$this->getChunk($x >> 4, $z >> 4, true)->setBlock($x & 0x0f, $y, $z & 0x0f, $id, $data);
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 skylight level * Gets the raw block skylight level
* *

View File

@ -23,6 +23,8 @@ declare(strict_types=1);
namespace pocketmine\level; namespace pocketmine\level;
use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\level\format\Chunk; use pocketmine\level\format\Chunk;
class SimpleChunkManager implements ChunkManager{ class SimpleChunkManager implements ChunkManager{
@ -41,42 +43,18 @@ class SimpleChunkManager implements ChunkManager{
$this->worldHeight = $worldHeight; $this->worldHeight = $worldHeight;
} }
/** public function getBlockAt(int $x, int $y, int $z) : Block{
* Gets the raw block id.
*
* @param int $x
* @param int $y
* @param int $z
*
* @return int 0-255
*/
public function getBlockIdAt(int $x, int $y, int $z) : int{
if($chunk = $this->getChunk($x >> 4, $z >> 4)){ if($chunk = $this->getChunk($x >> 4, $z >> 4)){
return $chunk->getBlockId($x & 0xf, $y, $z & 0xf); return BlockFactory::fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z & 0xf));
} }
return 0; return BlockFactory::get(Block::AIR);
} }
/** public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{
* Gets the raw block metadata
*
* @param int $x
* @param int $y
* @param int $z
*
* @return int 0-15
*/
public function getBlockDataAt(int $x, int $y, int $z) : int{
if($chunk = $this->getChunk($x >> 4, $z >> 4)){
return $chunk->getBlockData($x & 0xf, $y, $z & 0xf);
}
return 0;
}
public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{
if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){
$chunk->setBlock($x & 0xf, $y, $z & 0xf, $id, $data); return $chunk->setBlock($x & 0xf, $y, $z & 0xf, $block->getId(), $block->getDamage());
} }
return false;
} }
public function getBlockLightAt(int $x, int $y, int $z) : int{ public function getBlockLightAt(int $x, int $y, int $z) : int{

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\level\generator\object; namespace pocketmine\level\generator\object;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\block\Wood; use pocketmine\block\Wood;
use pocketmine\level\ChunkManager; use pocketmine\level\ChunkManager;
use pocketmine\utils\Random; use pocketmine\utils\Random;
@ -33,7 +34,7 @@ class BirchTree extends Tree{
protected $superBirch = false; protected $superBirch = false;
public function __construct(bool $superBirch = false){ public function __construct(bool $superBirch = false){
parent::__construct(Block::LOG, Block::LEAVES, Wood::BIRCH); parent::__construct(BlockFactory::get(Block::LOG, Wood::BIRCH), BlockFactory::get(Block::LEAVES, Wood::BIRCH));
$this->superBirch = $superBirch; $this->superBirch = $superBirch;
} }

View File

@ -24,11 +24,12 @@ declare(strict_types=1);
namespace pocketmine\level\generator\object; namespace pocketmine\level\generator\object;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\block\Wood; use pocketmine\block\Wood;
class JungleTree extends Tree{ class JungleTree extends Tree{
public function __construct(){ public function __construct(){
parent::__construct(Block::LOG, Block::LEAVES, Wood::JUNGLE, 8); parent::__construct(BlockFactory::get(Block::LOG, Wood::JUNGLE), BlockFactory::get(Block::LEAVES, Wood::JUNGLE), 8);
} }
} }

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\level\generator\object; namespace pocketmine\level\generator\object;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\block\Wood; use pocketmine\block\Wood;
use pocketmine\level\ChunkManager; use pocketmine\level\ChunkManager;
use pocketmine\utils\Random; use pocketmine\utils\Random;
@ -31,7 +32,7 @@ use pocketmine\utils\Random;
class OakTree extends Tree{ class OakTree extends Tree{
public function __construct(){ public function __construct(){
parent::__construct(Block::LOG, Block::LEAVES, Wood::OAK); parent::__construct(BlockFactory::get(Block::LOG, Wood::OAK), BlockFactory::get(Block::LEAVES, Wood::OAK));
} }
public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{

View File

@ -44,7 +44,7 @@ class Ore{
} }
public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z) : bool{ public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z) : bool{
return $level->getBlockIdAt($x, $y, $z) === Block::STONE; return $level->getBlockAt($x, $y, $z)->getId() === Block::STONE;
} }
public function placeObject(ChunkManager $level, int $x, int $y, int $z) : void{ public function placeObject(ChunkManager $level, int $x, int $y, int $z) : void{
@ -84,8 +84,8 @@ class Ore{
$sizeZ = ($z + 0.5 - $seedZ) / $size; $sizeZ = ($z + 0.5 - $seedZ) / $size;
$sizeZ *= $sizeZ; $sizeZ *= $sizeZ;
if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockIdAt($x, $y, $z) === Block::STONE){ if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockAt($x, $y, $z)->getId() === Block::STONE){
$level->setBlockIdAndDataAt($x, $y, $z, $this->type->material->getId(), $this->type->material->getDamage()); $level->setBlockAt($x, $y, $z, $this->type->material);
} }
} }
} }

View File

@ -32,7 +32,7 @@ use pocketmine\utils\Random;
class SpruceTree extends Tree{ class SpruceTree extends Tree{
public function __construct(){ public function __construct(){
parent::__construct(Block::LOG, Block::LEAVES, Wood::SPRUCE, 10); parent::__construct(BlockFactory::get(Block::LOG, Wood::SPRUCE), BlockFactory::get(Block::LEAVES, Wood::SPRUCE), 10);
} }
public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{
@ -58,8 +58,8 @@ class SpruceTree extends Tree{
continue; continue;
} }
if(!BlockFactory::get($level->getBlockIdAt($xx, $yyy, $zz))->isSolid()){ if(!$level->getBlockAt($xx, $yyy, $zz)->isSolid()){
$level->setBlockIdAndDataAt($xx, $yyy, $zz, $this->leafBlock, $this->blockMeta); $level->setBlockAt($xx, $yyy, $zz, $this->leafBlock);
} }
} }
} }

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\level\generator\object; namespace pocketmine\level\generator\object;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\level\ChunkManager; use pocketmine\level\ChunkManager;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\utils\Random; use pocketmine\utils\Random;
@ -31,21 +32,21 @@ use pocketmine\utils\Random;
class TallGrass{ class TallGrass{
public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{ public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{
/** @var Block[] $arr */
$arr = [ $arr = [
[Block::DANDELION, 0], BlockFactory::get(Block::DANDELION),
[Block::POPPY, 0], BlockFactory::get(Block::POPPY),
[Block::TALL_GRASS, 1], $tallGrass = BlockFactory::get(Block::TALL_GRASS, 1),
[Block::TALL_GRASS, 1], $tallGrass,
[Block::TALL_GRASS, 1], $tallGrass,
[Block::TALL_GRASS, 1] $tallGrass
]; ];
$arrC = count($arr) - 1; $arrC = count($arr) - 1;
for($c = 0; $c < $count; ++$c){ for($c = 0; $c < $count; ++$c){
$x = $random->nextRange($pos->x - $radius, $pos->x + $radius); $x = $random->nextRange($pos->x - $radius, $pos->x + $radius);
$z = $random->nextRange($pos->z - $radius, $pos->z + $radius); $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){ if($level->getBlockAt($x, $pos->y + 1, $z)->getId() === Block::AIR and $level->getBlockAt($x, $pos->y, $z)->getId() === Block::GRASS){
$t = $arr[$random->nextRange(0, $arrC)]; $level->setBlockAt($x, $pos->y + 1, $z, $arr[$random->nextRange(0, $arrC)]);
$level->setBlockIdAndDataAt($x, $pos->y + 1, $z, $t[0], $t[1]);
} }
} }
} }

View File

@ -33,20 +33,18 @@ use pocketmine\level\ChunkManager;
use pocketmine\utils\Random; use pocketmine\utils\Random;
abstract class Tree{ abstract class Tree{
/** @var Block */
/** @var int */
protected $blockMeta;
/** @var int */
protected $trunkBlock; protected $trunkBlock;
/** @var int */ /** @var Block */
protected $leafBlock; protected $leafBlock;
/** @var int */ /** @var int */
protected $treeHeight; protected $treeHeight;
public function __construct(int $trunkBlock, int $leafBlock, int $blockMeta, int $treeHeight = 7){ public function __construct(Block $trunkBlock, Block $leafBlock, int $treeHeight = 7){
$this->trunkBlock = $trunkBlock; $this->trunkBlock = $trunkBlock;
$this->leafBlock = $leafBlock; $this->leafBlock = $leafBlock;
$this->blockMeta = $blockMeta;
$this->treeHeight = $treeHeight; $this->treeHeight = $treeHeight;
} }
@ -91,7 +89,7 @@ abstract class Tree{
} }
for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){ for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){
for($zz = -$radiusToCheck; $zz < ($radiusToCheck + 1); ++$zz){ for($zz = -$radiusToCheck; $zz < ($radiusToCheck + 1); ++$zz){
if(!$this->canOverride(BlockFactory::get($level->getBlockIdAt($x + $xx, $y + $yy, $z + $zz)))){ if(!$this->canOverride($level->getBlockAt($x + $xx, $y + $yy, $z + $zz))){
return false; return false;
} }
} }
@ -114,8 +112,8 @@ abstract class Tree{
if($xOff === $mid and $zOff === $mid and ($yOff === 0 or $random->nextBoundedInt(2) === 0)){ if($xOff === $mid and $zOff === $mid and ($yOff === 0 or $random->nextBoundedInt(2) === 0)){
continue; continue;
} }
if(!BlockFactory::get($level->getBlockIdAt($xx, $yy, $zz))->isSolid()){ if(!$level->getBlockAt($xx, $yy, $zz)->isSolid()){
$level->setBlockIdAndDataAt($xx, $yy, $zz, $this->leafBlock, $this->blockMeta); $level->setBlockAt($xx, $yy, $zz, $this->leafBlock);
} }
} }
} }
@ -124,12 +122,11 @@ abstract class Tree{
protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight) : void{ protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight) : void{
// The base dirt block // The base dirt block
$level->setBlockIdAndDataAt($x, $y - 1, $z, Block::DIRT, 0); $level->setBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT));
for($yy = 0; $yy < $trunkHeight; ++$yy){ for($yy = 0; $yy < $trunkHeight; ++$yy){
$blockId = $level->getBlockIdAt($x, $y + $yy, $z); if($this->canOverride($level->getBlockAt($x, $y + $yy, $z))){
if($this->canOverride(BlockFactory::get($blockId))){ $level->setBlockAt($x, $y + $yy, $z, $this->trunkBlock);
$level->setBlockIdAndDataAt($x, $y + $yy, $z, $this->trunkBlock, $this->blockMeta);
} }
} }
} }

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\level\generator\populator; namespace pocketmine\level\generator\populator;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\level\ChunkManager; use pocketmine\level\ChunkManager;
use pocketmine\utils\Random; use pocketmine\utils\Random;
@ -44,25 +45,27 @@ class TallGrass extends Populator{
public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{
$this->level = $level; $this->level = $level;
$amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount;
$block = BlockFactory::get(Block::TALL_GRASS, 1);
for($i = 0; $i < $amount; ++$i){ for($i = 0; $i < $amount; ++$i){
$x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15); $x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15);
$z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15); $z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15);
$y = $this->getHighestWorkableBlock($x, $z); $y = $this->getHighestWorkableBlock($x, $z);
if($y !== -1 and $this->canTallGrassStay($x, $y, $z)){ if($y !== -1 and $this->canTallGrassStay($x, $y, $z)){
$this->level->setBlockIdAndDataAt($x, $y, $z, Block::TALL_GRASS, 1); $this->level->setBlockAt($x, $y, $z, $block);
} }
} }
} }
private function canTallGrassStay(int $x, int $y, int $z) : bool{ private function canTallGrassStay(int $x, int $y, int $z) : bool{
$b = $this->level->getBlockIdAt($x, $y, $z); $b = $this->level->getBlockAt($x, $y, $z)->getId();
return ($b === Block::AIR or $b === Block::SNOW_LAYER) and $this->level->getBlockIdAt($x, $y - 1, $z) === Block::GRASS; return ($b === Block::AIR or $b === Block::SNOW_LAYER) and $this->level->getBlockAt($x, $y - 1, $z)->getId() === Block::GRASS;
} }
private function getHighestWorkableBlock(int $x, int $z) : int{ private function getHighestWorkableBlock(int $x, int $z) : int{
for($y = 127; $y >= 0; --$y){ for($y = 127; $y >= 0; --$y){
$b = $this->level->getBlockIdAt($x, $y, $z); $b = $this->level->getBlockAt($x, $y, $z)->getId();
if($b !== Block::AIR and $b !== Block::LEAVES and $b !== Block::LEAVES2 and $b !== Block::SNOW_LAYER){ if($b !== Block::AIR and $b !== Block::LEAVES and $b !== Block::LEAVES2 and $b !== Block::SNOW_LAYER){
break; break;
} }

View File

@ -65,7 +65,7 @@ class Tree extends Populator{
private function getHighestWorkableBlock(int $x, int $z) : int{ private function getHighestWorkableBlock(int $x, int $z) : int{
for($y = 127; $y > 0; --$y){ for($y = 127; $y > 0; --$y){
$b = $this->level->getBlockIdAt($x, $y, $z); $b = $this->level->getBlockAt($x, $y, $z)->getId();
if($b === Block::DIRT or $b === Block::GRASS){ if($b === Block::DIRT or $b === Block::GRASS){
break; break;
}elseif($b !== Block::AIR and $b !== Block::SNOW_LAYER){ }elseif($b !== Block::AIR and $b !== Block::SNOW_LAYER){