Passed
Push — master ( bb5d68...d9c4a7 )
by Nico
56:35 queued 26:36
created

BuildingManager   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 191
Duplicated Lines 0 %

Test Coverage

Coverage 96.88%

Importance

Changes 0
Metric Value
eloc 97
c 0
b 0
f 0
dl 0
loc 191
ccs 93
cts 96
cp 0.9688
rs 10
wmc 29

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A saveHost() 0 6 2
B activate() 0 45 7
A updateWorkerAndMaxBev() 0 9 2
A finish() 0 33 5
A deactivate() 0 26 4
B remove() 0 35 8
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): bool
46
    {
47 7
        $building = $field->getBuilding();
48
49 7
        if ($building === null) {
50 1
            return false;
51
        }
52
53 6
        if (!$field->isActivateable()) {
54 2
            return false;
55
        }
56
57 4
        if ($field->isActive()) {
58 1
            return true;
59
        }
60
61 3
        if ($field->hasHighDamage()) {
62 1
            return false;
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 false;
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 1
        return true;
90
    }
91
92 6
    public function deactivate(PlanetFieldInterface $field): void
93
    {
94 6
        $building = $field->getBuilding();
95
96 6
        if ($building === null) {
97 1
            return;
98
        }
99
100 5
        if (!$field->isActivateable()) {
101 2
            return;
102
        }
103
104 3
        if (!$field->isActive()) {
105 1
            return;
106
        }
107
108 2
        $host = $field->getHost();
109
110 2
        $this->updateWorkerAndMaxBev($building, $host);
111 2
        $field->setActive(0);
112
113 2
        $this->planetFieldRepository->save($field);
114
115 2
        $this->buildingPostAction->handleDeactivation($building, $host);
116
117 2
        $this->saveHost($host);
118
    }
119
120 5
    private function saveHost(ColonyInterface|ColonySandboxInterface $host): void
121
    {
122 5
        if ($host instanceof ColonyInterface) {
123 5
            $this->colonyRepository->save($host);
124
        } else {
125
            $this->colonySandboxRepository->save($host);
126
        }
127
    }
128
129 2
    private function updateWorkerAndMaxBev(BuildingInterface $building, ColonyInterface|ColonySandboxInterface $host): void
130
    {
131 2
        $workerAmount = $building->getWorkers();
132
133 2
        if ($host instanceof ColonyInterface) {
134 2
            $host->setWorkless($host->getWorkless() + $workerAmount);
135
        }
136 2
        $host->setWorkers($host->getWorkers() - $workerAmount);
137 2
        $host->setMaxBev($host->getMaxBev() - $building->getHousing());
138
    }
139
140 3
    public function remove(
141
        PlanetFieldInterface $field,
142
        bool $upgrade = false
143
    ): void {
144 3
        $building = $field->getBuilding();
145 3
        if ($building === null) {
146 1
            return;
147
        }
148
149 2
        if (!$building->isRemovable() && $upgrade === false) {
150 1
            return;
151
        }
152
153 1
        $host = $field->getHost();
154
155 1
        if (!$field->isUnderConstruction()) {
156 1
            $this->deactivate($field);
157 1
            $host
158 1
                ->setMaxStorage($host->getMaxStorage() - $building->getStorage())
159 1
                ->setMaxEps($host->getMaxEps() - $building->getEpsStorage());
160
        }
161
162 1
        foreach ($building->getFunctions() as $function) {
163 1
            $buildingFunctionId = $function->getFunction();
164
165 1
            $handler = $this->buildingFunctionActionMapper->map($buildingFunctionId);
166 1
            if ($handler !== null && $host instanceof ColonyInterface) {
167 1
                $handler->destruct($buildingFunctionId, $host);
168
            }
169
        }
170
171 1
        $field->clearBuilding();
172
173 1
        $this->planetFieldRepository->save($field);
174 1
        $this->saveHost($host);
175
    }
176
177 2
    public function finish(PlanetFieldInterface $field, bool $activate = true): ?string
178
    {
179 2
        $building = $field->getBuilding();
180 2
        if ($building === null) {
181 1
            return null;
182
        }
183
184 1
        $host = $field->getHost();
185
186
187 1
        $field
188 1
            ->setActive(0)
189 1
            ->setIntegrity($building->getIntegrity());
190
191 1
        $activationDetails = null;
192 1
        if ($building->isActivateAble()) {
193 1
            if ($activate) {
194 1
                $activationDetails = $this->activate($field)
195
                    ? '[color=green]Und konnte wunschgemäß aktiviert werden[/color]'
196 1
                    : '[color=red]Konnte allerdings nicht wie gewünscht aktiviert werden[/color]';
197
            } else {
198
                $activationDetails = 'Und wurde wunschgemäß nicht aktiviert';
199
            }
200
        }
201
202 1
        $host
203 1
            ->setMaxStorage($host->getMaxStorage() + $building->getStorage())
204 1
            ->setMaxEps($host->getMaxEps() + $building->getEpsStorage());
205
206 1
        $this->saveHost($host);
207 1
        $this->planetFieldRepository->save($field);
208
209 1
        return $activationDetails;
210
    }
211
}
212