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

Player   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Test Coverage

Coverage 21.05%

Importance

Changes 8
Bugs 0 Features 1
Metric Value
wmc 19
eloc 61
c 8
b 0
f 1
dl 0
loc 148
ccs 12
cts 57
cp 0.2105
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getLevelProgress() 0 3 1
A heal() 0 6 2
A getCheckpoint() 0 3 1
A healCompletely() 0 3 1
A new() 0 23 1
A increaseExperience() 0 3 1
A calculateCorruptionBoundary() 0 17 3
A getTalentPoints() 0 3 1
A setCheckpoint() 0 3 1
A getAttributePoints() 0 3 1
A __construct() 0 26 1
A increaseEtherum() 0 19 4
A getMaximumHealth() 0 3 1
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