Passed
Push — master ( 69410e...6e6431 )
by Nico
42:43 queued 11:08
created

BeamUtil   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 97.1%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 69
dl 0
loc 146
ccs 67
cts 69
cp 0.971
rs 10
c 1
b 0
f 0
wmc 29

7 Methods

Rating   Name   Duplication   Size   Complexity  
A upperTargetStorage() 0 9 2
A consumeEps() 0 15 4
A __construct() 0 8 1
A lowerSourceStorage() 0 9 2
A getBeamFactor() 0 7 2
A getAvailableEps() 0 9 3
C transferCommodity() 0 67 15
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Lib\BeamUtil;
6
7
use RuntimeException;
8
use Stu\Component\Colony\Storage\ColonyStorageManagerInterface;
9
use Stu\Component\Ship\Storage\ShipStorageManagerInterface;
10
use Stu\Module\Control\GameControllerInterface;
11
use Stu\Module\Ship\Lib\ShipWrapperInterface;
12
use Stu\Orm\Entity\ColonyInterface;
13
use Stu\Orm\Entity\CommodityInterface;
14
use Stu\Orm\Entity\ShipInterface;
15
use Stu\Orm\Repository\ColonyRepositoryInterface;
16
17
final class BeamUtil implements BeamUtilInterface
18
{
19
    private ShipStorageManagerInterface $shipStorageManager;
20
21
    private ColonyStorageManagerInterface $colonyStorageManager;
22
23
    private ColonyRepositoryInterface $colonyRepository;
24
25 11
    public function __construct(
26
        ShipStorageManagerInterface $shipStorageManager,
27
        ColonyStorageManagerInterface $colonyStorageManager,
28
        ColonyRepositoryInterface $colonyRepository
29
    ) {
30 11
        $this->shipStorageManager = $shipStorageManager;
31 11
        $this->colonyStorageManager = $colonyStorageManager;
32 11
        $this->colonyRepository = $colonyRepository;
33
    }
34
35 11
    public function transferCommodity(
36
        int $commodityId,
37
        string|int $wantedAmount,
38
        ShipWrapperInterface|ColonyInterface $subject,
39
        ShipInterface|ColonyInterface $source,
40
        ShipInterface|ColonyInterface $target,
41
        GameControllerInterface $game
42
    ): void {
43
44 11
        $sourceStorage =  $source->getStorage()[$commodityId] ?? null;
45 11
        if ($sourceStorage === null) {
46 1
            return;
47
        }
48
49 10
        $commodity = $sourceStorage->getCommodity();
50 10
        if (!$commodity->isBeamable($source->getUser(), $target->getUser())) {
51 1
            $game->addInformationf(_('%s ist nicht beambar'), $commodity->getName());
52 1
            return;
53
        }
54
55 9
        $isDockTransfer = $source instanceof ShipInterface && $target instanceof ShipInterface
56 9
            && ($source->getDockedTo() === $target || $target->getDockedTo() === $source);
57
58 9
        $availableEps = $this->getAvailableEps($subject);
59 9
        if (!$isDockTransfer && $availableEps < 1) {
60 1
            return;
61
        }
62
63 8
        if ($wantedAmount === "max") {
64 1
            $amount = $sourceStorage->getAmount();
65 7
        } else if (!is_numeric($wantedAmount)) {
66 1
            return;
67
        } else {
68 6
            $amount =  (int)$wantedAmount;
69
        }
70
71 7
        if ($amount < 1) {
72 1
            return;
73
        }
74
75 6
        if ($target->getStorageSum() >= $target->getMaxStorage()) {
76 1
            return;
77
        }
78
79 5
        $amount = min($amount, $sourceStorage->getAmount());
80 5
        $transferAmount = $commodity->getTransferCount() * $this->getBeamFactor($subject);
81
82 5
        if (!$isDockTransfer && ceil($amount / $transferAmount) > $availableEps) {
83 3
            $amount = $availableEps * $transferAmount;
84
        }
85
86 5
        if ($target->getStorageSum() + $amount > $target->getMaxStorage()) {
87 1
            $amount = $target->getMaxStorage() - $target->getStorageSum();
88
        }
89
90 5
        $epsUsage = (int)ceil($amount / $transferAmount);
91
92 5
        $game->addInformationf(
93 5
            _('%d %s (Energieverbrauch: %d)'),
94 5
            $amount,
95 5
            $commodity->getName(),
96 5
            $epsUsage
97 5
        );
98
99 5
        $this->lowerSourceStorage($amount, $commodity, $source);
100 5
        $this->upperTargetStorage($amount, $commodity, $target);
101 5
        $this->consumeEps($epsUsage, $subject);
102
    }
103
104 5
    private function getBeamFactor(ShipWrapperInterface|ColonyInterface $subject): int
105
    {
106 5
        if ($subject instanceof ShipWrapperInterface) {
107 1
            return $subject->get()->getBeamFactor();
108
        }
109
110 4
        return $subject->getBeamFactor();
111
    }
112
113 9
    private function getAvailableEps(ShipWrapperInterface|ColonyInterface $subject): int
114
    {
115 9
        if ($subject instanceof ShipWrapperInterface) {
116 1
            $epsSystem = $subject->getEpsSystemData();
117
118 1
            return $epsSystem === null ? 0 : $epsSystem->getEps();
119
        }
120
121 8
        return $subject->getEps();
122
    }
123
124 5
    private function lowerSourceStorage(
125
        int $amount,
126
        CommodityInterface $commodity,
127
        ShipInterface|ColonyInterface $source
128
    ): void {
129 5
        if ($source instanceof ShipInterface) {
130 1
            $this->shipStorageManager->lowerStorage($source, $commodity,  $amount);
131
        } else {
132 4
            $this->colonyStorageManager->lowerStorage($source, $commodity,  $amount);
133
        }
134
    }
135
136 5
    private function upperTargetStorage(
137
        int $amount,
138
        CommodityInterface $commodity,
139
        ShipInterface|ColonyInterface $target
140
    ): void {
141 5
        if ($target instanceof ShipInterface) {
142 4
            $this->shipStorageManager->upperStorage($target, $commodity,  $amount);
143
        } else {
144 1
            $this->colonyStorageManager->upperStorage($target, $commodity,  $amount);
145
        }
146
    }
147
148 5
    private function consumeEps(int $epsUsage, ShipWrapperInterface|ColonyInterface $subject): void
149
    {
150 5
        if ($epsUsage === 0) {
151
            return;
152
        }
153
154 5
        if ($subject instanceof ShipWrapperInterface) {
155 1
            $epsSystem = $subject->getEpsSystemData();
156 1
            if ($epsSystem === null) {
157
                throw new RuntimeException('this should not happen');
158
            }
159 1
            $epsSystem->lowerEps($epsUsage)->update();
160
        } else {
161 4
            $subject->lowerEps($epsUsage);
162 4
            $this->colonyRepository->save($subject);
163
        }
164
    }
165
}
166