Skip to content

Commit 496ab80

Browse files
committed
First step towards standardised opening logic for containers and menu blocks
we'll want to introduce interfaces for these, but getting the code deduplicated is enough to start with.
1 parent 174dfd1 commit 496ab80

17 files changed

+269
-161
lines changed

src/block/Anvil.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use pocketmine\block\utils\HorizontalFacing;
3030
use pocketmine\block\utils\HorizontalFacingOption;
3131
use pocketmine\block\utils\HorizontalFacingTrait;
32+
use pocketmine\block\utils\InventoryMenuTrait;
3233
use pocketmine\block\utils\SupportType;
3334
use pocketmine\data\runtime\RuntimeDataDescriber;
3435
use pocketmine\entity\object\FallingBlock;
@@ -39,13 +40,15 @@
3940
use pocketmine\player\Player;
4041
use pocketmine\utils\Utils;
4142
use pocketmine\world\BlockTransaction;
43+
use pocketmine\world\Position;
4244
use pocketmine\world\sound\AnvilFallSound;
4345
use pocketmine\world\sound\Sound;
4446
use function round;
4547

4648
class Anvil extends Transparent implements Fallable, HorizontalFacing{
4749
use FallableTrait;
4850
use HorizontalFacingTrait;
51+
use InventoryMenuTrait;
4952

5053
public const UNDAMAGED = 0;
5154
public const SLIGHTLY_DAMAGED = 1;
@@ -80,12 +83,8 @@ public function getSupportType(Facing $facing) : SupportType{
8083
return SupportType::NONE;
8184
}
8285

83-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
84-
if($player instanceof Player){
85-
$player->setCurrentWindow(new AnvilInventoryWindow($player, $this->position));
86-
}
87-
88-
return true;
86+
protected function newWindow(Player $player, Position $position) : AnvilInventoryWindow{
87+
return new AnvilInventoryWindow($player, $position);
8988
}
9089

9190
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, Facing $face, Vector3 $clickVector, ?Player $player = null) : bool{

src/block/Barrel.php

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@
2323

2424
namespace pocketmine\block;
2525

26-
use pocketmine\block\inventory\window\BlockInventoryWindow;
27-
use pocketmine\block\tile\Barrel as TileBarrel;
2826
use pocketmine\block\utils\AnimatedContainer;
2927
use pocketmine\block\utils\AnimatedContainerTrait;
3028
use pocketmine\block\utils\AnyFacing;
3129
use pocketmine\block\utils\AnyFacingTrait;
30+
use pocketmine\block\utils\ContainerTrait;
3231
use pocketmine\data\runtime\RuntimeDataDescriber;
3332
use pocketmine\item\Item;
3433
use pocketmine\math\Facing;
@@ -44,6 +43,7 @@
4443
class Barrel extends Opaque implements AnimatedContainer, AnyFacing{
4544
use AnimatedContainerTrait;
4645
use AnyFacingTrait;
46+
use ContainerTrait;
4747

4848
protected bool $open = false;
4949

@@ -82,21 +82,6 @@ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Blo
8282
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
8383
}
8484

85-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
86-
if($player instanceof Player){
87-
$barrel = $this->position->getWorld()->getTile($this->position);
88-
if($barrel instanceof TileBarrel){
89-
if(!$barrel->canOpenWith($item->getCustomName())){
90-
return true;
91-
}
92-
93-
$player->setCurrentWindow(new BlockInventoryWindow($player, $barrel->getInventory(), $this->position));
94-
}
95-
}
96-
97-
return true;
98-
}
99-
10085
public function getFuelTime() : int{
10186
return 300;
10287
}

src/block/BrewingStand.php

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,20 @@
2626
use pocketmine\block\inventory\window\BrewingStandInventoryWindow;
2727
use pocketmine\block\tile\BrewingStand as TileBrewingStand;
2828
use pocketmine\block\utils\BrewingStandSlot;
29+
use pocketmine\block\utils\ContainerTrait;
2930
use pocketmine\block\utils\SupportType;
3031
use pocketmine\data\runtime\RuntimeDataDescriber;
31-
use pocketmine\item\Item;
32+
use pocketmine\inventory\Inventory;
3233
use pocketmine\math\Axis;
3334
use pocketmine\math\AxisAlignedBB;
3435
use pocketmine\math\Facing;
35-
use pocketmine\math\Vector3;
3636
use pocketmine\player\Player;
37+
use pocketmine\world\Position;
3738
use function array_key_exists;
3839
use function spl_object_id;
3940

