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

Player::increaseEtherum()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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