Passed
Pull Request — master (#1969)
by Janko
22:34 queued 10:03
created

SpacecraftTick::workSpacecraft()   F

Complexity

Conditions 26
Paths 1769

Size

Total Lines 188
Code Lines 118

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 702

Importance

Changes 0
Metric Value
cc 26
eloc 118
nc 1769
nop 1
dl 0
loc 188
ccs 0
cts 122
cp 0
crap 702
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Stu\Module\Tick\Spacecraft;
4
5
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use RuntimeException;
7
use Stu\Component\Faction\FactionEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Faction\FactionEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Stu\Component\Ship\AstronomicalMappingEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Ship\AstronomicalMappingEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Stu\Component\Spacecraft\Repair\RepairUtilInterface;
10
use Stu\Component\Spacecraft\SpacecraftAlertStateEnum;
11
use Stu\Component\Spacecraft\SpacecraftStateEnum;
12
use Stu\Lib\Transfer\Storage\StorageManagerInterface;
13
use Stu\Component\Spacecraft\System\Data\EpsSystemData;
14
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
15
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
16
use Stu\Component\Station\StationUtilityInterface;
17
use Stu\Module\Control\GameControllerInterface;
18
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...
19
use Stu\Module\Database\Lib\CreateDatabaseEntryInterface;
20
use Stu\Module\Logging\LoggerUtilFactoryInterface;
21
use Stu\Module\Logging\LoggerUtilInterface;
22
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
23
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
24
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...
25
use Stu\Module\Ship\Lib\AstroEntryLibInterface;
26
use Stu\Module\Spacecraft\Lib\Crew\SpacecraftLeaverInterface;
27
use Stu\Module\Spacecraft\Lib\Interaction\ShipTakeoverManagerInterface;
28
use Stu\Module\Spacecraft\Lib\Interaction\TrackerDeviceManagerInterface;
29
use Stu\Module\Spacecraft\Lib\ReactorWrapperInterface;
30
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
31
use Stu\Module\Ship\Lib\ShipWrapperInterface;
32
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
33
use Stu\Module\Station\Lib\StationWrapperInterface;
34
use Stu\Module\Tick\Spacecraft\ManagerComponent\ManagerComponentInterface;
35
use Stu\Orm\Entity\DatabaseEntryInterface;
36
use Stu\Orm\Entity\ShipInterface;
37
use Stu\Orm\Entity\SpacecraftInterface;
38
use Stu\Orm\Entity\StationInterface;
39
use Stu\Orm\Repository\DatabaseUserRepositoryInterface;
40
use Stu\Orm\Repository\LocationMiningRepositoryInterface;
41
use Stu\Orm\Repository\CommodityRepositoryInterface;
42
use Stu\Orm\Repository\SpacecraftRepositoryInterface;
43
use Stu\Orm\Repository\StorageRepositoryInterface;
44
45
final class SpacecraftTick implements SpacecraftTickInterface, ManagerComponentInterface
46
{
47
    private LoggerUtilInterface $loggerUtil;
48
49
    /**
50
     * @var array<string>
51
     */
52
    private array $msg = [];
53
54 1
    public function __construct(
55
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
56
        private PrivateMessageSenderInterface $privateMessageSender,
57
        private SpacecraftRepositoryInterface $spacecraftRepository,
58
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
59
        private SpacecraftLeaverInterface $spacecraftLeaver,
60
        private GameControllerInterface $game,
61
        private AstroEntryLibInterface $astroEntryLib,
62
        private DatabaseUserRepositoryInterface $databaseUserRepository,
63
        private CreateDatabaseEntryInterface $createDatabaseEntry,
64
        private StationUtilityInterface $stationUtility,
65
        private RepairUtilInterface $repairUtil,
66
        private ShipTakeoverManagerInterface $shipTakeoverManager,
67
        private TrackerDeviceManagerInterface $trackerDeviceManager,
68
        private StorageManagerInterface $storageManager,
69
        private LocationMiningRepositoryInterface $locationMiningRepository,
70
        private CommodityRepositoryInterface $commodityRepository,
71
        private StorageRepositoryInterface $storageRepository,
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
        $spacecraft = $wrapper->get();
89
90
        $startTime = microtime(true);
91
92
        // do construction stuff
93
        if ($spacecraft instanceof StationInterface && $this->doConstructionStuff($spacecraft)) {
94
            $this->spacecraftRepository->save($spacecraft);
95
            $this->sendMessages($spacecraft);
96
            return;
97
        }
98
99
        $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

99
        $this->potentialLog($spacecraft, "marker0", /** @scrutinizer ignore-type */ $startTime);
Loading history...
100
101
102
        $startTime = microtime(true);
103
        // repair station
104
        if ($wrapper instanceof StationWrapperInterface && $spacecraft->getState() === SpacecraftStateEnum::SHIP_STATE_REPAIR_PASSIVE) {
105
            $this->doRepairStation($wrapper);
106
        }
107
        $this->potentialLog($spacecraft, "marker1", $startTime);
108
109
        $startTime = microtime(true);
110
        // leave ship
111
        if ($spacecraft->getCrewCount() > 0 && !$spacecraft->isSystemHealthy(SpacecraftSystemTypeEnum::SYSTEM_LIFE_SUPPORT)) {
112
            $this->msg[] = _('Die Lebenserhaltung ist ausgefallen:');
113
            $this->msg[] = $this->spacecraftLeaver->evacuate($wrapper);
114
            $this->sendMessages($spacecraft);
115
            $this->potentialLog($spacecraft, "marker2", $startTime);
116
            return;
117
        }
118
119
        $startTime = microtime(true);
120
        $eps = $wrapper->getEpsSystemData();
121
        $reactor = $wrapper->getReactorWrapper();
122
        if ($eps === null) {
123
            $this->potentialLog($spacecraft, "marker3", $startTime);
124
            return;
125
        }
126
127
        $startTime = microtime(true);
128
        $hasEnoughCrew = $spacecraft->hasEnoughCrew();
129
130
        // not enough crew
131
        if (!$hasEnoughCrew) {
132
            $this->msg[] = _('Zu wenig Crew an Bord, Schiff ist nicht voll funktionsfähig! Systeme werden deaktiviert!');
133
134
            //deactivate all systems except life support
135
            foreach ($this->spacecraftSystemManager->getActiveSystems($spacecraft) as $system) {
136
                if ($system->getSystemType() != SpacecraftSystemTypeEnum::SYSTEM_LIFE_SUPPORT) {
137
                    $this->spacecraftSystemManager->deactivate($wrapper, $system->getSystemType(), true);
138
                }
139
            }
140
        }
141
        $this->potentialLog($spacecraft, "marker4", $startTime);
142
143
        $startTime = microtime(true);
144
        $reactorUsageForWarpdrive = $this->loadWarpdrive(
145
            $wrapper,
146
            $hasEnoughCrew
147
        );
148
        $this->potentialLog($spacecraft, "marker5", $startTime);
149
150
        $startTime = microtime(true);
151
        $availableEps = $this->getAvailableEps(
152
            $wrapper,
153
            $eps,
154
            $reactor,
155
            $hasEnoughCrew,
156
            $reactorUsageForWarpdrive
157
        );
158
        $this->potentialLog($spacecraft, "marker6", $startTime);
159
160
        $startTime = microtime(true);
161
        //try to save energy by reducing alert state
162
        if ($wrapper->getEpsUsage() > $availableEps) {
163
            $malus = $wrapper->getEpsUsage() - $availableEps;
164
            $alertUsage = $spacecraft->getAlertState()->value - 1;
165
166
            if ($alertUsage > 0) {
167
                $preState = $spacecraft->getAlertState();
168
                $reduce = (int)min($malus, $alertUsage);
169
170
                $spacecraft->setAlertState(SpacecraftAlertStateEnum::from($preState->value - $reduce));
171
                $this->msg[] = sprintf(
172
                    _('Wechsel von %s auf %s wegen Energiemangel'),
173
                    $preState->getDescription(),
174
                    $spacecraft->getAlertState()->getDescription()
175
                );
176
            }
177
        }
178
        $this->potentialLog($spacecraft, "marker7", $startTime);
179
180
        $startTime = microtime(true);
181
        //try to save energy by deactivating systems from low to high priority
182
        if ($wrapper->getEpsUsage() > $availableEps) {
183
            $activeSystems = $this->spacecraftSystemManager->getActiveSystems($spacecraft, true);
184
185
            foreach ($activeSystems as $system) {
186
                $energyConsumption = $this->spacecraftSystemManager->getEnergyConsumption($system->getSystemType());
187
                if ($energyConsumption < 1) {
188
                    continue;
189
                }
190
191
                //echo "- eps: ".$eps." - usage: ".$wrapper->getEpsUsage()."\n";
192
                if ($availableEps - $wrapper->getEpsUsage() - $energyConsumption < 0) {
193
                    //echo "-- hit system: ".$system->getDescription()."\n";
194
195
                    $this->spacecraftSystemManager->deactivate($wrapper, $system->getSystemType(), true);
196
197
                    $wrapper->lowerEpsUsage($energyConsumption);
198
                    $this->msg[] = $system->getSystemType()->getDescription() . ' deaktiviert wegen Energiemangel';
199
200
                    if ($spacecraft->getCrewCount() > 0 && $system->getSystemType() == SpacecraftSystemTypeEnum::SYSTEM_LIFE_SUPPORT) {
201
                        $this->msg[] = _('Die Lebenserhaltung ist ausgefallen:');
202
                        $this->msg[] = $this->spacecraftLeaver->evacuate($wrapper);
203
                        $this->sendMessages($spacecraft);
204
                        return;
205
                    }
206
                }
207
                if ($wrapper->getEpsUsage() <= $availableEps) {
208
                    break;
209
                }
210
            }
211
        }
212
213
        $this->potentialLog($spacecraft, "marker8", $startTime);
214
        $startTime = microtime(true);
215
216
        $newEps = $availableEps - $wrapper->getEpsUsage();
217
        $batteryReload = $spacecraft->isStation()
218
            && $eps->reloadBattery()
219
            && $newEps > $eps->getEps()
220
            ? min(
221
                (int) ceil($eps->getMaxBattery() / 10),
222
                $newEps - $eps->getEps(),
223
                $eps->getMaxBattery() - $eps->getBattery()
224
            ) : 0;
225
226
        $newEps -= $batteryReload;
227
        if ($newEps > $eps->getMaxEps()) {
228
            $newEps = $eps->getMaxEps();
229
        }
230
231
232
        $usedEnergy = $wrapper->getEpsUsage() + $batteryReload + ($newEps - $eps->getEps()) + $reactorUsageForWarpdrive;
233
234
        //echo "--- Generated Id ".$ship->getId()." - eps: ".$eps." - usage: ".$wrapper->getEpsUsage()." - old eps: ".$ship->getEps()." - wk: ".$wkuse."\n";
235
        $eps->setEps($newEps)
236
            ->setBattery($eps->getBattery() + $batteryReload)
237
            ->update();
238
239
        if ($usedEnergy > 0 && $reactor !== null) {
240
            $reactor->changeLoad(-$usedEnergy);
241
        }
242
243
        $this->potentialLog($spacecraft, "marker9", $startTime);
244
245
        $startTime = microtime(true);
246
        $this->checkForFinishedTakeover($spacecraft);
247
        $this->potentialLog($spacecraft, "marker10", $startTime);
248
249
        $startTime = microtime(true);
250
        $this->checkForFinishedAstroMapping($wrapper);
251
        $this->potentialLog($spacecraft, "marker11", $startTime);
252
253
        //update tracker status
254
        $startTime = microtime(true);
255
        $this->doTrackerDeviceStuff($wrapper);
256
        $this->potentialLog($spacecraft, "marker12", $startTime);
257
258
        $startTime = microtime(true);
259
        $this->spacecraftRepository->save($spacecraft);
260
        $this->potentialLog($spacecraft, "marker13", $startTime);
261
262
        $startTime = microtime(true);
263
        $this->sendMessages($spacecraft);
264
        $this->potentialLog($spacecraft, "marker14", $startTime);
265
266
        $startTime = microtime(true);
267
        $this->doBussardCollectorStuff($wrapper);
268
        $this->potentialLog($spacecraft, "marker15", $startTime);
269
270
        $startTime = microtime(true);
271
        $this->doAggregationSystemStuff($wrapper);
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): 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::SHIP_STATE_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
            $this->msg[] = sprintf(
365
                _('Nicht genügend Workbees (%d/%d) angedockt um %s weiterführen zu können'),
366
                $this->stationUtility->getDockedWorkbeeCount($station),
367
                $neededWorkbees,
368
                $isUnderConstruction ? 'den Bau' : 'die Demontage'
369
            );
370
            return true;
371
        }
372
373
        if ($progress->getRemainingTicks() === 1) {
374
            if ($isUnderConstruction) {
375
                $this->stationUtility->finishStation($progress);
376
            } else {
377
                $this->stationUtility->finishScrapping($progress);
378
            }
379
380
            $this->msg[] = sprintf(
381
                _('%s: %s bei %s fertiggestellt'),
382
                $station->getRump()->getName(),
383
                $isUnderConstruction ? 'Bau' : 'Demontage',
384
                $station->getSectorString()
385
            );
386
        } else {
387
            $this->stationUtility->reduceRemainingTicks($progress);
388
389
            if ($isUnderConstruction) {
390
                // raise hull
391
                $increase = intdiv($station->getMaxHull(), 2 * $station->getRump()->getBuildtime());
392
                $station->setHuell($station->getHull() + $increase);
393
            }
394
        }
395
396
        return true;
397
    }
