Passed
Push — dev ( 996fbb...25004f )
by Janko
16:40
created

SpacecraftStorageEntityWrapper   F

Complexity

Total Complexity 97

Size/Duplication

Total Lines 437
Duplicated Lines 0 %

Test Coverage

Coverage 8.11%

Importance

Changes 4
Bugs 4 Features 0
Metric Value
eloc 224
dl 0
loc 437
ccs 18
cts 222
cp 0.0811
rs 2
c 4
b 4
f 0
wmc 97

22 Methods

Rating   Name   Duplication   Size   Complexity  
A canTransfer() 0 9 2
A getUser() 0 4 1
A getName() 0 4 1
A getLocation() 0 4 1
A get() 0 4 1
A __construct() 0 13 1
B canStoreTorpedoType() 0 28 7
A getTorpedoCount() 0 4 1
B transfer() 0 37 9
D transferPerSpacecraft() 0 73 18
B acceptsCrewFrom() 0 41 11
A getMaxTorpedos() 0 4 1
B checkCrewStorage() 0 32 7
A getBeamFactor() 0 4 1
C postCrewTransfer() 0 59 17
A canTransferTorpedos() 0 9 2
A changeTorpedo() 0 7 1
A sendUplinkMessage() 0 12 5
A getTorpedo() 0 4 1
A getFreeCrewSpace() 0 13 4
A getOwnCrewCount() 0 9 3
A getMaxTransferrableCrew() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like SpacecraftStorageEntityWrapper 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 SpacecraftStorageEntityWrapper, 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 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 request;
9
use Stu\Component\Spacecraft\Crew\SpacecraftCrewCalculatorInterface;
10
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
11
use Stu\Component\Spacecraft\System\SpacecraftSystemModeEnum;
12
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
13
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...
14
use Stu\Component\Station\Dock\DockPrivilegeUtilityInterface;
15
use Stu\Lib\Information\InformationInterface;
16
use Stu\Lib\Pirate\PirateReactionInterface;
17
use Stu\Lib\Pirate\PirateReactionTriggerEnum;
18
use Stu\Lib\Transfer\CommodityTransferInterface;
19
use Stu\Lib\Transfer\EntityWithStorageInterface;
20
use Stu\Component\Spacecraft\System\Control\ActivatorDeactivatorHelperInterface;
21
use Stu\Module\Spacecraft\Lib\Auxiliary\SpacecraftShutdownInterface;
22
use Stu\Module\Spacecraft\Lib\Crew\TroopTransferUtilityInterface;
23
use Stu\Module\Spacecraft\Lib\Torpedo\ShipTorpedoManagerInterface;
24
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
25
use Stu\Orm\Entity\LocationInterface;
26
use Stu\Orm\Entity\ShipInterface;
27
use Stu\Orm\Entity\SpacecraftInterface;
28
use Stu\Orm\Entity\TorpedoTypeInterface;
29
use Stu\Orm\Entity\UserInterface;
30
31
class SpacecraftStorageEntityWrapper implements StorageEntityWrapperInterface
32
{
33
    private SpacecraftInterface $spacecraft;
34
35 13
    public function __construct(
36
        private ShipTorpedoManagerInterface $shipTorpedoManager,
37
        private PirateReactionInterface $pirateReaction,
38
        private CommodityTransferInterface $commodityTransfer,
39
        private TroopTransferUtilityInterface $troopTransferUtility,
40
        private DockPrivilegeUtilityInterface $dockPrivilegeUtility,
41
        private ActivatorDeactivatorHelperInterface $activatorDeactivatorHelper,
42
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
43
        private SpacecraftCrewCalculatorInterface $shipCrewCalculator,
44
        private SpacecraftShutdownInterface $spacecraftShutdown,
45
        private SpacecraftWrapperInterface $spacecraftWrapper
46
    ) {
47 13
        $this->spacecraft = $spacecraftWrapper->get();
48
    }
49
50
    // GENERAL
51 13
    #[Override]
52
    public function get(): EntityWithStorageInterface
53
    {
54 13
        return $this->spacecraft;
55
    }
56
57 13
    #[Override]
58
    public function getUser(): UserInterface
59
    {
60 13
        return $this->spacecraft->getUser();
61
    }
62
63 10
    #[Override]
64
    public function getName(): string
65
    {
66 10
        return $this->spacecraft->getName();
67
    }
68
69
    #[Override]
70
    public function canTransfer(InformationInterface $information): bool
71
    {
72
        if (!$this->spacecraft->hasEnoughCrew()) {
73
            $information->addInformation("Ungenügend Crew vorhanden");
74
            return false;
75
        }
76
77
        return true;
78
    }
79
80
    #[Override]
81
    public function getLocation(): LocationInterface
82
    {
83
        return $this->spacecraft->getLocation();
84
    }
85
86
    // COMMODITIES
87 11
    #[Override]
88
    public function getBeamFactor(): int
89
    {
90 11
        return $this->spacecraft->getRump()->getBeamFactor();
91
    }
92
93
    #[Override]
94
    public function transfer(
95
        bool $isUnload,
96
        StorageEntityWrapperInterface $target,
97
        InformationInterface $information
98
    ): void {
99
100
        $hasTransfered = false;
101
102
        // check for fleet option
103
        $fleetWrapper = $this->spacecraftWrapper->getFleetWrapper();
104
        if (request::postInt('isfleet') && $fleetWrapper !== null) {
105
            foreach ($fleetWrapper->getShipWrappers() as $wrapper) {
106
                if ($this->transferPerSpacecraft(
107
                    $isUnload,
108
                    $wrapper,
109
                    $target,
110
                    $information
111
                )) {
112
                    $hasTransfered = true;
113
                }
114
            }
115
        } else {
116
            $hasTransfered =  $this->transferPerSpacecraft($isUnload, $this->spacecraftWrapper, $target, $information);
117
        }
118
119
        $targetEntity = $target->get();
120
        if (
121
            !$isUnload
122
            && $hasTransfered
123
            && $this->spacecraft instanceof ShipInterface
124
            && $targetEntity instanceof ShipInterface
125
        ) {
126
            $this->pirateReaction->checkForPirateReaction(
127
                $targetEntity,
128
                PirateReactionTriggerEnum::ON_BEAM,
129
                $this->spacecraft
130
            );
131
        }
132
    }
133
134
    private function transferPerSpacecraft(
135
        bool $isUnload,
136
        SpacecraftWrapperInterface $wrapper,
137
        StorageEntityWrapperInterface $target,
138
        InformationInterface $information
139
    ): bool {
140
141
        $ship = $wrapper->get();
142
        $epsSystem = $wrapper->getEpsSystemData();
143
144
        //sanity checks
145
        $isDockTransfer = $this->commodityTransfer->isDockTransfer($ship, $target->get());
146
        if (!$isDockTransfer && ($epsSystem === null || $epsSystem->getEps() === 0)) {
147
            $information->addInformation("Keine Energie vorhanden");
148
            return false;
149
        }
150
        if ($ship->isCloaked()) {
151
            $information->addInformation("Die Tarnung ist aktiviert");
152
            return false;
153
        }
154
        if ($ship->isWarped()) {
155
            $information->addInformation("Schiff befindet sich im Warp");
156
            return false;
157
        }
158
159
        $transferTarget = $isUnload ? $target->get() : $ship;
160
        if ($transferTarget->getMaxStorage() <= $transferTarget->getStorageSum()) {
161
            $information->addInformationf('%s: Der Lagerraum ist voll', $isUnload ? $target->getName() : $ship->getName());
162
            return false;
163
        }
164
165
        $commodities = request::postArray('commodities');
166
        $gcount = request::postArray('count');
167
168
        $storage = $isUnload ? $ship->getBeamableStorage() : $target->get()->getBeamableStorage();
169
170
        if ($storage->isEmpty()) {
171
            $information->addInformation("Keine Waren zum Beamen vorhanden");
172
            return false;
173
        }
174
        if (count($commodities) == 0 || count($gcount) == 0) {
175
            $information->addInformation("Es wurden keine Waren zum Beamen ausgewählt");
176
            return false;
177
        }
178
        $information->addInformationf(
179
            'Die %s hat folgende Waren %s %s %s transferiert',
180
            $ship->getName(),
181
            $isUnload ? 'zur' : 'von der',
182
            $target->get()->getTransferEntityType()->getName(),
183
            $target->getName()
184
        );
185
186
        $hasTransfered = false;
187
        foreach ($commodities as $key => $value) {
188
            $commodityId = (int) $value;
189
190
            if (!array_key_exists($key, $gcount)) {
191
                continue;
192
            }
193
194
            if ($this->commodityTransfer->transferCommodity(
195
                $commodityId,
196
                $gcount[$key],
197
                $wrapper,
198
                $isUnload ? $ship : $target->get(),
199
                $transferTarget,
200
                $information
201
            )) {
202
                $hasTransfered = true;
203
            }
204
        }
205
206
        return $hasTransfered;
207
    }
208
209
    // CREW
210 4
    #[Override]
211
    public function getMaxTransferrableCrew(bool $isTarget, UserInterface $user): int
212
    {
213 4
        return min(
214 4
            $this->troopTransferUtility->ownCrewOnTarget($user, $this->spacecraft),
215 4
            $isTarget ? PHP_INT_MAX : $this->troopTransferUtility->getBeamableTroopCount($this->spacecraft)
216 4
        );
217
    }
218
219 4
    #[Override]
220
    public function getFreeCrewSpace(UserInterface $user): int
221
    {
222 4
        if ($user !== $this->spacecraft->getUser()) {
223
            if (!$this->spacecraft->hasUplink()) {
224
                return 0;
225
            }
226
227
            $userCrewOnTarget = $this->troopTransferUtility->ownCrewOnTarget($user, $this->spacecraft);
228
            return $userCrewOnTarget === 0 ? 1 : 0;
229
        }
230
231 4
        return $this->troopTransferUtility->getFreeQuarters($this->spacecraft);
232
    }
233
234
    #[Override]
235
    public function checkCrewStorage(int $amount, bool $isUnload, InformationInterface $information): bool
236
    {
237
        if (!$this->spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)) {
238
            return true;
239
        }
240
241
        $maxRumpCrew = $this->shipCrewCalculator->getMaxCrewCountByRump($this->spacecraft->getRump());
242
        $newCrewAmount = $this->spacecraft->getCrewCount() + ($isUnload ? -$amount : $amount);
243
        if ($newCrewAmount <= $maxRumpCrew) {
244
            return true;
245
        }
246
247
        if (!$this->spacecraft->isSystemHealthy(SpacecraftSystemTypeEnum::TROOP_QUARTERS)) {
248
            $information->addInformation("Die Truppenquartiere sind zerstört");
249
            return false;
250
        }
251
252
        if ($this->spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)->getMode()->isActivated()) {
253
            return true;
254
        }
