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

ShipTakeoverManager::sendCancelPm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
nc 1
nop 4
dl 0
loc 18
ccs 12
cts 12
cp 1
crap 1
rs 9.9332
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Lib\Interaction;
6
7
use Stu\Component\Ship\ShipStateEnum;
8
use Stu\Module\Control\GameControllerInterface;
9
use Stu\Module\History\Lib\EntryCreatorInterface;
10
use Stu\Module\Message\Lib\PrivateMessageFolderSpecialEnum;
11
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
12
use Stu\Module\PlayerSetting\Lib\UserEnum;
13
use Stu\Module\Prestige\Lib\CreatePrestigeLogInterface;
14
use Stu\Module\Ship\Lib\Fleet\LeaveFleetInterface;
15
use Stu\Module\Ship\View\ShowShip\ShowShip;
16
use Stu\Orm\Entity\BuildplanModuleInterface;
17
use Stu\Orm\Entity\ShipInterface;
18
use Stu\Orm\Entity\ShipTakeoverInterface;
19
use Stu\Orm\Entity\UserInterface;
20
use Stu\Orm\Repository\ShipRepositoryInterface;
21
use Stu\Orm\Repository\ShipTakeoverRepositoryInterface;
22
23
final class ShipTakeoverManager implements ShipTakeoverManagerInterface
24
{
25
    private ShipTakeoverRepositoryInterface $shipTakeoverRepository;
26
27
    private ShipRepositoryInterface $shipRepository;
28
29
    private CreatePrestigeLogInterface $createPrestigeLog;
30
31
    private LeaveFleetInterface $leaveFleet;
32
33
    private EntryCreatorInterface $entryCreator;
34
35
    private PrivateMessageSenderInterface $privateMessageSender;
36
37
    private GameControllerInterface $game;
38
39 15
    public function __construct(
40
        ShipTakeoverRepositoryInterface $shipTakeoverRepository,
41
        ShipRepositoryInterface $shipRepository,
42
        CreatePrestigeLogInterface $createPrestigeLog,
43
        LeaveFleetInterface $leaveFleet,
44
        EntryCreatorInterface $entryCreator,
45
        PrivateMessageSenderInterface $privateMessageSender,
46
        GameControllerInterface $game
47
    ) {
48 15
        $this->shipTakeoverRepository = $shipTakeoverRepository;
49 15
        $this->shipRepository = $shipRepository;
50 15
        $this->createPrestigeLog = $createPrestigeLog;
51 15
        $this->leaveFleet = $leaveFleet;
52 15
        $this->entryCreator = $entryCreator;
53 15
        $this->privateMessageSender = $privateMessageSender;
54 15
        $this->game = $game;
55
    }
56
57 2
    public function getPrestigeForBoardingAttempt(ShipInterface $target): int
58
    {
59 2
        return (int)ceil($this->getPrestigeForTakeover($target) / 10);
60
    }
61
62 2
    public function getPrestigeForTakeover(ShipInterface $target): int
63
    {
64 2
        $buildplan = $target->getBuildplan();
65 2
        if ($buildplan === null) {
66 1
            return self::BOARDING_PRESTIGE_PER_TRY;
67
        }
68
69 1
        return array_reduce(
70 1
            $buildplan->getModules()->toArray(),
71 1
            fn (int $value, BuildplanModuleInterface $buildplanModule) => $value + $buildplanModule->getModule()->getLevel() * self::BOARDING_PRESTIGE_PER_MODULE_LEVEL,
72 1
            self::BOARDING_PRESTIGE_PER_TRY
73 1
        );
74
    }
75
76 2
    public function startTakeover(ShipInterface $source, ShipInterface $target, int $prestige): void
77
    {
78 2
        $takeover = $this->shipTakeoverRepository->prototype();
79 2
        $takeover
80 2
            ->setSourceShip($source)
81 2
            ->setTargetShip($target)
82 2
            ->setPrestige($prestige)
83 2
            ->setStartTurn($this->game->getCurrentRound()->getTurn());
84
85 2
        $this->shipTakeoverRepository->save($takeover);
86
87 2
        $source->setTakeoverActive($takeover);
88
89 2
        $this->createPrestigeLog->createLog(
90 2
            -$prestige,
91 2
            sprintf(
92 2
                '-%d Prestige erhalten für den Start der Übernahme der %s von Spieler %s',
93 2
                $prestige,
94 2
                $target->getName(),
95 2
                $target->getUser()->getName()
96 2
            ),
97 2
            $source->getUser(),
98 2
            time()
99 2
        );
100
101 2
        $isFleet = $target->getFleet() !== null;
102 2
        if ($isFleet) {
103 1
            $this->leaveFleet->leaveFleet($target);
104
        }
105
106 2
        $this->sendStartPm($takeover, $isFleet);
107
    }
108
109
110 2
    private function sendStartPm(ShipTakeoverInterface $takeover, bool $leftFleet): void
111
    {
112 2
        $sourceShip = $takeover->getSourceShip();
113 2
        $sourceUser = $sourceShip->getUser();
114 2
        $target = $takeover->getTargetShip();
115 2
        $targetUser = $target->getUser();
116
117 2
        $href = sprintf('ship.php?%s=1&id=%d', ShowShip::VIEW_IDENTIFIER, $target->getId());
118
119 2
        $this->privateMessageSender->send(
120 2
            $sourceUser->getId(),
121 2
            $targetUser->getId(),
122 2
            sprintf(
123 2
                "Die %s von Spieler %s hat mit der Übernahme der %s begonnen.\n%s\n\nÜbernahme erfolgt in %d Runden.",
124 2
                $sourceShip->getName(),
125 2
                $sourceUser->getName(),
126 2
                $target->getName(),
127 2
                $leftFleet ? 'Die Flotte wurde daher verlassen.' : '',
128 2
                self::TURNS_TO_TAKEOVER
129 2
            ),
130 2
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_SHIP,
131 2
            $href
132 2
        );
133
    }
134
135 2
    public function isTakeoverReady(ShipTakeoverInterface $takeover): bool
136
    {
137 2
        $remainingTurns = $takeover->getStartTurn() + self::TURNS_TO_TAKEOVER - $this->game->getCurrentRound()->getTurn();
138 2
        if ($remainingTurns <= 0) {
139 1
            return true;
140
        }
141
142
        // message to owner of target ship
143 1
        $this->sendRemainingPm(
144 1
            $takeover,
145 1
            $takeover->getSourceShip()->getUser()->getId(),
146 1
            $takeover->getTargetShip(),
147 1
            $remainingTurns
148 1
        );
149
150
        // message to owner of source ship
151 1
        $this->sendRemainingPm(
152 1
            $takeover,
153 1
            UserEnum::USER_NOONE,
154 1
            $takeover->getSourceShip(),
155 1
            $remainingTurns
156 1
        );
157
158 1
        return false;
159
    }
160
161 1
    private function sendRemainingPm(
162
        ShipTakeoverInterface $takeover,
163
        int $fromId,
164
        ShipInterface $linked,
165
        int $remainingTurns
166
    ): void {
167 1
        $href = sprintf('ship.php?%s=1&id=%d', ShowShip::VIEW_IDENTIFIER, $linked->getId());
168
169 1
        $this->privateMessageSender->send(
170 1
            $fromId,
171 1
            $linked->getUser()->getId(),
172 1
            sprintf(
173 1
                'Die Übernahme der %s durch die %s erfolgt in %d Runde(n).',
174 1
                $takeover->getTargetShip()->getName(),
175 1
                $takeover->getSourceShip()->getName(),
176 1
                $remainingTurns
177 1
            ),
178 1
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_SHIP,
179 1
            $href
180 1
        );
181
    }
182
183 4
    public function cancelTakeover(
184
        ?ShipTakeoverInterface $takeover,
185
        string $cause = null,
186
        bool $force = false
187
    ): void {
188
189 4
        if ($takeover === null) {
190 2
            return;
191
        }
192
193 2
        if (!$force && $this->isTargetTractoredBySource($takeover)) {
194
            return;
195
        }
196
197
        // message to owner of target ship
198 2
        $this->sendCancelPm(
199 2
            $takeover,
200 2
            $takeover->getSourceShip()->getUser()->getId(),
201 2
            $takeover->getTargetShip(),
202 2
            $cause
203 2
        );
204
205
        // message to owner of source ship
206 2
        $this->sendCancelPm(
207 2
            $takeover,
208 2
            UserEnum::USER_NOONE,
209 2
            $takeover->getSourceShip(),
210 2
            $cause
211 2
        );
212
213 2
        $this->createPrestigeLog->createLog(
214 2
            $takeover->getPrestige(),
215 2
            sprintf(
216 2
                '%d Prestige erhalten für Abbruch der Übernahme der %s von Spieler %s',
217 2
                $takeover->getPrestige(),
218 2
                $takeover->getTargetShip()->getName(),
219 2
                $takeover->getTargetShip()->getUser()->getName()
220 2
            ),
221 2
            $takeover->getSourceShip()->getUser(),
222 2
            time()
223 2
        );
224
225 2
        $this->removeTakeover($takeover);
226
    }
227
228 2
    private function isTargetTractoredBySource(ShipTakeoverInterface $takeover): bool
229
    {
230 2
        return $takeover->getSourceShip() === $takeover->getTargetShip()->getTractoringShip();
231
    }
232
233
    public function cancelBothTakeover(ShipInterface $ship, string $passiveCause = null): void
234
    {
235
        $this->cancelTakeover(
236
            $ship->getTakeoverActive()
237
        );
238
239
        $this->cancelTakeover(
240
            $ship->getTakeoverPassive(),
241
            $passiveCause
242
        );
243
    }
244
245 2
    private function sendCancelPm(
246
        ShipTakeoverInterface $takeover,
247
        int $fromId,
248
        ShipInterface $linked,
249
        ?string $cause
250
    ): void {
251 2
        $href = sprintf('ship.php?%s=1&id=%d', ShowShip::VIEW_IDENTIFIER, $linked->getId());
252
253 2
        $this->privateMessageSender->send(
254 2
            $fromId,
255 2
            $linked->getUser()->getId(),
256 2
            sprintf(
257 2
                'Die Übernahme der %s wurde abgebrochen%s',
258 2
                $takeover->getTargetShip()->getName(),
259 2
                $cause ?? ''
260 2
            ),
261 2
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_SHIP,
262 2
            $href
263 2
        );
264
    }
265
266 1
    public function finishTakeover(ShipTakeoverInterface $takeover): void
267
    {
268 1
        $sourceUser = $takeover->getSourceShip()->getUser();
269 1
        $targetShip = $takeover->getTargetShip();
270 1
        $targetUser = $targetShip->getUser();
271
272
        // message to previous owner of target ship
273 1
        $this->sendFinishedPm(
274 1
            $takeover,
275 1
            $sourceUser->getId(),
276 1
            $targetUser,
277 1
            sprintf(
278 1
                'Die %s wurde von Spieler %s übernommen',
279 1
                $targetShip->getName(),
280 1
                $sourceUser->getName()
281 1
            ),
282 1
            false
283 1
        );
284
285
        // message to new owner of target ship
286 1
        $this->sendFinishedPm(
287 1
            $takeover,
288 1
            UserEnum::USER_NOONE,
289 1
            $sourceUser,
290 1
            sprintf(
291 1
                'Die %s von Spieler %s wurde übernommen',
292 1
                $targetShip->getName(),
293 1
                $targetUser->getName()
294 1
            ),
295 1
            true
296 1
        );
297
298 1
        $this->entryCreator->addShipEntry(sprintf(
299 1
            _('Die %s (%s) von Spieler %s wurde in Sektor %s durch %s übernommen'),
300 1
            $targetShip->getName(),
301 1
            $targetShip->getRump()->getName(),
302 1
            $targetUser->getName(),
303 1
            $targetShip->getSectorString(),
304 1
            $sourceUser->getName()
305 1
        ));
306
307 1
        $targetShip->setUser($sourceUser);
308 1
        $this->shipRepository->save($targetShip);
309
310 1
        $this->removeTakeover($takeover);
311
    }
312
313 1
    private function sendFinishedPm(
314
        ShipTakeoverInterface $takeover,
315
        int $fromId,
316
        UserInterface $to,
317
        string $message,
318
        bool $addHref
319
    ): void {
320 1
        $href = sprintf('ship.php?%s=1&id=%d', ShowShip::VIEW_IDENTIFIER, $takeover->getTargetShip()->getId());
321
322 1
        $this->privateMessageSender->send(
323 1
            $fromId,
324 1
            $to->getId(),
325 1
            $message,
326 1
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_SHIP,
327 1
            $addHref ? $href : null
328 1
        );
329
    }
330
331 3
    private function removeTakeover(ShipTakeoverInterface $takeover): void
332
    {
333 3
        $sourceShip = $takeover->getSourceShip();
334 3
        $sourceShip
335 3
            ->setTakeoverActive(null)
336 3
            ->setState(ShipStateEnum::SHIP_STATE_NONE);
337
338 3
        $takeover->getTargetShip()->setTakeoverPassive(null);
339
340 3
        $this->shipTakeoverRepository->delete($takeover);
341 3
        $this->shipRepository->save($sourceShip);
342
    }
343
}
344