Passed
Push — dev ( ac26ef...6b8aca )
by Nico
08:29
created

ShipTickManager::getLoggerUtil()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Tick\Ship;
6
7
use Stu\Component\Anomaly\AnomalyHandlingInterface;
8
use Stu\Module\Colony\Lib\ColonyLibFactoryInterface;
9
use Stu\Module\History\Lib\EntryCreatorInterface;
10
use Stu\Module\Logging\LoggerEnum;
11
use Stu\Module\Logging\LoggerUtilFactoryInterface;
12
use Stu\Module\Logging\LoggerUtilInterface;
13
use Stu\Module\Message\Lib\PrivateMessageFolderSpecialEnum;
14
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
15
use Stu\Module\PlayerSetting\Lib\UserEnum;
16
use Stu\Module\Ship\Lib\ShipRemoverInterface;
17
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
18
use Stu\Module\Tick\AbstractTickManager;
19
use Stu\Module\Tick\Ship\Crew\CrewLimitationsInterface;
20
use Stu\Module\Tick\Ship\Repair\RepairActionsInterface;
21
use Stu\Orm\Entity\ColonyInterface;
22
use Stu\Orm\Entity\ShipInterface;
23
use Stu\Orm\Repository\ShipCrewRepositoryInterface;
24
use Stu\Orm\Repository\ShipRepositoryInterface;
25
use Stu\Orm\Repository\TradePostRepositoryInterface;
26
use Ubench;
27
28
final class ShipTickManager extends AbstractTickManager implements ShipTickManagerInterface
29
{
30
    private CrewLimitationsInterface $crewLimitations;
31
32
    private PrivateMessageSenderInterface $privateMessageSender;
33
34
    private ShipRemoverInterface $shipRemover;
35
36
    private ShipTickInterface $shipTick;
37
38
    private ShipRepositoryInterface $shipRepository;
39
40
    private ShipCrewRepositoryInterface $shipCrewRepository;
41
42
    private TradePostRepositoryInterface $tradePostRepository;
43
44
    private ShipWrapperFactoryInterface $shipWrapperFactory;
45
46
    private EntryCreatorInterface $entryCreator;
47
48
    private ColonyLibFactoryInterface $colonyLibFactory;
49
50
    private RepairActionsInterface $repairActions;
51
52
    private AnomalyHandlingInterface $anomalyHandling;
53
54
    private LoggerUtilInterface $loggerUtil;
55
56
    private Ubench $benchmark;
57
58
    public function __construct(
59
        CrewLimitationsInterface $crewLimitations,
60
        PrivateMessageSenderInterface $privateMessageSender,
61
        ShipRemoverInterface $shipRemover,
62
        ShipTickInterface $shipTick,
63
        ShipRepositoryInterface $shipRepository,
64
        ShipCrewRepositoryInterface $shipCrewRepository,
65
        TradePostRepositoryInterface $tradePostRepository,
66
        ShipWrapperFactoryInterface $shipWrapperFactory,
67
        EntryCreatorInterface $entryCreator,
68
        ColonyLibFactoryInterface $colonyLibFactory,
69
        RepairActionsInterface $repairActions,
70
        AnomalyHandlingInterface $anomalyHandling,
71
        LoggerUtilFactoryInterface $loggerUtilFactory,
72
        Ubench $benchmark
73
    ) {
74
        $this->crewLimitations = $crewLimitations;
75
        $this->privateMessageSender = $privateMessageSender;
76
        $this->shipRemover = $shipRemover;
77
        $this->shipTick = $shipTick;
78
        $this->shipRepository = $shipRepository;
79
        $this->shipCrewRepository = $shipCrewRepository;
80
        $this->tradePostRepository = $tradePostRepository;
81
        $this->shipWrapperFactory = $shipWrapperFactory;
82
        $this->entryCreator = $entryCreator;
83
        $this->colonyLibFactory = $colonyLibFactory;
84
        $this->repairActions = $repairActions;
85
        $this->anomalyHandling = $anomalyHandling;
86
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil();
87
        $this->benchmark = $benchmark;
88
    }
89
90
    public function work(): void
91
    {
92
        $this->anomalyHandling->processExistingAnomalies();
93
        $this->crewLimitations->work();
94
95
        $startTime = microtime(true);
96
        $this->handleEscapePods();
97
        if ($this->loggerUtil->doLog()) {
98
            $endTime = microtime(true);
99
            $this->loggerUtil->log(sprintf("\t\thandleEscapePods, seconds: %F", $endTime - $startTime));
100
        }
101
        $this->repairActions->work();
102
103
        $startTime = microtime(true);
104
        $entityCount = 0;
105
        foreach ($this->shipRepository->getPlayerShipsForTick() as $ship) {
106
            //echo "Processing Ship ".$ship->getId()." at ".microtime()."\n";
107
108
            $this->shipTick->work($this->shipWrapperFactory->wrapShip($ship));
109
            $entityCount++;
110
        }
111
        if ($this->loggerUtil->doLog()) {
112
            $endTime = microtime(true);
113
            $this->loggerUtil->log(sprintf("\t\tshipTick, seconds: %F", $endTime - $startTime));
114
        }
115
116
        $startTime = microtime(true);
117
        $this->handleNPCShips();
118
        if ($this->loggerUtil->doLog()) {
119
            $endTime = microtime(true);
120
            $this->loggerUtil->log(sprintf("\t\thandleNPCShips, seconds: %F", $endTime - $startTime));
121
        }
122
123
        $startTime = microtime(true);
124
        $this->lowerTrumfieldHull();
125
        $this->lowerOrphanizedTradepostHull();
126
        $this->lowerStationConstructionHull();
127
        if ($this->loggerUtil->doLog()) {
128
            $endTime = microtime(true);
129
            $this->loggerUtil->log(sprintf("\t\tloweringTrumfieldConstruction, seconds: %F", $endTime - $startTime));
130
        }
131
132
        $this->loggerUtil->init('SHIPTICK', LoggerEnum::LEVEL_WARNING);
133
        $this->logBenchmarkResult($entityCount);
134
135
        $this->anomalyHandling->createNewAnomalies();
136
    }
137
138
    private function handleEscapePods(): void
139
    {
140
        $escapedToColonies = [];
141
142
        foreach ($this->shipRepository->getEscapePods() as $escapePod) {
143
            if ($escapePod->getCrewCount() === 0) {
144
                $this->shipRemover->remove($escapePod);
145
            }
146
147
            if ($escapePod->getStarsystemMap() !== null) {
148
                $colony = $escapePod->getStarsystemMap()->getColony();
149
150
                if ($colony !== null) {
151
                    $count = $this->transferOwnCrewToColony($escapePod, $colony);
152
153
                    if ($count > 0) {
154
                        if (array_key_exists($colony->getId(), $escapedToColonies)) {
155
                            $oldCount = $escapedToColonies[$colony->getId()][1];
156
157
                            $escapedToColonies[$colony->getId()][1] = $oldCount +  $count;
158
                        } else {
159
                            $escapedToColonies[$colony->getId()] = [$colony, $count];
160
                        }
161
                    }
162
                }
163
            }
164
        }
165
166
        foreach ($escapedToColonies as [$colony, $count]) {
167
            $msg = sprintf(_('%d deiner Crewman sind aus Fluchtkapseln auf deiner Kolonie %s gelandet'), $count, $colony->getName());
168
            $this->privateMessageSender->send(
169
                UserEnum::USER_NOONE,
170
                $colony->getUser()->getId(),
171
                $msg,
172
                PrivateMessageFolderSpecialEnum::PM_SPECIAL_COLONY
173
            );
174
        }
175
    }
176
177
    private function transferOwnCrewToColony(ShipInterface $escapePod, ColonyInterface $colony): int
178
    {
179
        $count = 0;
180
181
        foreach ($escapePod->getCrewlist() as $crewAssignment) {
182
            if ($crewAssignment->getUser() !== $colony->getUser()) {
183
                continue;
184
            }
185
186
            $freeAssignmentCount = $this->colonyLibFactory->createColonyPopulationCalculator(
187
                $colony
188
            )->getFreeAssignmentCount();
189
190
            if ($freeAssignmentCount === 0) {
191
                break;
192
            }
193
194
            $count++;
195
            $crewAssignment->setShip(null);
196
            $crewAssignment->setSlot(null);
197
            $crewAssignment->setColony($colony);
198
            $escapePod->getCrewlist()->removeElement($crewAssignment);
199
            $colony->getCrewAssignments()->add($crewAssignment);
200
            $this->shipCrewRepository->save($crewAssignment);
201
        }
202
203
        return $count;
204
    }
205
206
    private function lowerTrumfieldHull(): void
207
    {
208
        foreach ($this->shipRepository->getDebrisFields() as $ship) {
209
            $lower = random_int(5, 15);
210
            if ($ship->getHull() <= $lower) {
211
                $this->shipRemover->remove($ship);
212
                continue;
213
            }
214
            $ship->setHuell($ship->getHull() - $lower);
215
216
            $this->shipRepository->save($ship);
217
        }
218
    }
219
220
    private function lowerOrphanizedTradepostHull(): void
221
    {
222
        foreach ($this->tradePostRepository->getByUser(UserEnum::USER_NOONE) as $tradepost) {
223
            $ship = $tradepost->getShip();
224
225
            $lower = (int)ceil($ship->getMaxHull() / 100);
226
227
            if ($ship->getHull() <= $lower) {
228
                $this->shipRemover->destroy($this->shipWrapperFactory->wrapShip($ship));
229
230
                $this->entryCreator->addStationEntry(
231
                    'Der verlassene Handelsposten in Sektor ' . $ship->getSectorString() . ' ist zerfallen',
232
                    $ship->getUser()->getId()
233
                );
234
                continue;
235
            }
236
            $ship->setHuell($ship->getHull() - $lower);
237
238
            $this->shipRepository->save($ship);
239
        }
240
    }
241
242
    private function lowerStationConstructionHull(): void
243
    {
244
        foreach ($this->shipRepository->getStationConstructions() as $ship) {
245
            $lower = random_int(5, 15);
246
            if ($ship->getHull() <= $lower) {
247
                $msg = sprintf(_('Dein Konstrukt bei %s war zu lange ungenutzt und ist daher zerfallen'), $ship->getSectorString());
248
                $this->privateMessageSender->send(
249
                    UserEnum::USER_NOONE,
250
                    $ship->getUser()->getId(),
251
                    $msg,
252
                    PrivateMessageFolderSpecialEnum::PM_SPECIAL_STATION
253
                );
254
255
                $this->shipRemover->remove($ship);
256
                continue;
257
            }
258
            $ship->setHuell($ship->getHull() - $lower);
259
260
            $this->shipRepository->save($ship);
261
        }
262
    }
263
264
    private function handleNPCShips(): void
265
    {
266
        // @todo
267
        foreach ($this->shipRepository->getNpcShipsForTick() as $ship) {
268
            //load EPS
269
            $wrapper = $this->shipWrapperFactory->wrapShip($ship);
270
            $epsSystem = $wrapper->getEpsSystemData();
271
            $warpdrive = $wrapper->getWarpDriveSystemData();
272
            $warpcore = $wrapper->getWarpCoreSystemData();
273
274
            if ($epsSystem !== null) {
275
                if ($warpdrive != null) {
276
                    $eps = (int) ceil($ship->getReactorOutput() * (($warpcore->getWarpCoreSplit() / 100)) - $wrapper->getEpsUsage());
277
                } else {
278
                    $eps = (int) ceil($ship->getReactorOutput() - $wrapper->getEpsUsage());
279
                }
280
                if ($eps + $epsSystem->getEps() > $epsSystem->getMaxEps()) {
281
                    $eps = $epsSystem->getMaxEps() - $epsSystem->getEps();
282
                }
283
                $epsSystem->setEps($epsSystem->getEps() + $eps)->update();
284
            }
285
            if ($warpdrive !== null) {
286
                $availableWarpDrive = $warpdrive->getWarpDrive() + $wrapper->getEffectiveWarpDriveProduction();
287
            } else {
288
                return;
289
            }
290
            if ($warpdrive !== null) {
291
                if ($availableWarpDrive > $warpdrive->getMaxWarpDrive()) {
292
                    $availableWarpDrive = $warpdrive->getMaxWarpDrive();
293
                }
294
                $warpdrive->setWarpDrive($availableWarpDrive)->update();
295
            }
296
        }
297
    }
298
299
    protected function getBenchmark(): Ubench
300
    {
301
        return $this->benchmark;
302
    }
303
304
    protected function getLoggerUtil(): LoggerUtilInterface
305
    {
306
        return $this->loggerUtil;
307
    }
308
}