Passed
Push — master ( db7b85...c86096 )
by Nico
49:13 queued 24:57
created

RepairActions::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 11
dl 0
loc 24
ccs 0
cts 12
cp 0
crap 2
rs 9.9
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\Tick\Ship\ManagerComponent;
6
7
use Stu\Component\Building\BuildingEnum;
8
use Stu\Component\Colony\ColonyFunctionManagerInterface;
9
use Stu\Component\Colony\Storage\ColonyStorageManagerInterface;
10
use Stu\Component\Ship\Repair\RepairUtilInterface;
11
use Stu\Component\Ship\ShipStateEnum;
12
use Stu\Component\Ship\System\ShipSystemManagerInterface;
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\ShipWrapperFactoryInterface;
17
use Stu\Module\Ship\Lib\ShipWrapperInterface;
18
use Stu\Orm\Entity\ColonyInterface;
19
use Stu\Orm\Entity\ShipInterface;
20
use Stu\Orm\Repository\ColonyShipRepairRepositoryInterface;
21
use Stu\Orm\Repository\ModuleQueueRepositoryInterface;
22
use Stu\Orm\Repository\PlanetFieldRepositoryInterface;
23
use Stu\Orm\Repository\ShipRepositoryInterface;
24
use Stu\Orm\Repository\StationShipRepairRepositoryInterface;
25
26
final class RepairActions implements ManagerComponentInterface
27
{
28
    private ShipRepositoryInterface $shipRepository;
29
30
    private PrivateMessageSenderInterface $privateMessageSender;
31
32
    private ShipSystemManagerInterface $shipSystemManager;
33
34
    private ColonyShipRepairRepositoryInterface $colonyShipRepairRepository;
35
36
    private StationShipRepairRepositoryInterface $stationShipRepairRepository;
37
38
    private ColonyStorageManagerInterface $colonyStorageManager;
39
40
    private ModuleQueueRepositoryInterface $moduleQueueRepository;
41
42
    private RepairUtilInterface $repairUtil;
43
44
    private ShipWrapperFactoryInterface $shipWrapperFactory;
45
46
    private PlanetFieldRepositoryInterface $planetFieldRepository;
47
48
    private ColonyFunctionManagerInterface $colonyFunctionManager;
49
50
    public function __construct(
51
        ShipRepositoryInterface $shipRepository,
52
        PrivateMessageSenderInterface $privateMessageSender,
53
        ShipSystemManagerInterface $shipSystemManager,
54
        ColonyShipRepairRepositoryInterface $colonyShipRepairRepository,
55
        StationShipRepairRepositoryInterface $stationShipRepairRepository,
56
        ColonyStorageManagerInterface $colonyStorageManager,
57
        ModuleQueueRepositoryInterface $moduleQueueRepository,
58
        RepairUtilInterface $repairUtil,
59
        ShipWrapperFactoryInterface $shipWrapperFactory,
60
        PlanetFieldRepositoryInterface $planetFieldRepository,
61
        ColonyFunctionManagerInterface $colonyFunctionManager
62
    ) {
63
        $this->shipRepository = $shipRepository;
64
        $this->privateMessageSender = $privateMessageSender;
65
        $this->shipSystemManager = $shipSystemManager;
66
        $this->colonyShipRepairRepository = $colonyShipRepairRepository;
67
        $this->stationShipRepairRepository = $stationShipRepairRepository;
68
        $this->colonyStorageManager = $colonyStorageManager;
69
        $this->moduleQueueRepository = $moduleQueueRepository;
70
        $this->repairUtil = $repairUtil;
71
        $this->shipWrapperFactory = $shipWrapperFactory;
72
        $this->planetFieldRepository = $planetFieldRepository;
73
        $this->colonyFunctionManager = $colonyFunctionManager;
74
    }
75
76
    public function work(): void
77
    {
78
        //spare parts and system components are generated by ship tick, to avoid dead locks
79
        $this->proceedSpareParts();
80
        $this->repairShipsOnColonies(1);
81
        $this->repairShipsOnStations();
82
    }
83
84
    private function proceedSpareParts(): void
85
    {
86
        foreach ($this->moduleQueueRepository->findAll() as $queue) {
87
            $buildingFunction = $queue->getBuildingFunction();
88
89
            if (
90
                $buildingFunction === BuildingEnum::BUILDING_FUNCTION_FABRICATION_HALL ||
91
                $buildingFunction === BuildingEnum::BUILDING_FUNCTION_TECH_CENTER
92
            ) {
93
                $colony = $queue->getColony();
94
95
                if ($this->colonyFunctionManager->hasActiveFunction($colony, $buildingFunction)) {
96
                    $this->colonyStorageManager->upperStorage(
97
                        $colony,
98
                        $queue->getModule()->getCommodity(),
99
                        $queue->getAmount()
100
                    );
101
102
                    $this->privateMessageSender->send(
103
                        UserEnum::USER_NOONE,
104
                        $colony->getUser()->getId(),
105
                        sprintf(
106
                            _('Es wurden %d %s hergestellt'),
107
                            $queue->getAmount(),
108
                            $queue->getModule()->getName()
109
                        ),
110
                        PrivateMessageFolderSpecialEnum::PM_SPECIAL_COLONY
111
                    );
112
113
                    $this->moduleQueueRepository->delete($queue);
114
                }
115
            }
116
        }
117
    }
118
119
    private function repairShipsOnColonies(int $tickId): void
120
    {
121
        $usedShipyards = [];
122
123
        foreach ($this->colonyShipRepairRepository->getMostRecentJobs($tickId) as $obj) {
124
            $ship = $obj->getShip();
125
            $colony = $obj->getColony();
126
127
            if ($colony->isBlocked()) {
128
                continue;
129
            }
130
131
            $field = $this->planetFieldRepository->getByColonyAndFieldIndex(
132
                $obj->getColonyId(),
133
                $obj->getFieldId()
134
            );
135
136
            if ($field === null) {
137
                continue;
138
            }
139
140
            if (!$field->isActive()) {
141
                continue;
142
            }
143
144
            if (!array_key_exists($colony->getId(), $usedShipyards)) {
145
                $usedShipyards[$colony->getId()] = [];
146
            }
147
148
            $isRepairStationBonus = $this->colonyFunctionManager->hasActiveFunction($colony, BuildingEnum::BUILDING_FUNCTION_REPAIR_SHIPYARD);
149
150
            //already repaired a ship on this colony field, max is one without repair station
151
            if (
152
                !$isRepairStationBonus
153
                && array_key_exists($field->getFieldId(), $usedShipyards[$colony->getId()])
154
            ) {
155
                continue;
156
            }
157
158
            $usedShipyards[$colony->getId()][$field->getFieldId()] = [$field->getFieldId()];
159
160
            if ($this->repairShipOnEntity($ship, $colony, $isRepairStationBonus)) {
161
                $this->colonyShipRepairRepository->delete($obj);
162
                $this->shipRepository->save($ship);
163
            }
164
        }
165
    }
166
167
    private function repairShipsOnStations(): void
168
    {
169
        foreach ($this->stationShipRepairRepository->getMostRecentJobs() as $obj) {
170
            $ship = $obj->getShip();
171
            $station = $obj->getStation();
172
173
            if (!$station->hasEnoughCrew()) {
174
                continue;
175
            }
176
177
            if ($this->repairShipOnEntity($ship, $station, false)) {
178
                $this->stationShipRepairRepository->delete($obj);
179
                $this->shipRepository->save($ship);
180
            }
181
        }
182
    }
183
184
    private function repairShipOnEntity(ShipInterface $ship, ColonyInterface|ShipInterface $entity, bool $isRepairStationBonus): bool
185
    {
186
        // check for U-Mode
187
        if ($entity->getUser()->isVacationRequestOldEnough()) {
188
            return false;
189
        }
190
191
        $wrapper = $this->shipWrapperFactory->wrapShip($ship);
192
        $neededParts = $this->repairUtil->determineSpareParts($wrapper, true);
193
194
        // parts stored?
195
        if (!$this->repairUtil->enoughSparePartsOnEntity($neededParts, $entity, $ship)) {
196
            return false;
197
        }
198
199
        $repairFinished = false;
200
201
        $this->repairHull($ship, $isRepairStationBonus);
202
        $this->repairShipSystems($wrapper, $isRepairStationBonus);
203
204
        // consume spare parts
205
        $this->repairUtil->consumeSpareParts($neededParts, $entity);
206
207
        if (!$wrapper->canBeRepaired()) {
208
            $repairFinished = true;
209
210
            $ship->setHuell($ship->getMaxHull());
211
            $ship->setState(ShipStateEnum::SHIP_STATE_NONE);
212
213
            $this->sendPrivateMessages($ship, $entity);
214
        }
215
        $this->shipRepository->save($ship);
216
217
        return $repairFinished;
218
    }
219
220
    private function repairHull(ShipInterface $ship, bool $isRepairStationBonus): void
221
    {
222
        $hullRepairRate = $isRepairStationBonus ? $ship->getRepairRate() * 2 : $ship->getRepairRate();
223
        $ship->setHuell($ship->getHull() + $hullRepairRate);
224
        if ($ship->getHull() > $ship->getMaxHull()) {
225
            $ship->setHuell($ship->getMaxHull());
226
        }
227
    }
228
229
    private function repairShipSystems(ShipWrapperInterface $wrapper, bool $isRepairStationBonus): void
230
    {
231
        $ship = $wrapper->get();
232
233
        $damagedSystems = $wrapper->getDamagedSystems();
234
        if (!empty($damagedSystems)) {
235
            $firstSystem = $damagedSystems[0];
236
            $firstSystem->setStatus(100);
237
238
            if ($ship->getCrewCount() > 0) {
239
                $firstSystem->setMode($this->shipSystemManager->lookupSystem($firstSystem->getSystemType())->getDefaultMode());
240
            }
241
242
            // maximum of two systems get repaired
243
            if (count($damagedSystems) > 1) {
244
                $secondSystem = $damagedSystems[1];
245
                $secondSystem->setStatus(100);
246
247
                if ($ship->getCrewCount() > 0) {
248
                    $secondSystem->setMode($this->shipSystemManager->lookupSystem($secondSystem->getSystemType())->getDefaultMode());
249
                }
250
            }
251
252
            // maximum of two additional systems get repaired
253
            if ($isRepairStationBonus) {
254
                if (count($damagedSystems) > 2) {
255
                    $thirdSystem = $damagedSystems[2];
256
                    $thirdSystem->setStatus(100);
257
258
                    if ($ship->getCrewCount() > 0) {
259
                        $thirdSystem->setMode($this->shipSystemManager->lookupSystem($thirdSystem->getSystemType())->getDefaultMode());
260
                    }
261
                }
262
                if (count($damagedSystems) > 3) {
263
                    $fourthSystem = $damagedSystems[3];
264
                    $fourthSystem->setStatus(100);
265
266
                    if ($ship->getCrewCount() > 0) {
267
                        $fourthSystem->setMode($this->shipSystemManager->lookupSystem($fourthSystem->getSystemType())->getDefaultMode());
268
                    }
269
                }
270
            }
271
        }
272
    }
273
274
    private function sendPrivateMessages(ShipInterface $ship, ColonyInterface|ShipInterface $entity): void
275
    {
276
        $shipOwnerMessage = $entity instanceof ColonyInterface ? sprintf(
277
            "Die Reparatur der %s wurde in Sektor %s bei der Kolonie %s des Spielers %s fertiggestellt",
278
            $ship->getName(),
279
            $ship->getSectorString(),
280
            $entity->getName(),
281
            $entity->getUser()->getName()
282
        ) : sprintf(
283
            "Die Reparatur der %s wurde in Sektor %s von der %s %s des Spielers %s fertiggestellt",
284
            $ship->getName(),
285
            $ship->getSectorString(),
286
            $entity->getRump()->getName(),
287
            $entity->getName(),
288
            $entity->getUser()->getName()
289
        );
290
291
        $this->privateMessageSender->send(
292
            $entity->getUser()->getId(),
293
            $ship->getUser()->getId(),
294
            $shipOwnerMessage,
295
            PrivateMessageFolderSpecialEnum::PM_SPECIAL_SHIP
296
        );
297
298
        $entityOwnerMessage = $entity instanceof ColonyInterface ? sprintf(
299
            "Die Reparatur der %s von Siedler %s wurde in Sektor %s bei der Kolonie %s fertiggestellt",
300
            $ship->getName(),
301
            $ship->getUser()->getName(),
302
            $ship->getSectorString(),
303
            $entity->getName()
304
        ) : sprintf(
305
            "Die Reparatur der %s von Siedler %s wurde in Sektor %s von der %s %s fertiggestellt",
306
            $ship->getName(),
307
            $ship->getUser()->getName(),
308
            $ship->getSectorString(),
309
            $entity->getRump()->getName(),
310
            $entity->getName()
311
        );
312
313
        $this->privateMessageSender->send(
314
            UserEnum::USER_NOONE,
315
            $entity->getUser()->getId(),
316
            $entityOwnerMessage,
317
            $entity instanceof ColonyInterface ? PrivateMessageFolderSpecialEnum::PM_SPECIAL_COLONY :
318
                PrivateMessageFolderSpecialEnum::PM_SPECIAL_STATION
319
        );
320
    }
321
}
322