Test Failed
Push — master ( 6288df...4d55dd )
by Nico
33:49 queued 25:51
created

ActivatorDeactivatorHelper   F

Complexity

Total Complexity 70

Size/Duplication

Total Lines 421
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 217
dl 0
loc 421
ccs 0
cts 219
cp 0
rs 2.8
c 1
b 1
f 0
wmc 70

16 Methods

Rating   Name   Duplication   Size   Complexity  
A deactivateFleet() 0 32 5
A getTargetWrapper() 0 13 2
A setAlertState() 0 22 5
A setAlertYellow() 0 8 2
A setLSSMode() 0 19 3
A deactivate() 0 19 2
B setAlertStateShip() 0 48 10
A setAlertRed() 0 11 2
A activate() 0 19 2
A __construct() 0 8 1
A deactivateIntern() 0 23 5
A activateFleet() 0 32 5
B activateIntern() 0 43 10
A setAlertGreen() 0 11 3
B setAlertStateFleet() 0 33 8
A setWarpSplitFleet() 0 32 5

How to fix   Complexity   

Complex Class

Complex classes like ActivatorDeactivatorHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ActivatorDeactivatorHelper, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Lib;
6
7
use RuntimeException;
8
use Stu\Component\Ship\ShipAlertStateEnum;
9
use Stu\Component\Ship\ShipLSSModeEnum;
10
use Stu\Component\Ship\System\Exception\ActivationConditionsNotMetException;
11
use Stu\Component\Ship\System\Exception\AlreadyActiveException;
12
use Stu\Component\Ship\System\Exception\AlreadyOffException;
13
use Stu\Component\Ship\System\Exception\DeactivationConditionsNotMetException;
14
use Stu\Component\Ship\System\Exception\InsufficientCrewException;
15
use Stu\Component\Ship\System\Exception\InsufficientEnergyException;
16
use Stu\Component\Ship\System\Exception\ShipSystemException;
17
use Stu\Component\Ship\System\Exception\SystemCooldownException;
18
use Stu\Component\Ship\System\Exception\SystemDamagedException;
19
use Stu\Component\Ship\System\Exception\SystemNotActivatableException;
20
use Stu\Component\Ship\System\Exception\SystemNotDeactivatableException;
21
use Stu\Component\Ship\System\Exception\SystemNotFoundException;
22
use Stu\Component\Ship\System\ShipSystemManagerInterface;
23
use Stu\Component\Ship\System\ShipSystemTypeEnum;
24
use Stu\Module\Control\GameControllerInterface;
25
use Stu\Module\Tal\TalHelper;
26
use Stu\Orm\Repository\ShipRepositoryInterface;
27
28
final class ActivatorDeactivatorHelper implements ActivatorDeactivatorHelperInterface
29
{
30
    private ShipLoaderInterface $shipLoader;
31
32
    private ShipRepositoryInterface $shipRepository;
33
34
    private ShipSystemManagerInterface $shipSystemManager;
35
36
    public function __construct(
37
        ShipLoaderInterface $shipLoader,
38
        ShipRepositoryInterface $shipRepository,
39
        ShipSystemManagerInterface $shipSystemManager
40
    ) {
41
        $this->shipLoader = $shipLoader;
42
        $this->shipRepository = $shipRepository;
43
        $this->shipSystemManager = $shipSystemManager;
44
    }
45
46
    public function activate(
47
        ShipWrapperInterface|int $target,
48
        int $systemId,
49
        GameControllerInterface $game,
50
        bool $allowUplink = false
51
    ): bool {
52
        $userId = $game->getUser()->getId();
53
54
        $wrapper = $this->getTargetWrapper(
55
            $target,
56
            $userId,
57
            $allowUplink
58
        );
59
60
        if ($this->activateIntern($wrapper, $systemId, $game)) {
61
            $this->shipRepository->save($wrapper->get());
62
            return true;
63
        } else {
64
            return false;
65
        }
66
    }
67
68
    private function getTargetWrapper(
69
        ShipWrapperInterface|int $target,
70
        int $userId,
71
        bool $allowUplink
72
    ): ShipWrapperInterface {
73
        if ($target instanceof ShipWrapperInterface) {
74
            return $target;
75
        }
76
77
        return $this->shipLoader->getWrapperByIdAndUser(
78
            $target,
79
            $userId,
80
            $allowUplink
81
        );
82
    }
83
84
    private function activateIntern(
85
        ShipWrapperInterface $wrapper,
86
        int $systemId,
87
        GameControllerInterface $game
88
    ): bool {
89
        $systemName = ShipSystemTypeEnum::getDescription($systemId);
90
        $ship = $wrapper->get();
91
92
        try {
93
            $this->shipSystemManager->activate($wrapper, $systemId);
94
            $game->addInformation(sprintf(_('%s: System %s aktiviert'), $ship->getName(), $systemName));
95
            return true;
96
        } catch (AlreadyActiveException $e) {
97
            $game->addInformation(sprintf(_('%s: System %s ist bereits aktiviert'), $ship->getName(), $systemName));
98
        } catch (SystemNotActivatableException $e) {
99
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]System %s besitzt keinen Aktivierungsmodus[/color][/b]'), $ship->getName(), $systemName));
100
        } catch (InsufficientEnergyException $e) {
101
            $game->addInformation(sprintf(
102
                _('%s: [b][color=#ff2626]System %s kann aufgrund Energiemangels (%d benötigt) nicht aktiviert werden[/color][/b]'),
103
                $ship->getName(),
104
                $systemName,
105
                $e->getNeededEnergy()
106
            ));
107
        } catch (SystemCooldownException $e) {
108
            $game->addInformation(sprintf(
109
                _('%s: [b][color=#ff2626]System %s kann nicht aktiviert werden, Cooldown noch %s[/color][/b]'),
110
                $ship->getName(),
111
                $systemName,
112
                TalHelper::formatSeconds((string) $e->getRemainingSeconds())
113
            ));
114
        } catch (SystemDamagedException $e) {
115
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]System %s ist beschädigt und kann daher nicht aktiviert werden[/color][/b]'), $ship->getName(), $systemName));
116
        } catch (ActivationConditionsNotMetException $e) {
117
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]System %s konnte nicht aktiviert werden, weil %s[/color][/b]'), $ship->getName(), $systemName, $e->getMessage()));
118
        } catch (SystemNotFoundException $e) {
119
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]System %s nicht vorhanden[/color][/b]'), $ship->getName(), $systemName));
120
        } catch (InsufficientCrewException $e) {
121
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]System %s konnte wegen Mangel an Crew nicht aktiviert werden[/color][/b]'), $ship->getName(), $systemName));
122
        } catch (ShipSystemException $e) {
123
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]System %s konnte nicht aktiviert werden[/color][/b]'), $ship->getName(), $systemName));
124
        }
