Fixed getBlock() performance degradation caused by 781de3efabcd526281fd1adc8ce881d408471563, added Level->getBlockAt() to avoid creating vectors everywhere

This commit is contained in:
Dylan K. Taylor 2017-10-20 13:22:49 +01:00
parent 98cfd0b398
commit 18e4e5364f
10 changed files with 88 additions and 69 deletions

View File

@ -2579,7 +2579,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{
$block = $this->level->getBlock($this->temporalVector->setComponents($packet->blockX, $packet->blockY, $packet->blockZ));
$block = $this->level->getBlockAt($packet->blockX, $packet->blockY, $packet->blockZ);
//TODO: this doesn't handle crops correctly (need more API work)
$item = Item::get($block->getItemId(), $block->getVariant());

View File

@ -92,7 +92,7 @@ class Cactus extends Transparent{
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::CACTUS){
if($this->meta === 0x0f){
for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
$b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z);
if($b->getId() === self::AIR){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, BlockFactory::get(Block::CACTUS)));
if(!$ev->isCancelled()){

View File

@ -76,23 +76,22 @@ class Grass extends Solid{
return Level::BLOCK_UPDATE_RANDOM;
}elseif($lightAbove >= 9){
//try grass spread
$vector = $this->asVector3();
for($i = 0; $i < 4; ++$i){
$vector->x = mt_rand($this->x - 1, $this->x + 1);
$vector->y = mt_rand($this->y - 3, $this->y + 1);
$vector->z = mt_rand($this->z - 1, $this->z + 1);
$x = mt_rand($this->x - 1, $this->x + 1);
$y = mt_rand($this->y - 3, $this->y + 1);
$z = mt_rand($this->z - 1, $this->z + 1);
if(
$this->level->getBlockIdAt($vector->x, $vector->y, $vector->z) !== Block::DIRT or
$this->level->getBlockDataAt($vector->x, $vector->y, $vector->z) === 1 or
$this->level->getFullLightAt($vector->x, $vector->y + 1, $vector->z) < 4 or
BlockFactory::$lightFilter[$this->level->getBlockIdAt($vector->x, $vector->y + 1, $vector->z)] >= 3
$this->level->getBlockIdAt($x, $y, $z) !== Block::DIRT or
$this->level->getBlockDataAt($x, $y, $z) === 1 or
$this->level->getFullLightAt($x, $y + 1, $z) < 4 or
BlockFactory::$lightFilter[$this->level->getBlockIdAt($x, $y + 1, $z)] >= 3
){
continue;
}
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this->level->getBlock($vector), $this, BlockFactory::get(Block::GRASS)));
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($b = $this->level->getBlockAt($x, $y, $z), $this, BlockFactory::get(Block::GRASS)));
if(!$ev->isCancelled()){
$this->level->setBlock($vector, $ev->getNewState(), false, false);
$this->level->setBlock($b, $ev->getNewState(), false, false);
}
}

View File

