mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-01 23:59:53 +00:00
BaseInventory::addItem(item1,item2,item3) now has the same behaviour as multiple separate addItem() calls (#4237)
fixes #1412
This commit is contained in:
parent
71a4ea2a95
commit
15e5bdb210
@ -144,6 +144,20 @@ trait InventoryHelpersTrait{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var Item[] $returnSlots */
|
||||||
|
$returnSlots = [];
|
||||||
|
|
||||||
|
foreach($itemSlots as $item){
|
||||||
|
$leftover = $this->internalAddItem($item);
|
||||||
|
if(!$leftover->isNull()){
|
||||||
|
$returnSlots[] = $leftover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnSlots;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function internalAddItem(Item $slot) : Item{
|
||||||
$emptySlots = [];
|
$emptySlots = [];
|
||||||
|
|
||||||
for($i = 0, $size = $this->getSize(); $i < $size; ++$i){
|
for($i = 0, $size = $this->getSize(); $i < $size; ++$i){
|
||||||
@ -152,43 +166,31 @@ trait InventoryHelpersTrait{
|
|||||||
$emptySlots[] = $i;
|
$emptySlots[] = $i;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($itemSlots as $index => $slot){
|
if($slot->equals($item) and $item->getCount() < $item->getMaxStackSize()){
|
||||||
if($slot->equals($item) and $item->getCount() < $item->getMaxStackSize()){
|
$amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize());
|
||||||
$amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize());
|
if($amount > 0){
|
||||||
if($amount > 0){
|
$slot->setCount($slot->getCount() - $amount);
|
||||||
$slot->setCount($slot->getCount() - $amount);
|
$item->setCount($item->getCount() + $amount);
|
||||||
$item->setCount($item->getCount() + $amount);
|
$this->setItem($i, $item);
|
||||||
$this->setItem($i, $item);
|
if($slot->getCount() <= 0){
|
||||||
if($slot->getCount() <= 0){
|
break;
|
||||||
unset($itemSlots[$index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(count($itemSlots) === 0){
|
if(count($emptySlots) > 0){
|
||||||
|
foreach($emptySlots as $slotIndex){
|
||||||
|
$amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize());
|
||||||
|
$slot->setCount($slot->getCount() - $amount);
|
||||||
|
$item = clone $slot;
|
||||||
|
$item->setCount($amount);
|
||||||
|
$this->setItem($slotIndex, $item);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count($itemSlots) > 0 and count($emptySlots) > 0){
|
return $slot;
|
||||||
foreach($emptySlots as $slotIndex){
|
|
||||||
//This loop only gets the first item, then goes to the next empty slot
|
|
||||||
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);
|
|
||||||
if($slot->getCount() <= 0){
|
|
||||||
unset($itemSlots[$index]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $itemSlots;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeItem(Item ...$slots) : array{
|
public function removeItem(Item ...$slots) : array{
|
||||||
|
@ -24,8 +24,10 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\inventory;
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use pocketmine\item\Item;
|
||||||
use pocketmine\item\ItemFactory;
|
use pocketmine\item\ItemFactory;
|
||||||
use pocketmine\item\ItemIds;
|
use pocketmine\item\ItemIds;
|
||||||
|
use pocketmine\item\VanillaItems;
|
||||||
|
|
||||||
class BaseInventoryTest extends TestCase{
|
class BaseInventoryTest extends TestCase{
|
||||||
|
|
||||||
@ -47,4 +49,40 @@ class BaseInventoryTest extends TestCase{
|
|||||||
self::assertFalse($inv->canAddItem($item1), "Item WITH userdata should not stack with item WITHOUT userdata");
|
self::assertFalse($inv->canAddItem($item1), "Item WITH userdata should not stack with item WITHOUT userdata");
|
||||||
self::assertNotEmpty($inv->addItem($item1));
|
self::assertNotEmpty($inv->addItem($item1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Item[]
|
||||||
|
*/
|
||||||
|
private function getTestItems() : array{
|
||||||
|
return [
|
||||||
|
VanillaItems::APPLE()->setCount(16),
|
||||||
|
VanillaItems::APPLE()->setCount(16),
|
||||||
|
VanillaItems::APPLE()->setCount(16),
|
||||||
|
VanillaItems::APPLE()->setCount(16)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddMultipleItemsInOneCall() : void{
|
||||||
|
$inventory = new class(1) extends SimpleInventory{
|
||||||
|
|
||||||
|
};
|
||||||
|
$leftover = $inventory->addItem(...$this->getTestItems());
|
||||||
|
self::assertCount(0, $leftover);
|
||||||
|
self::assertTrue($inventory->getItem(0)->equalsExact(VanillaItems::APPLE()->setCount(64)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddMultipleItemsInOneCallWithLeftover() : void{
|
||||||
|
$inventory = new class(1) extends SimpleInventory{};
|
||||||
|
$inventory->setItem(0, VanillaItems::APPLE()->setCount(20));
|
||||||
|
$leftover = $inventory->addItem(...$this->getTestItems());
|
||||||
|
self::assertCount(2, $leftover); //the leftovers are not currently stacked - if they were given separately, they'll be returned separately
|
||||||
|
self::assertTrue($inventory->getItem(0)->equalsExact(VanillaItems::APPLE()->setCount(64)));
|
||||||
|
|
||||||
|
$leftoverCount = 0;
|
||||||
|
foreach($leftover as $item){
|
||||||
|
self::assertTrue($item->equals(VanillaItems::APPLE()));
|
||||||
|
$leftoverCount += $item->getCount();
|
||||||
|
}
|
||||||
|
self::assertSame(20, $leftoverCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user