Passed
Push — master ( f544cb...b3a3d9 )
by Nico
36:43 queued 09:10
created

UpgradeBuilding::doColonyCheckAndConsumeEnergy()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 38
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 24
c 0
b 0
f 0
nc 6
nop 3
dl 0
loc 38
ccs 0
cts 28
cp 0
crap 30
rs 9.2248
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Colony\Action\UpgradeBuilding;
6
7
use request;
8
use Stu\Component\Building\BuildingManagerInterface;
9
use Stu\Component\Colony\Storage\ColonyStorageManagerInterface;
10
use Stu\Lib\Colony\PlanetFieldHostProviderInterface;
11
use Stu\Module\Colony\Lib\BuildingActionInterface;
12
use Stu\Module\Control\ActionControllerInterface;
13
use Stu\Module\Control\GameControllerInterface;
14
use Stu\Orm\Entity\BuildingUpgradeCostInterface;
15
use Stu\Orm\Entity\BuildingUpgradeInterface;
16
use Stu\Orm\Entity\ColonyInterface;
17
use Stu\Orm\Entity\ColonySandboxInterface;
18
use Stu\Orm\Repository\BuildingFieldAlternativeRepositoryInterface;
19
use Stu\Orm\Repository\BuildingUpgradeRepositoryInterface;
20
use Stu\Orm\Repository\ColonyRepositoryInterface;
21
use Stu\Orm\Repository\PlanetFieldRepositoryInterface;
22
use Stu\Orm\Repository\ResearchedRepositoryInterface;
23
24
final class UpgradeBuilding implements ActionControllerInterface
25
{
26
    public const ACTION_IDENTIFIER = 'B_UPGRADE_BUILDING';
27
28
    private BuildingUpgradeRepositoryInterface $buildingUpgradeRepository;
29
30
    private PlanetFieldRepositoryInterface $planetFieldRepository;
31
32
    private BuildingFieldAlternativeRepositoryInterface $buildingFieldAlternativeRepository;
33
34
    private ResearchedRepositoryInterface $researchedRepository;
35
36
    private PlanetFieldHostProviderInterface $planetFieldHostProvider;
37
38
    private ColonyStorageManagerInterface $colonyStorageManager;
39
40
    private ColonyRepositoryInterface $colonyRepository;
41
42
    private BuildingActionInterface $buildingAction;
43
44
    private BuildingManagerInterface $buildingManager;
45
46
    public function __construct(
47
        BuildingUpgradeRepositoryInterface $buildingUpgradeRepository,
48
        PlanetFieldRepositoryInterface $planetFieldRepository,
49
        BuildingFieldAlternativeRepositoryInterface $buildingFieldAlternativeRepository,
50
        ResearchedRepositoryInterface $researchedRepository,
51
        PlanetFieldHostProviderInterface $planetFieldHostProvider,
52
        ColonyStorageManagerInterface $colonyStorageManager,
53
        ColonyRepositoryInterface $colonyRepository,
54
        BuildingActionInterface $buildingAction,
55
        BuildingManagerInterface $buildingManager
56
    ) {
57
        $this->buildingUpgradeRepository = $buildingUpgradeRepository;
58
        $this->planetFieldRepository = $planetFieldRepository;
59
        $this->buildingFieldAlternativeRepository = $buildingFieldAlternativeRepository;
60
        $this->researchedRepository = $researchedRepository;
61
        $this->planetFieldHostProvider = $planetFieldHostProvider;
62
        $this->colonyStorageManager = $colonyStorageManager;
63
        $this->colonyRepository = $colonyRepository;
64
        $this->buildingAction = $buildingAction;
65
        $this->buildingManager = $buildingManager;
66
    }
67
68
    public function handle(GameControllerInterface $game): void
69
    {
70
        $field = $this->planetFieldHostProvider->loadFieldViaRequestParameter($game->getUser());
71
        $host = $field->getHost();
72
73
        $game->setView($host->getDefaultViewIdentifier());
74
75
        // has to be string because of bigint issue
76
        $upgradeId = request::getStringFatal('upid');
77
78
        $upgrade = $this->buildingUpgradeRepository->find($upgradeId);
79
        if ($upgrade === null) {
80
            return;
81
        }
82
83
        if ($upgrade->getUpgradeFromBuildingId() != $field->getBuildingId()) {
84
            return;
85
        }
86
87
        $researchId = $upgrade->getResearchId();
88
        if (
89
            $researchId > 0 &&
90
            $this->researchedRepository->hasUserFinishedResearch($game->getUser(), [$researchId]) === false
91
        ) {
92
            return;
93
        }
94
        if ($field->isUnderConstruction()) {
95
            $game->addInformation(_('Das Gebäude auf diesem Feld ist noch nicht fertig'));
96
            return;
97
        }
98
99
        if ($host instanceof ColonyInterface) {
100
            if (!$this->doColonyCheckAndConsumeEnergy($upgrade, $host, $game)) {
101
                return;
102
            }
103
        }
104
105
        // Check for alternative building
106
        $alt_building = $this->buildingFieldAlternativeRepository->getByBuildingAndFieldType(
107
            $upgrade->getBuilding()->getId(),
108
            $field->getFieldType()
109
        );
110
        $building = $alt_building !== null ? $alt_building->getAlternativeBuilding() : $upgrade->getBuilding();
111
112
        $this->buildingAction->remove($field, $game, true);
113
114
        if ($host instanceof ColonyInterface) {
115
            foreach ($upgrade->getUpgradeCosts() as $obj) {
116
                $this->colonyStorageManager->lowerStorage($host, $obj->getCommodity(), $obj->getAmount());
117
            }
118
        }
119
120
        $field->setBuilding($building);
121
122
        if ($host instanceof ColonySandboxInterface) {
123
            $this->buildingManager->finish($field);
124
125
            $game->addInformationf(
126
                _('%s wurde gebaut'),
127
                $building->getName()
128
            );
129
        } else {
130
            $field->setActive(time() + $building->getBuildtime());
131
132
            $game->addInformationf(
133
                _('%s wird durchgeführt - Fertigstellung: %s'),
134
                $upgrade->getDescription(),
135
                date('d.m.Y H:i', $field->getBuildtime())
136
            );
137
        }
138
139
        $this->planetFieldRepository->save($field);
140
    }
141
142
    private function doColonyCheckAndConsumeEnergy(BuildingUpgradeInterface $upgrade, ColonyInterface $colony, GameControllerInterface $game): bool
143
    {
144
        $storage = $colony->getStorage();
145
146
        /** @var BuildingUpgradeCostInterface $obj */
147
        foreach ($upgrade->getUpgradeCosts() as $obj) {
148
            if (!$storage->containsKey($obj->getCommodityId())) {
149
                $game->addInformationf(
150
                    _('Es werden %d %s benötigt - Es ist jedoch keines vorhanden'),
151
                    $obj->getAmount(),
152
                    $obj->getCommodity()->getName()
153
                );
154
                return false;
155
            }
156
            if ($obj->getAmount() > $storage[$obj->getCommodityId()]->getAmount()) {
157
                $game->addInformationf(
158
                    _('Es werden %d %s benötigt - Vorhanden sind nur %d'),
159
                    $obj->getAmount(),
160
                    $obj->getCommodity()->getName(),
161
                    $storage[$obj->getCommodityId()]->getAmount()
162
                );
163
                return false;
164
            }
165
        }
166
167
        if ($colony->getEps() < $upgrade->getEnergyCost()) {
168
            $game->addInformationf(
169
                _('Zum Bau wird %d Energie benötigt - Vorhanden ist nur %d'),
170
                $upgrade->getEnergyCost(),
171
                $colony->getEps()
172
            );
173
            return false;
174
        }
175
176
        $colony->lowerEps($upgrade->getEnergyCost());
177
        $this->colonyRepository->save($colony);
178
179
        return true;
180
    }
181
182
    public function performSessionCheck(): bool
183
    {
184
        return true;
185
    }
186
}
187