Test Failed
Pull Request — master (#2030)
by Janko
10:36
created

FlightRoute::getCurrentWaypoint()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Spacecraft\Lib\Movement\Route;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Doctrine\Common\Collections\Collection;
9
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...
10
use RuntimeException;
11
use Stu\Component\Map\Effects\EffectHandlingInterface;
12
use Stu\Module\Spacecraft\Lib\Message\MessageCollectionInterface;
13
use Stu\Module\Spacecraft\Lib\Movement\Component\Consequence\FlightConsequenceInterface;
14
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
15
use Stu\Orm\Entity\LocationInterface;
16
use Stu\Orm\Entity\MapInterface;
17
use Stu\Orm\Entity\SpacecraftInterface;
18
use Stu\Orm\Entity\StarSystemMapInterface;
19
use Stu\Orm\Entity\StationInterface;
20
use Stu\Orm\Entity\WormholeEntryInterface;
21
22
final class FlightRoute implements FlightRouteInterface
23
{
24
    //Members
25
    private bool $isTraversing = false;
26
27
    private RouteModeEnum $routeMode = RouteModeEnum::FLIGHT;
28
29
    private LocationInterface $current;
30
31
    private ?WormholeEntryInterface $wormholeEntry = null;
32
33
    /**
34
     * @var Collection<int, LocationInterface>
35
     */
36
    private Collection $waypoints;
37
38
    /**
39
     * @param array<string, FlightConsequenceInterface> $flightConsequences
40
     * @param array<string, FlightConsequenceInterface> $postFlightConsequences
41 19
     */
42
    public function __construct(
43
        private CheckDestinationInterface $checkDestination,
44
        private LoadWaypointsInterface $loadWaypoints,
45
        private EnterWaypointInterface $enterWaypoint,
46
        private EffectHandlingInterface $effectHandling,
47
        private array $flightConsequences,
48 19
        private array $postFlightConsequences,
49
    ) {
50
        $this->waypoints = new ArrayCollection();
51 8
    }
52
53
    #[Override]
54
    public function setDestination(
55
        MapInterface|StarSystemMapInterface $destination,
56 8
        bool $isTranswarp
57
    ): FlightRouteInterface {
58 8
        $this->waypoints->add($destination);
59 6
60 1
        if ($destination instanceof MapInterface) {
61
            if ($isTranswarp) {
62 5
                $this->routeMode = RouteModeEnum::TRANSWARP;
63
            } else {
64
                $this->routeMode = RouteModeEnum::SYSTEM_EXIT;
65 2
            }
66
        } else {
67
            $this->routeMode = RouteModeEnum::SYSTEM_ENTRY;
68 8
        }
69
70
        return $this;
71 2
    }
72
73
    #[Override]
74 2
    public function setDestinationViaWormhole(WormholeEntryInterface $wormholeEntry, bool $isEntry): FlightRouteInterface
75 2
    {
76 1
        $this->wormholeEntry = $wormholeEntry;
77 1
        if ($isEntry) {
78
            $this->waypoints->add($wormholeEntry->getSystemMap());
79 1
            $this->routeMode = RouteModeEnum::WORMHOLE_ENTRY;
80 1
        } else {
81
            $this->waypoints->add($wormholeEntry->getMap());
82
            $this->routeMode = RouteModeEnum::WORMHOLE_EXIT;
83 2
        }
84
85
        return $this;
86 6
    }
87
88
    #[Override]
89 6
    public function setDestinationViaCoordinates(SpacecraftInterface $spacecraft, int $x, int $y): FlightRouteInterface
90 6
    {
91 6
        $start = $spacecraft->getLocation();
92
        $this->current = $start;
93 6
        $destination = $this->checkDestination->validate($spacecraft, $x, $y);
94 5
95 5
        if ($start !== $destination) {
96
            $this->waypoints = $this->loadWaypoints->load($start, $destination);
97
            $this->isTraversing = true;
98 6
        }
99
100
        return $this;
101
    }
102
103
    #[Override]
104
    public function getCurrentWaypoint(): LocationInterface
105
    {
106
        return $this->current;
107 8
    }
108
109
    #[Override]
110 8
    public function getNextWaypoint(): LocationInterface
111 1
    {
112
        if ($this->waypoints->isEmpty()) {
113
            throw new RuntimeException('isDestinationArrived has to be called beforehand');
114 7
        }
115
116
        return $this->waypoints->first();
117 6
    }
118
119
    private function stepForward(): void
120 6
    {
121
        $first =  $this->waypoints->first();
122 6
123 1
        if (!$first) {
124
            return;
125
        }
126 6
127 6
        $this->current = $first;
128
        $this->waypoints->removeElement($this->current);
129
    }
130 1
131
    #[Override]
132
    public function abortFlight(): void
133 1
    {
134
        $this->waypoints->clear();
135
    }
136 6
137
    #[Override]
138
    public function enterNextWaypoint(
139
        Collection $wrappers,
140
        MessageCollectionInterface $messages
141
    ): void {
142
143 6
        // flight consequences
144
        $this->walkWrappers(
145
            $wrappers,
146 6
            function (SpacecraftWrapperInterface $wrapper) use ($messages): void {
147 6
                $this->walkConsequences($this->flightConsequences, $wrapper, $messages);
148 6
            }
149 6
        );
150 6
151 6
        // enter waypoint
152
        $this->walkWrappers(
153
            $wrappers,
154 6
            function (SpacecraftWrapperInterface $wrapper): void {
155
                $this->enterWaypoint->enterNextWaypoint(
156
                    $wrapper->get(),
157
                    $this->isTraversing,
158
                    $this->getNextWaypoint(),
159
                    $this->wormholeEntry
160 6
                );
161
            }
162
        );
163
164
        $this->effectHandling->addFlightInformationForActiveEffects($this->getNextWaypoint(), $messages);
165 6
166 6
        // post flight consequences
167 6
        $this->walkWrappers(
168 6
            $wrappers,
169
            function (SpacecraftWrapperInterface $wrapper) use ($messages): void {
170
                $this->walkConsequences($this->postFlightConsequences, $wrapper, $messages);
171 8
            }
172
        );
173
174 8
        $this->stepForward();
175
    }
176
177 6
    /** @param Collection<int, SpacecraftWrapperInterface> $wrappers */
178
    private function walkWrappers(Collection $wrappers, callable $func): void
179
    {
180 6
        foreach ($wrappers as $wrapper) {
181
            $func($wrapper);
182
        }
183
    }
184
185
    /**
186
     * @param array<string, FlightConsequenceInterface> $consequences
187
     */
188
    private function walkConsequences(
189
        array $consequences,
190
        ?SpacecraftWrapperInterface $wrapper,
191
        MessageCollectionInterface $messages
192
    ): void {
193
194
        if ($wrapper === null) {
195
            return;
196
        }
197
198
        array_walk(
199
            $consequences,
200
            fn(FlightConsequenceInterface $consequence) => $consequence->trigger($wrapper, $this, $messages)
201
        );
202
203
        $this->walkConsequences($consequences, $wrapper->getTractoredShipWrapper(), $messages);
204
    }
205
206
    #[Override]
207
    public function isDestinationArrived(): bool
208
    {
209
        return $this->waypoints->isEmpty();
210
    }
211
212
    #[Override]
213
    public function getRouteMode(): RouteModeEnum
214
    {
215
        return $this->routeMode;
216
    }
217
218
    #[Override]
219
    public function isTraversing(): bool
220
    {
221
        return $this->isTraversing;
222
    }
223
224
    #[Override]
225
    public function isImpulseDriveNeeded(): bool
226
    {
227 2
        $routeMode = $this->routeMode;
228
229
        if (
230 2
            $routeMode === RouteModeEnum::SYSTEM_ENTRY
231 2
            || $routeMode === RouteModeEnum::WORMHOLE_ENTRY
232 1
        ) {
233
            return true;
234
        }
235
236 1
        return $routeMode === RouteModeEnum::FLIGHT
237
            && $this->getNextWaypoint() instanceof StarSystemMapInterface;
238
    }
239 2
240
    #[Override]
241
    public function isWarpDriveNeeded(): bool
242 2
    {
243
        $routeMode = $this->routeMode;
244 2
245 2
        if (
246
            $routeMode === RouteModeEnum::SYSTEM_EXIT
247
            || $routeMode === RouteModeEnum::TRANSWARP
248 4
        ) {
249
            return true;
250
        }
251 4
252
        return $routeMode === RouteModeEnum::FLIGHT
253 4
            && $this->getNextWaypoint() instanceof MapInterface;
254 4
    }
255
256
    #[Override]
257
    public function isTranswarpCoilNeeded(): bool
258
    {
259
        return $this->routeMode === RouteModeEnum::TRANSWARP;
260
    }
261
262
    #[Override]
263
    public function hasSpecialDamageOnField(): bool
264
    {
265
        foreach ($this->waypoints as $waypoint) {
266
            if ($waypoint->getFieldType()->getSpecialDamage() > 0) {
267
                return true;
268
            }
269
        }
270
271
        return false;
272
    }
273
274
    #[Override]
275
    public function isDestinationInAdminRegion(array $regionIds): bool
276
    {
277
        $destination = $this->waypoints->last();
278
279
        return $destination instanceof MapInterface
280
            && in_array($destination->getAdminRegionId(), $regionIds);
281
    }
282
283
    #[Override]
284
    public function isDestinationAtTradepost(): bool
285
    {
286
        $destination = $this->waypoints->last();
287
288
        return $destination instanceof MapInterface
289
            && $destination->getSpacecrafts()->exists(fn(int $key, SpacecraftInterface $spacecraft): bool => $spacecraft instanceof StationInterface && $spacecraft->getTradePost() !== null);
290
    }
291
}
292