398
399
    private function doRepairStation(StationWrapperInterface $wrapper): void
400
    {
401
        $station = $wrapper->get();
402
403
        if (!$this->stationUtility->hasEnoughDockedWorkbees($station, $station->getRump())) {
404
            $neededWorkbees = (int)ceil($station->getRump()->getNeededWorkbees() / 5);
405
406
            $this->msg[] = sprintf(
407
                _('Nicht genügend Workbees (%d/%d) angedockt um die Reparatur weiterführen zu können'),
408
                $this->stationUtility->getDockedWorkbeeCount($station),
409
                $neededWorkbees
410
            );
411
            return;
412
        }
413
414
        $neededParts = $this->repairUtil->determineSpareParts($wrapper, true);
415
416
        // parts stored?
417
        if (!$this->repairUtil->enoughSparePartsOnEntity($neededParts, $station, $station)) {
418
            return;
419
        }
420
421
        //repair hull
422
        $station->setHuell($station->getHull() + $station->getRepairRate());
423
        if ($station->getHull() > $station->getMaxHull()) {
424
            $station->setHuell($station->getMaxHull());
425
        }
426
427
        //repair station systems
428
        $damagedSystems = $wrapper->getDamagedSystems();
429
        if ($damagedSystems !== []) {
430
            $firstSystem = $damagedSystems[0];
431
            $firstSystem->setStatus(100);
432
433
            if ($station->getCrewCount() > 0) {
434
                $firstSystem->setMode($this->spacecraftSystemManager->lookupSystem($firstSystem->getSystemType())->getDefaultMode());
435
            }
436
437
            // maximum of two systems get repaired
438
            if (count($damagedSystems) > 1) {
439
                $secondSystem = $damagedSystems[1];
440
                $secondSystem->setStatus(100);
441
442
                if ($station->getCrewCount() > 0) {
443
                    $secondSystem->setMode($this->spacecraftSystemManager->lookupSystem($secondSystem->getSystemType())->getDefaultMode());
444
                }
445
            }
446
        }
447
448
        // consume spare parts
449
        $this->repairUtil->consumeSpareParts($neededParts, $station);
450
451
        if (!$wrapper->canBeRepaired()) {
452
            $station->setHuell($station->getMaxHull());
453
            $station->setState(SpacecraftStateEnum::SHIP_STATE_NONE);
454
455
            $shipOwnerMessage = sprintf(
456
                "Die Reparatur der %s wurde in Sektor %s fertiggestellt",
457
                $station->getName(),
458
                $station->getSectorString()
459
            );
460
461
            $this->privateMessageSender->send(
462
                UserEnum::USER_NOONE,
463
                $station->getUser()->getId(),
464
                $shipOwnerMessage,
465
                PrivateMessageFolderTypeEnum::SPECIAL_STATION
466
            );
467
        }
468
        $this->spacecraftRepository->save($station);
469
    }
470
471
    private function checkForFinishedTakeover(SpacecraftInterface $spacecraft): void
472
    {
473
        $startTime = microtime(true);
474
        $takeover = $spacecraft->getTakeoverActive();
475
        if ($takeover === null) {
476
            return;
477
        }
478
        $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

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