255
256
        if (!$this->activatorDeactivatorHelper->activate(
257
            $this->spacecraftWrapper,
258
            SpacecraftSystemTypeEnum::TROOP_QUARTERS,
259
            $information
260
        )) {
261
            $information->addInformation("Die Truppenquartiere konnten nicht aktiviert werden");
262
            return false;
263
        }
264
265
        return true;
266
    }
267
268
    #[Override]
269
    public function acceptsCrewFrom(int $amount, UserInterface $user, InformationInterface $information): bool
270
    {
271
        if (!$this->spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::LIFE_SUPPORT)) {
272
            $information->addInformationf('Die %s hat keine Lebenserhaltungssysteme', $this->spacecraft->getName());
273
274
            return false;
275
        }
276
277
        $needsTroopQuarters = $this->spacecraft->getCrewCount() + $amount > $this->shipCrewCalculator->getMaxCrewCountByRump($this->spacecraft->getRump());
278
        if (
279
            $needsTroopQuarters
280
            && $this->spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)
281
            && $this->spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)->getMode() === SpacecraftSystemModeEnum::MODE_OFF
282
            && !$this->activatorDeactivatorHelper->activate($this->spacecraftWrapper, SpacecraftSystemTypeEnum::TROOP_QUARTERS, $information)
