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