Passed
Push — master ( 784be2...c4713a )
by Nico
58:15 queued 29:26
created

ShowShip::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 37
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 18
c 0
b 0
f 0
nc 1
nop 17
dl 0
loc 37
ccs 0
cts 19
cp 0
crap 2
rs 9.6666

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
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\View\ShowShip;
6
7
use NavPanel;
8
use request;
9
use Stu\Component\Game\GameEnum;
10
use Stu\Component\Player\ColonizationCheckerInterface;
11
use Stu\Component\Ship\AstronomicalMappingEnum;
12
use Stu\Component\Ship\Crew\ShipCrewCalculatorInterface;
13
use Stu\Component\Ship\Nbs\NbsUtilityInterface;
14
use Stu\Component\Ship\ShipModuleTypeEnum;
15
use Stu\Component\Ship\ShipRumpEnum;
16
use Stu\Component\Station\StationUtilityInterface;
17
use Stu\Lib\ColonyStorageCommodityWrapper\ColonyStorageCommodityWrapper;
18
use Stu\Lib\SessionInterface;
19
use Stu\Module\Colony\Lib\ColonyLibFactoryInterface;
20
use Stu\Module\Control\GameControllerInterface;
21
use Stu\Module\Control\ViewControllerInterface;
22
use Stu\Module\Database\View\Category\Tal\DatabaseCategoryTalFactoryInterface;
23
use Stu\Module\Logging\LoggerEnum;
24
use Stu\Module\Logging\LoggerUtilFactoryInterface;
25
use Stu\Module\Logging\LoggerUtilInterface;
26
use Stu\Module\Ship\Lib\Battle\FightLibInterface;
27
use Stu\Module\Ship\Lib\ShipLoaderInterface;
28
use Stu\Module\Ship\Lib\ShipRumpSpecialAbilityEnum;
29
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
30
use Stu\Module\Ship\Lib\ShipWrapperInterface;
31
use Stu\Module\Ship\Lib\Ui\ShipUiFactoryInterface;
32
use Stu\Orm\Entity\ColonyInterface;
33
use Stu\Orm\Entity\DatabaseEntryInterface;
34
use Stu\Orm\Entity\ShipInterface;
35
use Stu\Orm\Entity\StationShipRepairInterface;
36
use Stu\Orm\Entity\UserInterface;
37
use Stu\Orm\Repository\AstroEntryRepositoryInterface;
38
use Stu\Orm\Repository\DatabaseUserRepositoryInterface;
39
use Stu\Orm\Repository\ShipyardShipQueueRepositoryInterface;
40
use Stu\Orm\Repository\StationShipRepairRepositoryInterface;
41
use Stu\Orm\Repository\UserLayerRepositoryInterface;
42
43
final class ShowShip implements ViewControllerInterface
44
{
45
    public const VIEW_IDENTIFIER = 'SHOW_SHIP';
46
47
    private SessionInterface $session;
48
49
    private LoggerUtilFactoryInterface $loggerUtilFactory;
50
51
    private LoggerUtilInterface $loggerUtil;
52
53
    private ShipLoaderInterface $shipLoader;
54
55
    private ColonizationCheckerInterface $colonizationChecker;
56
57
    private DatabaseCategoryTalFactoryInterface $databaseCategoryTalFactory;
58
59
    private AstroEntryRepositoryInterface $astroEntryRepository;
60
61
    private DatabaseUserRepositoryInterface $databaseUserRepository;
62
63
    private NbsUtilityInterface $nbsUtility;
64
65
    private StationShipRepairRepositoryInterface $stationShipRepairRepository;
66
67
    private ShipyardShipQueueRepositoryInterface $shipyardShipQueueRepository;
68
69
    private UserLayerRepositoryInterface $userLayerRepository;
70
71
    private StationUtilityInterface $stationUtility;
72
73
    private ShipWrapperFactoryInterface $shipWrapperFactory;
74
75
    private ColonyLibFactoryInterface $colonyLibFactory;
76
77
    private ShipUiFactoryInterface $shipUiFactory;
78
79
    private ShipCrewCalculatorInterface $shipCrewCalculator;
80
81
    private FightLibInterface $fightLib;
82
83
    public function __construct(
84
        SessionInterface $session,
85
        ShipLoaderInterface $shipLoader,
86
        ColonizationCheckerInterface $colonizationChecker,
87
        DatabaseCategoryTalFactoryInterface $databaseCategoryTalFactory,
88
        AstroEntryRepositoryInterface $astroEntryRepository,
89
        DatabaseUserRepositoryInterface $databaseUserRepository,
90
        NbsUtilityInterface $nbsUtility,
91
        StationShipRepairRepositoryInterface $stationShipRepairRepository,
92
        ShipyardShipQueueRepositoryInterface $shipyardShipQueueRepository,
93
        UserLayerRepositoryInterface $userLayerRepository,
94
        StationUtilityInterface $stationUtility,
95
        ShipWrapperFactoryInterface $shipWrapperFactory,
96
        ColonyLibFactoryInterface $colonyLibFactory,
97
        ShipUiFactoryInterface $shipUiFactory,
98
        ShipCrewCalculatorInterface $shipCrewCalculator,
99
        FightLibInterface $fightLib,
100
        LoggerUtilFactoryInterface $loggerUtilFactory
101
    ) {
102
        $this->session = $session;
103
        $this->shipLoader = $shipLoader;
104
        $this->colonizationChecker = $colonizationChecker;
105
        $this->databaseCategoryTalFactory = $databaseCategoryTalFactory;
106
        $this->astroEntryRepository = $astroEntryRepository;
107
        $this->databaseUserRepository = $databaseUserRepository;
108
        $this->nbsUtility = $nbsUtility;
109
        $this->stationShipRepairRepository = $stationShipRepairRepository;
110
        $this->shipyardShipQueueRepository = $shipyardShipQueueRepository;
111
        $this->userLayerRepository = $userLayerRepository;
112
        $this->stationUtility = $stationUtility;
113
        $this->shipWrapperFactory = $shipWrapperFactory;
114
        $this->loggerUtilFactory = $loggerUtilFactory;
115
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil();
116
        $this->colonyLibFactory = $colonyLibFactory;
117
        $this->shipUiFactory = $shipUiFactory;
118
        $this->shipCrewCalculator = $shipCrewCalculator;
119
        $this->fightLib = $fightLib;
120
    }
121
122
    public function handle(GameControllerInterface $game): void
123
    {
124
        $user = $game->getUser();
125
        $userId = $user->getId();
126
        $ownsCurrentColony = false;
127
128
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
129
            request::indInt('id'),
130
            $userId,
131
            true
132
        );
133
        $ship = $wrapper->get();
134
135
        $tachyonFresh = $game->getViewContext()['TACHYON_SCAN_JUST_HAPPENED'] ?? false;
136
        $tachyonActive = $tachyonFresh;
137
138
        // check if tachyon scan still active
139
        if (!$tachyonActive) {
140
            $tachyonActive = $this->nbsUtility->isTachyonActive($ship);
141
        }
142
143
        $rump = $ship->getRump();
144
145
        $colony = $this->getColony($ship);
146
        $canColonize = false;
147
        if ($colony !== null) {
148
            if ($rump->hasSpecialAbility(ShipRumpSpecialAbilityEnum::COLONIZE)) {
149
                $canColonize = $this->colonizationChecker->canColonize($user, $colony);
150
            }
151
            $ownsCurrentColony = $colony->getUser() === $user;
152
        }
153
154
        //Forschungseintrag erstellen, damit System-Link optional erstellt werden kann
155
        $starSystem = $ship->getSystem();
156
        if ($starSystem !== null && $starSystem->getDatabaseEntry() !== null) {
157
            $starSystemEntryTal = $this->databaseCategoryTalFactory->createDatabaseCategoryEntryTal($starSystem->getDatabaseEntry(), $user);
158
            $game->setTemplateVar('STARSYSTEM_ENTRY_TAL', $starSystemEntryTal);
159
        }
160
161
        $isBase = $ship->isBase();
162
        $game->appendNavigationPart(
163
            $isBase ? 'station.php' : 'ship.php',
164
            $isBase ? _('Stationen') : _('Schiffe')
165
        );
166
167
        $game->appendNavigationPart(
168
            sprintf('?%s=1&id=%d', static::VIEW_IDENTIFIER, $ship->getId()),
169
            $ship->getName()
170
        );
171
        $game->setPagetitle($ship->getName());
172
173
        $game->setTemplateFile('html/ship.twig', true);
174
175
        $game->setTemplateVar('WRAPPER', $wrapper);
176
177
        if ($ship->getLss()) {
178
179
            $this->createUserLayerIfNecessary($user, $ship);
180
181
            $game->setTemplateVar('VISUAL_NAV_PANEL', $this->shipUiFactory->createVisualNavPanel(
182
                $ship,
183
                $game->getUser(),
184
                $this->loggerUtilFactory->getLoggerUtil(),
185
                $ship->getTachyonState(),
186
                $tachyonFresh
187
            ));
188
        }
189
        $game->setTemplateVar('NAV_PANEL', new NavPanel($ship));
190
191
        $this->doConstructionStuff($ship, $game);
192
        $this->doStationStuff($ship, $game);
193
194
        $this->nbsUtility->setNbsTemplateVars($ship, $game, $this->session, $tachyonActive);
195
196
        $game->setTemplateVar('ASTRO_STATE_SYSTEM', $this->getAstroState($ship, $game, true));
197
        $game->setTemplateVar('ASTRO_STATE_REGION', $this->getAstroState($ship, $game, false));
198
        $game->setTemplateVar('TACHYON_ACTIVE', $tachyonActive);
199
        $game->setTemplateVar('CAN_COLONIZE', $canColonize);
200
        $game->setTemplateVar('OWNS_CURRENT_COLONY', $ownsCurrentColony);
201
        $game->setTemplateVar('CURRENT_COLONY', $colony);
202
        $game->setTemplateVar('FIGHT_LIB', $this->fightLib);
203
204
        $userLayers = $user->getUserLayers();
205
        if ($ship->hasTranswarp()) {
206
            $game->setTemplateVar('USER_LAYERS', $userLayers);
207
        }
208
209
        $layer = $ship->getLayer();
210
        if ($layer !== null && $userLayers->containsKey($layer->getId())) {
211
            $game->setTemplateVar('IS_MAP_BUTTON_VISIBLE', true);
212
        }
213
214
        $crewObj = $this->shipCrewCalculator->getCrewObj($rump);
215
216
        $game->setTemplateVar(
217
            'MAX_CREW_COUNT',
218
            $crewObj === null
219
                ? null
220
                : $this->shipCrewCalculator->getMaxCrewCountByShip($ship)
221
        );
222
223
        $this->addWarpcoreSplitJavascript($wrapper, $game);
224
225
        $this->loggerUtil->log(sprintf('ShowShip.handle-end, timestamp: %F', microtime(true)));
226
    }
