FightLib   A
last analyzed

Complexity

Total Complexity 42

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Test Coverage

Coverage 86.42%

Importance

Changes 0
Metric Value
eloc 83
dl 0
loc 182
ccs 70
cts 81
cp 0.8642
rs 9.0399
c 0
b 0
f 0
wmc 42

7 Methods

Rating   Name   Duplication   Size   Complexity  
C canAttackTarget() 0 49 17
A ready() 0 22 4
A getAttackersAndDefenders() 0 14 1
A isBoardingPossible() 0 15 6
A calculateHealthPercentage() 0 18 3
B readyInternal() 0 41 10
A __construct() 0 7 1

How to fix   Complexity   

Complex Class

Complex classes like FightLib often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FightLib, and based on these observations, apply Extract Interface, too.

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