Passed
Push — master ( 4158cc...85b774 )
by Nico
17:22 queued 07:50
created

Colonize::performSessionCheck()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Action\Colonize;
6
7
use InvalidArgumentException;
8
use request;
9
use Stu\Component\Player\ColonizationCheckerInterface;
10
use Stu\Module\Colony\Lib\PlanetColonizationInterface;
11
use Stu\Module\Colony\View\ShowColony\ShowColony;
12
use Stu\Module\Control\ActionControllerInterface;
13
use Stu\Module\Control\GameControllerInterface;
14
use Stu\Module\PlayerSetting\Lib\UserEnum;
15
use Stu\Module\Ship\Lib\InteractionCheckerInterface;
16
use Stu\Module\Ship\Lib\ShipLoaderInterface;
17
use Stu\Module\Ship\Lib\ShipRemoverInterface;
18
use Stu\Module\Ship\Lib\ShipRumpSpecialAbilityEnum;
19
use Stu\Module\Ship\View\ShowShip\ShowShip;
20
use Stu\Orm\Entity\ColonyInterface;
21
use Stu\Orm\Entity\ShipInterface;
22
use Stu\Orm\Repository\BuildingRepositoryInterface;
23
use Stu\Orm\Repository\ColonyDepositMiningRepositoryInterface;
24
use Stu\Orm\Repository\ColonyRepositoryInterface;
25
use Stu\Orm\Repository\PlanetFieldRepositoryInterface;
26
use Stu\Orm\Repository\ShipCrewRepositoryInterface;
27
use Stu\Orm\Repository\ShipRumpColonizationBuildingRepositoryInterface;
28
use Stu\Orm\Repository\UserRepositoryInterface;
29
use Stu\Component\Colony\Storage\ColonyStorageManagerInterface;
30
use Stu\Module\Commodity\CommodityTypeEnum;
31
use Stu\Orm\Entity\CommodityInterface;
32
use Stu\Orm\Repository\CommodityRepositoryInterface;
33
34
final class Colonize implements ActionControllerInterface
35
{
36
    public const ACTION_IDENTIFIER = 'B_COLONIZE';
37
38
    private ShipLoaderInterface $shipLoader;
39
40
    private ShipRumpColonizationBuildingRepositoryInterface $shipRumpColonizationBuildingRepository;
41
42
    private BuildingRepositoryInterface $buildingRepository;
43
44
    private PlanetFieldRepositoryInterface $planetFieldRepository;
45
46
    private PlanetColonizationInterface $planetColonization;
47
48
    private ColonyStorageManagerInterface $colonyStorageManager;
49
50
    private CommodityRepositoryInterface $commodityRepository;
51
52
    private ColonyRepositoryInterface $colonyRepository;
53
54
    private ShipRemoverInterface $shipRemover;
55
56
    private InteractionCheckerInterface $interactionChecker;
57
58
    private ColonizationCheckerInterface $colonizationChecker;
59
60
    private ShipCrewRepositoryInterface $shipCrewRepository;
61
62
    private ColonyDepositMiningRepositoryInterface $colonyDepositMiningRepository;
63
64
    private UserRepositoryInterface $userRepository;
65
66
    public function __construct(
67
        ShipLoaderInterface $shipLoader,
68
        ShipRumpColonizationBuildingRepositoryInterface $shipRumpColonizationBuildingRepository,
69
        BuildingRepositoryInterface $buildingRepository,
70
        PlanetFieldRepositoryInterface $planetFieldRepository,
71
        PlanetColonizationInterface $planetColonization,
72
        ColonyRepositoryInterface $colonyRepository,
73
        ColonyStorageManagerInterface $colonyStorageManager,
74
        CommodityRepositoryInterface $commodityRepository,
75
        ShipRemoverInterface $shipRemover,
76
        InteractionCheckerInterface $interactionChecker,
77
        ColonizationCheckerInterface $colonizationChecker,
78
        ShipCrewRepositoryInterface $shipCrewRepository,
79
        ColonyDepositMiningRepositoryInterface $colonyDepositMiningRepository,
80
        UserRepositoryInterface $userRepository
81
    ) {
82
        $this->shipLoader = $shipLoader;
83
        $this->shipRumpColonizationBuildingRepository = $shipRumpColonizationBuildingRepository;
84
        $this->buildingRepository = $buildingRepository;
85
        $this->planetFieldRepository = $planetFieldRepository;
86
        $this->planetColonization = $planetColonization;
87
        $this->colonyRepository = $colonyRepository;
88
        $this->colonyStorageManager = $colonyStorageManager;
89
        $this->commodityRepository = $commodityRepository;
90
        $this->shipRemover = $shipRemover;
91
        $this->interactionChecker = $interactionChecker;
92
        $this->colonizationChecker = $colonizationChecker;
93
        $this->shipCrewRepository = $shipCrewRepository;
94
        $this->colonyDepositMiningRepository = $colonyDepositMiningRepository;
95
        $this->userRepository = $userRepository;
96
    }
97
98
    public function handle(GameControllerInterface $game): void
99
    {
100
        $game->setView(ShowShip::VIEW_IDENTIFIER);
101
102
        $user = $game->getUser();
103
        $userId = $user->getId();
104
105
        $ship = $this->shipLoader->getByIdAndUser(
106
            request::indInt('id'),
107
            $userId
108
        );
109
110
        $colonyId = request::getIntFatal('colid');
111
        $fieldId = request::getIntFatal('field');
112
113
        $colony = $this->colonyRepository->find($colonyId);
114
        $field = $this->planetFieldRepository->find($fieldId);
115
116
        if ($field === null || $colony === null) {
117
            return;
118
        }
119
120
        if (!$ship->getRump()->hasSpecialAbility(ShipRumpSpecialAbilityEnum::COLONIZE)) {
121
            return;
122
        }
123
124
        if ($colony->getId() !== $field->getColonyId()) {
125
            return;
126
        }
127
        if (!$this->interactionChecker->checkColonyPosition($colony, $ship)) {
128
            return;
129
        }
130
        if ($this->colonizationChecker->canColonize($user, $colony) === false) {
131
            return;
132
        }
133
134
        $shipRumpColonizationBuilding = $this->shipRumpColonizationBuildingRepository->findByShipRump($ship->getRump());
135
        if ($shipRumpColonizationBuilding === null) {
136
            return;
137
        }
138
139
        $building = $this->buildingRepository->find($shipRumpColonizationBuilding->getBuildingId());
140
        if ($building === null) {
141
            return;
142
        }
143
144
        if (!$user->hasColony()) {
145
            $user->setState(UserEnum::USER_STATE_TUTORIAL1);
146
            $this->userRepository->save($user);
147
            $this->planetColonization->colonize(
148
                $colony,
149
                $userId,
150
                $building,
151
                $field
152
            );
153
            $this->colonyStorageManager->upperStorage(
154
                $colony,
155
                $this->getCommodity(CommodityTypeEnum::COMMODITY_BUILDING_MATERIALS),
156
                150
157
            );
158
            $this->colonyStorageManager->upperStorage(
159
                $colony,
160
                $this->getCommodity(CommodityTypeEnum::COMMODITY_TRANSPARENT_ALUMINIUM),
161
                150
162
            );
163
            $this->colonyStorageManager->upperStorage(
164
                $colony,
165
                $this->getCommodity(CommodityTypeEnum::COMMODITY_DURANIUM),
166
                150
167
            );
168
            $this->colonyStorageManager->upperStorage(
169
                $colony,
170
                $this->getCommodity(CommodityTypeEnum::COMMODITY_DEUTERIUM),
171
                100
172
            );
173
        } else {
174
175
            $this->planetColonization->colonize(
176
                $colony,
177
                $userId,
178
                $building,
179
                $field
180
            );
181
        }
182
183
184
        $this->transferCrewToColony($ship, $colony);
185
186
        $this->createUserDepositMinings($colony);
187
188
        $this->shipRemover->remove($ship);
189
190
        $game->checkDatabaseItem($colony->getColonyClass()->getDatabaseId());
191
192
        $game->redirectTo(sprintf(
193
            '/colony.php?%s=1&id=%d',
194
            ShowColony::VIEW_IDENTIFIER,
195
            $colony->getId()
196
        ));
197
    }
198
199
    private function getCommodity(int $commodityId): CommodityInterface
200
    {
201
        $commodity = $this->commodityRepository->find(CommodityTypeEnum::COMMODITY_DEUTERIUM);
202
        if ($commodity === null) {
203
            throw new InvalidArgumentException(sprintf('commodityId %d does not exist', $commodityId));
204
        }
205
206
        return $commodity;
207
    }
208
209
    private function transferCrewToColony(ShipInterface $ship, ColonyInterface $colony): void
210
    {
211
        foreach ($ship->getCrewlist() as $crewAssignment) {
212
            $crewAssignment->setColony($colony);
213
            $crewAssignment->setShip(null);
214
            $crewAssignment->setSlot(null);
215
            $colony->getCrewAssignments()->add($crewAssignment);
216
            $this->shipCrewRepository->save($crewAssignment);
217
        }
218
219
        $ship->getCrewlist()->clear();
220
    }
221
222
    private function createUserDepositMinings(ColonyInterface $colony): void
223
    {
224
        $deposits = $colony->getColonyClass()->getColonyClassDeposits();
225
        $userMinings = $colony->getUserDepositMinings();
226
227
        foreach ($deposits as $deposit) {
228
            //check if user already mined this commodity on this colony
229
            if (array_key_exists($deposit->getCommodity()->getId(), $userMinings)) {
230
                continue;
231
            }
232
233
            //create new mining entry
234
            $depositMining = $this->colonyDepositMiningRepository->prototype();
235
            $depositMining->setUser($colony->getUser());
236
            $depositMining->setColony($colony);
237
            $depositMining->setCommodity($deposit->getCommodity());
238
            $depositMining->setAmountLeft(random_int($deposit->getMinAmount(), $deposit->getMaxAmount()));
239
240
            $this->colonyDepositMiningRepository->save($depositMining);
241
        }
242
    }
243
244
    public function performSessionCheck(): bool
245
    {
246
        return true;
247
    }
248
}
249