Passed
Push — master ( 90a788...d30360 )
by Paweł
02:57
created

Block::cannotBeBlocked()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AardsGerds\Game\Fight;
6
7
use AardsGerds\Game\Build\Talent\Effect\BlockImmunity;
8
9
final class Block
10
{
11
    private const MINIMAL_CHANCE = 0.1;
12
    private const MAXIMAL_CHANCE = 0.9;
13
14
    /**
15
     * Bonus per level of (advantage in) weapon mastery
16
     * For example: 6 level vs 0 level = 6 x 0.05 + 6 x 0.5 = 0.6
17
     */
18
    private const BONUS_FOR_WEAPON_MASTERY = 0.05;
19
20
    /**
21
     * Bonus per point of advantage in strength, limited to 100 points
22
     * For example: 150 points vs 50 points = 100 x 0.005 = 0.5
23
     */
24
    private const BONUS_FOR_STRENGTH = 0.005;
25
26
    /**
27
     * @example
28
     * attacker: 2 wm, 50 str
29
     * target: 4 wm, 80 str
30
     * bonus for wm: 4 x 0.05 = 0.2
31
     * bonus for advantage: 2 x 0.05 + 30 x 0.005 = 0.1 + 0.15 = 0.25
32
     * expected chance: minimal + bonuses = 0.1 + 0.2 + 0.25 = 0.55
33
     *
34
     * @example
35
     * attacker: 4 wm, 80 str
36
     * target: 2 wm, 50 str
37
     * bonus for wm: 2 x 0.05 = 0.1
38
     * bonus for advantage: 0
39
     * expected chance: minimal + bonuses = 0.1 + 0.1 = 0.2
40
     */
41 5
    public static function calculateChance(
42
        Fighter $attacker,
43
        Fighter $target,
44
        Attack $attack,
45
    ): float {
46 5
        if (self::cannotBeBlocked($attack)) {
47 2
            return 0;
48
        }
49
50 3
        $chance = self::MINIMAL_CHANCE;
51
52 3
        $bonusForWeaponMastery = $target->getWeaponMasteryLevel()->get() * self::BONUS_FOR_WEAPON_MASTERY;
53 3
        $chance += $bonusForWeaponMastery;
54
55 3
        if ($target->getWeaponMasteryLevel()->isGreaterThan($attacker->getWeaponMasteryLevel())) {
56 2
            $advantageInWeaponMastery = $target->getWeaponMasteryLevel()->diff($attacker->getWeaponMasteryLevel());
57 2
            $chance += $advantageInWeaponMastery->get() * self::BONUS_FOR_WEAPON_MASTERY;
58
        }
59
60 3
        if ($target->getStrength()->isGreaterThan($attacker->getStrength())) {
61 2
            $advantageInStrength = $target->getStrength()->diff($attacker->getStrength());
62 2
            $chance += $advantageInStrength->get() * self::BONUS_FOR_STRENGTH;
63
        }
64
65 3
        if ($chance > self::MAXIMAL_CHANCE) {
66 1
            $chance = self::MAXIMAL_CHANCE;
67
        }
68
69 3
        return $chance;
70
    }
71
72 5
    private static function cannotBeBlocked(Attack $attack): bool
73
    {
74 5
        return $attack->getEffects()->has(BlockImmunity::getName()) || $attack instanceof EtherumAttack;
75
    }
76
}
77