Passed
Pull Request — master (#1866)
by Nico
52:42 queued 25:56
created

TroopTransferStrategy::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 10
dl 0
loc 13
ccs 0
cts 2
cp 0
crap 2
rs 10
c 1
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Lib\Transfer\Strategy;
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\Ship\Crew\ShipCrewCalculatorInterface;
10
use Stu\Component\Ship\System\Exception\ShipSystemException;
11
use Stu\Component\Ship\System\Exception\SystemNotActivatableException;
12
use Stu\Component\Ship\System\Exception\SystemNotFoundException;
13
use Stu\Component\Ship\System\ShipSystemManagerInterface;
14
use Stu\Component\Ship\System\ShipSystemModeEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Ship\System\ShipSystemModeEnum 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...
15
use Stu\Component\Ship\System\ShipSystemTypeEnum;
16
use Stu\Component\Ship\System\Type\UplinkShipSystem;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Ship\System\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...
17
use Stu\Lib\Information\InformationWrapper;
18
use Stu\Module\Colony\Lib\ColonyLibFactoryInterface;
19
use Stu\Module\Control\GameControllerInterface;
20
use Stu\Module\Logging\LoggerUtilFactoryInterface;
21
use Stu\Module\Logging\LoggerUtilInterface;
22
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
23
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
24
use Stu\Module\Ship\Lib\ActivatorDeactivatorHelperInterface;
25
use Stu\Module\Ship\Lib\Auxiliary\ShipShutdownInterface;
26
use Stu\Module\Ship\Lib\Crew\TroopTransferUtilityInterface;
27
use Stu\Module\Ship\Lib\Interaction\DockPrivilegeUtilityInterface;
28
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
29
use Stu\Module\Ship\Lib\ShipWrapperInterface;
30
use Stu\Module\Ship\View\ShowShip\ShowShip;
0 ignored issues
show
Bug introduced by
The type Stu\Module\Ship\View\ShowShip\ShowShip 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...
31
use Stu\Orm\Entity\ColonyInterface;
32
use Stu\Orm\Entity\ShipCrewInterface;
33
use Stu\Orm\Entity\ShipInterface;
34
35
class TroopTransferStrategy implements TransferStrategyInterface
36
{
37
    private LoggerUtilInterface $logger;
38
39
    public function __construct(
40
        private ShipCrewCalculatorInterface $shipCrewCalculator,
41
        private TroopTransferUtilityInterface $transferUtility,
42
        private ColonyLibFactoryInterface $colonyLibFactory,
43
        private ShipSystemManagerInterface $shipSystemManager,
44
        private DockPrivilegeUtilityInterface $dockPrivilegeUtility,
45
        private ActivatorDeactivatorHelperInterface $helper,
46
        private ShipShutdownInterface $shipShutdown,
47
        private ShipWrapperFactoryInterface $shipWrapperFactory,
48
        private PrivateMessageSenderInterface $privateMessageSender,
49
        LoggerUtilFactoryInterface $loggerUtilFactory
50
    ) {
51
        $this->logger = $loggerUtilFactory->getLoggerUtil();
52
    }
53
54
    #[Override]
55
    public function setTemplateVariables(
56
        bool $isUnload,
57
        ShipInterface $ship,
58
        ShipInterface|ColonyInterface $target,
59
        GameControllerInterface $game
60
    ): void {
61
62
        $user = $game->getUser();
63
64
        if (
65
            $target instanceof ShipInterface
66
            && $target->getBuildplan() !== null
67
        ) {
68
            $game->setTemplateVar('SHOW_TARGET_CREW', true);
69
            $game->setTemplateVar('ACTUAL_TARGET_CREW', $target->getCrewCount());
70
            $game->setTemplateVar('MINIMUM_TARGET_CREW', $target->getBuildplan()->getCrew());
71
            $game->setTemplateVar(
72
                'MAXIMUM_TARGET_CREW',
73
                $this->shipCrewCalculator->getMaxCrewCountByShip($target)
74
            );
75
        }
76
77
        $isUplinkSituation = false;
78
79
        if ($target instanceof ColonyInterface) {
80
            if ($isUnload) {
81
                $max = $this->transferUtility->getBeamableTroopCount($ship);
82
            } else {
83
                $max = min(
84
                    $target->getCrewAssignmentAmount(),
85
                    $this->transferUtility->getFreeQuarters($ship)
86
                );
87
            }
88
        } else {
89
            $ownCrewOnTarget = $this->transferUtility->ownCrewOnTarget($user, $target);
90
91
            if ($target->getUser() !== $user) {
92
                if ($target->hasUplink()) {
93
                    $isUplinkSituation = true;
94
                } else {
95
                    return;
96
                }
97
            }
98
99
            if ($isUnload) {
100
                $max = min(
101
                    $this->transferUtility->getBeamableTroopCount($ship),
102
                    $this->transferUtility->getFreeQuarters($target),
103
                    $isUplinkSituation ? ($ownCrewOnTarget === 0 ? 1 : 0) : PHP_INT_MAX
104
                );
105
            } else {
106
                $max = min(
107
                    $ownCrewOnTarget,
108
                    $this->transferUtility->getFreeQuarters($ship)
109
                );
110
111
                echo $ownCrewOnTarget;
112
            }
113
        }
114
115
        if (!$isUplinkSituation && $target->getUser() !== $ship->getUser()) {
116
            return;
117
        }
118
119
        $game->setTemplateVar('MAXIMUM', $max);
120
    }
121
122
    #[Override]
123
    public function transfer(
124
        bool $isUnload,
125
        ShipWrapperInterface $wrapper,
126
        ShipInterface|ColonyInterface $target,
127
        InformationWrapper $informations
128
    ): void {
129
130
        $ship = $wrapper->get();
131
        $user = $ship->getUser();
132
133
        if ($ship->hasShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS) && !$ship->isSystemHealthy(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)) {
134
            $informations->addInformation(_("Die Truppenquartiere sind zerstört"));
135
            return;
136
        }
137
138
        $epsSystem = $wrapper->getEpsSystemData();
139
        if ($epsSystem === null || $epsSystem->getEps() == 0) {
140
            $informations->addInformation(_("Keine Energie vorhanden"));
141
            return;
142
        }
143
        if ($ship->getCloakState()) {
144
            $informations->addInformation(_("Die Tarnung ist aktiviert"));
145
            return;
146
        }
147
        if ($ship->isWarped()) {
148
            $informations->addInformation("Schiff befindet sich im Warp");
149
            return;
150
        }
151
        if ($ship->getShieldState()) {
152
            $informations->addInformation(_("Die Schilde sind aktiviert"));
153
            return;
154
        }
155
156
        $requestedTransferCount = request::postInt('crewcount');
157
        $isColonyTarget = $target instanceof ColonyInterface;
158
        $amount = 0;
159
160
        try {
161
            if ($isColonyTarget) {
162
                if ($isUnload) {
163
                    $amount = $this->transferToColony($requestedTransferCount, $ship, $target);
164
                } else {
165
                    $amount = $this->transferFromColony($requestedTransferCount, $wrapper, $target, $informations);
166
                }
167
            } else {
168
                $isUplinkSituation = false;
169
                $ownCrewOnTarget = $this->transferUtility->ownCrewOnTarget($user, $target);
170
171
                if ($target->getUser() !== $user) {
172
                    if ($target->hasUplink()) {
173
                        $isUplinkSituation = true;
174
                    } else {
175
                        return;
176
                    }
177
                }
178
179
                if ($isUnload) {
180
                    if ($isUplinkSituation) {
181
                        if (!$this->dockPrivilegeUtility->checkPrivilegeFor($target->getId(), $user)) {
182
                            $informations->addInformation(_("Benötigte Andockerlaubnis wurde verweigert"));
183
                            return;
184
                        }
185
                        if (!$target->isSystemHealthy(ShipSystemTypeEnum::SYSTEM_UPLINK)) {
186
                            $informations->addInformation(_("Das Ziel verfügt über keinen intakten Uplink"));
187
                            return;
188
                        }
189
190
                        if ($this->transferUtility->foreignerCount($target) >= UplinkShipSystem::MAX_FOREIGNERS) {
191
                            $informations->addInformation(_("Maximale Anzahl an fremden Crewman ist bereits erreicht"));
192
                        }
193
                    }
194
195
                    $amount = $this->transferToShip($requestedTransferCount, $ship, $target, $isUplinkSituation, $ownCrewOnTarget, $informations);
196
                } else {
197
                    $amount = $this->transferFromShip($requestedTransferCount, $wrapper, $target, $isUplinkSituation, $ownCrewOnTarget, $informations);
198
                }
199
            }
200
        } catch (ShipSystemException) {
201
            return;
202
        }
203
204
        $informations->addInformation(
205
            sprintf(
206
                _('Die %s hat %d Crewman %s der %s transferiert'),
207
                $ship->getName(),
208
                $amount,
209
                $isUnload ? 'zu' : 'von',
210
                $target->getName()
211
            )
212
        );
213
214
        if (
215
            $ship->hasShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)
216
            && $ship->getSystemState(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)
217
            && $ship->getBuildplan() !== null && $ship->getCrewCount() <= $ship->getBuildplan()->getCrew()
218
        ) {
219
            $this->helper->deactivate($wrapper, ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS, $informations);
220
        }
221
    }
