Passed
Push — dev ( 5b1d95...923b08 )
by Janko
23:33 queued 07:31
created

EnergyConsumeHandler::handleSpacecraftTick()   F

Complexity

Conditions 17
Paths 442

Size

Total Lines 104
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 306

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 17
eloc 60
c 1
b 0
f 0
nc 442
nop 2
dl 0
loc 104
ccs 0
cts 64
cp 0
crap 306
rs 1.8249

How to fix   Long Method    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
namespace Stu\Module\Tick\Spacecraft\Handler;
4
5
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...
6
use Stu\Component\Spacecraft\SpacecraftAlertStateEnum;
7
use Stu\Component\Spacecraft\System\Data\EpsSystemData;
8
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
9
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
10
use Stu\Lib\Information\InformationInterface;
11
use Stu\Module\Spacecraft\Lib\Crew\SpacecraftLeaverInterface;
12
use Stu\Module\Spacecraft\Lib\ReactorWrapperInterface;
13
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
14
use Stu\Module\Tick\Spacecraft\SpacecraftTickFinishedException;
15
16
class EnergyConsumeHandler implements SpacecraftTickHandlerInterface
17
{
18 1
    public function __construct(
19
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
20
        private SpacecraftLeaverInterface $spacecraftLeaver,
21 1
    ) {}
22
23
    #[Override]
24
    public function handleSpacecraftTick(
25
        SpacecraftWrapperInterface $wrapper,
26
        InformationInterface $information
27
    ): void {
28
29
        $spacecraft = $wrapper->get();
30
        $hasEnoughCrew = $spacecraft->hasEnoughCrew();
31
32
        $reactorUsageForWarpdrive = $this->loadWarpdrive(
33
            $wrapper,
34
            $hasEnoughCrew
35
        );
36
37
        $eps = $wrapper->getEpsSystemData();
38
        if ($eps === null) {
39
            return;
40
        }
41
42
        $reactor = $wrapper->getReactorWrapper();
43
44
        $availableEps = $this->getAvailableEps(
45
            $wrapper,
46
            $eps,
47
            $reactor,
48
            $hasEnoughCrew,
49
            $reactorUsageForWarpdrive
50
        );
51
52
        //try to save energy by reducing alert state
53
        if ($wrapper->getEpsUsage() > $availableEps) {
54
            $malus = $wrapper->getEpsUsage() - $availableEps;
55
            $alertUsage = $spacecraft->getAlertState()->value - 1;
56
57
            if ($alertUsage > 0) {
58
                $preState = $spacecraft->getAlertState();
59
                $reduce = (int)min($malus, $alertUsage);
60
61
                $spacecraft->setAlertState(SpacecraftAlertStateEnum::from($preState->value - $reduce));
62
                $information->addInformationf(
63
                    'Wechsel von %s auf %s wegen Energiemangel',
64
                    $preState->getDescription(),
65
                    $spacecraft->getAlertState()->getDescription()
66
                );
67
            }
68
        }
69
70
        //try to save energy by deactivating systems from low to high priority
71
        if ($wrapper->getEpsUsage() > $availableEps) {
72
            $activeSystems = $this->spacecraftSystemManager->getActiveSystems($spacecraft, true);
73
74
            foreach ($activeSystems as $system) {
75
                $energyConsumption = $this->spacecraftSystemManager->getEnergyConsumption($system->getSystemType());
76
                if ($energyConsumption < 1) {
77
                    continue;
78
                }
79
80
                //echo "- eps: ".$eps." - usage: ".$wrapper->getEpsUsage()."\n";
81
                if ($availableEps - $wrapper->getEpsUsage() - $energyConsumption < 0) {
82
                    //echo "-- hit system: ".$system->getDescription()."\n";
83
84
                    $this->spacecraftSystemManager->deactivate($wrapper, $system->getSystemType(), true);
85
86
                    $wrapper->lowerEpsUsage($energyConsumption);
87
                    $information->addInformationf('%s deaktiviert wegen Energiemangel', $system->getSystemType()->getDescription());
88
89
                    if ($spacecraft->getCrewCount() > 0 && $system->getSystemType() == SpacecraftSystemTypeEnum::LIFE_SUPPORT) {
90
                        $information->addInformation('Die Lebenserhaltung ist ausgefallen:');
91
                        $information->addInformation($this->spacecraftLeaver->evacuate($wrapper));
92
93
                        throw new SpacecraftTickFinishedException();
94
                    }
95
                }
96
                if ($wrapper->getEpsUsage() <= $availableEps) {
97
                    break;
98
                }
99
            }
100
        }
101
102
        $newEps = $availableEps - $wrapper->getEpsUsage();
103
        $batteryReload = $spacecraft->isStation()
104
            && $eps->reloadBattery()
105
            && $newEps > $eps->getEps()
106
            ? min(
107
                (int) ceil($eps->getMaxBattery() / 10),
108
                $newEps - $eps->getEps(),
109
                $eps->getMaxBattery() - $eps->getBattery()
110
            ) : 0;
111
112
        $newEps -= $batteryReload;
113
        if ($newEps > $eps->getMaxEps()) {
114
            $newEps = $eps->getMaxEps();
115
        }
116
117
118
        $usedEnergy = $wrapper->getEpsUsage() + $batteryReload + ($newEps - $eps->getEps()) + $reactorUsageForWarpdrive;
119
120
        //echo "--- Generated Id ".$ship->getId()." - eps: ".$eps." - usage: ".$wrapper->getEpsUsage()." - old eps: ".$ship->getEps()." - wk: ".$wkuse."\n";
121
        $eps->setEps($newEps)
122
            ->setBattery($eps->getBattery() + $batteryReload)
123
            ->update();
124
125
        if ($usedEnergy > 0 && $reactor !== null) {
126
            $reactor->changeLoad(-$usedEnergy);
127
        }
128
    }
129
130
    private function loadWarpdrive(SpacecraftWrapperInterface $wrapper, bool $hasEnoughCrew): int
131
    {
132
        if (!$hasEnoughCrew) {
133
            return 0;
134
        }
135
136
        $reactor = $wrapper->getReactorWrapper();
137
        $warpdrive = $wrapper->getWarpDriveSystemData();
138
        if ($warpdrive === null || $reactor === null) {
139
            return 0;
140
        }
141
142
        $effectiveWarpdriveProduction = $reactor->getEffectiveWarpDriveProduction();
143
        if ($effectiveWarpdriveProduction === 0) {
144
            return 0;
145
        }
146
147
        $currentLoad = $warpdrive->getWarpDrive();
148
149
        $warpdrive->setWarpDrive($currentLoad + $effectiveWarpdriveProduction)->update();
150
151
        return $effectiveWarpdriveProduction * $wrapper->get()->getRump()->getFlightECost();
152
    }
153
154
    private function getAvailableEps(
155
        SpacecraftWrapperInterface $wrapper,
156
        EpsSystemData $eps,
157
        ?ReactorWrapperInterface $reactor,
158
        bool $hasEnoughCrew,
159
        int $reactorUsageForWarpdrive
160
    ): int {
161
        if ($hasEnoughCrew && $reactor !== null) {
162
163
            return $eps->getEps() + $reactor->getEpsProduction() +  $this->getCarryOver(
164
                $wrapper,
165
                $reactor,
166
                $reactorUsageForWarpdrive
167
            );
168
        }
169
170
        return $eps->getEps();
171
    }
172
173
    private function getCarryOver(
174
        SpacecraftWrapperInterface $wrapper,
175
        ReactorWrapperInterface $reactor,
176
        int $reactorUsageForWarpdrive
177
    ): int {
178
        $warpdrive = $wrapper->getWarpDriveSystemData();
179
        if ($warpdrive === null || !$warpdrive->getAutoCarryOver()) {
180
            return 0;
181
        }
182
183
        return $reactor->getOutputCappedByLoad() - $reactor->getEpsProduction() - $reactorUsageForWarpdrive;
184
    }
185
}
186