Passed
Pull Request — master (#2043)
by Janko
20:39 queued 09:47
created

SpacecraftTick::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 20
dl 0
loc 23
ccs 2
cts 2
cp 1
crap 1
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\Map\Effects\EffectHandlingInterface;
9
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...
10
use Stu\Component\Spacecraft\Repair\RepairUtilInterface;
11
use Stu\Component\Spacecraft\SpacecraftAlertStateEnum;
12
use Stu\Component\Spacecraft\SpacecraftStateEnum;
13
use Stu\Lib\Transfer\Storage\StorageManagerInterface;
14
use Stu\Component\Spacecraft\System\Data\EpsSystemData;
15
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
16
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
17
use Stu\Component\Station\StationUtilityInterface;
18
use Stu\Lib\Information\InformationFactoryInterface;
19
use Stu\Lib\Information\InformationWrapper;
20
use Stu\Module\Control\GameControllerInterface;
21
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...
22
use Stu\Module\Database\Lib\CreateDatabaseEntryInterface;
23
use Stu\Module\Logging\LoggerUtilFactoryInterface;
24
use Stu\Module\Logging\LoggerUtilInterface;
25
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
26
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
27
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...
28
use Stu\Module\Ship\Lib\AstroEntryLibInterface;
29
use Stu\Module\Spacecraft\Lib\Crew\SpacecraftLeaverInterface;
30
use Stu\Module\Spacecraft\Lib\Interaction\ShipTakeoverManagerInterface;
31
use Stu\Module\Spacecraft\Lib\Interaction\TrackerDeviceManagerInterface;
32
use Stu\Module\Spacecraft\Lib\ReactorWrapperInterface;
33
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
34
use Stu\Module\Ship\Lib\ShipWrapperInterface;
35
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
36
use Stu\Module\Station\Lib\StationWrapperInterface;
37
use Stu\Module\Tick\Spacecraft\ManagerComponent\ManagerComponentInterface;
38
use Stu\Orm\Entity\DatabaseEntryInterface;
39
use Stu\Orm\Entity\ShipInterface;
40
use Stu\Orm\Entity\SpacecraftInterface;
41
use Stu\Orm\Entity\StationInterface;
42
use Stu\Orm\Repository\DatabaseUserRepositoryInterface;
43
use Stu\Orm\Repository\LocationMiningRepositoryInterface;
44
use Stu\Orm\Repository\CommodityRepositoryInterface;
45
use Stu\Orm\Repository\SpacecraftRepositoryInterface;
46
use Stu\Orm\Repository\StorageRepositoryInterface;
47
48
final class SpacecraftTick implements SpacecraftTickInterface, ManagerComponentInterface
49
{
50
    private LoggerUtilInterface $loggerUtil;
51
52 1
    public function __construct(
53
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
54
        private PrivateMessageSenderInterface $privateMessageSender,
55
        private SpacecraftRepositoryInterface $spacecraftRepository,
56
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
57
        private EffectHandlingInterface $effectHandlingInterface,
58
        private SpacecraftLeaverInterface $spacecraftLeaver,
59
        private GameControllerInterface $game,
60
        private AstroEntryLibInterface $astroEntryLib,
61
        private DatabaseUserRepositoryInterface $databaseUserRepository,
62
        private CreateDatabaseEntryInterface $createDatabaseEntry,
63
        private StationUtilityInterface $stationUtility,
64
        private RepairUtilInterface $repairUtil,
65
        private ShipTakeoverManagerInterface $shipTakeoverManager,
66
        private TrackerDeviceManagerInterface $trackerDeviceManager,
67
        private StorageManagerInterface $storageManager,
68
        private LocationMiningRepositoryInterface $locationMiningRepository,
69
        private CommodityRepositoryInterface $commodityRepository,
70
        private StorageRepositoryInterface $storageRepository,
71
        private InformationFactoryInterface $informationFactory,
72
        LoggerUtilFactoryInterface $loggerUtilFactory
73
    ) {
74 1
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil(true);
75
    }
76
77
    #[Override]
78
    public function work(): void
79
    {
80
        foreach ($this->spacecraftRepository->getPlayerSpacecraftsForTick() as $spacecraft) {
81
            $this->workSpacecraft($this->spacecraftWrapperFactory->wrapSpacecraft($spacecraft));
82
        }
83
    }
84
85
    #[Override]
86
    public function workSpacecraft(SpacecraftWrapperInterface $wrapper): void
87
    {
88
        $informationWrapper = $this->informationFactory->createInformationWrapper();
89
90
        $this->workSpacecraftInternal($wrapper, $informationWrapper);
91
92
        $this->sendMessage($wrapper->get(), $informationWrapper);
93
    }
94
95
    private function workSpacecraftInternal(SpacecraftWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
96
    {
97
        $spacecraft = $wrapper->get();
98
99
        $startTime = microtime(true);
100
        $this->effectHandlingInterface->handleSpacecraftTick($wrapper, $informationWrapper);
101
        $this->potentialLog($spacecraft, "marker0.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

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

485
        $this->potentialLog($spacecraft, "marker10.1", /** @scrutinizer ignore-type */ $startTime);
Loading history...
486
487
        $startTime = microtime(true);
488
        $isTakeoverReady = $this->shipTakeoverManager->isTakeoverReady($takeover);
489
        $this->potentialLog($spacecraft, "marker10.2", $startTime);
490
491
        if ($isTakeoverReady) {
492
            $startTime = microtime(true);
493
            $this->shipTakeoverManager->finishTakeover($takeover);
494
            $this->potentialLog($spacecraft, "marker10.3", $startTime);
495
        }
496
    }
497
498
    private function checkForFinishedAstroMapping(SpacecraftWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
499
    {
500
        if (!$wrapper instanceof ShipWrapperInterface) {
501
            return;
502
        }
503
504
        $ship = $wrapper->get();
505
506
        $startTime = microtime(true);
507
508
        /** @var null|DatabaseEntryInterface $databaseEntry */
509
        /** @var string $message */
510
        [$message, $databaseEntry] = $this->getDatabaseEntryForShipLocation($ship);
511
512
        $astroLab = $wrapper->getAstroLaboratorySystemData();
513
514
        $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

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