227
228
    private function createUserLayerIfNecessary(UserInterface $user, ShipInterface $ship): void
229
    {
230
        $layer = $ship->getLayer();
231
        if ($layer === null) {
232
            return;
233
        }
234
235
        if ($ship->getMap() === null) {
236
            return;
237
        }
238
239
        $hasSeenLayer = $user->hasSeen($layer->getId());
240
        if ($hasSeenLayer) {
241
            return;
242
        }
243
244
        $userLayer = $this->userLayerRepository->prototype();
245
        $userLayer->setLayer($layer);
246
        $userLayer->setUser($user);
247
        $this->userLayerRepository->save($userLayer);
248
249
        $user->getUserLayers()->set($layer->getId(), $userLayer);
250
    }
251
252
    private function addWarpcoreSplitJavascript(ShipWrapperInterface $wrapper, GameControllerInterface $game): void
253
    {
254
        $warpDriveSystem = $wrapper->getWarpDriveSystemData();
255
        $epsSystem = $wrapper->getEpsSystemData();
256
257
        if ($warpDriveSystem !== null && $epsSystem !== null) {
258
            $ship = $wrapper->get();
259
260
            $game->addExecuteJS(sprintf(
261
                'setReactorSplitConstants(%d,%d,%d,%d,%d,%d,%d);',
262
                $ship->getReactorOutputCappedByReactorLoad(),
263
                $wrapper->getEpsUsage(),
264
                $ship->getRump()->getFlightEcost(),
265
                $epsSystem->getEps(),
266
                $epsSystem->getMaxEps(),
267
                $warpDriveSystem->getWarpDrive(),
268
                $warpDriveSystem->getMaxWarpDrive()
269
            ), GameEnum::JS_EXECUTION_AFTER_RENDER);
270
            $game->addExecuteJS(sprintf(
271
                'updateEpsSplitValues(%d);',
272
                $warpDriveSystem->getWarpCoreSplit(),
273
            ), GameEnum::JS_EXECUTION_AFTER_RENDER);
274
        }
275
    }
