Pokered Save Editor 2
Pokemon Red & Blue save file editor - Qt 6 C++/QML
Loading...
Searching...
No Matches
areapokemon.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#include "./areapokemon.h"
23#include "../../qmlownership.h"
24#include "../../savefile.h"
27#include <pse-db/pokemon.h>
28#include <pse-common/random.h>
29#include <pse-db/mapsdb.h>
32
37
39{
40 if(random)
41 randomize();
42}
43
45{
46 return level < a.level;
47}
48
50{
51 return level > a.level;
52}
53
55{
56 reset();
57
58 auto mon = PokemonDB::inst()->getIndAt(
59 "dex" + QString::number(Random::inst()->rangeExclusive(0, pokemonDexCount)));
60
61 index = mon->ind;
63
66}
67
69{
70 index = 0;
72
73 level = 0;
75}
76
78{
79 this->index = index;
81
82 this->level = level;
84}
85
87{
88 index = it->getByte();
90
91 level = it->getByte();
93}
94
100
102{
103 // Pre-generate 10 Pokemon each, keep these until the class is deleted
104 for(var8 i = 0; i < wildMonsCount; i++) {
105 grassMons[i] = new AreaPokemonWild;
106 waterMons[i] = new AreaPokemonWild;
107 }
108
109 load(saveFile);
110}
111
113{
114 for(var8 i = 0; i < wildMonsCount; i++) {
115 grassMons[i]->deleteLater();
116 waterMons[i]->deleteLater();
117 }
118}
119
121{
122 return wildMonsCount;
123}
124
126{
127 return qmlCppOwned(grassMons[ind]);
128}
129
130void AreaPokemon::grassMonsSwap(int from, int to)
131{
132 auto eFrom = grassMons[from];
133 auto eTo = grassMons[to];
134
135 grassMons[from] = eTo;
136 grassMons[to] = eFrom;
137
139}
140
142{
143 return wildMonsCount;
144}
145
147{
148 return qmlCppOwned(waterMons[ind]);
149}
150
151void AreaPokemon::waterMonsSwap(int from, int to)
152{
153 auto eFrom = waterMons[from];
154 auto eTo = waterMons[to];
155
156 waterMons[from] = eTo;
157 waterMons[to] = eFrom;
158
160}
161
163{
164 reset();
165
166 if(saveFile == nullptr)
167 return;
168
169 auto toolset = saveFile->toolset;
170 auto it = saveFile->iterator();
171
172 pauseMons3Steps = toolset->getBit(0x29D8, 1, 0);
174
175 grassRate = toolset->getByte(0x2B33);
177
178 waterRate = toolset->getByte(0x2B50);
180
181 // Only load wild land Pokemon if present. An encounter rate of zero means
182 // They're not present.
183 if(grassRate > 0) {
184 it->offsetTo(0x2B34);
185 for(var8 i = 0; i < wildMonsCount; i++)
186 grassMons[i]->load(it);
188 }
189
190 if(waterRate > 0) {
191 it->offsetTo(0x2B51);
192 for(var8 i = 0; i < wildMonsCount; i++)
193 waterMons[i]->load(it);
195 }
196
197 delete it;
198}
199
201{
202 auto toolset = saveFile->toolset;
203 auto it = saveFile->iterator();
204
205 toolset->setBit(0x29D8, 1, 0, pauseMons3Steps);
206 toolset->setByte(0x2B33, grassRate);
207 toolset->setByte(0x2B50, waterRate);
208
209 // Only save wild land Pokemon if present. An encounter rate of zero means
210 // They're not present.
211 if(grassRate > 0) {
212 it->offsetTo(0x2B34);
213 for(var8 i = 0; i < wildMonsCount; i++)
214 grassMons[i]->save(it);
215 }
216
217 if(waterRate > 0) {
218 it->offsetTo(0x2B51);
219 for(var8 i = 0; i < wildMonsCount; i++)
220 waterMons[i]->save(it);
221 }
222
223 delete it;
224}
225
227{
228 grassRate = 0;
230
231 waterRate = 0;
233
234 pauseMons3Steps = false;
236
237 for(var8 i = 0; i < wildMonsCount; i++) {
238 grassMons[i]->reset();
240
241 waterMons[i]->reset();
243 }
244}
245
247{
248 reset();
249
250 // Give a reasonable grass and water rate randomization
253
256
257 if(grassRate > 0)
258 for(var8 i = 0; i < wildMonsCount; i++) {
259 grassMons[i]->randomize();
261 }
262
263 if(waterRate > 0)
264 for(var8 i = 0; i < wildMonsCount; i++) {
265 waterMons[i]->randomize();
267 }
268}
269
271{
272 reset();
273
274 // Give a reasonable grass and water rate randomization
275 grassRate = (map == nullptr || map->getMonRate() < 0)
276 ? 0
277 : map->getMonRate();
279
280 waterRate = (map == nullptr || map->getMonRateWater() < 0)
281 ? 0
282 : map->getMonRateWater();
284
285 if(map == nullptr)
286 return;
287
288 bool redOrBlue = Random::inst()->flipCoin();
289 auto monData = (redOrBlue) ? map->getMonsRed() : map->getMonsBlue();
290
291 for(int i = 0; i < monData.size(); i++) {
292 grassMons[i]->index = monData.at(i)->getToPokemon()->ind;
293 grassMons[i]->indexChanged();
295
296 grassMons[i]->level = monData.at(i)->getLevel();
297 grassMons[i]->levelChanged();
299 }
300
301 auto monDataWater = map->getMonsWater();
302
303 for(int i = 0; i < monDataWater.size(); i++) {
304 waterMons[i]->index = monDataWater.at(i)->getToPokemon()->ind;
305 waterMons[i]->indexChanged();
307
308 waterMons[i]->level = monDataWater.at(i)->getLevel();
309 waterMons[i]->levelChanged();
311 }
312}
constexpr var8 wildMonsCount
Wild-encounter slots per list (grass or water).
Definition areapokemon.h:26
One wild-encounter slot: a species index and a level.
Definition areapokemon.h:37
void reset()
Blank this slot.
int index
Species index (backs property).
Definition areapokemon.h:66
bool operator>(const AreaPokemonWild &a)
Order by encounter value.
void save(SaveFileIterator *it)
Write one entry at the cursor.
bool operator<(const AreaPokemonWild &a)
Order by encounter value.
AreaPokemonWild(int index=0, int level=0)
< Species index.
protected::void indexChanged()
int level
Encounter level (backs property).
Definition areapokemon.h:67
void load(SaveFileIterator *it)
Read one entry at the cursor.
void randomize()
Generates a random Pokemon from any dex entry and level.
void waterMonsSwap(int from, int to)
Reorder water slots.
int waterMonsCount()
Water-slot count (wildMonsCount).
void grassMonsChanged()
void load(SaveFile *saveFile=nullptr)
Expand both encounter tables from the save.
AreaPokemonWild * grassMons[wildMonsCount]
The 10 grass-encounter slots.
void grassMonsSwap(int from, int to)
Reorder grass slots.
void waterRateChanged()
bool pauseMons3Steps
void randomize()
Randomize the encounter tables.
void waterMonsChanged()
AreaPokemonWild * waterMons[wildMonsCount]
The 10 water-encounter slots.
void setTo(MapDBEntry *map)
Set encounters from map.
void pauseMons3StepsChanged()
int grassMonsCount()
Grass-slot count (wildMonsCount).
AreaPokemonWild * grassMonsAt(int ind)
Grass slot ind (GC-protected return).
virtual ~AreaPokemon()
AreaPokemonWild * waterMonsAt(int ind)
Water slot ind (GC-protected return).
void reset()
Blank both encounter tables.
protected::void grassRateChanged()
AreaPokemon(SaveFile *saveFile=nullptr)
< Grass encounter rate (0 = none).
void save(SaveFile *saveFile)
Flatten both encounter tables to the save.
static PokemonDB * inst()
< Number of species.
Definition pokemon.cpp:183
PokemonDBEntry * getIndAt(const QString &key) const
Species by name key (for QML).
Definition pokemon.cpp:199
bool flipCoin() const
50/50 coin flip via the integer path (chanceSuccess(50)).
Definition random.cpp:84
int rangeInclusive(const int start, const int end) const
Random integer in the closed interval [start, end].
Definition random.cpp:42
static Random * inst()
< Convenience 50% coin flip (integer path), readable from QML.
Definition random.cpp:31
A moving cursor over a SaveFile, layering auto-advancing reads/writes on top of SaveFileToolset.
void setBit(var8 size, var8 bit, bool value, bool reverse=false)
Set a bit at the cursor.
void setByte(var8 val, var16 padding=0)
Write a byte at the cursor; advances.
var8 getByte(var16 padding=0)
Read a byte at the cursor; advances.
One loaded save: the raw 32 KB bytes, their expanded object tree, and the tools that move between the...
Definition savefile.h:46
SaveFileToolset * toolset
Tools to operate directly on the raw sav file data.
Definition savefile.h:117
SaveFileIterator * iterator()
Returns a unique iterator that's setup to iterate over the raw sav file data.
Definition savefile.cpp:53
var8e var8
Everyday 8-bit alias. Exact (not "fastest") to dodge the pointer-width bug noted above.
Definition types.h:124
constexpr var8 pokemonDexCount
Number of species.
Definition pokemon.h:28
constexpr var8 pokemonLevelMax
Maximum level.
Definition pokemon.h:29
qmlCppOwned() – protect Q_INVOKABLE QObject returns from QML's GC.
static T * qmlCppOwned(T *obj)
Hand QML CppOwnership of a C++-owned QObject returned from a Q_INVOKABLE.
One map's complete static definition – the root of the MapDBEntry family.
Definition mapdbentry.h:56
int getMonRate() const
const QVector< MapDBEntryWildMon * > getMonsBlue() const
Blue-version wild encounters.
const QVector< MapDBEntryWildMon * > getMonsWater() const
Water wild encounters.
int getMonRateWater() const
const QVector< MapDBEntryWildMon * > getMonsRed() const
Red-version wild encounters.