Passed
Push — dev ( 7d6113...6d43b1 )
by Nico
07:10
created

ActivatorDeactivatorHelper::getTargetWrapper()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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