Passed
Push — master ( 77a570...adeb98 )
by Nico
26:43
created

FightLib   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Test Coverage

Coverage 85.9%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 80
dl 0
loc 167
ccs 67
cts 78
cp 0.859
rs 9.44
c 1
b 1
f 0
wmc 37

7 Methods

Rating   Name   Duplication   Size   Complexity  
B ready() 0 43 9
A isBoardingPossible() 0 8 6
A __construct() 0 7 1
A calculateHealthPercentage() 0 18 3
A getAttackersAndDefenders() 0 13 1
C canAttackTarget() 0 54 14
A isTargetOutsideFinishedTholianWeb() 0 9 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Lib\Battle;
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 pq\Cancel;
9
use Stu\Component\Ship\Repair\CancelRepairInterface;
10
use Stu\Component\Ship\Retrofit\CancelRetrofitInterface;
11
use Stu\Component\Ship\System\Exception\ShipSystemException;
12
use Stu\Component\Ship\System\ShipSystemManagerInterface;
13
use Stu\Component\Ship\System\ShipSystemTypeEnum;
14
use Stu\Lib\Information\InformationFactoryInterface;
15
use Stu\Lib\Information\InformationInterface;
16
use Stu\Module\Ship\Lib\Battle\Party\BattlePartyFactoryInterface;
17
use Stu\Module\Ship\Lib\FleetWrapperInterface;
18
use Stu\Module\Ship\Lib\ShipNfsItem;
19
use Stu\Module\Ship\Lib\ShipWrapperInterface;
20
use Stu\Orm\Entity\ShipInterface;
21
use Stu\Orm\Entity\User;
22
23
final class FightLib implements FightLibInterface
24
{
25 37
    public function __construct(
26
        private ShipSystemManagerInterface $shipSystemManager,
27
        private  CancelRepairInterface $cancelRepair,
28
        private CancelRetrofitInterface $cancelRetrofit,
29
        private AlertLevelBasedReactionInterface $alertLevelBasedReaction,
30
        private InformationFactoryInterface $informationFactory
31 37
    ) {}
32
33 6
    #[Override]
34
    public function ready(ShipWrapperInterface $wrapper, InformationInterface $informations): void
35
    {
36 6
        $ship = $wrapper->get();
37
38
        if (
39 6
            $ship->isDestroyed()
40 6
            || $ship->getRump()->isEscapePods()
41
        ) {
42 2
            return;
43
        }
44 4
        if ($ship->getBuildplan() === null) {
45 1
            return;
46
        }
47 3
        if (!$ship->hasEnoughCrew()) {
48 1
            return;
49
        }
50
51 2
        $informationWrapper = $this->informationFactory->createInformationWrapper();
52
53 2
        if ($ship->getDockedTo() !== null) {
54 1
            $ship->setDockedTo(null);
55 1
            $informationWrapper->addInformation("- Das Schiff hat abgedockt");
56
        }
57
58
        try {
59 2
            $this->shipSystemManager->deactivate($wrapper, ShipSystemTypeEnum::SYSTEM_WARPDRIVE);
60 1
        } catch (ShipSystemException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
61
        }
62
        try {
63 2
            $this->shipSystemManager->deactivate($wrapper, ShipSystemTypeEnum::SYSTEM_CLOAK);
64 1
        } catch (ShipSystemException) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
65
        }
66
67 2
        $this->cancelRepair->cancelRepair($ship);
68
69 2
        $this->cancelRetrofit->cancelRetrofit($ship);
70
71 2
        $this->alertLevelBasedReaction->react($wrapper, $informationWrapper);
72
73 2
        if (!$informationWrapper->isEmpty()) {
74 1
            $informations->addInformationf('Aktionen der %s', $ship->getName());
75 1
            $informationWrapper->dumpTo($informations);
76
        }
77
    }
78
79 14
    #[Override]
80
    public function canAttackTarget(
81
        ShipInterface $ship,
82
        ShipInterface|ShipNfsItem $target,
83
        bool $checkCloaked = false,
84
        bool $checkActiveWeapons = true,
85
        bool $checkWarped = true
86
    ): bool {
87 14
        if ($checkActiveWeapons && !$ship->hasActiveWeapon()) {
88 1
            return false;
89
        }
90
91
        //can't attack itself
92 13
        if ($target === $ship) {
93 1
            return false;
94
        }
95
96
        //can't attack trumfields
97 12
        if ($target->isTrumfield()) {
98 1
            return false;
99
        }
100
101
        //can't attack cloaked target
102 11
        if ($checkCloaked && $target->getCloakState()) {
103 1
            return false;
104
        }
105
106
        //if tractored, can only attack tractoring ship
107 10
        $tractoringShip = $ship->getTractoringShip();
108 10
        if ($tractoringShip !== null) {
109 3
            return $target->getId() === $tractoringShip->getId();
110
        }
111
112
        //can't attack target under warp
113 7
        if ($checkWarped && $target->isWarped()) {
114 1
            return false;
115
        }
116
117
        //can't attack own target under cloak
118
        if (
119 6
            $target->getUserId() === $ship->getUserId()
120 6
            && $target->getCloakState()
121
        ) {
122 1
            return false;
123
        }
124
125
        //can't attack same fleet
126 5
        $ownFleetId = $ship->getFleetId();
127 5
        $targetFleetId = $target->getFleetId();
128 5
        if ($ownFleetId === null || $targetFleetId === null) {
129 2
            return true;
130
        }
131
132 3
        return $ownFleetId !== $targetFleetId;
133
    }
134
135 3
    #[Override]
136
    public function getAttackersAndDefenders(
137
        ShipWrapperInterface|FleetWrapperInterface $wrapper,
138
        ShipWrapperInterface $targetWrapper,
139
        BattlePartyFactoryInterface $battlePartyFactory
140
    ): array {
141 3
        $attackers = $battlePartyFactory->createAttackingBattleParty($wrapper);
142 3
        $defenders = $battlePartyFactory->createAttackedBattleParty($targetWrapper);
143
144 3
        return [
145 3
            $attackers,
146 3
            $defenders,
147 3
            count($attackers) + count($defenders) > 2
148 3
        ];
149
    }
150
151 4
    #[Override]
152
    public function isTargetOutsideFinishedTholianWeb(ShipInterface $ship, ShipInterface $target): bool
153
    {
154 4
        $web = $ship->getHoldingWeb();
155 4
        if ($web === null) {
156 1
            return false;
157
        }
158
159 3
        return $web->isFinished() && ($target->getHoldingWeb() !== $web);
160
    }
161
162 6
    public static function isBoardingPossible(ShipInterface|ShipNfsItem $ship): bool
163
    {
164 6
        return !(User::isUserNpc($ship->getUserId())
165 6
            || $ship->isBase()
166 6
            || $ship->isTrumfield()
167 6
            || $ship->getCloakState()
168 6
            || $ship->getShieldState()
169 6
            || $ship->isWarped());
170
    }
171
172
    #[Override]
173
    public function calculateHealthPercentage(ShipInterface $target): int
174
    {
175
        $shipCount = 0;
176
        $healthSum = 0;
177
178
        $fleet = $target->getFleet();
179
        if ($fleet !== null) {
180
            foreach ($fleet->getShips() as $ship) {
181
                $shipCount++;
182
                $healthSum += $ship->getHealthPercentage();
183
            }
184
        } else {
185
            $shipCount++;
186
            $healthSum += $target->getHealthPercentage();
187
        }
188
189
        return (int)($healthSum / $shipCount);
190
    }
191
}