Passed
Push — dev ( c3d0e2...ce9987 )
by Nico
05:22
created

CrewLimitations   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 197
Duplicated Lines 0 %

Test Coverage

Coverage 46.79%

Importance

Changes 0
Metric Value
eloc 99
dl 0
loc 197
ccs 51
cts 109
cp 0.4679
rs 9.68
c 0
b 0
f 0
wmc 34

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
B work() 0 32 10
A letEscapePodAssignmentsQuit() 0 25 4
A letTradepostAssignmentsQuit() 0 25 4
B letCrewQuit() 0 38 7
A letShipAssignmentsQuit() 0 26 4
A letColonyAssignmentsQuit() 0 25 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Tick\Spacecraft\ManagerComponent;
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\Player\CrewLimitCalculatorInterface;
9
use Stu\Component\Spacecraft\SpacecraftAlertStateEnum;
10
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
11
use Stu\Lib\Information\InformationWrapper;
12
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
13
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
14
use Stu\Module\PlayerSetting\Lib\UserConstants;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserConstants 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...
15
use Stu\Module\Spacecraft\Lib\Battle\AlertDetection\AlertReactionFacadeInterface;
16
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
17
use Stu\Orm\Entity\Spacecraft;
18
use Stu\Orm\Entity\User;
19
use Stu\Orm\Repository\CrewRepositoryInterface;
20
use Stu\Orm\Repository\CrewAssignmentRepositoryInterface;
21
use Stu\Orm\Repository\SpacecraftRepositoryInterface;
22
use Stu\Orm\Repository\UserRepositoryInterface;
23
24
final class CrewLimitations implements ManagerComponentInterface
25
{
26 1
    public function __construct(
27
        private PrivateMessageSenderInterface $privateMessageSender,
28
        private SpacecraftRepositoryInterface $spacecraftRepository,
29
        private UserRepositoryInterface $userRepository,
30
        private CrewRepositoryInterface $crewRepository,
31
        private CrewAssignmentRepositoryInterface $shipCrewRepository,
32
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
33
        private AlertReactionFacadeInterface $alertReactionFacade,
34
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
35
        private CrewLimitCalculatorInterface $crewLimitCalculator
36 1
    ) {}
37
38 1
    #[Override]
39
    public function work(): void
40
    {
41 1
        $userList = $this->userRepository->getNonNpcList();
42
43 1
        foreach ($userList as $user) {
44
            //only handle user that are not on vacation
45 1
            if ($user->isVacationRequestOldEnough()) {
46
                continue;
47
            }
48
49 1
            $userId = $user->getId();
50
51 1
            $crewLimit = $this->crewLimitCalculator->getGlobalCrewLimit($user);
52 1
            $crewOnColonies = $this->shipCrewRepository->getAmountByUserOnColonies($user);
53 1
            $crewOnShips = $this->shipCrewRepository->getAmountByUserOnShips($user);
54 1
            $crewAtTradeposts = $this->shipCrewRepository->getAmountByUserAtTradeposts($user);
55
56 1
            $crewToQuit = max(0, $crewOnColonies + $crewOnShips + $crewAtTradeposts - $crewLimit);
57
58
            //mutiny order: colonies, ships, tradeposts, escape pods
59 1
            if ($crewToQuit > 0 && $crewOnColonies > 0) {
60
                $crewToQuit -= $this->letColonyAssignmentsQuit($user, $crewToQuit);
61
            }
62 1
            if ($crewToQuit > 0 && $crewOnShips > 0) {
63 1
                $crewToQuit -= $this->letShipAssignmentsQuit($userId, $crewToQuit);
64
            }
65 1
            if ($crewToQuit > 0 && $crewAtTradeposts > 0) {
66
                $crewToQuit -= $this->letTradepostAssignmentsQuit($user, $crewToQuit);
67
            }
68 1
            if ($crewToQuit > 0) {
69
                $this->letEscapePodAssignmentsQuit($user, $crewToQuit);
70
            }
71
        }
72
    }
73
74
    private function letColonyAssignmentsQuit(User $user, int $crewToQuit): int
75
    {
76
        $amount = 0;
77
78
        foreach ($this->shipCrewRepository->getByUserAtColonies($user) as $crewAssignment) {
79
            if ($amount === $crewToQuit) {
80
                break;
81
            }
82
83
            $amount++;
84
            $this->crewRepository->delete($crewAssignment->getCrew());
85
            $this->shipCrewRepository->delete($crewAssignment);
86
        }
87
88
        if ($amount > 0) {
89
            $msg = sprintf(_('Wegen Überschreitung des globalen Crewlimits haben %d Crewman ihren Dienst auf deinen Kolonien quittiert'), $amount);
90
            $this->privateMessageSender->send(
91
                UserConstants::USER_NOONE,
92
                $user->getId(),
93
                $msg,
94
                PrivateMessageFolderTypeEnum::SPECIAL_COLONY
95
            );
96
        }
97
98
        return $amount;
99
    }
100
101
    private function letTradepostAssignmentsQuit(User $user, int $crewToQuit): int
102
    {
103
        $amount = 0;
104
105
        foreach ($this->shipCrewRepository->getByUserAtTradeposts($user) as $crewAssignment) {
106
            if ($amount === $crewToQuit) {
107
                break;
108
            }
109
110
            $amount++;
111
            $this->crewRepository->delete($crewAssignment->getCrew());
112
            $this->shipCrewRepository->delete($crewAssignment);
113
        }
114
115
        if ($amount > 0) {
116
            $msg = sprintf(_('Wegen Überschreitung des globalen Crewlimits haben %d deiner Crewman auf Handelsposten ihren Dienst quittiert'), $amount);
117
            $this->privateMessageSender->send(
118
                UserConstants::USER_NOONE,
119
                $user->getId(),
120
                $msg,
121
                PrivateMessageFolderTypeEnum::SPECIAL_SYSTEM
122
            );
123
        }
124
125
        return $amount;
126
    }
127
128
    private function letEscapePodAssignmentsQuit(User $user, int $crewToQuit): int
129
    {
130
        $amount = 0;
131
132
        foreach ($this->shipCrewRepository->getByUserOnEscapePods($user) as $crewAssignment) {
133
            if ($amount === $crewToQuit) {
134
                break;
135
            }
136
137
            $amount++;
138
            $this->crewRepository->delete($crewAssignment->getCrew());
139
            $this->shipCrewRepository->delete($crewAssignment);
140
        }
141
142
        if ($amount > 0) {
143
            $msg = sprintf(_('Wegen Überschreitung des globalen Crewlimits haben %d deiner Crewman auf Fluchtkapseln ihren Dienst quittiert'), $amount);
144
            $this->privateMessageSender->send(
145
                UserConstants::USER_NOONE,
146
                $user->getId(),
147
                $msg,
148
                PrivateMessageFolderTypeEnum::SPECIAL_SYSTEM
149
            );
150
        }
151
152
        return $amount;
153
    }
154
155 1
    private function letShipAssignmentsQuit(int $userId, int $crewToQuit): int
156
    {
157 1
        $wipedShipsIds = [];
158 1
        $amount = 0;
159
160 1
        $wipedShipIds = [];
161
162 1
        while ($amount < $crewToQuit) {
163 1
            $randomSpacecraft = $this->spacecraftRepository->getRandomSpacecraftWithCrewByUser($userId);
164
165
            //if no more ships available
166 1
            if ($randomSpacecraft === null) {
167
                break;
168
            }
169
170
            //if ship already wiped, go to next
171 1
            if (in_array($randomSpacecraft->getId(), $wipedShipIds)) {
172
                continue;
173
            }
174
175
            //wipe ship crew
176 1
            $wipedShipsIds[] = $randomSpacecraft->getId();
177 1
            $amount += $this->letCrewQuit($randomSpacecraft, $userId);
178
        }
179
180 1
        return $amount;
181
    }
182
183 1
    private function letCrewQuit(Spacecraft $randomSpacecraft, int $userId): int
184
    {
185 1
        $wrapper = $this->spacecraftWrapperFactory->wrapSpacecraft($randomSpacecraft);
186 1
        $doAlertRedCheck = $randomSpacecraft->getWarpDriveState() || $randomSpacecraft->isCloaked();
187
        //deactivate ship
188 1
        $this->spacecraftSystemManager->deactivateAll($wrapper);
189 1
        if ($randomSpacecraft->hasComputer()) {
190 1
            $wrapper->setAlertState(SpacecraftAlertStateEnum::ALERT_GREEN);
191
        }
192
193 1
        $this->spacecraftRepository->save($randomSpacecraft);
194
195 1
        $crewArray = [];
196 1
        foreach ($randomSpacecraft->getCrewAssignments() as $shipCrew) {
197 1
            $crewArray[] = $shipCrew->getCrew();
198
        }
199 1
        $randomSpacecraft->getCrewAssignments()->clear();
200
201
        //remove crew
202 1
        $this->shipCrewRepository->truncateBySpacecraft($randomSpacecraft);
203 1
        foreach ($crewArray as $crew) {
204 1
            $this->crewRepository->delete($crew);
205
        }
206
207 1
        $msg = sprintf(_('Wegen Überschreitung des globalen Crewlimits hat die Crew der %s gemeutert und das Schiff verlassen'), $randomSpacecraft->getName());
208 1
        $this->privateMessageSender->send(
209 1
            UserConstants::USER_NOONE,
210 1
            $userId,
211 1
            $msg,
212 1
            $randomSpacecraft->isStation() ? PrivateMessageFolderTypeEnum::SPECIAL_STATION : PrivateMessageFolderTypeEnum::SPECIAL_SHIP
213 1
        );
214
215
        //do alert red stuff
216 1
        if ($doAlertRedCheck) {
217
            $this->alertReactionFacade->doItAll($wrapper, new InformationWrapper());
218
        }
219
220 1
        return count($crewArray);
221
    }
222
}
223