Passed
Push — master ( 77a570...adeb98 )
by Nico
26:43
created

BeamUtil   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Test Coverage

Coverage 97.1%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 67
dl 0
loc 143
ccs 67
cts 69
cp 0.971
rs 9.92
c 1
b 1
f 0
wmc 31

8 Methods

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