mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-09 15:29:47 +00:00
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.
This commit is contained in:
parent
b5a69c829d
commit
ef3d16597a
@ -109,30 +109,22 @@ class Chest extends Transparent implements AnimatedContainer{
|
|||||||
$world = $this->position->getWorld();
|
$world = $this->position->getWorld();
|
||||||
$chest = $world->getTile($this->position);
|
$chest = $world->getTile($this->position);
|
||||||
if($chest instanceof TileChest){
|
if($chest instanceof TileChest){
|
||||||
|
[$pairOnLeft, $pair] = $this->locatePair($this->position) ?? [false, null];
|
||||||
if(
|
if(
|
||||||
!$this->getSide(Facing::UP)->isTransparent() ||
|
!$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())
|
!$chest->canOpenWith($item->getCustomName())
|
||||||
){
|
){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$window = null;
|
if($pair !== null){
|
||||||
if($chest->isPaired()){
|
[$left, $right] = $pairOnLeft ? [$pair->getPosition(), $this->position] : [$this->position, $pair->getPosition()];
|
||||||
$info = $this->locatePair($this->position);
|
|
||||||
if($info !== null){
|
|
||||||
[$clockwise, $pair] = $info;
|
|
||||||
[$left, $right] = $clockwise ? [$pair, $chest] : [$chest, $pair];
|
|
||||||
|
|
||||||
$doubleInventory = $left->getDoubleInventory() ?? $right->getDoubleInventory();
|
//TODO: we should probably construct DoubleChestInventory here directly too using the same logic
|
||||||
if($doubleInventory === null){
|
//right now it uses some weird logic in TileChest which produces incorrect results
|
||||||
$doubleInventory = new DoubleChestInventory($left->getInventory(), $right->getInventory());
|
//however I'm not sure if this is currently possible
|
||||||
$left->setDoubleInventory($doubleInventory);
|
$window = new DoubleChestInventoryWindow($player, $chest->getInventory(), $left, $right);
|
||||||
$right->setDoubleInventory($doubleInventory);
|
|
||||||
}
|
|
||||||
|
|
||||||
$window = new DoubleChestInventoryWindow($player, $doubleInventory, $left->getPosition(), $right->getPosition());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$player->setCurrentWindow($window ?? new BlockInventoryWindow($player, $chest->getInventory(), $this->position));
|
$player->setCurrentWindow($window ?? new BlockInventoryWindow($player, $chest->getInventory(), $this->position));
|
||||||
@ -146,15 +138,6 @@ class Chest extends Transparent implements AnimatedContainer{
|
|||||||
return 300;
|
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{
|
protected function getContainerOpenSound() : Sound{
|
||||||
return new ChestOpenSound();
|
return new ChestOpenSound();
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,10 @@ class Barrel extends Spawnable implements ContainerTile, 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";
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,10 @@ class BrewingStand extends Spawnable implements ContainerTile, 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)){
|
||||||
|
@ -59,6 +59,10 @@ class Campfire extends Spawnable implements ContainerTile{
|
|||||||
return $this->inventory;
|
return $this->inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRealInventory() : Inventory{
|
||||||
|
return $this->inventory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int[]
|
* @return int[]
|
||||||
* @phpstan-return array<int, int>
|
* @phpstan-return array<int, int>
|
||||||
|
@ -113,14 +113,15 @@ class Chest extends Spawnable implements ContainerTile, Nameable{
|
|||||||
$this->containerTraitBlockDestroyedHook();
|
$this->containerTraitBlockDestroyedHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInventory() : Inventory{
|
public function getInventory() : Inventory|DoubleChestInventory{
|
||||||
return $this->inventory;
|
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 getRealInventory() : Inventory{
|
||||||
|
return $this->inventory;
|
||||||
public function setDoubleInventory(?DoubleChestInventory $doubleChestInventory) : void{
|
|
||||||
$this->doubleInventory = $doubleChestInventory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function checkPairing() : void{
|
protected function checkPairing() : void{
|
||||||
@ -131,7 +132,18 @@ class Chest extends Spawnable implements ContainerTile, 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);
|
||||||
$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{
|
}else{
|
||||||
$this->doubleInventory = null;
|
$this->doubleInventory = null;
|
||||||
|
@ -55,6 +55,10 @@ class ChiseledBookshelf extends Tile implements ContainerTile{
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@ -83,7 +87,7 @@ class ChiseledBookshelf extends Tile implements ContainerTile{
|
|||||||
|
|
||||||
protected function loadItems(CompoundTag $tag) : void{
|
protected function loadItems(CompoundTag $tag) : void{
|
||||||
if(($inventoryTag = $tag->getTag(ContainerTile::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){
|
if(($inventoryTag = $tag->getTag(ContainerTile::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){
|
||||||
$inventory = $this->inventory;
|
$inventory = $this->getRealInventory();
|
||||||
$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
|
||||||
|
|
||||||
@ -114,7 +118,7 @@ class ChiseledBookshelf extends Tile implements ContainerTile{
|
|||||||
|
|
||||||
protected function saveItems(CompoundTag $tag) : void{
|
protected function saveItems(CompoundTag $tag) : void{
|
||||||
$items = [];
|
$items = [];
|
||||||
foreach($this->inventory->getContents(true) as $slot => $item){
|
foreach($this->getRealInventory()->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)
|
||||||
|
@ -23,12 +23,15 @@ 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 ContainerTile extends InventoryHolder{
|
interface ContainerTile 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.
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +25,7 @@ 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;
|
||||||
@ -39,9 +40,11 @@ trait ContainerTileTrait{
|
|||||||
/** @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(ContainerTile::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){
|
if(($inventoryTag = $tag->getTag(ContainerTile::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){
|
||||||
$inventory = $this->getInventory();
|
$inventory = $this->getRealInventory();
|
||||||
$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
|
||||||
|
|
||||||
@ -68,7 +71,7 @@ trait ContainerTileTrait{
|
|||||||
|
|
||||||
protected function saveItems(CompoundTag $tag) : void{
|
protected function saveItems(CompoundTag $tag) : void{
|
||||||
$items = [];
|
$items = [];
|
||||||
foreach($this->getInventory()->getContents() as $slot => $item){
|
foreach($this->getRealInventory()->getContents() as $slot => $item){
|
||||||
$items[] = $item->nbtSerialize($slot);
|
$items[] = $item->nbtSerialize($slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +98,7 @@ trait ContainerTileTrait{
|
|||||||
* @see Tile::onBlockDestroyedHook()
|
* @see Tile::onBlockDestroyedHook()
|
||||||
*/
|
*/
|
||||||
protected function onBlockDestroyedHook() : void{
|
protected function onBlockDestroyedHook() : void{
|
||||||
$inv = $this->getInventory();
|
$inv = $this->getRealInventory();
|
||||||
$pos = $this->getPosition();
|
$pos = $this->getPosition();
|
||||||
|
|
||||||
$world = $pos->getWorld();
|
$world = $pos->getWorld();
|
||||||
|
@ -91,6 +91,10 @@ abstract class Furnace extends Spawnable implements ContainerTile, 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();
|
||||||
|
@ -65,4 +65,8 @@ class Hopper extends Spawnable implements ContainerTile, Nameable{
|
|||||||
public function getInventory() : Inventory{
|
public function getInventory() : Inventory{
|
||||||
return $this->inventory;
|
return $this->inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRealInventory() : Inventory{
|
||||||
|
return $this->inventory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,10 @@ class ShulkerBox extends Spawnable implements ContainerTile, 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";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user