Passed
Push — master ( 954430...fcf71b )
by Paweł
02:57
created

Player::getLevelProgress()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
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\Inventory;
21
use AardsGerds\Game\Inventory\Weapon\ShortSword\RustyShortSword;
22
use AardsGerds\Game\Inventory\Weapon\Weapon;
23
use AardsGerds\Game\Shared\IntegerValueException;
24
25
final class Player extends Entity
26
{
27 1
    public function __construct(
28
        string $name,
29
        Health $health,
30
        Etherum $etherum,
31
        Strength $strength,
32
        Initiative $initiative,
33
        TalentCollection $talentCollection,
34
        Inventory $inventory,
35
        ?Weapon $weapon,
36
        bool $corrupted,
37
        private LevelProgress $levelProgress,
38
        private AttributePoints $attributePoints,
39
        private TalentPoints $talentPoints,
40
    ) {
41 1
        parent::__construct(
42 1
            $name,
43
            $health,
44
            $etherum,
45
            $strength,
46
            $initiative,
47
            $talentCollection,
48
            $inventory,
49
            $weapon,
50
            $corrupted,
51
        );
52 1
    }
53
54
    public static function new(string $name): self
55
    {
56
        return new self(
57
            $name,
58
            new Health(100),
59
            new Etherum(1),
60
            new Strength(5),
61
            new Initiative(10),
62
            new TalentCollection([new Slash()]),
63
            new Inventory([]),
64
            new RustyShortSword(),
65
            false,
66
            new LevelProgress(
67
                new Level(1),
68
                new Experience(0),
69
            ),
70
            new AttributePoints(0),
71
            new TalentPoints(0),
72
        );
73
    }
74
75 1
    public function getLevelProgress(): LevelProgress
76
    {
77 1
        return $this->levelProgress;
78
    }
79
80
    public function increaseExperience(Experience $experience): void
81
    {
82
        $this->levelProgress->increase($experience, $this);
83
    }
84
85
    /**
86
     * @throws PlayerException
87
     */
88
    public function increaseEtherum(Etherum $etherum): void
89
    {
90
        $this->etherum->increaseBy($etherum);
91
92
        if ($this->isCorrupted()) {
93
            return;
94
        }
95
96
        $playerAscension = $this->talentCollection->findSecretKnowledge()?->getAscension()
97
            ?? throw PlayerException::etherumOverdose();
98
99
        $corruptionBoundary = $this->calculateCorruptionBoundary();
100
101
        if ($this->etherum->isGreaterThanOrEqual($corruptionBoundary)) {
102
            if ($playerAscension->isLowerThan(Ascension::sixthAscension())) {
103
                throw PlayerException::etherumOverdose();
104
            }
105
106
            $this->corrupted = true;
107
        }
108
    }
109
110 1
    public function getAttributePoints(): AttributePoints
111
    {
112 1
        return $this->attributePoints;
113
    }
114
115 1
    public function getTalentPoints(): TalentPoints
116
    {
117 1
        return $this->talentPoints;
118
    }
119
120
    private function calculateCorruptionBoundary(): Etherum
121
    {
122
        $ascension = $this->talentCollection->findSecretKnowledge()?->getAscension();
123
        if ($ascension === null) {
124
            return new Etherum(2);
125
        }
126
127
        try {
128
            $nextAscensionEtherum = $ascension->increment()->getRequiredEtherum();
129
        } catch (IntegerValueException $exception) {
130
            // entity has 8th ascension
131
            $nextAscensionEtherum = new Etherum($ascension->getRequiredEtherum()->get() * 2);
132
        }
133
134
        // etherum required by next ascension + 0.5 x etherum required by next ascension
135
        return $nextAscensionEtherum->increaseBy(
136
            new Etherum((int) ($nextAscensionEtherum->get() * 0.5)),
137
        );
138
    }
139
}
140