Passed
Push — master ( 288b46...98b0e3 )
by Nico
31:30 queued 08:00
created

AttackBuilding::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 12
dl 0
loc 28
ccs 0
cts 14
cp 0
crap 2
rs 9.8333
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\Ship\Action\AttackBuilding;
6
7
use request;
8
use Stu\Component\Building\BuildingEnum;
9
use Stu\Component\Colony\ColonyFunctionManager;
10
use Stu\Component\Colony\ColonyFunctionManagerInterface;
11
use Stu\Lib\InformationWrapper;
12
use Stu\Module\Colony\Lib\PlanetFieldTypeRetrieverInterface;
13
use Stu\Module\Control\ActionControllerInterface;
14
use Stu\Module\Control\GameControllerInterface;
15
use Stu\Module\Message\Lib\PrivateMessageFolderSpecialEnum;
16
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
17
use Stu\Module\Ship\Lib\Battle\AlertRedHelperInterface;
18
use Stu\Module\Ship\Lib\Battle\FightLibInterface;
19
use Stu\Module\Ship\Lib\Message\MessageInterface;
20
use Stu\Module\Ship\Lib\Battle\Provider\AttackerProviderFactoryInterface;
21
use Stu\Module\Ship\Lib\Battle\Weapon\EnergyWeaponPhaseInterface;
22
use Stu\Module\Ship\Lib\Battle\Weapon\ProjectileWeaponPhaseInterface;
23
use Stu\Module\Ship\Lib\InteractionCheckerInterface;
24
use Stu\Module\Ship\Lib\ShipLoaderInterface;
25
use Stu\Module\Ship\View\ShowShip\ShowShip;
26
use Stu\Orm\Repository\ColonyRepositoryInterface;
27
use Stu\Orm\Repository\PlanetFieldRepositoryInterface;
28
29
final class AttackBuilding implements ActionControllerInterface
30
{
31
    public const ACTION_IDENTIFIER = 'B_ATTACK_BUILDING';
32
33
    private ShipLoaderInterface $shipLoader;
34
35
    private PlanetFieldRepositoryInterface $planetFieldRepository;
36
37
    private ColonyRepositoryInterface $colonyRepository;
38
39
    private InteractionCheckerInterface $interactionChecker;
40
41
    private FightLibInterface $fightLib;
42
43
    private EnergyWeaponPhaseInterface $energyWeaponPhase;
44
45
    private ProjectileWeaponPhaseInterface $projectileWeaponPhase;
46
47
    private PrivateMessageSenderInterface $privateMessageSender;
48
49
    private AlertRedHelperInterface $alertRedHelper;
50
51
    private InformationWrapper $informations;
52
53
    private PlanetFieldTypeRetrieverInterface $planetFieldTypeRetriever;
54
55
    private ColonyFunctionManagerInterface $colonyFunctionManager;
56
57
    private AttackerProviderFactoryInterface $attackerProviderFactory;
58
59
    public function __construct(
60
        ShipLoaderInterface $shipLoader,
61
        PlanetFieldRepositoryInterface $planetFieldRepository,
62
        ColonyRepositoryInterface $colonyRepository,
63
        InteractionCheckerInterface $interactionChecker,
64
        FightLibInterface $fightLib,
65
        EnergyWeaponPhaseInterface $energyWeaponPhase,
66
        ProjectileWeaponPhaseInterface $projectileWeaponPhase,
67
        PrivateMessageSenderInterface $privateMessageSender,
68
        AlertRedHelperInterface $alertRedHelper,
69
        PlanetFieldTypeRetrieverInterface $planetFieldTypeRetriever,
70
        ColonyFunctionManagerInterface $colonyFunctionManager,
71
        AttackerProviderFactoryInterface $attackerProviderFactory
72
    ) {
73
        $this->shipLoader = $shipLoader;
74
        $this->planetFieldRepository = $planetFieldRepository;
75
        $this->colonyRepository = $colonyRepository;
76
        $this->interactionChecker = $interactionChecker;
77
        $this->fightLib = $fightLib;
78
        $this->energyWeaponPhase = $energyWeaponPhase;
79
        $this->projectileWeaponPhase = $projectileWeaponPhase;
80
        $this->privateMessageSender = $privateMessageSender;
81
        $this->alertRedHelper = $alertRedHelper;
82
        $this->planetFieldTypeRetriever = $planetFieldTypeRetriever;
83
        $this->colonyFunctionManager = $colonyFunctionManager;
84
        $this->attackerProviderFactory = $attackerProviderFactory;
85
86
        $this->informations = new InformationWrapper();
87
    }
88
89
    public function handle(GameControllerInterface $game): void
90
    {
91
        $user = $game->getUser();
92
        $userId = $user->getId();
93
94
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
95
            request::indInt('id'),
96
            $userId
97
        );
98
99
        $colonyId = request::getIntFatal('colid');
100
        $fieldId = request::getIntFatal('field');
101
102
103
        $field = $this->planetFieldRepository->find($fieldId);
104
        $colony = $this->colonyRepository->find($colonyId);
105
        if ($field === null || $colony === null) {
106
            $game->addInformation(_('Feld oder Kolonie nicht vorhanden'));
107
            return;
108
        }
109
110
        if ($field->getFieldId() >= 80) {
111
            $game->addInformation(_('Der Untergrund kann nicht attackiert werden'));
112
            return;
113
        }
114
115
        $ship = $wrapper->get();
116
117
        if (!$ship->hasEnoughCrew($game)) {
118
            return;
119
        }
120
121
        if ($colony->getUser()->isVacationRequestOldEnough()) {
122
            $game->addInformation(_('Aktion nicht möglich, der Spieler befindet sich im Urlaubsmodus!'));
123
            return;
124
        }
125
126
        $epsSystem = $wrapper->getEpsSystemData();
127
128
        if ($epsSystem === null || $epsSystem->getEps() == 0) {
129
            $game->addInformation(_('Keine Energie vorhanden'));
130
            return;
131
        }
132
        if ($ship->isDisabled()) {
133
            $game->addInformation(_('Das Schiff ist kampfunfähig'));
134
            return;
135
        }
136
137
        if ($colony->getId() !== $field->getColonyId()) {
138
            return;
139
        }
140
        if (!$this->interactionChecker->checkColonyPosition($colony, $ship)) {
141
            return;
142
        }
143
144
        $isFleetAttack = false;
145
        $fleetWrapper = $wrapper->getFleetWrapper();
146
        if ($ship->isFleetLeader() && $fleetWrapper !== null) {
147
            $attackers = $fleetWrapper->getShipWrappers();
148
            $isFleetAttack = true;
149
        } else {
150
            $attackers = [$ship->getId() => $wrapper];
151
        }
152
153
        foreach ($attackers as $attackship) {
154
            $this->informations->addInformationWrapper($this->fightLib->ready($attackship));
155
        }
156
157
        // DEFENDING FLEETS
158
        foreach ($colony->getDefenders() as $fleet) {
159
            $this->alertRedHelper->performAttackCycle($fleet->getLeadShip(), $ship, $this->informations, true);
160
        }
161
162
        // ORBITAL DEFENSE
163
        $count = $this->colonyFunctionManager->getBuildingWithFunctionCount(
164
            $colony,
165
            BuildingEnum::BUILDING_FUNCTION_ENERGY_PHALANX,
166
            [ColonyFunctionManager::STATE_ENABLED]
167
        );
168
        $defendingPhalanx =  $this->attackerProviderFactory->getEnergyPhalanxAttacker($colony);
169
170
        for ($i = 0; $i < $count; $i++) {
171
            $attackerPool = $this->fightLib->filterInactiveShips($attackers);
172
173
            if ($attackerPool === []) {
174
                break;
175
            }
176
            $this->addMessageMerge($this->energyWeaponPhase->fire($defendingPhalanx, $attackerPool));
177
        }
178
179
        $count = $this->colonyFunctionManager->getBuildingWithFunctionCount(
180
            $colony,
181
            BuildingEnum::BUILDING_FUNCTION_PARTICLE_PHALANX,
182
            [ColonyFunctionManager::STATE_ENABLED]
183
        );
184
        $defendingPhalanx = $this->attackerProviderFactory->getProjectilePhalanxAttacker($colony);
185
186
        for ($i = 0; $i < $count; $i++) {
187
            $attackerPool = $this->fightLib->filterInactiveShips($attackers);
188
189
            if ($attackerPool === []) {
190
                break;
191
            }
192
            $this->addMessageMerge($this->projectileWeaponPhase->fire($defendingPhalanx, $attackerPool));
193
        }
194
195
        // OFFENSE OF ATTACKING SHIPS
196
        $isOrbitField = $this->planetFieldTypeRetriever->isOrbitField($field);
197
        $attackerPool = $this->fightLib->filterInactiveShips($attackers);
198
        $count = $this->colonyFunctionManager->getBuildingWithFunctionCount(
199
            $colony,
200
            BuildingEnum::BUILDING_FUNCTION_ANTI_PARTICLE,
201
            [ColonyFunctionManager::STATE_ENABLED]
202
        ) * 6;
203
204
        foreach ($attackerPool as $attackerWrapper) {
205
            $shipAttacker = $this->attackerProviderFactory->getShipAttacker($attackerWrapper);
206
207
            if ($isOrbitField) {
208
                $this->informations->addInformationWrapper($this->energyWeaponPhase->fireAtBuilding($shipAttacker, $field, $isOrbitField));
209
210
                if ($field->getIntegrity() === 0) {
211
                    break;
212
                }
213
            }
214
            $this->informations->addInformationWrapper($this->projectileWeaponPhase->fireAtBuilding($shipAttacker, $field, $isOrbitField, $count));
215
216
            if ($field->getIntegrity() === 0) {
217
                break;
218
            }
219
        }
220
221
        $this->colonyRepository->save($colony);
222
223
        $pm = sprintf(
224
            _("Kampf in Sektor %s, Kolonie %s\n%s"),
225
            $ship->getSectorString(),
226
            $colony->getName(),
227
            $this->informations->getInformationsAsString()
228
        );
229
        $this->privateMessageSender->send(
230
            $userId,
231
            $colony->getUserId(),
232
            $pm,
233
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_COLONY
234
        );
235
236
        if ($ship->isDestroyed()) {
237
            $game->addInformationWrapper($this->informations);
238
            return;
239
        }
240
        $game->setView(ShowShip::VIEW_IDENTIFIER);
241
242
        if ($isFleetAttack) {
243
            $game->addInformation(_("Angriff durchgeführt"));
244
            $game->setTemplateVar('FIGHT_RESULTS', $this->informations->getInformations());
245
        } else {
246
            $game->addInformationWrapper($this->informations);
247
            $game->setTemplateVar('FIGHT_RESULTS', null);
248
        }
249
    }
250
251
    /**
252
     * @param MessageInterface[] $messages
253
     */
254
    private function addMessageMerge(array $messages): void
255
    {
256
        foreach ($messages as $message) {
257
            $this->informations->addInformationArray($message->getMessage());
258
        }
259
    }
260
261
    public function performSessionCheck(): bool
262
    {
263
        return true;
264
    }
265
}
266