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

PlanetField   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 344
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 101
c 0
b 0
f 0
dl 0
loc 344
ccs 0
cts 122
cp 0
rs 6
wmc 55

37 Methods

Rating   Name   Duplication   Size   Complexity  
A getBuildingState() 0 6 2
A isUnderConstruction() 0 3 1
B getCssClass() 0 19 7
A getBuilding() 0 3 1
A setBuilding() 0 5 1
A hasBuilding() 0 3 1
A isDamaged() 0 9 3
A clearBuilding() 0 5 1
A getTerraformingId() 0 3 1
A getId() 0 3 1
A isActivateable() 0 9 3
A getTerraforming() 0 3 1
A setTerraforming() 0 5 1
A setColonySandbox() 0 4 1
A setIntegrity() 0 4 1
A getFieldType() 0 3 1
A setFieldId() 0 4 1
A getActivateAfterBuild() 0 3 1
A getPictureType() 0 3 1
A getBuildtime() 0 3 1
A setFieldType() 0 4 1
A getBuildingId() 0 3 1
A isColonizeAble() 0 3 1
A setActivateAfterBuild() 0 4 1
A setBuildMode() 0 3 1
A setColony() 0 4 1
A getConstructionStatusBar() 0 8 1
A isActive() 0 3 1
A getBuildProgress() 0 4 1
A getFieldId() 0 3 1
A getOverlayWidth() 0 5 1
A setActive() 0 4 1
A hasHighDamage() 0 6 2
A getHost() 0 10 4
A getDayNightPrefix() 0 9 4
A getActive() 0 3 1
A getIntegrity() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like PlanetField often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PlanetField, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Orm\Entity;
6
7
use Doctrine\ORM\Mapping\Column;
8
use Doctrine\ORM\Mapping\Entity;
9
use Doctrine\ORM\Mapping\GeneratedValue;
10
use Doctrine\ORM\Mapping\Id;
11
use Doctrine\ORM\Mapping\Index;
12
use Doctrine\ORM\Mapping\JoinColumn;
13
use Doctrine\ORM\Mapping\ManyToOne;
14
use Doctrine\ORM\Mapping\Table;
15
use RuntimeException;
16
use Stu\Module\Tal\StatusBarColorEnum;
17
use Stu\Module\Tal\TalStatusBar;
18
19
/**
20
 * @Entity(repositoryClass="Stu\Orm\Repository\PlanetFieldRepository")
21
 * @Table(
22
 *     name="stu_colonies_fielddata",
23
 *     indexes={
24
 *         @Index(name="colony_field_idx", columns={"colonies_id", "field_id"}),
25
 *         @Index(name="sandbox_field_idx", columns={"colony_sandbox_id", "field_id"}),
26
 *         @Index(name="colony_building_active_idx", columns={"colonies_id", "buildings_id", "aktiv"}),
27
 *         @Index(name="sandbox_building_active_idx", columns={"colony_sandbox_id", "buildings_id", "aktiv"}),
28
 *         @Index(name="active_idx", columns={"aktiv"})
29
 *     }
30
 * )
31
 **/