125
126
        return false;
127
    }
128
129
    public function activateFleet(
130
        int $shipId,
131
        int $systemId,
132
        GameControllerInterface $game
133
    ): void {
134
        $userId = $game->getUser()->getId();
135
136
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
137
            $shipId,
138
            $userId
139
        );
140
141
        $fleetWrapper = $wrapper->getFleetWrapper();
142
        if ($fleetWrapper === null) {
143
            throw new RuntimeException('ship not in fleet');
144
        }
145
146
        $success = false;
147
        foreach ($fleetWrapper->getShipWrappers() as $wrapper) {
148
            if ($this->activateIntern($wrapper, $systemId, $game)) {
149
                $success = true;
150
                $this->shipRepository->save($wrapper->get());
151
            }
152
        }
153
154
        // only show info if at least one ship was able to change
155
        if (!$success) {
156
            return;
157
        }
158
159
        $systemName = ShipSystemTypeEnum::getDescription($systemId);
160
        $game->addInformation(sprintf(_('Flottenbefehl ausgeführt: System %s aktiviert'), $systemName));
161
    }
162
163
    public function deactivate(
164
        int $shipId,
165
        int $systemId,
166
        GameControllerInterface $game,
167
        bool $allowUplink = false
168
    ): bool {
169
        $userId = $game->getUser()->getId();
170
171
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
172
            $shipId,
173
            $userId,
174
            $allowUplink
175
        );
176
177
        if ($this->deactivateIntern($wrapper, $systemId, $game)) {
178
            $this->shipRepository->save($wrapper->get());
179
            return true;
180
        } else {
181
            return false;
182
        }
183
    }
184
185
    private function deactivateIntern(
186
        ShipWrapperInterface $wrapper,
187
        int $systemId,
188
        GameControllerInterface $game
189
    ): bool {
190
        $systemName = ShipSystemTypeEnum::getDescription($systemId);
191
        $ship = $wrapper->get();
192
193
        try {
194
            $this->shipSystemManager->deactivate($wrapper, $systemId);
195
            $game->addInformation(sprintf(_('%s: System %s deaktiviert'), $ship->getName(), $systemName));
196
            return true;
197
        } catch (AlreadyOffException $e) {
198
            $game->addInformation(sprintf(_('%s: System %s ist bereits deaktiviert'), $ship->getName(), $systemName));
199
        } catch (SystemNotDeactivatableException $e) {
200
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]System %s besitzt keinen Deaktivierungsmodus[/color][/b]'), $ship->getName(), $systemName));
201
        } catch (DeactivationConditionsNotMetException $e) {
202
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]System %s konnte nicht deaktiviert werden, weil %s[/color][/b]'), $ship->getName(), $systemName, $e->getMessage()));
203
        } catch (SystemNotFoundException $e) {
204
            $game->addInformation(sprintf(_('%s: System %s nicht vorhanden'), $ship->getName(), $systemName));
205
        }
