Passed
Pull Request — master (#2013)
by Nico
19:24 queued 09:42
created

SpacecraftSystemManager::setCooldown()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

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