Passed
Push — dev ( d85471...98511f )
by Janko
18:01
created

ShipMover::leaveFleet()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 2
nc 2
nop 2
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Stu\Module\Spacecraft\Lib\Movement;
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 Stu\Lib\Information\InformationWrapper;
7
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...
8
use Stu\Module\Spacecraft\Lib\Battle\AlertDetection\AlertReactionFacadeInterface;
9
use Stu\Module\Ship\Lib\Fleet\LeaveFleetInterface;
10
use Stu\Module\Ship\Lib\ShipWrapperInterface;
11
use Stu\Module\Spacecraft\Lib\Message\MessageCollectionInterface;
12
use Stu\Module\Spacecraft\Lib\Message\MessageFactoryInterface;
13
use Stu\Module\Spacecraft\Lib\Movement\Route\FlightRouteInterface;
14
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
15
use Stu\Orm\Entity\ShipInterface;
16
use Stu\Orm\Entity\SpacecraftInterface;
17
use Stu\Orm\Repository\SpacecraftRepositoryInterface;
18
19
final class ShipMover implements ShipMoverInterface
20
{
21 4
    public function __construct(
22
        private SpacecraftRepositoryInterface $spacecraftRepository,
23
        private FlightCompanyFactory $flightCompanyFactory,
24
        private ShipMovementInformationAdderInterface $shipMovementInformationAdder,
25
        private LeaveFleetInterface $leaveFleet,
26
        private AlertReactionFacadeInterface $alertReactionFacade,
27
        private MessageFactoryInterface $messageFactory
28 4
    ) {}
29
30 3
    #[Override]
31
    public function checkAndMove(
32
        SpacecraftWrapperInterface $leadWrapper,
33
        FlightRouteInterface $flightRoute
34
    ): MessageCollectionInterface {
35
36 3
        $messages = $this->messageFactory->createMessageCollection();
37
38 3
        $flightCompany = $this->flightCompanyFactory->create($leadWrapper);
39 3
        $initialTractoredShips = $this->initTractoredShips($flightCompany);
40
41
        // fly until destination arrived
42 3
        $hasTravelled = $this->travelFlightRoute(
43 3
            $flightCompany,
44 3
            $flightRoute,
45 3
            $messages
46 3
        );
47
48
        //skip save and log info if flight did not happen
49 3
        if (!$hasTravelled) {
50 1
            return $messages;
51
        }
52
53
        // save all ships
54 2
        $this->saveShips($flightCompany, $initialTractoredShips);
55
56
        // add post flight informations
57 2
        $this->postFlightInformations(
58 2
            $flightCompany,
59 2
            $flightRoute,
60 2
            $messages
61 2
        );
62
63 2
        return $messages;
64
    }
65
66 3
    private function travelFlightRoute(
67
        FlightCompany $flightCompany,
68
        FlightRouteInterface $flightRoute,
69
        MessageCollectionInterface $messages
70
    ): bool {
71
72 3
        $hasTravelled = false;
73
74 3
        while (!$flightRoute->isDestinationArrived()) {
75 3
            $nextWaypoint = $flightRoute->getNextWaypoint();
76
77
            // nächstes Feld nicht passierbar
78 3
            if (!$nextWaypoint->getFieldType()->getPassable()) {
79
                $flightRoute->abortFlight();
80
                $messages->addInformation('Das nächste Feld kann nicht passiert werden');
81
                break;
82
            }
83
84 3
            if (!$flightCompany->isFlightPossible($flightRoute, $messages)) {
85 1
                $flightRoute->abortFlight();
86 1
                break;
87
            }
88
89 2
            if ($flightCompany->hasToLeaveFleet()) {
90
                $this->leaveFleet($flightCompany->getLeader(), $messages);
91
            }
92
93
            /** @var array<array{0: SpacecraftInterface, 1: ShipWrapperInterface}> */
94 2
            $movedTractoredShipWrappers = [];
95
96
            // move every possible ship by one field
97 2
            $this->moveShipsByOneField(
98 2
                $flightCompany,
99 2
                $flightRoute,
100 2
                $movedTractoredShipWrappers,
101 2
                $messages
102 2
            );
103 2
            $hasTravelled = true;
104
105
            // alert reaction check
106 2
            if (!$flightCompany->isEmpty()) {
107 1
                $this->alertReactionCheck(
108 1
                    $flightCompany->getLeadWrapper(),
109 1
                    $movedTractoredShipWrappers,
110 1
                    $messages
111 1
                );
112
            }
113
114 2
            if ($flightCompany->isEmpty()) {
115 1
                $flightRoute->abortFlight();
116
            }
117
        }
118
119 3
        return $hasTravelled;
120
    }
121
122
    /**
123
     * @param array<array{0: SpacecraftInterface, 1: ShipWrapperInterface}> $movedTractoredShipWrappers
124
     */
125 2
    private function moveShipsByOneField(
126
        FlightCompany $flightCompany,
127
        FlightRouteInterface $flightRoute,
128
        array &$movedTractoredShipWrappers,
129
        MessageCollectionInterface $messages
130
    ): void {
131
132 2
        $flightRoute->enterNextWaypoint(
133 2
            $flightCompany,
134 2
            $messages
135 2
        );
136
137 2
        foreach ($flightCompany->getActiveMembers() as $wrapper) {
138
139 2
            $tractoredShipWrapper = $wrapper->getTractoredShipWrapper();
140 2
            if ($tractoredShipWrapper !== null) {
141
                $movedTractoredShipWrappers[] = [$wrapper->get(), $tractoredShipWrapper];
142
            }
143
        }
144
    }
145
146
    /** @param array<array{0: SpacecraftInterface, 1: ShipWrapperInterface}> $movedTractoredShipWrappers */
147 1
    private function alertReactionCheck(
148
        SpacecraftWrapperInterface $leadWrapper,
149
        array $movedTractoredShipWrappers,
150
        MessageCollectionInterface $messages
151
    ): void {
152 1
        $alertRedInformations = new InformationWrapper();
153 1
        $this->alertReactionFacade->doItAll($leadWrapper, $alertRedInformations);
154
155 1
        if (!$alertRedInformations->isEmpty()) {
156
            $this->addInformationMerge($alertRedInformations->getInformations(), $messages);
157
        }
158
159
        // alert red check for tractored ships
160 1
        foreach ($movedTractoredShipWrappers as [$tractoringSpacecraft, $tractoredShipWrapper]) {
161
            if (!$tractoredShipWrapper->get()->isDestroyed()) {
162
                $alertRedInformations = new InformationWrapper();
163
                $this->alertReactionFacade->doItAll(
164
                    $tractoredShipWrapper,
165
                    $alertRedInformations,
166
                    $tractoringSpacecraft
167
                );
168
169
                if (!$alertRedInformations->isEmpty()) {
170
                    $this->addInformationMerge($alertRedInformations->getInformations(), $messages);
171
                }
172
            }
173
        }
174
    }
175
176
    /**
177
     * @return array<ShipInterface>
178
     */
179 3
    private function initTractoredShips(FlightCompany $flightCompany): array
180
    {
181 3
        $tractoredShips = [];
182
183 3
        foreach ($flightCompany->getActiveMembers() as $fleetShipWrapper) {
184 3
            $fleetShip = $fleetShipWrapper->get();
185
186 3
            $tractoredShip = $fleetShip->getTractoredShip();
187
            if (
188 3
                $tractoredShip !== null
189
            ) {
190
                $tractoredShips[] = $tractoredShip;
191
            }
192
        }
193
194 3
        return $tractoredShips;
195
    }
196
197
    private function leaveFleet(SpacecraftInterface $ship, MessageCollectionInterface $messages): void
198
    {
199
        if ($ship instanceof ShipInterface && $this->leaveFleet->leaveFleet($ship)) {
200
            $messages->addInformationf('Die %s hat die Flotte verlassen', $ship->getName());
201
        }
202
    }
203
204
    /**
205
     * @param array<ShipInterface> $initialTractoredShips
206
     */
207 2
    private function saveShips(FlightCompany $flightCompany, array $initialTractoredShips): void
208
    {
209 2
        foreach ($flightCompany->getActiveMembers() as $wrapper) {
210 1
            $ship = $wrapper->get();
211 1
            $this->spacecraftRepository->save($ship);
212
        }
213
214 2
        foreach ($initialTractoredShips as $tractoredShip) {
215
            $this->spacecraftRepository->save($tractoredShip);
216
        }
217
    }
218
219 2
    private function postFlightInformations(
220
        FlightCompany $flightCompany,
221
        FlightRouteInterface $flightRoute,
222
        MessageCollectionInterface $messages
223
    ): void {
224
225 2
        $wrappers = $flightCompany->getActiveMembers();
226
227
        //add tractor info
228 2
        foreach ($wrappers as $wrapper) {
229 1
            $ship = $wrapper->get();
230
231 1
            $tractoredShip = $ship->getTractoredShip();
232 1
            if ($tractoredShip !== null) {
233
                $this->shipMovementInformationAdder->pulledTractoredShip(
234
                    $ship,
235
                    $tractoredShip,
236
                    $flightRoute->getRouteMode(),
237
                    $messages
238
                );
239
            }
240
        }
241
242 2
        $leadSpacecraft = $flightCompany->getLeader();
243 2
        $leadSpacecraftName = $leadSpacecraft->getName();
244 2
        $isFleetMode = $flightCompany->isFleetMode();
245
246
        //add destination info
247 2
        if ($flightCompany->isEverybodyDestroyed()) {
248 1
            $this->shipMovementInformationAdder->reachedDestinationDestroyed(
249 1
                $leadSpacecraft,
250 1
                $leadSpacecraftName,
251 1
                $isFleetMode,
252 1
                $flightRoute->getRouteMode(),
253 1
                $messages
254 1
            );
255
        } else {
256 1
            $this->shipMovementInformationAdder->reachedDestination(
257 1
                $leadSpacecraft,
258 1
                $isFleetMode,
259 1
                $flightRoute->getRouteMode(),
260 1
                $messages
261 1
            );
262
        }
263
264 2
        $finalDestination = $leadSpacecraft->getLocation();
265
266
        //add info about anomalies
267 2
        foreach ($finalDestination->getAnomalies() as $anomaly) {
268
            $messages->addInformationf(
269
                '[b][color=yellow]In diesem Sektor befindet sich eine %s-Anomalie[/color][/b]',
270
                $anomaly->getAnomalyType()->getName()
271
            );
272
        }
273
        // add info about buyos
274 2
        foreach ($finalDestination->getBuoys() as $buoy) {
275
            $messages->addInformationf('[b][color=yellow]Boje entdeckt: [/color][/b]%s', $buoy->getText());
276
        }
277
    }
278
279
    /**
280
     * @param array<string> $value
281
     */
282
    private function addInformationMerge(array $value, MessageCollectionInterface $messages): void
283
    {
284
        $messages->add($this->messageFactory->createMessage(UserEnum::USER_NOONE, null, $value));
285
    }
286
}
287