Passed
Pull Request — master (#1779)
by Nico
49:51 queued 23:55
created

RageBehaviour::action()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 35
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 21
nc 2
nop 2
dl 0
loc 35
ccs 24
cts 24
cp 1
crap 3
rs 9.584
c 1
b 0
f 1
1
<?php
2
3
namespace Stu\Lib\Pirate\Behaviour;
4
5
use Stu\Lib\Information\InformationWrapper;
6
use Stu\Lib\Pirate\PirateReactionInterface;
7
use Stu\Lib\Pirate\PirateReactionTriggerEnum;
8
use Stu\Module\Logging\LoggerUtilFactoryInterface;
9
use Stu\Module\Logging\LoggerUtilInterface;
10
use Stu\Module\Ship\Lib\Battle\FightLibInterface;
11
use Stu\Module\Ship\Lib\Battle\ShipAttackCoreInterface;
12
use Stu\Module\Ship\Lib\FleetWrapperInterface;
13
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
14
use Stu\Module\Ship\Lib\Interaction\InteractionCheckerInterface;
15
use Stu\Orm\Entity\ShipInterface;
16
use Stu\Orm\Repository\ShipRepositoryInterface;
17
18
class RageBehaviour implements PirateBehaviourInterface
19
{
20
    private ShipRepositoryInterface $shipRepository;
21
22
    private InteractionCheckerInterface $interactionChecker;
23
24
    private FightLibInterface $fightLib;
25
26
    private ShipAttackCoreInterface $shipAttackCore;
27
28
    private ShipWrapperFactoryInterface $shipWrapperFactory;
29
30
    private LoggerUtilInterface $logger;
31
32 5
    public function __construct(
33
        ShipRepositoryInterface $shipRepository,
34
        InteractionCheckerInterface $interactionChecker,
35
        FightLibInterface $fightLib,
36
        ShipAttackCoreInterface $shipAttackCore,
37
        ShipWrapperFactoryInterface $shipWrapperFactory,
38
        LoggerUtilFactoryInterface $loggerUtilFactory
39
    ) {
40 5
        $this->shipRepository = $shipRepository;
41 5
        $this->interactionChecker = $interactionChecker;
42 5
        $this->fightLib = $fightLib;
43 5
        $this->shipAttackCore = $shipAttackCore;
44 5
        $this->shipWrapperFactory = $shipWrapperFactory;
45
46 5
        $this->logger = $loggerUtilFactory->getLoggerUtil();
47
    }
48
49 5
    public function action(FleetWrapperInterface $fleet, PirateReactionInterface $pirateReaction): void
50
    {
51 5
        $leadWrapper = $fleet->getLeadWrapper();
52 5
        $leadShip = $leadWrapper->get();
53
54 5
        $targets = $this->shipRepository->getPirateTargets($leadShip);
55
56 5
        $this->logger->log(sprintf('    %d targets in reach', count($targets)));
57
58 5
        $filteredTargets = array_filter(
59 5
            $targets,
60 5
            fn (ShipInterface $target) =>
61 4
            $this->interactionChecker->checkPosition($leadShip, $target)
62 4
                && $this->fightLib->canAttackTarget($leadShip, $target, false)
63 5
        );
64
65 5
        $this->logger->log(sprintf('    %d filtered targets in reach', count($filteredTargets)));
66
67 5
        if (empty($filteredTargets)) {
68 3
            return;
69
        }
70
71 2
        usort(
72 2
            $filteredTargets,
73 2
            fn (ShipInterface $a, ShipInterface $b) =>
74 1
            $this->calculateHealthPercentage($a) -  $this->calculateHealthPercentage($b)
75 2
        );
76
77 2
        $weakestTarget = current($filteredTargets);
78
79 2
        $this->attackShip($fleet, $weakestTarget);
80
81 2
        $pirateReaction->react(
82 2
            $fleet->get(),
83 2
            PirateReactionTriggerEnum::ON_RAGE
84 2
        );
85
    }
86
87 1
    private function calculateHealthPercentage(ShipInterface $target): int
88
    {
89 1
        $shipCount = 0;
90 1
        $healthSum = 0;
91
92 1
        $fleet = $target->getFleet();
93 1
        if ($fleet !== null) {
94 1
            foreach ($fleet->getShips() as $ship) {
95 1
                $shipCount++;
96 1
                $healthSum += $ship->getHealthPercentage();
97
            }
98
        } else {
99 1
            $shipCount++;
100 1
            $healthSum += $target->getHealthPercentage();
101
        }
102
103 1
        return (int)($healthSum / $shipCount);
104
    }
105
106 2
    private function attackShip(FleetWrapperInterface $fleetWrapper, ShipInterface $target): void
107
    {
108 2
        $leadWrapper = $fleetWrapper->getLeadWrapper();
109 2
        $isFleetFight = false;
110 2
        $informations = new InformationWrapper();
111
112 2
        $this->shipAttackCore->attack(
113 2
            $leadWrapper,
114 2
            $this->shipWrapperFactory->wrapShip($target),
115 2
            $isFleetFight,
116 2
            $informations
117 2
        );
118
    }
119
}
120