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

MapRepository::getExplored()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 42
c 0
b 0
f 0
nc 1
nop 5
dl 0
loc 47
ccs 0
cts 30
cp 0
crap 2
rs 9.248
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\ShipRumpEnum;
11
use Stu\Component\Ship\System\ShipSystemModeEnum;
12
use Stu\Module\PlayerSetting\Lib\UserEnum;
13
use Stu\Module\Starmap\Lib\ExploreableStarMap;
14
use Stu\Orm\Entity\Layer;
15
use Stu\Orm\Entity\Map;
16
use Stu\Orm\Entity\MapInterface;
17
18
/**
19
 * @extends EntityRepository<Map>
20
 */
21
final class MapRepository extends EntityRepository implements MapRepositoryInterface
22
{
23
    public function getAmountByLayer(int $layerId): int
24
    {
25
        return $this->count([
26
            'layer_id' => $layerId
27
        ]);
28
    }
29
30
    public function getAllOrdered(int $layerId): array
31
    {
32
        return $this->getEntityManager()
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this->getEntityM...$layerId))->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...
33
            ->createQuery(
34
                sprintf(
35
                    'SELECT m FROM %s m
36
                    JOIN %s l
37
                    WITH m.layer_id = l.id
38
                    WHERE m.cx BETWEEN 1 AND l.width
39
                    AND m.cy BETWEEN 1 AND l.height
40
                    AND m.layer_id = :layerId
41
                    ORDER BY m.cy, m.cx',
42
                    Map::class,
43
                    Layer::class
44
                )
45
            )
46
            ->setParameters([
47
                'layerId' => $layerId
48
            ])
49
            ->getResult();
50
    }
51
52
    public function getAllWithSystem(int $layerId): array
53
    {
54
        return $this->getEntityManager()
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this->getEntityM...$layerId))->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...
55
            ->createQuery(
56
                sprintf(
57
                    'SELECT m FROM %s m INDEX BY m.id
58
                    JOIN %s l
59
                    WITH m.layer_id = l.id
60
                    WHERE m.cx BETWEEN 1 AND l.width
61
                    AND m.cy BETWEEN 1 AND l.height
62
                    AND m.layer_id = :layerId
63
                    AND m.systems_id IS NOT null',
64
                    Map::class,
65
                    Layer::class
66
                )
67
            )
68
            ->setParameters([
69
                'layerId' => $layerId
70
            ])
71
            ->getResult();
72
    }
73
74
    public function getAllWithoutSystem(int $layerId): array
75
    {
76
        return $this->getEntityManager()
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this->getEntityM...$layerId))->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...
77
            ->createQuery(
78
                sprintf(
79
                    'SELECT m FROM %s m INDEX BY m.id
80
                    JOIN %s l
81
                    WITH m.layer_id = l.id
82
                    WHERE m.cx BETWEEN 1 AND l.width
83
                    AND m.cy BETWEEN 1 AND l.height
84
                    AND m.layer_id = :layerId
85
                    AND m.systems_id IS null',
86
                    Map::class,
87
                    Layer::class
88
                )
89
            )
90
            ->setParameters([
91
                'layerId' => $layerId
92
            ])
93
            ->getResult();
94
    }
95
96
    public function getByCoordinates(int $layerId, int $cx, int $cy): ?MapInterface
97
    {
98
        return $this->findOneBy([
99
            'layer_id' => $layerId,
100
            'cx' => $cx,
101
            'cy' => $cy
102
        ]);
103
    }
104
105
    public function getByCoordinateRange(
106
        int $layerId,
107
        int $startCx,
108
        int $endCx,
109
        int $startCy,
110
        int $endCy
111
    ): array {
112
        return $this->getEntityManager()
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this->getEntityM...> $endCy))->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...
113
            ->createQuery(
114
                sprintf(
115
                    'SELECT m FROM %s m
116
                    WHERE m.cx BETWEEN :startCx AND :endCx
117
                    AND m.cy BETWEEN :startCy AND :endCy
118
                    AND m.layer_id = :layerId
119
                    ORDER BY m.cy, m.cx',
120
                    Map::class
121
                )
122
            )
123
            ->setParameters([
124
                'layerId' => $layerId,
125
                'startCx' => $startCx,
126
                'endCx' => $endCx,
127
                'startCy' => $startCy,
128
                'endCy' => $endCy
129
            ])
130
            ->getResult();
131
    }
132
133
    public function save(MapInterface $map): void
134
    {
135
        $em = $this->getEntityManager();
136
137
        $em->persist($map);
138
    }
139
140
    public function getExplored(int $userId, int $layerId, int $startX, int $endX, int $cy): array
