Passed
Push — master ( f4068b...77f637 )
by Nico
40:27 queued 14:09
created

StartTakeover::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 6
dl 0
loc 14
ccs 0
cts 7
cp 0
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Ship\Action\StartTakeover;
6
7
use request;
8
use Stu\Component\Ship\Nbs\NbsUtilityInterface;
9
use Stu\Component\Ship\ShipStateEnum;
10
use Stu\Exception\SanityCheckException;
11
use Stu\Module\Control\ActionControllerInterface;
12
use Stu\Module\Control\GameControllerInterface;
13
use Stu\Module\Ship\Lib\Battle\FightLibInterface;
14
use Stu\Module\Ship\Lib\Interaction\InteractionCheckerInterface;
15
use Stu\Module\Ship\Lib\Interaction\ShipTakeoverManagerInterface;
16
use Stu\Module\Ship\Lib\ShipLoaderInterface;
17
use Stu\Module\Ship\Lib\ShipStateChangerInterface;
18
use Stu\Module\Ship\View\ShowShip\ShowShip;
19
20
final class StartTakeover implements ActionControllerInterface
21
{
22
    public const ACTION_IDENTIFIER = 'B_TAKEOVER_SHIP';
23
24
    private ShipLoaderInterface $shipLoader;
25
26
    private InteractionCheckerInterface $interactionChecker;
27
28
    private NbsUtilityInterface $nbsUtility;
29
30
    private FightLibInterface $fightLib;
31
32
    private ShipTakeoverManagerInterface $shipTakeoverManager;
33
34
    private ShipStateChangerInterface $shipStateChanger;
35
36
    public function __construct(
37
        ShipLoaderInterface $shipLoader,
38
        InteractionCheckerInterface $interactionChecker,
39
        NbsUtilityInterface $nbsUtility,
40
        FightLibInterface $fightLib,
41
        ShipTakeoverManagerInterface $shipTakeoverManager,
42
        ShipStateChangerInterface $shipStateChanger
43
    ) {
44
        $this->shipLoader = $shipLoader;
45
        $this->interactionChecker = $interactionChecker;
46
        $this->nbsUtility = $nbsUtility;
47
        $this->fightLib = $fightLib;
48
        $this->shipTakeoverManager = $shipTakeoverManager;
49
        $this->shipStateChanger = $shipStateChanger;
50
    }
51
52
    public function handle(GameControllerInterface $game): void
53
    {
54
        $game->setView(ShowShip::VIEW_IDENTIFIER);
55
56
        $user = $game->getUser();
57
        $userId = $user->getId();
58
59
        $shipId = request::getIntFatal('id');
60
        $targetId = request::getIntFatal('target');
61
62
        $wrappers = $this->shipLoader->getWrappersBySourceAndUserAndTarget(
63
            $shipId,
64
            $userId,
65
            $targetId
66
        );
67
68
        $wrapper = $wrappers->getSource();
69
        $ship = $wrapper->get();
70
71
        if ($ship->getTakeoverActive() !== null) {
72
            return;
73
        }
74
75
        $targetWrapper = $wrappers->getTarget();
76
        if ($targetWrapper === null) {
77
            return;
78
        }
79
        $target = $targetWrapper->get();
80
81
82
        if (!$target->isBoardingPossible()) {
83
            return;
84
        }
85
86
        if ($target->getUser() === $user) {
87
            return;
88
        }
89
90
        if ($target->getUser()->isNpc()) {
91
            $game->addInformation(_('Aktion nicht möglich, der Spieler ist NPC!'));
92
            return;
93
        }
94
95
        if ($target->getUser()->isVacationRequestOldEnough()) {
96
            $game->addInformation(_('Aktion nicht möglich, der Spieler befindet sich im Urlaubsmodus!'));
97
            return;
98
        }
99
100
        if (!$ship->hasEnoughCrew($game)) {
101
            return;
102
        }
103
        if (!$this->interactionChecker->checkPosition($target, $ship)) {
104
            throw new SanityCheckException('InteractionChecker->checkPosition failed', self::ACTION_IDENTIFIER);
105
        }
106
107
        if (!$this->fightLib->canAttackTarget($ship, $target, false)) {
108
            throw new SanityCheckException('Target cant be attacked', self::ACTION_IDENTIFIER);
109
        }
110
111
        if ($target->getCloakState() && !$this->nbsUtility->isTachyonActive($ship)) {
112
            throw new SanityCheckException('Attacked cloaked ship without active tachyon', self::ACTION_IDENTIFIER);
113
        }
114
115
        $epsSystemData = $wrapper->getEpsSystemData();
116
        if ($epsSystemData === null || $epsSystemData->getEps() === 0) {
117
            $game->addInformation(_('Keine Energie vorhanden'));
118
            return;
119
        }
120
121
        if ($ship->isDisabled()) {
122
            $game->addInformation(_('Das Schiff ist kampfunfähig'));
123
            return;
124
        }
125
126
        if ($this->fightLib->isTargetOutsideFinishedTholianWeb($ship, $target)) {
127
            $game->addInformation(_('Das Ziel ist nicht mit im Energienetz gefangen'));
128
            return;
129
        }
130
131
        if (!$target->getCrewAssignments()->isEmpty()) {
132
            $game->addInformation(_('Aktion nicht möglich, das Ziel ist bemannt'));
133
            return;
134
        }
135
136
        $neededPrestige = $this->shipTakeoverManager->getPrestigeForTakeover($target);
137
        if ($user->getPrestige() < $neededPrestige) {
138
            $game->addInformation(sprintf(
139
                'Nicht genügend Prestige vorhanden, benötigt wird: %d',
140
                $neededPrestige
141
            ));
142
            return;
143
        }
144
145
        $this->shipStateChanger->changeShipState($wrapper, ShipStateEnum::SHIP_STATE_ACTIVE_TAKEOVER);
146
        $this->shipTakeoverManager->startTakeover($ship, $target, $neededPrestige);
147
148
        $game->addInformationf(
149
            'Übernahme der %s wurde gestartet. Fertigstellung in %d Runden.',
150
            $target->getName(),
151
            ShipTakeoverManagerInterface::TURNS_TO_TAKEOVER
152
        );
153
    }
154
155
    public function performSessionCheck(): bool
156
    {
157
        return true;
158
    }
159
}
160