From ef3d16597afb7eccbebab8b1049eda10e95f79c1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 7 Dec 2024 16:04:50 +0000 Subject: [PATCH] Revert "Chest block now has responsibility for configuring double chest inventories" This reverts commit 1d2b52732e3c475ddc2bab4e45726d22850e3d5c. I hadn't considered that the likes of plugins and hoppers need to be able to interact with double chest inventories as well as players. If we were to move this logic to the Block side, we'd have to expose APIs on the Chest block to get the correct inventory lazily. I'm not sure I want to commit to having getInventory() on the block right now, as we can't guarantee it's available (see problems around Campfire inventory on the block). Short term, it'll probably be better to just expose the logic in block\Chest for deciding which side the inventories should be on. --- src/block/Chest.php | 33 +++++++-------------------- src/block/tile/Barrel.php | 4 ++++ src/block/tile/BrewingStand.php | 4 ++++ src/block/tile/Campfire.php | 4 ++++ src/block/tile/Chest.php | 26 +++++++++++++++------ src/block/tile/ChiseledBookshelf.php | 8 +++++-- src/block/tile/ContainerTile.php | 3 +++ src/block/tile/ContainerTileTrait.php | 9 +++++--- src/block/tile/Furnace.php | 4 ++++ src/block/tile/Hopper.php | 4 ++++ src/block/tile/ShulkerBox.php | 4 ++++ 11 files changed, 66 insertions(+), 37 deletions(-) diff --git a/src/block/Chest.php b/src/block/Chest.php index a688df0bd..a28262e1a 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -109,30 +109,22 @@ class Chest extends Transparent implements AnimatedContainer{ $world = $this->position->getWorld(); $chest = $world->getTile($this->position); if($chest instanceof TileChest){ + [$pairOnLeft, $pair] = $this->locatePair($this->position) ?? [false, null]; if( !$this->getSide(Facing::UP)->isTransparent() || - (($pair = $chest->getPair()) !== null && !$pair->getBlock()->getSide(Facing::UP)->isTransparent()) || + ($pair !== null && !$pair->getBlock()->getSide(Facing::UP)->isTransparent()) || !$chest->canOpenWith($item->getCustomName()) ){ return true; } - $window = null; - if($chest->isPaired()){ - $info = $this->locatePair($this->position); - if($info !== null){ - [$clockwise, $pair] = $info; - [$left, $right] = $clockwise ? [$pair, $chest] : [$chest, $pair]; + if($pair !== null){ + [$left, $right] = $pairOnLeft ? [$pair->getPosition(), $this->position] : [$this->position, $pair->getPosition()]; - $doubleInventory = $left->getDoubleInventory() ?? $right->getDoubleInventory(); - if($doubleInventory === null){ - $doubleInventory = new DoubleChestInventory($left->getInventory(), $right->getInventory()); - $left->setDoubleInventory($doubleInventory); - $right->setDoubleInventory($doubleInventory); - } - - $window = new DoubleChestInventoryWindow($player, $doubleInventory, $left->getPosition(), $right->getPosition()); - } + //TODO: we should probably construct DoubleChestInventory here directly too using the same logic + //right now it uses some weird logic in TileChest which produces incorrect results + //however I'm not sure if this is currently possible + $window = new DoubleChestInventoryWindow($player, $chest->getInventory(), $left, $right); } $player->setCurrentWindow($window ?? new BlockInventoryWindow($player, $chest->getInventory(), $this->position)); @@ -146,15 +138,6 @@ class Chest extends Transparent implements AnimatedContainer{ return 300; } - protected function getContainerViewerCount() : int{ - $tile = $this->position->getWorld()->getTile($this->position); - if($tile instanceof TileChest){ - $inventory = $tile->getDoubleInventory() ?? $tile->getInventory(); - return count($inventory->getViewers()); - } - return 0; - } - protected function getContainerOpenSound() : Sound{ return new ChestOpenSound(); } diff --git a/src/block/tile/Barrel.php b/src/block/tile/Barrel.php index bf3913b7b..23f7383ca 100644 --- a/src/block/tile/Barrel.php +++ b/src/block/tile/Barrel.php @@ -54,6 +54,10 @@ class Barrel extends Spawnable implements ContainerTile, Nameable{ return $this->inventory; } + public function getRealInventory() : Inventory{ + return $this->inventory; + } + public function getDefaultName() : string{ return "Barrel"; } diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 8c70b4d03..42828671c 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -105,6 +105,10 @@ class BrewingStand extends Spawnable implements ContainerTile, Nameable{ return $this->inventory; } + public function getRealInventory() : Inventory{ + return $this->inventory; + } + private function checkFuel(Item $item) : void{ $ev = new BrewingFuelUseEvent($this); if(!$item->equals(VanillaItems::BLAZE_POWDER(), true, false)){ diff --git a/src/block/tile/Campfire.php b/src/block/tile/Campfire.php index d2adcfda7..4efb70a0d 100644 --- a/src/block/tile/Campfire.php +++ b/src/block/tile/Campfire.php @@ -59,6 +59,10 @@ class Campfire extends Spawnable implements ContainerTile{ return $this->inventory; } + public function getRealInventory() : Inventory{ + return $this->inventory; + } + /** * @return int[] * @phpstan-return array diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 67581290b..b66e849c7 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -113,14 +113,15 @@ class Chest extends Spawnable implements ContainerTile, Nameable{ $this->containerTraitBlockDestroyedHook(); } - public function getInventory() : Inventory{ - return $this->inventory; + public function getInventory() : Inventory|DoubleChestInventory{ + if($this->isPaired() && $this->doubleInventory === null){ + $this->checkPairing(); + } + return $this->doubleInventory instanceof DoubleChestInventory ? $this->doubleInventory : $this->inventory; } - public function getDoubleInventory() : ?DoubleChestInventory{ return $this->doubleInventory; } - - public function setDoubleInventory(?DoubleChestInventory $doubleChestInventory) : void{ - $this->doubleInventory = $doubleChestInventory; + public function getRealInventory() : Inventory{ + return $this->inventory; } protected function checkPairing() : void{ @@ -131,7 +132,18 @@ class Chest extends Spawnable implements ContainerTile, Nameable{ }elseif(($pair = $this->getPair()) instanceof Chest){ if(!$pair->isPaired()){ $pair->createPair($this); - $this->doubleInventory = $pair->doubleInventory = null; + $pair->checkPairing(); + } + if($this->doubleInventory === null){ + if($pair->doubleInventory !== null){ + $this->doubleInventory = $pair->doubleInventory; + }else{ + if(($pair->position->x + ($pair->position->z << 15)) > ($this->position->x + ($this->position->z << 15))){ //Order them correctly + $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($pair->inventory, $this->inventory); + }else{ + $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($this->inventory, $pair->inventory); + } + } } }else{ $this->doubleInventory = null; diff --git a/src/block/tile/ChiseledBookshelf.php b/src/block/tile/ChiseledBookshelf.php index d18b606d7..e8b5e73ec 100644 --- a/src/block/tile/ChiseledBookshelf.php +++ b/src/block/tile/ChiseledBookshelf.php @@ -55,6 +55,10 @@ class ChiseledBookshelf extends Tile implements ContainerTile{ return $this->inventory; } + public function getRealInventory() : SimpleInventory{ + return $this->inventory; + } + public function getLastInteractedSlot() : ?ChiseledBookshelfSlot{ return $this->lastInteractedSlot; } @@ -83,7 +87,7 @@ class ChiseledBookshelf extends Tile implements ContainerTile{ protected function loadItems(CompoundTag $tag) : void{ if(($inventoryTag = $tag->getTag(ContainerTile::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){ - $inventory = $this->inventory; + $inventory = $this->getRealInventory(); $listeners = $inventory->getListeners()->toArray(); $inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization @@ -114,7 +118,7 @@ class ChiseledBookshelf extends Tile implements ContainerTile{ protected function saveItems(CompoundTag $tag) : void{ $items = []; - foreach($this->inventory->getContents(true) as $slot => $item){ + foreach($this->getRealInventory()->getContents(true) as $slot => $item){ if($item->isNull()){ $items[$slot] = CompoundTag::create() ->setByte(SavedItemStackData::TAG_COUNT, 0) diff --git a/src/block/tile/ContainerTile.php b/src/block/tile/ContainerTile.php index 51c7d3759..e5ce2dfe1 100644 --- a/src/block/tile/ContainerTile.php +++ b/src/block/tile/ContainerTile.php @@ -23,12 +23,15 @@ declare(strict_types=1); namespace pocketmine\block\tile; +use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryHolder; interface ContainerTile extends InventoryHolder{ public const TAG_ITEMS = "Items"; public const TAG_LOCK = "Lock"; + public function getRealInventory() : Inventory; + /** * Returns whether this container can be opened by an item with the given custom name. */ diff --git a/src/block/tile/ContainerTileTrait.php b/src/block/tile/ContainerTileTrait.php index f3e015ae4..0f07f51d6 100644 --- a/src/block/tile/ContainerTileTrait.php +++ b/src/block/tile/ContainerTileTrait.php @@ -25,6 +25,7 @@ namespace pocketmine\block\tile; use pocketmine\data\bedrock\item\SavedItemStackData; use pocketmine\data\SavedDataLoadingException; +use pocketmine\inventory\Inventory; use pocketmine\item\Item; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; @@ -39,9 +40,11 @@ trait ContainerTileTrait{ /** @var string|null */ private $lock = null; + abstract public function getRealInventory() : Inventory; + protected function loadItems(CompoundTag $tag) : void{ if(($inventoryTag = $tag->getTag(ContainerTile::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){ - $inventory = $this->getInventory(); + $inventory = $this->getRealInventory(); $listeners = $inventory->getListeners()->toArray(); $inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization @@ -68,7 +71,7 @@ trait ContainerTileTrait{ protected function saveItems(CompoundTag $tag) : void{ $items = []; - foreach($this->getInventory()->getContents() as $slot => $item){ + foreach($this->getRealInventory()->getContents() as $slot => $item){ $items[] = $item->nbtSerialize($slot); } @@ -95,7 +98,7 @@ trait ContainerTileTrait{ * @see Tile::onBlockDestroyedHook() */ protected function onBlockDestroyedHook() : void{ - $inv = $this->getInventory(); + $inv = $this->getRealInventory(); $pos = $this->getPosition(); $world = $pos->getWorld(); diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 4a7713f36..1657a4eed 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -91,6 +91,10 @@ abstract class Furnace extends Spawnable implements ContainerTile, Nameable{ return $this->inventory; } + public function getRealInventory() : Inventory{ + return $this->getInventory(); + } + protected function checkFuel(Item $fuel) : void{ $ev = new FurnaceBurnEvent($this, $fuel, $fuel->getFuelTime()); $ev->call(); diff --git a/src/block/tile/Hopper.php b/src/block/tile/Hopper.php index d001b8726..988d55c42 100644 --- a/src/block/tile/Hopper.php +++ b/src/block/tile/Hopper.php @@ -65,4 +65,8 @@ class Hopper extends Spawnable implements ContainerTile, Nameable{ public function getInventory() : Inventory{ return $this->inventory; } + + public function getRealInventory() : Inventory{ + return $this->inventory; + } } diff --git a/src/block/tile/ShulkerBox.php b/src/block/tile/ShulkerBox.php index 104f1b944..a7d5b9617 100644 --- a/src/block/tile/ShulkerBox.php +++ b/src/block/tile/ShulkerBox.php @@ -104,6 +104,10 @@ class ShulkerBox extends Spawnable implements ContainerTile, Nameable{ return $this->inventory; } + public function getRealInventory() : Inventory{ + return $this->inventory; + } + public function getDefaultName() : string{ return "Shulker Box"; }