222
223
224
    private function transferToColony(int $requestedTransferCount, ShipInterface $ship, ColonyInterface $colony): int
225
    {
226
        $freeAssignmentCount = $this->colonyLibFactory->createColonyPopulationCalculator(
227
            $colony
228
        )->getFreeAssignmentCount();
229
230
        $amount = min(
231
            $requestedTransferCount,
232
            $this->transferUtility->getBeamableTroopCount($ship),
233
            $freeAssignmentCount
234
        );
235
236
        $assignments = $ship->getCrewAssignments()->getValues();
237
238
        for ($i = 0; $i < $amount; $i++) {
239
            //assign crew to colony
240
            $this->transferUtility->assignCrew($assignments[$i], $colony);
241
        }
242
243
        return $amount;
244
    }
245
246
    private function transferFromColony(
247
        int $requestedTransferCount,
248
        ShipWrapperInterface $wrapper,
249
        ColonyInterface $colony,
250
        InformationWrapper $informations
251
    ): int {
252
        $ship = $wrapper->get();
253
254
        $amount = min(
255
            $requestedTransferCount,
256
            $colony->getCrewAssignmentAmount(),
257
            $this->transferUtility->getFreeQuarters($ship)
258
        );
259
260
        if ($ship->hasShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS) && ($amount > 0
261
            && $ship->getShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)->getMode() === ShipSystemModeEnum::MODE_OFF
262
            && !$this->helper->activate($wrapper, ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS, $informations))) {
263
            $amount = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $amount is dead and can be removed.
Loading history...
264
            throw new SystemNotActivatableException();
265
        }
