Passed
Push — master ( daadce...90a788 )
by Paweł
02:56
created

Player::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 4
Bugs 0 Features 1
Metric Value
eloc 10
c 4
b 0
f 1
dl 0
loc 25
ccs 3
cts 3
cp 1
rs 9.9332
cc 1
nc 1
nop 13
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace AardsGerds\Game\Player;
6
7
use AardsGerds\Game\Build\Attribute\AttributePoints;
8
use AardsGerds\Game\Build\Attribute\Etherum;
9
use AardsGerds\Game\Build\Attribute\Health;
10
use AardsGerds\Game\Build\Attribute\Initiative;
11
use AardsGerds\Game\Build\Attribute\Strength;
12
use AardsGerds\Game\Build\Experience;
13
use AardsGerds\Game\Build\Level;
14
use AardsGerds\Game\Build\LevelProgress;
15
use AardsGerds\Game\Build\Talent\SecretKnowledge\Ascension;
16
use AardsGerds\Game\Build\Talent\TalentCollection;
17
use AardsGerds\Game\Build\Talent\TalentPoints;
18
use AardsGerds\Game\Build\Talent\WeaponMastery\ShortSword\Novice\Slash;
19
use AardsGerds\Game\Entity\Entity;
20
use AardsGerds\Game\Inventory\Alchemy\Potion\HealthPotion;
21
use AardsGerds\Game\Inventory\Inventory;
22
use AardsGerds\Game\Inventory\Weapon\ShortSword\RustyShortSword;
23
use AardsGerds\Game\Inventory\Weapon\Weapon;
24
use AardsGerds\Game\Shared\IntegerValueException;
25
26
final class Player extends Entity
27
{
28 1
    public function __construct(
29
        string $name,
30
        Health $health,
31
        Etherum $etherum,
32
        Strength $strength,
33
        Initiative $initiative,
34
        TalentCollection $talentCollection,
35
        Inventory $inventory,
36
        ?Weapon $weapon,
37
        bool $corrupted,
38
        private LevelProgress $levelProgress,
39
        private Health $maximumHealth,
40
        private AttributePoints $attributePoints,
41
        private TalentPoints $talentPoints,
42
    ) {
43 1
        parent::__construct(
44 1
            $name,
45
            $health,
46
            $etherum,
47
            $strength,
48
            $initiative,
49
            $talentCollection,
50
            $inventory,
51
            $weapon,
52
            $corrupted,
53
        );
54 1
    }
55
56
    public static function new(string $name): self
57
    {
58
        return new self(
59
            $name,
60
            new Health(100),
61
            new Etherum(1),
62
            new Strength(5),
63
            new Initiative(10),
64
            new TalentCollection([new Slash()]),
65
            new Inventory([new HealthPotion(), new HealthPotion()]),
66
            new RustyShortSword(),
67
            false,
68
            new LevelProgress(
69
                new Level(1),
70
                new Experience(0),
71
            ),
72
            new Health(100),
73
            new AttributePoints(0),
74
            new TalentPoints(0),
75
        );
76
    }
77
78 1
    public function getLevelProgress(): LevelProgress
79
    {
80 1
        return $this->levelProgress;
81
    }
82
83
    public function increaseExperience(Experience $experience, PlayerAction $playerAction): void
84
    {
85
        $this->levelProgress->increase($experience, $this, $playerAction);
86
    }
87
88 1
    public function getMaximumHealth(): Health
89
    {
90 1
        return $this->maximumHealth;
91
    }
92
93 1
    public function getAttributePoints(): AttributePoints
94
    {
95 1
        return $this->attributePoints;
96
    }
97
98 1
    public function getTalentPoints(): TalentPoints
99
    {
100 1
        return $this->talentPoints;
101
    }
102
103
    public function heal(Health $health): void
104
    {
105
        $this->health->increaseBy($health);
106
107
        if ($this->health->isGreaterThan($this->maximumHealth)) {
108
            $this->healCompletely();
109
        }
110
    }
111
112
    public function healCompletely(): void
113
    {
114
        $this->health->replaceWith($this->maximumHealth);
115
    }
116
117
    /**
118
     * @throws PlayerException
119
     */
120
    public function increaseEtherum(Etherum $etherum): void
121
    {
122
        $this->etherum->increaseBy($etherum);
123
124
        if ($this->isCorrupted()) {
125
            return;
126
        }
127
128
        $playerAscension = $this->talentCollection->findSecretKnowledge()?->getAscension()
129
            ?? throw PlayerException::etherumOverdose();
130
131
        $corruptionBoundary = $this->calculateCorruptionBoundary();
132
133
        if ($this->etherum->isGreaterThanOrEqual($corruptionBoundary)) {
134
            if ($playerAscension->isLowerThan(Ascension::sixthAscension())) {
135
                throw PlayerException::etherumOverdose();
136
            }
137
138
            $this->corrupted = true;
139
        }
140
    }
141
142
    private function calculateCorruptionBoundary(): Etherum
143
    {
144
        $ascension = $this->talentCollection->findSecretKnowledge()?->getAscension();
145
        if ($ascension === null) {
146
            return new Etherum(2);
147
        }
148
149
        try {
150
            $nextAscensionEtherum = $ascension->increment()->getRequiredEtherum();
151
        } catch (IntegerValueException $exception) {
152
            // entity has 8th ascension
153
            $nextAscensionEtherum = new Etherum($ascension->getRequiredEtherum()->get() * 2);
154
        }
155
156
        // etherum required by next ascension + 0.5 x etherum required by next ascension
157
        return $nextAscensionEtherum->increaseBy(
158
            new Etherum((int) ($nextAscensionEtherum->get() * 0.5)),
159
        );
160
    }
161
}
162