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

SpacecraftTick::checkForFinishedTakeover()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 1
dl 0
loc 17
ccs 0
cts 13
cp 0
crap 12
rs 9.8666
c 0
b 0
f 0
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