Passed
Push — master ( af53cd...6ad387 )
by Paweł
03:49
created

Clash::occurred()   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
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AardsGerds\Game\Fight;
6
7
use AardsGerds\Game\Build\Attribute\Damage;
8
use AardsGerds\Game\Player\PlayerAction;
9
use AardsGerds\Game\Shared\Dice;
10
use AardsGerds\Game\Shared\IntegerValueException;
11
12
final class Clash
13
{
14
    /**
15
     * @throws IntegerValueException if target's health hits 0
16
     */
17
    public static function invoke(
18
        Fighter $attacker,
19
        Fighter $target,
20
        Attack $attack,
21
        PlayerAction $playerAction,
22
    ): void {
23
        if (self::blockOccurred($attacker, $target, $attack)) {
24
            $playerAction->tell("{$attacker->getName()} uses {$attack}, but {$target->getName()} has blocked this attack.");
25
            return;
26
        }
27
28
        $damage = self::calculateDamage($attacker, $attack);
29
30
        try {
31
            $target->getHealth()->decreaseBy($damage);
32
        } catch (IntegerValueException $exception) {
33
            $playerAction->tell("{$attacker->getName()} uses {$attack} and deals {$damage} damage, which brings opponent to their knees!");
34
            throw $exception;
35
        }
36
37
        $playerAction->tell("{$attacker->getName()} uses {$attack} and deals {$damage} damage.");
38
    }
39
40
    private static function calculateDamage(
41
        Fighter $attacker,
42
        Attack $attack,
43
    ): Damage {
44
        return match (true) {
45
            $attack instanceof MeleeAttack =>
46
                (new Damage(0))
47
                    ->increaseBy($attack->getDamage($attacker->getWeapon() ?? throw FightException::weaponRequired()))
0 ignored issues
show
Bug introduced by
The method getDamage() does not exist on AardsGerds\Game\Fight\Attack. Since it exists in all sub-types, consider adding an abstract or default implementation to AardsGerds\Game\Fight\Attack. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

47
                    ->increaseBy($attack->/** @scrutinizer ignore-call */ getDamage($attacker->getWeapon() ?? throw FightException::weaponRequired()))
Loading history...
48
                    ->increaseBy($attacker->getStrength()),
49
            $attack instanceof EtherumAttack => $attack->getDamage(),
50
            $attack instanceof NaturalAttack =>
51
                (new Damage(0))
52
                    ->increaseBy($attack->getDamage())
53
                    ->increaseBy($attacker->getStrength()),
54
            default => new Damage(0),
55
        };
56
    }
57
58
    private static function blockOccurred(
59
        Fighter $attacker,
60
        Fighter $target,
61
        Attack $attack,
62
    ): bool {
63
        return Dice::roll(Block::calculateChance($attacker, $target, $attack));
64
    }
65
}
66