RepairActions::repairShipOnEntity()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 17
nc 4
nop 3
dl 0
loc 34
ccs 0
cts 18
cp 0
crap 20
rs 9.7
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Tick\Spacecraft\ManagerComponent;
6
7
use Stu\Component\Building\BuildingFunctionEnum;
8
use Stu\Component\Colony\ColonyFunctionManagerInterface;
9
use Stu\Component\Spacecraft\Repair\RepairUtil;
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\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...
17
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
18
use Stu\Module\Ship\Lib\ShipWrapperInterface;
19
use Stu\Orm\Entity\Colony;
20
use Stu\Orm\Entity\Ship;
21
use Stu\Orm\Entity\Station;
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 1
    #[\Override]
33
    public function work(): void
34
    {
35
        //spare parts and system components are generated by spacecraft tick, to avoid dead locks
36 1
        $this->proceedSpareParts();
37 1
        $this->repairShipsOnColonies(1);
38 1
        $this->repairShipsOnStations();
39
    }
40
41 1
    private function proceedSpareParts(): void
42
    {
43 1
        foreach ($this->moduleQueueRepository->findAll() as $queue) {
44 1
            $buildingFunction = $queue->getBuildingFunction();
45
46
            if (
47 1
                $buildingFunction === BuildingFunctionEnum::FABRICATION_HALL ||
48 1
                $buildingFunction === BuildingFunctionEnum::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
                        UserConstants::USER_NOONE,
61
                        $colony->getUser()->getId(),
62
                        sprintf(
63
                            "Tickreport der Kolonie %s\nEs wurden %d %s hergestellt",
64
                            $colony->getName(),
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 1
    private function repairShipsOnColonies(int $tickId): void
78
    {
79 1
        $usedShipyards = [];
80
81 1
        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, BuildingFunctionEnum::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 1
    private function repairShipsOnStations(): void
126
    {
127 1
        foreach ($this->stationShipRepairRepository->getMostRecentJobs() as $obj) {
128 1
            $ship = $obj->getShip();
129 1
            $station = $obj->getStation();
130
131 1
            if (!$station->hasEnoughCrew()) {
132 1
                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(Ship $ship, Colony|Station $entity, bool $isRepairStationBonus): bool
143
    {
144
        // check for U-Mode
145
        if ($entity->getUser()->isVacationRequestOldEnough()) {
146
            return false;
147
        }
148
149
        $wrapper = $this->spacecraftWrapperFactory->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->getCondition()->setHull($ship->getMaxHull());
169
            $ship->getCondition()->setState(SpacecraftStateEnum::NONE);
170
171
            $this->sendPrivateMessages($ship, $entity);
172
        }
173
        $this->shipRepository->save($ship);
174
175
        return $repairFinished;
176
    }
177
178
    private function repairHull(Ship $ship, bool $isRepairStationBonus): void
179
    {
180
        $condition = $ship->getCondition();
181
        $hullRepairRate = $isRepairStationBonus ? RepairUtil::REPAIR_RATE_PER_TICK * 2 : RepairUtil::REPAIR_RATE_PER_TICK;
182
183
        $condition->changeHull($hullRepairRate);
184
        if ($condition->getHull() > $ship->getMaxHull()) {
185
            $condition->setHull($ship->getMaxHull());
186
        }
187
    }
188
189
    private function repairShipSystems(ShipWrapperInterface $wrapper, bool $isRepairStationBonus): void
190
    {
191
        $ship = $wrapper->get();
192
193
        $damagedSystems = $wrapper->getDamagedSystems();
194
        if ($damagedSystems !== []) {
195
            $firstSystem = $damagedSystems[0];
196
            $firstSystem->setStatus(100);
197
198
            if ($ship->getCrewCount() > 0) {
199
                $firstSystem->setMode($this->spacecraftSystemManager->lookupSystem($firstSystem->getSystemType())->getDefaultMode());
200
            }
201
202
            // maximum of two systems get repaired
203
            if (count($damagedSystems) > 1) {
204
                $secondSystem = $damagedSystems[1];
205
                $secondSystem->setStatus(100);
206
207
                if ($ship->getCrewCount() > 0) {
208
                    $secondSystem->setMode($this->spacecraftSystemManager->lookupSystem($secondSystem->getSystemType())->getDefaultMode());
209
                }
210
            }
211
212
            // maximum of two additional systems get repaired
213
            if ($isRepairStationBonus) {
214
                if (count($damagedSystems) > 2) {
215
                    $thirdSystem = $damagedSystems[2];
216
                    $thirdSystem->setStatus(100);
217
218
                    if ($ship->getCrewCount() > 0) {
219
                        $thirdSystem->setMode($this->spacecraftSystemManager->lookupSystem($thirdSystem->getSystemType())->getDefaultMode());
220
                    }
221
                }
222
                if (count($damagedSystems) > 3) {
223
                    $fourthSystem = $damagedSystems[3];
224
                    $fourthSystem->setStatus(100);
225
226
                    if ($ship->getCrewCount() > 0) {
227
                        $fourthSystem->setMode($this->spacecraftSystemManager->lookupSystem($fourthSystem->getSystemType())->getDefaultMode());
228
                    }
229
                }
230
            }
231
        }
232
    }
233
234
    private function sendPrivateMessages(Ship $ship, Colony|Station $entity): void
235
    {
236
        $shipOwnerMessage = $entity instanceof Colony ? sprintf(
237
            "Die Reparatur der %s wurde in Sektor %s bei der Kolonie %s des Spielers %s fertiggestellt",
238
            $ship->getName(),
239
            $ship->getSectorString(),
240
            $entity->getName(),
241
            $entity->getUser()->getName()
242
        ) : sprintf(
243
            "Die Reparatur der %s wurde in Sektor %s von der %s %s des Spielers %s fertiggestellt",
244
            $ship->getName(),
245
            $ship->getSectorString(),
246
            $entity->getRump()->getName(),
247
            $entity->getName(),
248
            $entity->getUser()->getName()
249
        );
250
251
        $this->privateMessageSender->send(
252
            $entity->getUser()->getId(),
253
            $ship->getUser()->getId(),
254
            $shipOwnerMessage,
255
            PrivateMessageFolderTypeEnum::SPECIAL_SHIP
256
        );
257
258
        $entityOwnerMessage = $entity instanceof Colony ? sprintf(
259
            "Die Reparatur der %s von Siedler %s wurde in Sektor %s bei der Kolonie %s fertiggestellt",
260
            $ship->getName(),
261
            $ship->getUser()->getName(),
262
            $ship->getSectorString(),
263
            $entity->getName()
264
        ) : sprintf(
265
            "Die Reparatur der %s von Siedler %s wurde in Sektor %s von der %s %s fertiggestellt",
266
            $ship->getName(),
267
            $ship->getUser()->getName(),
268
            $ship->getSectorString(),
269
            $entity->getRump()->getName(),
270
            $entity->getName()
271
        );
272
273
        $this->privateMessageSender->send(
274
            UserConstants::USER_NOONE,
275
            $entity->getUser()->getId(),
276
            $entityOwnerMessage,
277
            $entity instanceof Colony ? PrivateMessageFolderTypeEnum::SPECIAL_COLONY :
278
                PrivateMessageFolderTypeEnum::SPECIAL_STATION
279
        );
280
    }
281
}
282