Passed
Push — master ( 77a570...adeb98 )
by Nico
26:43
created

ShipRetrofit::updateBy()   C

Complexity

Conditions 13
Paths 45

Size

Total Lines 74
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 182

Importance

Changes 0
Metric Value
cc 13
eloc 44
nc 45
nop 3
dl 0
loc 74
ccs 0
cts 48
cp 0
crap 182
rs 6.6166
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Lib;
6
7
use Stu\Component\Ship\ShipModuleTypeEnum;
8
use Stu\Component\Colony\Storage\ColonyStorageManagerInterface;
9
use Stu\Component\Ship\System\ShipSystemTypeEnum;
10
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...
11
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
12
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
13
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...
14
use Stu\Module\ShipModule\ModuleSpecialAbilityEnum;
15
use Stu\Orm\Entity\ColonyInterface;
16
use Stu\Orm\Entity\ShipInterface;
17
use Stu\Orm\Entity\ShipBuildplanInterface;
18
use Stu\Orm\Entity\ModuleInterface;
19
use Stu\Orm\Repository\ShipSystemRepositoryInterface;
20
use Stu\Orm\Repository\BuildplanModuleRepositoryInterface;
21
use Stu\Orm\Repository\ModuleSpecialRepositoryInterface;
22
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
23
use Stu\Orm\Entity\BuildplanModuleInterface;
24
25
26
final class ShipRetrofit implements ShipRetrofitInterface
27
{
28
    private ShipSystemRepositoryInterface $shipSystemRepository;
29
    private BuildplanModuleRepositoryInterface $buildplanModuleRepository;
30
    private ModuleSpecialRepositoryInterface $moduleSpecialRepository;
31
    private ShipWrapperFactoryInterface $shipWrapperFactory;
32
    private ColonyStorageManagerInterface $colonyStorageManager;
33
    private PrivateMessageSenderInterface $privateMessageSender;
34
35
    public function __construct(
36
        ShipSystemRepositoryInterface $shipSystemRepository,
37
        BuildplanModuleRepositoryInterface $buildplanModuleRepository,
38
        ModuleSpecialRepositoryInterface $moduleSpecialRepository,
39
        ShipWrapperFactoryInterface $shipWrapperFactory,
40
        ColonyStorageManagerInterface $colonyStorageManager,
41
        PrivateMessageSenderInterface $privateMessageSender
42
    ) {
43
        $this->shipSystemRepository = $shipSystemRepository;
44
        $this->buildplanModuleRepository = $buildplanModuleRepository;
45
        $this->moduleSpecialRepository = $moduleSpecialRepository;
46
        $this->shipWrapperFactory = $shipWrapperFactory;
47
        $this->colonyStorageManager = $colonyStorageManager;
48
        $this->privateMessageSender = $privateMessageSender;
49
    }
50
51
    public function updateBy(ShipInterface $ship, ShipBuildplanInterface $newBuildplan, ColonyInterface $colony): void
52
    {
53
        $oldBuildplan = $ship->getBuildplan();
54
        $wrapper = $this->shipWrapperFactory->wrapShip($ship);
55
        $returnedmodules = [];
56
57
        if ($oldBuildplan === null) {
58
            return;
59
        }
60
61
62
        foreach (ShipModuleTypeEnum::cases() as $moduleType) {
63
            $oldModules = $this->buildplanModuleRepository->getByBuildplanAndModuleType($oldBuildplan->getId(), $moduleType->value);
64
            $newModules = $this->buildplanModuleRepository->getByBuildplanAndModuleType($newBuildplan->getId(), $moduleType->value);
65
66
            $addingModules = array_udiff($newModules, $oldModules, function ($a, $b) {
67
                return $a->getModule()->getId() - $b->getModule()->getId();
68
            });
69
70
            $deletingModules = array_udiff($oldModules, $newModules, function ($a, $b) {
71
                return $a->getModule()->getId() - $b->getModule()->getId();
72
            });
73
74
            if (!empty($addingModules)) {
75
                $systems = [];
76
                $this->addModuleSystems($addingModules, $systems);
77
                foreach ($systems as $systemType => $module) {
78
                    $this->createShipSystem($systemType, $ship, $module);
79
                    $moduleRumpWrapper = $moduleType->getModuleRumpWrapperCallable()($ship->getRump(), $newBuildplan);
80
                    $moduleRumpWrapper->apply($wrapper);
81
                }
82
            }
83
84
            foreach ($deletingModules as $oldModule) {
85
                $system = $this->shipSystemRepository->getByShipAndModule($ship->getId(), $oldModule->getModule()->getId());
86
                if ($system !== null) {
87
                    if ($system->getStatus() >= 100) {
88
                        if (mt_rand(1, 100) <= 25) {
89
                            $returnedmodules[] = $system->getModule();
90
                        }
91
                        $this->shipSystemRepository->delete($system);
92
                    }
93
                }
94
            }
95
        }
96
97
        if (!empty($returnedmodules)) {
98
            $msg = "
99
            Die folgenden Module wurden durch den Umbau zurückgewonnen: ";
100
            foreach ($returnedmodules as $module) {
101
                if ($module != null) {
102
                    $this->colonyStorageManager->upperStorage($colony, $module->getCommodity(), 1);
103
                    $msg .= $module->getName() . ", ";
104
                }
105
            }
106
            $msg = rtrim($msg, ", ");
107
        } else {
108
            $msg = null;
109
        }
110
111
        $txt = _("Auf der Kolonie " . $colony->getName() . " wurde die " . $ship->getName() . " umgerüstet");
112
113
        if ($msg !== null) {
114
            $txt .= '. ' . $msg;
115
        }
116
117
        $this->privateMessageSender->send(
118
            UserEnum::USER_NOONE,
119
            $colony->getUserId(),
120
            $txt,
121
            PrivateMessageFolderTypeEnum::SPECIAL_COLONY
122
        );
123
124
        $ship->setBuildplan($newBuildplan);
125
    }
126
127
    /**
128
     * @param array<BuildplanModuleInterface> $modules
129
     * @param array<int, ModuleInterface|null> $systems
130
     */
131
    private function addModuleSystems(array $modules, array &$systems): void
132
    {
133
        foreach ($modules as $buildplanmodule) {
134
            $module = $buildplanmodule->getModule();
135
136
            $systemType = $module->getSystemType();
137
            if (
138
                $systemType === null
139
                && $module->getType()->hasCorrespondingSystemType()
140
            ) {
141
                $systemType = $module->getType()->getSystemType();
142
            }
143
144
            if ($systemType !== null) {
145
                $systems[$systemType->value] = $module;
146
            }
147
148
            switch ($module->getType()) {
149
                case ShipModuleTypeEnum::SPECIAL:
150
                    $this->addSpecialSystems($module, $systems);
151
                    break;
152
            }
153
        }
154
    }
155
156
    /**
157
     * @param array<int, null|ModuleInterface> $systems
158
     */
159
    private function addSpecialSystems(ModuleInterface $module, array &$systems): void
160
    {
161
        $moduleSpecials = $this->moduleSpecialRepository->getByModule($module->getId());
162
163
        foreach ($moduleSpecials as $special) {
164
            switch ($special->getSpecialId()) {
165
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_CLOAK:
166
                    $systems[ShipSystemTypeEnum::SYSTEM_CLOAK->value] = $module;
167
                    break;
168
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_TACHYON_SCANNER:
169
                    $systems[ShipSystemTypeEnum::SYSTEM_TACHYON_SCANNER->value] = $module;
170
                    break;
171
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_TROOP_QUARTERS:
172
                    $systems[ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS->value] = $module;
173
                    break;
174
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_ASTRO_LABORATORY:
175
                    $systems[ShipSystemTypeEnum::SYSTEM_ASTRO_LABORATORY->value] = $module;
176
                    break;
177
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_SUBSPACE_FIELD_SENSOR:
178
                    $systems[ShipSystemTypeEnum::SYSTEM_SUBSPACE_SCANNER->value] = $module;
179
                    break;
180
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_MATRIX_SENSOR:
181
                    $systems[ShipSystemTypeEnum::SYSTEM_MATRIX_SCANNER->value] = $module;
182
                    break;
183
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_TORPEDO_STORAGE:
184
                    $systems[ShipSystemTypeEnum::SYSTEM_TORPEDO_STORAGE->value] = $module;
185
                    break;
186
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_SHUTTLE_RAMP:
187
                    $systems[ShipSystemTypeEnum::SYSTEM_SHUTTLE_RAMP->value] = $module;
188
                    break;
189
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_TRANSWARP_COIL:
190
                    $systems[ShipSystemTypeEnum::SYSTEM_TRANSWARP_COIL->value] = $module;
191
                    break;
192
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_HIROGEN_TRACKER:
193
                    $systems[ShipSystemTypeEnum::SYSTEM_TRACKER->value] = $module;
194
                    break;
195
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_THOLIAN_WEB:
196
                    $systems[ShipSystemTypeEnum::SYSTEM_THOLIAN_WEB->value] = $module;
197
                    break;
198
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_BUSSARD_COLLECTOR:
199
                    $systems[ShipSystemTypeEnum::SYSTEM_BUSSARD_COLLECTOR->value] = $module;
200
                    break;
201
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_RPG:
202
                    $systems[ShipSystemTypeEnum::SYSTEM_RPG_MODULE->value] = null;
203
                    break;
204
                case ModuleSpecialAbilityEnum::MODULE_SPECIAL_AGGREGATION_SYSTEM:
205
                    $systems[ShipSystemTypeEnum::SYSTEM_AGGREGATION_SYSTEM->value] = $module;
206
                    break;
207
            }
208
        }
209
    }
210
211
212
    private function createShipSystem(int $systemType, ShipInterface $ship, ?ModuleInterface $module): void
213
    {
214
        $shipSystem = $this->shipSystemRepository->prototype();
215
        $shipSystem->setShip($ship);
216
        $ship->getSystems()->set($systemType, $shipSystem);
217
        $shipSystem->setSystemType(ShipSystemTypeEnum::from($systemType));
218
        if ($module !== null) {
219
            $shipSystem->setModule($module);
220
        }
221
        $shipSystem->setStatus(100);
222
        $shipSystem->setMode(ShipSystemModeEnum::MODE_OFF);
223
224
        $this->shipSystemRepository->save($shipSystem);
225
    }
226
}