Passed
Push — master ( 2f9ca7...02ce50 )
by Nico
23:14 queued 13:11
created

ShowShip::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 17
c 0
b 0
f 0
nc 1
nop 16
dl 0
loc 35
ccs 0
cts 18
cp 0
crap 2
rs 9.7

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