Passed
Pull Request — master (#1969)
by Janko
22:34 queued 10:03
created

ActivatorDeactivatorHelper::setLssMode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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