Passed
Push — master ( df7727...a665f8 )
by Paweł
03:01
created

FightEvent::loot()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 15
c 0
b 0
f 0
dl 0
loc 27
ccs 0
cts 16
cp 0
rs 9.7666
cc 4
nc 4
nop 3
crap 20
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AardsGerds\Game\Event;
6
7
use AardsGerds\Game\Build\Experience;
8
use AardsGerds\Game\Entity\Entity;
9
use AardsGerds\Game\Entity\EntityCollection;
10
use AardsGerds\Game\Event\Decision\Decision;
11
use AardsGerds\Game\Event\Decision\DecisionCollection;
12
use AardsGerds\Game\Fight\Fight;
13
use AardsGerds\Game\Fight\FighterCollection;
14
use AardsGerds\Game\Inventory\Inventory;
15
use AardsGerds\Game\Player\Player;
16
use AardsGerds\Game\Player\PlayerAction;
17
use function Lambdish\Phunctional\map;
18
19
abstract class FightEvent extends Event
20
{
21
    public function __construct(
22
        Context $context,
23
        DecisionCollection $decisionCollection,
24
        protected EntityCollection $subjects,
25
        protected Experience $experience,
26
    ) {
27
        parent::__construct(
28
            $context,
29
            $decisionCollection,
30
        );
31
    }
32
33
    public function __invoke(Player $player, PlayerAction $playerAction): Decision
34
    {
35
        $playerAction->tell((string) $this->context);
36
37
        (new Fight($player, new FighterCollection($this->subjects), $playerAction))();
38
39
        $player->increaseExperience($this->experience, $playerAction);
40
41
        $loot = $playerAction->askForConfirmation('Do you want to loot?');
42
        if ($loot) {
43
            $lootInventory = new Inventory(
44
                array_merge(...map(
45
                    static fn(Entity $subject): array => $subject->getInventory()->getItems(),
46
                    $this->subjects,
47
                )),
48
            );
49
50
            $this->loot($player, $playerAction, $lootInventory);
51
        }
52
53
        return $playerAction->askForDecision(
54
            "Fight is over. What's next?",
55
            $this->decisionCollection,
56
        );
57
    }
58
59
    private function loot(Player $player, PlayerAction $playerAction, Inventory $lootInventory): void
60
    {
61
        $playerAction->listInventory($lootInventory);
62
63
        $choice = $playerAction->askForChoice(
64
            'Your choice',
65
            array_merge($lootInventory->getItems(), ['Take all', 'Leave']),
66
        );
67
68
        if ($choice === 'Leave') {
69
            return;
70
        }
71
72
        if ($choice === 'Take all') {
73
            $player->getInventory()->addMany(...$lootInventory->getItems());
74
            $playerAction->tell('You have obtained some new items');
75
76
            return;
77
        }
78
79
        $player->getInventory()->add($choice);
80
        $lootInventory->remove($choice);
81
82
        $playerAction->tell("You have obtained {$choice}");
83
84
        if (!$lootInventory->isEmpty()) {
85
            $this->loot($player, $playerAction, $lootInventory);
86
        }
87
    }
88
}
89