Passed
Push — dev ( 840a26...5b15b7 )
by Janko
18:04
created

StarSystemMapRepository::save()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Orm\Repository;
6
7
use Doctrine\ORM\EntityRepository;
8
use Doctrine\ORM\Query\ResultSetMapping;
9
use Stu\Component\Anomaly\Type\SubspaceEllipseHandler;
10
use Stu\Component\Ship\AstronomicalMappingEnum;
11
use Stu\Component\Ship\ShipRumpEnum;
12
use Stu\Component\Ship\System\ShipSystemModeEnum;
13
use Stu\Component\Ship\System\ShipSystemTypeEnum;
14
use Stu\Module\PlayerSetting\Lib\UserEnum;
15
use Stu\Orm\Entity\StarSystemInterface;
16
use Stu\Orm\Entity\StarSystemMap;
17
use Stu\Orm\Entity\StarSystemMapInterface;
18
19
/**
20
 * @extends EntityRepository<StarSystemMap>
21
 */
22
final class StarSystemMapRepository extends EntityRepository implements StarSystemMapRepositoryInterface
23
{
24
    public function getBySystemOrdered(int $starSystemId): array
25
    {
26
        return $this->findBy(
27
            ['systems_id' => $starSystemId],
28
            ['sy' => 'asc', 'sx' => 'asc']
29
        );
30
    }
31
32
    public function getByCoordinates(
33
        int $starSystemId,
34
        int $sx,
35
        int $sy
36
    ): ?StarSystemMapInterface {
37
        return $this->findOneBy([
38
            'systems_id' => $starSystemId,
39
            'sx' => $sx,
40
            'sy' => $sy
41
        ]);
42
    }
43
44
    public function getByCoordinateRange(
45
        StarSystemInterface $starSystem,
46
        int $startSx,
47
        int $endSx,
48
        int $startSy,
49
        int $endSy
50
    ): array {
51
        return $this->getEntityManager()
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this->getEntityM...> $endSy))->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
52
            ->createQuery(
53
                sprintf(
54
                    'SELECT m FROM %s m
55
                    WHERE m.systems_id = :starSystemId AND
56
                        m.sx BETWEEN :startSx AND :endSx AND
57
                        m.sy BETWEEN :startSy AND :endSy
58
                    ORDER BY m.sy, m.sx',
59
                    StarSystemMap::class
60
                )
61
            )
62
            ->setParameters([
63
                'starSystemId' => $starSystem,
64
                'startSx' => $startSx,
65
                'endSx' => $endSx,
66
                'startSy' => $startSy,
67
                'endSy' => $endSy
68
            ])
69
            ->getResult();
70
    }
71
72
    public function getRandomFieldsForAstroMeasurement(int $starSystemId): array
73
    {
74
        $result = [];
75
76
        $rsm = new ResultSetMapping();
77
        $rsm->addScalarResult('id', 'id', 'integer');
78
79
        $userColonyFields = $this->getEntityManager()
80
            ->createNativeQuery(
81
                'SELECT sm.id as id
82
                FROM stu_sys_map sm
83
                WHERE sm.systems_id = :systemId
84
                AND EXISTS (SELECT c.id
85
                            FROM stu_colonies c
86
                            WHERE c.starsystem_map_id = sm.id
87
                            AND c.user_id != :noOne)
88
                ORDER BY RANDOM()
89
                LIMIT 2',
90
                $rsm
91
            )
92
            ->setParameters([
93
                'systemId' => $starSystemId,
94
                'noOne' => UserEnum::USER_NOONE
95
            ])
96
            ->getResult();
97
98
        $result = array_merge($result, $userColonyFields);
99
100
        $otherColonyFields = $this->getEntityManager()
101
            ->createNativeQuery(
102
                'SELECT sm.id as id
103
                FROM stu_sys_map sm
104
                JOIN stu_map_ftypes ft
105
                ON sm.field_id = ft.id
106
                JOIN stu_colonies_classes cc
107
                ON ft.colonies_classes_id = cc.id
108
                WHERE sm.systems_id = :systemId
109
                AND ft.colonies_classes_id IS NOT NULL
110
                AND cc.type < 3
111
                AND sm.id NOT IN (:ids)
112
                ORDER BY RANDOM()
113
                LIMIT :theLimit',
114
                $rsm
115
            )
116
            ->setParameters([
117
                'systemId' => $starSystemId,
118
                'ids' => count($result) > 0 ? $result : [0],
119
                'theLimit' => AstronomicalMappingEnum::MEASUREMENT_COUNT - count($result)
120
            ])
121
            ->getResult();
122
123
        $result = array_merge($result, $otherColonyFields);
124
125
        if (count($result) < AstronomicalMappingEnum::MEASUREMENT_COUNT) {
126
            $otherFields = $this->getEntityManager()
127
                ->createNativeQuery(
128
                    'SELECT sm.id as id
129
                    FROM stu_sys_map sm
130
                    JOIN stu_map_ftypes ft
131
                    ON sm.field_id = ft.id
132
                    WHERE sm.systems_id = :systemId
133
                    AND ft.x_damage_system <= 10
134
                    AND ft.x_damage <= 10
135
                    ORDER BY RANDOM()
136
                    LIMIT :theLimit',
137
                    $rsm
138
                )
139
                ->setParameters([
140
                    'systemId' => $starSystemId,
141
                    'theLimit' => AstronomicalMappingEnum::MEASUREMENT_COUNT - count($result)
142
                ])
143
                ->getResult();
144
145
            $result = array_merge($result, $otherFields);
146
        }
147
148
        return array_values($result);
149
    }
