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\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,30 +203,20 @@ 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)){
}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?
$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);

View File

@ -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();
}
}

View File

@ -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
*/

View File

@ -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);
}
}

View File

@ -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;