Passed
Push — dev ( 82c4ce...00c566 )
by Janko
27:25
created

ShipAttacker::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 5
dl 0
loc 7
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Lib\Battle\Provider;
6
7
use RuntimeException;
8
use Stu\Component\Ship\System\ShipSystemTypeEnum;
9
use Stu\Module\Control\StuRandom;
10
use Stu\Module\Logging\LoggerUtilInterface;
11
use Stu\Module\Ship\Lib\ModuleValueCalculatorInterface;
12
use Stu\Module\Ship\Lib\ShipWrapperInterface;
13
use Stu\Module\Ship\Lib\Torpedo\ShipTorpedoManagerInterface;
14
use Stu\Orm\Entity\ModuleInterface;
15
use Stu\Orm\Entity\ShipInterface;
16
use Stu\Orm\Entity\TorpedoTypeInterface;
17
use Stu\Orm\Entity\UserInterface;
18
19
class ShipAttacker extends AbstractEnergyAttacker implements ProjectileAttackerInterface
20
{
21 24
    public function __construct(
22
        private ShipWrapperInterface $wrapper,
23
        private ModuleValueCalculatorInterface $moduleValueCalculator,
24
        private ShipTorpedoManagerInterface $shipTorpedoManager,
25
        private StuRandom $stuRandom,
26
        private LoggerUtilInterface $logger
27
    ) {
28 24
    }
29
30 1
    public function getPhaserVolleys(): int
31
    {
32 1
        return $this->get()->getRump()->getPhaserVolleys();
33
    }
34
35 1
    public function getPhaserState(): bool
36
    {
37 1
        return $this->get()->getPhaserState();
38
    }
39
40 3
    public function hasSufficientEnergy(int $amount): bool
41
    {
42 3
        $epsSystemData = $this->wrapper->getEpsSystemData();
43 3
        if ($epsSystemData === null) {
44 1
            return false;
45
        }
46 2
        return $epsSystemData->getEps() >= $amount;
47
    }
48
49 3
    public function getWeaponModule(): ModuleInterface
50
    {
51 3
        if ($this->module === null) {
52 3
            $shipSystem = $this->get()->getShipSystem(ShipSystemTypeEnum::SYSTEM_PHASER);
53
54 3
            $module = $shipSystem->getModule();
55 3
            if ($module === null) {
56 1
                throw new RuntimeException('weapon system should have a module');
57
            }
58
59 2
            $this->module = $module;
60
        }
61
62 2
        return $this->module;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->module could return the type null which is incompatible with the type-hinted return Stu\Orm\Entity\ModuleInterface. Consider adding an additional type-check to rule them out.
Loading history...
63
    }
64
65 1
    public function getEnergyWeaponBaseDamage(): int
66
    {
67 1
        return $this->moduleValueCalculator->calculateModuleValue(
68 1
            $this->get()->getRump(),
69 1
            $this->getWeaponModule(),
70 1
            'getBaseDamage'
71 1
        );
72
    }
73
74 2
    public function reduceEps(int $amount): void
75
    {
76 2
        $epsSystemData = $this->wrapper->getEpsSystemData();
77 2
        if ($epsSystemData === null) {
78 1
            return;
79
        }
80 1
        $epsSystemData->lowerEps($amount)->update();
81
    }
82
83 1
    public function getName(): string
84
    {
85 1
        return $this->get()->getName();
86
    }
87
88 1
    public function getUser(): UserInterface
89
    {
90 1
        return $this->get()->getUser();
91
    }
92
93 17
    private function get(): ShipInterface
94
    {
95 17
        return $this->wrapper->get();
96
    }
97
98 1
    public function getHitChance(): int
99
    {
100 1
        return $this->get()->getHitChance();
101
    }
102
103 1
    public function getPhaserShieldDamageFactor(): int
104
    {
105 1
        return $this->get()->getRump()->getPhaserShieldDamageFactor();
106
    }
107
108 1
    public function getPhaserHullDamageFactor(): int
109
    {
110 1
        return $this->get()->getRump()->getPhaserHullDamageFactor();
111
    }
112
113 1
    public function getTorpedoVolleys(): int
114
    {
115 1
        return $this->get()->getRump()->getTorpedoVolleys();
116
    }
117
118 1
    public function getTorpedoState(): bool
119
    {
120 1
        return $this->get()->getTorpedoState();
121
    }
122
123 1
    public function getTorpedoCount(): int
124
    {
125 1
        return $this->get()->getTorpedoCount();
126
    }
127
128 4
    public function getTorpedo(): ?TorpedoTypeInterface
129
    {
130 4
        return $this->get()->getTorpedo();
131
    }
132
133 1
    public function lowerTorpedoCount(int $amount): void
134
    {
135 1
        $this->shipTorpedoManager->changeTorpedo($this->wrapper, -$amount);
136
    }
137
138
    public function isShieldPenetration(): bool
139
    {
140
        $systemData = $this->wrapper->getProjectileLauncherSystemData();
141
        if ($systemData === null) {
142
            throw new RuntimeException('this should not happen');
143
        }
144
145
        return $this->stuRandom->rand(1, 10000) <= $systemData->getShieldPenetration();
146
    }
147
148 3
    public function getProjectileWeaponDamage(bool $isCritical): int
149
    {
150 3
        $torpedo = $this->getTorpedo();
151 3
        if ($torpedo === null) {
152 1
            $this->logger->log('shipAttacker->getProjectileWeaponDamage: no torpedo');
153 1
            return 0;
154
        }
155
156 2
        $module = $this->get()->getShipSystem(ShipSystemTypeEnum::SYSTEM_TORPEDO)->getModule();
157 2
        if ($module === null) {
158 1
            $this->logger->log('shipAttacker->getProjectileWeaponDamage: no module');
159 1
            return 0;
160
        }
161
162 1
        $variance = (int) round($torpedo->getBaseDamage() / 100 * $torpedo->getVariance());
163 1
        $basedamage = $this->moduleValueCalculator->calculateModuleValue(
164 1
            $this->get()->getRump(),
165 1
            $module,
166 1
            false,
167 1
            $torpedo->getBaseDamage()
168 1
        );
169 1
        $damage = random_int($basedamage - $variance, $basedamage + $variance);
170
171 1
        if ($damage === 0) {
172
            $this->logger->logf(
173
                'shipAttacker->getProjectileWeaponDamage, baseDamage: %d',
174
                $torpedo->getBaseDamage()
175
            );
176
        }
177
178 1
        return $isCritical ? $damage * 2 : $damage;
179
    }
180
}
181