Passed
Pull Request — master (#2040)
by Nico
20:26 queued 08:51
created

SpacecraftTick::doBussardCollectorStuff()   C

Complexity

Conditions 12
Paths 51

Size

Total Lines 57
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 12
eloc 39
c 2
b 1
f 0
nc 51
nop 2
dl 0
loc 57
ccs 0
cts 39
cp 0
crap 156
rs 6.9666

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;
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 RuntimeException;
7
use Stu\Component\Faction\FactionEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Faction\FactionEnum 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\Ship\AstronomicalMappingEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Ship\AstronomicalMappingEnum 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...
9
use Stu\Component\Spacecraft\Repair\RepairUtilInterface;
10
use Stu\Component\Spacecraft\SpacecraftAlertStateEnum;
11
use Stu\Component\Spacecraft\SpacecraftStateEnum;
12
use Stu\Lib\Transfer\Storage\StorageManagerInterface;
13
use Stu\Component\Spacecraft\System\Data\EpsSystemData;
14
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
15
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
16
use Stu\Component\Station\StationUtilityInterface;
17
use Stu\Lib\Information\InformationFactoryInterface;
18
use Stu\Lib\Information\InformationWrapper;
19
use Stu\Module\Control\GameControllerInterface;
20
use Stu\Module\Commodity\CommodityTypeEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Module\Commodity\CommodityTypeEnum 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...
21
use Stu\Module\Database\Lib\CreateDatabaseEntryInterface;
22
use Stu\Module\Logging\LoggerUtilFactoryInterface;
23
use Stu\Module\Logging\LoggerUtilInterface;
24
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
25
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
26
use Stu\Module\PlayerSetting\Lib\UserEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserEnum 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...
27
use Stu\Module\Ship\Lib\AstroEntryLibInterface;
28
use Stu\Module\Spacecraft\Lib\Crew\SpacecraftLeaverInterface;
29
use Stu\Module\Spacecraft\Lib\Interaction\ShipTakeoverManagerInterface;
30
use Stu\Module\Spacecraft\Lib\Interaction\TrackerDeviceManagerInterface;
31
use Stu\Module\Spacecraft\Lib\ReactorWrapperInterface;
32
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
33
use Stu\Module\Ship\Lib\ShipWrapperInterface;
34
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
35
use Stu\Module\Station\Lib\StationWrapperInterface;
36
use Stu\Module\Tick\Spacecraft\ManagerComponent\ManagerComponentInterface;
37
use Stu\Orm\Entity\DatabaseEntryInterface;
38
use Stu\Orm\Entity\ShipInterface;
39
use Stu\Orm\Entity\SpacecraftInterface;
40
use Stu\Orm\Entity\StationInterface;
41
use Stu\Orm\Repository\DatabaseUserRepositoryInterface;
42
use Stu\Orm\Repository\LocationMiningRepositoryInterface;
43
use Stu\Orm\Repository\CommodityRepositoryInterface;
44
use Stu\Orm\Repository\SpacecraftRepositoryInterface;
45
use Stu\Orm\Repository\StorageRepositoryInterface;
46
47
final class SpacecraftTick implements SpacecraftTickInterface, ManagerComponentInterface
48
{
49
    private LoggerUtilInterface $loggerUtil;
50
51 1
    public function __construct(
52
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
53
        private PrivateMessageSenderInterface $privateMessageSender,
54
        private SpacecraftRepositoryInterface $spacecraftRepository,
55
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
56
        private SpacecraftLeaverInterface $spacecraftLeaver,
57
        private GameControllerInterface $game,
58
        private AstroEntryLibInterface $astroEntryLib,
59
        private DatabaseUserRepositoryInterface $databaseUserRepository,
60
        private CreateDatabaseEntryInterface $createDatabaseEntry,
61
        private StationUtilityInterface $stationUtility,
62
        private RepairUtilInterface $repairUtil,
63
        private ShipTakeoverManagerInterface $shipTakeoverManager,
64
        private TrackerDeviceManagerInterface $trackerDeviceManager,
65
        private StorageManagerInterface $storageManager,
66
        private LocationMiningRepositoryInterface $locationMiningRepository,
67
        private CommodityRepositoryInterface $commodityRepository,
68
        private StorageRepositoryInterface $storageRepository,
69
        private InformationFactoryInterface $informationFactory,
70
        LoggerUtilFactoryInterface $loggerUtilFactory
71
    ) {
72 1
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil(true);
73
    }
74
75
    #[Override]
76
    public function work(): void
77
    {
78
        foreach ($this->spacecraftRepository->getPlayerSpacecraftsForTick() as $spacecraft) {
79
            $this->workSpacecraft($this->spacecraftWrapperFactory->wrapSpacecraft($spacecraft));
80
        }
81
    }
82
83
    #[Override]
84
    public function workSpacecraft(SpacecraftWrapperInterface $wrapper): void
85
    {
86
        $informationWrapper = $this->informationFactory->createInformationWrapper();
87
88
        $this->workSpacecraftInternal($wrapper, $informationWrapper);
89
90
        $this->sendMessage($wrapper->get(), $informationWrapper);
91
    }
92
93
    private function workSpacecraftInternal(SpacecraftWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
94
    {
95
        $spacecraft = $wrapper->get();
96
97
        $startTime = microtime(true);
98
99
        // do construction stuff
100
        if ($spacecraft instanceof StationInterface && $this->doConstructionStuff($spacecraft, $informationWrapper)) {
101
            $this->spacecraftRepository->save($spacecraft);
102
            return;
103
        }
104
105
        $this->potentialLog($spacecraft, "marker0", $startTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime can also be of type string; however, parameter $startTime of Stu\Module\Tick\Spacecra...aftTick::potentialLog() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

105
        $this->potentialLog($spacecraft, "marker0", /** @scrutinizer ignore-type */ $startTime);
Loading history...
106
107
108
        $startTime = microtime(true);
109
        // repair station
110
        if ($wrapper instanceof StationWrapperInterface && $spacecraft->getState() === SpacecraftStateEnum::REPAIR_PASSIVE) {
111
            $this->doRepairStation($wrapper, $informationWrapper);
112
        }
113
        $this->potentialLog($spacecraft, "marker1", $startTime);
114
115
        $startTime = microtime(true);
116
        // leave ship
117
        if ($spacecraft->getCrewCount() > 0 && !$spacecraft->isSystemHealthy(SpacecraftSystemTypeEnum::LIFE_SUPPORT)) {
118
            $informationWrapper->addInformation('Die Lebenserhaltung ist ausgefallen:');
119
            $informationWrapper->addInformation($this->spacecraftLeaver->evacuate($wrapper));
120
            $this->potentialLog($spacecraft, "marker2", $startTime);
121
            return;
122
        }
123
124
        $startTime = microtime(true);
125
        $eps = $wrapper->getEpsSystemData();
126
        $reactor = $wrapper->getReactorWrapper();
127
        if ($eps === null) {
128
            $this->potentialLog($spacecraft, "marker3", $startTime);
129
            return;
130
        }
131
132
        $startTime = microtime(true);
133
        $hasEnoughCrew = $spacecraft->hasEnoughCrew();
134
135
        // not enough crew
136
        if (!$hasEnoughCrew) {
137
            $informationWrapper->addInformation('Zu wenig Crew an Bord, Schiff ist nicht voll funktionsfähig! Systeme werden deaktiviert!');
138
139
            //deactivate all systems except life support
140
            foreach ($this->spacecraftSystemManager->getActiveSystems($spacecraft) as $system) {
141
                if ($system->getSystemType() != SpacecraftSystemTypeEnum::LIFE_SUPPORT) {
142
                    $this->spacecraftSystemManager->deactivate($wrapper, $system->getSystemType(), true);
143
                }
144
            }
145
        }
146
        $this->potentialLog($spacecraft, "marker4", $startTime);
147
148
        $startTime = microtime(true);
149
        $reactorUsageForWarpdrive = $this->loadWarpdrive(
150
            $wrapper,
151
            $hasEnoughCrew
152
        );
153
        $this->potentialLog($spacecraft, "marker5", $startTime);
154
155
        $startTime = microtime(true);
156
        $availableEps = $this->getAvailableEps(
157
            $wrapper,
158
            $eps,
159
            $reactor,
160
            $hasEnoughCrew,
161
            $reactorUsageForWarpdrive
162
        );
163
        $this->potentialLog($spacecraft, "marker6", $startTime);
164
165
        $startTime = microtime(true);
166
        //try to save energy by reducing alert state
167
        if ($wrapper->getEpsUsage() > $availableEps) {
168
            $malus = $wrapper->getEpsUsage() - $availableEps;
169
            $alertUsage = $spacecraft->getAlertState()->value - 1;
170
171
            if ($alertUsage > 0) {
172
                $preState = $spacecraft->getAlertState();
173
                $reduce = (int)min($malus, $alertUsage);
174
175
                $spacecraft->setAlertState(SpacecraftAlertStateEnum::from($preState->value - $reduce));
176
                $informationWrapper->addInformationf(
177
                    'Wechsel von %s auf %s wegen Energiemangel',
178
                    $preState->getDescription(),
179
                    $spacecraft->getAlertState()->getDescription()
180
                );
181
            }
182
        }
183
        $this->potentialLog($spacecraft, "marker7", $startTime);
184
185
        $startTime = microtime(true);
186
        //try to save energy by deactivating systems from low to high priority
187
        if ($wrapper->getEpsUsage() > $availableEps) {
188
            $activeSystems = $this->spacecraftSystemManager->getActiveSystems($spacecraft, true);
189
190
            foreach ($activeSystems as $system) {
191
                $energyConsumption = $this->spacecraftSystemManager->getEnergyConsumption($system->getSystemType());
192
                if ($energyConsumption < 1) {
193
                    continue;
194
                }
195
196
                //echo "- eps: ".$eps." - usage: ".$wrapper->getEpsUsage()."\n";
197
                if ($availableEps - $wrapper->getEpsUsage() - $energyConsumption < 0) {
198
                    //echo "-- hit system: ".$system->getDescription()."\n";
199
200
                    $this->spacecraftSystemManager->deactivate($wrapper, $system->getSystemType(), true);
201
202
                    $wrapper->lowerEpsUsage($energyConsumption);
203
                    $informationWrapper->addInformationf('%s deaktiviert wegen Energiemangel', $system->getSystemType()->getDescription());
204
205
                    if ($spacecraft->getCrewCount() > 0 && $system->getSystemType() == SpacecraftSystemTypeEnum::LIFE_SUPPORT) {
206
                        $informationWrapper->addInformation('Die Lebenserhaltung ist ausgefallen:');
207
                        $informationWrapper->addInformation($this->spacecraftLeaver->evacuate($wrapper));
208
                        return;
209
                    }
210
                }
211
                if ($wrapper->getEpsUsage() <= $availableEps) {
212
                    break;
213
                }
214
            }
215
        }
216
217
        $this->potentialLog($spacecraft, "marker8", $startTime);
218
        $startTime = microtime(true);
219
220
        $newEps = $availableEps - $wrapper->getEpsUsage();
221
        $batteryReload = $spacecraft->isStation()
222
            && $eps->reloadBattery()
223
            && $newEps > $eps->getEps()
224
            ? min(
225
                (int) ceil($eps->getMaxBattery() / 10),
226
                $newEps - $eps->getEps(),
227
                $eps->getMaxBattery() - $eps->getBattery()
228
            ) : 0;
229
230
        $newEps -= $batteryReload;
231
        if ($newEps > $eps->getMaxEps()) {
232
            $newEps = $eps->getMaxEps();
233
        }
234
235
236
        $usedEnergy = $wrapper->getEpsUsage() + $batteryReload + ($newEps - $eps->getEps()) + $reactorUsageForWarpdrive;
237
238
        //echo "--- Generated Id ".$ship->getId()." - eps: ".$eps." - usage: ".$wrapper->getEpsUsage()." - old eps: ".$ship->getEps()." - wk: ".$wkuse."\n";
239
        $eps->setEps($newEps)
240
            ->setBattery($eps->getBattery() + $batteryReload)
241
            ->update();
242
243
        if ($usedEnergy > 0 && $reactor !== null) {
244
            $reactor->changeLoad(-$usedEnergy);
245
        }
246
247
        $this->potentialLog($spacecraft, "marker9", $startTime);
248
249
        $startTime = microtime(true);
250
        $this->checkForFinishedTakeover($spacecraft);
251
        $this->potentialLog($spacecraft, "marker10", $startTime);
252
253
        $startTime = microtime(true);
254
        $this->checkForFinishedAstroMapping($wrapper, $informationWrapper);
255
        $this->potentialLog($spacecraft, "marker11", $startTime);
256
257
        //update tracker status
258
        $startTime = microtime(true);
259
        $this->doTrackerDeviceStuff($wrapper);
260
        $this->potentialLog($spacecraft, "marker12", $startTime);
261
262
        $startTime = microtime(true);
263
        $this->spacecraftRepository->save($spacecraft);
264
        $this->potentialLog($spacecraft, "marker13", $startTime);
265
266
        $startTime = microtime(true);
267
        $this->doBussardCollectorStuff($wrapper, $informationWrapper);
268
        $this->potentialLog($spacecraft, "marker15", $startTime);
269
270
        $startTime = microtime(true);
271
        $this->doAggregationSystemStuff($wrapper, $informationWrapper);
272
        $this->potentialLog($spacecraft, "marker16", $startTime);
273
    }
274
275
    private function potentialLog(SpacecraftInterface $spacecraft, string $marker, float $startTime): void
276
    {
277
        $endTime = microtime(true);
278
279
        if (
280
            $endTime - $startTime > 0.01
281
        ) {
282
            $this->loggerUtil->log(sprintf(
283
                "\t\t\t%s of %d, seconds: %F",
284
                $marker,
285
                $spacecraft->getId(),
286
                $endTime - $startTime
287
            ));
288
        }
289
    }
290
291
    private function getAvailableEps(
292
        SpacecraftWrapperInterface $wrapper,
293
        EpsSystemData $eps,
294
        ?ReactorWrapperInterface $reactor,
295
        bool $hasEnoughCrew,
296
        int $reactorUsageForWarpdrive
297
    ): int {
298
        if ($hasEnoughCrew && $reactor !== null) {
299
300
            return $eps->getEps() + $reactor->getEpsProduction() +  $this->getCarryOver(
301
                $wrapper,
302
                $reactor,
303
                $reactorUsageForWarpdrive
304
            );
305
        }
306
307
        return $eps->getEps();
308
    }
309
310
    private function getCarryOver(
311
        SpacecraftWrapperInterface $wrapper,
312
        ReactorWrapperInterface $reactor,
313
        int $reactorUsageForWarpdrive
314
    ): int {
315
        $warpdrive = $wrapper->getWarpDriveSystemData();
316
        if ($warpdrive === null || !$warpdrive->getAutoCarryOver()) {
317
            return 0;
318
        }
319
320
        return $reactor->getOutputCappedByLoad() - $reactor->getEpsProduction() - $reactorUsageForWarpdrive;
321
    }
322
323
    private function loadWarpdrive(SpacecraftWrapperInterface $wrapper, bool $hasEnoughCrew): int
324
    {
325
        if (!$hasEnoughCrew) {
326
            return 0;
327
        }
328
329
        $reactor = $wrapper->getReactorWrapper();
330
        $warpdrive = $wrapper->getWarpDriveSystemData();
331
        if ($warpdrive === null || $reactor === null) {
332
            return 0;
333
        }
334
335
        $effectiveWarpdriveProduction = $reactor->getEffectiveWarpDriveProduction();
336
        if ($effectiveWarpdriveProduction === 0) {
337
            return 0;
338
        }
339
340
        $currentLoad = $warpdrive->getWarpDrive();
341
342
        $warpdrive->setWarpDrive($currentLoad + $effectiveWarpdriveProduction)->update();
343
344
        return $effectiveWarpdriveProduction * $wrapper->get()->getRump()->getFlightECost();
345
    }
346
347
    private function doConstructionStuff(StationInterface $station, InformationWrapper $informationWrapper): bool
348
    {
349
        $progress =  $station->getConstructionProgress();
350
        if ($progress === null) {
351
            return false;
352
        }
353
354
        if ($progress->getRemainingTicks() === 0) {
355
            return false;
356
        }
357
358
        $isUnderConstruction = $station->getState() === SpacecraftStateEnum::UNDER_CONSTRUCTION;
359
360
        if (!$this->stationUtility->hasEnoughDockedWorkbees($station, $station->getRump())) {
361
            $neededWorkbees = $isUnderConstruction ? $station->getRump()->getNeededWorkbees() :
362
                (int)ceil($station->getRump()->getNeededWorkbees() / 2);
363
364
            $informationWrapper->addInformationf(
365
                'Nicht genügend Workbees (%d/%d) angedockt um %s weiterführen zu können',
366
                $this->stationUtility->getDockedWorkbeeCount($station),
367
                $neededWorkbees ?? 0,
368
                $isUnderConstruction ? 'den Bau' : 'die Demontage'
369
            );
370
            return true;
371
        }
372
373
        if ($isUnderConstruction) {
374
            // raise hull
375
            $increase = (int)ceil($station->getMaxHull() / (2 * $station->getRump()->getBuildtime()));
376
            $station->setHuell($station->getHull() + $increase);
377
        }
378
379
        if ($progress->getRemainingTicks() === 1) {
380
381
            $informationWrapper->addInformationf(
382
                '%s: %s bei %s fertiggestellt',
383
                $station->getRump()->getName(),
384
                $isUnderConstruction ? 'Bau' : 'Demontage',
385
                $station->getSectorString()
386
            );
387
388
            if ($isUnderConstruction) {
389
                $this->stationUtility->finishStation($progress);
390
            } else {
391
                $this->stationUtility->finishScrapping($progress, $informationWrapper);
392
            }
393
        } else {
394
            $this->stationUtility->reduceRemainingTicks($progress);
395
        }
396
397
        return true;
398
    }
399
400
    private function doRepairStation(StationWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
401
    {
402
        $station = $wrapper->get();
403
404
        if (!$this->stationUtility->hasEnoughDockedWorkbees($station, $station->getRump())) {
405
            $neededWorkbees = (int)ceil($station->getRump()->getNeededWorkbees() / 5);
406
407
            $informationWrapper->addInformationf(
408
                'Nicht genügend Workbees (%d/%d) angedockt um die Reparatur weiterführen zu können',
409
                $this->stationUtility->getDockedWorkbeeCount($station),
410
                $neededWorkbees
411
            );
412
            return;
413
        }
414
415
        $neededParts = $this->repairUtil->determineSpareParts($wrapper, true);
416
417
        // parts stored?
418
        if (!$this->repairUtil->enoughSparePartsOnEntity($neededParts, $station, $station)) {
419
            return;
420
        }
421
422
        //repair hull
423
        $station->setHuell($station->getHull() + $station->getRepairRate());
424
        if ($station->getHull() > $station->getMaxHull()) {
425
            $station->setHuell($station->getMaxHull());
426
        }
427
428
        //repair station systems
429
        $damagedSystems = $wrapper->getDamagedSystems();
430
        if ($damagedSystems !== []) {
431
            $firstSystem = $damagedSystems[0];
432
            $firstSystem->setStatus(100);
433
434
            if ($station->getCrewCount() > 0) {
435
                $firstSystem->setMode($this->spacecraftSystemManager->lookupSystem($firstSystem->getSystemType())->getDefaultMode());
436
            }
437
438
            // maximum of two systems get repaired
439
            if (count($damagedSystems) > 1) {
440
                $secondSystem = $damagedSystems[1];
441
                $secondSystem->setStatus(100);
442
443
                if ($station->getCrewCount() > 0) {
444
                    $secondSystem->setMode($this->spacecraftSystemManager->lookupSystem($secondSystem->getSystemType())->getDefaultMode());
445
                }
446
            }
447
        }
448
449
        // consume spare parts
450
        $this->repairUtil->consumeSpareParts($neededParts, $station);
451
452
        if (!$wrapper->canBeRepaired()) {
453
            $station->setHuell($station->getMaxHull());
454
            $station->setState(SpacecraftStateEnum::NONE);
455
456
            $shipOwnerMessage = sprintf(
457
                "Die Reparatur der %s wurde in Sektor %s fertiggestellt",
458
                $station->getName(),
459
                $station->getSectorString()
460
            );
461
462
            $this->privateMessageSender->send(
463
                UserEnum::USER_NOONE,
464
                $station->getUser()->getId(),
465
                $shipOwnerMessage,
466
                PrivateMessageFolderTypeEnum::SPECIAL_STATION
467
            );
468
        }
469
        $this->spacecraftRepository->save($station);
470
    }
471
472
    private function checkForFinishedTakeover(SpacecraftInterface $spacecraft): void
473
    {
474
        $startTime = microtime(true);
475
        $takeover = $spacecraft->getTakeoverActive();
476
        if ($takeover === null) {
477
            return;
478
        }
479
        $this->potentialLog($spacecraft, "marker10.1", $startTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime can also be of type string; however, parameter $startTime of Stu\Module\Tick\Spacecra...aftTick::potentialLog() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

479
        $this->potentialLog($spacecraft, "marker10.1", /** @scrutinizer ignore-type */ $startTime);
Loading history...
480
481
        $startTime = microtime(true);
482
        $isTakeoverReady = $this->shipTakeoverManager->isTakeoverReady($takeover);
483
        $this->potentialLog($spacecraft, "marker10.2", $startTime);
484
485
        if ($isTakeoverReady) {
486
            $startTime = microtime(true);
487
            $this->shipTakeoverManager->finishTakeover($takeover);
488
            $this->potentialLog($spacecraft, "marker10.3", $startTime);
489
        }
490
    }
491
492
    private function checkForFinishedAstroMapping(SpacecraftWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
493
    {
494
        if (!$wrapper instanceof ShipWrapperInterface) {
495
            return;
496
        }
497
498
        $ship = $wrapper->get();
499
500
        $startTime = microtime(true);
501
502
        /** @var null|DatabaseEntryInterface $databaseEntry */
503
        /** @var string $message */
504
        [$message, $databaseEntry] = $this->getDatabaseEntryForShipLocation($ship);
505
506
        $astroLab = $wrapper->getAstroLaboratorySystemData();
507
508
        $this->potentialLog($ship, "marker11.1", $startTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime can also be of type string; however, parameter $startTime of Stu\Module\Tick\Spacecra...aftTick::potentialLog() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

508
        $this->potentialLog($ship, "marker11.1", /** @scrutinizer ignore-type */ $startTime);
Loading history...
509
510
        if (
511
            $ship->getState() === SpacecraftStateEnum::ASTRO_FINALIZING
512
            && $databaseEntry !== null
513
            && $astroLab !== null
514
            && $this->game->getCurrentRound()->getTurn() >= ($astroLab->getAstroStartTurn() + AstronomicalMappingEnum::TURNS_TO_FINISH)
515
        ) {
516
517
            $startTime = microtime(true);
518
            $this->astroEntryLib->finish($wrapper);
519
            $this->potentialLog($ship, "marker11.2", $startTime);
520
521
            $informationWrapper->addInformationf(
522
                'Die Kartographierung %s wurde vollendet',
523
                $message
524
            );
525
526
            $userId = $ship->getUser()->getId();
527
            $databaseEntryId = $databaseEntry->getId();
528
529
            $startTime = microtime(true);
530
531
            if (!$this->databaseUserRepository->exists($userId, $databaseEntryId)) {
532
533
                $this->potentialLog($ship, "marker11.3", $startTime);
534
                $startTime = microtime(true);
535
536
                $entry = $this->createDatabaseEntry->createDatabaseEntryForUser($ship->getUser(), $databaseEntryId);
537
538
                if ($entry !== null) {
539
                    $informationWrapper->addInformationf(
540
                        'Neuer Datenbankeintrag: %s (+%d Punkte)',
541
                        $entry->getDescription(),
542
                        $entry->getCategory()->getPoints()
543
                    );
544
                }
545
            }
546
547
            $this->potentialLog($ship, "marker11.4", $startTime);
548
        }
549
    }
550
551
    /**
552
     * @return array{0: string|null, 1: DatabaseEntryInterface|null}
553
     */
554
    private function getDatabaseEntryForShipLocation(ShipInterface $ship): array
555
    {
556
        $system = $ship->getSystem();
557
        if ($system !== null) {
558
            return [
559
                'des Systems ' . $system->getName(),
560
                $system->getDatabaseEntry()
561
            ];
562
        }
563
564
        $mapRegion = $ship->getMapRegion();
565
        if ($mapRegion !== null) {
566
            return [
567
                'der Region ' . $mapRegion->getDescription(),
568
                $mapRegion->getDatabaseEntry()
569
            ];
570
        }
571
572
        return [null, null];
573
    }
574
575
    private function doTrackerDeviceStuff(SpacecraftWrapperInterface $wrapper): void
576
    {
577
        if (!$wrapper instanceof ShipWrapperInterface) {
578
            return;
579
        }
580
581
        $ship = $wrapper->get();
582
        $tracker = $wrapper->getTrackerSystemData();
583
584
        if ($tracker === null || $tracker->targetId === null) {
585
            return;
586
        }
587
588
        $targetWrapper = $tracker->getTargetWrapper();
589
        if ($targetWrapper === null) {
590
            throw new RuntimeException('should not happen');
591
        }
592
593
        $target = $targetWrapper->get();
594
        $shipLocation = $ship->getLocation();
595
        $targetLocation = $target->getLocation();
596
        $remainingTicks = $tracker->getRemainingTicks();
597
598
        $reduceByTicks = max(1, (int)ceil((abs($shipLocation->getCx() - $targetLocation->getCx())
599
            +  abs($shipLocation->getCy() - $targetLocation->getCy())) / 50));
600
601
        //reduce remaining ticks
602
        if ($remainingTicks > $reduceByTicks) {
603
            $tracker->setRemainingTicks($remainingTicks - $reduceByTicks)->update();
604
        } else {
605
            $this->trackerDeviceManager->deactivateTrackerIfActive($wrapper, true);
606
        }
607
    }
608
609
    private function doBussardCollectorStuff(SpacecraftWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
610
    {
611
        if (!$wrapper instanceof ShipWrapperInterface) {
612
            return;
613
        }
614
615
        $ship = $wrapper->get();
616
        $bussard = $wrapper->getBussardCollectorSystemData();
617
        $miningqueue = $ship->getMiningQueue();
618
619
        if ($bussard === null) {
620
            return;
621
        }
622
623
        if ($miningqueue == null) {
624
            return;
625
        } else {
626
            $locationmining = $miningqueue->getLocationMining();
627
            $actualAmount = $locationmining->getActualAmount();
628
            $freeStorage = $ship->getMaxStorage() - $ship->getStorageSum();
629
            $module = $ship->getSpacecraftSystem(SpacecraftSystemTypeEnum::BUSSARD_COLLECTOR)->getModule();
630
            $gathercount = 0;
631
632
            if ($module !== null) {
633
                if ($module->getFactionId() == null) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $module->getFactionId() of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
634
                    $gathercount =  (int) min(min(round(mt_rand(95, 105)), $actualAmount), $freeStorage);
635
                } else {
636
                    $gathercount = (int) min(min(round(mt_rand(190, 220)), $actualAmount), $freeStorage);
637
                }
638
            }
639
640
            $newAmount = $actualAmount - $gathercount;
641
            if ($gathercount > 0 && $locationmining->getDepletedAt() !== null) {
642
                $locationmining->setDepletedAt(null);
643
644
                $informationWrapper->addInformationf(
645
                    'Es sind keine %s bei den Koordinaten %s|%s vorhanden!',
646
                    $locationmining->getCommodity()->getName(),
647
                    (string)$locationmining->getLocation()->getCx(),
648
                    (string)$locationmining->getLocation()->getCy()
649
                );
650
            }
651
            if ($newAmount == 0 && $actualAmount > 0) {
652
                $locationmining->setDepletedAt(time());
653
            }
654
            $locationmining->setActualAmount($newAmount);
655
656
            $this->locationMiningRepository->save($locationmining);
657
            if ($gathercount + $ship->getStorageSum() >= $ship->getMaxStorage()) {
658
                $informationWrapper->addInformationf('Der Lagerraum des Schiffes wurde beim Sammeln von %s voll!', $locationmining->getCommodity()->getName());
659
            }
660
661
            if ($gathercount > 0) {
662
                $this->storageManager->upperStorage(
663
                    $ship,
664
                    $locationmining->getCommodity(),
665
                    $gathercount
666
                );
667
            }
668
        }
669
    }
670
671
    private function doAggregationSystemStuff(SpacecraftWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
672
    {
673
        if (!$wrapper instanceof StationWrapperInterface) {
674
            return;
675
        }
676
677
        $station = $wrapper->get();
678
        $aggsys = $wrapper->getAggregationSystemSystemData();
679
680
        if ($aggsys === null) {
681
            return;
682
        } else {
683
            $module = $station->getSpacecraftSystem(SpacecraftSystemTypeEnum::AGGREGATION_SYSTEM)->getModule();
684
            $producedAmount = 0;
685
            $usedAmount = 0;
686
            $usedCommodity = null;
687
            $producedCommodity = null;
688
689
690
            if ($module !== null) {
691
                $commodity = $aggsys->getCommodityId();
692
                $commodities = CommodityTypeEnum::COMMODITY_CONVERSIONS;
693
694
                if ($commodity > 0) {
695
                    foreach ($commodities as $entry) {
696
                        if ($entry[0] === $commodity) {
697
                            $producedCommodityId = $entry[1];
698
                            $producedCommodity = $this->commodityRepository->find($producedCommodityId);
699
                            $usedCommodity = $this->commodityRepository->find($entry[0]);
700
                            $usedAmount = $entry[2];
701
                            $producedAmount = $entry[3];
702
                            break;
703
                        }
704
                    }
705
706
                    if ($module->getFactionId() == FactionEnum::FACTION_FERENGI) {
707
                        $producedAmount *= 2;
708
                        $usedAmount *= 2;
709
                    }
710
                    $storage = $this->storageRepository->findOneBy([
711
                        'commodity' => $usedCommodity,
712
                        'spacecraft' => $station
713
                    ]);
714
                    if (!$storage && $usedCommodity) {
715
                        $informationWrapper->addInformationf('Es ist kein %s vorhanden!', $usedCommodity->getName());
716
                    }
717
718
                    if ($storage && $producedCommodity && $usedCommodity) {
719
                        if ($storage->getAmount() >= $usedAmount) {
720
                            $this->storageManager->lowerStorage(
721
                                $station,
722
                                $usedCommodity,
723
                                $usedAmount
724
                            );
725
                            $this->storageManager->upperStorage(
726
                                $station,
727
                                $producedCommodity,
728
                                $producedAmount
729
                            );
730
                        } else {
731
                            $informationWrapper->addInformationf('Nicht genügend %s vorhanden!', $usedCommodity->getName());
732
                        }
733
                    }
734
                }
735
            }
736
        }
737
    }
738
739
740
741
    private function sendMessage(SpacecraftInterface $ship, InformationWrapper $informationWrapper): void
742
    {
743
        if ($informationWrapper->isEmpty()) {
744
            return;
745
        }
746
747
        $text = sprintf("Tickreport der %s\n%s", $ship->getName(), $informationWrapper->getInformationsAsString());
748
749
        $this->privateMessageSender->send(
750
            UserEnum::USER_NOONE,
751
            $ship->getUser()->getId(),
752
            $text,
753
            $ship->getType()->getMessageFolderType(),
754
            $ship
755
        );
756
    }
757
}
758