266
267
        $crewAssignments = $colony->getCrewAssignments();
268
269
        for ($i = 0; $i < $amount; $i++) {
270
            /** @var ShipCrewInterface $crewAssignment */
271
            $crewAssignment = $crewAssignments->get(array_rand($crewAssignments->toArray()));
0 ignored issues
show
Bug introduced by
It seems like array_rand($crewAssignments->toArray()) can also be of type array; however, parameter $key of Doctrine\Common\Collecti...adableCollection::get() does only seem to accept integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

271
            $crewAssignment = $crewAssignments->get(/** @scrutinizer ignore-type */ array_rand($crewAssignments->toArray()));
Loading history...
272
273
            $this->transferUtility->assignCrew($crewAssignment, $ship);
274
        }
275
276
        return $amount;
277
    }
278
279
    private function transferToShip(
280
        int $requestedTransferCount,
281
        ShipInterface $ship,
282
        ShipInterface $target,
283
        bool $isUplinkSituation,
284
        int $ownCrewOnTarget,
285
        InformationWrapper $informations
286
    ): int {
287
        if (!$target->hasShipSystem(ShipSystemTypeEnum::SYSTEM_LIFE_SUPPORT)) {
288
            $informations->addInformation(sprintf(_('Die %s hat keine Lebenserhaltungssysteme'), $target->getName()));
289
290
            throw new SystemNotFoundException();
291
        }
292
293
        $this->logger->log(sprintf(
294
            'toShip, requested: %d, beamableOfSource: %d, freeOfTarget: %d',
295
            $requestedTransferCount,
296
            $this->transferUtility->getBeamableTroopCount($ship),
297
            $this->transferUtility->getFreeQuarters($target)
298
        ));
299
300
        $amount = min(
301
            $requestedTransferCount,
302
            $this->transferUtility->getBeamableTroopCount($ship),
303
            $this->transferUtility->getFreeQuarters($target),
304
            $isUplinkSituation ? ($ownCrewOnTarget === 0 ? 1 : 0) : PHP_INT_MAX
305
        );
306
307
        $assignments = $ship->getCrewAssignments()->getValues();
308
309
        if (
310
            $target->hasShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)
311
            && ($target->getShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)->getMode() === ShipSystemModeEnum::MODE_OFF
312
                && !$this->helper->activate($this->shipWrapperFactory->wrapShip($target), ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS, $informations))
313
        ) {
314
            $amount = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $amount is dead and can be removed.
Loading history...
315
            throw new SystemNotActivatableException();
316
        }
317
318
        for ($i = 0; $i < $amount; $i++) {
319
            $this->transferUtility->assignCrew($assignments[$i], $target);
320
        }
