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