Passed
Push — master ( 92a2e9...9d73f4 )
by Nico
41:55
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\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\Ship\Repair\RepairUtilInterface;
10
use Stu\Component\Ship\ShipAlertStateEnum;
11
use Stu\Component\Ship\ShipStateEnum;
12
use Stu\Component\Ship\Storage\ShipStorageManagerInterface;
13
use Stu\Component\Ship\System\Data\EpsSystemData;
14
use Stu\Component\Ship\System\ShipSystemManagerInterface;
15
use Stu\Component\Ship\System\ShipSystemTypeEnum;
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\Ship\Lib\Crew\ShipLeaverInterface;
27
use Stu\Module\Ship\Lib\Interaction\ShipTakeoverManagerInterface;
28
use Stu\Module\Ship\Lib\Interaction\TrackerDeviceManagerInterface;
29
use Stu\Module\Ship\Lib\ReactorWrapperInterface;
30
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
31
use Stu\Module\Ship\Lib\ShipWrapperInterface;
32
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...
33
use Stu\Module\Tick\Ship\ManagerComponent\ManagerComponentInterface;
34
use Stu\Orm\Entity\DatabaseEntryInterface;
35
use Stu\Orm\Entity\ShipInterface;
36
use Stu\Orm\Repository\DatabaseUserRepositoryInterface;
37
use Stu\Orm\Repository\ShipRepositoryInterface;
38
use Stu\Orm\Repository\LocationMiningRepositoryInterface;
39
use Stu\Orm\Repository\CommodityRepositoryInterface;
40
use Stu\Orm\Repository\StorageRepositoryInterface;
41
42
final class ShipTick implements ShipTickInterface, ManagerComponentInterface
43
{
44
    private LoggerUtilInterface $loggerUtil;
45
46
    /**
47
     * @var array<string>
48
     */
49
    private array $msg = [];
50
51
    public function __construct(
52
        private ShipWrapperFactoryInterface $shipWrapperFactory,
53
        private PrivateMessageSenderInterface $privateMessageSender,
54
        private ShipRepositoryInterface $shipRepository,
55
        private ShipSystemManagerInterface $shipSystemManager,
56
        private ShipLeaverInterface $shipLeaver,
57
        private GameControllerInterface $game,
58
        private AstroEntryLibInterface $astroEntryLib,
59
        private DatabaseUserRepositoryInterface $databaseUserRepository,
60
        private CreateDatabaseEntryInterface $createDatabaseEntry,
61
        private StationUtilityInterface $stationUtility,
62
        private RepairUtilInterface $repairUtil,
63
        private ShipTakeoverManagerInterface $shipTakeoverManager,
64
        private TrackerDeviceManagerInterface $trackerDeviceManager,
65
        private ShipStorageManagerInterface $shipStorageManager,
66
        private LocationMiningRepositoryInterface $locationMiningRepository,
67
        private CommodityRepositoryInterface $commodityRepository,
68
        private StorageRepositoryInterface $storageRepository,
69
        LoggerUtilFactoryInterface $loggerUtilFactory
70
    ) {
71
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil(true);
72
    }
73
74
    #[Override]
75
    public function work(): void
76
    {
77
        foreach ($this->shipRepository->getPlayerShipsForTick() as $ship) {
78
            $this->workShip($this->shipWrapperFactory->wrapShip($ship));
79
        }
80
    }
81
82
    #[Override]
83
    public function workShip(ShipWrapperInterface $wrapper): void
84
    {
85
        $ship = $wrapper->get();
86
87
        $startTime = microtime(true);
88
89
        // do construction stuff
90
        if ($this->doConstructionStuff($ship)) {
91
            $this->shipRepository->save($ship);
92
            $this->sendMessages($ship);
93
            return;
94
        }
95
96
        $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

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

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