11/* BDSP RNG
22 *
33 * From: https://github.com/PokemonAutomation/
4- *
5- * Pokemon generation for Brilliant Diamond / Shining Pearl, ported from
6- * PokeFinder's Gen 8 generators.
7- *
8- * The main game RNG is xorshift128 (see Pokemon_Xorshift128.h). Most values are
9- * read through bdsp_gen_transform(). Some encounters then seed a separate
10- * Xoroshiro128+ from a single xorshift128 output and generate everything else
11- * from that.
12- *
13- * Only the static/roamer and trainer-ID paths are implemented. Wild and egg
14- * generation additionally need per-species data and encounter tables, which
15- * this project does not have for BDSP yet.
16- *
4+ *
175 */
186
197#ifndef PokemonAutomation_Pokemon_BdspRng_H
@@ -34,21 +22,13 @@ namespace PokemonAutomation{
3422namespace Pokemon {
3523
3624
37- //
38- // Xoroshiro128+, BDSP flavor
39- //
40-
4125uint64_t bdsp_splitmix64 (uint64_t seed);
4226
43- // Sign-extend a 32-bit RNG output to 64 bits. Egg generation does this before
44- // seeding; roamer generation does not.
27+
4528inline uint64_t bdsp_sign_extend_seed (uint32_t seed){
4629 return (uint64_t )(int64_t )(int32_t )seed;
4730}
4831
49- // Same core as Xoroshiro128Plus, but seeded through splitmix and bounded
50- // differently. Do not substitute Xoroshiro128Plus::nextInt() here: it uses
51- // power-of-two rejection sampling, which is what Sword/Shield does, not BDSP.
5232class XoroshiroBDSP {
5333public:
5434 explicit XoroshiroBDSP (uint64_t seed);
@@ -61,11 +41,6 @@ class XoroshiroBDSP{
6141};
6242
6343
64-
65- //
66- // Results
67- //
68-
6944enum class BdspShiny : uint8_t {
7045 None = 0 ,
7146 Star = 1 ,
@@ -81,9 +56,6 @@ enum class BdspGender : uint8_t{
8156const char * bdsp_gender_name (BdspGender gender);
8257
8358struct BdspIVs {
84- // BDSP's order, which is also PokeFinder's: HP, Atk, Def, SpA, SpD, Spe.
85- // This is NOT the Gen 3 order used by AdvIVs in Pokemon_AdvRng.h, which puts
86- // Speed at index 3. Do not unify them.
8759 uint8_t hp = 0 ;
8860 uint8_t attack = 0 ;
8961 uint8_t defense = 0 ;
@@ -116,59 +88,33 @@ struct BdspIdResult{
11688 uint32_t sidtid = 0 ;
11789 uint16_t tid = 0 ;
11890 uint16_t sid = 0 ;
119- // The 6-digit number the trainer card shows under "ID No.". Derived from the
120- // whole 32-bit draw, so it is neither the TID nor the SID.
12191 uint32_t display_tid = 0 ;
12292
12393 uint16_t tsv () const { return (uint16_t )(tid ^ sid); }
12494 std::string to_string () const ;
12595};
12696
12797
128- // Natures are indexed in the game's own order (0 = Hardy), which is not the
129- // order of NatureCheckerValue. Convert before comparing against anything from
130- // the UI or from an IV/nature reader.
13198const char * bdsp_nature_name (uint8_t nature);
13299NatureCheckerValue bdsp_nature_to_checker_value (uint8_t nature);
133100
134- // psv == tsv is a square shiny; a difference under 16 is a star.
101+ // psv == tsv is a square shiny; a difference under 16 is a star
135102BdspShiny bdsp_get_shiny (uint32_t pid, uint16_t tsv);
136103bool bdsp_is_shiny (uint32_t pid, uint16_t tsv);
137104
138105
139-
140- //
141- // Generation
142- //
143-
144- // Passed as "synchronize_nature" when no Synchronize lead is active.
145106const uint8_t BDSP_NO_SYNCHRONIZE = 0xff ;
146107
147108struct BdspStaticTemplate {
148109 std::string species;
149110 uint8_t level = 1 ;
150-
151- // How many IVs are forced to 31 before the rest are rolled.
152111 uint8_t guaranteed_ivs = 0 ;
153-
154- // 0 or 1 forces that ability slot. 2 is the hidden ability, which still
155- // burns one roll. 3 rolls between the two normal abilities.
156112 uint8_t ability_kind = 3 ;
157-
158- // 255 = genderless, 254 = always female, 0 = always male. Otherwise a roll
159- // must come in under this value to be female.
160113 uint8_t gender_ratio = 255 ;
161-
162- // Shiny-locked encounters still roll a PID, then force it non-shiny.
163114 bool shiny_locked = false ;
164-
165- // Roamers (Cresselia, Mesprit) take one value from the main RNG as the EC,
166- // then generate everything else from a Xoroshiro seeded with it.
167115 bool roamer = false ;
168116};
169117
170- // Each of these takes the generator positioned at the target advance. The copy
171- // is deliberate: callers keep their own position.
172118BdspPokemonResult bdsp_generate_static (
173119 Xorshift128 rng, const BdspStaticTemplate& tmpl,
174120 uint16_t tsv, uint8_t synchronize_nature = BDSP_NO_SYNCHRONIZE
@@ -177,7 +123,6 @@ BdspPokemonResult bdsp_generate_roamer(
177123 Xorshift128 rng, const BdspStaticTemplate& tmpl,
178124 uint16_t tsv, uint8_t synchronize_nature = BDSP_NO_SYNCHRONIZE
179125);
180- // Dispatches on tmpl.roamer.
181126BdspPokemonResult bdsp_generate (
182127 Xorshift128 rng, const BdspStaticTemplate& tmpl,
183128 uint16_t tsv, uint8_t synchronize_nature = BDSP_NO_SYNCHRONIZE
@@ -186,11 +131,6 @@ BdspPokemonResult bdsp_generate(
186131BdspIdResult bdsp_generate_id (Xorshift128 rng);
187132
188133
189-
190- //
191- // Filtering and searching
192- //
193-
194134struct BdspRngHit {
195135 uint64_t advances = 0 ;
196136 Xorshift128State state;
@@ -209,20 +149,8 @@ class BdspStaticSearcher{
209149
210150 const BdspStaticTemplate& pokemon_template () const { return m_template; }
211151
212- // The Pokemon produced "advances" steps after the base state.
213- //
214- // This jumps from the base state on every call, which is the right thing for one
215- // advance and the wrong thing for a range: use scan() to sweep one, or the cost
216- // is a fresh jump per advance rather than a single step.
217152 BdspPokemonResult generate (uint64_t advances) const ;
218153
219- // Every advance in [min_advances, max_advances] that "accept" accepts, earliest
220- // first, or just the first of them if "stop_at_first".
221- //
222- // Walks forward one advance at a time through a sliding window, so sweeping a
223- // whole search window costs about what a single generate() does. The predicate
224- // is the caller's because programs filter through the shared UI tables, and a
225- // second filter type here would only be those tables written out twice.
226154 std::vector<BdspRngHit> scan (
227155 uint64_t min_advances, uint64_t max_advances,
228156 const std::function<bool (const BdspPokemonResult&)>& accept,
0 commit comments