Passed
Pull Request — master (#1969)
by Janko
22:34 queued 10:03
created

SpacecraftStorageEntityWrapper::postCrewTransfer()   C

Complexity

Conditions 13
Paths 41

Size

Total Lines 47
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 182

Importance

Changes 0
Metric Value
cc 13
eloc 27
nc 41
nop 3
dl 0
loc 47
ccs 0
cts 24
cp 0
crap 182
rs 6.6166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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