Passed
Push — master ( 0a21cd...0ad97c )
by Janko
05:01
created

checkActivationConditions()   C

Complexity

Conditions 12
Paths 9

Size

Total Lines 42
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 12

Importance

Changes 0
Metric Value
cc 12
eloc 22
nc 9
nop 4
dl 0
loc 42
ccs 23
cts 23
cp 1
crap 12
rs 6.9666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Component\Spacecraft\System;
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 Stu\Component\Spacecraft\System\Exception\ActivationConditionsNotMetException;
11
use Stu\Component\Spacecraft\System\Exception\AlreadyActiveException;
12
use Stu\Component\Spacecraft\System\Exception\AlreadyOffException;
13
use Stu\Component\Spacecraft\System\Exception\DeactivationConditionsNotMetException;
14
use Stu\Component\Spacecraft\System\Exception\InsufficientCrewException;
15
use Stu\Component\Spacecraft\System\Exception\InsufficientEnergyException;
16
use Stu\Component\Spacecraft\System\Exception\InvalidSystemException;
17
use Stu\Component\Spacecraft\System\Exception\SpacecraftSystemException;
18
use Stu\Component\Spacecraft\System\Exception\SystemCooldownException;
19
use Stu\Component\Spacecraft\System\Exception\SystemDamagedException;
20
use Stu\Component\Spacecraft\System\Exception\SystemNotActivatableException;
21
use Stu\Component\Spacecraft\System\Exception\SystemNotDeactivatableException;
22
use Stu\Component\Spacecraft\System\Exception\SystemNotFoundException;
23
use Stu\Module\Control\StuTime;
24
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
25
use Stu\Orm\Entity\SpacecraftSystem;
26
use Stu\Orm\Entity\Spacecraft;
27
28
final class SpacecraftSystemManager implements SpacecraftSystemManagerInterface
29
{
30
    /**
31
     * @param array<SpacecraftSystemTypeInterface> $systemList
32
     */
33 20
    public function __construct(private array $systemList, private StuTime $stuTime) {}
34
35 25
    #[Override]
36
    public function activate(
37
        SpacecraftWrapperInterface $wrapper,
38
        SpacecraftSystemTypeEnum $type,
39
        bool $force = false,
40
        bool $isDryRun = false
41
    ): void {
42 25
        $time = $this->stuTime->time();
43 25
        $system = $this->lookupSystem($type);
44
45 25
        if (!$force) {
46 25
            $this->checkActivationConditions($wrapper, $system, $type, $time);
47
        }
48
49 12
        if ($isDryRun) {
50 5
            return;
51
        }
52
53 11
        $epsSystem = $wrapper->getEpsSystemData();
54 11
        if ($epsSystem !== null) {
55 11
            $epsSystem->lowerEps($system->getEnergyUsageForActivation())->update();
56
        }
57
58 11
        $this->setCooldown($wrapper, $type, $time, $system);
59
60 11
        $system->activate($wrapper, $this);
61
    }
62
63 11
    private function setCooldown(
64
        SpacecraftWrapperInterface $wrapper,
65
        SpacecraftSystemTypeEnum $type,
66
        int $time,
67
        SpacecraftSystemTypeInterface $system
68
    ): void {
69 11
        $shipSystem = $wrapper->get()->getSystems()[$type->value] ?? null;
70 11
        if ($shipSystem !== null && $system->getCooldownSeconds() !== null) {
71 1
            $shipSystem->setCooldown($time + $system->getCooldownSeconds());
72
        }
73
    }
74
75 15
    #[Override]
76
    public function deactivate(SpacecraftWrapperInterface $wrapper, SpacecraftSystemTypeEnum $type, bool $force = false): void
77
    {
78 15
        $system = $this->lookupSystem($type);
79
80 14
        if (!$force) {
81 9
            $this->checkDeactivationConditions($wrapper, $system, $type);
82
        }
83
84 9
        $system->deactivate($wrapper);
85
    }
86
87 3
    #[Override]
88
    public function deactivateAll(SpacecraftWrapperInterface $wrapper): void
89
    {
90 3
        foreach ($wrapper->get()->getSystems() as $shipSystem) {
91
            try {
92 3
                $this->deactivate($wrapper, $shipSystem->getSystemType(), true);
93 1
            } catch (SpacecraftSystemException) {
94 1
                continue;
95
            }
96
        }
97
    }
98
99 4
    #[Override]
100
    public function getEnergyUsageForActivation(SpacecraftSystemTypeEnum $type): int
101
    {
102 4
        $system = $this->lookupSystem($type);
103
104 4
        return $system->getEnergyUsageForActivation();
105
    }
106
107 13
    #[Override]
108
    public function getEnergyConsumption(SpacecraftSystemTypeEnum $type): int
109
    {
110 13
        $system = $this->lookupSystem($type);
111
112 13
        return $system->getEnergyConsumption();
113
    }
114
115 44
    #[Override]
116
    public function lookupSystem(SpacecraftSystemTypeEnum $type): SpacecraftSystemTypeInterface
117
    {
118 44
        $system = $this->systemList[$type->value] ?? null;
119 44
        if ($system === null) {
120 1
            throw new InvalidSystemException();
121
        }
122
123 43
        return $system;
124
    }
125
126 25
    private function checkActivationConditions(
127
        SpacecraftWrapperInterface $wrapper,
128
        SpacecraftSystemTypeInterface $system,
129
        SpacecraftSystemTypeEnum $type,
130
        int $time
131
    ): void {
132 25
        $ship = $wrapper->get();
133 25
        $shipSystem = $ship->getSystems()[$type->value] ?? null;
134 25
        if ($shipSystem === null) {
135 6
            throw new SystemNotFoundException();
136
        }
137
138 22
        if ($shipSystem->getStatus() === 0) {
139 1
            throw new SystemDamagedException();
140
        }
141
142 21
        $mode = $shipSystem->getMode();
143 21
        if ($mode === SpacecraftSystemModeEnum::MODE_ALWAYS_OFF) {
144 1
            throw new SystemNotActivatableException();
145
        }
146
147 20
        if ($mode->isActivated()) {
148 5
            throw new AlreadyActiveException();
149
        }
150
151 17
        if (!$ship->hasEnoughCrew() && !$system->canBeActivatedWithInsufficientCrew()) {
152 2
            throw new InsufficientCrewException();
153
        }
154
155 15
        $epsSystem = $wrapper->getEpsSystemData();
156 15
        if ($epsSystem === null || $epsSystem->getEps() < $system->getEnergyUsageForActivation()) {
157 1
            throw new InsufficientEnergyException($system->getEnergyUsageForActivation());
158
        }
159
160 14
        $cooldown = $shipSystem->getCooldown();
161 14
        if ($cooldown !== null && $cooldown > $time) {
162 1
            throw new SystemCooldownException($cooldown - $time);
163
        }
164
165 13
        $reason = '';
166 13
        if (!$system->checkActivationConditions($wrapper, $reason)) {
167 1
            throw new ActivationConditionsNotMetException($reason);
168
        }
169
    }
170
171 9
    private function checkDeactivationConditions(
172
        SpacecraftWrapperInterface $wrapper,
173
        SpacecraftSystemTypeInterface $system,
174
        SpacecraftSystemTypeEnum $type
175
    ): void {
176 9
        $ship = $wrapper->get();
177 9
        $shipSystem = $ship->getSystems()[$type->value] ?? null;
178 9
        if ($shipSystem === null) {
179 1
            throw new SystemNotFoundException();
180
        }
181
182 9
        $mode = $shipSystem->getMode();
183 9
        if ($mode === SpacecraftSystemModeEnum::MODE_ALWAYS_ON) {
184 1
            throw new SystemNotDeactivatableException();
185
        }
186
187
        if (
188 8
            $mode === SpacecraftSystemModeEnum::MODE_OFF
189 8
            ||  $mode === SpacecraftSystemModeEnum::MODE_ALWAYS_OFF
190
        ) {
191 4
            throw new AlreadyOffException();
192
        }
193
194 5
        $reason = '';
195 5
        if (!$system->checkDeactivationConditions($wrapper, $reason)) {
196 1
            throw new DeactivationConditionsNotMetException($reason);
197
        }
198
    }
199
200
    #[Override]
201
    public function handleDestroyedSystem(SpacecraftWrapperInterface $wrapper, SpacecraftSystemTypeEnum $type): void
202
    {
203
        $system = $this->lookupSystem($type);
204
205
        $system->handleDestruction($wrapper);
206
    }
207
208 1
    #[Override]
209
    public function handleDamagedSystem(SpacecraftWrapperInterface $wrapper, SpacecraftSystemTypeEnum $type): void
210
    {
211 1
        $system = $this->lookupSystem($type);
212
213 1
        $system->handleDamage($wrapper);
214
    }
215
216 16
    #[Override]
217
    public function getActiveSystems(Spacecraft $ship, bool $sort = false): Collection
218
    {
219 16
        $activeSystems = [];
220 16
        $prioArray = [];
221 16
        foreach ($ship->getSystems() as $system) {
222 16
            if ($system->getMode()->isActivated()) {
223 14
                $activeSystems[] = $system;
224 14
                if ($sort) {
225
                    $prioArray[$system->getSystemType()->value] = $system->getSystemType()->getPriority();
226
                }
227
            }
228
        }
229
230 16
        if ($sort) {
231
            usort(
232
                $activeSystems,
233
                fn(SpacecraftSystem $a, SpacecraftSystem $b): int => $prioArray[$a->getSystemType()->value] <=> $prioArray[$b->getSystemType()->value]
234
            );
235
        }
236
237 16
        return new ArrayCollection($activeSystems);
238
    }
239
}
240