RepairActions::repairShipOnEntity()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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