141
    {
142
        $rsm = new ResultSetMapping();
143
        $rsm->addEntityResult(ExploreableStarMap::class, 'm');
144
        $rsm->addFieldResult('m', 'id', 'id');
145
        $rsm->addFieldResult('m', 'cx', 'cx');
146
        $rsm->addFieldResult('m', 'cy', 'cy');
147
        $rsm->addFieldResult('m', 'field_id', 'field_id');
148
        $rsm->addFieldResult('m', 'bordertype_id', 'bordertype_id');
149
        $rsm->addFieldResult('m', 'user_id', 'user_id');
150
        $rsm->addFieldResult('m', 'mapped', 'mapped');
151
        $rsm->addFieldResult('m', 'system_name', 'system_name');
152
        $rsm->addFieldResult('m', 'influence_area_id', 'influence_area_id');
153
        $rsm->addFieldResult('m', 'region_id', 'region_id');
154
        $rsm->addFieldResult('m', 'tradepost_id', 'tradepost_id');
155
        $rsm->addFieldResult('m', 'region_description', 'region_description');
156
        $rsm->addFieldResult('m', 'layer_id', 'layer_id');
157
158
        return $this->getEntityManager()
159
            ->createNativeQuery(
160
                'SELECT m.id,m.cx,m.cy,m.field_id,m.systems_id,m.bordertype_id,um.user_id,
161
                    dbu.database_id as mapped, m.influence_area_id as influence_area_id, m.admin_region_id as region_id,
162
                    sys.name as system_name, m.layer_id,
163
                    (SELECT tp.id FROM stu_ships s JOIN stu_trade_posts tp ON s.id = tp.ship_id WHERE s.map_id = m.id) as tradepost_id,
164
                    (SELECT mr.description FROM stu_map_regions mr left join stu_database_user dbu on dbu.user_id = :userId and mr.database_id = dbu.database_id where m.region_id = mr.id) as region_description
165
                FROM stu_map m
166
                LEFT JOIN stu_user_map um
167
                    ON um.cy = m.cy AND um.cx = m.cx AND um.user_id = :userId AND um.layer_id = m.layer_id
168
                LEFT JOIN stu_systems sys
169
                    ON m.systems_id = sys.id
170
                LEFT JOIN stu_database_user dbu
171
                    ON dbu.user_id = :userId
172
                    AND sys.database_id = dbu.database_id
173
                WHERE m.cx BETWEEN :startX AND :endX
174
                AND m.cy = :cy
175
                AND m.layer_id = :layerId
176
                ORDER BY m.cx ASC',
177
                $rsm
178
            )
179
            ->setParameters([
180
                'layerId' => $layerId,
181
                'userId' => $userId,
182
                'startX' => $startX,
183
                'endX' => $endX,
184
                'cy' => $cy
185
            ])
186
            ->getResult();
187
    }
188
189
    public function getForSubspaceEllipseCreation(): array
190
    {
191
        $rsm = new ResultSetMapping();
192
        $rsm->addScalarResult('map_id', 'map_id', 'integer');
193
        $rsm->addScalarResult('descriminator', 'descriminator', 'integer');
194
195
        $mapIds = $this->getEntityManager()
196
            ->createNativeQuery(
197
                'select map_id, descriminator from (
198
                    select coalesce(sum(r1.tractor_mass) / 10, 0)
199
                            + coalesce(sum(r2.tractor_mass), 0)
200
                            + coalesce((select count(ca.id)
201
                                            from stu_crew_assign ca
202
                                            join stu_ships s
203
                                            on ca.ship_id = s.id
204
                                            where s.user_id >= :firstUserId
205
                                            and s.map_id = m.id)
206
                                        * (select count(ss.id)
207
                                            from stu_ship_system ss
208
                                            join stu_ships s
209
                                            on ss.ship_id = s.id
210
                                            where s.user_id >= :firstUserId
211
                                            and s.map_id = m.id
212
                                            and ss.mode > :mode)
213
                                        * 100, 0) - :threshold as descriminator,
214
                        m.id as map_id from stu_map m
215
                        join stu_ships s
216
                        on s.map_id = m.id
217
                        left join stu_rumps r1
218
                        on s.rumps_id = r1.id
219
                        and r1.category_id = :rumpCategory
220
                        left join stu_rumps r2
221
                        on s.rumps_id = r2.id
222
                        and r2.category_id != :rumpCategory
223
                        where s.user_id >= :firstUserId
224
                        group by m.id) as foo
225
                    where descriminator > 0',
226
                $rsm
227
            )
228
            ->setParameters([
229
                'threshold' => SubspaceEllipseHandler::MASS_CALCULATION_THRESHOLD,
230
                'rumpCategory' => ShipRumpEnum::SHIP_CATEGORY_STATION,
231
                'firstUserId' => UserEnum::USER_FIRST_ID,
232
                'mode' => ShipSystemModeEnum::MODE_OFF
233
            ])
234
            ->getResult();
235
236
        $finalIds = [];
237
        foreach ($mapIds as $entry) {
238
            $descriminator = $entry['descriminator'];
239
240
            if ((int)ceil($descriminator / 500000 + 25) > rand(1, 100)) {
241
                $finalIds[] = $entry['map_id'];
242
            }
243
        }
244
245
        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...
246
            ->createQuery(
247
                sprintf(
248
                    'SELECT m FROM %s m
249
                    WHERE m.id in (:ids)',
250
                    Map::class
251
                )
252
            )
253
            ->setParameters([
254
                'ids' => $finalIds
255
            ])
256
            ->getResult();
257
    }
258
}
259