Clean up tile destruction

This commit is contained in:
Dylan K. Taylor 2019-02-13 12:02:04 +00:00
parent 1496eefb8b
commit 260c5dcf00
5 changed files with 54 additions and 35 deletions

View File

@ -41,9 +41,6 @@ use pocketmine\math\Facing;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\ExplodePacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\tile\Chest;
use pocketmine\tile\Container;
use pocketmine\tile\Tile;
use function ceil; use function ceil;
use function floor; use function floor;
use function mt_rand; use function mt_rand;
@ -206,31 +203,21 @@ class Explosion{
$airBlock = BlockFactory::get(Block::AIR); $airBlock = BlockFactory::get(Block::AIR);
foreach($this->affectedBlocks as $block){ foreach($this->affectedBlocks as $block){
$yieldDrops = false;
if($block instanceof TNT){ if($block instanceof TNT){
$block->ignite(mt_rand(10, 30)); $block->ignite(mt_rand(10, 30));
}elseif($yieldDrops = (mt_rand(0, 100) < $yield)){ }else{
foreach($block->getDrops($air) as $drop){ if(mt_rand(0, 100) < $yield){
$this->level->dropItem($block->add(0.5, 0.5, 0.5), $drop); 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); $pos = new Vector3($block->x, $block->y, $block->z);
foreach(Facing::ALL as $side){ foreach(Facing::ALL as $side){

View File

@ -81,8 +81,6 @@ use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\plugin\Plugin; use pocketmine\plugin\Plugin;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\tile\Chest;
use pocketmine\tile\Container;
use pocketmine\tile\Spawnable; use pocketmine\tile\Spawnable;
use pocketmine\tile\Tile; use pocketmine\tile\Tile;
use pocketmine\timings\Timings; use pocketmine\timings\Timings;
@ -1759,15 +1757,7 @@ class Level implements ChunkManager, Metadatable{
$tile = $this->getTile($target); $tile = $this->getTile($target);
if($tile !== null){ if($tile !== null){
if($tile instanceof Container){ $tile->onBlockDestroyed();
if($tile instanceof Chest){
$tile->unpair();
}
$tile->getInventory()->dropContents($this, $target);
}
$tile->close();
} }
} }

View File

@ -35,7 +35,9 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{
use NameableTrait { use NameableTrait {
addAdditionalSpawnData as addNameSpawnData; addAdditionalSpawnData as addNameSpawnData;
} }
use ContainerTrait; use ContainerTrait {
onBlockDestroyedHook as containerTraitBlockDestroyedHook;
}
public const TAG_PAIRX = "pairx"; public const TAG_PAIRX = "pairx";
public const TAG_PAIRZ = "pairz"; 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 * @return ChestInventory|DoubleChestInventory
*/ */

View File

@ -25,6 +25,7 @@ namespace pocketmine\tile;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Position;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
@ -85,4 +86,23 @@ trait ContainerTrait{
public function canOpenWith(string $key) : bool{ public function canOpenWith(string $key) : bool{
return $this->lock === null or $this->lock === $key; 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);
}
} }

View File

@ -129,6 +129,21 @@ abstract class Tile extends Position{
$this->close(); $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{ public function close() : void{
if(!$this->closed){ if(!$this->closed){
$this->closed = true; $this->closed = true;