RepairActions   A
last analyzed

Complexity

Total Complexity 41

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Test Coverage

Coverage 0.66%

Importance

Changes 0
Metric Value
eloc 140
dl 0
loc 251
ccs 1
cts 152
cp 0.0066
rs 9.1199
c 0
b 0
f 0
wmc 41

9 Methods

Rating   Name   Duplication   Size   Complexity  
A work() 0 7 1
A __construct() 0 1 1
B repairShipsOnColonies() 0 44 9
A repairHull() 0 8 3
A sendPrivateMessages() 0 45 4
A repairShipsOnStations() 0 13 4
A repairShipOnEntity() 0 34 4
B repairShipSystems() 0 39 10
A proceedSpareParts() 0 31 5

How to fix   Complexity   

Complex Class

Complex classes like RepairActions often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use RepairActions, and based on these observations, apply Extract Interface, too.

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