SpacecraftStorageCrewLogic   B
last analyzed

Complexity

Total Complexity 47

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Test Coverage

Coverage 9.52%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 98
dl 0
loc 190
ccs 10
cts 105
cp 0.0952
rs 8.64
c 2
b 1
f 0
wmc 47

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getMaxTransferrableCrew() 0 5 2
A __construct() 0 8 1
B checkCrewStorage() 0 33 7
A getFreeCrewSpace() 0 12 4
C acceptsCrewFrom() 0 46 12
A getOwnCrewCount() 0 9 3
A sendUplinkMessage() 0 12 5
C postCrewTransfer() 0 47 13

How to fix   Complexity   

Complex Class

Complex classes like SpacecraftStorageCrewLogic often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SpacecraftStorageCrewLogic, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Lib\Transfer\Wrapper;
6
7
use Stu\Component\Spacecraft\Crew\SpacecraftCrewCalculatorInterface;
8
use Stu\Component\Spacecraft\System\SpacecraftSystemModeEnum;
9
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
10
use Stu\Component\Spacecraft\System\Type\UplinkShipSystem;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Spacecraft...m\Type\UplinkShipSystem 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\Component\Station\Dock\DockPrivilegeUtilityInterface;
12
use Stu\Lib\Information\InformationInterface;
13
use Stu\Component\Spacecraft\System\Control\ActivatorDeactivatorHelperInterface;
14
use Stu\Module\Spacecraft\Lib\Auxiliary\SpacecraftShutdownInterface;
15
use Stu\Module\Spacecraft\Lib\Auxiliary\SpacecraftStartupInterface;
16
use Stu\Module\Spacecraft\Lib\Crew\TroopTransferUtilityInterface;
17
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
18
use Stu\Orm\Entity\Spacecraft;
19
use Stu\Orm\Entity\Station;
20
use Stu\Orm\Entity\User;
21
22
class SpacecraftStorageCrewLogic
23
{
24 1
    public function __construct(
25
        private readonly TroopTransferUtilityInterface $troopTransferUtility,
26
        private readonly DockPrivilegeUtilityInterface $dockPrivilegeUtility,
27
        private readonly ActivatorDeactivatorHelperInterface $activatorDeactivatorHelper,
28
        private readonly SpacecraftCrewCalculatorInterface $shipCrewCalculator,
29
        private readonly SpacecraftShutdownInterface $spacecraftShutdown,
30
        private readonly SpacecraftStartupInterface $spacecraftStartup
31 1
    ) {}
32
33 4
    public function getMaxTransferrableCrew(Spacecraft $spacecraft, bool $isTarget, User $user): int
34
    {
35 4
        return min(
36 4
            $this->troopTransferUtility->ownCrewOnTarget($user, $spacecraft),
37 4
            $isTarget ? PHP_INT_MAX : $this->troopTransferUtility->getBeamableTroopCount($spacecraft)
38 4
        );
39
    }
40
41 4
    public function getFreeCrewSpace(Spacecraft $spacecraft, User $user): int
42
    {
43 4
        if ($user !== $spacecraft->getUser()) {
44
            if (!$spacecraft->hasUplink()) {
45
                return 0;
46
            }
47
48
            $userCrewOnTarget = $this->troopTransferUtility->ownCrewOnTarget($user, $spacecraft);
49
            return $userCrewOnTarget === 0 ? 1 : 0;
50
        }
51
52 4
        return $this->troopTransferUtility->getFreeQuarters($spacecraft);
53
    }
54
55
    public function checkCrewStorage(SpacecraftWrapperInterface $wrapper, int $amount, bool $isUnload, InformationInterface $information): bool
56
    {
57
        $spacecraft = $wrapper->get();
58
59
        if (!$spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)) {
60
            return true;
61
        }
62
63
        $maxRumpCrew = $this->shipCrewCalculator->getMaxCrewCountByRump($spacecraft->getRump());
64
        $newCrewAmount = $spacecraft->getCrewCount() + ($isUnload ? -$amount : $amount);
65
        if ($newCrewAmount <= $maxRumpCrew) {
66
            return true;
67
        }
68
69
        if (!$spacecraft->isSystemHealthy(SpacecraftSystemTypeEnum::TROOP_QUARTERS)) {
70
            $information->addInformation("Die Truppenquartiere sind zerstört");
71
            return false;
72
        }
73
74
        if ($spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)->getMode()->isActivated()) {
75
            return true;
76
        }
77
78
        if (!$this->activatorDeactivatorHelper->activate(
79
            $wrapper,
80
            SpacecraftSystemTypeEnum::TROOP_QUARTERS,
81
            $information
82
        )) {
83
            $information->addInformation("Die Truppenquartiere konnten nicht aktiviert werden");
84
            return false;
85
        }
86
87
        return true;
88
    }
89
90
    public function acceptsCrewFrom(SpacecraftWrapperInterface $wrapper, int $amount, User $user, InformationInterface $information): bool
91
    {
92
        $spacecraft = $wrapper->get();
93
94
        if (!$spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::LIFE_SUPPORT)) {
95
            $information->addInformationf('Die %s hat keine Lebenserhaltungssysteme', $spacecraft->getName());
96
97
            return false;
98
        }