276
277
    private function getColony(ShipInterface $ship): ?ColonyInterface
278
    {
279
        if ($ship->getStarsystemMap() === null) {
280
            return null;
281
        }
282
283
        return $ship->getStarsystemMap()->getColony();
284
    }
285
286
    private function getAstroState(ShipInterface $ship, GameControllerInterface $game, bool $isSystem): AstroStateWrapper
287
    {
288
        //$this->loggerUtil->init('SS', LoggerEnum::LEVEL_ERROR);
289
290
        $databaseEntry = $this->getDatabaseEntryForShipLocation($ship, $isSystem);
291
292
        $this->loggerUtil->log(sprintf('databaseEntry: %d', $databaseEntry !== null ? $databaseEntry->getId() : 0));
293
294
        $astroEntry = null;
295
296
        if ($databaseEntry === null) {
297
            $state = AstronomicalMappingEnum::NONE;
298
        } elseif ($this->databaseUserRepository->exists($game->getUser()->getId(), $databaseEntry->getId())) {
299
            $state = AstronomicalMappingEnum::DONE;
300
        } else {
301
            $astroEntry = $this->astroEntryRepository->getByShipLocation($ship, $isSystem);
302
303
            $this->loggerUtil->log(sprintf('isSystem: %b, astroEntry?: %b', $isSystem, $astroEntry !== null));
304
305
            $state = $astroEntry === null ? AstronomicalMappingEnum::PLANNABLE : $astroEntry->getState();
306
        }
307
        $turnsLeft = null;
308
        if ($state === AstronomicalMappingEnum::FINISHING && $astroEntry !== null) {
309
            $turnsLeft = AstronomicalMappingEnum::TURNS_TO_FINISH - ($game->getCurrentRound()->getTurn() - $astroEntry->getAstroStartTurn());
310
        }
311
312
        $wrapper = new AstroStateWrapper($state, $turnsLeft, $isSystem);
313
314
        $this->loggerUtil->log(sprintf('type: %s', $wrapper->getType()));
315
316
        return $wrapper;
317
    }
