Passed
Push — dev ( a2895b...0690be )
by Janko
18:58 queued 09:24
created

ShipTakeoverManager::sendFinishedPm()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

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