holder = $player; parent::__construct(); } public function getName() : string{ return "Player"; } public function getDefaultSize() : int{ return 36; } /** * Called when a client equips a hotbar slot. This method should not be used by plugins. * This method will call PlayerItemHeldEvent. * * @param int $hotbarSlot Number of the hotbar slot to equip. * * @return bool if the equipment change was successful, false if not. */ public function equipItem(int $hotbarSlot) : bool{ if(!$this->isHotbarSlot($hotbarSlot)){ $this->sendContents($this->getHolder()); return false; } $this->getHolder()->getLevel()->getServer()->getPluginManager()->callEvent($ev = new PlayerItemHeldEvent($this->getHolder(), $this->getItem($hotbarSlot), $hotbarSlot)); if($ev->isCancelled()){ $this->sendHeldItem($this->getHolder()); return false; } $this->setHeldItemIndex($hotbarSlot, false); return true; } private function isHotbarSlot(int $slot) : bool{ return $slot >= 0 and $slot <= $this->getHotbarSize(); } /** * @param int $slot * @throws \InvalidArgumentException */ private function throwIfNotHotbarSlot(int $slot){ if(!$this->isHotbarSlot($slot)){ throw new \InvalidArgumentException("$slot is not a valid hotbar slot index (expected 0 - " . ($this->getHotbarSize() - 1) . ")"); } } /** * Returns the item in the specified hotbar slot. * * @param int $hotbarSlot * @return Item * * @throws \InvalidArgumentException if the hotbar slot index is out of range */ public function getHotbarSlotItem(int $hotbarSlot) : Item{ $this->throwIfNotHotbarSlot($hotbarSlot); return $this->getItem($hotbarSlot); } /** * Returns the hotbar slot number the holder is currently holding. * @return int */ public function getHeldItemIndex() : int{ return $this->itemInHandIndex; } /** * Sets which hotbar slot the player is currently loading. * * @param int $hotbarSlot 0-8 index of the hotbar slot to hold * @param bool $send Whether to send updates back to the inventory holder. This should usually be true for plugin calls. * It should only be false to prevent feedback loops of equipment packets between client and server. * * @throws \InvalidArgumentException if the hotbar slot is out of range */ public function setHeldItemIndex(int $hotbarSlot, bool $send = true){ $this->throwIfNotHotbarSlot($hotbarSlot); $this->itemInHandIndex = $hotbarSlot; if($this->getHolder() instanceof Player and $send){ $this->sendHeldItem($this->getHolder()); } $this->sendHeldItem($this->getHolder()->getViewers()); } /** * Returns the currently-held item. * * @return Item */ public function getItemInHand() : Item{ return $this->getHotbarSlotItem($this->itemInHandIndex); } /** * Sets the item in the currently-held slot to the specified item. * * @param Item $item * * @return bool */ public function setItemInHand(Item $item) : bool{ return $this->setItem($this->getHeldItemIndex(), $item); } /** * Sends the currently-held item to specified targets. * @param Player|Player[] $target */ public function sendHeldItem($target){ $item = $this->getItemInHand(); $pk = new MobEquipmentPacket(); $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->item = $item; $pk->inventorySlot = $pk->hotbarSlot = $this->getHeldItemIndex(); $pk->windowId = ContainerIds::INVENTORY; if(!is_array($target)){ $target->dataPacket($pk); if($target === $this->getHolder()){ $this->sendSlot($this->getHeldItemIndex(), $target); } }else{ $this->getHolder()->getLevel()->getServer()->broadcastPacket($target, $pk); if(in_array($this->getHolder(), $target, true)){ $this->sendSlot($this->getHeldItemIndex(), $this->getHolder()); } } } /** * Returns the number of slots in the hotbar. * @return int */ public function getHotbarSize() : int{ return 9; } public function sendCreativeContents(){ $pk = new InventoryContentPacket(); $pk->windowId = ContainerIds::CREATIVE; if(!$this->getHolder()->isSpectator()){ //fill it for all gamemodes except spectator foreach(Item::getCreativeItems() as $i => $item){ $pk->items[$i] = clone $item; } } $this->getHolder()->dataPacket($pk); } /** * This override is here for documentation and code completion purposes only. * @return Human|Player */ public function getHolder(){ return $this->holder; } }