Passed
Push — master ( 7d944e...416fd2 )
by Janko
10:32 queued 05:08
created

ReactorWrapper::setOutput()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Spacecraft\Lib;
6
7
use Stu\Component\Spacecraft\System\Data\AbstractReactorSystemData;
8
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
9
10
final class ReactorWrapper implements ReactorWrapperInterface
11
{
12
    //absolute values
13
    private ?int $epsProduction = null;
14
    private ?int $warpdriveProduction = null;
15
16
    /** @var null|array{eps: int, warpdrive: int} */
17
    private ?array $effectiveValues = null;
18
19 26
    public function __construct(private SpacecraftWrapperInterface $wrapper, private AbstractReactorSystemData $reactorSystemData) {}
20
21 12
    #[\Override]
22
    public function get(): AbstractReactorSystemData
23
    {
24 12
        return $this->reactorSystemData;
25
    }
26
27 13
    #[\Override]
28
    public function getEpsProduction(): int
29
    {
30 13
        if ($this->epsProduction === null) {
31 13
            $warpdrive = $this->wrapper->getWarpDriveSystemData();
32 13
            $warpdriveSplit = $warpdrive === null ? 100 : $warpdrive->getWarpDriveSplit();
33 13
            $reactorOutput = $this->getOutputCappedByLoad();
34
35 13
            if ($warpdriveSplit === 0) {
36 2
                $this->epsProduction = min($reactorOutput, $this->wrapper->getEpsUsage());
37
            } else {
38 11
                $warpDriveProduction = $this->getWarpdriveProduction();
39 11
                $flightCost = $this->wrapper->get()->getRump()->getFlightEcost();
40
41 11
                $this->epsProduction = $reactorOutput - ($warpDriveProduction * $flightCost);
42
            }
43
        }
44
45 13
        return $this->epsProduction;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->epsProduction could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
46
    }
47
48 11
    private function getWarpdriveProduction(): int
49
    {
50 11
        if ($this->warpdriveProduction === null) {
51 11
            $warpdrive = $this->wrapper->getWarpDriveSystemData();
52
53 11
            if ($warpdrive === null) {
54 3
                $this->warpdriveProduction = 0;
55
            } else {
56 8
                $warpdriveSplit = $warpdrive->getWarpDriveSplit();
57 8
                $reactorOutput = $this->getOutputCappedByLoad();
58 8
                $flightCost = $this->wrapper->get()->getRump()->getFlightEcost();
59 8
                $maxWarpdriveGain = max(0, (int)floor(($reactorOutput - $this->wrapper->getEpsUsage()) / $flightCost));
60
61 8
                $this->warpdriveProduction = (int)round((1 - ($warpdriveSplit / 100)) * $maxWarpdriveGain);
62
            }
63
        }
64
65 11
        return $this->warpdriveProduction;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->warpdriveProduction could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
66
    }
67
68 8
    #[\Override]
69
    public function getEffectiveEpsProduction(): int
70
    {
71 8
        if ($this->effectiveValues === null) {
72 8
            $this->effectiveValues = $this->calculateEffectiveProduction();
73
        }
74 8
        return $this->effectiveValues['eps'];
75
    }
76
77 6
    #[\Override]
78
    public function getEffectiveWarpDriveProduction(): int
79
    {
80 6
        if ($this->effectiveValues === null) {
81 2
            $this->effectiveValues = $this->calculateEffectiveProduction();
82
        }
83
84 6
        return $this->effectiveValues['warpdrive'];
85
    }
86
87
    /** @return array{eps: int, warpdrive: int} */
88 9
    private function calculateEffectiveProduction(): array
89
    {
90 9
        $epsSystem = $this->wrapper->getEpsSystemData();
91 9
        $warpdrive = $this->wrapper->getWarpDriveSystemData();
92
93 9
        $missingEps = $epsSystem === null ? 0 : $epsSystem->getMaxEps() - $epsSystem->getEps();
94 9
        $missingWarpdrive = $warpdrive === null ? 0 : $warpdrive->getMaxWarpdrive() - $warpdrive->getWarpDrive();
95
96 9
        $potential = $this->getOutputCappedByLoad();
97 9
        $potential -= $this->wrapper->getEpsUsage();
98
99 9
        $flightCost = $this->wrapper->get()->getRump()->getFlightEcost();
100
101 9
        $epsChange = $this->getEpsProduction() - $this->wrapper->getEpsUsage();
102 9
        $effEpsProd = min($missingEps, $epsChange);
103 9
        $effWdProd = min($missingWarpdrive, $this->getWarpdriveProduction());
104
105 9
        if ($warpdrive !== null && $warpdrive->getAutoCarryOver()) {
106
            $excess = max(0, $potential - $effEpsProd - $effWdProd * $flightCost);
107
            $epsChange = $this->getEpsProduction() + $excess - $this->wrapper->getEpsUsage();
108
109
            $effEpsProd = min($missingEps, $epsChange);
110
            $effWdProd = min($missingWarpdrive, $this->getWarpdriveProduction() + (int)floor($excess / $flightCost));
111
        }
112
113 9
        return ['eps' => $effEpsProd, 'warpdrive' => $effWdProd];
114
    }
115
116 4
    #[\Override]
117
    public function getUsage(): int
118
    {
119 4
        return $this->getEffectiveEpsProduction()
120 4
            + $this->getEffectiveWarpDriveProduction() * $this->wrapper->get()->getRump()->getFlightEcost();
121
    }
122
123 11
    #[\Override]
124
    public function getCapacity(): int
125
    {
126 11
        return $this->reactorSystemData->getCapacity();
127
    }
128
129 17
    #[\Override]
130
    public function getOutput(): int
131
    {
132 17
        return $this->reactorSystemData->getOutput();
133
    }
134
135 2
    #[\Override]
136
    public function setOutput(int $output): ReactorWrapperInterface
137
    {
138 2
        $this->reactorSystemData->setOutput($output)->update();
139
140 2
        return $this;
141
    }
142
143 15
    #[\Override]
144
    public function getOutputCappedByLoad(): int
145
    {
146 15
        if ($this->getOutput() > $this->getLoad()) {
147 4
            return $this->getLoad();
148
        }
149
150 11
        return $this->getOutput();
151
    }
152
153 20
    #[\Override]
154
    public function getLoad(): int
155
    {
156 20
        return $this->reactorSystemData->getLoad();
157
    }
158
159 1
    #[\Override]
160
    public function setLoad(int $load): ReactorWrapperInterface
161
    {
162 1
        $this->reactorSystemData->setLoad($load)->update();
163
164 1
        return $this;
165
    }
166
167 1
    #[\Override]
168
    public function changeLoad(int $amount): ReactorWrapperInterface
169
    {
170 1
        $this->reactorSystemData->setLoad($this->reactorSystemData->getLoad() + $amount)->update();
171
172 1
        return $this;
173
    }
174
175 3
    #[\Override]
176
    public function isHealthy(): bool
177
    {
178 3
        return $this->wrapper->get()->isSystemHealthy($this->reactorSystemData->getSystemType());
179
    }
180
181 9
    #[\Override]
182
    public function getReactorLoadStyle(): string
183
    {
184 9
        $load = $this->getLoad();
185 9
        $output = $this->getOutput();
186
187 9
        if ($load < $output) {
188
            return "color: red;";
189
        }
190
191 9
        if ($this->getCapacity() === 0) {
192
            return "";
193
        }
194
195 9
        $percentage = $load / $this->getCapacity();
196
197 9
        return $percentage > 0.3 ? "" : "color: yellow;";
198
    }
199
}
200