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

ShipTakeoverManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 8
dl 0
loc 10
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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