Passed
Pull Request — master (#2043)
by Janko
20:39 queued 09:47
created

FlightRoute::hasEffectOnRoute()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

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