Passed
Push — dev ( e7d4e1...a76960 )
by Janko
20:02
created

SpacecraftTick::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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

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

filter:
    dependency_paths: ["lib/*"]

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

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

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

filter:
    dependency_paths: ["lib/*"]

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

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

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

filter:
    dependency_paths: ["lib/*"]

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

Loading history...
9
use Stu\Component\Spacecraft\Repair\RepairUtilInterface;
10
use Stu\Component\Spacecraft\SpacecraftAlertStateEnum;
11
use Stu\Component\Spacecraft\SpacecraftStateEnum;
12
use Stu\Lib\Transfer\Storage\StorageManagerInterface;
13
use Stu\Component\Spacecraft\System\Data\EpsSystemData;
14
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
15
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
16
use Stu\Component\Station\StationUtilityInterface;
17
use Stu\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::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::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::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 ($isUnderConstruction) {
374
            // raise hull
375
            $increase = (int)ceil($station->getMaxHull() / (2 * $station->getRump()->getBuildtime()));
376
            $station->setHuell($station->getHull() + $increase);
377
        }
378
379
        if ($progress->getRemainingTicks() === 1) {
380
            if ($isUnderConstruction) {
381
                $this->stationUtility->finishStation($progress);
382
            } else {
383
                $this->stationUtility->finishScrapping($progress);
384
            }
385
386
            $this->msg[] = sprintf(
387
                _('%s: %s bei %s fertiggestellt'),
388
                $station->getRump()->getName(),
389
                $isUnderConstruction ? 'Bau' : 'Demontage',
390
                $station->getSectorString()
391
            );
392
        } else {
393
            $this->stationUtility->reduceRemainingTicks($progress);
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
        $startTime = microtime(true);
500
501
        /** @var null|DatabaseEntryInterface $databaseEntry */
502
        [$message, $databaseEntry] = $this->getDatabaseEntryForShipLocation($ship);
503
504
        $astroLab = $wrapper->getAstroLaboratorySystemData();
505
506
        $this->potentialLog($ship, "marker11.1", $startTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime can also be of type string; however, parameter $startTime of Stu\Module\Tick\Spacecra...aftTick::potentialLog() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

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