Passed
Pull Request — master (#1801)
by Nico
23:50
created

RageBehaviour   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 49
dl 0
loc 97
ccs 55
cts 55
cp 1
rs 10
c 3
b 0
f 1
wmc 13

4 Methods

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