diff --git a/include/mirror.h b/include/mirror.h index 4f1df10..ef69916 100644 --- a/include/mirror.h +++ b/include/mirror.h @@ -1,6 +1,7 @@ #ifndef MIRROR_H #define MIRROR_H #include +#include "pokemon.h" #define MEM_CRAM 0x0E000000 //!< Cart RAM @@ -16,7 +17,7 @@ extern vu32 memory_section_array[14]; extern char mem_name; void initalize_memory_locations(); -bool insert_pokemon(vu8 party_array[], int num); +bool insert_pokemon(Pokemon party_array[], int num); void reverse_endian(u8 *data, size_t size); void update_memory_buffer_checksum(); diff --git a/include/pokemon.h b/include/pokemon.h index 5135e64..ca45d12 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -7,7 +7,8 @@ class Pokemon { public: - Pokemon(int gen, int index, byte *party_data); + Pokemon(); + void load_data(int gen, int index, byte *party_data); void convert_to_gen_three(u32 random_32); void copy_from_to(byte *source, byte *destination, int size, bool reverse_endian); void alocate_data_chunks(byte *G, byte *A, byte *E, byte *M); @@ -18,6 +19,7 @@ public: byte* convert_text(byte *text_array, int size, int gen); u32 generate_pid(byte pid_species_index, byte nature, byte *pid_ivs, u32 seed); byte rand_reverse_mod(byte modulo_divisor, byte target_mod, u32 seed); + byte get_rand_gender_byte(byte index_num, byte attack_DVs, u32 seed); private: byte gen; diff --git a/include/pokemon_data.h b/include/pokemon_data.h index 5dd7c72..5216038 100644 --- a/include/pokemon_data.h +++ b/include/pokemon_data.h @@ -14,7 +14,12 @@ extern const u8 EXP_MAX[251]; extern const u32 EXP_TYPES[6]; +extern const int GENDER_THRESHOLDS[2][8]; +extern const u8 GENDER_RATIO[251]; +extern const bool NUM_ABILITIES[251]; u32 get_max_exp(int index_num); +u8 get_gender_threshold(int index_num, bool is_gen_3); +bool get_num_abilities(int index_num); #endif \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 907b5c1..b57d921 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -11,16 +11,26 @@ #include "pokemon.h" #include "random.h" +/*TODO: +- Add Pokemon to Pokedex +- Enable ribbon viewing +- Implement shiny +- Randomize base seed +- Double check that returns false when PC is full +- Fix abilities +*/ + // This file is autogenerated from the file in the graphics folder #include "metr.h" OBJ_ATTR obj_buffer[128]; OBJ_AFFINE *obj_aff_buffer = (OBJ_AFFINE *)obj_buffer; -byte party[441] = {0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x6, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0xFF, 0x25, 0xDA, 0xC9, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50}; +byte party_data[441] = {0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x6, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0xFF, 0x25, 0xDA, 155, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x9B, 0x0, 0x21, 0x2B, 0x0, 0x0, 0x25, 0xDA, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x21, 0x23, 0x1E, 0x0, 0x0, 0x46, 0x0, 0x85, 0x81, 0x5, 0x0, 0x0, 0x0, 0x13, 0x0, 0x13, 0x0, 0x0A, 0x0, 0x9, 0x0, 0x0B, 0x0, 0x0B, 0x0, 0x0A, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50, 0x82, 0x98, 0x8D, 0x83, 0x80, 0x90, 0x94, 0x88, 0x8B, 0x50, 0x50}; Poke_Random poke_rand(0x12162001); -Pokemon test(2, 0, &party[0]); + +Pokemon party[6] = {}; vu8 pkmn[480] = { 0x5C, 0xF2, 0x9B, 0x70, 0x9B, 0x2A, 0x81, 0xE4, 0xBB, 0xC6, 0xBC, 0xBF, 0xCC, 0xCE, 0xFF, 0x00, @@ -79,6 +89,16 @@ void load_sprite(void) oam_copy(oam_mem, obj_buffer, 1); // Update first OAM object } +void load_pokemon(byte *party_array, int gen){ + + for (int i = 0; i < 6; i++) + { + party[i].load_data(2, 0, &party_array[0]); + poke_rand.next_frame(); + party[i].convert_to_gen_three(poke_rand.get_rand()); + } +} + int main(void) { @@ -94,6 +114,7 @@ int main(void) initalize_memory_locations(); //load_sprite(); + load_pokemon(&party_data[0], 2); int frame = 0; int arr = 0; @@ -126,8 +147,7 @@ int main(void) } if (key_released(KEY_A)) { - test.convert_to_gen_three(poke_rand.get_rand()); - insert_pokemon(test.get_full_gen_3_array(), 1); + insert_pokemon(&party[0], 6); print = true; } @@ -152,12 +172,12 @@ int main(void) tte_write("Pokemon Injected!"); tte_set_pos(0,30); for(int i = 0; i < 80; i++){ - tte_write(intToHex(test.get_gen_3_data(i)).c_str()); + tte_write(intToHex(party[0].get_gen_3_data(i)).c_str()); tte_write(" "); } tte_set_pos(0, 110); for(int i = 0; i < 49; i++){ - tte_write(intToHex(test.get_unencrypted_data(i)).c_str()); + tte_write(intToHex(party[0].get_unencrypted_data(i)).c_str()); tte_write(" "); } diff --git a/source/mirror.cpp b/source/mirror.cpp index 70a01ad..444ef74 100644 --- a/source/mirror.cpp +++ b/source/mirror.cpp @@ -1,6 +1,9 @@ #include #include "mirror.h" #include "gba_flash.h" +#include "pokemon.h" + +#define pkmn_length 80 vu32 newest_save_offset = MEM_CRAM + SAVE_A_OFFSET; @@ -8,7 +11,6 @@ vu32 memory_section_array[14] = {}; u8 memory_buffer[0x1000]; char mem_name = 'A'; -vu8 pkmn_length = 80; // Fills the variables with the current offset information void initalize_memory_locations(){ @@ -31,11 +33,6 @@ void initalize_memory_locations(){ memory_section_array[mem_id] = newest_save_offset + (i * 0x1000); mem_id = (mem_id + 1) % 14; } - - - //for (vu32 i = 0; i < 14; i++){ - // memory_section_array[*(vu8*)(newest_save_offset + (i * 0x1000) + SECTION_ID_OFFSET)] = newest_save_offset + (i * 0x1000); - //} } // Reverses the endian of the given array @@ -49,7 +46,7 @@ void reverse_endian(u8 *data, size_t size){ } // Inserts "total_num" Pokemon from the party array -bool insert_pokemon(vu8 party_array[], int total_num){ +bool insert_pokemon(Pokemon party[], int total_num){ int pkmn_num = 0; int mem_section = 5; int byte_location = 4; @@ -71,7 +68,7 @@ bool insert_pokemon(vu8 party_array[], int total_num){ // Writes a byte of the current Pokemon to the current spot if (write_pkmn){ - memory_buffer[byte_location] = party_array[(pkmn_length * pkmn_num) + pkmn_byte]; + memory_buffer[byte_location] = party[pkmn_num].get_full_gen_3_array()[pkmn_byte]; byte_location++; pkmn_byte++; // Determines if the whole Pokemon has been written diff --git a/source/pokemon.cpp b/source/pokemon.cpp index ecd984d..88521d3 100644 --- a/source/pokemon.cpp +++ b/source/pokemon.cpp @@ -15,8 +15,11 @@ byte gen_2_char_array[0x80]{ 0xB4, 0xCA, 0xC7, 0xAE, 0x00, 0x00, 0xAC, 0xAB, 0xAD, 0x2D, 0x1B, 0x7C, 0x00, 0xEF, 0x00, 0xB5, 0xB7, 0xEC, 0xAD, 0xBA, 0xB8, 0xB6, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA}; +Pokemon::Pokemon(){ -Pokemon::Pokemon(int gen, int index, byte *party_data) +}; + +void Pokemon::load_data(int gen, int index, byte *party_data) { int party_offset = 21 + (index * pkmn_size); int ot_offset = 21 + (6 * pkmn_size) + (index * name_size); @@ -46,23 +49,27 @@ Pokemon::Pokemon(int gen, int index, byte *party_data) void Pokemon::convert_to_gen_three(u32 random_32) { - u32 n_pid = generate_pid(species_index, 0, &dvs[0], random_32); - for(int i = 0; i < 4; i++){ + // Generate PID + u32 n_pid = generate_pid(species_index, *(vu32 *)exp % 25, &dvs[0], random_32); + for (int i = 0; i < 4; i++) + { pid[i] = (n_pid >> (i * 8)) & 0xFF; } + // Make sure Level is not over 100 based on EXP if (*(vu32 *)exp > get_max_exp(species_index)) { *(vu32 *)exp = get_max_exp(species_index); } + // Separate the PP Up values from the Move PP values for (int i = 0; i < 4; i++) { pure_pp_values[i] = (pp_values[i] & 0b00111111); pp_bonus |= (pp_values[i] & 0b11000000) >> (6 - i * 2); } - // Convert IVs + // Convert and set IVs int hp_iv = 0; for (int i = 0; i < 4; i++) { @@ -77,7 +84,9 @@ void Pokemon::convert_to_gen_three(u32 random_32) ivs[i] = (ivs[i] * 2) + 1; iv_egg_ability |= ((ivs[i] & 0b11111) << (i * 5)); } - iv_egg_ability |= (pid[0] & 0x1) << 31; // Ability + + // Determine and set Ability + iv_egg_ability |= ((pid[0] & 0x1) ? get_num_abilities(species_index) : 1) << 31; // Origin info origin_info |= ((caught_data[0] & 0b10000000) << 8); // OT gender - We would shift left 15 bits, but the bit is already shifted over 7 @@ -128,7 +137,7 @@ void Pokemon::convert_to_gen_three(u32 random_32) { data_section_M[i + 4] = (iv_egg_ability >> (i * 8) & 0xFF); // Set IVs, Egg, and Ability } - copy_from_to(&ribbons[0], &data_section_M[8], 4, false); //Ribbons and Fateful Encounter + copy_from_to(&ribbons[0], &data_section_M[8], 4, false); // Ribbons and Fateful Encounter // Checksum: checksum = 0x0000; @@ -314,11 +323,14 @@ byte *Pokemon::convert_text(byte *text_array, int size, int gen) return text_array; } -u32 Pokemon::generate_pid(byte pid_species_index, byte nature, byte *pid_dvs, u32 seed){ +u32 Pokemon::generate_pid(byte pid_species_index, byte nature, byte *pid_dvs, u32 seed) +{ + // Set Unown Letter u32 new_pid = 0; byte letter = 0; Poke_Random random_num(seed); - if(pid_species_index == 0xC9){ + if (pid_species_index == 0xC9) + { letter |= ((pid_dvs[0] >> 5) & 0b11) << 6; letter |= ((pid_dvs[0] >> 1) & 0b11) << 4; letter |= ((pid_dvs[1] >> 5) & 0b11) << 2; @@ -326,16 +338,55 @@ u32 Pokemon::generate_pid(byte pid_species_index, byte nature, byte *pid_dvs, u3 letter = letter / 10; byte letter_mod = rand_reverse_mod(28, letter, random_num.get_rand()); - for(int i = 0; i < 4; i++){ + for (int i = 0; i < 4; i++) + { new_pid |= ((letter_mod >> (i * 2)) & 0b11) << (8 * i); } + + // Randomize rest of PID new_pid |= random_num.get_rand() & 0xFCFCFCFC; + + // Set Nature + while ((new_pid % 25) != nature) + { + new_pid = (new_pid & 0xFFFFFF00) | ((new_pid & 0xFF) + 4); + } + return new_pid; + } + else + { + // Set the correct gender for the Pokemon + new_pid |= get_rand_gender_byte(pid_species_index, ((pid_dvs[0] >> 4) & 0b1111), seed); + + // Randomize rest of PID + new_pid |= random_num.get_rand() & 0xFFFFFF00; + + while(new_pid % 25 != nature) + { + new_pid = new_pid + 256; + } return new_pid; - } else { - return 0xFEFCFDFA; } } -byte Pokemon::rand_reverse_mod(byte modulo_divisor, byte target_mod, u32 seed){ +byte Pokemon::rand_reverse_mod(byte modulo_divisor, byte target_mod, u32 seed) +{ return (modulo_divisor * convert_random(seed, 0, (255 - target_mod) / modulo_divisor)) + target_mod; +} + +byte Pokemon::get_rand_gender_byte(byte index_num, byte attack_DVs, u32 seed) +{ + byte gen2_threshold = get_gender_threshold(index_num, false); + byte gen3_threshold = get_gender_threshold(index_num, true); + if (gen2_threshold == -1) // Is one gender or is genderless + { + return convert_random(seed, 0, 256); + } else if (attack_DVs < gen2_threshold) // Is Female + { + return convert_random(seed, 0, gen3_threshold); + } + else // Is Male + { + return convert_random(seed, gen3_threshold, 256); + } } \ No newline at end of file diff --git a/source/pokemon_data.cpp b/source/pokemon_data.cpp index a5bf782..0fd36d2 100644 --- a/source/pokemon_data.cpp +++ b/source/pokemon_data.cpp @@ -7,10 +7,25 @@ const u32 EXP_TYPES[6] = { med_slow_max, slow_max}; +const int GENDER_THRESHOLDS[2][8]{ + {-1, 2, 4, 8, 12, 14, -1, -1}, + {-1, 31, 63, 127, 191, 225, -1, -1}}; + u32 get_max_exp(int index_num) { - return EXP_TYPES[EXP_MAX[index_num]]; -} + return EXP_TYPES[EXP_MAX[index_num - 1]]; +}; + +u8 get_gender_threshold(int index_num, bool is_gen_3) +{ + return GENDER_THRESHOLDS[is_gen_3][GENDER_RATIO[index_num - 1]]; +}; + +// If the Pokemon has two abilities it returns a 1, since ability 1 is valid. Otherwise it returns 0 +bool get_num_abilities(int index_num) +{ + return NUM_ABILITIES[index_num - 1]; +}; const u8 EXP_MAX[251] = { 2, // Bulbasaur @@ -265,3 +280,509 @@ const u8 EXP_MAX[251] = { 3, // Ho-Oh 2, // Celebi }; +const u8 GENDER_RATIO[251] = { + 1, // Bulbasaur [1♀:7♂] + 1, // Ivysaur [1♀:7♂] + 1, // Venusaur [1♀:7♂] + 1, // Charmander [1♀:7♂] + 1, // Charmeleon [1♀:7♂] + 1, // Charizard [1♀:7♂] + 1, // Squirtle [1♀:7♂] + 1, // Wartortle [1♀:7♂] + 1, // Blastoise [1♀:7♂] + 3, // Caterpie [1♀:1♂] + 3, // Metapod [1♀:1♂] + 3, // Butterfree [1♀:1♂] + 3, // Weedle [1♀:1♂] + 3, // Kakuna [1♀:1♂] + 3, // Beedrill [1♀:1♂] + 3, // Pidgey [1♀:1♂] + 3, // Pidgeotto [1♀:1♂] + 3, // Pidgeot [1♀:1♂] + 3, // Rattata [1♀:1♂] + 3, // Raticate [1♀:1♂] + 3, // Spearow [1♀:1♂] + 3, // Fearow [1♀:1♂] + 3, // Ekans [1♀:1♂] + 3, // Arbok [1♀:1♂] + 3, // Pikachu [1♀:1♂] + 3, // Raichu [1♀:1♂] + 3, // Sandshrew [1♀:1♂] + 3, // Sandslash [1♀:1♂] + 6, // Nidoran♀ [Female Only] + 6, // Nidorina [Female Only] + 6, // Nidoqueen [Female Only] + 0, // Nidoran♂ [Male Only] + 0, // Nidorino [Male Only] + 0, // Nidoking [Male Only] + 4, // Clefairy [3♀:1♂] + 4, // Clefable [3♀:1♂] + 4, // Vulpix [3♀:1♂] + 4, // Ninetales [3♀:1♂] + 4, // Jigglypuff [3♀:1♂] + 4, // Wigglytuff [3♀:1♂] + 3, // Zubat [1♀:1♂] + 3, // Golbat [1♀:1♂] + 3, // Oddish [1♀:1♂] + 3, // Gloom [1♀:1♂] + 3, // Vileplume [1♀:1♂] + 3, // Paras [1♀:1♂] + 3, // Parasect [1♀:1♂] + 3, // Venonat [1♀:1♂] + 3, // Venomoth [1♀:1♂] + 3, // Diglett [1♀:1♂] + 3, // Dugtrio [1♀:1♂] + 3, // Meowth [1♀:1♂] + 3, // Persian [1♀:1♂] + 3, // Psyduck [1♀:1♂] + 3, // Golduck [1♀:1♂] + 3, // Mankey [1♀:1♂] + 3, // Primeape [1♀:1♂] + 2, // Growlithe [1♀:3♂] + 2, // Arcanine [1♀:3♂] + 3, // Poliwag [1♀:1♂] + 3, // Poliwhirl [1♀:1♂] + 3, // Poliwrath [1♀:1♂] + 2, // Abra [1♀:3♂] + 2, // Kadabra [1♀:3♂] + 2, // Alakazam [1♀:3♂] + 2, // Machop [1♀:3♂] + 2, // Machoke [1♀:3♂] + 2, // Machamp [1♀:3♂] + 3, // Bellsprout [1♀:1♂] + 3, // Weepinbell [1♀:1♂] + 3, // Victreebel [1♀:1♂] + 3, // Tentacool [1♀:1♂] + 3, // Tentacruel [1♀:1♂] + 3, // Geodude [1♀:1♂] + 3, // Graveler [1♀:1♂] + 3, // Golem [1♀:1♂] + 3, // Ponyta [1♀:1♂] + 3, // Rapidash [1♀:1♂] + 3, // Slowpoke [1♀:1♂] + 3, // Slowbro [1♀:1♂] + 7, // Magnemite [Gender Unknown] + 7, // Magneton [Gender Unknown] + 3, // Farfetch'd [1♀:1♂] + 3, // Doduo [1♀:1♂] + 3, // Dodrio [1♀:1♂] + 3, // Seel [1♀:1♂] + 3, // Dewgong [1♀:1♂] + 3, // Grimer [1♀:1♂] + 3, // Muk [1♀:1♂] + 3, // Shellder [1♀:1♂] + 3, // Cloyster [1♀:1♂] + 3, // Gastly [1♀:1♂] + 3, // Haunter [1♀:1♂] + 3, // Gengar [1♀:1♂] + 3, // Onix [1♀:1♂] + 3, // Drowzee [1♀:1♂] + 3, // Hypno [1♀:1♂] + 3, // Krabby [1♀:1♂] + 3, // Kingler [1♀:1♂] + 7, // Voltorb [Gender Unknown] + 7, // Electrode [Gender Unknown] + 3, // Exeggcute [1♀:1♂] + 3, // Exeggutor [1♀:1♂] + 3, // Cubone [1♀:1♂] + 3, // Marowak [1♀:1♂] + 0, // Hitmonlee [Male Only] + 0, // Hitmonchan [Male Only] + 3, // Lickitung [1♀:1♂] + 3, // Koffing [1♀:1♂] + 3, // Weezing [1♀:1♂] + 3, // Rhyhorn [1♀:1♂] + 3, // Rhydon [1♀:1♂] + 6, // Chansey [Female Only] + 3, // Tangela [1♀:1♂] + 6, // Kangaskhan [Female Only] + 3, // Horsea [1♀:1♂] + 3, // Seadra [1♀:1♂] + 3, // Goldeen [1♀:1♂] + 3, // Seaking [1♀:1♂] + 7, // Staryu [Gender Unknown] + 7, // Starmie [Gender Unknown] + 3, // Mr. Mime [1♀:1♂] + 3, // Scyther [1♀:1♂] + 6, // Jynx [Female Only] + 2, // Electabuzz [1♀:3♂] + 2, // Magmar [1♀:3♂] + 3, // Pinsir [1♀:1♂] + 0, // Tauros [Male Only] + 3, // Magikarp [1♀:1♂] + 3, // Gyarados [1♀:1♂] + 3, // Lapras [1♀:1♂] + 7, // Ditto [Gender Unknown] + 1, // Eevee [1♀:7♂] + 1, // Vaporeon [1♀:7♂] + 1, // Jolteon [1♀:7♂] + 1, // Flareon [1♀:7♂] + 7, // Porygon [Gender Unknown] + 1, // Omanyte [1♀:7♂] + 1, // Omastar [1♀:7♂] + 1, // Kabuto [1♀:7♂] + 1, // Kabutops [1♀:7♂] + 1, // Aerodactyl [1♀:7♂] + 1, // Snorlax [1♀:7♂] + 7, // Articuno [Gender Unknown] + 7, // Zapdos [Gender Unknown] + 7, // Moltres [Gender Unknown] + 3, // Dratini [1♀:1♂] + 3, // Dragonair [1♀:1♂] + 3, // Dragonite [1♀:1♂] + 7, // Mewtwo [Gender Unknown] + 7, // Mew [Gender Unknown] + 1, // Chikorita [1♀:7♂] + 1, // Bayleef [1♀:7♂] + 1, // Meganium [1♀:7♂] + 1, // Cyndaquil [1♀:7♂] + 1, // Quilava [1♀:7♂] + 1, // Typhlosion [1♀:7♂] + 1, // Totodile [1♀:7♂] + 1, // Croconaw [1♀:7♂] + 1, // Feraligatr [1♀:7♂] + 3, // Sentret [1♀:1♂] + 3, // Furret [1♀:1♂] + 3, // Hoothoot [1♀:1♂] + 3, // Noctowl [1♀:1♂] + 3, // Ledyba [1♀:1♂] + 3, // Ledian [1♀:1♂] + 3, // Spinarak [1♀:1♂] + 3, // Ariados [1♀:1♂] + 3, // Crobat [1♀:1♂] + 3, // Chinchou [1♀:1♂] + 3, // Lanturn [1♀:1♂] + 3, // Pichu [1♀:1♂] + 4, // Cleffa [3♀:1♂] + 4, // Igglybuff [3♀:1♂] + 1, // Togepi [1♀:7♂] + 1, // Togetic [1♀:7♂] + 3, // Natu [1♀:1♂] + 3, // Xatu [1♀:1♂] + 3, // Mareep [1♀:1♂] + 3, // Flaaffy [1♀:1♂] + 3, // Ampharos [1♀:1♂] + 3, // Bellossom [1♀:1♂] + 3, // Marill [1♀:1♂] + 3, // Azumarill [1♀:1♂] + 3, // Sudowoodo [1♀:1♂] + 3, // Politoed [1♀:1♂] + 3, // Hoppip [1♀:1♂] + 3, // Skiploom [1♀:1♂] + 3, // Jumpluff [1♀:1♂] + 3, // Aipom [1♀:1♂] + 3, // Sunkern [1♀:1♂] + 3, // Sunflora [1♀:1♂] + 3, // Yanma [1♀:1♂] + 3, // Wooper [1♀:1♂] + 3, // Quagsire [1♀:1♂] + 1, // Espeon [1♀:7♂] + 1, // Umbreon [1♀:7♂] + 3, // Murkrow [1♀:1♂] + 3, // Slowking [1♀:1♂] + 3, // Misdreavus [1♀:1♂] + 7, // Unown [Gender Unknown] + 3, // Wobbuffet [1♀:1♂] + 3, // Girafarig [1♀:1♂] + 3, // Pineco [1♀:1♂] + 3, // Forretress [1♀:1♂] + 3, // Dunsparce [1♀:1♂] + 3, // Gligar [1♀:1♂] + 3, // Steelix [1♀:1♂] + 4, // Snubbull [3♀:1♂] + 4, // Granbull [3♀:1♂] + 3, // Qwilfish [1♀:1♂] + 3, // Scizor [1♀:1♂] + 3, // Shuckle [1♀:1♂] + 3, // Heracross [1♀:1♂] + 3, // Sneasel [1♀:1♂] + 3, // Teddiursa [1♀:1♂] + 3, // Ursaring [1♀:1♂] + 3, // Slugma [1♀:1♂] + 3, // Magcargo [1♀:1♂] + 3, // Swinub [1♀:1♂] + 3, // Piloswine [1♀:1♂] + 4, // Corsola [3♀:1♂] + 3, // Remoraid [1♀:1♂] + 3, // Octillery [1♀:1♂] + 3, // Delibird [1♀:1♂] + 3, // Mantine [1♀:1♂] + 3, // Skarmory [1♀:1♂] + 3, // Houndour [1♀:1♂] + 3, // Houndoom [1♀:1♂] + 3, // Kingdra [1♀:1♂] + 3, // Phanpy [1♀:1♂] + 3, // Donphan [1♀:1♂] + 7, // Porygon2 [Gender Unknown] + 3, // Stantler [1♀:1♂] + 3, // Smeargle [1♀:1♂] + 0, // Tyrogue [Male Only] + 0, // Hitmontop [Male Only] + 6, // Smoochum [Female Only] + 2, // Elekid [1♀:3♂] + 2, // Magby [1♀:3♂] + 6, // Miltank [Female Only] + 6, // Blissey [Female Only] + 7, // Raikou [Gender Unknown] + 7, // Entei [Gender Unknown] + 7, // Suicune [Gender Unknown] + 3, // Larvitar [1♀:1♂] + 3, // Pupitar [1♀:1♂] + 3, // Tyranitar [1♀:1♂] + 7, // Lugia [Gender Unknown] + 7, // Ho-Oh [Gender Unknown] + 7, // Celebi [Gender Unknown] +}; +const bool NUM_ABILITIES[251] = { + 0, // Bulbasaur Overgrow + 0, // Ivysaur Overgrow + 0, // Venusaur Overgrow + 0, // Charmander Blaze + 0, // Charmeleon Blaze + 0, // Charizard Blaze + 0, // Squirtle Torrent + 0, // Wartortle Torrent + 0, // Blastoise Torrent + 0, // Caterpie Shield Dust + 0, // Metapod Shed Skin + 0, // Butterfree Compound Eyes + 0, // Weedle Shield Dust + 0, // Kakuna Shed Skin + 0, // Beedrill Swarm + 0, // Pidgey Keen Eye + 0, // Pidgeotto Keen Eye + 0, // Pidgeot Keen Eye + 1, // Rattata Run Away/Guts + 1, // Raticate Run Away/Guts + 0, // Spearow Keen Eye + 0, // Fearow Keen Eye + 1, // Ekans Intimidate/Shed Skin + 1, // Arbok Intimidate/Shed Skin + 0, // Pikachu Static + 0, // Raichu Static + 0, // Sandshrew Sand Veil + 0, // Sandslash Sand Veil + 0, // Nidoran♀ Poison Point + 0, // Nidorina Poison Point + 0, // Nidoqueen Poison Point + 0, // Nidoran♂ Poison Point + 0, // Nidorino Poison Point + 0, // Nidoking Poison Point + 0, // Clefairy Cute Charm + 0, // Clefable Cute Charm + 0, // Vulpix Flash Fire + 0, // Ninetales Flash Fire + 0, // Jigglypuff Cute Charm + 0, // Wigglytuff Cute Charm + 0, // Zubat Inner Focus + 0, // Golbat Inner Focus + 0, // Oddish Chlorophyll + 0, // Gloom Chlorophyll + 0, // Vileplume Chlorophyll + 0, // Paras Effect Spore + 0, // Parasect Effect Spore + 0, // Venonat Compound Eyes + 0, // Venomoth Shield Dust + 1, // Diglett Sand Veil/Arena Trap + 1, // Dugtrio Sand Veil/Arena Trap + 0, // Meowth Pickup + 0, // Persian Limber + 1, // Psyduck Damp/Cloud Nine + 1, // Golduck Damp/Cloud Nine + 0, // Mankey Vital Spirit + 0, // Primeape Vital Spirit + 1, // Growlithe Intimidate/Flash Fire + 1, // Arcanine Intimidate/Flash Fire + 1, // Poliwag Water Absorb/Damp + 1, // Poliwhirl Water Absorb/Damp + 1, // Poliwrath Water Absorb/Damp + 1, // Abra Synchronize/Inner Focus + 1, // Kadabra Synchronize/Inner Focus + 1, // Alakazam Synchronize/Inner Focus + 0, // Machop Guts + 0, // Machoke Guts + 0, // Machamp Guts + 0, // Bellsprout Chlorophyll + 0, // Weepinbell Chlorophyll + 0, // Victreebel Chlorophyll + 1, // Tentacool Clear Body/Liquid Ooze + 1, // Tentacruel Clear Body/Liquid Ooze + 1, // Geodude Rock Head/Sturdy + 1, // Graveler Rock Head/Sturdy + 1, // Golem Rock Head/Sturdy + 1, // Ponyta Run Away/Flash Fire + 1, // Rapidash Run Away/Flash Fire + 1, // Slowpoke Oblivious/Own Tempo + 1, // Slowbro Oblivious/Own Tempo + 1, // Magnemite Magnet Pull/Sturdy + 1, // Magneton Magnet Pull/Sturdy + 1, // Farfetch'd Keen Eye/Inner Focus + 1, // Doduo Run Away/Early Bird + 1, // Dodrio Run Away/Early Bird + 0, // Seel Thick Fat + 0, // Dewgong Thick Fat + 1, // Grimer Stench/Sticky Hold + 1, // Muk Stench/Sticky Hold + 0, // Shellder Shell Armor + 0, // Cloyster Shell Armor + 0, // Gastly Levitate + 0, // Haunter Levitate + 0, // Gengar Cursed Body + 1, // Onix Rock Head/Sturdy + 0, // Drowzee Insomnia + 0, // Hypno Insomnia + 1, // Krabby Hyper Cutter/Shell Armor + 1, // Kingler Hyper Cutter/Shell Armor + 1, // Voltorb Soundproof/Static + 1, // Electrode Soundproof/Static + 0, // Exeggcute Chlorophyll + 0, // Exeggutor Chlorophyll + 1, // Cubone Rock Head/Lightning Rod + 1, // Marowak Rock Head/Lightning Rod + 0, // Hitmonlee Limber + 0, // Hitmonchan Keen Eye + 1, // Lickitung Own Tempo/Oblivious + 0, // Koffing Levitate + 0, // Weezing Levitate + 1, // Rhyhorn Lightning Rod/Rock Head + 1, // Rhydon Lightning Rod/Rock Head + 1, // Chansey Natural Cure/Serene Grace + 0, // Tangela Chlorophyll + 0, // Kangaskhan Early Bird + 0, // Horsea Swift Swim + 0, // Seadra Poison Point + 1, // Goldeen Swift Swim/Water Veil + 1, // Seaking Swift Swim/Water Veil + 1, // Staryu Illuminate/Natural Cure + 1, // Starmie Illuminate/Natural Cure + 0, // Mr. Mime Soundproof + 0, // Scyther Swarm + 0, // Jynx Oblivious + 0, // Electabuzz Static + 0, // Magmar Flame Body + 0, // Pinsir Hyper Cutter + 0, // Tauros Intimidate + 0, // Magikarp Swift Swim + 0, // Gyarados Intimidate + 1, // Lapras Water Absorb/Shell Armor + 0, // Ditto Limber + 0, // Eevee Run Away + 0, // Vaporeon Water Absorb + 0, // Jolteon Volt Absorb + 0, // Flareon Flash Fire + 0, // Porygon Trace + 1, // Omanyte Swift Swim/Shell Armor + 1, // Omastar Swift Swim/Shell Armor + 1, // Kabuto Swift Swim/Battle Armor + 1, // Kabutops Swift Swim/Battle Armor + 1, // Aerodactyl Rock Head/Pressure + 1, // Snorlax Immunity/Thick Fat + 0, // Articuno Pressure + 0, // Zapdos Pressure + 0, // Moltres Pressure + 0, // Dratini Shed Skin + 0, // Dragonair Shed Skin + 0, // Dragonite Inner Focus + 0, // Mewtwo Pressure + 0, // Mew Synchronize + 0, // Chikorita Overgrow + 0, // Bayleef Overgrow + 0, // Meganium Overgrow + 0, // Cyndaquil Blaze + 0, // Quilava Blaze + 0, // Typhlosion Blaze + 0, // Totodile Torrent + 0, // Croconaw Torrent + 0, // Feraligatr Torrent + 1, // Sentret Run Away/Keen Eye + 1, // Furret Run Away/Keen Eye + 1, // Hoothoot Insomnia/Keen Eye + 1, // Noctowl Insomnia/Keen Eye + 1, // Ledyba Swarm/Early Bird + 1, // Ledian Swarm/Early Bird + 1, // Spinarak Swarm/Insomnia + 1, // Ariados Swarm/Insomnia + 0, // Crobat Inner Focus + 1, // Chinchou Volt Absorb/Illuminate + 1, // Lanturn Volt Absorb/Illuminate + 0, // Pichu Static + 0, // Cleffa Cute Charm + 0, // Igglybuff Cute Charm + 1, // Togepi Hustle/Serene Grace + 1, // Togetic Hustle/Serene Grace + 1, // Natu Synchronize/Early Bird + 1, // Xatu Synchronize/Early Bird + 0, // Mareep Static + 0, // Flaaffy Static + 0, // Ampharos Static + 0, // Bellossom Chlorophyll + 1, // Marill Thick Fat/Huge Power + 1, // Azumarill Thick Fat/Huge Power + 1, // Sudowoodo Sturdy/Rock Head + 1, // Politoed Water Absorb/Damp + 0, // Hoppip Chlorophyll + 0, // Skiploom Chlorophyll + 0, // Jumpluff Chlorophyll + 1, // Aipom Run Away/Pickup + 0, // Sunkern Chlorophyll + 0, // Sunflora Chlorophyll + 1, // Yanma Speed Boost/Compound Eyes + 1, // Wooper Damp/Water Absorb + 1, // Quagsire Damp/Water Absorb + 0, // Espeon Synchronize + 0, // Umbreon Synchronize + 0, // Murkrow Insomnia + 1, // Slowking Oblivious/Own Tempo + 0, // Misdreavus Levitate + 0, // Unown Levitate + 0, // Wobbuffet Shadow Tag + 1, // Girafarig Inner Focus/Early Bird + 0, // Pineco Sturdy + 0, // Forretress Sturdy + 1, // Dunsparce Serene Grace/Run Away + 1, // Gligar Hyper Cutter/Sand Veil + 1, // Steelix Rock Head/Sturdy + 1, // Snubbull Intimidate/Run Away + 0, // Granbull Intimidate + 1, // Qwilfish Poison Point/Swift Swim + 0, // Scizor Swarm + 0, // Shuckle Sturdy + 1, // Heracross Swarm/Guts + 1, // Sneasel Inner Focus/Keen Eye + 0, // Teddiursa Pickup + 0, // Ursaring Guts + 1, // Slugma Magma Armor/Flame Body + 1, // Magcargo Magma Armor/Flame Body + 0, // Swinub Oblivious + 0, // Piloswine Oblivious + 1, // Corsola Hustle/Natural Cure + 0, // Remoraid Hustle + 0, // Octillery Suction Cups + 1, // Delibird Vital Spirit/Hustle + 1, // Mantine Swift Swim/Water Absorb + 1, // Skarmory Keen Eye/Sturdy + 1, // Houndour Early Bird/Flash Fire + 1, // Houndoom Early Bird/Flash Fire + 0, // Kingdra Swift Swim + 0, // Phanpy Pickup + 0, // Donphan Sturdy + 0, // Porygon2 Trace + 0, // Stantler Intimidate + 0, // Smeargle Own Tempo + 0, // Tyrogue Guts + 0, // Hitmontop Intimidate + 0, // Smoochum Oblivious + 0, // Elekid Static + 0, // Magby Flame Body + 0, // Miltank Thick Fat + 1, // Blissey Natural Cure/Serene Grace + 0, // Raikou Pressure + 0, // Entei Pressure + 0, // Suicune Pressure + 0, // Larvitar Guts + 0, // Pupitar Shed Skin + 0, // Tyranitar Sand Stream + 0, // Lugia Pressure + 0, // Ho-Oh Pressure + 0, // Celebi Natural Cure +}; \ No newline at end of file