Inventory improvements

This commit is contained in:
Andy Kernel 2024-08-20 19:11:21 +02:00 committed by solcloud
parent 1e9a185fca
commit b380e97426
7 changed files with 47 additions and 21 deletions

View File

@ -10,15 +10,23 @@ use cs\Weapon;
class BuyMenu
{
/** @var array<int,int> [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) {

View File

@ -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());

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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