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

BuildingManager::deactivate()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 4
nop 1
dl 0
loc 26
ccs 14
cts 14
cp 1
crap 4
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Component\Building;
6
7
use Stu\Module\Building\Action\BuildingFunctionActionMapperInterface;
8
use Stu\Orm\Entity\BuildingInterface;
9
use Stu\Orm\Entity\ColonyInterface;
10
use Stu\Orm\Entity\ColonySandboxInterface;
11
use Stu\Orm\Entity\PlanetFieldInterface;
12
use Stu\Orm\Repository\ColonyRepositoryInterface;
13
use Stu\Orm\Repository\ColonySandboxRepositoryInterface;
14
use Stu\Orm\Repository\PlanetFieldRepositoryInterface;
15
16
/**
17
 * Manages actions relating to buildings on planets
18
 */
19
final class BuildingManager implements BuildingManagerInterface
20
{
21
    private PlanetFieldRepositoryInterface $planetFieldRepository;
22
23
    private ColonyRepositoryInterface $colonyRepository;
24
25
    private ColonySandboxRepositoryInterface $colonySandboxRepository;
26
27
    private BuildingPostActionInterface $buildingPostAction;
28
29
    private BuildingFunctionActionMapperInterface $buildingFunctionActionMapper;
30
31 16
    public function __construct(
32
        PlanetFieldRepositoryInterface $planetFieldRepository,
33
        ColonyRepositoryInterface $colonyRepository,
34
        ColonySandboxRepositoryInterface $colonySandboxRepository,
35
        BuildingFunctionActionMapperInterface $buildingFunctionActionMapper,
36
        BuildingPostActionInterface $buildingPostAction
37
    ) {
38 16
        $this->planetFieldRepository = $planetFieldRepository;
39 16
        $this->colonyRepository = $colonyRepository;
40 16
        $this->colonySandboxRepository = $colonySandboxRepository;
41 16
        $this->buildingFunctionActionMapper = $buildingFunctionActionMapper;
42 16
        $this->buildingPostAction = $buildingPostAction;
43
    }
44
45 7
    public function activate(PlanetFieldInterface $field): void
46
    {
47 7
        $building = $field->getBuilding();
48
49 7
        if ($building === null) {
50 1
            return;
51
        }
52
53 6
        if (!$field->isActivateable()) {
54 2
            return;
55
        }
56
57 4
        if ($field->isActive()) {
58 1
            return;
59
        }
60
61 3
        if ($field->hasHighDamage()) {
62 1
            return;
63
        }
64
65 2
        $host = $field->getHost();
66
67 2
        $workerAmount = $building->getWorkers();
68
69 2
        if ($host instanceof ColonyInterface) {
70 2
            $worklessAmount = $host->getWorkless();
71 2
            if ($worklessAmount < $workerAmount) {
72 1
                return;
73
            }
74
75 1
            $host->setWorkless($worklessAmount - $workerAmount);
76
        }
77
78 1
        $host
79 1
            ->setWorkers($host->getWorkers() + $workerAmount)
80 1
            ->setMaxBev($host->getMaxBev() + $building->getHousing());
81 1
        $field->setActive(1);
82
83 1
        $this->planetFieldRepository->save($field);
84
85 1
        $this->buildingPostAction->handleActivation($building, $host);
86
87 1
        $this->saveHost($host);
88
    }
89
90 6
    public function deactivate(PlanetFieldInterface $field): void
91
    {
92 6
        $building = $field->getBuilding();
93
94 6
        if ($building === null) {
95 1
            return;
96
        }
97
98 5
        if (!$field->isActivateable()) {
99 2
            return;
100
        }
101
102 3
        if (!$field->isActive()) {
103 1
            return;
104
        }
105
106 2
        $host = $field->getHost();
107
108 2
        $this->updateWorkerAndMaxBev($building, $host);
109 2
        $field->setActive(0);
110
111 2
        $this->planetFieldRepository->save($field);
112
113 2
        $this->buildingPostAction->handleDeactivation($building, $host);
114
115 2
        $this->saveHost($host);
116
    }
117
118 5
    private function saveHost(ColonyInterface|ColonySandboxInterface $host): void
119
    {
120 5
        if ($host instanceof ColonyInterface) {
121 5
            $this->colonyRepository->save($host);
122
        } else {
123
            $this->colonySandboxRepository->save($host);
124
        }
125
    }
126
127 2
    private function updateWorkerAndMaxBev(BuildingInterface $building, ColonyInterface|ColonySandboxInterface $host): void
128
    {
129 2
        $workerAmount = $building->getWorkers();
130
131 2
        if ($host instanceof ColonyInterface) {
132 2
            $host->setWorkless($host->getWorkless() + $workerAmount);
133
        }
134 2
        $host->setWorkers($host->getWorkers() - $workerAmount);
135 2
        $host->setMaxBev($host->getMaxBev() - $building->getHousing());
136
    }
137
138 3
    public function remove(
139
        PlanetFieldInterface $field,
140
        bool $upgrade = false
141
    ): void {
142 3
        $building = $field->getBuilding();
143 3
        if ($building === null) {
144 1
            return;
145
        }
146
147 2
        if (!$building->isRemovable() && $upgrade === false) {
148 1
            return;
149
        }
150
151 1
        $host = $field->getHost();
152
153 1
        if (!$field->isUnderConstruction()) {
154 1
            $this->deactivate($field);
155 1
            $host
156 1
                ->setMaxStorage($host->getMaxStorage() - $building->getStorage())
157 1
                ->setMaxEps($host->getMaxEps() - $building->getEpsStorage());
158
        }
159
160 1
        foreach ($building->getFunctions() as $function) {
161 1
            $buildingFunctionId = $function->getFunction();
162
163 1
            $handler = $this->buildingFunctionActionMapper->map($buildingFunctionId);
164 1
            if ($handler !== null && $host instanceof ColonyInterface) {
165 1
                $handler->destruct($buildingFunctionId, $host);
166
            }
167
        }
168
169 1
        $field->clearBuilding();
170
171 1
        $this->planetFieldRepository->save($field);
172 1
        $this->saveHost($host);
173
    }
174
175 2
    public function finish(PlanetFieldInterface $field, bool $activate = true): void
176
    {
177 2
        $building = $field->getBuilding();
178 2
        if ($building === null) {
179 1
            return;
180
        }
181
182 1
        $host = $field->getHost();
183
184 1
        $field
185 1
            ->setActive(0)
186 1
            ->setIntegrity($building->getIntegrity());
187
188 1
        if ($building->isActivateAble() && $activate === true) {
189 1
            $this->activate($field);
190
        }
191
192 1
        $host
193 1
            ->setMaxStorage($host->getMaxStorage() + $building->getStorage())
194 1
            ->setMaxEps($host->getMaxEps() + $building->getEpsStorage());
195
196 1
        $this->saveHost($host);
197 1
        $this->planetFieldRepository->save($field);
198
    }
199
}
200