32
class PlanetField implements PlanetFieldInterface
33
{
34
    /**
35
     * @Id
36
     * @Column(type="integer")
37
     * @GeneratedValue(strategy="IDENTITY")
38
     *
39
     */
40
    private int $id;
41
42
    /**
43
     * @Column(type="integer", nullable=true)
44
     */
45
    private ?int $colonies_id = null;
0 ignored issues
show
introduced by
The private property $colonies_id is not used, and could be removed.
Loading history...
46
47
    /**
48
     * @Column(type="integer", nullable=true)
49
     */
50
    private ?int $colony_sandbox_id = null;
0 ignored issues
show
introduced by
The private property $colony_sandbox_id is not used, and could be removed.
Loading history...
51
52
    /**
53
     * @Column(type="smallint")
54
     *
55
     */
56
    private int $field_id = 0;
57
58
    /**
59
     * @Column(type="integer")
60
     *
61
     */
62
    private int $type_id = 0;
63
64
    /**
65
     * @Column(type="integer", nullable=true)
66
     *
67
     */
68
    private ?int $buildings_id = null;
69
70
    /**
71
     * @Column(type="integer", nullable=true)
72
     *
73
     */
74
    private ?int $terraforming_id = null;
75
76
    /**
77
     * @Column(type="smallint")
78
     *
79
     */
80
    private int $integrity = 0;
81
82
    /**
83
     * @Column(type="integer")
84
     *
85
     */
86
    private int $aktiv = 0;
87
88
    /**
89
     * @Column(type="boolean")
90
     *
91
     */
92
    private bool $activate_after_build = true;
93
94
    /**
95
     *
96
     * @ManyToOne(targetEntity="Building")
97
     * @JoinColumn(name="buildings_id", referencedColumnName="id")
98
     */
99
    private ?BuildingInterface $building = null;
100
101
    /**
102
     *
103
     * @ManyToOne(targetEntity="Terraforming")
104
     * @JoinColumn(name="terraforming_id", referencedColumnName="id")
105
     */
106
    private ?TerraformingInterface $terraforming = null;
107
108
    /**
109
     * @ManyToOne(targetEntity="Colony")
110
     * @JoinColumn(name="colonies_id", referencedColumnName="id", onDelete="CASCADE")
111
     */
112
    private ?ColonyInterface $colony = null;
113
114
    /**
115
     * @ManyToOne(targetEntity="ColonySandbox")
116
     * @JoinColumn(name="colony_sandbox_id", referencedColumnName="id", onDelete="CASCADE")
117
     */
118
    private ?ColonySandboxInterface $sandbox = null;
119
120
    private bool $buildmode = false;
121
122
    public function getId(): int
123
    {
124
        return $this->id;
125
    }
126
127
    public function getFieldId(): int
128
    {
129
        return $this->field_id;
130
    }
131
132
    public function setFieldId(int $fieldId): PlanetFieldInterface
133
    {
134
        $this->field_id = $fieldId;
135
        return $this;
136
    }
137
138
    public function getFieldType(): int
139
    {
140
        return $this->type_id;
141
    }
142
143
    public function setFieldType(int $planetFieldTypeId): PlanetFieldInterface
144
    {
145
        $this->type_id = $planetFieldTypeId;
146
        return $this;
147
    }
148
149
    public function getBuildingId(): ?int
150
    {
151
        return $this->buildings_id;
152
    }
153
154
    public function getTerraformingId(): ?int
155
    {
156
        return $this->terraforming_id;
157
    }
158
159
    public function getIntegrity(): int
160
    {
161
        return $this->integrity;
162
    }
163
164
    public function setIntegrity(int $integrity): PlanetFieldInterface
165
    {
166
        $this->integrity = $integrity;
167
        return $this;
168
    }
169
170
    public function getActive(): int
171
    {
172
        return $this->aktiv;
173
    }
174
175
    public function setActive(int $aktiv): PlanetFieldInterface
176
    {
177
        $this->aktiv = $aktiv;
178
        return $this;
179
    }
180
181
    public function getActivateAfterBuild(): bool
182
    {
183
        return $this->activate_after_build;
184
    }
185
186
    public function setActivateAfterBuild(bool $activateAfterBuild): PlanetFieldInterface
187
    {
188
        $this->activate_after_build = $activateAfterBuild;
189
        return $this;
190
    }
191
192
    public function setBuildMode(bool $value): void
193
    {
194
        $this->buildmode = $value;
195
    }
196
197
    public function getBuildtime(): int
198
    {
199
        return $this->getActive();
200
    }
201
202
    public function isActive(): bool
203
    {
204
        return $this->getActive() === 1;
205
    }
206
207
    public function isActivateable(): bool
208
    {
209
        if ($this->hasBuilding() === false) {
210
            return false;
211
        }
212
        if ($this->isUnderConstruction()) {
213
            return false;
214
        }
215
        return $this->getBuilding()->isActivateable();
216
    }
217
218
    public function hasHighDamage(): bool
219
    {
220
        if (!$this->isDamaged()) {
221
            return false;
222
        }
223
        return round((100 / $this->getBuilding()->getIntegrity()) * $this->getIntegrity()) < 50;
224
    }
225
226
    public function isUnderConstruction(): bool
227
    {
228
        return $this->getActive() > 1;
229
    }
230
231
    public function hasBuilding(): bool
232
    {
233
        return $this->getBuilding() !== null;
234
    }
235
236
    public function getCssClass(): string
237
    {
238
        if ($this->buildmode === true) {
239
            return 'cfb';
240
        }
241
        if ($this->isActive()) {
242
            if ($this->isDamaged()) {
243
                return 'cfld';
244
            }
245
            return 'cfa';
246
        }
247
        if ($this->hasHighDamage()) {
248
            return 'cfhd';
249
        }
250
        if ($this->hasBuilding() && $this->isActivateable()) {
251
            return 'cfd';
252
        }
253
254
        return 'cfu';
255
    }
256
257
    public function getBuildingState(): string
258
    {
259
        if ($this->isUnderConstruction()) {
260
            return 'b';
261
        }
262
        return 'a';
263
    }
264
265
    public function getBuilding(): ?BuildingInterface
266
    {
267
        return $this->building;
268
    }
269
270
    public function setBuilding(?BuildingInterface $building): PlanetFieldInterface
271
    {
272
        $this->building = $building;
273
274
        return $this;
275
    }
276
277
    public function isDamaged(): bool
278
    {
279
        if (!$this->hasBuilding()) {
280
            return false;
281
        }
282
        if ($this->isUnderConstruction()) {
283
            return false;
284
        }
285
        return $this->getIntegrity() !== $this->getBuilding()->getIntegrity();
286
    }
287
288
    public function clearBuilding(): void
289
    {
290
        $this->setBuilding(null);
291
        $this->setIntegrity(0);
292
        $this->setActive(0);
293
    }
294
295
    public function getHost(): ColonyInterface|ColonySandboxInterface
296
    {
297
        $colony = $this->colony;
298
        $sandbox = $this->sandbox;
299
300
        if ($colony === null && $sandbox === null) {
301
            throw new RuntimeException('this should not happen');
302
        }
303
304
        return $colony === null ? $sandbox : $colony;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $colony === null ? $sandbox : $colony could return the type null which is incompatible with the type-hinted return Stu\Orm\Entity\ColonyInt...\ColonySandboxInterface. Consider adding an additional type-check to rule them out.
Loading history...
305
    }
306
307
    public function setColony(ColonyInterface $colony): PlanetFieldInterface
308
    {
309
        $this->colony = $colony;
310
        return $this;
311
    }
312
313
    public function setColonySandbox(ColonySandboxInterface $sandbox): PlanetFieldInterface
314
    {
315
        $this->sandbox = $sandbox;
316
        return $this;
317
    }
318
319
    public function getTerraforming(): ?TerraformingInterface
320
    {
321
        return $this->terraforming;
322
    }
323
324
    public function setTerraforming(?TerraformingInterface $terraforming): PlanetFieldInterface
325
    {
326
        $this->terraforming = $terraforming;
327
328
        return $this;
329
    }
330
331
    public function getDayNightPrefix(): string
332
    {
333
        $twilightZone = $this->getHost()->getTwilightZone();
334
335
        if ($twilightZone >= 0) {
336
            return $this->getFieldId() % $this->getHost()->getSurfaceWidth() >= $twilightZone ? 'n' : 't';
337
        }
338
339
        return $this->getFieldId() % $this->getHost()->getSurfaceWidth() < -$twilightZone ? 'n' : 't';
340
    }
341
342
    public function getBuildProgress(): int
343
    {
344
        $start = $this->getBuildtime() - $this->getBuilding()->getBuildTime();
345
        return time() - $start;
346
    }
347
348
    public function getOverlayWidth(): int
349
    {
350
        $buildtime = $this->getBuilding()->getBuildtime();
351
        $perc = max(0, @round((100 / $buildtime) * min($this->getBuildProgress(), $buildtime)));
352
        return (int) round((40 / 100) * $perc);
353
    }
354
355
    public function getPictureType(): string
356
    {
357
        return $this->getBuildingId() . "/" . $this->getBuilding()->getBuildingType() . $this->getBuildingState();
358
    }
359
360
    public function isColonizeAble(): bool
361
    {
362
        return in_array($this->getFieldType(), $this->getHost()->getColonyClass()->getColonizeableFields());
363
    }
364
365
    /**
366
     * @todo temporary, remove it.
367
     */
368
    public function getConstructionStatusBar(): string
369
    {
370
        return (new TalStatusBar())
371
            ->setColor(StatusBarColorEnum::STATUSBAR_GREEN)
372
            ->setLabel(_('Fortschritt'))
373
            ->setMaxValue($this->getBuilding()->getBuildtime())
374
            ->setValue($this->getBuildProgress())
375
            ->render();
376
    }
377
}
378