Passed
Push — dev ( b2109c...60db09 )
by Janko
10:33
created

AssaultPhalanxBehaviour   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Test Coverage

Coverage 2.86%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 62
dl 0
loc 130
ccs 2
cts 70
cp 0.0286
rs 10
c 1
b 0
f 0
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getBoardingPirateWrapper() 0 17 2
A sendPms() 0 16 1
A __construct() 0 14 1
B action() 0 73 5
1
<?php
2
3
namespace Stu\Lib\Pirate\Behaviour;
4
5
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use RuntimeException;
7
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
8
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
9
use Stu\Lib\Map\DistanceCalculationInterface;
10
use Stu\Lib\Pirate\Component\PirateNavigationInterface;
11
use Stu\Lib\Pirate\Component\TrapDetectionInterface;
12
use Stu\Lib\Pirate\PirateBehaviourEnum;
13
use Stu\Lib\Pirate\PirateReactionInterface;
14
use Stu\Lib\Pirate\PirateReactionMetadata;
15
use Stu\Module\Logging\LoggerUtilFactoryInterface;
16
use Stu\Module\Logging\PirateLoggerInterface;
17
use Stu\Module\Message\Lib\DistributedMessageSenderInterface;
18
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
19
use Stu\Module\PlayerSetting\Lib\UserEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Stu\Module\Ship\Lib\FleetWrapperInterface;
21
use Stu\Module\Ship\Lib\ShipWrapperInterface;
22
use Stu\Module\Spacecraft\Lib\CloseCombat\BoardShipUtilInterface;
23
use Stu\Module\Spacecraft\Lib\CloseCombat\CloseCombatUtilInterface;
24
use Stu\Module\Spacecraft\Lib\Message\MessageCollectionInterface;
25
use Stu\Module\Spacecraft\Lib\Message\MessageFactoryInterface;
26
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
27
use Stu\Orm\Entity\SpacecraftInterface;
28
use Stu\Orm\Entity\StationInterface;
29
use Stu\Orm\Repository\StationRepositoryInterface;
30
31
class AssaultPhalanxBehaviour implements PirateBehaviourInterface
32
{
33
    private PirateLoggerInterface $logger;
34
35 1
    public function __construct(
36
        private StationRepositoryInterface $stationRepository,
37
        private DistanceCalculationInterface $distanceCalculation,
38
        private PirateNavigationInterface $pirateNavigation,
39
        private CloseCombatUtilInterface $closeCombatUtil,
40
        private BoardShipUtilInterface $boardShip,
41
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
42
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
43
        private TrapDetectionInterface $trapDetection,
44
        private MessageFactoryInterface $messageFactory,
45
        private DistributedMessageSenderInterface $distributedMessageSender,
46
        LoggerUtilFactoryInterface $loggerUtilFactory
47
    ) {
48 1
        $this->logger = $loggerUtilFactory->getPirateLogger();
49
    }
50
51
    #[Override]
52
    public function action(
53
        FleetWrapperInterface $fleet,
54
        PirateReactionInterface $pirateReaction,
55
        PirateReactionMetadata $reactionMetadata,
56
        ?SpacecraftInterface $triggerSpacecraft
57
    ): ?PirateBehaviourEnum {
58
        $leadWrapper = $fleet->getLeadWrapper();
59
        $leadShip = $leadWrapper->get();
60
61
        $targets = $this->stationRepository->getPiratePhalanxTargets($leadShip);
62
63
        $this->logger->log(sprintf('    %d targets in reach', count($targets)));
64
65
        $filteredTargets = array_filter(
66
            $targets,
67
            fn(StationInterface $target): bool =>
68
            !$this->trapDetection->isAlertTrap($target->getLocation(), $leadShip)
69
        );
70
71
        $this->logger->log(sprintf('    %d filtered targets in reach', count($filteredTargets)));
72
73
        if ($filteredTargets === []) {
74
            return null;
75
        }
76
77
        usort(
78
            $filteredTargets,
79
            fn(StationInterface $a, StationInterface $b): int =>
80
            $this->distanceCalculation->shipToShipDistance($leadShip, $a) - $this->distanceCalculation->shipToShipDistance($leadShip, $b)
81
        );
82
83
        $closestPhalanx = current($filteredTargets);
84
85
        if ($this->pirateNavigation->navigateToTarget($fleet, $closestPhalanx->getLocation())) {
86
87
            $boardingWrapper = $this->getBoardingPirateWrapper($fleet);
88
            $boardingShip = $boardingWrapper->get();
89
90
            $this->spacecraftSystemManager->deactivate($boardingWrapper, SpacecraftSystemTypeEnum::SHIELDS, true);
91
92
            $combatGroupAttacker = $this->closeCombatUtil->getCombatGroup($boardingShip);
93
            $combatGroupDefender = $this->closeCombatUtil->getCombatGroup($closestPhalanx);
94
95
            $messages = $this->messageFactory->createMessageCollection();
96
            $message = $this->messageFactory->createMessage(UserEnum::USER_NPC_KAZON, $closestPhalanx->getUser()->getId(), [sprintf(
97
                'Das Piratenschiff %s entsendet ein Enterkommando auf die %s',
98
                $boardingShip->getName(),
99
                $closestPhalanx->getName()
100
            )]);
101
102
            $messages->add($message);
103
104
            while (!empty($combatGroupAttacker) && !empty($combatGroupDefender)) {
105
106
                $this->logger->logf('    %d vs %d', count($combatGroupAttacker), count($combatGroupDefender));
107
108
                $this->boardShip->cycleKillRound(
109
                    $combatGroupAttacker,
110
                    $combatGroupDefender,
111
                    $boardingWrapper,
112
                    $this->spacecraftWrapperFactory->wrapStation($closestPhalanx),
113
                    $messages
114
                );
115
            }
116
117
            $this->sendPms(
118
                $closestPhalanx->getSectorString(),
119
                $messages
120
            );
121
        }
122
123
        return null;
124
    }
125
126
    private function getBoardingPirateWrapper(FleetWrapperInterface $fleetWrapper): ShipWrapperInterface
127
    {
128
129
        $pirateWrapperArray = $fleetWrapper->getShipWrappers()->toArray();
130
131
        usort(
132
            $pirateWrapperArray,
133
            fn(ShipWrapperInterface $a, ShipWrapperInterface $b): int =>
134
            $b->get()->getCrewCount() - $a->get()->getCrewCount()
135
        );
136
137
        $pirateShipWithMostCrew = current($pirateWrapperArray);
138
        if ($pirateShipWithMostCrew === false) {
139
            throw new RuntimeException('this should not happen');
140
        }
141
142
        return $pirateShipWithMostCrew;
143
    }
144
145
    private function sendPms(
146
        string $sectorString,
147
        MessageCollectionInterface $messageCollection
148
    ): void {
149
150
        $header = sprintf(
151
            "Plünderung in Sektor %s",
152
            $sectorString
153
        );
154
155
        $this->distributedMessageSender->distributeMessageCollection(
156
            $messageCollection,
157
            UserEnum::USER_NPC_KAZON,
158
            PrivateMessageFolderTypeEnum::SPECIAL_STATION,
159
            $header,
160
            true
161
        );
162
    }
163
}
164