Passed
Push — dev ( 6e0cf6...2a5475 )
by Janko
14:36
created

ShipMover::addInformationMerge()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
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 1
                $messages->addInformation('Es wurden alle Schiffe zerstört');
117
            }
118
        }
119
120 3
        return $hasTravelled;
121
    }
122
123
    /**
124
     * @param array<array{0: SpacecraftInterface, 1: ShipWrapperInterface}> $movedTractoredShipWrappers
125
     */
126 2
    private function moveShipsByOneField(
127
        FlightCompany $flightCompany,
128
        FlightRouteInterface $flightRoute,
129
        array &$movedTractoredShipWrappers,
130
        MessageCollectionInterface $messages
131
    ): void {
132
133 2
        $flightRoute->enterNextWaypoint(
134 2
            $flightCompany,
135 2
            $messages
136 2
        );
137
138 2
        foreach ($flightCompany->getActiveMembers() as $wrapper) {
139
140 2
            $tractoredShipWrapper = $wrapper->getTractoredShipWrapper();
141 2
            if ($tractoredShipWrapper !== null) {
142
                $movedTractoredShipWrappers[] = [$wrapper->get(), $tractoredShipWrapper];
143
            }
144
        }
145
    }
146
147
    /** @param array<array{0: SpacecraftInterface, 1: ShipWrapperInterface}> $movedTractoredShipWrappers */
148 1
    private function alertReactionCheck(
149
        SpacecraftWrapperInterface $leadWrapper,
150
        array $movedTractoredShipWrappers,
151
        MessageCollectionInterface $messages
152
    ): void {
153 1
        $alertRedInformations = new InformationWrapper();
154 1
        $this->alertReactionFacade->doItAll($leadWrapper, $alertRedInformations);
155
156 1
        if (!$alertRedInformations->isEmpty()) {
157
            $this->addInformationMerge($alertRedInformations->getInformations(), $messages);
158
        }
159
160
        // alert red check for tractored ships
161 1
        foreach ($movedTractoredShipWrappers as [$tractoringSpacecraft, $tractoredShipWrapper]) {
162
            if (!$tractoredShipWrapper->get()->isDestroyed()) {
163
                $alertRedInformations = new InformationWrapper();
164
                $this->alertReactionFacade->doItAll(
165
                    $tractoredShipWrapper,
166
                    $alertRedInformations,
167
                    $tractoringSpacecraft
168
                );
169
170
                if (!$alertRedInformations->isEmpty()) {
171
                    $this->addInformationMerge($alertRedInformations->getInformations(), $messages);
172
                }
173
            }
174
        }
175
    }
176
177
    /**
178
     * @return array<ShipInterface>
179
     */
180 3
    private function initTractoredShips(FlightCompany $flightCompany): array
181
    {
182 3
        $tractoredShips = [];
183
184 3
        foreach ($flightCompany->getActiveMembers() as $fleetShipWrapper) {
185 3
            $fleetShip = $fleetShipWrapper->get();
186
187 3
            $tractoredShip = $fleetShip->getTractoredShip();
188
            if (
189 3
                $tractoredShip !== null
190
            ) {
191
                $tractoredShips[] = $tractoredShip;
192
            }
193
        }
194
195 3
        return $tractoredShips;
196
    }
197
198
    private function leaveFleet(SpacecraftInterface $ship, MessageCollectionInterface $messages): void
199
    {
200
        if ($ship instanceof ShipInterface) {
201
            if ($this->leaveFleet->leaveFleet($ship)) {
202
                $messages->addInformationf('Die %s hat die Flotte verlassen', $ship->getName());
203
            }
204
        }
205
    }
206
207
    /**
208
     * @param array<ShipInterface> $initialTractoredShips
209
     */
210 2
    private function saveShips(FlightCompany $flightCompany, array $initialTractoredShips): void
211
    {
212 2
        foreach ($flightCompany->getActiveMembers() as $wrapper) {
213 1
            $ship = $wrapper->get();
214 1
            $this->spacecraftRepository->save($ship);
215
        }
216
217 2
        foreach ($initialTractoredShips as $tractoredShip) {
218
            $this->spacecraftRepository->save($tractoredShip);
219
        }
220
    }
221
222 2
    private function postFlightInformations(
223
        FlightCompany $flightCompany,
224
        FlightRouteInterface $flightRoute,
225
        MessageCollectionInterface $messages
226
    ): void {
227
228 2
        $wrappers = $flightCompany->getActiveMembers();
229
230
        //add tractor info
231 2
        foreach ($wrappers as $wrapper) {
232 1
            $ship = $wrapper->get();
233
234 1
            $tractoredShip = $ship->getTractoredShip();
235 1
            if ($tractoredShip !== null) {
236
                $this->shipMovementInformationAdder->pulledTractoredShip(
237
                    $ship,
238
                    $tractoredShip,
239
                    $flightRoute->getRouteMode(),
240
                    $messages
241
                );
242
            }
243
        }
244
245 2
        $leadSpacecraft = $flightCompany->getLeader();
246 2
        $leadSpacecraftName = $leadSpacecraft->getName();
247 2
        $isFleetMode = $flightCompany->isFleetMode();
248
249
        //add destination info
250 2
        if ($flightCompany->isEmpty()) {
251 1
            $this->shipMovementInformationAdder->reachedDestinationDestroyed(
252 1
                $leadSpacecraft,
253 1
                $leadSpacecraftName,
254 1
                $isFleetMode,
255 1
                $flightRoute->getRouteMode(),
256 1
                $messages
257 1
            );
258
        } else {
259 1
            $this->shipMovementInformationAdder->reachedDestination(
260 1
                $leadSpacecraft,
261 1
                $isFleetMode,
262 1
                $flightRoute->getRouteMode(),
263 1
                $messages
264 1
            );
265
        }
266
267 2
        $finalDestination = $leadSpacecraft->getLocation();
268
269
        //add info about anomalies
270 2
        foreach ($finalDestination->getAnomalies() as $anomaly) {
271
            $messages->addInformationf(
272
                '[b][color=yellow]In diesem Sektor befindet sich eine %s-Anomalie[/color][/b]',
273
                $anomaly->getAnomalyType()->getName()
274
            );
275
        }
276
        // add info about buyos
277 2
        foreach ($finalDestination->getBuoys() as $buoy) {
278
            $messages->addInformationf('[b][color=yellow]Boje entdeckt: [/color][/b]%s', $buoy->getText());
279
        }
280
    }
281
282
    /**
283
     * @param array<string> $value
284
     */
285
    private function addInformationMerge(array $value, MessageCollectionInterface $messages): void
286
    {
287
        $messages->add($this->messageFactory->createMessage(UserEnum::USER_NOONE, null, $value));
288
    }
289
}
290