Pokered Save Editor 2
Pokemon Red & Blue save file editor - Qt 6 C++/QML
Loading...
Searching...
No Matches
mapdbentryconnect.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 Twilight
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15*/
16
22
23#include <QDebug>
24#include <QQmlEngine>
25#include <pse-common/utility.h>
26#include "./mapdbentryconnect.h"
27#include "../mapsdb.h"
28#include "./mapdbentry.h"
29
34 MapDBEntry* const fromMap,
35 const QJsonValue& data)
36{
38 // Set Direction
39 this->dir = dir;
40
41 // Save from map
42 this->fromMap = fromMap;
44
45 // Set other values from JSON
46 map = data["map"].toString();
47 stripMove = data["stripMove"].toDouble();
48 stripOffset = data["stripOffset"].toDouble();
49 flag = data["flag"].toBool(false);
50}
51
53{
54 toMap = MapsDB::inst()->getInd().value(map, nullptr);
55
56#ifdef QT_DEBUG
57 if(toMap == nullptr)
58 qCritical() << "Map Connect: " << map << ", could not be deep linked to";
59#endif
60}
61
63{
64 static bool once = false;
65 if(once)
66 return;
67
68 qmlRegisterUncreatableType<MapDBEntryConnect>(
69 "PSE.DB.MapDBEntryConnect", 1, 0, "MapDBEntryConnect", "Can't instantiate in QML");
70 once = true;
71}
72
77
78void MapDBEntryConnect::qmlProtect(const QQmlEngine* const engine) const
79{
80 Utility::qmlProtectUtil(this, engine);
81}
82
87
89{
90 return toMap;
91}
92
94{
95 return flag;
96}
97
99{
100 return stripOffset;
101}
102
104{
105 return stripMove;
106}
107
112
113const QString MapDBEntryConnect::getMap() const
114{
115 return map;
116}
117
119{
120 // Stop if toMap is not accessible or it doesn't have a data pointer
121 // A valid toMap is required
122 if(toMap == nullptr ||
123 toMap->getDataPtr() <= 0 ||
124 toMap->getWidth() <= 0 ||
125 toMap->getHeight() <= 0)
126 return 0;
127
128 int ret = 0;
129
130 int dataPtr = toMap->getDataPtr();
131 int toWidth = toMap->getWidth();
132 int toHeight = toMap->getHeight();
133
134 // These can vary based on direction
135 if(dir == ConnectDir::NORTH) {
136 ret = dataPtr + (toWidth * (toHeight - 3)) + stripOffset;
137 }
138 else if(dir == ConnectDir::SOUTH) {
139 ret = dataPtr + stripOffset;
140 }
141 else if(dir == ConnectDir::WEST) {
142 ret = dataPtr + (toWidth * stripOffset) + toWidth - 3;
143 }
144 else {
145 ret = dataPtr + (toWidth * stripOffset);
146 }
147
148 return ret;
149}
150
152{
153 if(fromMap == nullptr ||
154 fromMap->getHeight() <= 0 ||
155 fromMap->getWidth() <= 0)
156 return 0;
157
158 int ret = 0;
159 int fromHeight = fromMap->getHeight();
160 int fromWidth = fromMap->getWidth();
161
162 if(dir == ConnectDir::NORTH) {
163 ret = worldMapPtr + 3 + stripMove;
164 }
165 else if(dir == ConnectDir::SOUTH) {
166 ret = worldMapPtr + 3 + (fromHeight + 3) * (fromWidth + 6) + stripMove;
167 }
168 else if(dir == ConnectDir::WEST) {
169 ret = worldMapPtr + (fromWidth + 6) * (stripMove + 3);
170 }
171 else {
172 ret = worldMapPtr - 3 + (fromWidth + 6) * (stripMove + 4);
173 }
174
175 return ret;
176}
177
179{
180 if(fromMap == nullptr ||
181 toMap == nullptr ||
182 fromMap->getWidth() <= 0 ||
183 toMap->getWidth() <= 0 ||
184 fromMap->getHeight() <= 0 ||
185 toMap->getHeight() <= 0)
186 return 0;
187
188 int ret = 0;
189 int fromWidth = fromMap->getWidth();
190 int toWidth = toMap->getWidth();
191 int fromHeight = fromMap->getHeight();
192 int toHeight = toMap->getHeight();
193
194 if(dir == ConnectDir::NORTH) {
195 if(fromWidth < toWidth)
196 ret = fromWidth - stripMove + 3;
197 else
198 ret = toWidth - stripOffset;
199 }
200 else if(dir == ConnectDir::SOUTH) {
201 if(fromWidth < toWidth) {
202 if(flag)
203 ret = fromWidth - stripMove + 3;
204 else
205 ret = fromWidth - stripMove;
206 }
207 else {
208 ret = toWidth - stripOffset;
209 }
210 }
211 else if(dir == ConnectDir::WEST) {
212 if(fromHeight < toHeight)
213 ret = fromHeight - stripMove + 3;
214 else
215 ret = toHeight - stripOffset;
216 }
217 else {
218 if(fromHeight < toHeight) {
219 if(flag)
220 ret = fromHeight - stripMove + 3;
221 else
222 ret = fromHeight - stripMove;
223 }
224 else {
225 ret = toHeight - stripOffset;
226 }
227 }
228
229 return ret;
230}
231
233{
234 if(toMap == nullptr ||
235 toMap->getHeight() <= 0)
236 return 0;
237
238 int ret;
239 int toHeight = toMap->getHeight();
240
241 if(dir == ConnectDir::NORTH) {
242 ret = (toHeight * 2) - 1;
243 }
244 else if(dir == ConnectDir::SOUTH) {
245 ret = 0;
246 }
247 else if(dir == ConnectDir::WEST) {
248 ret = (stripMove - stripOffset) * -2;
249 }
250 else {
251 ret = (stripMove - stripOffset) * -2;
252 }
253
254 return ret;
255}
256
258{
259 // Same "valid toMap required" guard as yAlign()/window()/stripSize(): a missing
260 // map or a non-positive width yields 0. The `<= 0` was missing here (a copy-paste
261 // typo), so the bare `toMap->getWidth()` inverted the test -- it returned 0 for
262 // every real map and only computed when width was 0. Confirmed against the
263 // connection-data formulas in notes/reference/gen1-knowledge.md (xAlign mirrors
264 // yAlign, which matches the documented North Y-align = (height*2)-1).
265 if(toMap == nullptr ||
266 toMap->getWidth() <= 0)
267 return 0;
268
269 int ret;
270 int toWidth = toMap->getWidth();
271
272 if(dir == ConnectDir::NORTH) {
273 ret = (stripMove - stripOffset) * -2;
274 }
275 else if(dir == ConnectDir::SOUTH) {
276 ret = (stripMove - stripOffset) * -2;
277 }
278 else if(dir == ConnectDir::WEST) {
279 ret = (toWidth * 2) - 1;
280 }
281 else {
282 ret = 0;
283 }
284
285 return ret;
286}
287
289{
290 if(toMap == nullptr ||
291 toMap->getHeight() <= 0 ||
292 toMap->getWidth() <= 0)
293 return 0;
294
295 int ret;
296 int toHeight = toMap->getHeight();
297 int toWidth = toMap->getWidth();
298
299 if(dir == ConnectDir::NORTH) {
300 ret = worldMapPtr + 1 + (toHeight * (toWidth + 6));
301 }
302 else if(dir == ConnectDir::SOUTH) {
303 ret = worldMapPtr + 7 + toWidth;
304 }
305 else if(dir == ConnectDir::WEST) {
306 ret = worldMapPtr + 6 + (2 * toWidth);
307 }
308 else {
309 ret = worldMapPtr + 7 + toWidth;
310 }
311
312 return ret;
313}
static MapsDB * inst()
< Number of maps.
Definition mapsdb.cpp:35
const QHash< QString, MapDBEntry * > getInd() const
Name->map index.
Definition mapsdb.cpp:46
static void qmlProtectUtil(const QObject *const obj, const QQmlEngine *const engine)
Pin obj to C++ ownership so the QML engine never garbage-collects it.
Definition utility.cpp:63
const QString getMap() const
MapDBEntry * toMap
Resolved connected map (deepLink).
bool flag
+3 offset flag (purpose unknown; see note).
static const constexpr int worldMapPtr
< Strip source pointer.
int stripOffset
Strip position.
ConnectDir dir
Edge direction.
int stripMove
Strip centering.
void qmlRegister() const
Register with QML.
void qmlProtect(const QQmlEngine *const engine) const
Pin to C++ ownership.
MapDBEntry * fromMap
Owning map.
QString map
Connected map name.
MapDBEntry * getToMap() const
MapDBEntry * getParent() const
ConnectDir getDir() const
MapDBEntry * getFromMap() const
void deepLink()
Resolve the connected map.
ConnectDir
The four connectable edges.
MapDBEntryConnect()
Empty entry.