283
        ) {
284
            return false;
285
        }
286
287
        if ($this->spacecraft->getUser() === $user) {
288
            return true;
289
        }
290
        if (!$this->spacecraft->hasUplink()) {
291
            return false;
292
        }
293
294
        if (!$this->dockPrivilegeUtility->checkPrivilegeFor($this->spacecraft->getId(), $user)) {
295
            $information->addInformation("Benötigte Andockerlaubnis wurde verweigert");
296
            return false;
297
        }
298
        if (!$this->spacecraft->isSystemHealthy(SpacecraftSystemTypeEnum::UPLINK)) {
299
            $information->addInformation("Das Ziel verfügt über keinen intakten Uplink");
300
            return false;
301
        }
302
303
        if ($this->troopTransferUtility->foreignerCount($this->spacecraft) >= UplinkShipSystem::MAX_FOREIGNERS) {
304
            $information->addInformation("Maximale Anzahl an fremden Crewman ist bereits erreicht");
305
            return false;
306
        }
307
308
        return true;
309
    }
310
311
    #[Override]
312
    public function postCrewTransfer(int $foreignCrewChangeAmount, StorageEntityWrapperInterface $other, InformationInterface $information): void
313
    {
314
        // no crew left, so shut down
315
        if ($this->spacecraft->getCrewCount() === 0) {
316
            $this->spacecraftShutdown->shutdown($this->spacecraftWrapper);
317
            return;
318
        }
319
320
        if ($foreignCrewChangeAmount !== 0) {
321
322
            $ownCrew = $this->getOwnCrewCount($this->spacecraft);
323
            $minOwnCrew = 0;
324
            $buildplan = $this->spacecraft->getBuildplan();
325
            if ($buildplan !== null) {
326
                $minOwnCrew = $buildplan->getCrew();
327
            }
328
329
            $hasForeigners = $this->troopTransferUtility->foreignerCount($this->spacecraft) > 0;
330
            if (
331
                !$hasForeigners
332
                && $this->spacecraft->getSystemState(SpacecraftSystemTypeEnum::UPLINK)
333
            ) {
334
                $this->spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::UPLINK)->setMode(SpacecraftSystemModeEnum::MODE_OFF);
335
            }
336
            if (
337
                $hasForeigners
338
                && !$this->spacecraft->getSystemState(SpacecraftSystemTypeEnum::UPLINK)
339
                && $ownCrew >= $minOwnCrew
340
            ) {
341
                $this->spacecraft->getSpacecraftSystem(SpacecraftSystemTypeEnum::UPLINK)->setMode(SpacecraftSystemModeEnum::MODE_ON);
342
            }
343
344
            $this->sendUplinkMessage($hasForeigners, $information, $this->spacecraft->getSystemState(SpacecraftSystemTypeEnum::UPLINK), $ownCrew >= $minOwnCrew);
345
        }
