Test Failed
Push — dev ( d4c172...a63c79 )
by Janko
09:28
created

ManageCrew::manage()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 18
nc 4
nop 3
dl 0
loc 28
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Lib\SpacecraftManagement\Manager;
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\Spacecraft\Crew\SpacecraftCrewCalculatorInterface;
10
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
11
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
12
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...
13
use Stu\Lib\SpacecraftManagement\Provider\ManagerProviderInterface;
14
use Stu\Module\Spacecraft\Lib\Auxiliary\ShipShutdownInterface;
15
use Stu\Module\Spacecraft\Lib\Crew\SpacecraftLeaverInterface;
16
use Stu\Module\Spacecraft\Lib\Crew\TroopTransferUtilityInterface;
17
use Stu\Module\Spacecraft\Lib\ActivatorDeactivatorHelperInterface;
18
use Stu\Lib\Information\InformationWrapper;
19
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
20
use Stu\Orm\Entity\SpacecraftBuildplanInterface;
21
use Stu\Orm\Entity\SpacecraftInterface;
22
23
class ManageCrew implements ManagerInterface
24
{
25
    public function __construct(
26
        private SpacecraftCrewCalculatorInterface $shipCrewCalculator,
27
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
28
        private TroopTransferUtilityInterface $troopTransferUtility,
29
        private ShipShutdownInterface $shipShutdown,
30
        private SpacecraftLeaverInterface $spacecraftLeaver,
31
        private ActivatorDeactivatorHelperInterface $helper
32
    ) {}
33
34
    #[Override]
35
    public function manage(SpacecraftWrapperInterface $wrapper, array $values, ManagerProviderInterface $managerProvider): array
36
    {
37
        $msg = [];
38
        $informations = new InformationWrapper();
39
40
        $newCrewCountArray = $values['crew'] ?? null;
41
        if ($newCrewCountArray === null) {
42
            throw new RuntimeException('value array not existent');
43
        }
44
45
        $ship = $wrapper->get();
46
        $user = $managerProvider->getUser();
47
        $buildplan = $ship->getBuildplan();
48
49
        if (
50
            isset($newCrewCountArray[$ship->getId()])
51
            && $ship->canMan()
52
            && $buildplan !== null
53
            && $ship->getUser() === $user
54
        ) {
55
            $newCrewCount = (int)$newCrewCountArray[$ship->getId()];
56
            if ($ship->getCrewCount() !== $newCrewCount) {
57
                $this->setNewCrew($newCrewCount, $wrapper, $buildplan, $managerProvider, $msg, $informations);
58
            }
59
        }
60
61
        return array_merge($msg, $informations->getInformations());
62
    }
63
64
    /**
65
     * @param array<string> $msg
66
     */
67
    private function setNewCrew(
68
        int $newCrewCount,
69
        SpacecraftWrapperInterface $wrapper,
70
        SpacecraftBuildplanInterface $buildplan,
71
        ManagerProviderInterface $managerProvider,
72
        array &$msg,
73
        InformationWrapper $informations
74
    ): void {
75
        $ship = $wrapper->get();
76
77
        if ($newCrewCount > $ship->getCrewCount()) {
78
            $this->increaseCrew($newCrewCount, $wrapper, $buildplan, $managerProvider, $msg, $informations);
79
        } else {
80
            $this->descreaseCrew($newCrewCount, $wrapper, $managerProvider, $msg);
81
        }
82
    }
83
84
    /**
85
     * @param array<string> $msg
86
     */
87
    private function increaseCrew(
88
        int $newCrewCount,
89
        SpacecraftWrapperInterface $wrapper,
90
        SpacecraftBuildplanInterface $buildplan,
91
        ManagerProviderInterface $managerProvider,
92
        array &$msg,
93
        InformationWrapper $informations
94
    ): void {
95
        $ship = $wrapper->get();
96
97
        if ($managerProvider->getFreeCrewAmount() == 0) {
98
            $msg[] = sprintf(
99
                _('%s: Keine Crew auf der %s vorhanden'),
100
                $ship->getName(),
101
                $managerProvider->getName(),
102
                $buildplan->getCrew()
103
            );
104
        } else {
105
            $additionalCrew = min(
106
                $newCrewCount - $ship->getCrewCount(),
107
                $managerProvider->getFreeCrewAmount()
108
            );
109
110
            if ($ship->getBuildplan() != null) {
111
                $mincrew = $ship->getBuildplan()->getCrew();
112
                $actualcrew = $ship->getCrewCount();
113
                $maxcrew = $this->shipCrewCalculator->getMaxCrewCountByRump($ship->getRump());
114
115
                if (
116
                    $actualcrew >= $mincrew
117
                    && $actualcrew + $additionalCrew > $maxcrew
118
                    && ($ship->hasShipSystem(SpacecraftSystemTypeEnum::SYSTEM_TROOP_QUARTERS) && ($additionalCrew > 0
119
                        && $ship->getShipSystem(SpacecraftSystemTypeEnum::SYSTEM_TROOP_QUARTERS)->getMode() === SpacecraftSystemModeEnum::MODE_OFF
120
                        && !$this->helper->activate($wrapper, SpacecraftSystemTypeEnum::SYSTEM_TROOP_QUARTERS, $informations)))
121
                ) {
122
123
                    $additionalCrew  = 0;
124
                }
125
            }
126
127
            $managerProvider->addCrewAssignment($ship, $additionalCrew);
128
            $msg[] = sprintf(
129
                _('%s: %d Crewman wurde(n) hochgebeamt'),
130
                $ship->getName(),
131
                $additionalCrew
132
            );
133
134
            if ($ship->hasShipSystem(SpacecraftSystemTypeEnum::SYSTEM_LIFE_SUPPORT)) {
135
                $this->spacecraftSystemManager->activate($wrapper, SpacecraftSystemTypeEnum::SYSTEM_LIFE_SUPPORT, true);
136
            }
137
        }
138
    }
139
140
    /**
141
     * @param array<string> $msg
142
     */
143
    private function descreaseCrew(
144
        int $newCrewCount,
145
        SpacecraftWrapperInterface $wrapper,
146
        ManagerProviderInterface $managerProvider,
147
        array &$msg
148
    ): void {
149
        $ship = $wrapper->get();
150
        $user = $managerProvider->getUser();
151
152
        if ($managerProvider->getFreeCrewStorage() == 0) {
153
            $msg[] = sprintf(
154
                _('%s: Kein Platz für die Crew auf der %s'),
155
                $ship->getName(),
156
                $managerProvider->getName()
157
            );
158
            return;
159
        }
160
161
        $ownCrewCount = $this->troopTransferUtility->ownCrewOnTarget($user, $ship);
162
163
        $removedCrew = min(
164
            $ownCrewCount,
165
            $ship->getCrewCount() - $newCrewCount,
166
            $managerProvider->getFreeCrewStorage()
167
        );
168
169
        $this->dumpForeignCrew($ship);
170
171
        $managerProvider->addCrewAssignments(array_slice(
172
            $ship->getCrewAssignments()->toArray(),
173
            0,
174
            $removedCrew
175
        ));
176
177
        $msg[] = sprintf(
178
            _('%s: %d Crewman wurde(n) runtergebeamt'),
179
            $ship->getName(),
180
            $removedCrew
181
        );
182
183
        if ($removedCrew === $ownCrewCount) {
184
            $this->shipShutdown->shutdown($wrapper);
185
        }
186
    }
187
188
    private function dumpForeignCrew(SpacecraftInterface $spacecraft): void
189
    {
190
        foreach ($spacecraft->getCrewAssignments() as $shipCrew) {
191
            if ($shipCrew->getCrew()->getUser() !== $spacecraft->getUser()) {
192
                $this->spacecraftLeaver->dumpCrewman(
193
                    $shipCrew,
194
                    sprintf(
195
                        'Die Dienste von Crewman %s werden nicht mehr auf der Station %s von Spieler %s benötigt.',
196
                        $shipCrew->getCrew()->getName(),
197
                        $spacecraft->getName(),
198
                        $spacecraft->getUser()->getName(),
199
                    )
200
                );
201
            }
202
        }
203
    }
204
}
205