Passed
Pull Request — master (#2043)
by Janko
20:39 queued 09:47
created

PirateCreation   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Test Coverage

Coverage 2.47%

Importance

Changes 0
Metric Value
eloc 85
c 0
b 0
f 0
dl 0
loc 166
ccs 2
cts 81
cp 0.0247
rs 10
wmc 16

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getRandomPirateSetup() 0 7 1
A createShips() 0 46 5
A createPirateFleet() 0 36 3
A createPirateFleetsIfNeeded() 0 24 3
A getRandomMapLocation() 0 14 3
A __construct() 0 16 1
1
<?php
2
3
namespace Stu\Lib\Pirate;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
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...
7
use RuntimeException;
8
use Stu\Component\Map\MapEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Map\MapEnum 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...
9
use Stu\Component\Spacecraft\SpacecraftAlertStateEnum;
10
use Stu\Lib\Map\FieldTypeEffectEnum;
11
use Stu\Module\Control\GameControllerInterface;
12
use Stu\Module\Control\StuRandom;
13
use Stu\Module\Logging\LoggerUtilFactoryInterface;
14
use Stu\Module\Logging\PirateLoggerInterface;
15
use Stu\Module\PlayerSetting\Lib\UserEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserEnum 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...
16
use Stu\Module\Ship\Lib\ShipCreatorInterface;
17
use Stu\Orm\Entity\FleetInterface;
18
use Stu\Orm\Entity\MapInterface;
19
use Stu\Orm\Entity\PirateSetupInterface;
20
use Stu\Orm\Entity\ShipInterface;
21
use Stu\Orm\Repository\FleetRepositoryInterface;
22
use Stu\Orm\Repository\GameTurnRepositoryInterface;
23
use Stu\Orm\Repository\LayerRepositoryInterface;
24
use Stu\Orm\Repository\MapRepositoryInterface;
25
use Stu\Orm\Repository\NamesRepositoryInterface;
26
use Stu\Orm\Repository\PirateSetupRepositoryInterface;
27
use Stu\Orm\Repository\ShipRepositoryInterface;
28
use Stu\Orm\Repository\UserRepositoryInterface;
29
30
class PirateCreation implements PirateCreationInterface
31
{
32
    public const MAX_PIRATE_FLEETS = 5;
33
    public const MAX_PIRATE_FLEETS_PER_TICK = 5;
34
35
    public const FORBIDDEN_ADMIN_AREAS = [
36
        MapEnum::ADMIN_REGION_SUPERPOWER_CENTRAL,
37
        MapEnum::ADMIN_REGION_SUPERPOWER_PERIPHERAL
38
    ];
39
40
    private PirateLoggerInterface $logger;
41
42 1
    public function __construct(
43
        private FleetRepositoryInterface $fleetRepository,
44
        private ShipRepositoryInterface $shipRepository,
45
        private UserRepositoryInterface $userRepository,
46
        private PirateSetupRepositoryInterface $pirateSetupRepository,
47
        private GameTurnRepositoryInterface $gameTurnRepository,
48
        private ShipCreatorInterface $shipCreator,
49
        private LayerRepositoryInterface $layerRepository,
50
        private MapRepositoryInterface $mapRepository,
51
        private GameControllerInterface $game,
52
        private StuRandom $stuRandom,
53
        private EntityManagerInterface $entityManager,
54
        private NamesRepositoryInterface $namesRepository,
55
        LoggerUtilFactoryInterface $loggerUtilFactory
56
    ) {
57 1
        $this->logger = $loggerUtilFactory->getPirateLogger();
58
    }
59
60
    #[Override]
61
    public function createPirateFleetsIfNeeded(): array
62
    {
63
        $gameTurn = $this->game->getCurrentRound();
64
        $pirateFleets = $this->fleetRepository->getByUser(UserEnum::USER_NPC_KAZON);
65
66
        $missingFleetAmount = min(
67
            max(0, self::MAX_PIRATE_FLEETS_PER_TICK - $gameTurn->getPirateFleets()),
68
            max(0, self::MAX_PIRATE_FLEETS - count($pirateFleets))
69
        );
70
71
        if ($missingFleetAmount > 0) {
72
            $this->logger->logf('    creating %d new needed pirate fleets', $missingFleetAmount);
73
        }
74
75
        for ($i = 0; $i < $missingFleetAmount; $i++) {
76
            $this->logger->logf('  fleet nr. %d', $i);
77
            $pirateFleets[] = $this->createPirateFleet();
78
            $gameTurn->setPirateFleets($gameTurn->getPirateFleets() + 1);
79
        }
80
81
        $this->gameTurnRepository->save($gameTurn);
82
83
        return $pirateFleets;
84
    }
85
86
    #[Override]
87
    public function createPirateFleet(?ShipInterface $supportCaller = null): FleetInterface
88
    {
89
        $pirateUser = $this->userRepository->find(UserEnum::USER_NPC_KAZON);
90
        if ($pirateUser === null) {
91
            throw new RuntimeException('this should not happen');
92
        }
93
94
        $pirateSetup = $this->getRandomPirateSetup();
95
96
        //create ships
97
        $ships = $this->createShips($pirateSetup, $supportCaller);
98
        $this->entityManager->flush();
99
100
        $fleetLeader = $ships[array_rand($ships)];
101
        $fleetLeader->setIsFleetLeader(true);
102
103
        //create fleet
104
        $fleet = $this->fleetRepository->prototype();
105
        $fleet->setUser($pirateUser);
106
        $fleet->setName($pirateSetup->getName());
107
        $fleet->setIsFleetFixed(true);
108
        $fleet->setLeadShip($fleetLeader);
109
110
        $this->logger->log(sprintf('    shipCount: %d', count($ships)));
111
112
        foreach ($ships as $ship) {
113
            $fleet->getShips()->add($ship);
114
            $ship->setFleet($fleet);
115
            $this->shipRepository->save($ship);
116
        }
117
118
        $this->fleetRepository->save($fleet);
119
        $this->entityManager->flush();
120
121
        return $fleet;
122
    }
123
124
    /** @return array<ShipInterface> */
125
    private function createShips(PirateSetupInterface $pirateSetup, ?ShipInterface $supportCaller): array
126
    {
127
        $randomLocation = $supportCaller === null ? $this->getRandomMapLocation() : $supportCaller->getLocation();
128
129
        $randomAlertLevel = SpacecraftAlertStateEnum::getRandomAlertLevel();
130
131
        $this->logger->log(sprintf('    randomAlertLevel: %d', $randomAlertLevel->value));
132
133
        $result = [];
134
135
        foreach ($pirateSetup->getSetupBuildplans() as $setupBuildplan) {
136
137
            $buildplan = $setupBuildplan->getBuildplan();
138
            $rump = $buildplan->getRump();
139
140
            for ($i = 0; $i < $setupBuildplan->getAmount(); $i++) {
141
142
                $mostUnusedNames = $this->namesRepository->mostUnusedNames();
143
                if ($mostUnusedNames !== []) {
144
                    $selectedNameEntry = $mostUnusedNames[array_rand($mostUnusedNames)];
145
                    $shipName = $selectedNameEntry->getName();
146
                    $selectedNameEntry->setCount($selectedNameEntry->getCount() + 1);
147
                    $this->namesRepository->save($selectedNameEntry);
148
                } else {
149
                    $shipName = "Pirate Ship";
150
                }
151
152
153
                $result[] = $this->shipCreator
154
                    ->createBy(
155
                        UserEnum::USER_NPC_KAZON,
156
                        $rump->getId(),
157
                        $buildplan->getId()
158
                    )
159
                    ->setLocation($randomLocation)
160
                    ->maxOutSystems()
161
                    ->createCrew()
162
                    ->setTorpedo()
163
                    ->setSpacecraftName($shipName)
164
                    ->setAlertState($randomAlertLevel)
165
                    ->finishConfiguration()
166
                    ->get();
167
            }
168
        }
169
170
        return $result;
171
    }
172
173
    private function getRandomPirateSetup(): PirateSetupInterface
174
    {
175
        $pirateSetups = $this->pirateSetupRepository->findAll();
176
177
        $pirateProbabilities = array_map(fn(PirateSetupInterface $setup): int => $setup->getProbabilityWeight(), $pirateSetups);
178
179
        return $pirateSetups[$this->stuRandom->randomKeyOfProbabilities($pirateProbabilities)];
180
    }
181
182
    private function getRandomMapLocation(): MapInterface
183
    {
184
        $defaultLayer = $this->layerRepository->getDefaultLayer();
185
186
        do {
187
            $map = $this->mapRepository->getRandomPassableUnoccupiedWithoutDamage($defaultLayer);
188
        } while (
189
            in_array($map->getAdminRegionId(), self::FORBIDDEN_ADMIN_AREAS)
190
            && $map->getFieldType()->hasEffect(FieldTypeEffectEnum::NO_PIRATES)
191
        );
192
193
        $this->logger->log(sprintf('    randomMapLocation: %s', $map->getSectorString()));
194
195
        return $map;
196
    }
197
}
198