Passed
Push — master ( f4068b...77f637 )
by Nico
40:27 queued 14:09
created

ShipLeaver   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Test Coverage

Coverage 10.61%

Importance

Changes 0
Metric Value
eloc 65
c 0
b 0
f 0
dl 0
loc 133
ccs 7
cts 66
cp 0.1061
rs 10
wmc 13

6 Methods

Rating   Name   Duplication   Size   Complexity  
A escapeIntoPods() 0 12 2
A dumpCrewman() 0 35 3
A __construct() 0 14 1
A sendPmToOwner() 0 15 1
A letCrewDie() 0 11 3
A evacuate() 0 20 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Lib\Crew;
6
7
use RuntimeException;
8
use Stu\Component\Ship\ShipRumpEnum;
9
use Stu\Module\Message\Lib\PrivateMessageFolderSpecialEnum;
10
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
11
use Stu\Module\Ship\Lib\Auxiliary\ShipShutdownInterface;
12
use Stu\Module\Ship\Lib\Crew\LaunchEscapePodsInterface;
13
use Stu\Module\Ship\Lib\ShipWrapperInterface;
14
use Stu\Orm\Entity\ShipCrewInterface;
15
use Stu\Orm\Entity\ShipInterface;
16
use Stu\Orm\Entity\UserInterface;
17
use Stu\Orm\Repository\CrewRepositoryInterface;
18
use Stu\Orm\Repository\ShipCrewRepositoryInterface;
19
use Stu\Orm\Repository\ShipRumpRepositoryInterface;
20
21
//TODO unit tests
22
final class ShipLeaver implements ShipLeaverInterface
23
{
24
    private ShipCrewRepositoryInterface $shipCrewRepository;
25
26
    private ShipRumpRepositoryInterface $shipRumpRepository;
27
28
    private CrewRepositoryInterface $crewRepository;
29
30
    private LaunchEscapePodsInterface $launchEscapePods;
31
32
    private ShipShutdownInterface $shipShutdown;
33
34
    private PrivateMessageSenderInterface $privateMessageSender;
35
36 1
    public function __construct(
37
        ShipCrewRepositoryInterface $shipCrewRepository,
38
        ShipRumpRepositoryInterface $shipRumpRepository,
39
        CrewRepositoryInterface $crewRepository,
40
        LaunchEscapePodsInterface $launchEscapePods,
41
        ShipShutdownInterface $shipShutdown,
42
        PrivateMessageSenderInterface $privateMessageSender
43
    ) {
44 1
        $this->shipCrewRepository = $shipCrewRepository;
45 1
        $this->shipRumpRepository = $shipRumpRepository;
46 1
        $this->crewRepository = $crewRepository;
47 1
        $this->launchEscapePods = $launchEscapePods;
48 1
        $this->shipShutdown = $shipShutdown;
49 1
        $this->privateMessageSender = $privateMessageSender;
50
    }
51
52
    public function evacuate(ShipWrapperInterface $wrapper): string
53
    {
54
        $ship = $wrapper->get();
55
        $this->shipShutdown->shutdown($wrapper);
56
57
        if ($ship->getRump()->isEscapePods()) {
58
            $this->letCrewDie($ship);
59
            return _('Die Rettungskapseln wurden zerstört, die Crew ist daher verstorben!');
60
        }
61
62
        $podRump = $this->shipRumpRepository->find($ship->getUser()->getFactionId() + ShipRumpEnum::SHIP_RUMP_BASE_ID_ESCAPE_PODS);
63
64
        if ($podRump === null) {
65
            $this->letCrewDie($ship);
66
            return _('Keine Rettungskapseln vorhanden, die Crew ist daher verstorben!');
67
        }
68
69
        $this->escapeIntoPods($ship);
70
71
        return _('Die Crew hat das Schiff in den Rettungskapseln verlassen!');
72
    }
73
74
    private function escapeIntoPods(ShipInterface $ship): void
75
    {
76
        //create pods entity
77
        $pods = $this->launchEscapePods->launch($ship);
78
79
        //transfer crew into pods
80
        //TODO not all...! depends on race config
81
        $crewList = $ship->getCrewAssignments();
82
        foreach ($crewList as $shipCrew) {
83
            $shipCrew->setShip($pods);
84
            $shipCrew->setSlot(null);
85
            $this->shipCrewRepository->save($shipCrew);
86
        }
87
    }
88
89
    public function dumpCrewman(ShipCrewInterface $shipCrew, string $message): string
90
    {
91
        $ship = $shipCrew->getShip();
92
        if ($ship === null) {
93
            throw new RuntimeException('can only dump crewman on ship');
94
        }
95
96
        //create pods entity
97
        $pods = $this->launchEscapePods->launch($ship);
98
99
        if ($pods == null) {
100
            $crew = $shipCrew->getCrew();
101
            $this->shipCrewRepository->delete($shipCrew);
102
            $this->crewRepository->delete($crew);
103
104
            $survivalMessage = _('Der Crewman wurde exekutiert!');
105
        } else {
106
107
            //transfer crewman into pods
108
            $shipCrew->setShip($pods);
109
            $shipCrew->setShipId($pods->getId());
110
            $ship->getCrewAssignments()->removeElement($shipCrew);
111
            $this->shipCrewRepository->save($shipCrew);
112
113
            $survivalMessage = _('Der Crewman hat das Schiff in einer Rettungskapsel verlassen!');
114
        }
115
116
        $this->sendPmToOwner(
117
            $ship->getUser(),
118
            $shipCrew->getUser(),
119
            $message,
120
            $survivalMessage
121
        );
122
123
        return $survivalMessage;
124
    }
125
126
    private function sendPmToOwner(
127
        UserInterface $sender,
128
        UserInterface $owner,
129
        string $message,
130
        string $survivalMessage
131
    ): void {
132
        $this->privateMessageSender->send(
133
            $sender->getId(),
134
            $owner->getId(),
135
            sprintf(
136
                "%s\n%s",
137
                $message,
138
                $survivalMessage
139
            ),
140
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_SYSTEM
141
        );
142
    }
143
144
    private function letCrewDie(ShipInterface $ship): void
145
    {
146
        $crewArray = [];
147
        foreach ($ship->getCrewAssignments() as $shipCrew) {
148
            $crewArray[] = $shipCrew->getCrew();
149
        }
150
151
        $this->shipCrewRepository->truncateByShip($ship->getId());
152
153
        foreach ($crewArray as $crew) {
154
            $this->crewRepository->delete($crew);
155
        }
156
    }
157
}
158