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

ColonyPopulationCalculator::getGrowth()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 7
eloc 13
c 2
b 1
f 0
nc 10
nop 0
dl 0
loc 23
ccs 0
cts 14
cp 0
crap 56
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Component\Colony;
6
7
use RuntimeException;
8
use Stu\Component\Faction\FactionEnum;
9
use Stu\Lib\Colony\PlanetFieldHostInterface;
10
use Stu\Lib\ColonyProduction\ColonyProduction;
11
use Stu\Module\Commodity\CommodityTypeEnum;
12
use Stu\Orm\Entity\ColonyInterface;
13
14
final class ColonyPopulationCalculator implements ColonyPopulationCalculatorInterface
15
{
16
    private PlanetFieldHostInterface $host;
17
18
    private ?int $positive_effect_secondary = null;
19
20
    private ?int $positive_effect_primary = null;
21
22
    /** @var array<int, ColonyProduction> */
23
    private array $production;
24
25
    /**
26
     * @param array<int, ColonyProduction> $production
27
     */
28
    public function __construct(
29
        PlanetFieldHostInterface $host,
30
        array $production
31
    ) {
32
        $this->host = $host;
33
        $this->production = $production;
34
    }
35
36
    public function getFreeAssignmentCount(): int
37
    {
38
        if (!$this->host instanceof ColonyInterface) {
39
            return 0;
40
        }
41
42
        return max(0, $this->getCrewLimit() - $this->host->getCrewAssignmentAmount());
0 ignored issues
show
Bug introduced by
The method getCrewAssignmentAmount() does not exist on Stu\Lib\Colony\PlanetFieldHostInterface. It seems like you code against a sub-type of Stu\Lib\Colony\PlanetFieldHostInterface such as Stu\Orm\Entity\ColonyInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

42
        return max(0, $this->getCrewLimit() - $this->host->/** @scrutinizer ignore-call */ getCrewAssignmentAmount());
Loading history...
43
    }
44
45
    public function getCrewLimit(): int
46
    {
47
        return (int) floor(
48
            10 +
49
                min(
50
                    max(
51
                        ($this->getPositiveEffectPrimary() - (4 * max(
52
                            0,
53
                            $this->getNegativeEffect() - $this->getPositiveEffectSecondary()
54
                        ))),
55
                        0
56
                    ),
57
                    $this->host->getWorkers()
58
                ) / 5 * $this->getLifeStandardPercentage() / 100
59
        );
60
    }
61
62
    public function getLifeStandardPercentage(): int
63
    {
64
        $colonyProduction = $this->production[CommodityTypeEnum::COMMODITY_EFFECT_LIFE_STANDARD] ?? null;
65
        $production = $colonyProduction !== null ? $colonyProduction->getProduction() : 0;
66
67
        if ($production == 0) {
68
            return 0;
69
        }
70
71
        if ($production > $this->host->getPopulation()) {
72
            return 100;
73
        }
74
75
        return (int)floor($production * 100 / $this->host->getPopulation());
76
    }
77
78
    public function getNegativeEffect(): int
79
    {
80
        return (int) ceil($this->host->getPopulation() / 70);
81
    }
82
83
    public function getPositiveEffectPrimary(): int
84
    {
85
        if ($this->positive_effect_primary === null) {
86
            // TODO we should use a faction-factory...
87
            switch ($this->host->getUser()->getFactionId()) {
88
                case FactionEnum::FACTION_FEDERATION:
89
                    $key = ColonyEnum::COMMODITY_SATISFACTION_FED_PRIMARY;
90
                    break;
91
                case FactionEnum::FACTION_ROMULAN:
92
                    $key = ColonyEnum::COMMODITY_SATISFACTION_ROMULAN_PRIMARY;
93
                    break;
94
                case FactionEnum::FACTION_KLINGON:
95
                    $key = ColonyEnum::COMMODITY_SATISFACTION_KLINGON_PRIMARY;
96
                    break;
97
                case FactionEnum::FACTION_CARDASSIAN:
98
                    $key = ColonyEnum::COMMODITY_SATISFACTION_CARDASSIAN_PRIMARY;
99
                    break;
100
                case FactionEnum::FACTION_FERENGI:
101
                    $key = ColonyEnum::COMMODITY_SATISFACTION_FERENGI_PRIMARY;
102
                    break;
103
                default:
104
                    throw new RuntimeException('faction id is not configured');
105
            }
106
            $this->positive_effect_primary = 0;
107
            if (!array_key_exists($key, $this->production)) {
108
                return 0;
109
            }
110
            $this->positive_effect_primary += $this->production[$key]->getProduction();
111
        }
112
        return $this->positive_effect_primary;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->positive_effect_primary could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
113
    }
114
115
    public function getPositiveEffectSecondary(): int
116
    {
117
        if ($this->positive_effect_secondary === null) {
118
            $this->positive_effect_secondary = 0;
119
            // XXX we should use a faction-factory...
120
            switch ($this->host->getUser()->getFactionId()) {
121
                case FactionEnum::FACTION_FEDERATION:
122
                    $key = ColonyEnum::COMMODITY_SATISFACTION_FED_SECONDARY;
123
                    break;
124
                case FactionEnum::FACTION_ROMULAN:
125
                    $key = ColonyEnum::COMMODITY_SATISFACTION_ROMULAN_SECONDARY;
126
                    break;
127
                case FactionEnum::FACTION_KLINGON:
128
                    $key = ColonyEnum::COMMODITY_SATISFACTION_KLINGON_SECONDARY;
129
                    break;
130
                case FactionEnum::FACTION_CARDASSIAN:
131
                    $key = ColonyEnum::COMMODITY_SATISFACTION_CARDASSIAN_SECONDARY;
132
                    break;
133
                case FactionEnum::FACTION_FERENGI:
134
                    $key = ColonyEnum::COMMODITY_SATISFACTION_FERENGI_SECONDARY;
135
                    break;
136
                default:
137
                    throw new RuntimeException('faction id is not configured');
138
            }
139
            if (!array_key_exists($key, $this->production)) {
140
                return 0;
141
            }
142
            $this->positive_effect_secondary += $this->production[$key]->getProduction();
143
        }
144
        return $this->positive_effect_secondary;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->positive_effect_secondary could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
145
    }
146
147
    public function getGrowth(): int
148
    {
149
        $host = $this->host;
150
        if (!$host instanceof ColonyInterface) {
151
            return 0;
152
        }
153
154
        if ($host->getImmigrationState() === false) {
155
            return 0;
156
        }
157
158
        // TBD: depends on social things. return dummy for now
159
        $im = ceil((($host->getMaxBev() - $host->getPopulation()) / 3) / 100 * $host->getColonyClass()->getBevGrowthRate() *  $this->getLifeStandardPercentage() / 50);
160
        if ($host->getPopulation() + $im > $host->getMaxBev()) {
161
            $im = $host->getMaxBev() - $host->getPopulation();
162
        }
163
        if ($host->getPopulationLimit() > 0 && $host->getPopulation() + $im > $host->getPopulationLimit()) {
164
            $im = $host->getPopulationLimit() - $host->getPopulation();
165
        }
166
        if ($im < 0) {
167
            return 0;
168
        }
169
        return (int) $im;
170
    }
171
172
    public function getPositiveEffectPrimaryDescription(): string
173
    {
174
        switch ($this->host->getUser()->getFactionId()) {
175
            case FactionEnum::FACTION_FEDERATION:
176
                return _('Zufriedenheit');
177
            case FactionEnum::FACTION_ROMULAN:
178
                return _('Loyalität');
179
            case FactionEnum::FACTION_KLINGON:
180
                return _('Ehre');
181
            case FactionEnum::FACTION_CARDASSIAN:
182
                return _('Stolz');
183
            case FactionEnum::FACTION_FERENGI:
184
                return _('Wohlstand');
185
        }
186
        return '';
187
    }
188
189
    public function getPositiveEffectSecondaryDescription(): string
190
    {
191
        switch ($this->host->getUser()->getFactionId()) {
192
            case FactionEnum::FACTION_FEDERATION:
193
                return _('Bildung');
194
            case FactionEnum::FACTION_ROMULAN:
195
                return _('Imperiales Gedankengut');
196
            case FactionEnum::FACTION_KLINGON:
197
                return _('Kampftraining');
198
            case FactionEnum::FACTION_CARDASSIAN:
199
                return _('Patriotismus');
200
            case FactionEnum::FACTION_FERENGI:
201
                return _('Profitgier');
202
        }
203
        return '';
204
    }
205
206
    public function getNegativeEffectDescription(): string
207
    {
208
        switch ($this->host->getUser()->getFactionId()) {
209
            case FactionEnum::FACTION_FEDERATION:
210
            case FactionEnum::FACTION_ROMULAN:
211
            case FactionEnum::FACTION_KLINGON:
212
            case FactionEnum::FACTION_CARDASSIAN:
213
            case FactionEnum::FACTION_FERENGI:
214
                return _('Bevölkerungsdichte');
215
        }
216
        return '';
217
    }
218
}
219