Passed
Push — dev ( d07f2d...f2f2f9 )
by Nico
08:53
created

ActivatorDeactivatorHelper::deactivateFleet()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 32
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

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