Passed
Push — dev ( 6d75ea...915030 )
by Nico
13:24
created

ApplyDamage::handleCriticalHit()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 18
c 1
b 0
f 0
nc 4
nop 3
dl 0
loc 23
ccs 0
cts 17
cp 0
crap 20
rs 9.6666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Spacecraft\Lib\Damage;
6
7
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use RuntimeException;
9
use Stu\Component\Spacecraft\System\SpacecraftSystemManagerInterface;
10
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
11
use Stu\Lib\Damage\DamageModeEnum;
12
use Stu\Lib\Damage\DamageWrapper;
13
use Stu\Lib\Information\InformationInterface;
14
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
15
16
//TODO unit tests
17
final class ApplyDamage implements ApplyDamageInterface
18
{
19 1
    public function __construct(
20
        private SpacecraftSystemManagerInterface $spacecraftSystemManager,
21
        private SystemDamageInterface $systemDamage
22 1
    ) {}
23
24
    #[Override]
25
    public function damage(
26
        DamageWrapper $damageWrapper,
27
        SpacecraftWrapperInterface $wrapper,
28
        InformationInterface $informations
29
    ): void {
30
31
        if ($damageWrapper->getNetDamage() <= 0) {
32
            throw new RuntimeException('this should not happen');
33
        }
34
35
        $spacecraft = $wrapper->get();
36
37
        if ($spacecraft->isShielded()) {
38
39
            if ($damageWrapper->isShieldPenetration()) {
40
                $informations->addInformationf('- Projektil hat Schilde durchdrungen!');
41
            } else {
42
                $this->damageShields($wrapper, $damageWrapper, $informations);
43
            }
44
        }
45
        if ($damageWrapper->getNetDamage() <= 0) {
46
            return;
47
        }
48
49
        $disablemessage = false;
50
        $damage = (int) $damageWrapper->getDamageRelative($spacecraft, DamageModeEnum::HULL);
51
        $hull = $spacecraft->getCondition()->getHull();
52
        if ($spacecraft->getSystemState(SpacecraftSystemTypeEnum::RPG_MODULE) && $hull - $damage < round($spacecraft->getMaxHull() / 100 * 10)) {
53
            $damage = (int) round($hull - $spacecraft->getMaxHull() / 100 * 10);
54
            $disablemessage = _('-- Das Schiff wurde kampfunfähig gemacht');
55
            $spacecraft->getCondition()->setDisabled(true);
56
        }
57
        if ($hull > $damage) {
58
            $this->damageHull($wrapper, $damageWrapper, $damage, $informations);
59
60
            if ($disablemessage) {
61
                $informations->addInformation($disablemessage);
62
            }
63
        } else {
64
            $informations->addInformation("- Hüllenschaden: " . $damage);
65
            $informations->addInformation("-- Das Schiff wurde zerstört!");
66
            $spacecraft->getCondition()->setIsDestroyed(true);
67
        }
68
    }
69
70
    private function damageShields(SpacecraftWrapperInterface $wrapper, DamageWrapper $damageWrapper, InformationInterface $informations): void
71
    {
72
        $spacecraft = $wrapper->get();
73
        $condition = $spacecraft->getCondition();
74
75
        $damage = (int) $damageWrapper->getDamageRelative($spacecraft, DamageModeEnum::SHIELDS);
76
        if ($damage >= $condition->getShield()) {
77
            $informations->addInformation("- Schildschaden: " . $condition->getShield());
78
            $informations->addInformation("-- Schilde brechen zusammen!");
79
80
            $this->spacecraftSystemManager->deactivate($wrapper, SpacecraftSystemTypeEnum::SHIELDS);
81
82
            $condition->setShield(0);
83
        } else {
84
            $condition->setShield($condition->getShield() - $damage);
85
            $informations->addInformation("- Schildschaden: " . $damage . " - Status: " . $condition->getShield());
86
        }
87
88
        $shieldSystemData = $wrapper->getShieldSystemData();
89
        if ($shieldSystemData === null) {
90
            throw new RuntimeException('this should not happen');
91
        }
92
93
        $shieldSystemData->setShieldRegenerationTimer(time())->update();
94
    }
95
96
    private function damageHull(SpacecraftWrapperInterface $wrapper, DamageWrapper $damageWrapper, int $damage, InformationInterface $informations): void
97
    {
98
        $spacecraft = $wrapper->get();
99
        $condition = $spacecraft->getCondition();
100
101
        if ($damageWrapper->isCrit()) {
102
            $this->handleCriticalHit($wrapper, $damageWrapper, $informations);
103
        }
104
105
        $huelleVorher = $condition->getHull();
106
        $condition->changeHull(-$damage);
107
        $informations->addInformationf("- Hüllenschaden: %d - Status: %d", $damage, $condition->getHull());
108
109
        if (!$this->systemDamage->checkForDamagedShipSystems(
110
            $wrapper,
111
            $damageWrapper,
112
            $huelleVorher,
113
            $informations
114
        )) {
115
            $this->systemDamage->damageRandomShipSystem(
116
                $wrapper,
117
                $damageWrapper,
118
                $informations,
119
                (int)ceil((100 * $damage * random_int(1, 5)) / $spacecraft->getMaxHull())
120
            );
121
        }
122
    }
123
124
    private function handleCriticalHit(SpacecraftWrapperInterface $wrapper, DamageWrapper $damageWrapper, InformationInterface $informations): void
125
    {
126
        $spacecraft = $wrapper->get();
127
        $currentHull = $spacecraft->getCondition()->getHull();
128
        $maxHull = $spacecraft->getMaxHull();
129
        $hullPercentage = ($currentHull / $maxHull) * 100;
130
131
        if ($hullPercentage > 50) {
132
            $criticalDamage = random_int(30, 60);
133
            $this->systemDamage->damageRandomShipSystem($wrapper, $damageWrapper, $informations, $criticalDamage);
134
            $informations->addInformationf("- Kritischer Hüllen-Treffer verursacht %d%% Systemschaden", $criticalDamage);
135
        } else {
136
            $destructionChance = (50 - $hullPercentage) / 50;
137
138
            if (random_int(1, 100) <= ($destructionChance * 100)) {
139
                $systemName = $this->systemDamage->destroyRandomShipSystem($wrapper, $damageWrapper);
140
                if ($systemName !== null) {
141
                    $informations->addInformationf("- Kritischer Hüllen-Treffer zerstört System: %s", $systemName);
142
                }
143
            } else {
144
                $criticalDamage = random_int(50, 90);
145
                $this->systemDamage->damageRandomShipSystem($wrapper, $damageWrapper, $informations, $criticalDamage);
146
                $informations->addInformationf("- Kritischer Hüllen-Treffer verursacht %d%% Systemschaden", $criticalDamage);
147
            }
148
        }
149
    }
150
}
151