Passed
Push — dev ( 74922b...2964fe )
by Janko
07:20
created

SpacecraftAttackCore::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 7
dl 0
loc 9
ccs 2
cts 2
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\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 RuntimeException;
9
use Stu\Lib\Information\InformationWrapper;
10
use Stu\Module\Message\Lib\DistributedMessageSenderInterface;
11
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
12
use Stu\Module\Spacecraft\Lib\Battle\AlertDetection\AlertReactionFacadeInterface;
13
use Stu\Module\Spacecraft\Lib\Battle\Party\AttackingBattleParty;
14
use Stu\Module\Spacecraft\Lib\Battle\Party\BattlePartyFactoryInterface;
15
use Stu\Module\Spacecraft\Lib\Battle\Party\BattlePartyInterface;
16
use Stu\Module\Ship\Lib\FleetWrapperInterface;
17
use Stu\Module\Ship\Lib\TholianWebUtilInterface;
18
use Stu\Module\Spacecraft\Lib\Message\MessageCollectionInterface;
19
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
20
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
21
use Stu\Orm\Entity\Ship;
22
use Stu\Orm\Entity\Spacecraft;
23
24
final class SpacecraftAttackCore implements SpacecraftAttackCoreInterface
25
{
26 1
    public function __construct(
27
        private DistributedMessageSenderInterface $distributedMessageSender,
28
        private SpacecraftAttackCycleInterface $spacecraftAttackCycle,
29
        private AlertReactionFacadeInterface $alertReactionFacade,
30
        private FightLibInterface $fightLib,
31
        private TholianWebUtilInterface $tholianWebUtil,
32
        private SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
33
        private BattlePartyFactoryInterface $battlePartyFactory
34 1
    ) {}
35
36
    #[Override]
37
    public function attack(
38
        SpacecraftWrapperInterface|FleetWrapperInterface $sourceWrapper,
39
        SpacecraftWrapperInterface $targetWrapper,
40
        bool $isAttackingShieldsOnly,
41
        bool &$isFleetFight,
42
        InformationWrapper $informations
43
    ): bool {
44
        $wrapper = $sourceWrapper instanceof SpacecraftWrapperInterface ? $sourceWrapper : $sourceWrapper->getLeadWrapper();
45
        $ship = $wrapper->get();
46
47
        $target = $targetWrapper->get();
48
        $userId = $ship->getUser()->getId();
49
        $isTargetBase = $target->isStation();
50
51
        $isActiveTractorShipWarped = $this->isActiveTractorShipWarped($ship, $target);
52
53
        [$attacker, $defender, $isFleetFight, $attackCause] = $this->getAttackersAndDefenders(
54
            $wrapper,
55
            $targetWrapper,
56
            $isAttackingShieldsOnly
57
        );
58
59
        $messageCollection = $this->spacecraftAttackCycle->cycle($attacker, $defender, $attackCause);
60
61
        $this->sendPms(
62
            $userId,
63
            $ship->getSectorString(),
64
            $messageCollection,
65
            ($attackCause !== SpacecraftAttackCauseEnum::THOLIAN_WEB_REFLECTION) && $isTargetBase
66
        );
67
68
        $informations->addInformationWrapper($messageCollection->getInformationDump());
69
70
        if ($isActiveTractorShipWarped) {
71
            //Alarm-Rot check for ship
72
            if (!$ship->getCondition()->isDestroyed()) {
73
                $this->alertReactionFacade->doItAll($wrapper, $informations);
0 ignored issues
show
Bug introduced by
It seems like $wrapper can also be of type Stu\Module\Ship\Lib\FleetWrapperInterface; however, parameter $incomingWrapper of Stu\Module\Spacecraft\Li...adeInterface::doItAll() does only seem to accept Stu\Module\Spacecraft\Li...cecraftWrapperInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
                $this->alertReactionFacade->doItAll(/** @scrutinizer ignore-type */ $wrapper, $informations);
Loading history...
74
            }
75
76
            //Alarm-Rot check for traktor ship
77
            if (!$target->getCondition()->isDestroyed()) {
78
                $this->alertReactionFacade->doItAll($targetWrapper, $informations);
79
            }
80
        }
81
82
        return !$ship->getCondition()->isDestroyed();
83
    }
84
85
    private function isActiveTractorShipWarped(Spacecraft $spacecraft, Spacecraft $target): bool
86
    {
87
        $tractoringShip = $spacecraft instanceof Ship ? $spacecraft->getTractoringSpacecraft() : null;
88
        if ($tractoringShip === null) {
89
            return false;
90
        }
91
92
        if ($tractoringShip !== $target) {
93
            return false;
94
        } else {
95
            return $target->getWarpDriveState();
96
        }
97
    }
98
99
    private function sendPms(
100
        int $userId,
101
        string $sectorString,
102
        MessageCollectionInterface $messageCollection,
103
        bool $isTargetBase
104
    ): void {
105
106
        $header = sprintf(
107
            _("Kampf in Sektor %s"),
108
            $sectorString
109
        );
110
111
        $this->distributedMessageSender->distributeMessageCollection(
112
            $messageCollection,
113
            $userId,
114
            $isTargetBase ? PrivateMessageFolderTypeEnum::SPECIAL_STATION : PrivateMessageFolderTypeEnum::SPECIAL_SHIP,
115
            $header
116
        );
117
    }
118
119
    /**
120
     * @return array{0: AttackingBattleParty, 1: BattlePartyInterface, 2: bool, 3: SpacecraftAttackCauseEnum}
121
     */
122
    private function getAttackersAndDefenders(
123
        SpacecraftWrapperInterface|FleetWrapperInterface $wrapper,
124
        SpacecraftWrapperInterface $targetWrapper,
125
        bool $isAttackingShieldsOnly
126
    ): array {
127
        $attackCause = SpacecraftAttackCauseEnum::SHIP_FIGHT;
128
        $ship = $wrapper instanceof SpacecraftWrapperInterface ? $wrapper->get() : $wrapper->get()->getLeadShip();
129
130
        [$attacker, $defender, $isFleetFight] = $this->fightLib->getAttackersAndDefenders(
131
            $wrapper,
132
            $targetWrapper,
133
            $isAttackingShieldsOnly,
134
            $this->battlePartyFactory
135
        );
136
137
        $isTargetOutsideFinishedWeb = $this->tholianWebUtil->isTargetOutsideFinishedTholianWeb($ship, $targetWrapper->get());
138
139
        //if in tholian web and defenders outside, reflect damage
140
        if ($isTargetOutsideFinishedWeb) {
141
            $attackCause = SpacecraftAttackCauseEnum::THOLIAN_WEB_REFLECTION;
142
            $holdingWeb = $ship->getHoldingWeb();
143
            if ($holdingWeb === null) {
144
                throw new RuntimeException('this should not happen');
145
            }
146
147
            $defender = $this->battlePartyFactory->createMixedBattleParty(
148
                $this->spacecraftWrapperFactory->wrapSpacecrafts($holdingWeb->getCapturedSpacecrafts()->toArray())
149
            );
150
        } elseif ($this->tholianWebUtil->isTargetInsideFinishedTholianWeb(
151
            $ship,
152
            $targetWrapper->get()
153
        )) {
154
            $attackCause = SpacecraftAttackCauseEnum::THOLIAN_WEB_REFLECTION;
155
        }
156
157
        return [
158
            $attacker,
159
            $defender,
160
            $isFleetFight,
161
            $attackCause
162
        ];
163
    }
164
}
165