Passed
Push — dev ( dc1a8e...52c71a )
by Nico
05:53
created

AssaultPhalanxBehaviour::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 13
dl 0
loc 16
ccs 2
cts 2
cp 1
crap 1
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\SpacecraftSystemModeEnum;
9
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
10
use Stu\Lib\Information\InformationWrapper;
11
use Stu\Lib\Map\DistanceCalculationInterface;
12
use Stu\Lib\Pirate\Component\PirateNavigationInterface;
13
use Stu\Lib\Pirate\Component\TrapDetectionInterface;
14
use Stu\Lib\Pirate\PirateBehaviourEnum;
15
use Stu\Lib\Pirate\PirateReactionInterface;
16
use Stu\Lib\Pirate\PirateReactionMetadata;
17
use Stu\Module\Logging\LoggerUtilFactoryInterface;
18
use Stu\Module\Logging\PirateLoggerInterface;
19
use Stu\Module\Message\Lib\DistributedMessageSenderInterface;
20
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
21
use Stu\Module\PlayerSetting\Lib\UserConstants;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserConstants 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...
22
use Stu\Module\Ship\Lib\FleetWrapperInterface;
23
use Stu\Module\Ship\Lib\ShipWrapperInterface;
24
use Stu\Module\Spacecraft\Lib\Crew\TroopTransferUtilityInterface;
25
use Stu\Module\Spacecraft\Lib\Battle\SpacecraftAttackCoreInterface;
26
use Stu\Module\Spacecraft\Lib\CloseCombat\BoardShipUtilInterface;
27
use Stu\Module\Spacecraft\Lib\CloseCombat\CloseCombatUtilInterface;
28
use Stu\Module\Spacecraft\Lib\Message\MessageCollectionInterface;
29
use Stu\Module\Spacecraft\Lib\Message\MessageFactoryInterface;
30
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
31
use Stu\Orm\Entity\Spacecraft;
32
use Stu\Orm\Entity\Station;
33
use Stu\Orm\Repository\StationRepositoryInterface;
34
35
class AssaultPhalanxBehaviour implements PirateBehaviourInterface
36
{
37
    private PirateLoggerInterface $logger;
38
39 1
    public function __construct(
40
        private StationRepositoryInterface $stationRepository,
41
        private DistanceCalculationInterface $distanceCalculation,
42
        private PirateNavigationInterface $pirateNavigation,
43
        private SpacecraftAttackCoreInterface $spacecraftAttackCore,
44
        private CloseCombatUtilInterface $closeCombatUtil,
45
        private BoardShipUtilInterface $boardShip,
46
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
47
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
48
        private TrapDetectionInterface $trapDetection,
49
        private MessageFactoryInterface $messageFactory,
50
        private DistributedMessageSenderInterface $distributedMessageSender,
51
        private TroopTransferUtilityInterface $troopTransferUtility,
52
        LoggerUtilFactoryInterface $loggerUtilFactory
53
    ) {
54 1
        $this->logger = $loggerUtilFactory->getPirateLogger();
55
    }
56
57
    #[Override]
58
    public function action(
59
        FleetWrapperInterface $fleet,
60
        PirateReactionInterface $pirateReaction,
61
        PirateReactionMetadata $reactionMetadata,
62
        ?Spacecraft $triggerSpacecraft
63
    ): ?PirateBehaviourEnum {
64
65
        $leadWrapper = $fleet->getLeadWrapper();
66
        $leadShip = $leadWrapper->get();
67
68
        $targets = $this->stationRepository->getPiratePhalanxTargets($leadWrapper);
69
70
        $this->logger->log(sprintf('    %d targets in reach', count($targets)));
71
72
        $filteredTargets = array_filter(
73
            $targets,
74
            fn(Station $target): bool =>
75
            !$this->trapDetection->isAlertTrap($target->getLocation(), $leadShip)
76
        );
77
78
        $this->logger->log(sprintf('    %d filtered targets in reach', count($filteredTargets)));
79
80
        if ($filteredTargets === []) {
81
            return null;
82
        }
83
84
        usort(
85
            $filteredTargets,
86
            fn(Station $a, Station $b): int =>
87
            $this->distanceCalculation->shipToShipDistance($leadShip, $a) - $this->distanceCalculation->shipToShipDistance($leadShip, $b)
88
        );
89
90
        $isFleetFight = false;
91
        $informations = new InformationWrapper();
92
93
        /** @var Station */
94
        $closestPhalanx = current($filteredTargets);
95
        $phalanxWrapper = $this->spacecraftWrapperFactory->wrapStation($closestPhalanx);
96
97
        if (!$this->pirateNavigation->navigateToTarget($fleet, $closestPhalanx->getLocation())) {
98
            return null;
99
        }
100
101
        // take down shields only
102
        while ($closestPhalanx->isShielded()) {
103
            $this->spacecraftAttackCore->attack($leadWrapper, $phalanxWrapper, true, $isFleetFight, $informations);
104
        }
105
106
        if ($closestPhalanx->getCondition()->isDestroyed()) {
107
            return null;
108
        }
109
110
        $boardingWrapper = $this->getBoardingPirateWrapper($fleet);
111
        $boardingShip = $boardingWrapper->get();
112
113
        $this->spacecraftSystemManager->deactivate($boardingWrapper, SpacecraftSystemTypeEnum::SHIELDS, true);
114
115
        $combatGroupAttacker = $this->closeCombatUtil->getCombatGroup($boardingShip);
116
        $combatGroupDefender = $this->closeCombatUtil->getCombatGroup($closestPhalanx);
117
118
        $messages = $this->messageFactory->createMessageCollection();
119
        $message = $this->messageFactory->createMessage(UserConstants::USER_NPC_KAZON, $closestPhalanx->getUser()->getId(), [sprintf(
120
            'Das Piratenschiff %s entsendet ein Enterkommando auf die %s',
121
            $boardingShip->getName(),
122
            $closestPhalanx->getName()
123
        )]);
124
125
        $messages->add($message);
126
127
        while ($combatGroupAttacker !== [] && $combatGroupDefender !== []) {
128
129
            $this->logger->logf('    %d vs %d', count($combatGroupAttacker), count($combatGroupDefender));
130
131
            $this->boardShip->cycleKillRound(
132
                $combatGroupAttacker,
133
                $combatGroupDefender,
134
                $boardingWrapper,
135
                $phalanxWrapper,
136
                $messages
137
            );
138
        }
139
140
        // Check uplink status after combat
141
        $uplinkMessages = $this->checkUplinkStatus($phalanxWrapper);
142
143
        // Füge die Uplink-Meldungen zur Nachrichtensammlung hinzu
144
        if (!empty($uplinkMessages)) {
145
            // Erstelle eine einzige Nachricht mit allen Uplink-Meldungen
146
            $message = $this->messageFactory->createMessage(
147
                UserConstants::USER_NPC_KAZON,
148
                $closestPhalanx->getUser()->getId(),
149
                $uplinkMessages
150
            );
151
            $messages->add($message);
152
        }
153
154
        // Send messages including combat results and uplink status
155
        $this->sendPms(
156
            $closestPhalanx->getSectorString(),
157
            $messages
158
        );
159
160
        return null;
161
    }
162
163
    private function getBoardingPirateWrapper(FleetWrapperInterface $fleetWrapper): ShipWrapperInterface
164
    {
165
166
        $pirateWrapperArray = $fleetWrapper->getShipWrappers()->toArray();
167
168
        usort(
169
            $pirateWrapperArray,
170
            fn(ShipWrapperInterface $a, ShipWrapperInterface $b): int =>
171
            $b->get()->getCrewCount() - $a->get()->getCrewCount()
172
        );
173
174
        $pirateShipWithMostCrew = current($pirateWrapperArray);
175
        if ($pirateShipWithMostCrew === false) {
176
            throw new RuntimeException('this should not happen');
177
        }
178
179
        return $pirateShipWithMostCrew;
180
    }
181
182
    /**
183
     * @return array<string>
184
     */
185
    private function checkUplinkStatus(\Stu\Module\Station\Lib\StationWrapperInterface $wrapper): array
186
    {
187
        $spacecraft = $wrapper->get();
188
        $messages = [];
189
190
        // Check if uplink system exists and is active
191
        if (!$spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::UPLINK)) {
192
            return $messages;
193
        }
194
195
        $hasForeigners = $this->troopTransferUtility->foreignerCount($spacecraft) > 0;
196
        $ownCrewCount = $this->getOwnCrewCount($spacecraft);
197
        $minOwnCrew = 0;
198
199
        $buildplan = $spacecraft->getBuildplan();
200
        if ($buildplan !== null) {
201
            $minOwnCrew = $buildplan->getCrew();
202
        }
203
204
        // Deactivate uplink if no foreigners left
205
        if (!$hasForeigners && $spacecraft->getSystemState(SpacecraftSystemTypeEnum::UPLINK)) {
206
            $spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::UPLINK)->setMode(SpacecraftSystemModeEnum::MODE_OFF);
207
            $message = sprintf('Der Uplink der %s wurde deaktiviert, da sich keine fremden Crewmitglieder mehr an Bord befinden', $spacecraft->getName());
208
            $this->logger->log($message);
209
            $messages[] = $message;
210
        }
