Passed
Push — master ( db7b85...c86096 )
by Nico
49:13 queued 24:57
created

CallForSupportBehaviour   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 50
c 6
b 0
f 0
dl 0
loc 98
ccs 0
cts 58
cp 0
rs 10
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A action() 0 17 1
B getSupportFleet() 0 50 6
A createSupportFleet() 0 11 1
1
<?php
2
3
namespace Stu\Lib\Pirate\Behaviour;
4
5
use RuntimeException;
6
use Stu\Lib\Map\DistanceCalculationInterface;
7
use Stu\Lib\Pirate\Component\PirateNavigationInterface;
8
use Stu\Lib\Pirate\Component\ReloadMinimalEpsInterface;
9
use Stu\Lib\Pirate\PirateBehaviourEnum;
10
use Stu\Lib\Pirate\PirateCreationInterface;
11
use Stu\Module\Ship\Lib\FleetWrapperInterface;
12
use Stu\Lib\Pirate\PirateReactionInterface;
13
use Stu\Lib\Pirate\PirateReactionTriggerEnum;
14
use Stu\Module\Logging\LoggerUtilFactoryInterface;
15
use Stu\Module\Logging\PirateLoggerInterface;
16
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
17
use Stu\Orm\Entity\FleetInterface;
18
use Stu\Orm\Entity\ShipInterface;
19
use Stu\Orm\Repository\ShipRepositoryInterface;
20
21
class CallForSupportBehaviour implements PirateBehaviourInterface
22
{
23
    private PirateLoggerInterface $logger;
24
25
    public function __construct(
26
        private ShipRepositoryInterface $shipRepository,
27
        private PirateCreationInterface $pirateCreation,
28
        private DistanceCalculationInterface $distanceCalculation,
29
        private ReloadMinimalEpsInterface $reloadMinimalEps,
30
        private PirateNavigationInterface $pirateNavigation,
31
        private ShipWrapperFactoryInterface $shipWrapperFactory,
32
        LoggerUtilFactoryInterface $loggerUtilFactory
33
    ) {
34
        $this->logger = $loggerUtilFactory->getPirateLogger();
35
    }
36
37
    public function action(
38
        FleetWrapperInterface $fleet,
39
        PirateReactionInterface $pirateReaction,
40
        ?ShipInterface $triggerShip
41
    ): ?PirateBehaviourEnum {
42
        $leadWrapper = $fleet->getLeadWrapper();
43
        $leadShip = $leadWrapper->get();
44
45
        $supportFleet = $this->getSupportFleet($leadShip);
46
47
        $pirateReaction->react(
48
            $supportFleet,
49
            PirateReactionTriggerEnum::ON_SUPPORT_CALL,
50
            $leadShip
51
        );
52
53
        return null;
54
    }
55
56
    private function getSupportFleet(ShipInterface $leadShip): FleetInterface
57
    {
58
        $friends = $this->shipRepository->getPirateFriends($leadShip);
59
60
        $filteredFriends = array_filter(
61
            $friends,
62
            fn (ShipInterface $friend) =>
63
            !$friend->isDestroyed()
64
                && $friend->isFleetLeader()
65
                && $friend->getCurrentMapField() !== $leadShip->getCurrentMapField()
66
        );
67
68
        usort(
69
            $filteredFriends,
70
            fn (ShipInterface $a, ShipInterface $b) =>
71
            $this->distanceCalculation->shipToShipDistance($leadShip, $a) - $this->distanceCalculation->shipToShipDistance($leadShip, $b)
72
        );
73
74
        $closestFriend = current($filteredFriends);
75
        if (!$closestFriend) {
76
            return $this->createSupportFleet($leadShip);
77
        }
78
79
        $supportFleet = $closestFriend->getFleet();
80
        if ($supportFleet === null) {
81
            throw new RuntimeException('pirate ships should always be in fleet');
82
        }
83
84
        $this->logger->logf(
85
            '    calling already existing support fleet %s (%d) to %s',
86
            $supportFleet->getId(),
87
            $supportFleet->getName(),
88
            $leadShip->getSectorString()
89
        );
90
91
        $fleetWrapper = $this->shipWrapperFactory->wrapFleet($supportFleet);
92
93
        $this->reloadMinimalEps->reload($fleetWrapper, 75);
94
        if (!$this->pirateNavigation->navigateToTarget($fleetWrapper, $leadShip->getCurrentMapField())) {
95
            return $this->createSupportFleet($leadShip);
96
        }
97
98
        $this->logger->logf(
99
            '    already existing support fleet (%d) "%s" reached here %s',
100
            $supportFleet->getId(),
101
            $supportFleet->getName(),
102
            $supportFleet->getLeadShip()->getSectorString()
103
        );
104
105
        return $supportFleet;
106
    }
107
108
    private function createSupportFleet(ShipInterface $leadShip): FleetInterface
109
    {
110
        $supportFleet = $this->pirateCreation->createPirateFleet($leadShip);
111
        $this->logger->logf(
112
            '    created support fleet %d "%s" here %s',
113
            $supportFleet->getId(),
114
            $supportFleet->getName(),
115
            $supportFleet->getLeadShip()->getSectorString()
116
        );
117
118
        return $supportFleet;
119
    }
120
}
121