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

Terraform   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 82
c 0
b 0
f 0
dl 0
loc 151
ccs 0
cts 83
cp 0
rs 10
wmc 16

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 1
A performSessionCheck() 0 3 1
B doColonyCheckAndConsume() 0 63 6
B handle() 0 49 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Colony\Action\Terraform;
6
7
use request;
8
use Stu\Component\Colony\Storage\ColonyStorageManagerInterface;
9
use Stu\Exception\SanityCheckException;
10
use Stu\Lib\Colony\PlanetFieldHostProviderInterface;
11
use Stu\Module\Control\ActionControllerInterface;
12
use Stu\Module\Control\GameControllerInterface;
13
use Stu\Orm\Entity\ColonyInterface;
14
use Stu\Orm\Entity\PlanetFieldInterface;
15
use Stu\Orm\Entity\TerraformingInterface;
16
use Stu\Orm\Repository\ColonyRepositoryInterface;
17
use Stu\Orm\Repository\ColonyTerraformingRepositoryInterface;
18
use Stu\Orm\Repository\PlanetFieldRepositoryInterface;
19
use Stu\Orm\Repository\TerraformingRepositoryInterface;
20
21
final class Terraform implements ActionControllerInterface
22
{
23
    public const ACTION_IDENTIFIER = 'B_TERRAFORM';
24
25
    private PlanetFieldHostProviderInterface $planetFieldHostProvider;
26
27
    private TerraformingRepositoryInterface $terraformingRepository;
28
29
    private ColonyTerraformingRepositoryInterface $colonyTerraformingRepository;
30
31
    private PlanetFieldRepositoryInterface $planetFieldRepository;
32
33
    private ColonyStorageManagerInterface $colonyStorageManager;
34
35
    private ColonyRepositoryInterface $colonyRepository;
36
37
    public function __construct(
38
        PlanetFieldHostProviderInterface $planetFieldHostProvider,
39
        TerraformingRepositoryInterface $terraformingRepository,
40
        ColonyTerraformingRepositoryInterface $colonyTerraformingRepository,
41
        PlanetFieldRepositoryInterface $planetFieldRepository,
42
        ColonyStorageManagerInterface $colonyStorageManager,
43
        ColonyRepositoryInterface $colonyRepository
44
    ) {
45
        $this->planetFieldHostProvider = $planetFieldHostProvider;
46
        $this->terraformingRepository = $terraformingRepository;
47
        $this->colonyTerraformingRepository = $colonyTerraformingRepository;
48
        $this->planetFieldRepository = $planetFieldRepository;
49
        $this->colonyStorageManager = $colonyStorageManager;
50
        $this->colonyRepository = $colonyRepository;
51
    }
52
53
    public function handle(GameControllerInterface $game): void
54
    {
55
        $user = $game->getUser();
56
        $userId = $user->getId();
57
58
        $field = $this->planetFieldHostProvider->loadFieldViaRequestParameter($game->getUser());
59
        $host = $field->getHost();
60
61
        $game->setView($host->getDefaultViewIdentifier());
62
63
64
        if ($field->getBuildingId() > 0) {
65
            return;
66
        }
67
        if ($field->getTerraformingId() > 0) {
68
            return;
69
        }
70
71
        $terraforming = $this->terraformingRepository->find(request::getIntFatal('tfid'));
72
        if ($terraforming === null) {
73
            return;
74
        }
75
        if ($field->getFieldType() !== $terraforming->getFromFieldTypeId()) {
76
            return;
77
        }
78
79
        //sanity check if user has researched this terraforming
80
        $terraformingopts = $this->terraformingRepository->getBySourceFieldTypeAndUser(
81
            $field->getFieldType(),
82
            $userId
83
        );
84
        if (!array_key_exists($terraforming->getId(), $terraformingopts)) {
85
            throw new SanityCheckException('user tried to perform unresearched terraforming', self::ACTION_IDENTIFIER);
86
        }
87
88
        if ($host instanceof ColonyInterface) {
89
            if (!$this->doColonyCheckAndConsume($terraforming, $field, $host, $game)) {
90
                return;
91
            }
92
        } else {
93
            $field->setFieldType($terraforming->getToFieldTypeId());
94
95
            $game->addInformationf(
96
                _('%s wurde durchgeführt'),
97
                $terraforming->getDescription()
98
            );
99
        }
100
101
        $this->planetFieldRepository->save($field);
102
    }
103
104
    private function doColonyCheckAndConsume(
105
        TerraformingInterface $terraforming,
106
        PlanetFieldInterface $field,
107
        ColonyInterface $colony,
108
        GameControllerInterface $game
109
    ): bool {
110
111
        if ($terraforming->getEnergyCosts() > $colony->getEps()) {
112
            $game->addInformationf(
113
                _('Es wird %s Energie benötigt - Vorhanden ist nur %s'),
114
                $terraforming->getEnergyCosts(),
115
                $colony->getEps()
116
            );
117
            return false;
118
        }
119
120
        $storage = $colony->getStorage();
121
122
        foreach ($terraforming->getCosts() as $obj) {
123
            $commodityId = $obj->getCommodityId();
124
            if (!$storage->containsKey($commodityId)) {
125
                $game->addInformationf(
126
                    _('Es werden %s %s benötigt - Es ist jedoch keines vorhanden'),
127
                    $obj->getAmount(),
128
                    $obj->getCommodity()->getName()
129
                );
130
                return false;
131
            }
132
            if ($obj->getAmount() > $storage[$commodityId]->getAmount()) {
133
                $game->addInformationf(
134
                    _('Es werden %s %s benötigt - Vorhanden sind nur %s'),
135
                    $obj->getAmount(),
136
                    $obj->getCommodity()->getName(),
137
                    $storage[$commodityId]->getAmount()
138
                );
139
                return false;
140
            }
141
        }
142
        foreach ($terraforming->getCosts() as $obj) {
143
            $this->colonyStorageManager->lowerStorage($colony, $obj->getCommodity(), $obj->getAmount());
144
        }
145
146
        $colony->lowerEps($terraforming->getEnergyCosts());
147
        $this->colonyRepository->save($colony);
148
        $time = time() + $terraforming->getDuration();
149
150
        $colonyTerraforming = $this->colonyTerraformingRepository->prototype();
151
        $colonyTerraforming->setColony($colony);
152
        $colonyTerraforming->setField($field);
153
        $colonyTerraforming->setTerraforming($terraforming);
154
        $colonyTerraforming->setFinishDate($time);
155
156
        $this->colonyTerraformingRepository->save($colonyTerraforming);
157
158
        $field->setTerraforming($terraforming);
159
160
        $game->addInformationf(
161
            _('%s wird durchgeführt - Fertigstellung: %s'),
162
            $terraforming->getDescription(),
163
            date('d.m.Y H:i', $time)
164
        );
165
166
        return true;
167
    }
168
169
    public function performSessionCheck(): bool
170
    {
171
        return true;
172
    }
173
}
174