holder = $holder; $this->inventory = $inventory; $this->inventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener( function(Inventory $unused, int $slot, Item $oldItem) : void{ $this->onSlotChange($slot, $oldItem); }, function(Inventory $unused, array $oldContents) : void{ $this->onContentChange($oldContents); } )); } public function getEnderInventory() : PlayerEnderInventory{ return $this->inventory; } public function getSize() : int{ return $this->inventory->getSize(); } public function getItem(int $index) : Item{ return $this->inventory->getItem($index); } protected function internalSetItem(int $index, Item $item) : void{ $this->inventory->setItem($index, $item); } public function getContents(bool $includeEmpty = false) : array{ return $this->inventory->getContents($includeEmpty); } protected function internalSetContents(array $items) : void{ $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(); } protected function getCloseSound() : Sound{ return new EnderChestCloseSound(); } protected function animateBlock(bool $isOpen) : void{ $holder = $this->getHolder(); //event ID is always 1 for a chest $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); } 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 } } }