150
151
    public function getRumpCategoryInfo(int $cx, int $cy): array
152
    {
153
        $rsm = new ResultSetMapping();
154
        $rsm->addScalarResult('category_name', 'category_name', 'string');
155
        $rsm->addScalarResult('amount', 'amount', 'integer');
156
157
        return $this->getEntityManager()
158
            ->createNativeQuery(
159
                'SELECT rc.name as category_name, count(*) as amount
160
                FROM stu_ships s
161
                JOIN stu_rumps r
162
                ON s.rumps_id = r.id
163
                JOIN stu_rumps_categories rc
164
                ON r.category_id = rc.id
165
                WHERE s.cx = :cx
166
                AND s.cy = :cy
167
                AND NOT EXISTS (SELECT ss.id
168
                                    FROM stu_ship_system ss
169
                                    WHERE s.id = ss.ship_id
170
                                    AND ss.system_type = :systemId
171
                                    AND ss.mode > 1)
172
                GROUP BY rc.name
173
                ORDER BY 2 desc',
174
                $rsm
175
            )
176
            ->setParameters([
177
                'cx' => $cx,
178
                'cy' => $cy,
179
                'systemId' => ShipSystemTypeEnum::SYSTEM_CLOAK
180
            ])
181
            ->getResult();
182
    }
183
184
    public function save(StarSystemMapInterface $starSystemMap): void
185
    {
186
        $em = $this->getEntityManager();
187
188
        $em->persist($starSystemMap);
189
    }
190
191
    public function getForSubspaceEllipseCreation(): array
192
    {
193
        $rsm = new ResultSetMapping();
194
        $rsm->addScalarResult('sys_map_id', 'sys_map_id', 'integer');
195
        $rsm->addScalarResult('descriminator', 'descriminator', 'integer');
196
197
        $sysMapIds = $this->getEntityManager()
198
            ->createNativeQuery(
199
                'select sys_map_id, descriminator from (
200
                    select coalesce(sum(r1.tractor_mass) / 10, 0)
201
                            + coalesce(sum(r2.tractor_mass), 0)
202
                            + coalesce((select count(ca.id)
203
                                            from stu_crew_assign ca
204
                                            join stu_ships s
205
                                            on ca.ship_id = s.id
206
                                            where s.user_id >= :firstUserId
207
                                            and s.starsystem_map_id = sm.id)
208
                                        * (select count(ss.id)
209
                                            from stu_ship_system ss
210
                                            join stu_ships s
211
                                            on ss.ship_id = s.id
212
                                            where s.user_id >= :firstUserId
213
                                            and s.starsystem_map_id = sm.id
214
                                            and ss.mode > :mode)
215
                                        * 100, 0) - :threshold as descriminator,
216
                        sm.id as sys_map_id from stu_sys_map sm
217
                        join stu_ships s
218
                        on s.starsystem_map_id = sm.id
219
                        left join stu_rumps r1
220
                        on s.rumps_id = r1.id
221
                        and r1.category_id = :rumpCategory
222
                        left join stu_rumps r2
223
                        on s.rumps_id = r2.id
224
                        and r2.category_id != :rumpCategory
225
                        where s.user_id >= :firstUserId
226
                        group by sm.id) as foo
227
                    where descriminator > 0',
228
                $rsm
229
            )
230
            ->setParameters([
231
                'threshold' => SubspaceEllipseHandler::MASS_CALCULATION_THRESHOLD,
232
                'rumpCategory' => ShipRumpEnum::SHIP_CATEGORY_STATION,
233
                'firstUserId' => UserEnum::USER_FIRST_ID,
234
                'mode' => ShipSystemModeEnum::MODE_OFF
235
            ])
236
            ->getResult();
237
238
        $finalIds = [];
239
        foreach ($sysMapIds as $entry) {
240
            $descriminator = $entry['descriminator'];
241
242
            if ((int)ceil($descriminator / 500000 + 25) > rand(1, 100)) {
243
                $finalIds[] = $entry['sys_map_id'];
244
            }
245
        }
246
247
        return $this->getEntityManager()
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this->getEntityM...finalIds))->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
248
            ->createQuery(
249
                sprintf(
250
                    'SELECT sm FROM %s sm
251
                    WHERE sm.id in (:ids)',
252
                    StarSystemMap::class
253
                )
254
            )
255
            ->setParameters([
256
                'ids' => $finalIds
257
            ])
258
            ->getResult();
259
    }
260
}
261