Passed
Push — master ( 955384...f3a3f5 )
by Paweł
11:23
created

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