mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 08:17:34 +00:00
Separate held item index change listener logic from PlayerInventory
This commit is contained in:
parent
01c867b608
commit
c70c0b55df
@ -264,7 +264,12 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
}
|
||||
|
||||
$this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0), false);
|
||||
$this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0));
|
||||
$this->inventory->getHeldItemIndexChangeListeners()->add(function(int $oldIndex) : void{
|
||||
foreach($this->getViewers() as $viewer){
|
||||
$viewer->getNetworkSession()->onMobEquipmentChange($this);
|
||||
}
|
||||
});
|
||||
|
||||
$this->hungerManager->setFood((float) $nbt->getInt("foodLevel", (int) $this->hungerManager->getFood()));
|
||||
$this->hungerManager->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->hungerManager->getExhaustion()));
|
||||
@ -457,6 +462,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
|
||||
protected function onDispose() : void{
|
||||
$this->inventory->removeAllViewers();
|
||||
$this->inventory->getHeldItemIndexChangeListeners()->clear();
|
||||
$this->enderChestInventory->removeAllViewers();
|
||||
parent::onDispose();
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use Ds\Set;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\player\Player;
|
||||
@ -35,8 +36,15 @@ class PlayerInventory extends BaseInventory{
|
||||
/** @var int */
|
||||
protected $itemInHandIndex = 0;
|
||||
|
||||
/**
|
||||
* @var \Closure[]|Set
|
||||
* @phpstan-var Set<\Closure(int $oldIndex) : void>
|
||||
*/
|
||||
protected $heldItemIndexChangeListeners;
|
||||
|
||||
public function __construct(Human $player){
|
||||
$this->holder = $player;
|
||||
$this->heldItemIndexChangeListeners = new Set();
|
||||
parent::__construct(36);
|
||||
}
|
||||
|
||||
@ -73,25 +81,27 @@ class PlayerInventory extends BaseInventory{
|
||||
/**
|
||||
* 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.
|
||||
* @param int $hotbarSlot 0-8 index of the hotbar slot to hold
|
||||
*
|
||||
* @throws \InvalidArgumentException if the hotbar slot is out of range
|
||||
*/
|
||||
public function setHeldItemIndex(int $hotbarSlot, bool $send = true) : void{
|
||||
public function setHeldItemIndex(int $hotbarSlot) : void{
|
||||
$this->throwIfNotHotbarSlot($hotbarSlot);
|
||||
|
||||
$oldIndex = $this->itemInHandIndex;
|
||||
$this->itemInHandIndex = $hotbarSlot;
|
||||
|
||||
if($this->holder instanceof Player and $send){
|
||||
$this->holder->getNetworkSession()->getInvManager()->syncSelectedHotbarSlot();
|
||||
}
|
||||
foreach($this->holder->getViewers() as $viewer){
|
||||
$viewer->getNetworkSession()->onMobEquipmentChange($this->holder);
|
||||
foreach($this->heldItemIndexChangeListeners as $callback){
|
||||
$callback($oldIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Closure[]|Set
|
||||
* @phpstan-return Set<\Closure(int $oldIndex) : void>
|
||||
*/
|
||||
public function getHeldItemIndexChangeListeners() : Set{ return $this->heldItemIndexChangeListeners; }
|
||||
|
||||
/**
|
||||
* Returns the currently-held item.
|
||||
*/
|
||||
|
@ -76,6 +76,8 @@ class InventoryManager{
|
||||
* @phpstan-var array<int, array<int, Item>>
|
||||
*/
|
||||
private $initiatedSlotChanges = [];
|
||||
/** @var int */
|
||||
private $clientSelectedHotbarSlot = -1;
|
||||
|
||||
public function __construct(Player $player, NetworkSession $session){
|
||||
$this->player = $player;
|
||||
@ -84,6 +86,10 @@ class InventoryManager{
|
||||
$this->add(ContainerIds::INVENTORY, $this->player->getInventory());
|
||||
$this->add(ContainerIds::ARMOR, $this->player->getArmorInventory());
|
||||
$this->add(ContainerIds::UI, $this->player->getCursorInventory());
|
||||
|
||||
$this->player->getInventory()->getHeldItemIndexChangeListeners()->add(function() : void{
|
||||
$this->syncSelectedHotbarSlot();
|
||||
});
|
||||
}
|
||||
|
||||
private function add(int $id, Inventory $inventory) : void{
|
||||
@ -206,13 +212,21 @@ class InventoryManager{
|
||||
}
|
||||
}
|
||||
|
||||
public function onClientSelectHotbarSlot(int $slot) : void{
|
||||
$this->clientSelectedHotbarSlot = $slot;
|
||||
}
|
||||
|
||||
public function syncSelectedHotbarSlot() : void{
|
||||
$this->session->sendDataPacket(MobEquipmentPacket::create(
|
||||
$this->player->getId(),
|
||||
TypeConverter::getInstance()->coreItemStackToNet($this->player->getInventory()->getItemInHand()),
|
||||
$this->player->getInventory()->getHeldItemIndex(),
|
||||
ContainerIds::INVENTORY
|
||||
));
|
||||
$selected = $this->player->getInventory()->getHeldItemIndex();
|
||||
if($selected !== $this->clientSelectedHotbarSlot){
|
||||
$this->session->sendDataPacket(MobEquipmentPacket::create(
|
||||
$this->player->getId(),
|
||||
TypeConverter::getInstance()->coreItemStackToNet($this->player->getInventory()->getItemInHand()),
|
||||
$selected,
|
||||
ContainerIds::INVENTORY
|
||||
));
|
||||
$this->clientSelectedHotbarSlot = $selected;
|
||||
}
|
||||
}
|
||||
|
||||
public function syncCreative() : void{
|
||||
|
@ -448,6 +448,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function handleMobEquipment(MobEquipmentPacket $packet) : bool{
|
||||
$this->session->getInvManager()->onClientSelectHotbarSlot($packet->hotbarSlot);
|
||||
if(!$this->player->selectHotbarSlot($packet->hotbarSlot)){
|
||||
$this->session->getInvManager()->syncSelectedHotbarSlot();
|
||||
}
|
||||
|
@ -1373,7 +1373,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->inventory->setHeldItemIndex($hotbarSlot, false);
|
||||
$this->inventory->setHeldItemIndex($hotbarSlot);
|
||||
$this->setUsingItem(false);
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user