321
322
        if ($amount > 0) {
323
            if (
324
                $target->isSystemHealthy(ShipSystemTypeEnum::SYSTEM_LIFE_SUPPORT)
325
                && $target->getShipSystem(ShipSystemTypeEnum::SYSTEM_LIFE_SUPPORT)->getMode() == ShipSystemModeEnum::MODE_OFF
326
            ) {
327
                $this->shipSystemManager->activate($this->shipWrapperFactory->wrapShip($target), ShipSystemTypeEnum::SYSTEM_LIFE_SUPPORT, true);
328
            }
329
330
            if ($isUplinkSituation) {
331
                $target->getShipSystem(ShipSystemTypeEnum::SYSTEM_UPLINK)->setMode(ShipSystemModeEnum::MODE_ON);
332
                $this->sendUplinkMessage(true, true, $ship, $target);
333
            }
334
        }
335
336
        return $amount;
337
    }
338
339
    private function transferFromShip(
340
        int $requestedTransferCount,
341
        ShipWrapperInterface $wrapper,
342
        ShipInterface $target,
343
        bool $isUplinkSituation,
344
        int $ownCrewOnTarget,
345
        InformationWrapper $informations
346
    ): int {
347
        $ship = $wrapper->get();
348
349
        $amount = min(
350
            $requestedTransferCount,
351
            $this->transferUtility->getFreeQuarters($ship),
352
            $ownCrewOnTarget
353
        );
354
355
        if ($amount === 0) {
356
            return 0;
357
        }
358
359
        if (
360
            $ship->hasShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)
361
            && ($ship->getShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)->getMode() === ShipSystemModeEnum::MODE_OFF
362
                && !$this->helper->activate($wrapper, ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS, $informations))
363
        ) {
364
            $amount = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $amount is dead and can be removed.
Loading history...
365
            throw new SystemNotActivatableException();
366
        }
367
368
        $array = $target->getCrewAssignments()->getValues();
369
        $targetCrewCount = $target->getCrewCount();
370
371
        $i = 0;
372
        foreach ($array as $crewAssignment) {
373
            if ($crewAssignment->getCrew()->getUser() !== $ship->getUser()) {
374
                continue;
375
            }
376
377
            $this->transferUtility->assignCrew($crewAssignment, $ship);
378
            $i++;
379
380
            if ($i === $amount) {
381
                break;
382
            }
383
        }
384
385
        if ($isUplinkSituation) {
386
            //no foreigners left, shut down uplink
387
            if ($this->transferUtility->foreignerCount($target) === 0) {
388
                $target->getShipSystem(ShipSystemTypeEnum::SYSTEM_UPLINK)->setMode(ShipSystemModeEnum::MODE_OFF);
389
                $this->sendUplinkMessage(false, false, $ship, $target);
390
            } else {
391
                $this->sendUplinkMessage(false, true, $ship, $target);
392
            }
393
        }
394
395
        $targetWrapper = $this->shipWrapperFactory->wrapShip($target);
396
397
        // no crew left
398
        if ($amount === $targetCrewCount) {
399
            $this->shipShutdown->shutdown($targetWrapper);
400
        } elseif (
401
            $target->hasShipSystem(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)
402
            && $target->getSystemState(ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS)
403
            && $target->getBuildplan() !== null && $target->getCrewCount() <= $target->getBuildplan()->getCrew()
404
        ) {
405
            $this->helper->deactivate($targetWrapper, ShipSystemTypeEnum::SYSTEM_TROOP_QUARTERS, $informations);
406
        }
407
408
        return $amount;
409
    }
410
411
    private function sendUplinkMessage(bool $isUnload, bool $isOn, ShipInterface $ship, ShipInterface $target): void
412
    {
413
        $href = sprintf('ship.php?%s=1&id=%d', ShowShip::VIEW_IDENTIFIER, $target->getId());
414
415
        $msg = sprintf(
416
            _('Die %s von Spieler %s hat 1 Crewman %s deiner Station %s gebeamt. Der Uplink ist %s'),
417
            $ship->getName(),
418
            $ship->getUser()->getName(),
419
            $isUnload ? 'zu' : 'von',
420
            $target->getName(),
421
            $isOn ? 'aktiviert' : 'deaktiviert'
422
        );
423
424
        $this->privateMessageSender->send(
425
            $ship->getUser()->getId(),
426
            $target->getUser()->getId(),
427
            $msg,
428
            PrivateMessageFolderTypeEnum::SPECIAL_STATION,
429
            $href
430
        );
431
    }
432
}
433