318
319
    private function getDatabaseEntryForShipLocation(ShipInterface $ship, bool $isSystem): ?DatabaseEntryInterface
320
    {
321
        if ($isSystem) {
322
            $system = $ship->getSystem() ?? $ship->isOverSystem();
323
            if ($system !== null) {
324
                return $system->getDatabaseEntry();
325
            }
326
327
            return null;
328
        }
329
330
        $mapRegion = $ship->getMapRegion();
331
        if ($mapRegion !== null) {
332
            $this->loggerUtil->log('mapREgion found');
333
            return $mapRegion->getDatabaseEntry();
334
        }
335
336
        return null;
337
    }
338
339
    private function doConstructionStuff(ShipInterface $ship, GameControllerInterface $game): void
340
    {
341
        if (!$ship->isConstruction() && !$ship->isBase()) {
342
            return;
343
        }
344
345
        $progress =  $this->stationUtility->getConstructionProgress($ship);
346
        if ($progress === null || $progress->getRemainingTicks() === 0) {
347
            $game->setTemplateVar('CONSTRUCTION_PROGRESS_WRAPPER', null);
348
        } else {
349
            $dockedWorkbees = $this->stationUtility->getDockedWorkbeeCount($ship);
350
            $neededWorkbees = $this->stationUtility->getNeededWorkbeeCount($ship, $ship->getRump());
351
352
            $game->setTemplateVar('CONSTRUCTION_PROGRESS_WRAPPER', new ConstructionProgressWrapper(
353
                $progress,
354
                $ship,
355
                $dockedWorkbees,
356
                $neededWorkbees
357
            ));
358
        }
359
360
        if ($progress === null) {
361
            $plans = $this->stationUtility->getStationBuildplansByUser($game->getUser()->getId());
362
            $game->setTemplateVar('POSSIBLE_STATIONS', $plans);
363
364
            $moduleSelectors = [];
365
            foreach ($plans as $plan) {
366
                $ms = $this->colonyLibFactory->createModuleSelectorSpecial(
367
                    ShipModuleTypeEnum::MODULE_TYPE_SPECIAL,
368
                    null,
369
                    $ship,
370
                    $plan->getRump(),
371
                    $game->getUser()->getId()
372
                );
373
374
                $ms->setDummyId($plan->getId());
375
                $moduleSelectors[] = $ms;
376
            }
377
378
            $game->setTemplateVar('MODULE_SELECTORS', $moduleSelectors);
379
            $game->setTemplateVar('HAS_STORAGE', new ColonyStorageCommodityWrapper($ship->getStorage()));
380
        }
381
    }
