Store ender chest viewer count on the tile, instead of relying on the inventory's viewer count (#4238)

Fixes #4021
This commit is contained in:
Jason 2021-06-13 09:37:09 -04:00 committed by GitHub
parent 408e29da90
commit 6fb364b16f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 2 deletions

View File

@ -53,6 +53,7 @@ class EnderChest extends Transparent{
if($player instanceof Player){
$enderChest = $this->pos->getWorld()->getTile($this->pos);
if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){
$enderChest->setViewerCount($enderChest->getViewerCount() + 1);
$player->setCurrentWindow(new EnderChestInventory($this->pos, $player->getEnderInventory()));
}
}

View File

@ -30,6 +30,10 @@ use function count;
trait AnimatedBlockInventoryTrait{
use BlockInventoryTrait;
public function getViewerCount() : int{
return count($this->getViewers());
}
/**
* @return Player[]
* @phpstan-return array<int, Player>
@ -43,7 +47,7 @@ trait AnimatedBlockInventoryTrait{
public function onOpen(Player $who) : void{
parent::onOpen($who);
if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){
if($this->getHolder()->isValid() and $this->getViewerCount() === 1){
//TODO: this crap really shouldn't be managed by the inventory
$this->animateBlock(true);
$this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound());
@ -53,7 +57,7 @@ trait AnimatedBlockInventoryTrait{
abstract protected function animateBlock(bool $isOpen) : void;
public function onClose(Player $who) : void{
if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){
if($this->getHolder()->isValid() and $this->getViewerCount() === 1){
//TODO: this crap really shouldn't be managed by the inventory
$this->animateBlock(false);
$this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound());

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\inventory;
use pocketmine\block\tile\EnderChest;
use pocketmine\inventory\BaseInventory;
use pocketmine\inventory\CallbackInventoryListener;
use pocketmine\inventory\Inventory;
@ -85,6 +86,14 @@ class EnderChestInventory extends BaseInventory implements BlockInventory{
$this->inventory->setContents($items);
}
public function getViewerCount() : int{
$enderChest = $this->getHolder()->getWorld()->getTile($this->getHolder());
if(!$enderChest instanceof EnderChest){
return 0;
}
return $enderChest->getViewerCount();
}
protected function getOpenSound() : Sound{
return new EnderChestOpenSound();
}
@ -102,6 +111,10 @@ class EnderChestInventory extends BaseInventory implements BlockInventory{
public function onClose(Player $who) : void{
$this->animatedBlockInventoryTrait_onClose($who);
$enderChest = $this->getHolder()->getWorld()->getTile($this->getHolder());
if($enderChest instanceof EnderChest){
$enderChest->setViewerCount($enderChest->getViewerCount() - 1);
}
if($who === $this->inventory->getHolder()){
$this->inventory->getListeners()->remove($this->inventoryListener);
$this->inventoryListener = CallbackInventoryListener::onAnyChange(static function() : void{}); //break cyclic reference

View File

@ -27,6 +27,19 @@ use pocketmine\nbt\tag\CompoundTag;
class EnderChest extends Spawnable{
protected int $viewerCount = 0;
public function getViewerCount() : int{
return $this->viewerCount;
}
public function setViewerCount(int $viewerCount) : void{
if($viewerCount < 0){
throw new \InvalidArgumentException('Viewer count cannot be negative');
}
$this->viewerCount = $viewerCount;
}
public function readSaveData(CompoundTag $nbt) : void{
}