Passed
Pull Request — master (#1849)
by Nico
55:37 queued 21:01
created

ShipCreator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

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\Lib;
6
7
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...
8
use RuntimeException;
9
use Stu\Component\Ship\ShipModuleTypeEnum;
10
use Stu\Component\Ship\ShipRumpEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Ship\ShipRumpEnum 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...
11
use Stu\Component\Ship\ShipStateEnum;
12
use Stu\Component\Ship\SpacecraftTypeEnum;
13
use Stu\Component\Ship\System\ShipSystemModeEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Ship\System\ShipSystemModeEnum 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...
14
use Stu\Component\Ship\System\ShipSystemTypeEnum;
15
use Stu\Module\Logging\LoggerUtilFactoryInterface;
16
use Stu\Module\Logging\LoggerUtilInterface;
17
use Stu\Module\ShipModule\ModuleSpecialAbilityEnum;
18
use Stu\Orm\Entity\BuildplanModuleInterface;
19
use Stu\Orm\Entity\ColonyInterface;
20
use Stu\Orm\Entity\ConstructionProgressInterface;
21
use Stu\Orm\Entity\ModuleInterface;
22
use Stu\Orm\Entity\ShipInterface;
23
use Stu\Orm\Repository\BuildplanModuleRepositoryInterface;
24
use Stu\Orm\Repository\ModuleSpecialRepositoryInterface;
25
use Stu\Orm\Repository\ShipBuildplanRepositoryInterface;
26
use Stu\Orm\Repository\ShipRepositoryInterface;
27
use Stu\Orm\Repository\ShipRumpRepositoryInterface;
28
use Stu\Orm\Repository\ShipSystemRepositoryInterface;
29
use Stu\Orm\Repository\UserRepositoryInterface;
30
31
final class ShipCreator implements ShipCreatorInterface
32
{
33
    private LoggerUtilInterface $loggerUtil;
34
35
    public function __construct(
36
        private BuildplanModuleRepositoryInterface $buildplanModuleRepository,
37
        private ShipSystemRepositoryInterface $shipSystemRepository,
38
        private ShipRepositoryInterface $shipRepository,
39
        private UserRepositoryInterface $userRepository,
40
        private ShipRumpRepositoryInterface $shipRumpRepository,
41
        private ShipBuildplanRepositoryInterface $shipBuildplanRepository,
42
        private ModuleSpecialRepositoryInterface $moduleSpecialRepository,
43
        private ShipWrapperFactoryInterface $shipWrapperFactory,
44
        private ShipConfiguratorFactoryInterface $shipConfiguratorFactory,
45
        LoggerUtilFactoryInterface $loggerUtilFactory
46
    ) {
47
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil();
48
    }
49
50
    #[Override]
51
    public function createBy(
52
        int $userId,
53
        int $shipRumpId,
54
        int $shipBuildplanId,
55
        ?ColonyInterface $colony = null,
56
        ?ConstructionProgressInterface $progress = null
57
    ): ShipConfiguratorInterface {
58
        $user = $this->userRepository->find($userId);
59
        if ($user === null) {
60
            throw new RuntimeException('user not existent');
61
        }
62
63
        $rump = $this->shipRumpRepository->find($shipRumpId);
64
        if ($rump === null) {
65
            throw new RuntimeException('rump not existent');
66
        }
67
68
        $buildplan = $this->shipBuildplanRepository->find($shipBuildplanId);
69
        if ($buildplan === null) {
70
            throw new RuntimeException('buildplan not existent');
71
        }
72
73
        $ship = $progress !== null ? $progress->getShip() : $this->shipRepository->prototype();
74
        $ship->setUser($user);
75
        $ship->setBuildplan($buildplan);
76
        $ship->setRump($rump);
77
        $ship->setState(ShipStateEnum::SHIP_STATE_NONE);
78
79
        if ($ship->getRump()->getCategoryId() === ShipRumpEnum::SHIP_CATEGORY_STATION) {
80
            $ship->setSpacecraftType(SpacecraftTypeEnum::SPACECRAFT_TYPE_STATION);
81
        }
82
83
        //create ship systems
84
        $this->createShipSystemsByModuleList(
85
            $ship,
86
            $this->buildplanModuleRepository->getByBuildplan(
87
                $buildplan->getId()
88
            ),
89
            $progress
90
        );
91
92
        $wrapper = $this->shipWrapperFactory->wrapShip($ship);
93
94
        foreach (ShipModuleTypeEnum::cases() as $moduleType) {
95
96
            $moduleTypeId = $moduleType->value;
97
98
            if ($this->loggerUtil->doLog()) {
99
                $this->loggerUtil->log(sprintf("moduleTypeId: %d", $moduleTypeId));
100
            }
101
            $buildplanModules = $buildplan->getModulesByType($moduleType);
102
            if ($buildplanModules !== []) {
103
                if ($this->loggerUtil->doLog()) {
104
                    $this->loggerUtil->log("wrapperCallable!");
105
                }
106
                $moduleRumpWrapper = $moduleType->getModuleRumpWrapperCallable()($rump, $buildplan);
107
                $moduleRumpWrapper->apply($wrapper);
108
            }
109
        }
110
111
        if ($ship->getName() === '' || $ship->getName() === sprintf('%s in Bau', $ship->getRump()->getName())) {
112
            $ship->setName($ship->getRump()->getName());
113
        }
114
115
        $ship->setAlertStateGreen();
116
117
        $this->shipRepository->save($ship);
118
        if ($colony !== null) {
119
120
            $ship->setLocation($colony->getStarsystemMap());
121
122
            $this->shipRepository->save($ship);
123
        }
124
125
        return $this->shipConfiguratorFactory->createShipConfigurator($wrapper);
126
    }
127
128
    /**
129
     * @param array<BuildplanModuleInterface> $modules
130
     */
131
    private function createShipSystemsByModuleList(
132
        ShipInterface $ship,
133
        array $modules,
134
        ?ConstructionProgressInterface $progress
135
    ): void {
136
        $systems = $this->getDefaultSystems($ship);
137
138
        $this->addModuleSystems($modules, $systems);
139
        $this->addProgressModuleSystems($progress, $systems);
140
141
        foreach ($systems as $systemType => $module) {
142
            $this->createShipSystem($systemType, $ship, $module);
143
        }
144
    }
145
146
    /** @return array<int, ModuleInterface|null>  */
147
    private function getDefaultSystems(ShipInterface $ship): array
148
    {
149
        $systems = [];
150
151
        //default systems, that almost every ship should have
152
        if ($ship->getRump()->getCategoryId() !== ShipRumpEnum::SHIP_CATEGORY_SHUTTLE) {
153
            $systems[ShipSystemTypeEnum::SYSTEM_DEFLECTOR->value] = null;
154
            $systems[ShipSystemTypeEnum::SYSTEM_TRACTOR_BEAM->value] = null;
155
        }
156
        $systems[ShipSystemTypeEnum::SYSTEM_LIFE_SUPPORT->value] = null;
157
        //TODO transporter
158
159
        if ($ship->getRump()->getCategoryId() === ShipRumpEnum::SHIP_CATEGORY_STATION) {
160
            $systems[ShipSystemTypeEnum::SYSTEM_BEAM_BLOCKER->value] = null;
161
        }
162
163
        if ($ship->getRump()->isShipyard()) {
164
            $systems[ShipSystemTypeEnum::SYSTEM_CONSTRUCTION_HUB->value] = null;
165
        }
166
167
        if ($ship->getRump()->getRoleId() === ShipRumpEnum::SHIP_ROLE_SENSOR) {
168
            $systems[ShipSystemTypeEnum::SYSTEM_UPLINK->value] = null;
169
        }
170
171
        return $systems;
172
    }
173
174
    /**
175
     * @param array<BuildplanModuleInterface> $modules
176
     * @param array<int, ModuleInterface|null> $systems
177
     */
178
    private function addModuleSystems(array $modules, array &$systems): void
179
    {
180
        foreach ($modules as $buildplanmodule) {
181
            $module = $buildplanmodule->getModule();
182
183
            $systemType = $module->getSystemType();
184
            if (
185
                $systemType === null
186
                && $module->getType()->hasCorrespondingSystemType()
187
            ) {
188
                $systemType = $module->getType()->getSystemType();
189
            }
190
191
            if ($systemType !== null) {
192
                $systems[$systemType->value] = $module;
193
            }
194
195
            switch ($module->getType()) {
196
                case ShipModuleTypeEnum::SENSOR:
197
                    $systems[ShipSystemTypeEnum::SYSTEM_NBS->value] = null;
198
                    break;
199
                case ShipModuleTypeEnum::SPECIAL:
200
                    $this->addSpecialSystems($module, $systems);
201
                    break;
202
            }
203
        }
204
    }
205
206
    /**
207
     * @param array<int, ModuleInterface|null> $systems
208
     */
209
    private function addProgressModuleSystems(?ConstructionProgressInterface $progress, array &$systems): void
210
    {
211
        if ($progress !== null) {
212
            foreach ($progress->getSpecialModules() as $mod) {
213
                $this->addSpecialSystems($mod->getModule(), $systems);
214
            }
215
        }
216
    }
217
218
    private function createShipSystem(int $systemType, ShipInterface $ship, ?ModuleInterface $module): void
219
    {
220
        $shipSystem = $this->shipSystemRepository->prototype();
221
        $shipSystem->setShip($ship);
222
        $ship->getSystems()->set($systemType, $shipSystem);
223
        $shipSystem->setSystemType(ShipSystemTypeEnum::from($systemType));
224
        if ($module !== null) {
225
            $shipSystem->setModule($module);
226
        }
227
        $shipSystem->setStatus(100);
228
        $shipSystem->setMode(ShipSystemModeEnum::MODE_OFF);
229
230
        $this->shipSystemRepository->save($shipSystem);
231
    }
232
233
    /**
234
     * @param array<int, null|ModuleInterface> $systems
235
     */
236
    private function addSpecialSystems(ModuleInterface $module, array &$systems): void
237
    {
238
        $moduleSpecials = $this->moduleSpecialRepository->getByModule($module->getId());
239
240
        foreach ($moduleSpecials as $special) {
241
            switch ($special->getSpecialId()) {
242
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_CLOAK:
243
                    $systems[ShipSystemTypeEnum::SYSTEM_CLOAK->value] = $module;
244
                    break;
245
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_TACHYON_SCANNER:
246
                    $systems[ShipSystemTypeEnum::SYSTEM_TACHYON_SCANNER->value] = $module;
247
                    break;
248
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_TROOP_QUARTERS:
249
                    $systems[ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS->value] = $module;
250
                    break;
251
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_ASTRO_LABORATORY:
252
                    $systems[ShipSystemTypeEnum::SYSTEM_ASTRO_LABORATORY->value] = $module;
253
                    break;
254
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_SUBSPACE_FIELD_SENSOR:
255
                    $systems[ShipSystemTypeEnum::SYSTEM_SUBSPACE_SCANNER->value] = $module;
256
                    break;
257
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_MATRIX_SENSOR:
258
                    $systems[ShipSystemTypeEnum::SYSTEM_MATRIX_SCANNER->value] = $module;
259
                    break;
260
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_TORPEDO_STORAGE:
261
                    $systems[ShipSystemTypeEnum::SYSTEM_TORPEDO_STORAGE->value] = $module;
262
                    break;
263
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_SHUTTLE_RAMP:
264
                    $systems[ShipSystemTypeEnum::SYSTEM_SHUTTLE_RAMP->value] = $module;
265
                    break;
266
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_TRANSWARP_COIL:
267
                    $systems[ShipSystemTypeEnum::SYSTEM_TRANSWARP_COIL->value] = $module;
268
                    break;
269
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_HIROGEN_TRACKER:
270
                    $systems[ShipSystemTypeEnum::SYSTEM_TRACKER->value] = $module;
271
                    break;
272
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_THOLIAN_WEB:
273
                    $systems[ShipSystemTypeEnum::SYSTEM_THOLIAN_WEB->value] = $module;
274
                    break;
275
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_RPG:
276
                    $systems[ShipSystemTypeEnum::SYSTEM_RPG_MODULE->value] = null;
277
                    break;
278
            }
279
        }
280
    }
281
}
282