some cleanup to held item handling

This commit is contained in:
Dylan K. Taylor 2019-06-26 19:40:40 +01:00
parent 61d443bf4e
commit 7f56f27505
6 changed files with 37 additions and 36 deletions

View File

@ -25,11 +25,7 @@ namespace pocketmine\inventory;
use pocketmine\entity\Human;
use pocketmine\item\Item;
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
use pocketmine\network\mcpe\protocol\types\ContainerIds;
use pocketmine\player\Player;
use function in_array;
use function is_array;
class PlayerInventory extends BaseInventory{
@ -98,11 +94,12 @@ class PlayerInventory extends BaseInventory{
$this->itemInHandIndex = $hotbarSlot;
if($this->getHolder() instanceof Player and $send){
$this->sendHeldItem($this->getHolder());
if($this->holder instanceof Player and $send){
$this->holder->getNetworkSession()->getInvManager()->syncSelectedHotbarSlot();
}
foreach($this->holder->getViewers() as $viewer){
$viewer->getNetworkSession()->onMobEquipmentChange($this->holder);
}
$this->sendHeldItem($this->getHolder()->getViewers());
}
/**
@ -121,29 +118,8 @@ class PlayerInventory extends BaseInventory{
*/
public function setItemInHand(Item $item) : void{
$this->setItem($this->getHeldItemIndex(), $item);
$this->sendHeldItem($this->holder->getViewers());
}
/**
* Sends the currently-held item to specified targets.
*
* @param Player|Player[] $target
*/
public function sendHeldItem($target) : void{
$item = $this->getItemInHand();
$pk = MobEquipmentPacket::create($this->getHolder()->getId(), $item, $this->getHeldItemIndex(), ContainerIds::INVENTORY);
if(!is_array($target)){
$target->sendDataPacket($pk);
if($target === $this->getHolder()){
$target->getNetworkSession()->getInvManager()->syncSlot($this, $this->getHeldItemIndex());
}
}else{
$this->getHolder()->getWorld()->getServer()->broadcastPacket($target, $pk);
if(in_array($this->getHolder(), $target, true)){
$target->getNetworkSession()->getInvManager()->syncSlot($this, $this->getHeldItemIndex());
}
foreach($this->holder->getViewers() as $viewer){
$viewer->getNetworkSession()->onMobEquipmentChange($this->holder);
}
}

View File

@ -36,6 +36,7 @@ use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
use pocketmine\network\mcpe\protocol\InventoryContentPacket;
use pocketmine\network\mcpe\protocol\InventorySlotPacket;
use pocketmine\network\mcpe\protocol\PlayerHotbarPacket;
use pocketmine\network\mcpe\protocol\types\ContainerIds;
use pocketmine\network\mcpe\protocol\types\WindowTypes;
use pocketmine\player\Player;
@ -144,6 +145,10 @@ class InventoryManager{
}
}
public function syncSelectedHotbarSlot() : void{
$this->session->sendDataPacket(PlayerHotbarPacket::create($this->player->getInventory()->getHeldItemIndex(), ContainerIds::INVENTORY));
}
public function syncCreative() : void{
$items = [];
if(!$this->player->isSpectator()){ //fill it for all gamemodes except spectator

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe;
use pocketmine\entity\effect\EffectInstance;
use pocketmine\entity\Human;
use pocketmine\entity\Living;
use pocketmine\event\player\PlayerCreationEvent;
use pocketmine\event\server\DataPacketReceiveEvent;
@ -47,6 +48,7 @@ use pocketmine\network\mcpe\protocol\DisconnectPacket;
use pocketmine\network\mcpe\protocol\GarbageServerboundPacket;
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
use pocketmine\network\mcpe\protocol\MobEffectPacket;
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
use pocketmine\network\mcpe\protocol\ModalFormRequestPacket;
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket;
@ -62,6 +64,7 @@ use pocketmine\network\mcpe\protocol\TransferPacket;
use pocketmine\network\mcpe\protocol\types\CommandData;
use pocketmine\network\mcpe\protocol\types\CommandEnum;
use pocketmine\network\mcpe\protocol\types\CommandParameter;
use pocketmine\network\mcpe\protocol\types\ContainerIds;
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
@ -776,6 +779,18 @@ class NetworkSession{
return $this->invManager;
}
/**
* TODO: expand this to more than just humans
* TODO: offhand
*
* @param Human $mob
*/
public function onMobEquipmentChange(Human $mob) : void{
//TODO: we could send zero for slot here because remote players don't need to know which slot was selected
$inv = $mob->getInventory();
$this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), $inv->getItemInHand(), $inv->getHeldItemIndex(), ContainerIds::INVENTORY));
}
public function onMobArmorChange(Living $mob) : void{
$inv = $mob->getArmorInventory();
$this->sendDataPacket(MobArmorEquipmentPacket::create($mob->getId(), $inv->getHelmet(), $inv->getChestplate(), $inv->getLeggings(), $inv->getBoots()));

View File

@ -359,7 +359,7 @@ class InGamePacketHandler extends PacketHandler{
public function handleMobEquipment(MobEquipmentPacket $packet) : bool{
if(!$this->player->selectHotbarSlot($packet->hotbarSlot)){
$this->player->getInventory()->sendHeldItem($this->player);
$this->session->getInvManager()->syncSelectedHotbarSlot();
}
return true;
}

View File

@ -93,7 +93,7 @@ class PreSpawnPacketHandler extends PacketHandler{
$this->session->getInvManager()->syncAll();
$this->session->getInvManager()->syncCreative();
$this->player->getInventory()->sendHeldItem($this->player);
$this->session->getInvManager()->syncSelectedHotbarSlot();
$this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket());
$this->session->syncPlayerList();

View File

@ -28,9 +28,6 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\network\mcpe\protocol\types\ContainerIds;
/**
* One of the most useless packets.
*/
class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{
public const NETWORK_ID = ProtocolInfo::PLAYER_HOTBAR_PACKET;
@ -41,6 +38,14 @@ class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, Server
/** @var bool */
public $selectHotbarSlot = true;
public static function create(int $slot, int $windowId, bool $selectSlot = true) : self{
$result = new self;
$result->selectedHotbarSlot = $slot;
$result->windowId = $windowId;
$result->selectHotbarSlot = $selectSlot;
return $result;
}
protected function decodePayload() : void{
$this->selectedHotbarSlot = $this->getUnsignedVarInt();
$this->windowId = $this->getByte();