Test Failed
Pull Request — dev (#1952)
by Janko
02:59
created

AssaultPhalanxBehaviour::checkUplinkStatus()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 41
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 25
c 1
b 0
f 0
nc 9
nop 1
dl 0
loc 41
ccs 0
cts 27
cp 0
crap 72
rs 8.4444
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\Information\InformationWrapper;
10
use Stu\Lib\Map\DistanceCalculationInterface;
11
use Stu\Lib\Pirate\Component\PirateNavigationInterface;
12
use Stu\Lib\Pirate\Component\TrapDetectionInterface;
13
use Stu\Lib\Pirate\PirateBehaviourEnum;
14
use Stu\Lib\Pirate\PirateReactionInterface;
15
use Stu\Lib\Pirate\PirateReactionMetadata;
16
use Stu\Module\Logging\LoggerUtilFactoryInterface;
17
use Stu\Module\Logging\PirateLoggerInterface;
18
use Stu\Module\Message\Lib\DistributedMessageSenderInterface;
19
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
20
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...
21
use Stu\Module\Ship\Lib\FleetWrapperInterface;
22
use Stu\Module\Ship\Lib\ShipWrapperInterface;
23
use Stu\Module\Spacecraft\Lib\Battle\SpacecraftAttackCoreInterface;
24
use Stu\Module\Spacecraft\Lib\CloseCombat\BoardShipUtilInterface;
25
use Stu\Module\Spacecraft\Lib\CloseCombat\CloseCombatUtilInterface;
26
use Stu\Module\Spacecraft\Lib\Message\MessageCollectionInterface;
27
use Stu\Module\Spacecraft\Lib\Message\MessageFactoryInterface;
28
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
29
use Stu\Orm\Entity\Spacecraft;
30
use Stu\Orm\Entity\Station;
31
use Stu\Orm\Repository\StationRepositoryInterface;
32
33
class AssaultPhalanxBehaviour implements PirateBehaviourInterface
34
{
35
    private PirateLoggerInterface $logger;
36
37
    public function __construct(
38
        private StationRepositoryInterface $stationRepository,
39 1
        private DistanceCalculationInterface $distanceCalculation,
40
        private PirateNavigationInterface $pirateNavigation,
41
        private SpacecraftAttackCoreInterface $spacecraftAttackCore,
42
        private CloseCombatUtilInterface $closeCombatUtil,
43
        private BoardShipUtilInterface $boardShip,
44
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
45
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
46
        private TrapDetectionInterface $trapDetection,
47
        private MessageFactoryInterface $messageFactory,
48
        private DistributedMessageSenderInterface $distributedMessageSender,
49
        LoggerUtilFactoryInterface $loggerUtilFactory
50
    ) {
51
        $this->logger = $loggerUtilFactory->getPirateLogger();
52
    }
53
54 1
    #[Override]
55
    public function action(
56
        FleetWrapperInterface $fleet,
57
        PirateReactionInterface $pirateReaction,
58
        PirateReactionMetadata $reactionMetadata,
59
        ?Spacecraft $triggerSpacecraft
60
    ): ?PirateBehaviourEnum {
61
62
        $leadWrapper = $fleet->getLeadWrapper();
63
        $leadShip = $leadWrapper->get();
64
65
        $targets = $this->stationRepository->getPiratePhalanxTargets($leadWrapper);
66
67
        $this->logger->log(sprintf('    %d targets in reach', count($targets)));
68
69
        $filteredTargets = array_filter(
70
            $targets,
71
            fn(Station $target): bool =>
72
            !$this->trapDetection->isAlertTrap($target->getLocation(), $leadShip)
73
        );
74
75
        $this->logger->log(sprintf('    %d filtered targets in reach', count($filteredTargets)));
76
77
        if ($filteredTargets === []) {
78
            return null;
79
        }
80
81
        usort(
82
            $filteredTargets,
83
            fn(Station $a, Station $b): int =>
84
            $this->distanceCalculation->shipToShipDistance($leadShip, $a) - $this->distanceCalculation->shipToShipDistance($leadShip, $b)
85
        );
86
87
        $isFleetFight = false;
88
        $informations = new InformationWrapper();
89
90
        /** @var Station */
91
        $closestPhalanx = current($filteredTargets);
92
        $phalanxWrapper = $this->spacecraftWrapperFactory->wrapStation($closestPhalanx);
93
94
        if (!$this->pirateNavigation->navigateToTarget($fleet, $closestPhalanx->getLocation())) {
95
            return null;
96
        }
97
98
        // take down shields only
99
        while ($closestPhalanx->isShielded()) {
100
            $this->spacecraftAttackCore->attack($leadWrapper, $phalanxWrapper, true, $isFleetFight, $informations);
101
        }
102
103
        if ($closestPhalanx->getCondition()->isDestroyed()) {
104
            return null;
105
        }
106
107
        $boardingWrapper = $this->getBoardingPirateWrapper($fleet);
108
        $boardingShip = $boardingWrapper->get();
109
110
        $this->spacecraftSystemManager->deactivate($boardingWrapper, SpacecraftSystemTypeEnum::SHIELDS, true);
111
112
        $combatGroupAttacker = $this->closeCombatUtil->getCombatGroup($boardingShip);
113
        $combatGroupDefender = $this->closeCombatUtil->getCombatGroup($closestPhalanx);
114
115
        $messages = $this->messageFactory->createMessageCollection();
116
        $message = $this->messageFactory->createMessage(UserConstants::USER_NPC_KAZON, $closestPhalanx->getUser()->getId(), [sprintf(
117
            'Das Piratenschiff %s entsendet ein Enterkommando auf die %s',
118
            $boardingShip->getName(),
119
            $closestPhalanx->getName()
120
        )]);
121
122
        $messages->add($message);
123
124
        while ($combatGroupAttacker !== [] && $combatGroupDefender !== []) {
125
126
            $this->logger->logf('    %d vs %d', count($combatGroupAttacker), count($combatGroupDefender));
127
128
            $this->boardShip->cycleKillRound(
129
                $combatGroupAttacker,
130
                $combatGroupDefender,
131
                $boardingWrapper,
132
                $phalanxWrapper,
133
                $messages
134
            );
135
        }
136
137
        $this->sendPms(
138
            $closestPhalanx->getSectorString(),
139
            $messages
140
        );
141
142
        return null;
143
    }
144
145
    private function getBoardingPirateWrapper(FleetWrapperInterface $fleetWrapper): ShipWrapperInterface
146
    {
147
148
        $pirateWrapperArray = $fleetWrapper->getShipWrappers()->toArray();
149
150
        usort(
151
            $pirateWrapperArray,
152
            fn(ShipWrapperInterface $a, ShipWrapperInterface $b): int =>
153
            $b->get()->getCrewCount() - $a->get()->getCrewCount()
154
        );
155
156
        $pirateShipWithMostCrew = current($pirateWrapperArray);
157
        if ($pirateShipWithMostCrew === false) {
158
            throw new RuntimeException('this should not happen');
159
        }
160
161
        return $pirateShipWithMostCrew;
162
    }
163
164
    private function sendPms(
165
        string $sectorString,
166
        MessageCollectionInterface $messageCollection
167
    ): void {
168
169
        $header = sprintf(
170
            "Plünderung in Sektor %s",
171
            $sectorString
172
        );
173
174
        $this->distributedMessageSender->distributeMessageCollection(
175
            $messageCollection,
176
            UserConstants::USER_NPC_KAZON,
177
            PrivateMessageFolderTypeEnum::SPECIAL_STATION,
178
            $header,
179
            true
180
        );
181
    }
182
}
183