@ -117,7 +117,7 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){
++$z;
}
$sideBlock = $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $z));
$sideBlock = $this->getLevel()->getBlockAt($x, $y, $z);
$blockDecay = $this->getEffectiveFlowDecay($sideBlock);
if($blockDecay < 0){
@ -125,7 +125,7 @@ abstract class Liquid extends Transparent{
continue;
}
$blockDecay = $this->getEffectiveFlowDecay($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z)));
$blockDecay = $this->getEffectiveFlowDecay($this->getLevel()->getBlockAt($x, $y - 1, $z));
if($blockDecay >= 0){
$realDecay = $blockDecay - ($decay - 8);
@ -146,21 +146,21 @@ abstract class Liquid extends Transparent{
if($this->getDamage() >= 8){
$falling = false;
if(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1))->canBeFlowedInto()){
if(!$this->getLevel()->getBlockAt($this->x, $this->y, $this->z - 1)->canBeFlowedInto()){
$falling = true;
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1))->canBeFlowedInto()){
}elseif(!$this->getLevel()->getBlockAt($this->x, $this->y, $this->z + 1)->canBeFlowedInto()){
$falling = true;
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z))->canBeFlowedInto()){
}elseif(!$this->getLevel()->getBlockAt($this->x - 1, $this->y, $this->z)->canBeFlowedInto()){
$falling = true;
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z))->canBeFlowedInto()){
}elseif(!$this->getLevel()->getBlockAt($this->x + 1, $this->y, $this->z)->canBeFlowedInto()){
$falling = true;
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z - 1))->canBeFlowedInto()){
}elseif(!$this->getLevel()->getBlockAt($this->x, $this->y + 1, $this->z - 1)->canBeFlowedInto()){
$falling = true;
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z + 1))->canBeFlowedInto()){
}elseif(!$this->getLevel()->getBlockAt($this->x, $this->y + 1, $this->z + 1)->canBeFlowedInto()){
$falling = true;
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y + 1, $this->z))->canBeFlowedInto()){
}elseif(!$this->getLevel()->getBlockAt($this->x - 1, $this->y + 1, $this->z)->canBeFlowedInto()){
$falling = true;
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y + 1, $this->z))->canBeFlowedInto()){
}elseif(!$this->getLevel()->getBlockAt($this->x + 1, $this->y + 1, $this->z)->canBeFlowedInto()){
$falling = true;
}
@ -206,10 +206,10 @@ abstract class Liquid extends Transparent{
if($decay > 0){
$smallestFlowDecay = -100;
$this->adjacentSources = 0;
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1)), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1)), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z)), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z)), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x, $this->y, $this->z - 1), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x, $this->y, $this->z + 1), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x - 1, $this->y, $this->z), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x + 1, $this->y, $this->z), $smallestFlowDecay);
$k = $smallestFlowDecay + $multiplier;
@ -217,7 +217,7 @@ abstract class Liquid extends Transparent{
$k = -1;
}
if(($topFlowDecay = $this->getFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z)))) >= 0){
if(($topFlowDecay = $this->getFlowDecay($this->level->getBlockAt($this->x, $this->y + 1, $this->z))) >= 0){
if($topFlowDecay >= 8){
$k = $topFlowDecay;
}else{
@ -226,7 +226,7 @@ abstract class Liquid extends Transparent{
}
if($this->adjacentSources >= 2 and $this instanceof Water){
$bottomBlock = $this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y - 1, $this->z));
$bottomBlock = $this->level->getBlockAt($this->x, $this->y - 1, $this->z);
if($bottomBlock->isSolid()){
$k = 0;
}elseif($bottomBlock instanceof Water and $bottomBlock->getDamage() === 0){
@ -256,7 +256,7 @@ abstract class Liquid extends Transparent{
}
if($decay >= 0){
$bottomBlock = $this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y - 1, $this->z));
$bottomBlock = $this->level->getBlockAt($this->x, $this->y - 1, $this->z);
if($this instanceof Lava and $bottomBlock instanceof Water){
$this->getLevel()->setBlock($bottomBlock, BlockFactory::get(Block::STONE), true, true);
@ -281,19 +281,19 @@ abstract class Liquid extends Transparent{
}
if($flags[0]){
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z)), $l);
$this->flowIntoBlock($this->level->getBlockAt($this->x - 1, $this->y, $this->z), $l);
}
if($flags[1]){
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z)), $l);
$this->flowIntoBlock($this->level->getBlockAt($this->x + 1, $this->y, $this->z), $l);
}
if($flags[2]){
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1)), $l);
$this->flowIntoBlock($this->level->getBlockAt($this->x, $this->y, $this->z - 1), $l);
}
if($flags[3]){
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1)), $l);
$this->flowIntoBlock($this->level->getBlockAt($this->x, $this->y, $this->z + 1), $l);
}
}
@ -336,13 +336,13 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){
++$z;
}
$blockSide = $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $z));
$blockSide = $this->getLevel()->getBlockAt($x, $y, $z);
if(!$blockSide->canBeFlowedInto() and !($blockSide instanceof Liquid)){
continue;
}elseif($blockSide instanceof Liquid and $blockSide->getDamage() === 0){
continue;
}elseif($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z))->canBeFlowedInto()){
}elseif($this->getLevel()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){
return $accumulatedCost;
}
@ -386,13 +386,13 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){
++$z;
}
$block = $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $z));
$block = $this->getLevel()->getBlockAt($x, $y, $z);
if(!$block->canBeFlowedInto() and !($block instanceof Liquid)){
continue;
}elseif($block instanceof Liquid and $block->getDamage() === 0){
continue;
}elseif($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z))->canBeFlowedInto()){
}elseif($this->getLevel()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){
$this->flowCost[$j] = 0;
}else{
$this->flowCost[$j] = $this->calculateFlowCost($block, 1, $j);

View File

@ -67,7 +67,7 @@ class Mycelium extends Solid{
$x = mt_rand($this->x - 1, $this->x + 1);
$y = mt_rand($this->y - 2, $this->y + 2);
$z = mt_rand($this->z - 1, $this->z + 1);
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
$block = $this->getLevel()->getBlockAt($x, $y, $z);
if($block->getId() === Block::DIRT){
if($block->getSide(Vector3::SIDE_UP) instanceof Transparent){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, BlockFactory::get(Block::MYCELIUM)));

View File

@ -52,7 +52,7 @@ class Sugarcane extends Flowable{
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){
for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
$b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z);
if($b->getId() === self::AIR){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, BlockFactory::get(Block::SUGARCANE_BLOCK)));
if(!$ev->isCancelled()){
@ -85,7 +85,7 @@ class Sugarcane extends Flowable{
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){
if($this->meta === 0x0F){
for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
$b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z);
if($b->getId() === self::AIR){
$this->getLevel()->setBlock($b, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
break;

View File

@ -1105,7 +1105,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
}
if($this->onGround){
$friction *= $this->level->getBlock($this->floor()->subtract(0, 1, 0))->getFrictionFactor();
$friction *= $this->level->getBlockAt(Math::floorFloat($this->x), Math::floorFloat($this->y) - 1, Math::floorFloat($this->z))->getFrictionFactor();
}
$this->motionX *= $friction;
@ -1385,7 +1385,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
}
public function isInsideOfWater() : bool{
$block = $this->level->getBlock($this->temporalVector->setComponents(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z)));
$block = $this->level->getBlockAt(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z));
if($block instanceof Water){
$f = ($block->y + 1) - ($block->getFluidHeightPercent() - 0.1111111);
@ -1396,7 +1396,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
}
public function isInsideOfSolid() : bool{
$block = $this->level->getBlock($this->temporalVector->setComponents(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z)));
$block = $this->level->getBlockAt(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z));
return $block->isSolid() and !$block->isTransparent() and $block->collidesWithBB($this->getBoundingBox());
}
@ -1627,7 +1627,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
for($z = $minZ; $z <= $maxZ; ++$z){
for($x = $minX; $x <= $maxX; ++$x){
for($y = $minY; $y <= $maxY; ++$y){
$block = $this->level->getBlock($this->temporalVector->setComponents($x, $y, $z));
$block = $this->level->getBlockAt($x, $y, $z);
if($block->hasEntityCollision()){
$this->blocksAround[] = $block;
}

View File

@ -232,7 +232,7 @@ class Explosion{
continue;
}
if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlock($sideBlock)));
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlockAt($sideBlock->x, $sideBlock->y, $sideBlock->z)));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(Level::BLOCK_UPDATE_NORMAL);
}

