diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 2b9bd77bd..212888530 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1628,10 +1628,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->inventory->sendHeldItem($this); }else{ $item = $this->inventory->getItemInHand(); + $oldItem = clone $item; //TODO: Implement adventure mode checks if($this->level->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){ - $this->inventory->setItemInHand($item, $this); - $this->inventory->sendHeldItem($this->hasSpawned); + if(!$item->equals($oldItem, true) or $item->getCount() !== $oldItem->getCount()){ + $this->inventory->setItemInHand($item, $this); + $this->inventory->sendHeldItem($this->hasSpawned); + } break; } } @@ -1802,13 +1805,17 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ if($this->isCreative()){ $item = $this->inventory->getItemInHand(); }else{ - $item = clone $this->inventory->getItemInHand(); + $item = $this->inventory->getItemInHand(); } + $oldItem = clone $item; + if($this->level->useBreakOn($vector, $item, $this) === true){ if($this->isSurvival()){ - $this->inventory->setItemInHand($item, $this); - $this->inventory->sendHeldItem($this->hasSpawned); + if(!$item->equals($oldItem, true) or $item->getCount() !== $oldItem->getCount()){ + $this->inventory->setItemInHand($item, $this); + $this->inventory->sendHeldItem($this->hasSpawned); + } } break; } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 0d83c2417..268c808c7 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -233,41 +233,58 @@ abstract class BaseInventory implements Inventory{ $source = null; } + /** @var Item[] $itemSlots */ /** @var Item[] $slots */ - foreach($slots as $i => $slot){ - $slots[$i] = clone $slot; + $itemSlots = []; + foreach($slots as $slot){ + if($slot->getId() !== 0 and $slot->getCount() > 0){ + $itemSlots[] = clone $slot; + } } + $emptySlots = []; + for($i = 0; $i < $this->getSize(); ++$i){ $item = $this->getItem($i); - foreach($slots as $index => $slot){ - if($item->getID() === Item::AIR or $item->getCount() <= 0){ - $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); - $slot->setCount($slot->getCount() - $amount); - $item = clone $slot; - $item->setCount($amount); - $this->setItem($i, $item, $source); - $item = $this->getItem($i); - if($slot->getCount() <= 0){ - unset($slots[$index]); - } - }elseif($slot->equals($item, true) and $item->getCount() < $item->getMaxStackSize()){ + if($item->getId() === Item::AIR or $item->getCount() <= 0){ + $emptySlots[] = $i; + } + + foreach($itemSlots as $index => $slot){ + if($slot->equals($item, true) and $item->getCount() < $item->getMaxStackSize()){ $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); - $slot->setCount($slot->getCount() - $amount); - $item->setCount($item->getCount() + $amount); - $this->setItem($i, $item, $source); - if($slot->getCount() <= 0){ - unset($slots[$index]); + if($amount > 0){ + $slot->setCount($slot->getCount() - $amount); + $item->setCount($item->getCount() + $amount); + $this->setItem($i, $item, $source); + if($slot->getCount() <= 0){ + unset($itemSlots[$index]); + } } } } - if(count($slots) === 0){ + if(count($itemSlots) === 0){ break; } } - return $slots; + if(count($itemSlots) > 0 and count($emptySlots) > 0){ + foreach($emptySlots as $slotIndex){ + foreach($itemSlots as $index => $slot){ + $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); + $slot->setCount($slot->getCount() - $amount); + $item = clone $slot; + $item->setCount($amount); + $this->setItem($slotIndex, $item, $source); + if($slot->getCount() <= 0){ + unset($itemSlots[$index]); + } + } + } + } + + return $itemSlots; } public function removeItem(...$slots){ @@ -279,31 +296,39 @@ abstract class BaseInventory implements Inventory{ $source = null; } + /** @var Item[] $itemSlots */ /** @var Item[] $slots */ + $itemSlots = []; + foreach($slots as $slot){ + if($slot->getId() !== 0 and $slot->getCount() > 0){ + $itemSlots[] = clone $slot; + } + } + for($i = 0; $i < $this->getSize(); ++$i){ $item = $this->getItem($i); - if($item->getID() === Item::AIR){ + if($item->getId() === Item::AIR or $item->getCount() <= 0){ continue; } - foreach($slots as $index => $slot){ + foreach($itemSlots as $index => $slot){ if($slot->equals($item, $slot->getDamage() === null ? false : true)){ $amount = min($item->getCount(), $slot->getCount()); $slot->setCount($slot->getCount() - $amount); $item->setCount($item->getCount() - $amount); $this->setItem($i, $item, $source); if($slot->getCount() <= 0){ - unset($slots[$index]); + unset($itemSlots[$index]); } } } - if(count($slots) === 0){ + if(count($itemSlots) === 0){ break; } } - return $slots; + return $itemSlots; } public function clear($index, $source = null){ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index ff7aa0aaf..11fb44484 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -625,7 +625,7 @@ class Item{ } final public function __toString(){ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->meta === null ? "?" : $this->meta) . ")"; + return "Item " . $this->name . " (" . $this->id . ":" . ($this->meta === null ? "?" : $this->meta) . ")x".$this->count; } public function getDestroySpeed(Block $block, Player $player){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f7387c486..471874e18 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1091,8 +1091,8 @@ class Level implements ChunkManager, Metadatable{ $tile->unpair(); } - foreach($tile->getInventory()->getContents() as $item){ - $this->dropItem($target, $item); + foreach($tile->getInventory()->getContents() as $chestItem){ + $this->dropItem($target, $chestItem); } }