Passed
Push — master ( ef7bc0...8d062d )
by Nico
18:32 queued 09:24
created

ShipRetrofit::addSpecialSystems()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 2
dl 0
loc 7
ccs 0
cts 5
cp 0
crap 12
rs 10
c 0
b 0
f 0
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 Stu\Component\Spacecraft\SpacecraftModuleTypeEnum;
9
use Stu\Lib\Transfer\Storage\StorageManagerInterface;
10
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
11
use Stu\Component\Spacecraft\System\SpacecraftSystemModeEnum;
12
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
13
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
14
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...
15
use Stu\Orm\Entity\ColonyInterface;
16
use Stu\Orm\Entity\ShipInterface;
17
use Stu\Orm\Entity\SpacecraftBuildplanInterface;
18
use Stu\Orm\Entity\ModuleInterface;
19
use Stu\Orm\Repository\SpacecraftSystemRepositoryInterface;
20
use Stu\Orm\Repository\ModuleSpecialRepositoryInterface;
21
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
22
23
24
final class ShipRetrofit implements ShipRetrofitInterface
25
{
26 1
    public function __construct(
27
        private SpacecraftSystemRepositoryInterface $shipSystemRepository,
28
        private ModuleSpecialRepositoryInterface $moduleSpecialRepository,
29
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
30
        private StorageManagerInterface $storageManager,
31
        private PrivateMessageSenderInterface $privateMessageSender
32 1
    ) {}
33
34
    #[Override]
35
    public function updateBy(ShipInterface $ship, SpacecraftBuildplanInterface $newBuildplan, ColonyInterface $colony): void
36
    {
37
        $oldBuildplan = $ship->getBuildplan();
38
        $wrapper = $this->spacecraftWrapperFactory->wrapShip($ship);
39
        $returnedmodules = [];
40
41
        if ($oldBuildplan === null) {
42
            return;
43
        }
44
45
46
        foreach (SpacecraftModuleTypeEnum::getModuleSelectorOrder() as $moduleType) {
47
48
            $oldModules = $oldBuildplan->getModulesByType($moduleType)->toArray();
49
            $newModules = $newBuildplan->getModulesByType($moduleType)->toArray();
50
51
            /** @var array<ModuleInterface> */
52
            $addingModules = array_udiff($newModules, $oldModules, function (ModuleInterface $a, ModuleInterface $b): int {
53
                return $a->getId() - $b->getId();
54
            });
55
56
            /** @var array<ModuleInterface> */
57
            $deletingModules = array_udiff($oldModules, $newModules, function (ModuleInterface $a, ModuleInterface $b): int {
58
                return $a->getId() - $b->getId();
59
            });
60
61
            if ($addingModules !== []) {
62
                $systems = [];
63
                $this->addModuleSystems($addingModules, $systems);
64
                foreach ($systems as $systemType => $module) {
65
                    $this->createShipSystem($systemType, $ship, $module);
66
                    $moduleRumpWrapper = $moduleType->getModuleRumpWrapperCallable()($ship->getRump(), $newBuildplan);
67
                    $moduleRumpWrapper->apply($wrapper);
68
                }
69
            }
70
71
            foreach ($deletingModules as $oldModule) {
72
                $systemType = $oldModule->getSystemType() ?? $oldModule->getType()->getSystemType();
73
                $system = $ship->getSystems()->get($systemType->value);
74
                if ($system !== null) {
75
                    if ($system->getStatus() >= 100 && mt_rand(1, 100) <= 25) {
76
                        $returnedmodules[] = $system->getModule();
77
                    }
78
                    $this->shipSystemRepository->delete($system);
79
                    $ship->getSystems()->removeElement($system);
80
                }
81
            }
82
        }
83
84
        if ($returnedmodules !== []) {
85
            $msg = "
86
            Die folgenden Module wurden durch den Umbau zurückgewonnen: ";
87
            foreach ($returnedmodules as $module) {
88
                if ($module != null) {
89
                    $this->storageManager->upperStorage($colony, $module->getCommodity(), 1);
90
                    $msg .= $module->getName() . ", ";
91
                }
92
            }
93
            $msg = rtrim($msg, ", ");
94
        } else {
95
            $msg = null;
96
        }
97
98
        $txt = _("Auf der Kolonie " . $colony->getName() . " wurde die " . $ship->getName() . " umgerüstet");
99
100
        if ($msg !== null) {
101
            $txt .= '. ' . $msg;
102
        }
103
104
        $this->privateMessageSender->send(
105
            UserEnum::USER_NOONE,
106
            $colony->getUserId(),
107
            $txt,
108
            PrivateMessageFolderTypeEnum::SPECIAL_COLONY
109
        );
110
111
        $ship->setBuildplan($newBuildplan);
112
    }
113
114
    /**
115
     * @param array<ModuleInterface> $modules
116
     * @param array<int, ModuleInterface|null> $systems
117
     */
118
    private function addModuleSystems(array $modules, array &$systems): void
119
    {
120
        foreach ($modules as $module) {
121
122
            $systemType = $module->getSystemType();
123
            if (
124
                $systemType === null
125
                && $module->getType()->hasCorrespondingSystemType()
126
            ) {
127
                $systemType = $module->getType()->getSystemType();
128
            }
129
130
            if ($systemType !== null) {
131
                $systems[$systemType->value] = $module;
132
            }
133
134
            if ($module->getType() === SpacecraftModuleTypeEnum::SPECIAL) {
135
                $this->addSpecialSystems($module, $systems);
136
            }
137
        }
138
    }
139
140
    /**
141
     * @param array<int, null|ModuleInterface> $systems
142
     */
143
    private function addSpecialSystems(ModuleInterface $module, array &$systems): void
144
    {
145
        $moduleSpecials = $this->moduleSpecialRepository->getByModule($module->getId());
146
147
        foreach ($moduleSpecials as $special) {
148
            $moduleSpecial = $special->getSpecialId();
149
            $systems[$moduleSpecial->getSystemType()->value] = $moduleSpecial->hasCorrespondingModule() ? $module : null;
150
        }
151
    }
152
153
154
    private function createShipSystem(int $systemType, ShipInterface $ship, ?ModuleInterface $module): void
155
    {
156
        $shipSystem = $this->shipSystemRepository->prototype();
157
        $shipSystem->setSpacecraft($ship);
158
        $ship->getSystems()->set($systemType, $shipSystem);
159
        $shipSystem->setSystemType(SpacecraftSystemTypeEnum::from($systemType));
160
        if ($module !== null) {
161
            $shipSystem->setModule($module);
162
        }
163
        $shipSystem->setStatus(100);
164
        $shipSystem->setMode(SpacecraftSystemModeEnum::MODE_OFF);
165
166
        $this->shipSystemRepository->save($shipSystem);
167
    }
168
}
169