Passed
Push — master ( f544cb...b3a3d9 )
by Nico
36:43 queued 09:10
created

ColonySurface::getSurface()   B

Complexity

Conditions 8
Paths 5

Size

Total Lines 43
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 24
c 1
b 0
f 0
nc 5
nop 0
dl 0
loc 43
ccs 0
cts 26
cp 0
crap 72
rs 8.4444
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Colony\Lib;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use RuntimeException;
9
use Stu\Component\Building\BuildingEnum;
10
use Stu\Component\Colony\ColonyPopulationCalculatorInterface;
11
use Stu\Lib\Colony\PlanetFieldHostInterface;
12
use Stu\Lib\ColonyProduction\ColonyProduction;
13
use Stu\Module\Building\BuildingFunctionTypeEnum;
14
use Stu\Module\Logging\LoggerUtilInterface;
15
use Stu\Orm\Entity\ColonyInterface;
16
use Stu\Orm\Entity\ColonySandboxInterface;
17
use Stu\Orm\Entity\PlanetFieldInterface;
18
use Stu\Orm\Repository\BuildingRepositoryInterface;
19
use Stu\Orm\Repository\ColonyRepositoryInterface;
20
use Stu\Orm\Repository\PlanetFieldRepositoryInterface;
21
use Stu\Orm\Repository\ResearchedRepositoryInterface;
22
use Stu\PlanetGenerator\Exception\PlanetGeneratorException;
23
use Stu\PlanetGenerator\PlanetGeneratorInterface;
24
25
/**
26
 * Provides access to several colony surface related methods
27
 */
