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

SpacecraftTick::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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

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\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