Passed
Pull Request — master (#1969)
by Janko
22:34 queued 10:03
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;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Spacecraft...pacecraftSystemModeEnum 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...
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\BuildplanModuleRepositoryInterface;
21
use Stu\Orm\Repository\ModuleSpecialRepositoryInterface;
22
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
23
use Stu\Orm\Entity\BuildplanModuleInterface;
24
25
26
final class ShipRetrofit implements ShipRetrofitInterface
27
{
28 1
    public function __construct(
29
        private SpacecraftSystemRepositoryInterface $shipSystemRepository,
30
        private BuildplanModuleRepositoryInterface $buildplanModuleRepository,
31
        private ModuleSpecialRepositoryInterface $moduleSpecialRepository,
32
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
33
        private StorageManagerInterface $storageManager,
34
        private PrivateMessageSenderInterface $privateMessageSender
35 1
    ) {}
36
37
    #[Override]
38
    public function updateBy(ShipInterface $ship, SpacecraftBuildplanInterface $newBuildplan, ColonyInterface $colony): void
39
    {
40
        $oldBuildplan = $ship->getBuildplan();
41
        $wrapper = $this->spacecraftWrapperFactory->wrapShip($ship);
42
        $returnedmodules = [];
43
44
        if ($oldBuildplan === null) {
45
            return;
46
        }
47
48
49
        foreach (SpacecraftModuleTypeEnum::getModuleSelectorOrder() as $moduleType) {
50
            $oldModules = $this->buildplanModuleRepository->getByBuildplanAndModuleType($oldBuildplan->getId(), $moduleType->value);
51
            $newModules = $this->buildplanModuleRepository->getByBuildplanAndModuleType($newBuildplan->getId(), $moduleType->value);
52
53
            $addingModules = array_udiff($newModules, $oldModules, function ($a, $b): int {
54
                return $a->getModule()->getId() - $b->getModule()->getId();
55
            });
56
57
            $deletingModules = array_udiff($oldModules, $newModules, function ($a, $b): int {
58
                return $a->getModule()->getId() - $b->getModule()->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
                $system = $this->shipSystemRepository->getByShipAndModule($ship->getId(), $oldModule->getModule()->getId());
73
                if ($system !== null) {
74
                    if ($system->getStatus() >= 100 && mt_rand(1, 100) <= 25) {
75
                        $returnedmodules[] = $system->getModule();
76
                    }
77
                    $this->shipSystemRepository->delete($system);
78
                }
79
            }
80
        }
81
82
        if ($returnedmodules !== []) {
83
            $msg = "
84
            Die folgenden Module wurden durch den Umbau zurückgewonnen: ";
85
            foreach ($returnedmodules as $module) {
86
                if ($module != null) {
87
                    $this->storageManager->upperStorage($colony, $module->getCommodity(), 1);
88
                    $msg .= $module->getName() . ", ";
89
                }
90
            }
91
            $msg = rtrim($msg, ", ");
92
        } else {
93
            $msg = null;
94
        }
95
96
        $txt = _("Auf der Kolonie " . $colony->getName() . " wurde die " . $ship->getName() . " umgerüstet");
97
98
        if ($msg !== null) {
99
            $txt .= '. ' . $msg;
100
        }
101
102
        $this->privateMessageSender->send(
103
            UserEnum::USER_NOONE,
104
            $colony->getUserId(),
105
            $txt,
106
            PrivateMessageFolderTypeEnum::SPECIAL_COLONY
107
        );
108
109
        $ship->setBuildplan($newBuildplan);
110
    }
111
112
    /**
113
     * @param array<BuildplanModuleInterface> $modules
114
     * @param array<int, ModuleInterface|null> $systems
115
     */
116
    private function addModuleSystems(array $modules, array &$systems): void
117
    {
118
        foreach ($modules as $buildplanmodule) {
119
            $module = $buildplanmodule->getModule();
120
121
            $systemType = $module->getSystemType();
122
            if (
123
                $systemType === null
124
                && $module->getType()->hasCorrespondingSystemType()
125
            ) {
126
                $systemType = $module->getType()->getSystemType();
127
            }
128
129
            if ($systemType !== null) {
130
                $systems[$systemType->value] = $module;
131
            }
132
133
            if ($module->getType() === SpacecraftModuleTypeEnum::SPECIAL) {
134
                $this->addSpecialSystems($module, $systems);
135
            }
136
        }
137
    }
138
139
    /**
140
     * @param array<int, null|ModuleInterface> $systems
141
     */
142
    private function addSpecialSystems(ModuleInterface $module, array &$systems): void
143
    {
144
        $moduleSpecials = $this->moduleSpecialRepository->getByModule($module->getId());
145
146
        foreach ($moduleSpecials as $special) {
147
            $moduleSpecial = $special->getSpecialId();
148
            $systems[$moduleSpecial->getSystemType()->value] = $moduleSpecial->hasCorrespondingModule() ? $module : null;
149
        }
150
    }
151
152
153
    private function createShipSystem(int $systemType, ShipInterface $ship, ?ModuleInterface $module): void
154
    {
155
        $shipSystem = $this->shipSystemRepository->prototype();
156
        $shipSystem->setSpacecraft($ship);
157
        $ship->getSystems()->set($systemType, $shipSystem);
158
        $shipSystem->setSystemType(SpacecraftSystemTypeEnum::from($systemType));
159
        if ($module !== null) {
160
            $shipSystem->setModule($module);
161
        }
162
        $shipSystem->setStatus(100);
163
        $shipSystem->setMode(SpacecraftSystemModeEnum::MODE_OFF);
164
165
        $this->shipSystemRepository->save($shipSystem);
166
    }
167
}
168