Passed
Pull Request — master (#1969)
by Janko
22:34 queued 10:03
created

RepairActions   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 248
Duplicated Lines 0 %

Test Coverage

Coverage 0.67%

Importance

Changes 0
Metric Value
eloc 138
dl 0
loc 248
ccs 1
cts 150
cp 0.0067
rs 9.1199
c 0
b 0
f 0
wmc 41

9 Methods

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