Hello, does anyone know why this inventorytransactionevent doesn't work for my virtual inventory? I already created a tile and all of that, heres my code. PHP: foreach($event->getTransaction()->getInventories() as $inventory){ if($inventory->getHolder() instanceof Player){ $player = $inventory->getHolder(); }else{ $chest = $inventory->getHolder(); $viewers = $inventory->getViewers(); } } foreach($event->getTransaction()->getActions() as $transaction){ if($oldItemChest === null and $newItemChest === null){ $oldItemChest = $transaction->getSourceItem(); $newItemChest = $transaction->getTargetItem(); }else{ $oldItemPlayer = $transaction->getSourceItem(); $newItemPlayer = $transaction->getTargetItem(); } if($chestSlot !== null){ $playerSlot = $transaction->getSlot(); }else{ $chestSlot = $transaction->getSlot(); } } if($player !== null and $chest !== null and $oldItemPlayer !== null and $newItemPlayer !== null and $oldItemChest !== null and $newItemChest !== null and $chestSlot !== null and $playerSlot !== null){ $action = $oldItemChest->getCount() > $newItemChest->getCount();//true if player take an item $diff = $action ? $oldItemChest->getCount() - $newItemChest->getCount() : $newItemChest->getCount() - $oldItemChest->getCount(); if($i->getId() == 1 && $i->getCustomName() == c::GREEN. "addWindow"){ $this->closeWindow($tile->getInventory()); $ev->getPlayer()->sendMessage("hai"); } } }
Use packets, sometimes they work bettter. PHP: public function onDataRecieve(DataPacketReceiveEvent $event) { $pk = $event->getPacket(); if($pk instanceof InventoryTransactionPacket) { if($pk->transactionType === 0) { $item = $pk->actions[0]->oldItem; $player = $event->getPlayer(); } } }
Why use packets when there's an event being fired already. And to top it off, DataPacketReceiveEvent is fired heavily, so use it only if you are certain that there's no better way of doing what you are trying to do. InventoryTransactionEvent is just the perfect choice here.
In the first block, I see you are looping through all inventories to get the player that is involved in the transaction. There's already a function for that. PHP: $transaction = $event->getTransaction();$player = $transaction->getSource();//https://github.com/pmmp/PocketMine-MP/blob/9bbebaa0716e8f2f27b4c1eebe4d9ab1f417dd31/src/pocketmine/inventory/transaction/InventoryTransaction.php#L67 But you'll need to loop through the inventories to fetch the chest tile. PHP: /** @var tile\Chest|null */$chest = null;foreach($transaction->getInventories() as $inventory){ if($inventory instanceof ChestInventory){ $chest = $inventory->getHolder(); break; }} I don't understand the rest, mind explaining what you are doing over here? PHP: foreach($event->getTransaction()->getActions() as $transaction){ if($oldItemChest === null and $newItemChest === null){ $oldItemChest = $transaction->getSourceItem(); $newItemChest = $transaction->getTargetItem(); }else{ $oldItemPlayer = $transaction->getSourceItem(); $newItemPlayer = $transaction->getTargetItem(); } if($chestSlot !== null){ $playerSlot = $transaction->getSlot(); }else{ $chestSlot = $transaction->getSlot(); } } if($player !== null and $chest !== null and $oldItemPlayer !== null and $newItemPlayer !== null and $oldItemChest !== null and $newItemChest !== null and $chestSlot !== null and $playerSlot !== null){ $action = $oldItemChest->getCount() > $newItemChest->getCount();//true if player take an item $diff = $action ? $oldItemChest->getCount() - $newItemChest->getCount() : $newItemChest->getCount() - $oldItemChest->getCount(); if($i->getId() == 1 && $i->getCustomName() == c::GREEN. "addWindow"){ $this->closeWindow($tile->getInventory()); $ev->getPlayer()->sendMessage("hai"); } }
Ok but how do I make it so when I pick up an item from that inventory it sends a message or something what's the code?