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

Player::healCompletely()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
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