Issues (8)

src/Fight/Clash.php (1 issue)

Labels
Severity
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 5
    public static function invoke(
18
        Fighter $attacker,
19
        Fighter $target,
20
        Attack $attack,
21
        PlayerAction $playerAction,
22
    ): void {
23 5
        if (self::blockOccurred($attacker, $target, $attack)) {
24 2
            $playerAction->tell("{$attacker->getName()} uses {$attack}, but {$target->getName()} has blocked this attack.");
25 2
            return;
26
        }
27
28 5
        $damage = self::calculateDamage($attacker, $attack);
29
30
        try {
31 5
            $target->getHealth()->decreaseBy($damage);
32 5
        } catch (IntegerValueException $exception) {
33 5
            $playerAction->tell("{$attacker->getName()} uses {$attack} and deals {$damage} damage, which brings opponent to their knees!");
34 5
            throw $exception;
35
        }
36
37 3
        $playerAction->tell("{$attacker->getName()} uses {$attack} and deals {$damage} damage.");
38 3
    }
39
40 5
    private static function calculateDamage(
41
        Fighter $attacker,
42
        Attack $attack,
43
    ): Damage {
44
        return match (true) {
45 5
            $attack instanceof MeleeAttack =>
46 5
                (new Damage(0))
47 5
                    ->increaseBy($attack->getDamage($attacker->getWeapon() ?? throw FightException::weaponRequired()))
0 ignored issues
show
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 5
                    ->increaseBy($attacker->getStrength()),
49 1
            $attack instanceof EtherumAttack => $attack->getDamage(),
50 1
            $attack instanceof NaturalAttack =>
51 1
                (new Damage(0))
52 1
                    ->increaseBy($attack->getDamage())
53 1
                    ->increaseBy($attacker->getStrength()),
54 5
            default => new Damage(0),
55
        };
56
    }
57
58 5
    private static function blockOccurred(
59
        Fighter $attacker,
60
        Fighter $target,
61
        Attack $attack,
62
    ): bool {
63 5
        return Dice::roll(Block::calculateChance($attacker, $target, $attack));
64
    }
65
}
66