Passed
Pull Request — master (#1969)
by Janko
22:34 queued 10:03
created

ApplyDamage::damage()   C

Complexity

Conditions 13
Paths 154

Size

Total Lines 69
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 182

Importance

Changes 0
Metric Value
cc 13
eloc 41
nc 154
nop 3
dl 0
loc 69
ccs 0
cts 42
cp 0
crap 182
rs 6.1666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\SpacecraftSystemModeEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Spacecraft...pacecraftSystemModeEnum 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...
11
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
12
use Stu\Lib\Damage\DamageModeEnum;
13
use Stu\Lib\Damage\DamageWrapper;
14
use Stu\Lib\Information\InformationInterface;
15
use Stu\Lib\Information\InformationWrapper;
16
use Stu\Module\Colony\Lib\ColonyLibFactoryInterface;
17
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
18
use Stu\Orm\Entity\ColonyInterface;
19
use Stu\Orm\Entity\PlanetFieldInterface;
20
use Stu\Orm\Entity\SpacecraftSystemInterface;
21
22
//TODO unit tests and move to Lib/Damage
23
final class ApplyDamage implements ApplyDamageInterface
24
{
25 1
    public function __construct(
26
        private ColonyLibFactoryInterface $colonyLibFactory,
27
        private SpacecraftSystemManagerInterface $spacecraftSystemManager
28 1
    ) {}
29
30
    #[Override]
31
    public function damage(
32
        DamageWrapper $damageWrapper,
33
        SpacecraftWrapperInterface $shipWrapper,
34
        InformationInterface $informations
35
    ): void {
36
37
        if ($damageWrapper->getNetDamage() <= 0) {
38
            throw new RuntimeException('this should not happen');
39
        }
40
41
        $ship = $shipWrapper->get();
42
43
        if ($ship->getShieldState()) {
44
45
            if ($damageWrapper->isShieldPenetration()) {
46
                $informations->addInformationf('- Projektil hat Schilde durchdrungen!');
47
            } else {
48
                $this->damageShields($shipWrapper, $damageWrapper, $informations);
49
            }
50
        }
51
        if ($damageWrapper->getNetDamage() <= 0) {
52
            return;
53
        }
54
55
        $disablemessage = false;
56
        $damage = (int) $damageWrapper->getDamageRelative($ship, DamageModeEnum::HULL);
57
        if ($ship->getSystemState(SpacecraftSystemTypeEnum::SYSTEM_RPG_MODULE) && $ship->getHull() - $damage < round($ship->getMaxHull() / 100 * 10)) {
58
            $damage = (int) round($ship->getHull() - $ship->getMaxHull() / 100 * 10);
59
            $disablemessage = _('-- Das Schiff wurde kampfunfähig gemacht');
60
            $ship->setDisabled(true);
61
        }
62
        if ($ship->getHull() > $damage) {
63
            if ($damageWrapper->isCrit()) {
64
                $systemName = $this->destroyRandomShipSystem($shipWrapper);
65
66
                if ($systemName !== null) {
67
                    $informations->addInformation("- Kritischer Hüllen-Treffer zerstört System: " . $systemName);
68
                }
69
            }
70
            $huelleVorher = $ship->getHull();
71
            $ship->setHuell($huelleVorher - $damage);
72
            $informations->addInformation("- Hüllenschaden: " . $damage . " - Status: " . $ship->getHull());
73
74
            if (!$this->checkForDamagedShipSystems(
75
                $shipWrapper,
76
                $huelleVorher,
77
                $informations
78
            )) {
79
                $this->damageRandomShipSystem(
80
                    $shipWrapper,
81
                    $informations,
82
                    (int)ceil((100 * $damage * random_int(1, 5)) / $ship->getMaxHull())
83
                );
84
            }
85
86
            if ($disablemessage) {
87
                $informations->addInformation($disablemessage);
88
            }
89
90
            if ($ship->isDestroyed()) {
91
                $informations->addInformation("-- Das Schiff wurde zerstört!");
92
            }
93
94
            return;
95
        }
96
        $informations->addInformation("- Hüllenschaden: " . $damage);
97
        $informations->addInformation("-- Das Schiff wurde zerstört!");
98
        $ship->setIsDestroyed(true);
99
    }
100
101
    private function damageShields(SpacecraftWrapperInterface $wrapper, DamageWrapper $damageWrapper, InformationInterface $informations): void
102
    {
103
        $ship = $wrapper->get();
104
105
        $damage = (int) $damageWrapper->getDamageRelative($ship, DamageModeEnum::SHIELDS);
106
        if ($damage >= $ship->getShield()) {
107
            $informations->addInformation("- Schildschaden: " . $ship->getShield());
108
            $informations->addInformation("-- Schilde brechen zusammen!");
109
110
            $this->spacecraftSystemManager->deactivate($wrapper, SpacecraftSystemTypeEnum::SYSTEM_SHIELDS);
111
112
            $ship->setShield(0);
113
        } else {
114
            $ship->setShield($ship->getShield() - $damage);
115
            $informations->addInformation("- Schildschaden: " . $damage . " - Status: " . $ship->getShield());
116
        }
117
118
        $ship->setShieldRegenerationTimer(time());
119
    }
120
121
    #[Override]
122
    public function damageBuilding(
123
        DamageWrapper $damageWrapper,
124
        PlanetFieldInterface $target,
125
        bool $isOrbitField
126
    ): InformationWrapper {
127
        $informations = new InformationWrapper();
128
129
        $colony = $target->getHost();
130
        if (!$colony instanceof ColonyInterface) {
131
            throw new RuntimeException('this should not happen');
132
        }
133
134
        if (!$isOrbitField && $this->colonyLibFactory->createColonyShieldingManager($colony)->isShieldingEnabled()) {
135
            $damage = (int) $damageWrapper->getDamageRelative($colony, DamageModeEnum::SHIELDS);
136
            if ($damage > $colony->getShields()) {
137
                $informations->addInformation("- Schildschaden: " . $colony->getShields());
138
                $informations->addInformation("-- Schilde brechen zusammen!");
139
140
                $colony->setShields(0);
141
            } else {
142
                $colony->setShields($colony->getShields() - $damage);
143
                $informations->addInformation("- Schildschaden: " . $damage . " - Status: " . $colony->getShields());
144
            }
145
        }
146
        if ($damageWrapper->getNetDamage() <= 0) {
147
            return $informations;
148
        }
149
        $damage = (int) $damageWrapper->getDamageRelative($colony, DamageModeEnum::HULL);
150
        if ($target->getIntegrity() > $damage) {
151
            $target->setIntegrity($target->getIntegrity() - $damage);
152
            $informations->addInformation("- Gebäudeschaden: " . $damage . " - Status: " . $target->getIntegrity());
153
154
            return $informations;
155
        }
156
        $informations->addInformation("- Gebäudeschaden: " . $damage);
157
        $informations->addInformation("-- Das Gebäude wurde zerstört!");
158
        $target->setIntegrity(0);
159
160
        return $informations;
161
    }
162
163
    private function checkForDamagedShipSystems(
164
        SpacecraftWrapperInterface $wrapper,
165
        int $huelleVorher,
166
        InformationInterface $informations
167
    ): bool {
168
        $ship = $wrapper->get();
169
        $systemsToDamage = ceil($huelleVorher * 6 / $ship->getMaxHull()) -
170
            ceil($ship->getHull() * 6 / $ship->getMaxHull());
171
172
        if ($systemsToDamage == 0) {
173
            return false;
174
        }
175
176
        for ($i = 1; $i <= $systemsToDamage; $i++) {
177
            $this->damageRandomShipSystem($wrapper, $informations);
178
        }
179
180
        return true;
181
    }
182
183
    private function destroyRandomShipSystem(SpacecraftWrapperInterface $wrapper): ?string
184
    {
185
        $healthySystems = $wrapper->get()->getHealthySystems();
186
        shuffle($healthySystems);
187
188
        if ($healthySystems === []) {
189
            return null;
190
        }
191
        $system = $healthySystems[0];
192
        $system->setStatus(0);
193
        $system->setMode(SpacecraftSystemModeEnum::MODE_OFF);
194
        $this->spacecraftSystemManager->handleDestroyedSystem($wrapper, $healthySystems[0]->getSystemType());
195
196
        return $healthySystems[0]->getSystemType()->getDescription();
197
    }
198
199
    private function damageRandomShipSystem(
200
        SpacecraftWrapperInterface $wrapper,
201
        InformationInterface $informations,
202
        ?int $percent = null
203
    ): void {
204
        $healthySystems = $wrapper->get()->getHealthySystems();
205
        shuffle($healthySystems);
206
207
        if ($healthySystems !== []) {
208
            $system = $healthySystems[0];
209
210
            $this->damageShipSystem($wrapper, $system, $percent ?? random_int(1, 70), $informations);
211
        }
212
    }
213
214
    #[Override]
215
    public function damageShipSystem(
216
        SpacecraftWrapperInterface $wrapper,
217
        SpacecraftSystemInterface $system,
218
        int $dmg,
219
        InformationInterface $informations
220
    ): bool {
221
        $status = $system->getStatus();
222
        $systemName = $system->getSystemType()->getDescription();
223
224
        if ($status > $dmg) {
225
            $system->setStatus($status - $dmg);
226
            $this->spacecraftSystemManager->handleDamagedSystem($wrapper, $system->getSystemType());
227
            $informations->addInformation("- Folgendes System wurde beschädigt: " . $systemName);
228
229
            return false;
230
        } else {
231
            $system->setStatus(0);
232
            $system->setMode(SpacecraftSystemModeEnum::MODE_OFF);
233
            $this->spacecraftSystemManager->handleDestroyedSystem($wrapper, $system->getSystemType());
234
            $informations->addInformation("- Der Schaden zerstört folgendes System: " . $systemName);
235
236
            return true;
237
        }
238
    }
239
}
240