FightEvent   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 7
eloc 30
c 1
b 0
f 0
dl 0
loc 66
ccs 0
cts 33
cp 0
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A __invoke() 0 22 2
A loot() 0 27 4
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
        if ($playerAction->askForConfirmation('Do you want to loot?')) {
42
            $lootInventory = new Inventory(
43
                array_merge(...map(
44
                    static fn(Entity $subject): array => $subject->getInventory()->getItems(),
45
                    $this->subjects,
46
                )),
47
            );
48
49
            $this->loot($player, $playerAction, $lootInventory);
50
        }
51
52
        return $playerAction->askForDecision(
53
            "Fight is over. What's next?",
54
            $this->decisionCollection,
55
        );
56
    }
57
58
    private function loot(Player $player, PlayerAction $playerAction, Inventory $lootInventory): void
59
    {
60
        $playerAction->listInventory($lootInventory);
61
62
        $choice = $playerAction->askForChoice(
63
            'Your choice',
64
            array_merge($lootInventory->getItems(), ['Take all', 'Leave']),
65
        );
66
67
        if ($choice === 'Leave') {
68
            return;
69
        }
70
71
        if ($choice === 'Take all') {
72
            $player->getInventory()->addMany(...$lootInventory->getItems());
73
            $playerAction->tell('You have obtained some new items');
74
75
            return;
76
        }
77
78
        $player->getInventory()->add($choice);
79
        $lootInventory->remove($choice);
80
81
        $playerAction->tell("You have obtained {$choice}");
82
83
        if (!$lootInventory->isEmpty()) {
84
            $this->loot($player, $playerAction, $lootInventory);
85
        }
86
    }
87
}
88