Passed
Push — dev ( 238307...62244f )
by Nico
26:37
created

ShipTick::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 18
dl 0
loc 21
ccs 0
cts 2
cp 0
crap 2
rs 10
c 2
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\Ship;
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\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...
8
use Stu\Component\Ship\Repair\RepairUtilInterface;
9
use Stu\Component\Ship\ShipAlertStateEnum;
10
use Stu\Component\Ship\ShipStateEnum;
11
use Stu\Component\Ship\Storage\ShipStorageManagerInterface;
12
use Stu\Component\Ship\System\Data\EpsSystemData;
13
use Stu\Component\Ship\System\ShipSystemManagerInterface;
14
use Stu\Component\Ship\System\ShipSystemTypeEnum;
15
use Stu\Component\Station\StationUtilityInterface;
16
use Stu\Module\Control\GameControllerInterface;
17
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...
18
use Stu\Module\Database\Lib\CreateDatabaseEntryInterface;
19
use Stu\Module\Logging\LoggerUtilFactoryInterface;
20
use Stu\Module\Logging\LoggerUtilInterface;
21
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
22
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
23
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...
24
use Stu\Module\Ship\Lib\AstroEntryLibInterface;
25
use Stu\Module\Ship\Lib\Crew\ShipLeaverInterface;
26
use Stu\Module\Ship\Lib\Interaction\ShipTakeoverManagerInterface;
27
use Stu\Module\Ship\Lib\Interaction\TrackerDeviceManagerInterface;
28
use Stu\Module\Ship\Lib\ReactorWrapperInterface;
29
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
30
use Stu\Module\Ship\Lib\ShipWrapperInterface;
31
use Stu\Module\Ship\View\ShowShip\ShowShip;
0 ignored issues
show
Bug introduced by
The type Stu\Module\Ship\View\ShowShip\ShowShip 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...
32
use Stu\Module\Tick\Ship\ManagerComponent\ManagerComponentInterface;
33
use Stu\Orm\Entity\DatabaseEntryInterface;
34
use Stu\Orm\Entity\ShipInterface;
35
use Stu\Orm\Repository\DatabaseUserRepositoryInterface;
36
use Stu\Orm\Repository\ShipRepositoryInterface;
37
use Stu\Orm\Repository\LocationMiningRepositoryInterface;
38
use Stu\Orm\Repository\CommodityRepositoryInterface;
39
use Stu\Orm\Repository\StorageRepositoryInterface;
40
41
final class ShipTick implements ShipTickInterface, ManagerComponentInterface
42
{
43
    private LoggerUtilInterface $loggerUtil;
44
45
    /**
46
     * @var array<string>
47
     */
48
    private array $msg = [];
49
50
    public function __construct(
51
        private ShipWrapperFactoryInterface $shipWrapperFactory,
52
        private PrivateMessageSenderInterface $privateMessageSender,
53
        private ShipRepositoryInterface $shipRepository,
54
        private ShipSystemManagerInterface $shipSystemManager,
55
        private ShipLeaverInterface $shipLeaver,
56
        private GameControllerInterface $game,
57
        private AstroEntryLibInterface $astroEntryLib,
58
        private DatabaseUserRepositoryInterface $databaseUserRepository,
59
        private CreateDatabaseEntryInterface $createDatabaseEntry,
60
        private StationUtilityInterface $stationUtility,
61
        private RepairUtilInterface $repairUtil,
62
        private ShipTakeoverManagerInterface $shipTakeoverManager,
63
        private TrackerDeviceManagerInterface $trackerDeviceManager,
64
        private ShipStorageManagerInterface $shipStorageManager,
65
        private LocationMiningRepositoryInterface $locationMiningRepository,
66
        private CommodityRepositoryInterface $commodityRepository,
67
        private StorageRepositoryInterface $storageRepository,
68
        LoggerUtilFactoryInterface $loggerUtilFactory
69
    ) {
70
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil(true);
71
    }
72
73
    #[Override]
74
    public function work(): void
75
    {
76
        foreach ($this->shipRepository->getPlayerShipsForTick() as $ship) {
77
            $this->workShip($this->shipWrapperFactory->wrapShip($ship));
78
        }
79
    }
80
81
    #[Override]
82
    public function workShip(ShipWrapperInterface $wrapper): void
83
    {
84
        $ship = $wrapper->get();
85
86
        $startTime = microtime(true);
87
88
        // do construction stuff
89
        if ($this->doConstructionStuff($ship)) {
90
            $this->shipRepository->save($ship);
91
            $this->sendMessages($ship);
92
            return;
93
        }
94
95
        $this->potentialLog($ship, "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\Ship\ShipTick::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

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

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