346
347
        if (
348
            $this->spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TROOP_QUARTERS)
349
            && $this->spacecraft->getSystemState(SpacecraftSystemTypeEnum::TROOP_QUARTERS)
350
            && $this->spacecraft->getBuildplan() !== null
351
            && $this->spacecraft->getCrewCount() <= $this->shipCrewCalculator->getMaxCrewCountByRump($this->spacecraft->getRump())
352
        ) {
353
            $this->activatorDeactivatorHelper->deactivate($this->spacecraftWrapper, SpacecraftSystemTypeEnum::TROOP_QUARTERS, $information);
354
        }
355
356
        if (!$this->spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::LIFE_SUPPORT)) {
357
            return;
358
        }
359
360
        if ($this->spacecraft->getCrewCount() === 0) {
361
            $this->spacecraftSystemManager->deactivate($this->spacecraftWrapper, SpacecraftSystemTypeEnum::LIFE_SUPPORT, true);
362
            return;
363
        }
364
365
        if (
366
            $this->spacecraft->getCrewCount() > 0
367
            && !$this->spacecraft->getSystemState(SpacecraftSystemTypeEnum::LIFE_SUPPORT)
368
        ) {
369
            $this->spacecraftSystemManager->activate($this->spacecraftWrapper, SpacecraftSystemTypeEnum::LIFE_SUPPORT, true);
370
        }