206
207
        return false;
208
    }
209
210
    public function deactivateFleet(
211
        int $shipId,
212
        int $systemId,
213
        GameControllerInterface $game
214
    ): void {
215
        $userId = $game->getUser()->getId();
216
217
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
218
            $shipId,
219
            $userId
220
        );
221
222
        $fleetWrapper = $wrapper->getFleetWrapper();
223
        if ($fleetWrapper === null) {
224
            throw new RuntimeException('ship not in fleet');
225
        }
226
227
        $success = false;
228
        foreach ($fleetWrapper->getShipWrappers() as $wrapper) {
229
            if ($this->deactivateIntern($wrapper, $systemId, $game)) {
230
                $success = true;
231
                $this->shipRepository->save($wrapper->get());
232
            }
233
        }
234
235
        // only show info if at least one ship was able to change
236
        if (!$success) {
237
            return;
238
        }
239
240
        $systemName = ShipSystemTypeEnum::getDescription($systemId);
241
        $game->addInformation(sprintf(_('Flottenbefehl ausgeführt: System %s deaktiviert'), $systemName));
242
    }
243
244
    public function setLSSMode(
245
        int $shipId,
246
        int $lssMode,
247
        GameControllerInterface $game
248
    ): void {
249
        $userId = $game->getUser()->getId();
250
251
        $ship = $this->shipLoader->getByIdAndUser(
252
            $shipId,
253
            $userId
254
        );
255
256
        $ship->setLSSMode($lssMode);
257
        $this->shipRepository->save($ship);
258
259
        if ($lssMode === ShipLSSModeEnum::LSS_NORMAL) {
260
            $game->addInformation("Territoriale Grenzanzeige deaktiviert");
261
        } elseif ($lssMode === ShipLSSModeEnum::LSS_BORDER) {
262
            $game->addInformation("Territoriale Grenzanzeige aktiviert");
263
        }
264
    }
265
266
    public function setAlertState(
267
        int $shipId,
268
        int $alertState,
269
        GameControllerInterface $game
270
    ): void {
271
        $userId = $game->getUser()->getId();
272
273
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
274
            $shipId,
275
            $userId
276
        );
277
278
        if (!$this->setAlertStateShip($wrapper, $alertState, $game)) {
279
            return;
280
        }
281
282
        if ($alertState === ShipAlertStateEnum::ALERT_RED) {
283
            $game->addInformation("Die Alarmstufe wurde auf [b][color=red]Rot[/color][/b] geändert");
284
        } elseif ($alertState === ShipAlertStateEnum::ALERT_YELLOW) {
285
            $game->addInformation("Die Alarmstufe wurde auf [b][color=yellow]Gelb[/color][/b] geändert");
286
        } elseif ($alertState === ShipAlertStateEnum::ALERT_GREEN) {
287
            $game->addInformation("Die Alarmstufe wurde auf [b][color=green]Grün[/color][/b] geändert");
288
        }
289
    }
290
291
    public function setAlertStateFleet(
292
        int $shipId,
293
        int $alertState,
294
        GameControllerInterface $game
295
    ): void {
296
        $userId = $game->getUser()->getId();
297
298
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
299
            $shipId,
300
            $userId
301
        );
302
303
        $fleetWrapper = $wrapper->getFleetWrapper();
304
        if ($fleetWrapper === null) {
305
            throw new RuntimeException('ship not in fleet');
306
        }
307
308
        $success = false;
309
        foreach ($fleetWrapper->getShipWrappers() as $wrapper) {
310
            $success = $this->setAlertStateShip($wrapper, $alertState, $game) || $success;
311
        }
312
313
        // only show info if at least one ship was able to change
314
        if (!$success) {
315
            return;
316
        }
317
318
        if ($alertState === ShipAlertStateEnum::ALERT_RED) {
319
            $game->addInformation(_('Flottenbefehl ausgeführt: Alarmstufe [b][color=red]Rot[/color][/b]'));
320
        } elseif ($alertState === ShipAlertStateEnum::ALERT_YELLOW) {
321
            $game->addInformation(_('Flottenbefehl ausgeführt: Alarmstufe [b][color=yellow]Gelb[/color][/b]'));
322
        } elseif ($alertState === ShipAlertStateEnum::ALERT_GREEN) {
323
            $game->addInformation(_('Flottenbefehl ausgeführt: Alarmstufe [b][color=green]Grün[/color][/b]'));
324
        }
325
    }
326
327
    private function setAlertStateShip(ShipWrapperInterface $wrapper, int $alertState, GameControllerInterface $game): bool
