diff --git a/src/block/Campfire.php b/src/block/Campfire.php index 831e0043a3..a9649ab84b 100644 --- a/src/block/Campfire.php +++ b/src/block/Campfire.php @@ -270,9 +270,6 @@ class Campfire extends Transparent{ $this->position->getWorld()->addSound($this->position, $furnaceType->getCookSound()); } $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS); - }else{ - //make sure the visual state is updated when items are added - $this->position->getWorld()->setBlock($this->position, $this); } } diff --git a/src/block/tile/Barrel.php b/src/block/tile/Barrel.php index 23f7383ca7..c5914c6484 100644 --- a/src/block/tile/Barrel.php +++ b/src/block/tile/Barrel.php @@ -50,6 +50,13 @@ class Barrel extends Spawnable implements ContainerTile, Nameable{ $this->saveItems($nbt); } + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(); + parent::close(); + } + } + public function getInventory() : Inventory{ return $this->inventory; } diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 42828671c5..cda7599f66 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -27,6 +27,7 @@ use pocketmine\block\inventory\window\BrewingStandInventoryWindow; use pocketmine\crafting\BrewingRecipe; use pocketmine\event\block\BrewingFuelUseEvent; use pocketmine\event\block\BrewItemEvent; +use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; @@ -63,6 +64,9 @@ class BrewingStand extends Spawnable implements ContainerTile, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new SimpleInventory(5); + $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(static function(Inventory $unused) use ($world, $pos) : void{ + $world->scheduleDelayedBlockUpdate($pos, 1); + })); } public function readSaveData(CompoundTag $nbt) : void{ @@ -101,6 +105,14 @@ class BrewingStand extends Spawnable implements ContainerTile, Nameable{ return "Brewing Stand"; } + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(); + + parent::close(); + } + } + public function getInventory() : Inventory{ return $this->inventory; } diff --git a/src/block/tile/Campfire.php b/src/block/tile/Campfire.php index 4efb70a0d5..dc8066d319 100644 --- a/src/block/tile/Campfire.php +++ b/src/block/tile/Campfire.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\block\tile; +use pocketmine\block\Campfire as BlockCampfire; +use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; @@ -53,6 +55,14 @@ class Campfire extends Spawnable implements ContainerTile{ parent::__construct($world, $pos); $this->inventory = new SimpleInventory(4); $this->inventory->setMaxStackSize(1); + $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( + static function(Inventory $unused) use ($world, $pos) : void{ + $block = $world->getBlock($pos); + if($block instanceof BlockCampfire){ + $world->setBlock($pos, $block); + } + }) + ); } public function getInventory() : Inventory{ diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 6cb523c7de..ab03174cf4 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -94,6 +94,8 @@ class Chest extends Spawnable implements ContainerTile, Nameable{ public function close() : void{ if(!$this->closed){ + $this->inventory->removeAllViewers(); + if($this->doubleInventory !== null){ if($this->isPaired() && $this->position->getWorld()->isChunkLoaded($this->pairX >> Chunk::COORD_BIT_SIZE, $this->pairZ >> Chunk::COORD_BIT_SIZE)){ $this->doubleInventory->removeAllViewers(); diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 1657a4eed2..0da17bba45 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -29,6 +29,7 @@ use pocketmine\crafting\FurnaceRecipe; use pocketmine\crafting\FurnaceType; use pocketmine\event\inventory\FurnaceBurnEvent; use pocketmine\event\inventory\FurnaceSmeltEvent; +use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; @@ -56,6 +57,11 @@ abstract class Furnace extends Spawnable implements ContainerTile, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new SimpleInventory(3); + $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( + static function(Inventory $unused) use ($world, $pos) : void{ + $world->scheduleDelayedBlockUpdate($pos, 1); + }) + ); } public function readSaveData(CompoundTag $nbt) : void{ @@ -73,6 +79,10 @@ abstract class Furnace extends Spawnable implements ContainerTile, Nameable{ $this->loadName($nbt); $this->loadItems($nbt); + + if($this->remainingFuelTime > 0){ + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, 1); + } } protected function writeSaveData(CompoundTag $nbt) : void{ @@ -87,6 +97,14 @@ abstract class Furnace extends Spawnable implements ContainerTile, Nameable{ return "Furnace"; } + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(); + + parent::close(); + } + } + public function getInventory() : Inventory{ return $this->inventory; } diff --git a/src/block/tile/Hopper.php b/src/block/tile/Hopper.php index 988d55c42e..ff58b68e94 100644 --- a/src/block/tile/Hopper.php +++ b/src/block/tile/Hopper.php @@ -58,6 +58,14 @@ class Hopper extends Spawnable implements ContainerTile, Nameable{ $nbt->setInt(self::TAG_TRANSFER_COOLDOWN, $this->transferCooldown); } + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(); + + parent::close(); + } + } + public function getDefaultName() : string{ return "Hopper"; } diff --git a/src/block/tile/ShulkerBox.php b/src/block/tile/ShulkerBox.php index a7d5b9617c..13ed3980f9 100644 --- a/src/block/tile/ShulkerBox.php +++ b/src/block/tile/ShulkerBox.php @@ -80,6 +80,13 @@ class ShulkerBox extends Spawnable implements ContainerTile, Nameable{ } } + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(); + parent::close(); + } + } + protected function onBlockDestroyedHook() : void{ //NOOP override of ContainerTrait - shulker boxes retain their contents when destroyed } diff --git a/src/world/World.php b/src/world/World.php index c3fdbfa8ae..82740276d0 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -30,7 +30,6 @@ use pocketmine\block\Air; use pocketmine\block\Block; use pocketmine\block\BlockTypeIds; use pocketmine\block\RuntimeBlockStateRegistry; -use pocketmine\block\tile\ContainerTile; use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; @@ -58,8 +57,6 @@ use pocketmine\event\world\WorldDisplayNameChangeEvent; use pocketmine\event\world\WorldParticleEvent; use pocketmine\event\world\WorldSaveEvent; use pocketmine\event\world\WorldSoundEvent; -use pocketmine\inventory\Inventory; -use pocketmine\inventory\InventoryListener; use pocketmine\item\Item; use pocketmine\item\ItemUseResult; use pocketmine\item\LegacyStringToItemParser; @@ -148,7 +145,7 @@ use const PHP_INT_MIN; * @phpstan-type BlockPosHash int * @phpstan-type ChunkBlockPosHash int */ -class World implements ChunkManager, InventoryListener{ +class World implements ChunkManager{ private static int $worldIdCounter = 1; @@ -290,12 +287,6 @@ class World implements ChunkManager, InventoryListener{ */ private array $chunks = []; - /** - * @var Vector3[]|\WeakMap - * @phpstan-var \WeakMap - */ - private \WeakMap $containerToBlockPositionMap; - /** * @var Vector3[][] chunkHash => [relativeBlockHash => Vector3] * @phpstan-var array> @@ -523,8 +514,6 @@ class World implements ChunkManager, InventoryListener{ } }); - $this->containerToBlockPositionMap = new \WeakMap(); - $this->scheduledBlockUpdateQueue = new ReversePriorityQueue(); $this->scheduledBlockUpdateQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH); @@ -2874,10 +2863,6 @@ class World implements ChunkManager, InventoryListener{ //delegate tile ticking to the corresponding block $this->scheduleDelayedBlockUpdate($pos->asVector3(), 1); - if($tile instanceof ContainerTile){ - $tile->getInventory()->getListeners()->add($this); - $this->containerToBlockPositionMap[$tile->getInventory()] = $pos->asVector3(); - } } /** @@ -2896,40 +2881,11 @@ class World implements ChunkManager, InventoryListener{ if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->removeTile($tile); } - if($tile instanceof ContainerTile){ - $inventory = $tile->getInventory(); - $inventory->removeAllViewers(); - $inventory->getListeners()->remove($this); - unset($this->containerToBlockPositionMap[$inventory]); - } foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ $listener->onBlockChanged($pos->asVector3()); } } - private function notifyInventoryUpdate(Inventory $inventory) : void{ - $blockPosition = $this->containerToBlockPositionMap[$inventory] ?? null; - if($blockPosition !== null){ - $this->scheduleDelayedBlockUpdate($blockPosition, 1); - } - } - - /** - * @internal - * @see InventoryListener - */ - public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem) : void{ - $this->notifyInventoryUpdate($inventory); - } - - /** - * @internal - * @see InventoryListener - */ - public function onContentChange(Inventory $inventory, array $oldContents) : void{ - $this->notifyInventoryUpdate($inventory); - } - public function isChunkInUse(int $x, int $z) : bool{ return isset($this->chunkLoaders[$index = World::chunkHash($x, $z)]) && count($this->chunkLoaders[$index]) > 0; }