Passed
Push — dev ( 2f14ee...90276d )
by Nico
09:47
created

SpacecraftStorageEntityWrapper::getOwnCrewCount()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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