371
    }
372
373
    private function sendUplinkMessage(bool $hasForeigners, InformationInterface $information, bool $state, bool $enoughOwnCrew): void
374
    {
375
        if (!$hasForeigners) {
376
            $information->addInformationf(
377
                'Der Uplink ist %s',
378
                $state ? 'aktiviert' : 'deaktiviert'
379
            );
380
        } else {
381
            $information->addInformationf(
382
                'Der Uplink %s%s',
383
                $state ? 'ist aktiviert' : 'bleibt deaktiviert',
384
                $enoughOwnCrew ? '' : '. Es befindet sich nicht ausreichend Crew des Besitzers an Bord'
385
            );
386
        }
387
    }
388
389
    private function getOwnCrewCount(SpacecraftInterface $spacecraft): int
390
    {
391
        $count = 0;
392
        foreach ($spacecraft->getCrewAssignments() as $spacecraftCrew) {
393
            if ($spacecraftCrew->getCrew()->getUser() === $spacecraft->getUser()) {
394
                $count++;
395
            }
396
        }
397
        return $count;
398
    }
399
400
    // TORPEDOS
401
402
    #[Override]
403
    public function getTorpedo(): ?TorpedoTypeInterface
404
    {
405
        return $this->spacecraft->getTorpedo();
406
    }
407
408
    #[Override]
409
    public function getTorpedoCount(): int
410
    {
411
        return $this->spacecraft->getTorpedoCount();
412
    }
413
414
    #[Override]
415
    public function getMaxTorpedos(): int
416
    {
417
        return $this->spacecraft->getMaxTorpedos();
418
    }
419
420
    #[Override]
421
    public function canTransferTorpedos(InformationInterface $information): bool
422
    {
423
        if (!$this->spacecraft->isSystemHealthy(SpacecraftSystemTypeEnum::TORPEDO_STORAGE)) {
424
            $information->addInformation("Das Torpedolager ist zerstört");
425
            return false;
426
        }
427
428
        return true;
429
    }
430
431
    #[Override]
432
    public function canStoreTorpedoType(TorpedoTypeInterface $torpedoType, InformationInterface $information): bool
433
    {
434
        if (
435
            !$this->spacecraft->isSystemHealthy(SpacecraftSystemTypeEnum::TORPEDO_STORAGE)
436
            && $this->spacecraft->getRump()->getTorpedoLevel() !== $torpedoType->getLevel()
437
        ) {
438
            $information->addInformationf('Die %s kann den Torpedotyp nicht ausrüsten', $this->spacecraft->getName());
439
            return false;
440
        }
441
442
        if (
443
            !$this->spacecraft->hasSpacecraftSystem(SpacecraftSystemTypeEnum::TORPEDO_STORAGE)
444
            && $torpedoType->getLevel() > $this->spacecraft->getRump()->getTorpedoLevel()
445
        ) {
446
            $information->addInformationf("Die %s kann den Torpedotyp nicht ausrüsten", $this->spacecraft->getName());
447
            return false;
448
        }
449
450
        if (
451
            $this->spacecraft->getTorpedo() !== null
452
            && $this->spacecraft->getTorpedo() !== $torpedoType
453
        ) {
454
            $information->addInformation("Es ist bereits ein anderer Torpedotyp geladen");
455
            return false;
456
        }
457
458
        return true;
459
    }
460
461
    #[Override]
462
    public function changeTorpedo(int $changeAmount, TorpedoTypeInterface $type): void
463
    {
464
        $this->shipTorpedoManager->changeTorpedo(
465
            $this->spacecraftWrapper,
466
            $changeAmount,
467
            $type
468
        );
469
    }
470
}
471