Chest block now has responsibility for configuring double chest inventories

it already needs to locate the correct pair anyway to know the left/right for DoubleChestInventoryWindow, so we might as well use this logic for initializing the DoubleChestInventory itself too. The old logic in tile/Chest didn't work correctly.
This commit is contained in:
Dylan K. Taylor 2024-11-24 22:47:35 +00:00
parent 9c5df90e9b
commit 1d2b52732e
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
11 changed files with 31 additions and 69 deletions

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\block\inventory\ChestInventoryWindow; use pocketmine\block\inventory\ChestInventoryWindow;
use pocketmine\block\inventory\DoubleChestInventory;
use pocketmine\block\inventory\DoubleChestInventoryWindow; use pocketmine\block\inventory\DoubleChestInventoryWindow;
use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\tile\Chest as TileChest;
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
@ -87,18 +88,25 @@ class Chest extends Transparent{
return true; return true;
} }
foreach([false, true] as $clockwise){ $window = null;
$sideFacing = Facing::rotateY($this->facing, $clockwise); if($chest->isPaired()){
$side = $this->position->getSide($sideFacing); foreach([false, true] as $clockwise){
$pair = $world->getTile($side); $sideFacing = Facing::rotateY($this->facing, $clockwise);
if($pair instanceof TileChest && $pair->getPair() === $chest){ $side = $this->position->getSide($sideFacing);
[$left, $right] = $clockwise ? [$side, $this->position] : [$this->position, $side]; $pair = $world->getTile($side);
if($pair instanceof TileChest && $pair->getPair() === $chest){
[$left, $right] = $clockwise ? [$pair, $chest] : [$chest, $pair];
//TODO: we should probably construct DoubleChestInventory here directly too using the same logic $doubleInventory = $left->getDoubleInventory() ?? $right->getDoubleInventory();
//right now it uses some weird logic in TileChest which produces incorrect results if($doubleInventory === null){
//however I'm not sure if this is currently possible $doubleInventory = new DoubleChestInventory($left->getInventory(), $right->getInventory());
$window = new DoubleChestInventoryWindow($player, $chest->getInventory(), $left, $right); $left->setDoubleInventory($doubleInventory);
break; $right->setDoubleInventory($doubleInventory);
}
$window = new DoubleChestInventoryWindow($player, $doubleInventory, $left->getPosition(), $right->getPosition());
break;
}
} }
} }

View File

@ -61,10 +61,6 @@ class Barrel extends Spawnable implements Container, Nameable{
return $this->inventory; return $this->inventory;
} }
public function getRealInventory() : Inventory{
return $this->inventory;
}
public function getDefaultName() : string{ public function getDefaultName() : string{
return "Barrel"; return "Barrel";
} }

View File

