Passed
Pull Request — master (#2331)
by Janko
11:37 queued 06:03
created

ShipMover::travelFlightRoute()   B

Complexity

Conditions 7
Paths 3

Size

Total Lines 54
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 7.116

Importance

Changes 0
Metric Value
cc 7
eloc 27
nc 3
nop 3
dl 0
loc 54
ccs 26
cts 30
cp 0.8667
crap 7.116
rs 8.5546
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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