Passed
Push — master ( e78b81...6bf3a3 )
by Janko
29:20 queued 20:05
created

canTransferTorpedos()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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