From 260c5dcf0051142138b3719750249b0c4e728dd5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Feb 2019 12:02:04 +0000 Subject: [PATCH] Clean up tile destruction --- src/pocketmine/level/Explosion.php | 33 ++++++++------------------ src/pocketmine/level/Level.php | 12 +--------- src/pocketmine/tile/Chest.php | 9 ++++++- src/pocketmine/tile/ContainerTrait.php | 20 ++++++++++++++++ src/pocketmine/tile/Tile.php | 15 ++++++++++++ 5 files changed, 54 insertions(+), 35 deletions(-) diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 5251ee366..c58ffe059 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -41,9 +41,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\tile\Chest; -use pocketmine\tile\Container; -use pocketmine\tile\Tile; use function ceil; use function floor; use function mt_rand; @@ -206,31 +203,21 @@ class Explosion{ $airBlock = BlockFactory::get(Block::AIR); foreach($this->affectedBlocks as $block){ - $yieldDrops = false; - if($block instanceof TNT){ $block->ignite(mt_rand(10, 30)); - }elseif($yieldDrops = (mt_rand(0, 100) < $yield)){ - foreach($block->getDrops($air) as $drop){ - $this->level->dropItem($block->add(0.5, 0.5, 0.5), $drop); + }else{ + if(mt_rand(0, 100) < $yield){ + foreach($block->getDrops($air) as $drop){ + $this->level->dropItem($block->add(0.5, 0.5, 0.5), $drop); + } } + if(($t = $this->level->getTileAt($block->x, $block->y, $block->z)) !== null){ + $t->onBlockDestroyed(); //needed to create drops for inventories + } + $this->level->setBlockAt($block->x, $block->y, $block->z, $airBlock, false); //TODO: should updating really be disabled here? + $this->level->updateAllLight($block); } - $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); - if($t instanceof Tile){ - if($t instanceof Chest){ - $t->unpair(); - } - if($yieldDrops and $t instanceof Container){ - $t->getInventory()->dropContents($this->level, $t->add(0.5, 0.5, 0.5)); - } - - $t->close(); - } - $this->level->updateAllLight($block); - $pos = new Vector3($block->x, $block->y, $block->z); foreach(Facing::ALL as $side){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index ebe325583..5734e85dc 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -81,8 +81,6 @@ use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; -use pocketmine\tile\Chest; -use pocketmine\tile\Container; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\timings\Timings; @@ -1759,15 +1757,7 @@ class Level implements ChunkManager, Metadatable{ $tile = $this->getTile($target); if($tile !== null){ - if($tile instanceof Container){ - if($tile instanceof Chest){ - $tile->unpair(); - } - - $tile->getInventory()->dropContents($this, $target); - } - - $tile->close(); + $tile->onBlockDestroyed(); } } diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index a5aad2fda..7b2ffb25f 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -35,7 +35,9 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ use NameableTrait { addAdditionalSpawnData as addNameSpawnData; } - use ContainerTrait; + use ContainerTrait { + onBlockDestroyedHook as containerTraitBlockDestroyedHook; + } public const TAG_PAIRX = "pairx"; public const TAG_PAIRZ = "pairz"; @@ -104,6 +106,11 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } } + protected function onBlockDestroyedHook() : void{ + $this->unpair(); + $this->containerTraitBlockDestroyedHook(); + } + /** * @return ChestInventory|DoubleChestInventory */ diff --git a/src/pocketmine/tile/ContainerTrait.php b/src/pocketmine/tile/ContainerTrait.php index 71fe63152..b09bfb42c 100644 --- a/src/pocketmine/tile/ContainerTrait.php +++ b/src/pocketmine/tile/ContainerTrait.php @@ -25,6 +25,7 @@ namespace pocketmine\tile; use pocketmine\inventory\Inventory; use pocketmine\item\Item; +use pocketmine\level\Position; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; @@ -85,4 +86,23 @@ trait ContainerTrait{ public function canOpenWith(string $key) : bool{ return $this->lock === null or $this->lock === $key; } + + /** + * @see Position::asPosition() + * @return Position + */ + abstract protected function asPosition() : Position; + + /** + * @see Tile::onBlockDestroyedHook() + */ + protected function onBlockDestroyedHook() : void{ + $inv = $this->getRealInventory(); + $pos = $this->asPosition(); + + foreach($inv->getContents() as $k => $item){ + $pos->level->dropItem($pos->add(0.5, 0.5, 0.5), $item); + } + $inv->clearAll(false); + } } diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 60bb22fff..963129dfb 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -129,6 +129,21 @@ abstract class Tile extends Position{ $this->close(); } + /** + * Called when the tile's block is destroyed. + */ + final public function onBlockDestroyed() : void{ + $this->onBlockDestroyedHook(); + $this->close(); + } + + /** + * Override this method to do actions you need to do when this tile is destroyed due to block being broken. + */ + protected function onBlockDestroyedHook() : void{ + + } + public function close() : void{ if(!$this->closed){ $this->closed = true;