Passed
Push — dev ( c4f015...eeaa0f )
by Janko
27:51
created

RepairActions::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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