Passed
Pull Request — master (#2065)
by Nico
29:40 queued 17:22
created

NpcShipHandling::workSpacecraft()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 7
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Stu\Module\Tick\Spacecraft\ManagerComponent;
4
5
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...
6
use Stu\Component\Spacecraft\Repair\RepairUtilInterface;
7
use Stu\Component\Spacecraft\SpacecraftStateEnum;
8
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
9
use Stu\Component\Station\StationUtilityInterface;
10
use Stu\Lib\Information\InformationFactoryInterface;
11
use Stu\Lib\Information\InformationWrapper;
12
use Stu\Module\Station\Lib\StationWrapperInterface;
13
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
14
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
15
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
16
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
17
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...
18
use Stu\Orm\Entity\SpacecraftInterface;
19
use Stu\Orm\Entity\StationInterface;
20
use Stu\Orm\Repository\SpacecraftRepositoryInterface;
21
22
class NpcShipHandling implements ManagerComponentInterface
23
{
24 1
    public function __construct(
25
        private SpacecraftRepositoryInterface $spacecraftRepository,
26
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
27
        private StationUtilityInterface $stationUtility,
28
        private RepairUtilInterface $repairUtil,
29
        private PrivateMessageSenderInterface $privateMessageSender,
30
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
31
        private InformationFactoryInterface $informationFactory
32 1
    ) {}
33
34
    #[Override]
35
    public function work(): void
36
    {
37
        // @todo
38
        foreach ($this->spacecraftRepository->getNpcSpacecraftsForTick() as $spacecraft) {
39
            $wrapper = $this->spacecraftWrapperFactory->wrapSpacecraft($spacecraft);
40
            $reactor = $wrapper->getReactorWrapper();
41
            $this->workSpacecraft($wrapper);
42
            if ($reactor === null) {
43
                continue;
44
            }
45
46
            $epsSystem = $wrapper->getEpsSystemData();
47
            $warpdrive = $wrapper->getWarpDriveSystemData();
48
49
            //load EPS
50
            if ($epsSystem !== null) {
51
                $epsSystem->setEps($epsSystem->getEps() + $reactor->getEffectiveEpsProduction())->update();
52
            }
53
54
            //load warpdrive
55
            if ($warpdrive !== null) {
56
                $warpdrive->setWarpDrive($warpdrive->getWarpDrive() + $reactor->getEffectiveWarpDriveProduction())->update();
57
            }
58
        }
59
    }
60
61
    public function workSpacecraft(SpacecraftWrapperInterface $wrapper): void
62
    {
63
        $informationWrapper = $this->informationFactory->createInformationWrapper();
64
65
        $this->workSpacecraftInternal($wrapper, $informationWrapper);
66
67
        $this->sendMessage($wrapper->get(), $informationWrapper);
68
    }
69
70
71
    private function workSpacecraftInternal(SpacecraftWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
72
    {
73
        $spacecraft = $wrapper->get();
74
75
        // do construction stuff
76
        if ($spacecraft instanceof StationInterface && $this->doConstructionStuff($spacecraft, $informationWrapper)) {
77
            $this->spacecraftRepository->save($spacecraft);
78
            return;
79
        }
80
81
        // repair station
82
        if ($wrapper instanceof StationWrapperInterface && $spacecraft->getState() === SpacecraftStateEnum::REPAIR_PASSIVE) {
83
            $this->doRepairStation($wrapper, $informationWrapper);
84
        }
85
    }
86
87
88
    private function doConstructionStuff(StationInterface $station, InformationWrapper $informationWrapper): bool
89
    {
90
        $progress =  $station->getConstructionProgress();
91
        if ($progress === null) {
92
            return false;
93
        }
94
95
        if ($progress->getRemainingTicks() === 0) {
96
            return false;
97
        }
98
99
        $isUnderConstruction = $station->getState() === SpacecraftStateEnum::UNDER_CONSTRUCTION;
100
101
        if (!$this->stationUtility->hasEnoughDockedWorkbees($station, $station->getRump())) {
102
            $neededWorkbees = $isUnderConstruction ? $station->getRump()->getNeededWorkbees() :
103
                (int)ceil($station->getRump()->getNeededWorkbees() / 2);
104
105
            $informationWrapper->addInformationf(
106
                'Nicht genügend Workbees (%d/%d) angedockt um %s weiterführen zu können',
107
                $this->stationUtility->getDockedWorkbeeCount($station),
108
                $neededWorkbees ?? 0,
109
                $isUnderConstruction ? 'den Bau' : 'die Demontage'
110
            );
111
            return true;
112
        }
113
114
        if ($isUnderConstruction) {
115
            // raise hull
116
            $increase = (int)ceil($station->getMaxHull() / (2 * $station->getRump()->getBuildtime()));
117
            $station->setHuell($station->getHull() + $increase);
118
        }
119
120
        if ($progress->getRemainingTicks() === 1) {
121
122
            $informationWrapper->addInformationf(
123
                '%s: %s bei %s fertiggestellt',
124
                $station->getRump()->getName(),
125
                $isUnderConstruction ? 'Bau' : 'Demontage',
126
                $station->getSectorString()
127
            );
128
129
            if ($isUnderConstruction) {
130
                $this->stationUtility->finishStation($progress);
131
            } else {
132
                $this->stationUtility->finishScrapping($progress, $informationWrapper);
133
            }
134
        } else {
135
            $this->stationUtility->reduceRemainingTicks($progress);
136
        }
137
138
        return true;
139
    }
140
141
    private function doRepairStation(StationWrapperInterface $wrapper, InformationWrapper $informationWrapper): void
142
    {
143
        $station = $wrapper->get();
144
145
        if (!$this->stationUtility->hasEnoughDockedWorkbees($station, $station->getRump())) {
146
            $neededWorkbees = (int)ceil($station->getRump()->getNeededWorkbees() / 5);
147
148
            $informationWrapper->addInformationf(
149
                'Nicht genügend Workbees (%d/%d) angedockt um die Reparatur weiterführen zu können',
150
                $this->stationUtility->getDockedWorkbeeCount($station),
151
                $neededWorkbees
152
            );
153
            return;
154
        }
155
156
        $neededParts = $this->repairUtil->determineSpareParts($wrapper, true);
157
158
        // parts stored?
159
        if (!$this->repairUtil->enoughSparePartsOnEntity($neededParts, $station, $station)) {
160
            return;
161
        }
162
163
        //repair hull
164
        $station->setHuell($station->getHull() + $station->getRepairRate());
165
        if ($station->getHull() > $station->getMaxHull()) {
166
            $station->setHuell($station->getMaxHull());
167
        }
168
169
        //repair station systems
170
        $damagedSystems = $wrapper->getDamagedSystems();
171
        if ($damagedSystems !== []) {
172
            $firstSystem = $damagedSystems[0];
173
            $firstSystem->setStatus(100);
174
175
            if ($station->getCrewCount() > 0) {
176
                $firstSystem->setMode($this->spacecraftSystemManager->lookupSystem($firstSystem->getSystemType())->getDefaultMode());
177
            }
178
179
            // maximum of two systems get repaired
180
            if (count($damagedSystems) > 1) {
181
                $secondSystem = $damagedSystems[1];
182
                $secondSystem->setStatus(100);
183
184
                if ($station->getCrewCount() > 0) {
185
                    $secondSystem->setMode($this->spacecraftSystemManager->lookupSystem($secondSystem->getSystemType())->getDefaultMode());
186
                }
187
            }
188
        }
189
190
        // consume spare parts
191
        $this->repairUtil->consumeSpareParts($neededParts, $station);
192
193
        if (!$wrapper->canBeRepaired()) {
194
            $station->setHuell($station->getMaxHull());
195
            $station->setState(SpacecraftStateEnum::NONE);
196
197
            $shipOwnerMessage = sprintf(
198
                "Die Reparatur der %s wurde in Sektor %s fertiggestellt",
199
                $station->getName(),
200
                $station->getSectorString()
201
            );
202
203
            $this->privateMessageSender->send(
204
                UserEnum::USER_NOONE,
205
                $station->getUser()->getId(),
206
                $shipOwnerMessage,
207
                PrivateMessageFolderTypeEnum::SPECIAL_STATION
208
            );
209
        }
210
        $this->spacecraftRepository->save($station);
211
    }
212
213
    private function sendMessage(SpacecraftInterface $ship, InformationWrapper $informationWrapper): void
214
    {
215
        if ($informationWrapper->isEmpty()) {
216
            return;
217
        }
218
219
        $text = sprintf("Tickreport der %s\n%s", $ship->getName(), $informationWrapper->getInformationsAsString());
220
221
        $this->privateMessageSender->send(
222
            UserEnum::USER_NOONE,
223
            $ship->getUser()->getId(),
224
            $text,
225
            $ship->getType()->getMessageFolderType(),
226
            $ship
227
        );
228
    }
229
}
230