382
383
    private function doStationStuff(ShipInterface $ship, GameControllerInterface $game): void
384
    {
385
        if ($this->stationUtility->canManageShips($ship)) {
386
            $game->setTemplateVar('CAN_MANAGE', true);
387
        }
388
389
        if ($this->stationUtility->canRepairShips($ship)) {
390
            $game->setTemplateVar('CAN_REPAIR', true);
391
392
            $shipRepairProgress = array_map(
393
                fn (StationShipRepairInterface $repair): ShipWrapperInterface => $this->shipWrapperFactory->wrapShip($repair->getShip()),
394
                $this->stationShipRepairRepository->getByStation(
395
                    $ship->getId()
396
                )
397
            );
398
399
            $game->setTemplateVar('SHIP_REPAIR_PROGRESS', $shipRepairProgress);
400
        }
401
402
        if ($ship->getRump()->getRoleId() === ShipRumpEnum::SHIP_ROLE_SHIPYARD) {
403
            $game->setTemplateVar('SHIP_BUILD_PROGRESS', $this->shipyardShipQueueRepository->getByShipyard($ship->getId()));
404
        }
405
406
        $firstOrbitShip = null;
407
408
        $dockedShips = $ship->getDockedShips();
409
        if (!$dockedShips->isEmpty()) {
410
            // if selected, return the current target
411
            $target = request::postInt('target');
412
413
            if ($target !== 0) {
414
                foreach ($dockedShips as $ship) {
415
                    if ($ship->getId() === $target) {
416
                        $firstOrbitShip = $ship;
417
                    }
418
                }
419
            }
420
            if ($firstOrbitShip === null) {
0 ignored issues
show
introduced by
The condition $firstOrbitShip === null is always true.
Loading history...
421
                $firstOrbitShip = $dockedShips->first();
422
            }
423
        }
424
425
        $game->setTemplateVar('FIRST_MANAGE_SHIP', $firstOrbitShip !== null ? $this->shipWrapperFactory->wrapShip($firstOrbitShip) : null);
426
        $game->setTemplateVar('CAN_UNDOCK', true);
427
428
        if ($ship->getRump()->isShipyard()) {
429
            $game->setTemplateVar('AVAILABLE_BUILDPLANS', $this->stationUtility->getShipyardBuildplansByUser($game->getUser()->getId()));
430
        }
431
    }
432
}
433