View File

@ -706,7 +706,7 @@ class Level implements ChunkManager, Metadatable{
$index = $this->neighbourBlockUpdateQueue->dequeue();
Level::getBlockXYZ($index, $x, $y, $z);
$block = $this->getBlock($this->temporalVector->setComponents($x, $y, $z));
$block = $this->getBlockAt($x, $y, $z);
$block->clearBoundingBoxes(); //for blocks like fences, force recalculation of connected AABBs
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block));
@ -1025,33 +1025,36 @@ class Level implements ChunkManager, Metadatable{
* @param Vector3 $pos
*/
public function updateAround(Vector3 $pos){
$pos = $pos->floor();
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y - 1, $pos->z))));
$x = (int) floor($pos->x);
$y = (int) floor($pos->y);
$z = (int) floor($pos->z);
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlockAt($x, $y - 1, $z)));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y + 1, $pos->z))));
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlockAt($x, $y + 1, $z)));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x - 1, $pos->y, $pos->z))));
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlockAt($x - 1, $y, $z)));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x + 1, $pos->y, $pos->z))));
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlockAt($x + 1, $y, $z)));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y, $pos->z - 1))));
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlockAt($x, $y, $z - 1)));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y, $pos->z + 1))));
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlockAt($x, $y, $z + 1)));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
@ -1123,7 +1126,7 @@ class Level implements ChunkManager, Metadatable{
for($z = $minZ; $z <= $maxZ; ++$z){
for($x = $minX; $x <= $maxX; ++$x){
for($y = $minY; $y <= $maxY; ++$y){
$block = $this->getBlock($this->temporalVector->setComponents($x, $y, $z));
$block = $this->getBlockAt($x, $y, $z);
if($block->getId() !== 0 and $block->collidesWithBB($bb)){
return [$block];
}
@ -1134,7 +1137,7 @@ class Level implements ChunkManager, Metadatable{
for($z = $minZ; $z <= $maxZ; ++$z){
for($x = $minX; $x <= $maxX; ++$x){
for($y = $minY; $y <= $maxY; ++$y){
$block = $this->getBlock($this->temporalVector->setComponents($x, $y, $z));
$block = $this->getBlockAt($x, $y, $z);
if($block->getId() !== 0 and $block->collidesWithBB($bb)){
$collides[] = $block;
}
@ -1186,7 +1189,7 @@ class Level implements ChunkManager, Metadatable{
for($z = $minZ; $z <= $maxZ; ++$z){
for($x = $minX; $x <= $maxX; ++$x){
for($y = $minY; $y <= $maxY; ++$y){
$block = $this->getBlock($this->temporalVector->setComponents($x, $y, $z));
$block = $this->getBlockAt($x, $y, $z);
if(!$block->canPassThrough() and $block->collidesWithBB($bb)){
foreach($block->getCollisionBoxes() as $blockBB){
$collides[] = $blockBB;
@ -1311,10 +1314,11 @@ class Level implements ChunkManager, Metadatable{
}
/**
* Gets the Block object at the Vector3 location
* Gets the Block object at the Vector3 location. This method wraps around {@link getBlockAt}, converting the
* vector components to integers.
*
* Note for plugin developers: If you are using this method a lot (thousands of times for many positions for
* example), you may want to set addToCache to false to avoid using excessive amounts of memory.
* Note: If you're using this for performance-sensitive code, and you're guaranteed to be supplying ints in the
* specified vector, consider using {@link getBlockAt} instead for better performance.
*
* @param Vector3 $pos
* @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate)
@ -1323,25 +1327,41 @@ class Level implements ChunkManager, Metadatable{
* @return Block
*/
public function getBlock(Vector3 $pos, bool $cached = true, bool $addToCache = true) : Block{
$pos = $pos->floor();
return $this->getBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $cached, $addToCache);
}
/**
* Gets the Block object at the specified coordinates.
*
* Note for plugin developers: If you are using this method a lot (thousands of times for many positions for
* example), you may want to set addToCache to false to avoid using excessive amounts of memory.
*
* @param int $x
* @param int $y
* @param int $z
* @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate)
* @param bool $addToCache Whether to cache the block object created by this method call.
*
* @return Block
*/
public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{
$fullState = 0;
$index = null;
if($this->isInWorld($pos->x, $pos->y, $pos->z)){
$index = Level::blockHash($pos->x, $pos->y, $pos->z);
if($this->isInWorld($x, $y, $z)){
$index = Level::blockHash($x, $y, $z);
if($cached and isset($this->blockCache[$index])){
return $this->blockCache[$index];
}elseif(isset($this->chunks[$chunkIndex = Level::chunkHash($pos->x >> 4, $pos->z >> 4)])){
$fullState = $this->chunks[$chunkIndex]->getFullBlock($pos->x & 0x0f, $pos->y, $pos->z & 0x0f);
}elseif(isset($this->chunks[$chunkIndex = Level::chunkHash($x >> 4, $z >> 4)])){
$fullState = $this->chunks[$chunkIndex]->getFullBlock($x & 0x0f, $y, $z & 0x0f);
}
}
$block = clone $this->blockStates[$fullState & 0xfff];
$block->x = $pos->x;
$block->y = $pos->y;
$block->z = $pos->z;
$block->x = $x;
$block->y = $y;
$block->z = $z;
$block->level = $this;
if($addToCache and $index !== null){
@ -1656,7 +1676,7 @@ class Level implements ChunkManager, Metadatable{
$drops = $target->getDrops($item); //Fixes tile entities being deleted before getting drops
}
$above = $this->getBlock(new Vector3($target->x, $target->y + 1, $target->z));
$above = $this->getBlockAt($target->x, $target->y + 1, $target->z);
if($above->getId() === Block::FIRE){ //TODO: this should be done in Fire's onUpdate(), not with this hack
$this->setBlock($above, BlockFactory::get(Block::AIR), true);
}

View File

@ -226,7 +226,7 @@ abstract class Tile extends Position{
* @return Block
*/
public function getBlock() : Block{
return $this->level->getBlock($this);
return $this->level->getBlockAt($this->x, $this->y, $this->z);
}
/**