From b380e97426933eccd5a0e156f1197146cd0d6204 Mon Sep 17 00:00:00 2001 From: Andy Kernel <171799466+starswaitforus@users.noreply.github.com> Date: Tue, 20 Aug 2024 19:11:21 +0200 Subject: [PATCH] Inventory improvements --- server/src/Core/BuyMenu.php | 22 ++++++++++++++------- server/src/Core/Inventory.php | 17 ++++++++-------- server/src/Core/Item.php | 5 +++++ server/src/Core/World.php | 6 +++--- server/src/Equipment/Flashbang.php | 7 +++++++ server/src/Traits/Player/InventoryTrait.php | 5 ++--- test/og/Inventory/SimpleInventoryTest.php | 6 ++++++ 7 files changed, 47 insertions(+), 21 deletions(-) diff --git a/server/src/Core/BuyMenu.php b/server/src/Core/BuyMenu.php index 459d025..5ac4319 100644 --- a/server/src/Core/BuyMenu.php +++ b/server/src/Core/BuyMenu.php @@ -10,15 +10,23 @@ use cs\Weapon; class BuyMenu { /** @var array [itemId => count] */ - private array $itemBuyCount = []; - private int $grenadeCount = 0; + private array $itemBuyCount; + private int $grenadeCount; private int $grenadeCountMax = 4; - /** - * @param Item[] $alreadyHaveItems - */ - public function __construct(public readonly bool $forAttackerStore, array $alreadyHaveItems) + /** @param Item[] $alreadyHaveItems */ + public function __construct(public bool $forAttackerStore, array $alreadyHaveItems) { + $this->reset($this->forAttackerStore, $alreadyHaveItems); + } + + /** @param Item[] $alreadyHaveItems */ + public function reset(bool $forAttackerStore, array $alreadyHaveItems): void + { + $this->grenadeCount = 0; + $this->itemBuyCount = []; + $this->forAttackerStore = $forAttackerStore; + foreach ($alreadyHaveItems as $item) { if ($item->getType() === ItemType::TYPE_GRENADE) { $this->grenadeCount++; @@ -72,7 +80,7 @@ class BuyMenu return $item; } - public function buy(Item $item): void + public function confirmPurchase(Item $item): void { $this->itemBuyCount[$item->getId()]++; if ($item->getType() === ItemType::TYPE_GRENADE) { diff --git a/server/src/Core/Inventory.php b/server/src/Core/Inventory.php index db8de2f..93d06e5 100644 --- a/server/src/Core/Inventory.php +++ b/server/src/Core/Inventory.php @@ -5,7 +5,6 @@ namespace cs\Core; use cs\Enum\ArmorType; use cs\Enum\BuyMenuItem; use cs\Enum\InventorySlot; -use cs\Equipment\Flashbang; use cs\Equipment\Grenade; use cs\Equipment\Kevlar; use cs\Event\EquipEvent; @@ -27,6 +26,7 @@ class Inventory public function __construct(bool $isAttackerSide) { + $this->store = new BuyMenu($isAttackerSide, []); $this->reset($isAttackerSide, true); } @@ -53,7 +53,7 @@ class Inventory } $this->removeBomb(); - $this->store = new BuyMenu($isAttackerSide, $this->items); + $this->store->reset($isAttackerSide, $this->items); } private function updateEquippedSlot(): int @@ -95,11 +95,12 @@ class Inventory } $this->updateEquippedSlot(); $item->unEquip(); - } else { - $item->decrementQuantity(); + + return $item; } - return $item; + $item->decrementQuantity(); + return $item->clone(); } public function removeSlot(int $slot): void @@ -129,7 +130,7 @@ class Inventory } if ($alreadyHave) { - return ($alreadyHave->canPurchaseMultipleTime($item)); + return $alreadyHave->canPurchaseMultipleTime($item); } return true; } @@ -144,7 +145,7 @@ class Inventory $alreadyHave = $this->items[$item->getSlot()->value] ?? null; $this->dollars -= $item->getPrice($alreadyHave); if ($alreadyHave) { - if ($alreadyHave instanceof Flashbang) { + if ($alreadyHave->getQuantity() < $item->getMaxQuantity()) { $alreadyHave->incrementQuantity(); $item = $alreadyHave; } elseif ($alreadyHave instanceof Kevlar && $alreadyHave->getArmorType() === ArmorType::BODY_AND_HEAD) { @@ -156,7 +157,7 @@ class Inventory } } - $this->store->buy($item); + $this->store->confirmPurchase($item); $this->items[$item->getSlot()->value] = $item; if ($item->canBeEquipped()) { return $this->equip($item->getSlot()); diff --git a/server/src/Core/Item.php b/server/src/Core/Item.php index 1b63193..31fd81a 100644 --- a/server/src/Core/Item.php +++ b/server/src/Core/Item.php @@ -80,6 +80,11 @@ abstract class Item // empty hook } + public function clone(): static + { + throw new GameException('Override clone() method if makes sense for item: ' . get_class($this)); + } + public abstract function getType(): ItemType; public abstract function getSlot(): InventorySlot; diff --git a/server/src/Core/World.php b/server/src/Core/World.php index 744e81b..fdf41b2 100644 --- a/server/src/Core/World.php +++ b/server/src/Core/World.php @@ -330,19 +330,19 @@ class World continue; } - $gunSwap = false; + $shouldEquipOnPickup = false; $item = $dropItem->getItem(); $slot = $item->getSlot(); $slotId = $slot->value; if ($player->getInventory()->has($slotId) && in_array($slotId, [InventorySlot::SLOT_PRIMARY->value, InventorySlot::SLOT_SECONDARY->value], true)) { - $gunSwap = true; + $shouldEquipOnPickup = ($player->getEquippedItem()->getSlot() === $slot); $player->dropItemFromSlot($slotId); } if ($player->getInventory()->pickup($item)) { $sound = new SoundEvent($dropItem->getPosition(), SoundType::ITEM_PICKUP); $this->makeSound($sound->setPlayer($player)->setItem($item)->addExtra('id', $dropItem->getId())); unset($this->dropItems[$key]); - if ($gunSwap) { + if ($shouldEquipOnPickup) { $player->equip($slot); } return; diff --git a/server/src/Equipment/Flashbang.php b/server/src/Equipment/Flashbang.php index 9045567..15dc5b4 100644 --- a/server/src/Equipment/Flashbang.php +++ b/server/src/Equipment/Flashbang.php @@ -26,6 +26,13 @@ class Flashbang extends Grenade return $this->quantity; } + public function clone(): static + { + $clone = clone $this; + $clone->quantity = 1; + return $clone; + } + public function getMaxQuantity(): int { return 2; diff --git a/server/src/Traits/Player/InventoryTrait.php b/server/src/Traits/Player/InventoryTrait.php index 903d267..fa4fbd2 100644 --- a/server/src/Traits/Player/InventoryTrait.php +++ b/server/src/Traits/Player/InventoryTrait.php @@ -64,12 +64,11 @@ trait InventoryTrait public function dropEquippedItem(): ?Item { - $item = $this->getEquippedItem(); - if (!$item->isUserDroppable()) { + $item = $this->inventory->removeEquipped(); + if (null === $item) { return null; } - $this->inventory->removeEquipped(); $this->world->dropItem($this, $item); $this->equip($this->getEquippedItem()->getSlot()); return $item; diff --git a/test/og/Inventory/SimpleInventoryTest.php b/test/og/Inventory/SimpleInventoryTest.php index b47df57..db1c917 100644 --- a/test/og/Inventory/SimpleInventoryTest.php +++ b/test/og/Inventory/SimpleInventoryTest.php @@ -357,6 +357,12 @@ class SimpleInventoryTest extends BaseTestCase $this->assertInstanceOf(Flashbang::class, $item); $this->assertSame($itemPrice, $item->getPrice()); $this->assertFalse($game->getPlayer(1)->getInventory()->canBuy($item)); + + $flashBang1 = $game->getPlayer(1)->dropEquippedItem(); + $this->assertInstanceOf(Flashbang::class, $flashBang1); + $flashBang2 = $game->getPlayer(1)->dropEquippedItem(); + $this->assertInstanceOf(Flashbang::class, $flashBang2); + $this->assertFalse($flashBang1 === $flashBang2); } public function testPlayerBuyMaxFourGrenades(): void