diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 420b19496..fcbcbe202 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -74,16 +74,24 @@ class Bed extends Transparent{ return 0b1111; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); //read extra state information from the tile - this is an ugly hack - //TODO: extend this hack to setting block as well so we don't have to deal with tile hacks in the main code $tile = $this->level->getTile($this); if($tile instanceof TileBed){ $this->color = $tile->getColor(); } } + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + //extra block properties storage hack + $tile = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this)); + if($tile instanceof TileBed){ + $tile->setColor($this->color); + } + } + public function getHardness() : float{ return 0.2; } @@ -186,16 +194,6 @@ class Bed extends Transparent{ $nextState->head = true; $this->getLevel()->setBlock($next, $nextState); - //TODO: make this happen automatically on block set - $tile1 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this)); - if($tile1 instanceof TileBed){ - $tile1->setColor($this->color); - } - $tile2 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next)); - if($tile2 instanceof TileBed){ - $tile2->setColor($this->color); - } - return true; } } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index cc6ac4b86..17bdaaa61 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -149,6 +149,22 @@ class Block extends Position implements BlockIds, Metadatable{ //NOOP } + /** + * Called when this block is created, set, or has a neighbouring block update, to re-detect dynamic properties which + * are not saved on the world. + * + * Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as + * AABBs and force recalculation. + */ + public function readStateFromWorld() : void{ + $this->boundingBox = null; + $this->collisionBoxes = null; + } + + public function writeStateToWorld() : void{ + $this->level->getChunkAtPosition($this)->setBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getId(), $this->getDamage()); + } + /** * Returns a bitmask used to extract state bits from block metadata. * @@ -448,7 +464,7 @@ class Block extends Position implements BlockIds, Metadatable{ $this->y = (int) $v->y; $this->z = (int) $v->z; $this->level = $v->level; - $this->updateState(); + $this->readStateFromWorld(); } /** @@ -717,18 +733,6 @@ class Block extends Position implements BlockIds, Metadatable{ return AxisAlignedBB::one(); } - /** - * Called when this block is created, set, or has a neighbouring block update, to re-detect dynamic properties which - * are not saved on the world. - * - * Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as - * AABBs and force recalculation. - */ - public function updateState() : void{ - $this->boundingBox = null; - $this->collisionBoxes = null; - } - /** * @param Vector3 $pos1 * @param Vector3 $pos2 diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index a944dc20d..21b0a1f37 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -48,8 +48,8 @@ class CobblestoneWall extends Transparent{ return 2; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); foreach(Facing::HORIZONTAL as $facing){ $block = $this->getSide($facing); diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 7191d80a4..76a67c7fa 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -69,8 +69,8 @@ abstract class Door extends Transparent{ return 0b1111; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); //copy door properties from other half $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index 44847f58d..caad4df8e 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -34,8 +34,8 @@ abstract class Fence extends Transparent{ return 0.25; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); foreach(Facing::HORIZONTAL as $facing){ $block = $this->getSide($facing); diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 2ea31779e..01e369ee3 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -118,8 +118,8 @@ abstract class Liquid extends Transparent{ return $block->falling ? 0 : $block->decay; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); $this->flowVector = null; } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index c0e42bc9c..b49017bb5 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -59,8 +59,8 @@ class Skull extends Flowable{ return 0b111; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); $tile = $this->level->getTile($this); if($tile instanceof TileSkull){ $this->type = $tile->getType(); @@ -68,6 +68,15 @@ class Skull extends Flowable{ } } + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this)); + if($tile instanceof TileSkull){ + $tile->setRotation($this->rotation); + $tile->setType($this->type); + } + } + public function getHardness() : float{ return 1; } @@ -91,17 +100,7 @@ class Skull extends Flowable{ if($player !== null and $face === Facing::UP){ $this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf; } - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - //TODO: make this automatic on block set - $tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this)); - if($tile instanceof TileSkull){ - $tile->setRotation($this->rotation); - $tile->setType($this->type); - } - return true; - } - - return false; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getItem() : Item{ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 85c539689..89b666f8d 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -762,7 +762,7 @@ class Level implements ChunkManager, Metadatable{ Level::getBlockXYZ($index, $x, $y, $z); $block = $this->getBlockAt($x, $y, $z); - $block->updateState(); //for blocks like fences, force recalculation of connected AABBs + $block->readStateFromWorld(); //for blocks like fences, force recalculation of connected AABBs $ev = new BlockUpdateEvent($block); $ev->call(); @@ -1372,7 +1372,7 @@ class Level implements ChunkManager, Metadatable{ $block->y = $y; $block->z = $z; $block->level = $this; - $block->updateState(); + $block->readStateFromWorld(); if($addToCache and $blockHash !== null){ $this->blockCache[$chunkHash][$blockHash] = $block; @@ -1517,51 +1517,46 @@ class Level implements ChunkManager, Metadatable{ $this->timings->setBlock->startTiming(); - if($this->getChunkAtPosition($pos, true)->setBlock($pos->x & 0x0f, $pos->y, $pos->z & 0x0f, $block->getId(), $block->getDamage())){ - if(!($pos instanceof Position)){ - $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); - } + if(!($pos instanceof Position)){ + $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); + } - $block = clone $block; + $block = clone $block; - $block->position($pos); + $block->position($pos); + $block->writeStateToWorld(); - $chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4); - $blockHash = Level::blockHash($pos->x, $pos->y, $pos->z); + $chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4); + $blockHash = Level::blockHash($pos->x, $pos->y, $pos->z); - unset($this->blockCache[$chunkHash][$blockHash]); + unset($this->blockCache[$chunkHash][$blockHash]); - if(!isset($this->changedBlocks[$chunkHash])){ - $this->changedBlocks[$chunkHash] = []; - } - $this->changedBlocks[$chunkHash][$blockHash] = $block; + if(!isset($this->changedBlocks[$chunkHash])){ + $this->changedBlocks[$chunkHash] = []; + } + $this->changedBlocks[$chunkHash][$blockHash] = $block; - foreach($this->getChunkLoaders($pos->x >> 4, $pos->z >> 4) as $loader){ - $loader->onBlockChanged($block); - } + foreach($this->getChunkLoaders($pos->x >> 4, $pos->z >> 4) as $loader){ + $loader->onBlockChanged($block); + } - if($update){ - $this->updateAllLight($block); + if($update){ + $this->updateAllLight($block); - $ev = new BlockUpdateEvent($block); - $ev->call(); - if(!$ev->isCancelled()){ - foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){ - $entity->onNearbyBlockChange(); - } - $ev->getBlock()->onNearbyBlockChange(); - $this->scheduleNeighbourBlockUpdates($pos); + $ev = new BlockUpdateEvent($block); + $ev->call(); + if(!$ev->isCancelled()){ + foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){ + $entity->onNearbyBlockChange(); } + $ev->getBlock()->onNearbyBlockChange(); + $this->scheduleNeighbourBlockUpdates($pos); } - - $this->timings->setBlock->stopTiming(); - - return true; } $this->timings->setBlock->stopTiming(); - return false; + return true; } /**