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

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

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