Passed
Pull Request — master (#1806)
by Nico
53:13 queued 28:49
created

PirateNavigation::navigateIntoSystem()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 14
c 2
b 0
f 0
nc 7
nop 2
dl 0
loc 26
ccs 0
cts 14
cp 0
crap 42
rs 9.2222
1
<?php
2
3
namespace Stu\Lib\Pirate\Component;
4
5
use Stu\Module\Logging\LoggerUtilFactoryInterface;
6
use Stu\Module\Ship\Lib\FleetWrapperInterface;
7
use Stu\Module\Ship\Lib\Movement\Route\FlightRouteFactoryInterface;
8
use Stu\Module\Ship\Lib\Movement\Route\RandomSystemEntryInterface;
9
use Stu\Module\Ship\Lib\ShipWrapperInterface;
10
use Stu\Lib\Pirate\Component\PirateFlightInterface;
11
use Stu\Module\Logging\PirateLoggerInterface;
12
use Stu\Orm\Entity\MapInterface;
13
use Stu\Orm\Entity\StarSystemInterface;
14
use Stu\Orm\Entity\StarSystemMapInterface;
15
16
class PirateNavigation implements PirateNavigationInterface
17
{
18
    private PirateLoggerInterface $logger;
19
20
    public function __construct(
21
        private MoveOnLayerInterface $moveOnLayer,
22
        private FlightRouteFactoryInterface $flightRouteFactory,
23
        private PirateFlightInterface $pirateFlight,
24
        private RandomSystemEntryInterface $randomSystemEntry,
25
        LoggerUtilFactoryInterface $loggerUtilFactory
26
    ) {
27
        $this->logger = $loggerUtilFactory->getPirateLogger();
28
    }
29
30
    public function navigateToTarget(
31
        FleetWrapperInterface $fleet,
32
        MapInterface|StarSystemMapInterface|StarSystemInterface $target
33
    ): bool {
34
        $leadWrapper = $fleet->getLeadWrapper();
35
        $leadShip = $leadWrapper->get();
36
        $shipSystem = $leadShip->getSystem();
37
38
        $targetSystem = $this->getTargetSystem($target);
39
40
        // leave system
41
        if (
42
            $shipSystem !== null
43
            && $shipSystem !== $targetSystem
44
        ) {
45
            $this->logger->logf('    leave current system "%s"', $shipSystem->getName());
46
            if (!$this->leaveStarSystem($leadWrapper, $shipSystem)) {
47
                $this->logger->log('    could not leave current system');
48
                return false;
49
            }
50
        }
51
52
        if ($targetSystem !== null) {
53
            if (!$this->navigateIntoSystem($leadWrapper, $targetSystem)) {
54
                return false;
55
            }
56
        }
57
58
        if ($target instanceof StarSystemInterface) {
59
            return true;
60
        }
61
62
        // move to target
63
        $currentLocation = $leadShip->getCurrentMapField();
64
        if ($currentLocation !== $target) {
65
            if (!$this->moveOnLayer->move($leadWrapper, $target)) {
66
                $this->logger->log('    did not reach target');
67
                return false;
68
            }
69
        }
70
71
        return true;
72
    }
73
74
    private function getTargetSystem(MapInterface|StarSystemMapInterface|StarSystemInterface $target): ?StarSystemInterface
75
    {
76
        if ($target instanceof StarSystemInterface) {
77
            return $target;
78
        }
79
80
        if ($target instanceof StarSystemMapInterface) {
81
            return $target->getSystem();
82
        }
83
84
        return null;
85
    }
86
87
    private function navigateIntoSystem(ShipWrapperInterface $wrapper, StarSystemInterface $system): bool
88
    {
89
        $leadShip = $wrapper->get();
90
91
        // move to system
92
        if (
93
            $leadShip->getSystem() === null
94
            && $leadShip->isOverSystem() !== $system
95
        ) {
96
            $this->logger->log('    move to system');
97
            if (!$this->moveOnLayer->move($wrapper, $system->getMapField())) {
98
                $this->logger->log('    could not reach system');
99
                return false;
100
            }
101
        }
102
103
        // enter system
104
        if ($leadShip->isOverSystem() === $system) {
105
            $this->logger->logf('    enter system "%s"', $system->getName());
106
            if (!$this->enterSystem($wrapper, $system)) {
107
                $this->logger->log('    could not enter system');
108
                return false;
109
            }
110
        }
111
112
        return true;
113
    }
114
115
    private function leaveStarSystem(ShipWrapperInterface $wrapper, StarSystemInterface $system): bool
116
    {
117
        $mapField = $system->getMapField();
118
        if ($mapField === null) {
119
            return false;
120
        }
121
122
        $flightRoute = $this->flightRouteFactory->getRouteForMapDestination(
123
            $mapField
124
        );
125
126
        $this->pirateFlight->movePirate($wrapper, $flightRoute);
127
128
        return $wrapper->get()->getSystem() === null;
129
    }
130
131
    private function enterSystem(ShipWrapperInterface $wrapper, StarSystemInterface $system): bool
132
    {
133
        $destination = $this->randomSystemEntry->getRandomEntryPoint($wrapper->get(), $system);
134
135
        $flightRoute = $this->flightRouteFactory->getRouteForMapDestination(
136
            $destination
137
        );
138
139
        $this->pirateFlight->movePirate($wrapper, $flightRoute);
140
141
        return $wrapper->get()->getSystem() === $system;
142
    }
143
}
144