Passed
Push — master ( e661f4...30021e )
by Nico
25:16 queued 10:59
created

AssaultPhalanxBehaviour   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 142
Duplicated Lines 0 %

Test Coverage

Coverage 2.67%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 67
dl 0
loc 142
ccs 2
cts 75
cp 0.0267
rs 10
c 1
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getBoardingPirateWrapper() 0 17 2
A sendPms() 0 16 1
A __construct() 0 15 1
B action() 0 84 6
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\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...
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\SpacecraftInterface;
30
use Stu\Orm\Entity\StationInterface;
31
use Stu\Orm\Repository\StationRepositoryInterface;
32
33
class AssaultPhalanxBehaviour implements PirateBehaviourInterface
34
{
35
    private PirateLoggerInterface $logger;
36
37 1
    public function __construct(
38
        private StationRepositoryInterface $stationRepository,
39
        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 1
        $this->logger = $loggerUtilFactory->getPirateLogger();
52
    }
53
54
    #[Override]
55
    public function action(
56
        FleetWrapperInterface $fleet,
57
        PirateReactionInterface $pirateReaction,
58
        PirateReactionMetadata $reactionMetadata,
59
        ?SpacecraftInterface $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(StationInterface $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(StationInterface $a, StationInterface $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 StationInterface */
91
        $closestPhalanx = current($filteredTargets);
92
        $phalanxWrapper = $this->spacecraftWrapperFactory->wrapStation($closestPhalanx);
93
94
        if ($this->pirateNavigation->navigateToTarget($fleet, $closestPhalanx->getLocation())) {
95
96
            // take down shields only
97
            while ($closestPhalanx->isShielded()) {
98
                $this->spacecraftAttackCore->attack($leadWrapper, $phalanxWrapper, true, $isFleetFight, $informations);
99
            }
100
101
            $boardingWrapper = $this->getBoardingPirateWrapper($fleet);
102
            $boardingShip = $boardingWrapper->get();
103
104
            $this->spacecraftSystemManager->deactivate($boardingWrapper, SpacecraftSystemTypeEnum::SHIELDS, true);
105
106
            $combatGroupAttacker = $this->closeCombatUtil->getCombatGroup($boardingShip);
107
            $combatGroupDefender = $this->closeCombatUtil->getCombatGroup($closestPhalanx);
108
109
            $messages = $this->messageFactory->createMessageCollection();
110
            $message = $this->messageFactory->createMessage(UserEnum::USER_NPC_KAZON, $closestPhalanx->getUser()->getId(), [sprintf(
111
                'Das Piratenschiff %s entsendet ein Enterkommando auf die %s',
112
                $boardingShip->getName(),
113
                $closestPhalanx->getName()
114
            )]);
115
116
            $messages->add($message);
117
118
            while (!empty($combatGroupAttacker) && !empty($combatGroupDefender)) {
119
120
                $this->logger->logf('    %d vs %d', count($combatGroupAttacker), count($combatGroupDefender));
121
122
                $this->boardShip->cycleKillRound(
123
                    $combatGroupAttacker,
124
                    $combatGroupDefender,
125
                    $boardingWrapper,
126
                    $phalanxWrapper,
127
                    $messages
128
                );
129
            }
130
131
            $this->sendPms(
132
                $closestPhalanx->getSectorString(),
133
                $messages
134
            );
135
        }
136
137
        return null;
138
    }
139
140
    private function getBoardingPirateWrapper(FleetWrapperInterface $fleetWrapper): ShipWrapperInterface
141
    {
142
143
        $pirateWrapperArray = $fleetWrapper->getShipWrappers()->toArray();
144
145
        usort(
146
            $pirateWrapperArray,
147
            fn(ShipWrapperInterface $a, ShipWrapperInterface $b): int =>
148
            $b->get()->getCrewCount() - $a->get()->getCrewCount()
149
        );
150
151
        $pirateShipWithMostCrew = current($pirateWrapperArray);
152
        if ($pirateShipWithMostCrew === false) {
153
            throw new RuntimeException('this should not happen');
154
        }
155
156
        return $pirateShipWithMostCrew;
157
    }
158
159
    private function sendPms(
160
        string $sectorString,
161
        MessageCollectionInterface $messageCollection
162
    ): void {
163
164
        $header = sprintf(
165
            "Plünderung in Sektor %s",
166
            $sectorString
167
        );
168
169
        $this->distributedMessageSender->distributeMessageCollection(
170
            $messageCollection,
171
            UserEnum::USER_NPC_KAZON,
172
            PrivateMessageFolderTypeEnum::SPECIAL_STATION,
173
            $header,
174
            true
175
        );
176
    }
177
}
178