@ -117,10 +117,6 @@ class BrewingStand extends Spawnable implements Container, Nameable{
return $this->inventory; return $this->inventory;
} }
public function getRealInventory() : Inventory{
return $this->inventory;
}
private function checkFuel(Item $item) : void{ private function checkFuel(Item $item) : void{
$ev = new BrewingFuelUseEvent($this); $ev = new BrewingFuelUseEvent($this);
if(!$item->equals(VanillaItems::BLAZE_POWDER(), true, false)){ if(!$item->equals(VanillaItems::BLAZE_POWDER(), true, false)){

View File

@ -68,10 +68,6 @@ class Campfire extends Spawnable implements Container{
return $this->inventory; return $this->inventory;
} }
public function getRealInventory() : CampfireInventory{
return $this->inventory;
}
/** /**
* @return int[] * @return int[]
* @phpstan-return array<int, int> * @phpstan-return array<int, int>

View File

@ -115,15 +115,14 @@ class Chest extends Spawnable implements Container, Nameable{
$this->containerTraitBlockDestroyedHook(); $this->containerTraitBlockDestroyedHook();
} }
public function getInventory() : Inventory|DoubleChestInventory{ public function getInventory() : Inventory{
if($this->isPaired() && $this->doubleInventory === null){ return $this->inventory;
$this->checkPairing();
}
return $this->doubleInventory instanceof DoubleChestInventory ? $this->doubleInventory : $this->inventory;
} }
public function getRealInventory() : Inventory{ public function getDoubleInventory() : ?DoubleChestInventory{ return $this->doubleInventory; }
return $this->inventory;
public function setDoubleInventory(?DoubleChestInventory $doubleChestInventory) : void{
$this->doubleInventory = $doubleChestInventory;
} }
protected function checkPairing() : void{ protected function checkPairing() : void{
@ -134,18 +133,7 @@ class Chest extends Spawnable implements Container, Nameable{
}elseif(($pair = $this->getPair()) instanceof Chest){ }elseif(($pair = $this->getPair()) instanceof Chest){
if(!$pair->isPaired()){ if(!$pair->isPaired()){
$pair->createPair($this); $pair->createPair($this);
$pair->checkPairing(); $this->doubleInventory = $pair->doubleInventory = null;
}
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{ }else{
$this->doubleInventory = null; $this->doubleInventory = null;

View File

@ -55,10 +55,6 @@ class ChiseledBookshelf extends Tile implements Container{
return $this->inventory; return $this->inventory;
} }
public function getRealInventory() : SimpleInventory{
return $this->inventory;
}
public function getLastInteractedSlot() : ?ChiseledBookshelfSlot{ public function getLastInteractedSlot() : ?ChiseledBookshelfSlot{
return $this->lastInteractedSlot; return $this->lastInteractedSlot;
} }
@ -87,7 +83,7 @@ class ChiseledBookshelf extends Tile implements Container{
protected function loadItems(CompoundTag $tag) : void{ protected function loadItems(CompoundTag $tag) : void{
if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){ if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){
$inventory = $this->getRealInventory(); $inventory = $this->inventory;
$listeners = $inventory->getListeners()->toArray(); $listeners = $inventory->getListeners()->toArray();
$inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization $inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization
@ -118,7 +114,7 @@ class ChiseledBookshelf extends Tile implements Container{
protected function saveItems(CompoundTag $tag) : void{ protected function saveItems(CompoundTag $tag) : void{
$items = []; $items = [];
foreach($this->getRealInventory()->getContents(true) as $slot => $item){ foreach($this->inventory->getContents(true) as $slot => $item){
if($item->isNull()){ if($item->isNull()){
$items[$slot] = CompoundTag::create() $items[$slot] = CompoundTag::create()
->setByte(SavedItemStackData::TAG_COUNT, 0) ->setByte(SavedItemStackData::TAG_COUNT, 0)

View File

@ -23,15 +23,12 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\inventory\Inventory;
use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\InventoryHolder;
interface Container extends InventoryHolder{ interface Container extends InventoryHolder{
public const TAG_ITEMS = "Items"; public const TAG_ITEMS = "Items";
public const TAG_LOCK = "Lock"; public const TAG_LOCK = "Lock";
public function getRealInventory() : Inventory;
/** /**
* Returns whether this container can be opened by an item with the given custom name. * Returns whether this container can be opened by an item with the given custom name.
*/ */

View File

@ -25,7 +25,6 @@ namespace pocketmine\block\tile;
use pocketmine\data\bedrock\item\SavedItemStackData; use pocketmine\data\bedrock\item\SavedItemStackData;
use pocketmine\data\SavedDataLoadingException; use pocketmine\data\SavedDataLoadingException;
use pocketmine\inventory\Inventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
@ -40,11 +39,9 @@ trait ContainerTrait{
/** @var string|null */ /** @var string|null */
private $lock = null; private $lock = null;
abstract public function getRealInventory() : Inventory;
protected function loadItems(CompoundTag $tag) : void{ protected function loadItems(CompoundTag $tag) : void{
if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){ if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){
$inventory = $this->getRealInventory(); $inventory = $this->getInventory();
$listeners = $inventory->getListeners()->toArray(); $listeners = $inventory->getListeners()->toArray();
$inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization $inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization
@ -71,7 +68,7 @@ trait ContainerTrait{
protected function saveItems(CompoundTag $tag) : void{ protected function saveItems(CompoundTag $tag) : void{
$items = []; $items = [];
foreach($this->getRealInventory()->getContents() as $slot => $item){ foreach($this->getInventory()->getContents() as $slot => $item){
$items[] = $item->nbtSerialize($slot); $items[] = $item->nbtSerialize($slot);
} }
@ -98,7 +95,7 @@ trait ContainerTrait{
* @see Tile::onBlockDestroyedHook() * @see Tile::onBlockDestroyedHook()
*/ */
protected function onBlockDestroyedHook() : void{ protected function onBlockDestroyedHook() : void{
$inv = $this->getRealInventory(); $inv = $this->getInventory();
$pos = $this->getPosition(); $pos = $this->getPosition();
$world = $pos->getWorld(); $world = $pos->getWorld();

View File

@ -109,10 +109,6 @@ abstract class Furnace extends Spawnable implements Container, Nameable{
return $this->inventory; return $this->inventory;
} }
public function getRealInventory() : Inventory{
return $this->getInventory();
}
protected function checkFuel(Item $fuel) : void{ protected function checkFuel(Item $fuel) : void{
$ev = new FurnaceBurnEvent($this, $fuel, $fuel->getFuelTime()); $ev = new FurnaceBurnEvent($this, $fuel, $fuel->getFuelTime());
$ev->call(); $ev->call();

View File

@ -73,8 +73,4 @@ class Hopper extends Spawnable implements Container, Nameable{
public function getInventory() : Inventory{ public function getInventory() : Inventory{
return $this->inventory; return $this->inventory;
} }
public function getRealInventory() : Inventory{
return $this->inventory;
}
} }

View File

@ -111,10 +111,6 @@ class ShulkerBox extends Spawnable implements Container, Nameable{
return $this->inventory; return $this->inventory;
} }
public function getRealInventory() : Inventory{
return $this->inventory;
}
public function getDefaultName() : string{ public function getDefaultName() : string{
return "Shulker Box"; return "Shulker Box";
} }