28
final class ColonySurface implements ColonySurfaceInterface
29
{
30
    private PlanetFieldRepositoryInterface $planetFieldRepository;
31
32
    private BuildingRepositoryInterface $buildingRepository;
33
34
    private ColonyRepositoryInterface $colonyRepository;
35
36
    private ResearchedRepositoryInterface $researchedRepository;
37
38
    private PlanetGeneratorInterface $planetGenerator;
39
40
    private EntityManagerInterface $entityManager;
41
42
    private PlanetFieldHostInterface $host;
43
44
    private ?int $buildingId;
45
46
    private bool $showUnderground;
47
48
    private PlanetFieldTypeRetrieverInterface $planetFieldTypeRetriever;
49
50
    private ColonyLibFactoryInterface $colonyLibFactory;
51
52
    private ?int $energyProduction = null;
53
54
    private ?ColonyPopulationCalculatorInterface $colonyPopulationCalculator = null;
55
56
    /** @var array<ColonyProduction>|null */
57
    private ?array $production = null;
58
59
    public function __construct(
60
        ColonyLibFactoryInterface $colonyLibFactory,
61
        PlanetFieldRepositoryInterface $planetFieldRepository,
62
        BuildingRepositoryInterface $buildingRepository,
63
        ColonyRepositoryInterface $colonyRepository,
64
        ResearchedRepositoryInterface $researchedRepository,
65
        PlanetGeneratorInterface $planetGenerator,
66
        EntityManagerInterface $entityManager,
67
        PlanetFieldTypeRetrieverInterface $planetFieldTypeRetriever,
68
        PlanetFieldHostInterface $host,
69
        ?int $buildingId,
70
        bool $showUnderground,
71
        LoggerUtilInterface $loggerUtil
0 ignored issues
show
Unused Code introduced by
The parameter $loggerUtil is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

71
        /** @scrutinizer ignore-unused */ LoggerUtilInterface $loggerUtil

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
72
    ) {
73
        $this->colonyLibFactory = $colonyLibFactory;
74
        $this->host = $host;
75
        $this->planetFieldRepository = $planetFieldRepository;
76
        $this->buildingRepository = $buildingRepository;
77
        $this->buildingId = $buildingId;
78
        $this->colonyRepository = $colonyRepository;
79
        $this->researchedRepository = $researchedRepository;
80
        $this->planetGenerator = $planetGenerator;
81
        $this->entityManager = $entityManager;
82
        $this->showUnderground = $showUnderground;
83
        $this->planetFieldTypeRetriever = $planetFieldTypeRetriever;
84
    }
85
86
    public function getSurface(): array
87
    {
88
        try {
89
            $this->updateSurface();
90
        } catch (PlanetGeneratorException $e) {
91
            return $this->host->getPlanetFields()->toArray();
92
        }
93
94
        $fields = $this->host->getPlanetFields()->toArray();
95
96
        if (!$this->showUnderground) {
97
            $fields = array_filter(
98
                $fields,
99
                fn (PlanetFieldInterface $field): bool => !$this->planetFieldTypeRetriever->isUndergroundField($field)
100
            );
101
        }
102
103
        if ($this->buildingId !== null) {
104
            $building = $this->buildingRepository->find($this->buildingId);
105
            $user = $this->host->getUser();
106
107
            $researchedArray = $this->researchedRepository->getFinishedListByUser($user->getId());
108
109
            array_walk(
110
                $fields,
111
                function (PlanetFieldInterface $field) use ($building, $researchedArray): void {
112
                    if (
113
                        $field->getTerraformingId() === null &&
114
                        $building->getBuildableFields()->containsKey($field->getFieldType())
115
                    ) {
116
                        //PlanetFieldTypeBuildingInterface
117
                        $fieldBuilding = $building->getBuildableFields()->get($field->getFieldType());
118
119
                        $researchId = $fieldBuilding->getResearchId();
120
                        if ($researchId == null || $this->isResearched($researchId, $researchedArray)) {
121
                            $field->setBuildMode(true);
122
                        }
123
                    }
124
                }
125
            );
126
        }
127
128
        return $fields;
129
    }
130
131
    private function isResearched(int $researchId, array $researched): bool
132
    {
133
        foreach ($researched as $research) {
134
            if ($research->getResearchId() == $researchId) {
135
                return true;
136
            }
137
        }
138
139
        return false;
140
    }
141
142
    public function getSurfaceTileStyle(): string
143
    {
144
        $width = $this->planetGenerator->loadColonyClassConfig($this->host->getColonyClass()->getId())['sizew'];
145
        $gridArray = [];
146
        for ($i = 0; $i < $width; $i++) {
147
            $gridArray[] = '43px';
148
        }
149
150
        return sprintf('display: grid; grid-template-columns: %s;', implode(' ', $gridArray));
151
    }
152
153
    private function getColony(): ColonyInterface
154
    {
155
        $host = $this->host;
156
        if ($host instanceof ColonyInterface) {
157
            return $host;
158
        }
159
160
        throw new RuntimeException('not available for sandbox');
161
    }
162
163
    public function getEpsBoxTitleString(): string
164
    {
165
        $energyProduction = $this->getEnergyProduction();
166
167
        $host = $this->host;
168
        if ($host instanceof ColonyInterface) {
169
            $forecast = $host->getEps() + $energyProduction;
170
            if ($host->getEps() + $energyProduction < 0) {
171
                $forecast = 0;
172
            }
173
            if ($host->getEps() + $energyProduction > $host->getMaxEps()) {
174
                $forecast = $host->getMaxEps();
175
            }
176
177
            $eps = $host->getEps();
178
        } else {
179
            $eps = 0;
180
            $forecast = $energyProduction;
181
        }
182
183
        if ($energyProduction > 0) {
184
            $energyProduction = sprintf('+%d', $energyProduction);
185
        }
186
187
        return sprintf(
188
            _('Energie: %d/%d (%s/Runde = %d)'),
189
            $eps,
190
            $host->getMaxEps(),
191
            $energyProduction,
192
            $forecast
193
        );
194
    }
195
196
    public function getShieldBoxTitleString(): string
197
    {
198
        $host = $this->host;
199
200
        return sprintf(
201
            'Schildstärke: %d/%d',
202
            $host instanceof ColonyInterface ? $host->getShields() : 0,
203
            $this->planetFieldRepository->getMaxShieldsOfColony($this->host)
204
        );
205
    }
206
207
    public function getStorageSumPercent(): float
208
    {
209
        if ($this->host instanceof ColonySandboxInterface) {
210
            return 0;
211
        }
212
213
        $colony = $this->getColony();
214
215
        $maxStorage = $colony->getMaxStorage();
216
217
        if ($maxStorage === 0) {
218
            return 0;
219
        }
220
221
        return round(100 / $maxStorage * $colony->getStorageSum(), 2);
222
    }
223
224
    public function updateSurface(): void
225
    {
226
        $host = $this->host;
227
        if (!$host instanceof ColonyInterface) {
228
            return;
229
        }
230
        if (!$host->isFree()) {
231
            return;
232
        }
233
234
        $mask = $host->getMask();
235
236
        if ($mask === null) {
237
            $planetConfig = $this->planetGenerator->generateColony(
238
                $host->getColonyClassId(),
239
                $host->getSystem()->getBonusFieldAmount()
240
            );
241
242
            $mask = base64_encode(serialize($planetConfig->getFieldArray()));
243
244
            $host->setMask($mask);
245
            $host->setSurfaceWidth($planetConfig->getSurfaceWidth());
246
247
            $this->colonyRepository->save($host);
248
        }
249
250
        $fields = $host->getPlanetFields()->toArray();
251
252
        $surface = unserialize(base64_decode($mask));
253
        foreach ($surface as $fieldId => $type) {
254
            if (!array_key_exists($fieldId, $fields)) {
255
                $newField = $this->planetFieldRepository->prototype();
256
                $fields[$fieldId] = $newField;
257
                $fields[$fieldId]->setColony($host);
258
                $fields[$fieldId]->setFieldId($fieldId);
259
                $host->getPlanetFields()->set($fieldId, $newField);
260
            }
261
262
            $fields[$fieldId]->setBuilding(null);
263
            $fields[$fieldId]->setIntegrity(0);
264
            $fields[$fieldId]->setFieldType((int) $type);
265
            $fields[$fieldId]->setActive(0);
266
267
            $this->planetFieldRepository->save($fields[$fieldId]);
268
        }
269
270
        $this->entityManager->flush();
271
    }
272
273
    public function getUserDepositMinings(): array
274
    {
275
        $production = $this->getProduction();
276
277
        $result = [];
278
        if (!$this->host instanceof ColonyInterface) {
279
            return $result;
280
        }
281
282
        foreach ($this->host->getDepositMinings() as $deposit) {
0 ignored issues
show
Bug introduced by
The method getDepositMinings() does not exist on Stu\Lib\Colony\PlanetFieldHostInterface. It seems like you code against a sub-type of Stu\Lib\Colony\PlanetFieldHostInterface such as Stu\Orm\Entity\ColonyInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

282
        foreach ($this->host->/** @scrutinizer ignore-call */ getDepositMinings() as $deposit) {
Loading history...
283
            if ($deposit->getUser() === $this->host->getUser()) {
284
                $prod = $production[$deposit->getCommodity()->getId()] ?? null;
285
286
                $result[$deposit->getCommodity()->getId()] = [
287
                    'deposit' => $deposit,
288
                    'currentlyMined' => $prod === null ? 0 : $prod->getProduction()
289
                ];
290
            }
291
        }
292
293
        return $result;
294
    }
295
296
    public function getEnergyProduction(): int
297
    {
298
        if ($this->energyProduction === null) {
299
            $this->energyProduction = $this->planetFieldRepository->getEnergyProductionByColony(
300
                $this->host
301
            );
302
        }
303
304
        return $this->energyProduction;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->energyProduction 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...
305
    }
306
307
    public function hasShipyard(): bool
308
    {
309
        return $this->planetFieldRepository->getCountByColonyAndBuildingFunctionAndState(
310
            $this->host,
311
            BuildingFunctionTypeEnum::getShipyardOptions(),
312
            [0, 1]
313
        ) > 0;
314
    }
315
316
    public function hasModuleFab(): bool
317
    {
318
        return $this->planetFieldRepository->getCountByColonyAndBuildingFunctionAndState(
319
            $this->host,
320
            BuildingFunctionTypeEnum::getModuleFabOptions(),
321
            [0, 1]
322
        ) > 0;
323
    }
324
325
    public function hasAirfield(): bool
326
    {
327
        return $this->planetFieldRepository->getCountByColonyAndBuildingFunctionAndState(
328
            $this->host,
329
            [BuildingEnum::BUILDING_FUNCTION_AIRFIELD],
330
            [0, 1]
331
        ) > 0;
332
    }
333
334
    public function getPopulation(): ColonyPopulationCalculatorInterface
335
    {
336
        if ($this->colonyPopulationCalculator === null) {
337
            $this->colonyPopulationCalculator = $this->colonyLibFactory->createColonyPopulationCalculator(
338
                $this->host,
339
                $this->getProduction()
340
            );
341
        }
342
343
        return $this->colonyPopulationCalculator;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->colonyPopulationCalculator could return the type null which is incompatible with the type-hinted return Stu\Component\Colony\Col...tionCalculatorInterface. Consider adding an additional type-check to rule them out.
Loading history...
344
    }
345
346
    /**
347
     * @return array<ColonyProduction>
348
     */
349
    private function getProduction(): array
350
    {
351
        if ($this->production === null) {
352
            $this->production = $this->colonyLibFactory->createColonyCommodityProduction($this->host)->getProduction();
353
        }
354
355
        return $this->production;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->production could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
356
    }
357
}
358