SkillAttack::doSingleAttack()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 15
c 1
b 0
f 1
dl 0
loc 23
rs 9.7666
ccs 15
cts 15
cp 1
cc 3
nc 4
nop 4
crap 3
1
<?php
2
declare(strict_types=1);
3
4
namespace HeroesofAbenez\Combat\CombatActions;
5
6
use HeroesofAbenez\Combat\Character;
7
use HeroesofAbenez\Combat\CombatBase;
8
use HeroesofAbenez\Combat\CharacterAttackSkill;
9
use HeroesofAbenez\Combat\ICombatAction;
10
use HeroesofAbenez\Combat\SkillAttack as Skill;
11
use HeroesofAbenez\Combat\NotImplementedException;
12
use Nexendrie\Utils\Numbers;
13
14 1
final class SkillAttack implements ICombatAction
15
{
16
    public const ACTION_NAME = "skill_attack";
17
18
    public function getName(): string
19
    {
20 1
        return self::ACTION_NAME;
21
    }
22
23
    public function getPriority(): int
24
    {
25 1
        return 1001;
26
    }
27
28
    public function shouldUse(CombatBase $combat, Character $character): bool
29
    {
30
        $attackTarget = $combat->selectAttackTarget($character);
31
        if ($attackTarget === null) {
32
            return false;
33
        }
34
        if (count($character->usableSkills) < 1) {
35
            return false;
36
        }
37
        return ($character->usableSkills[0] instanceof CharacterAttackSkill);
38
    }
39
40
    private function doSingleAttack(
41
        Character $attacker,
42
        Character $defender,
43
        CharacterAttackSkill $skill,
44
        CombatBase $combat
45
    ): void {
46 1
        $result = [];
47 1
        $result["result"] = $combat->successCalculator->hasHit($attacker, $defender, $skill);
48 1
        $result["amount"] = 0;
49 1
        if ($result["result"]) {
50 1
            $amount = (int) (($attacker->damage - $defender->defense) / 100 * $skill->damage);
51 1
            $result["amount"] = Numbers::range($amount, 0, $defender->hitpoints);
52
        }
53 1
        if ($result["amount"] > 0) {
54 1
            $defender->harm($result["amount"]);
55
        }
56 1
        $result["action"] = $this->getName();
57 1
        $result["name"] = $skill->skill->name;
58 1
        $result["character1"] = $attacker;
59 1
        $result["character2"] = $defender;
60 1
        $combat->logDamage($attacker, $result["amount"]);
61 1
        $combat->log->log($result);
62 1
        $skill->resetCooldown();
63 1
    }
64
65
    /**
66
     * @throws NotImplementedException
67
     */
68
    public function do(CombatBase $combat, Character $character): void
69
    {
70
        /** @var CharacterAttackSkill $skill */
71 1
        $skill = $character->usableSkills[0];
72
        /** @var Character $primaryTarget */
73 1
        $primaryTarget = $combat->selectAttackTarget($character);
74 1
        $targets = match ($skill->skill->target) {
75 1
            Skill::TARGET_SINGLE => [$primaryTarget],
76
            Skill::TARGET_ROW => $combat->getTeam($primaryTarget)->getItems(["positionRow" => $primaryTarget->positionRow]),
0 ignored issues
show
introduced by
Line exceeds 120 characters; contains 124 characters
Loading history...
77
            Skill::TARGET_COLUMN => $combat->getTeam($primaryTarget)->getItems(["positionColumn" => $primaryTarget->positionColumn]),
0 ignored issues
show
introduced by
Line exceeds 120 characters; contains 133 characters
Loading history...
78
            default => throw new NotImplementedException("Target {$skill->skill->target} for attack skills is not implemented."),
0 ignored issues
show
introduced by
Line exceeds 120 characters; contains 129 characters
Loading history...
79
        };
80 1
        foreach ($targets as $target) {
81 1
            for ($i = 1; $i <= $skill->skill->strikes; $i++) {
82 1
                if ($target->hitpoints > 0) {
83 1
                    $this->doSingleAttack($character, $target, $skill, $combat);
84
                }
85
            }
86
        }
87 1
    }
88
}
89