99
100
        $needsTroopQuarters = $spacecraft->getCrewCount() + $amount > $this->shipCrewCalculator->getMaxCrewCountByRump($spacecraft->getRump());
101
        if (
102
            $needsTroopQuarters
103
            && $spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)
104
            && $spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)->getMode() === SpacecraftSystemModeEnum::MODE_OFF
105
            && !$this->activatorDeactivatorHelper->activate($wrapper, SpacecraftSystemTypeEnum::TROOP_QUARTERS, $information)
106
        ) {
107
            return false;
108
        }
109
110
        if ($spacecraft->getUser() === $user) {
111
            return true;
112
        }
113
114
        if (!$spacecraft instanceof Station) {
115
            return false;
116
        }
117
        if (!$spacecraft->hasUplink()) {
118
            return false;
119
        }
120
121
        if (!$this->dockPrivilegeUtility->checkPrivilegeFor($spacecraft, $user)) {
122
            $information->addInformation("Benötigte Andockerlaubnis wurde verweigert");
123
            return false;
124
        }
125
        if (!$spacecraft->isSystemHealthy(SpacecraftSystemTypeEnum::UPLINK)) {
126
            $information->addInformation("Das Ziel verfügt über keinen intakten Uplink");
127
            return false;
128
        }
129
130
        if ($this->troopTransferUtility->foreignerCount($spacecraft) >= UplinkShipSystem::MAX_FOREIGNERS) {
131
            $information->addInformation("Maximale Anzahl an fremden Crewman ist bereits erreicht");
132
            return false;
133
        }
134
135
        return true;
136
    }
137
138
    public function postCrewTransfer(SpacecraftWrapperInterface $wrapper, int $foreignCrewChangeAmount, InformationInterface $information): void
139
    {
140
        $spacecraft = $wrapper->get();
141
142
        // no crew left, so shut down
143
        if ($spacecraft->getCrewCount() === 0) {
144
            $this->spacecraftShutdown->shutdown($wrapper);
145
            return;
146
        }
147
148
        if ($foreignCrewChangeAmount !== 0) {
149
150
            $ownCrew = $this->getOwnCrewCount($spacecraft);
151
            $minOwnCrew = 0;
152
            $buildplan = $spacecraft->getBuildplan();
153
            if ($buildplan !== null) {
154
                $minOwnCrew = $buildplan->getCrew();
155
            }
156
157
            $hasForeigners = $this->troopTransferUtility->foreignerCount($spacecraft) > 0;
158
            if (
159
                !$hasForeigners
160
                && $spacecraft->getSystemState(SpacecraftSystemTypeEnum::UPLINK)
161
            ) {
162
                $spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::UPLINK)->setMode(SpacecraftSystemModeEnum::MODE_OFF);
163
            }
164
            if (
165
                $hasForeigners
166
                && !$spacecraft->getSystemState(SpacecraftSystemTypeEnum::UPLINK)
167
                && $ownCrew >= $minOwnCrew
168
            ) {
169
                $spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::UPLINK)->setMode(SpacecraftSystemModeEnum::MODE_ON);
170
            }
171
172
            $this->sendUplinkMessage($hasForeigners, $information, $spacecraft->getSystemState(SpacecraftSystemTypeEnum::UPLINK), $ownCrew >= $minOwnCrew);
173
        }
174
175
        if (
176
            $spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)
177
            && $spacecraft->getSystemState(SpacecraftSystemTypeEnum::TROOP_QUARTERS)
178
            && $spacecraft->getBuildplan() !== null
179
            && $spacecraft->getCrewCount() <= $this->shipCrewCalculator->getMaxCrewCountByRump($spacecraft->getRump())
180
        ) {
181
            $this->activatorDeactivatorHelper->deactivate($wrapper, SpacecraftSystemTypeEnum::TROOP_QUARTERS, $information);
182
        }
183
184
        $this->spacecraftStartup->startup($wrapper);
185
    }
186
187
    private function sendUplinkMessage(bool $hasForeigners, InformationInterface $information, bool $state, bool $enoughOwnCrew): void
188
    {
189
        if (!$hasForeigners) {
190
            $information->addInformationf(
191
                'Der Uplink ist %s',
192
                $state ? 'aktiviert' : 'deaktiviert'
193
            );
194
        } else {
195
            $information->addInformationf(
196
                'Der Uplink %s%s',
197
                $state ? 'ist aktiviert' : 'bleibt deaktiviert',
198
                $enoughOwnCrew ? '' : '. Es befindet sich nicht ausreichend Crew des Besitzers an Bord'
199
            );
200
        }
201
    }
202
203
    private function getOwnCrewCount(Spacecraft $spacecraft): int
204
    {
205
        $count = 0;
206
        foreach ($spacecraft->getCrewAssignments() as $spacecraftCrew) {
207
            if ($spacecraftCrew->getCrew()->getUser() === $spacecraft->getUser()) {
208
                $count++;
209
            }
210
        }
211
        return $count;
212
    }
213
}
214