Passed
Pull Request — master (#1821)
by Nico
52:02 queued 25:23
created

FightLib::getDefenders()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5.0073

Importance

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