Passed
Pull Request — master (#1686)
by Nico
31:24
created

DisassembleShip::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 9
dl 0
loc 20
ccs 0
cts 10
cp 0
crap 2
rs 9.9666
c 0
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\Module\Colony\Action\DisassembleShip;
6
7
use request;
8
use Stu\Component\Colony\Storage\ColonyStorageManagerInterface;
9
use Stu\Module\Colony\Lib\ColonyLibFactoryInterface;
10
use Stu\Module\Colony\Lib\ColonyLoaderInterface;
11
use Stu\Module\Colony\View\ShowShipDisassembly\ShowShipDisassembly;
12
use Stu\Module\Control\ActionControllerInterface;
13
use Stu\Module\Control\GameControllerInterface;
14
use Stu\Module\Ship\Lib\Crew\TroopTransferUtilityInterface;
15
use Stu\Module\Ship\Lib\ShipLoaderInterface;
16
use Stu\Module\Ship\Lib\ShipRemoverInterface;
17
use Stu\Module\Ship\Lib\ShipWrapperInterface;
18
use Stu\Module\Ship\Lib\Torpedo\ClearTorpedoInterface;
19
use Stu\Orm\Entity\ColonyInterface;
20
use Stu\Orm\Entity\ShipInterface;
21
use Stu\Orm\Repository\ColonyRepositoryInterface;
22
use Stu\Orm\Repository\CommodityRepositoryInterface;
23
24
final class DisassembleShip implements ActionControllerInterface
25
{
26
    public const ACTION_IDENTIFIER = 'B_DISASSEMBLE_SHIP';
27
28
    private ColonyLoaderInterface $colonyLoader;
29
30
    private ShipLoaderInterface $shipLoader;
31
32
    private ColonyRepositoryInterface $colonyRepository;
33
34
    private ShipRemoverInterface $shipRemover;
35
36
    private ColonyStorageManagerInterface $colonyStorageManager;
37
38
    private CommodityRepositoryInterface $commodityRepository;
39
40
    private ClearTorpedoInterface $clearTorpedo;
41
42
    private TroopTransferUtilityInterface $troopTransferUtility;
43
44
    private ColonyLibFactoryInterface $colonyLibFactory;
45
46
    public function __construct(
47
        ColonyLoaderInterface $colonyLoader,
48
        ShipLoaderInterface $shipLoader,
49
        ColonyRepositoryInterface $colonyRepository,
50
        ShipRemoverInterface $shipRemover,
51
        ColonyStorageManagerInterface $colonyStorageManager,
52
        CommodityRepositoryInterface $commodityRepository,
53
        ClearTorpedoInterface $clearTorpedo,
54
        ColonyLibFactoryInterface $colonyLibFactory,
55
        TroopTransferUtilityInterface $troopTransferUtility
56
    ) {
57
        $this->colonyLoader = $colonyLoader;
58
        $this->shipLoader = $shipLoader;
59
        $this->colonyRepository = $colonyRepository;
60
        $this->shipRemover = $shipRemover;
61
        $this->colonyStorageManager = $colonyStorageManager;
62
        $this->commodityRepository = $commodityRepository;
63
        $this->clearTorpedo = $clearTorpedo;
64
        $this->troopTransferUtility = $troopTransferUtility;
65
        $this->colonyLibFactory = $colonyLibFactory;
66
    }
67
68
    public function handle(GameControllerInterface $game): void
69
    {
70
        $game->setView(ShowShipDisassembly::VIEW_IDENTIFIER);
71
72
        $userId = $game->getUser()->getId();
73
74
        $colony = $this->colonyLoader->byIdAndUser(
75
            request::indInt('id'),
76
            $userId
77
        );
78
79
        if ($colony->getEps() < 20) {
80
            $game->addInformation(_('Zur Demontage des Schiffes wird 20 Energie benötigt'));
81
            return;
82
        }
83
84
        $freeAssignmentCount = $this->colonyLibFactory->createColonyPopulationCalculator(
85
            $colony
86
        )->getFreeAssignmentCount();
87
88
        $ship_id = request::getIntFatal('ship_id');
89
        $wrapper = $this->shipLoader->getWrapperByIdAndUser($ship_id, $userId);
90
        $ship = $wrapper->get();
91
        if ($ship->getCrewCount() > $freeAssignmentCount) {
92
            $game->addInformation(_('Nicht genügend Platz für die Crew auf der Kolonie'));
93
            return;
94
        }
95
96
        $colony->lowerEps(20);
97
98
        $this->colonyRepository->save($colony);
99
100
        $this->retrieveSomeIntactModules($ship, $colony, $game);
101
        $this->retrieveReactorLoad($wrapper, $colony, $game);
102
        $this->retrieveLoadedTorpedos($wrapper, $colony, $game);
103
104
        $this->transferCrewToColony($ship, $colony);
105
106
        $this->shipRemover->remove($ship);
107
108
        $game->addInformationf(_('Das Schiff wurde demontiert'));
109
    }
110
111
    private function transferCrewToColony(ShipInterface $ship, ColonyInterface $colony): void
112
    {
113
        foreach ($ship->getCrewAssignments() as $crewAssignment) {
114
            $this->troopTransferUtility->assignCrew($crewAssignment, $colony);
115
        }
116
    }
117
118
    private function retrieveSomeIntactModules(ShipInterface $ship, ColonyInterface $colony, GameControllerInterface $game): void
119
    {
120
        $intactModules = [];
121
122
        foreach ($ship->getSystems() as $system) {
123
            if (
124
                $system->getModule() !== null
125
                && $system->getStatus() == 100
126
            ) {
127
                $module = $system->getModule();
128
129
                if (!array_key_exists($module->getId(), $intactModules)) {
130
                    $intactModules[$module->getId()] = $module;
131
                }
132
            }
133
        }
134
135
        $maxStorage = $colony->getMaxStorage();
136
137
        //retrieve 50% of all intact modules
138
        $recycleCount = (int) ceil(count($intactModules) / 2);
139
        for ($i = 1; $i <= $recycleCount; $i++) {
140
            if ($colony->getStorageSum() >= $maxStorage) {
141
                $game->addInformationf(_('Kein Lagerraum frei um Module zu recyclen!'));
142
                break;
143
            }
144
145
            $module = $intactModules[array_rand($intactModules)];
146
            unset($intactModules[$module->getId()]);
147
148
            $this->colonyStorageManager->upperStorage(
149
                $colony,
150
                $module->getCommodity(),
151
                1
152
            );
153
154
            $game->addInformationf(sprintf(_('Folgendes Modul konnte recycelt werden: %s'), $module->getName()));
155
        }
156
    }
157
158
    private function retrieveReactorLoad(ShipWrapperInterface $wrapper, ColonyInterface $colony, GameControllerInterface $game): void
159
    {
160
        $reactorWrapper = $wrapper->getReactorWrapper();
161
        if ($reactorWrapper === null) {
162
            return;
163
        }
164
165
        $reactor = $reactorWrapper->get();
166
167
        $loads = (int) floor($reactorWrapper->getLoad() / $reactor->getLoadUnits());
168
        if ($loads < 1) {
169
            return;
170
        }
171
172
        $maxStorage = $colony->getMaxStorage();
173
174
        foreach ($reactor->getLoadCost() as $commodityId => $loadCost) {
175
            if ($colony->getStorageSum() >= $maxStorage) {
176
                $game->addInformationf(
177
                    _('Kein Lagerraum frei um %s-Mix zu sichern!'),
178
                    $reactor->getSystemType()->getDescription()
179
                );
180
                break;
181
            }
182
183
            $amount = $loads * $loadCost;
184
            if ($maxStorage - $colony->getStorageSum() < $amount) {
185
                $amount = $maxStorage - $colony->getStorageSum();
186
            }
187
188
            $commodity = $this->commodityRepository->find($commodityId);
189
            $this->colonyStorageManager->upperStorage(
190
                $colony,
191
                $commodity,
0 ignored issues
show
Bug introduced by
It seems like $commodity can also be of type null; however, parameter $commodity of Stu\Component\Colony\Sto...terface::upperStorage() does only seem to accept Stu\Orm\Entity\CommodityInterface, 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

191
                /** @scrutinizer ignore-type */ $commodity,
Loading history...
192
                $amount
193
            );
194
195
            $game->addInformationf(sprintf(_('%d Einheiten folgender Ware konnten recycelt werden: %s'), $amount, $commodity->getName()));
196
        }
197
    }
198
199
    private function retrieveLoadedTorpedos(ShipWrapperInterface $wrapper, ColonyInterface $colony, GameControllerInterface $game): void
200
    {
201
        $ship = $wrapper->get();
202
        $torpedoStorage = $ship->getTorpedoStorage();
203
204
        if ($torpedoStorage === null) {
205
            return;
206
        }
207
208
        $maxStorage = $colony->getMaxStorage();
209
210
        if ($colony->getStorageSum() >= $maxStorage) {
211
            $game->addInformationf(_('Kein Lagerraum frei um geladene Torpedos zu sichern!'));
212
            return;
213
        }
214
215
        $amount = $torpedoStorage->getStorage()->getAmount();
216
        if ($maxStorage - $colony->getStorageSum() < $amount) {
217
            $amount = $maxStorage - $colony->getStorageSum();
218
        }
219
220
        $commodity = $torpedoStorage->getStorage()->getCommodity();
221
        $this->colonyStorageManager->upperStorage(
222
            $colony,
223
            $commodity,
224
            $amount
225
        );
226
227
        $this->clearTorpedo->clearTorpedoStorage($wrapper);
228
229
        $game->addInformationf(sprintf(_('%d Einheiten folgender Ware konnten recycelt werden: %s'), $amount, $commodity->getName()));
230
    }
231
232
    public function performSessionCheck(): bool
233
    {
234
        return false;
235
    }
236
}
237