Passed
Push — master ( 91d807...98c78f )
by Nico
50:21 queued 24:31
created

FlightRoute::isImpulseDriveNeeded()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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