Skip to content

Commit

Permalink
Character Inventory Services are all 100% tested
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamKyle committed Nov 15, 2023
1 parent 9c6e11e commit 5cb5627
Show file tree
Hide file tree
Showing 5 changed files with 487 additions and 99 deletions.
86 changes: 49 additions & 37 deletions app/Game/CharacterInventory/Services/CharacterInventoryService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Game\CharacterInventory\Services;

use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use League\Fractal\Resource\Collection as LeagueCollection;
Expand Down Expand Up @@ -136,6 +137,11 @@ public function setPositions(array $positions): CharacterInventoryService {
return $this;
}

/**
* Get api response.
*
* @return array
*/
public function getInventoryForApi(): array {
$equipped = $this->fetchEquipped();
$usableSets = $this->getUsableSets();
Expand Down Expand Up @@ -368,6 +374,11 @@ public function getUsableSets(): array {
}

/**
* Get inventory collection.
*
* - Does not include equipped, usable or quest items.
* - Only comes from inventory, does not include sets.
*
* @return Collection
*/
public function getInventoryCollection(): Collection {
Expand Down Expand Up @@ -396,6 +407,14 @@ public function fetchCharacterInventory(): array {
return array_reverse($this->manager->createData($slots)->toArray());
}

/**
* Fetch inventory slot items.
*
* - Does not include alchemy or quest items.
* - Items can also not be equipped.
*
* @return array
*/
public function findCharacterInventorySlotIds(): array {

return $this->character
Expand Down Expand Up @@ -455,41 +474,29 @@ public function fetchEquipped(): array|null {
/**
* Set the inventory
*
* @param Request $request
* @return CharacterInventoryService
*/
public function setInventory(string $type): CharacterInventoryService {

$useArray = !in_array($type, ['body', 'shield', 'leggings', 'feet', 'sleeves', 'helmet', 'gloves', 'artifact']);
public function setInventory(): CharacterInventoryService {

$this->inventory = $this->getInventory($type, $useArray);
$this->inventory = $this->getInventory();

return $this;
}

protected function getInventory(string $type, bool $useArray = false): Collection {
$inventory = $this->character->inventory->slots->filter(function ($slot) use ($type, $useArray) {
if ($useArray) {
return in_array($slot->position, $this->positions) && $slot->equipped;
}

return $slot->item->type === $type && $slot->equipped;
});
/**
* Get inventory
*
* @return Collection
*/
protected function getInventory(): Collection {

if ($inventory->isEmpty()) {
$equippedSet = $this->character->inventorySets()->where('is_equipped', true)->first();
if (!is_null($equippedSet)) {
$inventory = $equippedSet->slots->filter(function ($slot) use ($type, $useArray) {
if ($useArray) {
return in_array($slot->position, $this->positions) && $slot->equipped;
}
$inventory = $this->character->inventory->slots->whereIn('position', $this->positions)->where('equipped', true);

return $slot->item->type === $type && $slot->equipped;
});
}
if (!$inventory->isEmpty()) {
return $inventory;
}

return $inventory;
return $this->character->inventorySets->where('is_equipped', true)->whereIn('slots.position', $this->positions);
}

/**
Expand All @@ -504,27 +511,32 @@ public function inventory(): Collection {
/**
* Fetches the type of the item.
*
* @param Request $request
* @param Item $item
* @return string
* @throws Exception
*/
public function getType(Item $item, string $type = null): string {
if (!is_null($type)) {
return $this->fetchType($type);
}

if ($item->type === 'bow') {
return $item->type;
}

return $item->crafting_type;
public function getType(Item $item): string {
return $this->fetchType($item->type);
}

/**
* Fetch type based on accepted types.
*
* @param string $type
* @return string
* @throws Exception
*/
protected function fetchType(string $type): string {
$acceptedTypes = [
'weapon', 'ring', 'shield', 'artifact', 'spell', 'armour', 'trinket', 'stave', 'hammer'
'weapon', 'ring', 'shield', 'artifact', 'spell', 'armour',
'trinket', 'stave', 'hammer', 'bow', 'alchemy', 'quest',
];

return in_array($type, $acceptedTypes) ? $type : 'armour';
// Spells do not have the tye spell - they are differentiated by damage or healing suffix.
if ($type === 'spell-damage' || $type === 'spell-healing') {
$type = 'spell';
}

return !in_array($type, $acceptedTypes) ? throw new Exception('Unknown Item type: ' . $type) : $type;
}
}
9 changes: 5 additions & 4 deletions app/Game/CharacterInventory/Services/ComparisonService.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ public function __construct(
* @param Character $character
* @param InventorySlot $itemToEquip
* @param string $type
* @return array
*/
public function buildComparisonData(Character $character, InventorySlot $itemToEquip, string $type) {
public function buildComparisonData(Character $character, InventorySlot $itemToEquip, string $type): array {
$service = $this->characterInventoryService->setCharacter($character)
->setInventorySlot($itemToEquip)
->setPositions($this->validEquipPositionsValue->getPositions($itemToEquip->item))
Expand All @@ -70,7 +71,7 @@ public function buildComparisonData(Character $character, InventorySlot $itemToE
'details' => [],
'atonement' => $this->itemAtonements->getAtonements($itemToEquip->item, $inventory),
'itemToEquip' => $itemToEquip->item->type === 'alchemy' ? $this->buildUsableItemDetails($itemToEquip) : $this->buildItemDetails($itemToEquip),
'type' => $service->getType($itemToEquip->item, $type),
'type' => $service->getType($itemToEquip->item),
'slotId' => $itemToEquip->id,
'characterId' => $character->id,
'bowEquipped' => $this->hasTypeEquipped($character, 'bow'),
Expand All @@ -95,7 +96,7 @@ public function buildComparisonData(Character $character, InventorySlot $itemToE
'details' => $this->equipItemService->getItemStats($itemToEquip->item, $inventory, $character),
'atonement' => $this->itemAtonements->getAtonements($itemToEquip->item, $inventory),
'itemToEquip' => $this->buildItemDetails($itemToEquip),
'type' => $service->getType($itemToEquip->item, $type),
'type' => $service->getType($itemToEquip->item),
'slotId' => $itemToEquip->id,
'slotPosition' => $itemToEquip->position,
'characterId' => $character->id,
Expand Down Expand Up @@ -138,7 +139,7 @@ public function buildShopData(Character $character, Item $item, string $type = n
'details' => $this->equipItemService->getItemStats($item, $inventory, $character),
'atonement' => $this->itemAtonements->getAtonements($item, $inventory),
'itemToEquip' => $this->itemDetails($item),
'type' => $service->getType($item, $type),
'type' => $service->getType($item),
'slotId' => $item->id,
'slotPosition' => null,
'characterId' => $character->id,
Expand Down
75 changes: 17 additions & 58 deletions app/Game/CharacterInventory/Services/EquipItemService.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,25 +197,12 @@ public function getItemStats(Item $toCompare, Collection $inventorySlots, Charac
}

/**
* Do we have a bow equipped?
* Unequipped a slot.
*
* @param Item $itemToEquip
* @param Collection $inventorySlots
* @param string $type
* @return bool
* @param InventorySlot $characterSlot
* @param Inventory|InventorySet $inventory
* @return void
*/
public function isTwoHandedItemEquipped(Item $itemToEquip, Collection $inventorySlots, string $type): bool {
$validTypes = ['bow', 'hammer', 'stave'];

if (!in_array($itemToEquip->type, $validTypes)) {
return false;
}

return $inventorySlots->filter(function ($slot) use ($type) {
return $slot->item->type === $type && $slot->equipped;
})->isNotEmpty();
}

public function unequipSlot(InventorySlot $characterSlot, Inventory|InventorySet $inventory) {
if ($characterSlot->item->type === 'bow') {
$this->unequipBothHands();
Expand All @@ -225,55 +212,27 @@ public function unequipSlot(InventorySlot $characterSlot, Inventory|InventorySet
$this->unequipBothHands();
} else {

if (!$this->removeTwoHandedWeapon($inventory)) {
$itemForPosition = $inventory->slots->filter(function ($slot) {
return $slot->position === $this->request['position'] && $slot->equipped;
})->first();

if (!is_null($itemForPosition)) {
$itemForPosition->update(['equipped' => false]);

$this->character->inventory->slots()->create([
'inventory_id' => $this->character->inventory->id,
'item_id' => $itemForPosition->item->id,
]);

$itemForPosition->delete();
}
}
}
}

protected function removeTwoHandedWeapon(Inventory|InventorySet $inventory): bool {
if ($this->request['position'] === 'right-hand' || $this->request['position'] === 'left-hand') {

$itemsForPosition = $inventory->slots->filter(function ($slot) {
return ($slot->position === 'right-hand' || $slot->position === 'left-hand') && $slot->equipped;
});

$unequipTypes = ['bow', 'hammer', 'stave'];

foreach ($itemsForPosition as $itemForPosition) {
if (in_array($itemForPosition->item->type, $unequipTypes)) {
$itemForPosition->update(['equipped' => false]);
$itemForPosition = $inventory->slots->filter(function ($slot) {
return $slot->position === $this->request['position'] && $slot->equipped;
})->first();

$this->character->inventory->slots()->create([
'inventory_id' => $this->character->inventory->id,
'item_id' => $itemForPosition->item->id,
]);
if (!is_null($itemForPosition)) {
$itemForPosition->update(['equipped' => false]);

$itemForPosition->delete();
$this->character->inventory->slots()->create([
'inventory_id' => $this->character->inventory->id,
'item_id' => $itemForPosition->item->id,
]);

return true;
}
$itemForPosition->delete();
}
}

return false;
}

/**
* Unequips both hands.
* Unequip both hands.
*
* @return void
*/
public function unequipBothHands() {
$slots = $this->character->inventory->slots->filter(function ($slot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,10 @@ public function testFetchEquippedSetWithNoName() {

$this->assertNotEmpty($this->characterInventoryService->setCharacter($character)->fetchEquipped());
}

public function testFetchEquippedReturnsNull() {
$character = $this->character->inventorySetManagement()->createInventorySets()->getCharacter();

$this->assertNull($this->characterInventoryService->setCharacter($character)->fetchEquipped());
}
}
Loading

0 comments on commit 5cb5627

Please sign in to comment.