Passed
Push — dev ( abc703...3069a8 )
by Nico
39:22 queued 29:02
created

ShipRetrofit::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 6
dl 0
loc 8
ccs 2
cts 2
cp 1
crap 1
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\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
					$ship->getSystems()->removeElement($system);
79
				}
80
			}
81
		}
82
83
		if ($returnedmodules !== []) {
84
			$msg = "
85
            Die folgenden Module wurden durch den Umbau zurückgewonnen: ";
86
			foreach ($returnedmodules as $module) {
87
				if ($module != null) {
88
					$this->storageManager->upperStorage($colony, $module->getCommodity(), 1);
89
					$msg .= $module->getName() . ", ";
90
				}
91
			}
92
			$msg = rtrim($msg, ", ");
93
		} else {
94
			$msg = null;
95
		}
96
97
		$txt = _("Auf der Kolonie " . $colony->getName() . " wurde die " . $ship->getName() . " umgerüstet");
98
99
		if ($msg !== null) {
100
			$txt .= '. ' . $msg;
101
		}
102
103
		$this->privateMessageSender->send(
104
			UserEnum::USER_NOONE,
105
			$colony->getUserId(),
106
			$txt,
107
			PrivateMessageFolderTypeEnum::SPECIAL_COLONY
108
		);
109
110
		$ship->setBuildplan($newBuildplan);
111
	}
112
113
	/**
114
	 * @param array<BuildplanModuleInterface> $modules
115
	 * @param array<int, ModuleInterface|null> $systems
116
	 */
117
	private function addModuleSystems(array $modules, array &$systems): void
118
	{
119
		foreach ($modules as $buildplanmodule) {
120
			$module = $buildplanmodule->getModule();
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
}