Passed
Push — master ( 0ac6a9...434e9a )
by Nico
16:38 queued 10:37
created

CrewLimitations   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Test Coverage

Coverage 44.35%

Importance

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