328
    {
329
        $ship = $wrapper->get();
330
331
        // station constructions can't change alert state
332
        if ($ship->isConstruction()) {
333
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]Konstrukte können die Alarmstufe nicht ändern[/color][/b]'), $ship->getName()));
334
            return false;
335
        }
336
337
        // can only change when there is enough crew
338
        if (!$ship->hasEnoughCrew()) {
339
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]Mangel an Crew verhindert den Wechsel der Alarmstufe[/color][/b]'), $ship->getName()));
340
            return false;
341
        }
342
343
        if ($alertState === ShipAlertStateEnum::ALERT_RED && $ship->getCloakState()) {
344
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]Tarnung verhindert den Wechsel zu Alarm-Rot[/color][/b]'), $ship->getName()));
345
            return false;
346
        }
347
348
        try {
349
            $alertMsg = $wrapper->setAlertState($alertState);
350
            $this->shipRepository->save($ship);
351
352
            if ($alertMsg !== null) {
353
                $game->addInformation(sprintf(_('%s: [b][color=FAFA03]%s[/color][/b]'), $ship->getName(), $alertMsg));
354
            }
355
        } catch (InsufficientEnergyException $e) {
356
            $game->addInformation(sprintf(_('%s: [b][color=#ff2626]Nicht genügend Energie um die Alarmstufe zu wechseln (%d benötigt)[/color][/b]'), $ship->getName(), $e->getNeededEnergy()));
357
            return false;
358
        }
359
360
        switch ($alertState) {
361
            case ShipAlertStateEnum::ALERT_RED:
362
                $this->setAlertRed($wrapper, $game);
363
                break;
364
            case ShipAlertStateEnum::ALERT_YELLOW:
365
                $this->setAlertYellow($wrapper, $game);
366
                break;
367
            case ShipAlertStateEnum::ALERT_GREEN:
368
                $this->setAlertGreen($wrapper, $game);
369
                break;
370
        }
371
372
        $this->shipRepository->save($ship);
373
374
        return true;
375
    }
376
377
    private function setAlertRed(ShipWrapperInterface $wrapper, GameControllerInterface $game): void
378
    {
379
        $alertSystems = [
380
            ShipSystemTypeEnum::SYSTEM_SHIELDS,
381
            ShipSystemTypeEnum::SYSTEM_NBS,
382
            ShipSystemTypeEnum::SYSTEM_PHASER,
383
            ShipSystemTypeEnum::SYSTEM_TORPEDO
384
        ];
385
386
        foreach ($alertSystems as $systemId) {
387
            $this->activateIntern($wrapper, $systemId, $game);
388
        }
389
    }
390
391
    private function setAlertYellow(ShipWrapperInterface $wrapper, GameControllerInterface $game): void
392
    {
393
        $alertSystems = [
394
            ShipSystemTypeEnum::SYSTEM_NBS
395
        ];
396
397
        foreach ($alertSystems as $systemId) {
398
            $this->activateIntern($wrapper, $systemId, $game);
399
        }
400
    }
401
402
    private function setAlertGreen(ShipWrapperInterface $wrapper, GameControllerInterface $game): void
403
    {
404
        $deactivateSystems = [
405
            ShipSystemTypeEnum::SYSTEM_PHASER,
406
            ShipSystemTypeEnum::SYSTEM_TORPEDO,
407
            ShipSystemTypeEnum::SYSTEM_SHIELDS
408
        ];
409
410
        foreach ($deactivateSystems as $systemId) {
411
            if ($wrapper->get()->hasShipSystem($systemId)) {
412
                $this->deactivateIntern($wrapper, $systemId, $game);
413
            }
414
        }
415
    }
416
417
    public function setWarpSplitFleet(
418
        int $shipId,
419
        GameControllerInterface $game
420
    ): void {
421
        $userId = $game->getUser()->getId();
422
423
        $wrapper = $this->shipLoader->getWrapperByIdAndUser(
424
            $shipId,
425
            $userId
426
        );
427
        $warpsplit = $wrapper->getWarpCoreSystemData()->getWarpCoreSplit();
428
429
        $fleetWrapper = $wrapper->getFleetWrapper();
430
        if ($fleetWrapper === null) {
431
            throw new RuntimeException('ship not in fleet');
432
        }
433
434
        $success = false;
435
        foreach ($fleetWrapper->getShipWrappers() as $wrapper) {
436
            if ($wrapper->getWarpDriveSystemData() !== null) {
437
                $success = true;
438
                $wrapper->getWarpCoreSystemData()->setWarpCoreSplit($warpsplit)->update();
439
            }
440
        }
441
442
        // only show info if at least one ship was able to change
443
        if (!$success) {
444
            return;
445
        }
446
447
448
        $game->addInformation(sprintf(_('Flottenbefehl ausgeführt: Warpkernsplit von %d Prozent auf Flotte angewendet'), $warpsplit));
449
    }
450
}
451