Test Failed
Push — master ( 41d27c...a3b7e3 )
by Paweł
03:17
created

Player::__construct()   A

Complexity

Conditions 1
Paths 1

Size

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