4041
class BrewingStand extends Transparent{
42+
use ContainerTrait;
4143

4244
/**
4345
* @var BrewingStandSlot[]
@@ -96,15 +98,8 @@ public function setSlots(array $slots) : self{
9698
return $this;
9799
}
98100

99-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
100-
if($player instanceof Player){
101-
$stand = $this->position->getWorld()->getTile($this->position);
102-
if($stand instanceof TileBrewingStand && $stand->canOpenWith($item->getCustomName())){
103-
$player->setCurrentWindow(new BrewingStandInventoryWindow($player, $stand->getInventory(), $this->position));
104-
}
105-
}
106-
107-
return true;
101+
protected function newWindow(Player $player, Inventory $inventory, Position $position) : BrewingStandInventoryWindow{
102+
return new BrewingStandInventoryWindow($player, $inventory, $position);
108103
}
109104

110105
public function onScheduledUpdate() : void{

src/block/CartographyTable.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,15 @@
2424
namespace pocketmine\block;
2525

2626
use pocketmine\block\inventory\window\CartographyTableInventoryWindow;
27-
use pocketmine\item\Item;
28-
use pocketmine\math\Facing;
29-
use pocketmine\math\Vector3;
27+
use pocketmine\block\utils\InventoryMenuTrait;
3028
use pocketmine\player\Player;
29+
use pocketmine\world\Position;
3130

3231
final class CartographyTable extends Opaque{
32+
use InventoryMenuTrait;
3333

34-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
35-
if($player !== null){
36-
$player->setCurrentWindow(new CartographyTableInventoryWindow($player, $this->position));
37-
}
38-
39-
return true;
34+
protected function newWindow(Player $player, Position $position) : CartographyTableInventoryWindow{
35+
return new CartographyTableInventoryWindow($player, $position);
4036
}
4137

4238
public function getFuelTime() : int{

src/block/Chest.php

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,17 @@
2828
use pocketmine\block\tile\Chest as TileChest;
2929
use pocketmine\block\utils\AnimatedContainer;
3030
use pocketmine\block\utils\AnimatedContainerTrait;
31+
use pocketmine\block\utils\ContainerTrait;
3132
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
3233
use pocketmine\block\utils\HorizontalFacing;
3334
use pocketmine\block\utils\SupportType;
3435
use pocketmine\event\block\ChestPairEvent;
35-
use pocketmine\item\Item;
36+
use pocketmine\inventory\Inventory;
3637
use pocketmine\math\AxisAlignedBB;
3738
use pocketmine\math\Facing;
38-
use pocketmine\math\Vector3;
3939
use pocketmine\network\mcpe\protocol\BlockEventPacket;
4040
use pocketmine\network\mcpe\protocol\types\BlockPosition;
41+
use pocketmine\player\InventoryWindow;
4142
use pocketmine\player\Player;
4243
use pocketmine\world\Position;
4344
use pocketmine\world\sound\ChestCloseSound;
@@ -46,6 +47,7 @@
4647

4748
class Chest extends Transparent implements AnimatedContainer, HorizontalFacing{
4849
use AnimatedContainerTrait;
50+
use ContainerTrait;
4951
use FacesOppositePlacingPlayerTrait;
5052

5153
protected function recalculateCollisionBoxes() : array{
@@ -100,34 +102,25 @@ public function onPostPlace() : void{
100102
}
101103
}
102104

103-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
104-
if($player instanceof Player){
105-
$world = $this->position->getWorld();
106-
$chest = $world->getTile($this->position);
107-
if($chest instanceof TileChest){
108-
[$pairOnLeft, $pair] = $this->locatePair($this->position) ?? [false, null];
109-
if(
110-
!$this->getSide(Facing::UP)->isTransparent() ||
111-
($pair !== null && !$pair->getBlock()->getSide(Facing::UP)->isTransparent()) ||
112-
!$chest->canOpenWith($item->getCustomName())
113-
){
114-
return true;
115-
}
116-
117-
if($pair !== null){
118-
[$left, $right] = $pairOnLeft ? [$pair->getBlock(), $this] : [$this, $pair->getBlock()];
119-
120-
//TODO: we should probably construct DoubleChestInventory here directly too using the same logic
121-
//right now it uses some weird logic in TileChest which produces incorrect results
122-
//however I'm not sure if this is currently possible
123-
$window = new DoubleChestInventoryWindow($player, $chest->getInventory(), $left->position, $right->position);
124-
}
105+
protected function isOpeningObstructed() : bool{
106+
if(!$this->getSide(Facing::UP)->isTransparent()){
107+
return true;
108+
}
109+
[, $pair] = $this->locatePair($this->position) ?? [false, null];
110+
return $pair !== null && !$pair->getBlock()->getSide(Facing::UP)->isTransparent();
111+
}
125112

126-
$player->setCurrentWindow($window ?? new BlockInventoryWindow($player, $chest->getInventory(), $this->position));
127-
}
113+
protected function newWindow(Player $player, Inventory $inventory, Position $position) : InventoryWindow{
114+
[$pairOnLeft, $pair] = $this->locatePair($position) ?? [false, null];
115+
if($pair === null){
116+
return new BlockInventoryWindow($player, $inventory, $position);
128117
}
118+
[$left, $right] = $pairOnLeft ? [$pair->getPosition(), $position] : [$position, $pair->getPosition()];
129119

130-
return true;
120+
//TODO: we should probably construct DoubleChestInventory here directly too using the same logic
121+
//right now it uses some weird logic in TileChest which produces incorrect results
122+
//however I'm not sure if this is currently possible
123+
return new DoubleChestInventoryWindow($player, $inventory, $left, $right);
131124
}
132125

133126
public function getFuelTime() : int{

src/block/CraftingTable.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,15 @@
2424
namespace pocketmine\block;
2525

2626
use pocketmine\block\inventory\window\CraftingTableInventoryWindow;
27-
use pocketmine\item\Item;
28-
use pocketmine\math\Facing;
29-
use pocketmine\math\Vector3;
27+
use pocketmine\block\utils\InventoryMenuTrait;
3028
use pocketmine\player\Player;
29+
use pocketmine\world\Position;
3130

3231
class CraftingTable extends Opaque{
32+
use InventoryMenuTrait;
3333

34-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
35-
if($player instanceof Player){
36-
$player->setCurrentWindow(new CraftingTableInventoryWindow($player, $this->position));
37-
}
38-
39-
return true;
34+
protected function newWindow(Player $player, Position $position) : CraftingTableInventoryWindow{
35+
return new CraftingTableInventoryWindow($player, $position);
4036
}
4137

4238
public function getFuelTime() : int{

src/block/EnchantingTable.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@
2424
namespace pocketmine\block;
2525

2626
use pocketmine\block\inventory\window\EnchantingTableInventoryWindow;
27+
use pocketmine\block\utils\InventoryMenuTrait;
2728
use pocketmine\block\utils\SupportType;
28-
use pocketmine\item\Item;
2929
use pocketmine\math\AxisAlignedBB;
3030
use pocketmine\math\Facing;
31-
use pocketmine\math\Vector3;
3231
use pocketmine\player\Player;
32+
use pocketmine\world\Position;
3333

3434
class EnchantingTable extends Transparent{
35+
use InventoryMenuTrait;
3536

3637
protected function recalculateCollisionBoxes() : array{
3738
return [AxisAlignedBB::one()->trimmedCopy(Facing::UP, 0.25)];
@@ -41,13 +42,7 @@ public function getSupportType(Facing $facing) : SupportType{
4142
return SupportType::NONE;
4243
}
4344

44-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
45-
if($player instanceof Player){
46-
//TODO lock
47-
48-
$player->setCurrentWindow(new EnchantingTableInventoryWindow($player, $this->position));
49-
}
50-
51-
return true;
45+
protected function newWindow(Player $player, Position $position) : EnchantingTableInventoryWindow{
46+
return new EnchantingTableInventoryWindow($player, $position);
5247
}
5348
}

src/block/EnderChest.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929
use pocketmine\block\utils\AnimatedContainerTrait;
3030
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
3131
use pocketmine\block\utils\HorizontalFacing;
32+
use pocketmine\block\utils\InventoryMenuTrait;
3233
use pocketmine\block\utils\SupportType;
3334
use pocketmine\item\Item;
3435
use pocketmine\math\AxisAlignedBB;
3536
use pocketmine\math\Facing;
36-
use pocketmine\math\Vector3;
3737
use pocketmine\network\mcpe\protocol\BlockEventPacket;
3838
use pocketmine\network\mcpe\protocol\types\BlockPosition;
3939
use pocketmine\player\Player;
@@ -47,6 +47,7 @@ class EnderChest extends Transparent implements AnimatedContainer, HorizontalFac
4747
onContainerOpen as private traitOnContainerOpen;
4848
onContainerClose as private traitOnContainerClose;
4949
}
50+
use InventoryMenuTrait;
5051
use FacesOppositePlacingPlayerTrait;
5152

5253
public function getLightLevel() : int{
@@ -62,15 +63,12 @@ public function getSupportType(Facing $facing) : SupportType{
6263
return SupportType::NONE;
6364
}
6465

65-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
66-
if($player instanceof Player){
67-
$enderChest = $this->position->getWorld()->getTile($this->position);
68-
if($enderChest instanceof TileEnderChest && $this->getSide(Facing::UP)->isTransparent()){
69-
$player->setCurrentWindow(new BlockInventoryWindow($player, $player->getEnderInventory(), $this->position));
70-
}
71-
}
66+
protected function isOpeningObstructed() : bool{
67+
return !$this->getSide(Facing::UP)->isTransparent();
68+
}
7269

73-
return true;
70+
protected function newWindow(Player $player, Position $position) : BlockInventoryWindow{
71+
return new BlockInventoryWindow($player, $player->getEnderInventory(), $position);
7472
}
7573

7674
public function getDropsForCompatibleTool(Item $item) : array{

src/block/Furnace.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,21 @@
2525

2626
use pocketmine\block\inventory\window\FurnaceInventoryWindow;
2727
use pocketmine\block\tile\Furnace as TileFurnace;
28+
use pocketmine\block\utils\ContainerTrait;
2829
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
2930
use pocketmine\block\utils\HorizontalFacing;
3031
use pocketmine\block\utils\Lightable;
3132
use pocketmine\block\utils\LightableTrait;
3233
use pocketmine\crafting\FurnaceType;
3334
use pocketmine\data\runtime\RuntimeDataDescriber;
34-
use pocketmine\item\Item;
35-
use pocketmine\math\Facing;
36-
use pocketmine\math\Vector3;
35+
use pocketmine\inventory\Inventory;
36+
use pocketmine\player\InventoryWindow;
3737
use pocketmine\player\Player;
38+
use pocketmine\world\Position;
3839
use function mt_rand;
3940

4041
class Furnace extends Opaque implements Lightable, HorizontalFacing{
42+
use ContainerTrait;
4143
use FacesOppositePlacingPlayerTrait;
4244
use LightableTrait;
4345

@@ -61,15 +63,8 @@ public function getLightLevel() : int{
6163
return $this->lit ? 13 : 0;
6264
}
6365

64-
public function onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
65-
if($player instanceof Player){
66-
$furnace = $this->position->getWorld()->getTile($this->position);
67-
if($furnace instanceof TileFurnace && $furnace->canOpenWith($item->getCustomName())){
68-
$player->setCurrentWindow(new FurnaceInventoryWindow($player, $furnace->getInventory(), $this->position, $this->furnaceType));
69-
}
70-
}
71-
72-
return true;
66+
protected function newWindow(Player $player, Inventory $inventory, Position $position) : InventoryWindow{
67+
return new FurnaceInventoryWindow($player, $inventory, $position, $this->furnaceType);
7368
}
7469

7570
public function onScheduledUpdate() : void{

0 commit comments

Comments
 (0)