211
212
        // Deactivate uplink if not enough own crew
213
        if ($hasForeigners && $spacecraft->getSystemState(SpacecraftSystemTypeEnum::UPLINK) && $ownCrewCount < $minOwnCrew) {
214
            $spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::UPLINK)->setMode(SpacecraftSystemModeEnum::MODE_OFF);
215
            $message = sprintf(
216
                'Der Uplink der %s wurde deaktiviert, da nicht mehr genügend eigene Crewmitglieder an Bord sind (%d/%d)',
217
                $spacecraft->getName(),
218
                $ownCrewCount,
219
                $minOwnCrew
220
            );
221
            $this->logger->log($message);
222
            $messages[] = $message;
223
        }
224
225
        return $messages;
226
    }
227
228
    private function getOwnCrewCount(Spacecraft $spacecraft): int
229
    {
230
        $count = 0;
231
        foreach ($spacecraft->getCrewAssignments() as $spacecraftCrew) {
232
            if ($spacecraftCrew->getCrew()->getUser()->getId() === $spacecraft->getUser()->getId()) {
233
                $count++;
234
            }
235
        }
236
        return $count;
237
    }
238
239
    private function sendPms(
240
        string $sectorString,
241
        MessageCollectionInterface $messageCollection
242
    ): void {
243
244
        $header = sprintf(
245
            "Plünderung in Sektor %s",
246
            $sectorString
247
        );
248
249
        $this->distributedMessageSender->distributeMessageCollection(
250
            $messageCollection,
251
            UserConstants::USER_NPC_KAZON,
252
            PrivateMessageFolderTypeEnum::SPECIAL_STATION,
253
            $header,
254
            true
255
        );
256
    }
257
}
258