FightLib::ready()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

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