mirror of
https://github.com/Lorenzooone/Pokemon-Gen3-to-Gen-X.git
synced 2026-04-26 08:37:40 -05:00
Implement gen12 to gen3 pokemon conversion
This commit is contained in:
parent
bb0851588e
commit
912e9fcca0
Binary file not shown.
Binary file not shown.
BIN
data/encounters_static.bin
Normal file
BIN
data/encounters_static.bin
Normal file
Binary file not shown.
BIN
data/shiny_unown_banned_tsv.bin
Normal file
BIN
data/shiny_unown_banned_tsv.bin
Normal file
Binary file not shown.
BIN
data/shiny_unown_banned_tsv_letter_table.bin
Normal file
BIN
data/shiny_unown_banned_tsv_letter_table.bin
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -33,6 +33,12 @@ const u16 ribbon_pos [] = {0x290, 0x21C, 0x328};
|
|||
const u16 special_area [] = {0, 9, 9};
|
||||
const u16 rs_valid_maps[VALID_MAPS] = {0x0202, 0x0203, 0x0301, 0x0302, 0x0405, 0x0406, 0x0503, 0x0504, 0x0603, 0x0604, 0x0700, 0x0701, 0x0804, 0x0805, 0x090a, 0x090b, 0x0a05, 0x0a06, 0x0b05, 0x0b06, 0x0c02, 0x0c03, 0x0d06, 0x0d07, 0x0e03, 0x0e04, 0x0f02, 0x0f03, 0x100c, 0x100d, 0x100a, 0x1918, 0x1919, 0x191a, 0x191b, 0x1a05};
|
||||
|
||||
struct game_data_t* own_game_data_ptr;
|
||||
|
||||
struct game_data_t* get_own_game_data() {
|
||||
return own_game_data_ptr;
|
||||
}
|
||||
|
||||
void init_game_data(struct game_data_t* game_data) {
|
||||
init_game_identifier(&game_data->game_identifier);
|
||||
|
||||
|
|
@ -187,4 +193,5 @@ void read_gen_3_data(struct game_data_t* game_data){
|
|||
}
|
||||
|
||||
read_party(slot, game_data);
|
||||
own_game_data_ptr = game_data;
|
||||
}
|
||||
|
|
@ -24,5 +24,6 @@ struct game_data_t {
|
|||
|
||||
void init_game_data(struct game_data_t*);
|
||||
void read_gen_3_data(struct game_data_t*);
|
||||
struct game_data_t* get_own_game_data();
|
||||
|
||||
#endif
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include "graphics_handler.h"
|
||||
#include "version_identifier.h"
|
||||
#include "bin_table_handler.h"
|
||||
#include "gen3_save.h"
|
||||
|
||||
#include "pokemon_moves_pp_gen1_bin.h"
|
||||
#include "pokemon_moves_pp_bin.h"
|
||||
|
|
@ -24,6 +25,7 @@
|
|||
#include "sprites_info_bin.h"
|
||||
#include "palettes_references_bin.h"
|
||||
#include "item_gen3_to_12_bin.h"
|
||||
#include "item_gen12_to_3_bin.h"
|
||||
#include "gen3_to_1_conv_table_bin.h"
|
||||
#include "gen1_to_3_conv_table_bin.h"
|
||||
#include "pokemon_exp_groups_bin.h"
|
||||
|
|
@ -34,6 +36,10 @@
|
|||
#include "pokemon_natures_bin.h"
|
||||
#include "pokemon_abilities_bin.h"
|
||||
#include "encounter_types_bin.h"
|
||||
#include "egg_locations_bin.h"
|
||||
#include "encounters_static_bin.h"
|
||||
#include "encounters_roamers_bin.h"
|
||||
#include "encounters_unown_bin.h"
|
||||
#include "encounter_types_gen2_bin.h"
|
||||
#include "special_encounters_gen2_bin.h"
|
||||
#include "fast_pokemon_methods.h"
|
||||
|
|
@ -134,6 +140,10 @@ u16 get_mon_index_gen1(int index){
|
|||
return gen3_to_1_conv_table_bin[index];
|
||||
}
|
||||
|
||||
u16 get_mon_index_gen1_to_3(u8 index){
|
||||
return gen1_to_3_conv_table_bin[index];
|
||||
}
|
||||
|
||||
const u8* get_pokemon_name(int index, u32 pid, u8 is_egg, u8 deoxys_form){
|
||||
return get_table_pointer(pokemon_names_bin, get_mon_index(index, pid, is_egg, deoxys_form));
|
||||
}
|
||||
|
|
@ -334,7 +344,7 @@ const u8* get_move_name_gen3(struct gen3_mon_attacks* attacks, u8 slot){
|
|||
return get_table_pointer(move_names_bin, move);
|
||||
}
|
||||
|
||||
u8 has_legal_moves(struct gen3_mon_attacks* attacks){
|
||||
u8 has_legal_moves_gen3(struct gen3_mon_attacks* attacks){
|
||||
u8 previous_moves[MOVES_SIZE];
|
||||
u8 curr_slot = 0;
|
||||
|
||||
|
|
@ -352,6 +362,27 @@ u8 has_legal_moves(struct gen3_mon_attacks* attacks){
|
|||
return 0;
|
||||
}
|
||||
|
||||
u8 has_legal_moves_gen12(u8* moves, u8 is_gen2){
|
||||
u8 last_valid_move = LAST_VALID_GEN_1_MOVE;
|
||||
if(is_gen2)
|
||||
last_valid_move = LAST_VALID_GEN_2_MOVE;
|
||||
|
||||
u8 previous_moves[MOVES_SIZE];
|
||||
u8 curr_slot = 0;
|
||||
for(int i = 0; i < MOVES_SIZE; i++) {
|
||||
if((moves[i] != 0) && (moves[i] <= last_valid_move)) {
|
||||
for(int j = 0; j < curr_slot; j++)
|
||||
if(moves[i] == previous_moves[j])
|
||||
return 0;
|
||||
previous_moves[curr_slot++] = moves[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(curr_slot)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 get_pokemon_gender_gen2(u8 index, u8 atk_ivs, u8 is_egg, u8 curr_gen){
|
||||
u8 gender_kind = get_pokemon_gender_kind_gen2(index, is_egg, curr_gen);
|
||||
switch(gender_kind){
|
||||
|
|
@ -464,8 +495,12 @@ u8 is_shiny_gen2(u8 atk_ivs, u8 def_ivs, u8 spa_ivs, u8 spe_ivs){
|
|||
return 0;
|
||||
}
|
||||
|
||||
u8 is_shiny_gen2_unfiltered(u16 ivs){
|
||||
return is_shiny_gen2((ivs >> 4) & 0xF, ivs & 0xF, (ivs >> 8) & 0xF, (ivs >> 12) & 0xF);
|
||||
}
|
||||
|
||||
u8 is_shiny_gen2_raw(struct gen2_mon_data* src){
|
||||
return is_shiny_gen2((src->ivs >> 4) & 0xF, src->ivs & 0xF, (src->ivs >> 8) & 0xF, (src->ivs >> 12) & 0xF);
|
||||
return is_shiny_gen2_unfiltered(src->ivs);
|
||||
}
|
||||
|
||||
u8 decrypt_data(struct gen3_mon* src, u32* decrypted_dst) {
|
||||
|
|
@ -485,6 +520,19 @@ u8 decrypt_data(struct gen3_mon* src, u32* decrypted_dst) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void encrypt_data(struct gen3_mon* dst) {
|
||||
// Prepare the checksum
|
||||
u16 checksum = 0;
|
||||
for(int i = 0; i < (ENC_DATA_SIZE>>1); i++)
|
||||
checksum += ((u16*)dst->enc_data)[i];
|
||||
dst->checksum = checksum;
|
||||
|
||||
// Encrypt the data
|
||||
u32 key = dst->pid ^ dst->ot_id;
|
||||
for(int i = 0; i < (ENC_DATA_SIZE>>2); i++)
|
||||
dst->enc_data[i] = dst->enc_data[i] ^ key;
|
||||
}
|
||||
|
||||
#define ATK_STAT_INDEX 1
|
||||
#define DEF_STAT_INDEX 2
|
||||
#define SPE_STAT_INDEX 3
|
||||
|
|
@ -563,6 +611,25 @@ u32 get_level_exp_mon_index(u16 mon_index, u8 level) {
|
|||
return exp_table[level].exp_kind[pokemon_exp_groups_bin[mon_index]];
|
||||
}
|
||||
|
||||
u32 get_proper_exp_gen2(u16 mon_index, u8 level, u8* given_exp) {
|
||||
|
||||
s32 exp = (given_exp[0]<<0x10) + (given_exp[1]<<0x8) + (given_exp[2]<<0);
|
||||
s32 min_exp = get_level_exp_mon_index(mon_index, level);
|
||||
s32 max_exp = min_exp;
|
||||
if(level == MAX_LEVEL)
|
||||
exp = min_exp;
|
||||
else
|
||||
max_exp = get_level_exp_mon_index(mon_index, level+1)-1;
|
||||
if(exp < min_exp)
|
||||
exp = min_exp;
|
||||
if(exp > max_exp)
|
||||
exp = max_exp;
|
||||
if(exp < 0)
|
||||
exp = 0;
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
||||
u32 get_proper_exp(struct gen3_mon* src, struct gen3_mon_growth* growth, u8 deoxys_form) {
|
||||
u8 level = to_valid_level_gen3(src);
|
||||
|
||||
|
|
@ -684,6 +751,58 @@ u32 swap_endian_int(u32 integer) {
|
|||
return ((integer & 0xFF000000) >> 24) | ((integer & 0xFF) << 24) | ((integer & 0xFF0000) >> 8) | ((integer & 0xFF00) << 8);
|
||||
}
|
||||
|
||||
u8 validate_converting_mon_of_gen1(u8 index, struct gen1_mon* data_src) {
|
||||
|
||||
// Check for matching index to species
|
||||
if(index != data_src->data.species)
|
||||
return 0;
|
||||
|
||||
u8 conv_species = get_mon_index_gen1_to_3(data_src->data.species);
|
||||
|
||||
// Is this a valid mon
|
||||
if((conv_species > LAST_VALID_GEN_1_MON) || (conv_species == 0))
|
||||
return 0;
|
||||
|
||||
// Does it have a valid movepool
|
||||
if(!has_legal_moves_gen12(data_src->data.moves, 0))
|
||||
return 0;
|
||||
|
||||
// Check for valid types
|
||||
u8 matched[2] = {0,0};
|
||||
for(int i = 0; i < 2; i++) {
|
||||
if((data_src->data.type[i] == pokemon_types_gen1_bin[(2*data_src->data.species)]) && (!matched[0]))
|
||||
matched[0] = 1;
|
||||
else if((data_src->data.type[i] == pokemon_types_gen1_bin[(2*data_src->data.species)+1]) && (!matched[1]))
|
||||
matched[1] = 1;
|
||||
}
|
||||
for(int i = 0; i < 2; i++)
|
||||
if(!matched[i])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 validate_converting_mon_of_gen2(u8 index, struct gen2_mon* data_src) {
|
||||
if(index == GEN2_EGG)
|
||||
data_src->is_egg = 1;
|
||||
else
|
||||
data_src->is_egg = 0;
|
||||
|
||||
// Check for matching index to species
|
||||
if((!data_src->is_egg) && (index != data_src->data.species))
|
||||
return 0;
|
||||
|
||||
// Is this a valid mon
|
||||
if((data_src->data.species > LAST_VALID_GEN_2_MON) || (data_src->data.species == 0))
|
||||
return 0;
|
||||
|
||||
// Does it have a valid movepool
|
||||
if(!has_legal_moves_gen12(data_src->data.moves, 1))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 validate_converting_mon_of_gen3(struct gen3_mon* src, struct gen3_mon_growth* growth, u8 is_shiny, u8 gender, u8 gender_kind, u8 is_egg, u8 is_gen2) {
|
||||
u8 last_valid_mon = LAST_VALID_GEN_1_MON;
|
||||
if(is_gen2)
|
||||
|
|
@ -754,14 +873,48 @@ u8 convert_moves_of_gen3(struct gen3_mon_attacks* attacks, u8 pp_bonuses, u8* mo
|
|||
return used_slots;
|
||||
}
|
||||
|
||||
u8 convert_moves_to_gen3(struct gen3_mon_attacks* attacks, struct gen3_mon_growth* growth, u8* moves, u8* pps, u8 is_gen2) {
|
||||
// Start converting moves
|
||||
u8 last_valid_move = LAST_VALID_GEN_1_MOVE;
|
||||
if(is_gen2)
|
||||
last_valid_move = LAST_VALID_GEN_2_MOVE;
|
||||
|
||||
u8 used_slots = 0;
|
||||
|
||||
for(int i = 0; i < MOVES_SIZE; i++) {
|
||||
u16 move = moves[i];
|
||||
if((move > 0) && (move <= last_valid_move)) {
|
||||
u8 base_pp = pokemon_moves_pp_bin[move];
|
||||
u8 bonus_pp = (pps[i] >> 6) & 3;
|
||||
u8 base_increase_pp = Div(base_pp, 5);
|
||||
base_pp += (base_increase_pp * bonus_pp);
|
||||
|
||||
growth->pp_bonuses |= (bonus_pp)<<(2*i);
|
||||
attacks->pp[used_slots] = base_pp;
|
||||
attacks->moves[used_slots++] = move;
|
||||
}
|
||||
}
|
||||
|
||||
return used_slots;
|
||||
}
|
||||
|
||||
u8 convert_item_of_gen3(u16 item) {
|
||||
if(item > LAST_VALID_GEN_3_ITEM)
|
||||
item = 0;
|
||||
return item_gen3_to_12_bin[item];
|
||||
item = item_gen3_to_12_bin[item];
|
||||
if((item == GEN2_NO_ITEM) || (item == GEN2_MAIL))
|
||||
item = 0;
|
||||
return item;
|
||||
}
|
||||
|
||||
u8 to_valid_level_gen3(struct gen3_mon* src) {
|
||||
u8 level = src->level;
|
||||
u16 convert_item_to_gen3(u16 item) {
|
||||
item = item_gen12_to_3_bin[item*2] + (item_gen12_to_3_bin[(item*2)+1]<<8);
|
||||
if(item == GEN3_NO_ITEM)
|
||||
item = 0;
|
||||
return item;
|
||||
}
|
||||
|
||||
u8 to_valid_level(u8 level) {
|
||||
if(level < MIN_LEVEL)
|
||||
return MIN_LEVEL;
|
||||
if(level > MAX_LEVEL)
|
||||
|
|
@ -769,6 +922,10 @@ u8 to_valid_level_gen3(struct gen3_mon* src) {
|
|||
return level;
|
||||
}
|
||||
|
||||
u8 to_valid_level_gen3(struct gen3_mon* src) {
|
||||
return to_valid_level(src->level);
|
||||
}
|
||||
|
||||
void convert_exp_nature_of_gen3(struct gen3_mon* src, struct gen3_mon_growth* growth, u8* level_ptr, u8* exp_ptr, u8 is_gen2) {
|
||||
if(((is_gen2) && (growth->species > LAST_VALID_GEN_2_MON)) || ((!is_gen2) && (growth->species > LAST_VALID_GEN_1_MON)))
|
||||
return;
|
||||
|
|
@ -813,6 +970,24 @@ void convert_exp_nature_of_gen3(struct gen3_mon* src, struct gen3_mon_growth* gr
|
|||
exp_ptr[2-i] = (exp >> (8*i))&0xFF;
|
||||
}
|
||||
|
||||
u8 get_exp_nature(struct gen3_mon* dst, struct gen3_mon_growth* growth, u8 level, u8* given_exp) {
|
||||
// Level handling
|
||||
level = to_valid_level(level);
|
||||
|
||||
u16 mon_index = get_mon_index_gen2(growth->species, 0);
|
||||
|
||||
// Experience handling
|
||||
s32 exp = get_proper_exp_gen2(mon_index, level, given_exp);
|
||||
|
||||
// Save nature in experience, like the Gen I-VII conversion
|
||||
u8 nature = SWI_DivMod(exp, NUM_NATURES);
|
||||
|
||||
// Store exp and level
|
||||
dst->level = level;
|
||||
growth->exp = exp;
|
||||
return nature;
|
||||
}
|
||||
|
||||
u16 convert_ivs_of_gen3(struct gen3_mon_misc* misc, u16 species, u32 pid, u8 is_shiny, u8 gender, u8 gender_kind, u8 is_gen2) {
|
||||
if(((is_gen2) && (species > LAST_VALID_GEN_2_MON)) || ((!is_gen2) && (species > LAST_VALID_GEN_1_MON)))
|
||||
return 0;
|
||||
|
|
@ -864,7 +1039,121 @@ u16 convert_ivs_of_gen3(struct gen3_mon_misc* misc, u16 species, u32 pid, u8 is_
|
|||
return (atk_ivs << 4) | def_ivs | (spa_ivs << 8) | (spe_ivs << 12);
|
||||
}
|
||||
|
||||
void fix_name_change_of_gen3(struct gen3_mon* src, u16 species, u8* nickname, u8 is_egg, u8 is_gen2) {
|
||||
void set_ivs(struct gen3_mon_misc* misc, u32 ivs) {
|
||||
misc->hp_ivs = (ivs >> 0) & 0x1F;
|
||||
misc->atk_ivs = (ivs >> 5) & 0x1F;
|
||||
misc->def_ivs = (ivs >> 10) & 0x1F;
|
||||
misc->spe_ivs = (ivs >> 15) & 0x1F;
|
||||
misc->spa_ivs = (ivs >> 20) & 0x1F;
|
||||
misc->spd_ivs = (ivs >> 25) & 0x1F;
|
||||
}
|
||||
|
||||
void set_origin_pid_iv(struct gen3_mon* dst, struct gen3_mon_misc* misc, u16 species, u16 wanted_ivs, u8 wanted_nature, u8 ot_gender, u8 no_restrictions) {
|
||||
struct game_data_t* trainer_data = get_own_game_data();
|
||||
u8 trainer_game_version = id_to_version(&trainer_data->game_identifier);
|
||||
u8 trainer_gender = trainer_data->trainer_gender;
|
||||
|
||||
u8 chosen_version = FR_VERSION_ID;
|
||||
if(!no_restrictions) {
|
||||
chosen_version = trainer_game_version;
|
||||
ot_gender = trainer_gender;
|
||||
}
|
||||
|
||||
u8 encounter_type = (encounter_types_bin[species>>2]>>(2*(species&3)))&3;
|
||||
u8 is_shiny = is_shiny_gen2_unfiltered(wanted_ivs);
|
||||
u32 ivs = 0;
|
||||
const u8* searchable_table = egg_locations_bin;
|
||||
u8 find_in_table = 0;
|
||||
|
||||
// Get PID and IVs
|
||||
switch(encounter_type) {
|
||||
case STATIC_ENCOUNTER:
|
||||
if(!is_shiny)
|
||||
generate_static_info(wanted_nature, wanted_ivs, (dst->ot_id & 0xFFFF) ^ (dst->ot_id >> 16), &dst->pid, &ivs);
|
||||
else
|
||||
generate_static_shiny_info(wanted_nature, (dst->ot_id & 0xFFFF) ^ (dst->ot_id >> 16), &dst->pid, &ivs);
|
||||
searchable_table = encounters_static_bin;
|
||||
find_in_table = 1;
|
||||
break;
|
||||
case ROAMER_ENCOUNTER:
|
||||
if(!is_shiny)
|
||||
generate_static_info(wanted_nature, wanted_ivs, (dst->ot_id & 0xFFFF) ^ (dst->ot_id >> 16), &dst->pid, &ivs);
|
||||
else
|
||||
generate_static_shiny_info(wanted_nature, (dst->ot_id & 0xFFFF) ^ (dst->ot_id >> 16), &dst->pid, &ivs);
|
||||
// Roamers only get the first byte of their IVs
|
||||
ivs &= 0xFF;
|
||||
searchable_table = encounters_roamers_bin;
|
||||
find_in_table = 1;
|
||||
break;
|
||||
case UNOWN_ENCOUNTER:
|
||||
if(!is_shiny)
|
||||
generate_unown_info(wanted_nature, wanted_ivs, (dst->ot_id & 0xFFFF) ^ (dst->ot_id >> 16), &dst->pid, &ivs);
|
||||
else
|
||||
generate_unown_shiny_info(wanted_nature, wanted_ivs, (dst->ot_id & 0xFFFF) ^ (dst->ot_id >> 16), &dst->pid, &ivs);
|
||||
searchable_table = encounters_unown_bin;
|
||||
find_in_table = 1;
|
||||
break;
|
||||
default:
|
||||
if(!is_shiny)
|
||||
generate_egg_info(species, wanted_nature, wanted_ivs, (dst->ot_id & 0xFFFF) ^ (dst->ot_id >> 16), 2, &dst->pid, &ivs);
|
||||
else
|
||||
generate_egg_shiny_info(species, wanted_nature, wanted_ivs, (dst->ot_id & 0xFFFF) ^ (dst->ot_id >> 16), 2, &dst->pid, &ivs);
|
||||
break;
|
||||
}
|
||||
|
||||
// Set met location and origins info
|
||||
u8 met_location = egg_locations_bin[chosen_version];
|
||||
u8 met_level = 0;
|
||||
|
||||
if(find_in_table) {
|
||||
u16 mon_index = get_mon_index(species, dst->pid, 0, 0);
|
||||
u8* possible_met_data = search_table_for_index(searchable_table, mon_index);
|
||||
if(possible_met_data != NULL) {
|
||||
u8 num_elems = possible_met_data[0];
|
||||
u8 chosen_entry = 0;
|
||||
for(int i = 0; i < num_elems; i++)
|
||||
if(possible_met_data[1+(3*i)] == chosen_version)
|
||||
chosen_entry = i;
|
||||
chosen_version = possible_met_data[1+(3*chosen_entry)];
|
||||
met_location = possible_met_data[2+(3*chosen_entry)];
|
||||
met_level = possible_met_data[3+(3*chosen_entry)];
|
||||
}
|
||||
}
|
||||
misc->met_location = met_location;
|
||||
misc->origins_info = ((ot_gender&1)<<15) | ((POKEBALL_ID&0xF)<<11) | ((chosen_version&0xF)<<7) | ((met_level&0x7F)<<0);
|
||||
|
||||
// Set IVs
|
||||
set_ivs(misc, ivs);
|
||||
|
||||
// Set ability
|
||||
if(dst->pid & 1) {
|
||||
u16 abilities = get_possible_abilities_pokemon(species, dst->pid, 0, 0);
|
||||
u8 abilities_same = (abilities&0xFF) == ((abilities>>8)&0xFF);
|
||||
if(!abilities_same)
|
||||
misc->ability = 1;
|
||||
}
|
||||
}
|
||||
|
||||
u8 are_trainers_same(struct gen3_mon* dst, u8 is_jp) {
|
||||
struct game_data_t* trainer_data = get_own_game_data();
|
||||
u8 trainer_is_jp = trainer_data->game_identifier.game_is_jp;
|
||||
u32 trainer_id = trainer_data->trainer_id;
|
||||
u8* trainer_name = trainer_data->trainer_name;
|
||||
|
||||
// Languages do not match
|
||||
if(is_jp ^ trainer_is_jp)
|
||||
return 0;
|
||||
|
||||
// IDs do not match
|
||||
if((trainer_id & 0xFFFF) != (dst->ot_id & 0xFFFF))
|
||||
return 0;
|
||||
|
||||
// Return whether the OT names are the same
|
||||
return text_gen3_is_same(dst->ot_name, trainer_name, OT_NAME_GEN3_SIZE, OT_NAME_GEN3_SIZE);
|
||||
|
||||
}
|
||||
|
||||
void fix_name_change_from_gen3(struct gen3_mon* src, u16 species, u8* nickname, u8 is_egg, u8 is_gen2) {
|
||||
u8 tmp_text_buffer[NAME_SIZE];
|
||||
|
||||
// Get the string to compare to
|
||||
|
|
@ -879,6 +1168,18 @@ void fix_name_change_of_gen3(struct gen3_mon* src, u16 species, u8* nickname, u
|
|||
}
|
||||
}
|
||||
|
||||
void fix_name_change_to_gen3(struct gen3_mon* dst, u8 species) {
|
||||
u8 tmp_text_buffer[STRING_GEN2_INT_CAP];
|
||||
u8 tmp_text_buffer2[NICKNAME_GEN3_SIZE];
|
||||
|
||||
// Get the string to compare to
|
||||
text_gen12_to_gen3(get_pokemon_name_gen2(species, 0, 0, tmp_text_buffer), tmp_text_buffer2, STRING_GEN2_INT_CAP, NICKNAME_GEN3_SIZE, 0, 0);
|
||||
|
||||
// If it's the same, update the nickname with the new one
|
||||
if(text_gen3_is_same(dst->nickname, tmp_text_buffer2, NICKNAME_GEN3_SIZE, NICKNAME_GEN3_SIZE))
|
||||
text_generic_to_gen3(get_pokemon_name(species, 0, 0, 0), dst->nickname, NAME_SIZE, NICKNAME_GEN3_SIZE, 0, 0);
|
||||
}
|
||||
|
||||
void convert_strings_of_gen3(struct gen3_mon* src, u16 species, u8* ot_name, u8* ot_name_jp, u8* nickname, u8* nickname_jp, u8 is_egg, u8 is_gen2) {
|
||||
u8 gen2_buffer[STRING_GEN2_INT_SIZE];
|
||||
u8 is_jp = (src->language == JAPANESE_LANGUAGE);
|
||||
|
|
@ -899,7 +1200,7 @@ void convert_strings_of_gen3(struct gen3_mon* src, u16 species, u8* ot_name, u8*
|
|||
// Idk if something similar happens in Jap...
|
||||
// Maybe there are some French things with accents...
|
||||
if((species == MR_MIME_SPECIES) && !is_egg)
|
||||
fix_name_change_of_gen3(src, species, nickname, is_egg, is_gen2);
|
||||
fix_name_change_from_gen3(src, species, nickname, is_egg, is_gen2);
|
||||
|
||||
// Put the "EGG" name
|
||||
if(is_gen2 && is_egg) {
|
||||
|
|
@ -918,6 +1219,69 @@ void convert_strings_of_gen3(struct gen3_mon* src, u16 species, u8* ot_name, u8*
|
|||
|
||||
}
|
||||
|
||||
void convert_strings_of_gen12(struct gen3_mon* dst, u8 species, u8* ot_name, u8* nickname, u8 is_egg) {
|
||||
u8 gen2_buffer[STRING_GEN2_INT_SIZE];
|
||||
u8 is_jp = (dst->language == JAPANESE_LANGUAGE);
|
||||
|
||||
u8 name_cap = STRING_GEN2_INT_CAP;
|
||||
if(is_jp)
|
||||
name_cap = STRING_GEN2_JP_CAP;
|
||||
|
||||
// Text conversions
|
||||
text_gen3_terminator_fill(dst->nickname, NICKNAME_GEN3_SIZE);
|
||||
text_gen3_terminator_fill(dst->ot_name, OT_NAME_GEN3_SIZE);
|
||||
|
||||
text_gen12_to_gen3(nickname, dst->nickname, name_cap, NICKNAME_GEN3_SIZE, is_jp, is_jp);
|
||||
text_gen12_to_gen3(ot_name, dst->ot_name, name_cap, OT_NAME_GEN3_SIZE, is_jp, is_jp);
|
||||
|
||||
// Handle Mew's special Japanese-only nature
|
||||
if(species == MEW_SPECIES) {
|
||||
dst->language = JAPANESE_LANGUAGE;
|
||||
text_gen12_to_gen3(nickname, dst->nickname, name_cap, NICKNAME_JP_GEN3_SIZE, is_jp, 1);
|
||||
text_gen12_to_gen3(ot_name, dst->ot_name, name_cap, OT_NAME_JP_GEN3_SIZE, is_jp, 1);
|
||||
name_cap = STRING_GEN2_JP_CAP;
|
||||
is_jp = 1;
|
||||
}
|
||||
|
||||
// Fix text up
|
||||
// "MR.MIME" gen 2 == "MR. MIME" gen 3
|
||||
// Idk if something similar happens in Jap...
|
||||
// Maybe there are some French things with accents...
|
||||
if((species == MR_MIME_SPECIES) && !is_egg && !is_jp)
|
||||
fix_name_change_to_gen3(dst, species);
|
||||
|
||||
// Put the "EGG" name
|
||||
if(is_egg) {
|
||||
dst->language = JAPANESE_LANGUAGE;
|
||||
text_gen12_to_gen3(get_pokemon_name_gen2(species, 1, 1, gen2_buffer), dst->nickname, STRING_GEN2_JP_CAP, NICKNAME_GEN3_SIZE, 1, 1);
|
||||
}
|
||||
else {
|
||||
// Handle bad naming conversions (? >= half the name) and empty names
|
||||
s32 question_marks_count = text_gen3_count_question(dst->nickname, NICKNAME_GEN3_SIZE) - text_gen2_count_question(nickname, name_cap);
|
||||
if((question_marks_count >= (text_gen3_size(dst->nickname, NICKNAME_GEN3_SIZE) >> 1)) || (text_gen3_size(dst->nickname, NICKNAME_GEN3_SIZE) == 0))
|
||||
text_gen12_to_gen3(get_pokemon_name_gen2(species, 0, is_jp, gen2_buffer), dst->nickname, name_cap, NICKNAME_GEN3_SIZE, is_jp, is_jp);
|
||||
}
|
||||
}
|
||||
|
||||
void place_and_encrypt_gen3_data(struct gen3_mon_data_unenc* src, struct gen3_mon* dst) {
|
||||
u8 index = get_index_key(dst->pid);
|
||||
|
||||
u8 pos_data = 12*((positions[index] >> 0)&3);
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_growth); i++)
|
||||
((u8*)dst->enc_data)[pos_data+i] = ((u8*)(&src->growth))[i];
|
||||
pos_data = 12*((positions[index] >> 2)&3);
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_attacks); i++)
|
||||
((u8*)dst->enc_data)[pos_data+i] = ((u8*)(&src->attacks))[i];
|
||||
pos_data = 12*((positions[index] >> 4)&3);
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_evs); i++)
|
||||
((u8*)dst->enc_data)[pos_data+i] = ((u8*)(&src->evs))[i];
|
||||
pos_data = 12*((positions[index] >> 6)&3);
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_misc); i++)
|
||||
((u8*)dst->enc_data)[pos_data+i] = ((u8*)(&src->misc))[i];
|
||||
|
||||
encrypt_data(dst);
|
||||
}
|
||||
|
||||
void process_gen3_data(struct gen3_mon* src, struct gen3_mon_data_unenc* dst, u8 main_version, u8 sub_version) {
|
||||
dst->src = src;
|
||||
|
||||
|
|
@ -973,7 +1337,7 @@ void process_gen3_data(struct gen3_mon* src, struct gen3_mon_data_unenc* dst, u8
|
|||
return;
|
||||
}
|
||||
|
||||
if(!has_legal_moves(attacks)) {
|
||||
if(!has_legal_moves_gen3(attacks)) {
|
||||
dst->is_valid_gen3 = 0;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1153,5 +1517,181 @@ u8 gen3_to_gen1(struct gen1_mon* dst_data, struct gen3_mon_data_unenc* data_src,
|
|||
// Text conversions
|
||||
convert_strings_of_gen3(src, growth->species, dst_data->ot_name, dst_data->ot_name_jp, dst_data->nickname, dst_data->nickname_jp, 0, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 gen2_to_gen3(struct gen2_mon* src_data, struct gen3_mon_data_unenc* data_dst, u8 index, u8* ot_name, u8* nickname, u8 is_jp) {
|
||||
struct gen2_mon_data* src = &src_data->data;
|
||||
struct gen3_mon* dst = &data_dst->src;
|
||||
u8 no_restrictions = 1;
|
||||
|
||||
// Reset everything
|
||||
for(int i = 0; i < sizeof(struct gen3_mon); i++)
|
||||
((u8*)(dst))[i] = 0;
|
||||
|
||||
data_dst->is_valid_gen3 = 0;
|
||||
data_dst->is_valid_gen2 = 0;
|
||||
|
||||
// Check if valid
|
||||
if(!validate_converting_mon_of_gen2(index, src_data))
|
||||
return 0;
|
||||
|
||||
data_dst->is_valid_gen3 = 1;
|
||||
data_dst->is_valid_gen2 = 1;
|
||||
|
||||
// Set base data
|
||||
dst->has_species = 1;
|
||||
dst->pokerus_rem = 0xFF;
|
||||
data_dst->is_egg = src_data->is_egg;
|
||||
|
||||
if(is_jp)
|
||||
dst->language = JAPANESE_LANGUAGE;
|
||||
else
|
||||
dst->language = ENGLISH_LANGUAGE;
|
||||
|
||||
// Handle Nickname + OT conversion
|
||||
convert_strings_of_gen12(dst, src->species, ot_name, nickname, src_data->is_egg);
|
||||
|
||||
// Handle OT ID, if same as the game owner, set it to the game owner's
|
||||
dst->ot_id = swap_endian_short(src->ot_id);
|
||||
|
||||
if(are_trainers_same(dst, is_jp)) {
|
||||
no_restrictions = 0;
|
||||
dst->ot_id = get_own_game_data()->trainer_id;
|
||||
}
|
||||
else
|
||||
dst->ot_id = generate_ot(dst->ot_id, dst->ot_name);
|
||||
|
||||
// Reset everything
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_growth); i++)
|
||||
((u8*)(&data_dst->growth))[i] = 0;
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_attacks); i++)
|
||||
((u8*)(&data_dst->attacks))[i] = 0;
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_evs); i++)
|
||||
((u8*)(&data_dst->evs))[i] = 0;
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_misc); i++)
|
||||
((u8*)(&data_dst->misc))[i] = 0;
|
||||
|
||||
// Set species, exp, level and item
|
||||
data_dst->growth.species = src->species;
|
||||
u8 wanted_nature = get_exp_nature(dst, &data_dst->growth, src->level, src->exp);
|
||||
data_dst->growth.item = convert_item_to_gen3(src->item);
|
||||
|
||||
// Store egg cycles
|
||||
if(src_data->is_egg) {
|
||||
data_dst->growth.friendship = src->friendship;
|
||||
data_dst->misc.is_egg = 1;
|
||||
dst->use_egg_name = 1;
|
||||
}
|
||||
else
|
||||
data_dst->growth.friendship = BASE_FRIENDSHIP;
|
||||
|
||||
// Set the moves
|
||||
convert_moves_to_gen3(&data_dst->attacks, &data_dst->growth, src->moves, src->pps, 1);
|
||||
|
||||
data_dst->misc.pokerus = src->pokerus;
|
||||
if(!(data_dst->misc.pokerus & 0xF) && (data_dst->misc.pokerus>>4))
|
||||
dst->pokerus_rem = 0;
|
||||
|
||||
// Special Mew handling
|
||||
if(data_dst->growth.species == MEW_SPECIES)
|
||||
data_dst->misc.obedience = 1;
|
||||
|
||||
// Set the PID-Origin-IVs data, they're all connected
|
||||
set_origin_pid_iv(dst, &data_dst->misc, data_dst->growth.species, src->ivs, wanted_nature, src->ot_gender, no_restrictions);
|
||||
|
||||
// Place all the substructures' data
|
||||
place_and_encrypt_gen3_data(data_dst, dst);
|
||||
|
||||
// Calculate stats
|
||||
dst->curr_hp = calc_stats_gen3_raw(data_dst, HP_STAT_INDEX);
|
||||
for(int i = 0; i < GEN2_STATS_TOTAL; i++)
|
||||
dst->stats[index_conversion_gen3[i]] = calc_stats_gen3_raw(data_dst, i);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 gen1_to_gen3(struct gen1_mon* src_data, struct gen3_mon_data_unenc* data_dst, u8 index, u8* ot_name, u8* nickname, u8 is_jp) {
|
||||
struct gen1_mon_data* src = &src_data->data;
|
||||
struct gen3_mon* dst = &data_dst->src;
|
||||
u8 no_restrictions = 1;
|
||||
|
||||
// Reset everything
|
||||
for(int i = 0; i < sizeof(struct gen3_mon); i++)
|
||||
((u8*)(dst))[i] = 0;
|
||||
|
||||
data_dst->is_valid_gen3 = 0;
|
||||
data_dst->is_valid_gen1 = 0;
|
||||
|
||||
// Check if valid
|
||||
if(!validate_converting_mon_of_gen1(index, src_data))
|
||||
return 0;
|
||||
|
||||
data_dst->is_valid_gen3 = 1;
|
||||
data_dst->is_valid_gen1 = 1;
|
||||
|
||||
// Set base data
|
||||
dst->has_species = 1;
|
||||
dst->pokerus_rem = 0xFF;
|
||||
data_dst->is_egg = 0;
|
||||
|
||||
if(is_jp)
|
||||
dst->language = JAPANESE_LANGUAGE;
|
||||
else
|
||||
dst->language = ENGLISH_LANGUAGE;
|
||||
|
||||
// Handle Nickname + OT conversion
|
||||
convert_strings_of_gen12(dst, get_mon_index_gen1_to_3(src->species), ot_name, nickname, 0);
|
||||
|
||||
// Handle OT ID, if same as the game owner, set it to the game owner's
|
||||
dst->ot_id = swap_endian_short(src->ot_id);
|
||||
|
||||
if(are_trainers_same(dst, is_jp)) {
|
||||
no_restrictions = 0;
|
||||
dst->ot_id = get_own_game_data()->trainer_id;
|
||||
}
|
||||
else
|
||||
dst->ot_id = generate_ot(dst->ot_id, dst->ot_name);
|
||||
|
||||
// Reset everything
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_growth); i++)
|
||||
((u8*)(&data_dst->growth))[i] = 0;
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_attacks); i++)
|
||||
((u8*)(&data_dst->attacks))[i] = 0;
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_evs); i++)
|
||||
((u8*)(&data_dst->evs))[i] = 0;
|
||||
for(int i = 0; i < sizeof(struct gen3_mon_misc); i++)
|
||||
((u8*)(&data_dst->misc))[i] = 0;
|
||||
|
||||
// Set species, exp, level and item
|
||||
data_dst->growth.species = get_mon_index_gen1_to_3(src->species);
|
||||
u8 wanted_nature = get_exp_nature(dst, &data_dst->growth, src->level, src->exp);
|
||||
data_dst->growth.item = convert_item_to_gen3(src->item);
|
||||
|
||||
// Set base friendship
|
||||
data_dst->growth.friendship = BASE_FRIENDSHIP;
|
||||
|
||||
// Set the moves
|
||||
convert_moves_to_gen3(&data_dst->attacks, &data_dst->growth, src->moves, src->pps, 1);
|
||||
|
||||
data_dst->misc.pokerus = 0;
|
||||
if(!(data_dst->misc.pokerus & 0xF) && (data_dst->misc.pokerus>>4))
|
||||
dst->pokerus_rem = 0;
|
||||
|
||||
// Special Mew handling
|
||||
if(data_dst->growth.species == MEW_SPECIES)
|
||||
data_dst->misc.obedience = 1;
|
||||
|
||||
// Set the PID-Origin-IVs data, they're all connected
|
||||
set_origin_pid_iv(dst, &data_dst->misc, data_dst->growth.species, src->ivs, wanted_nature, 0, no_restrictions);
|
||||
|
||||
// Place all the substructures' data
|
||||
place_and_encrypt_gen3_data(data_dst, dst);
|
||||
|
||||
// Calculate stats
|
||||
dst->curr_hp = calc_stats_gen3_raw(data_dst, HP_STAT_INDEX);
|
||||
for(int i = 0; i < GEN2_STATS_TOTAL; i++)
|
||||
dst->stats[index_conversion_gen3[i]] = calc_stats_gen3_raw(data_dst, i);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -14,6 +14,10 @@
|
|||
#define GEN2_STATS_TOTAL 6
|
||||
#define GEN1_STATS_TOTAL 5
|
||||
|
||||
#define GEN3_NO_ITEM 0xFFFF
|
||||
#define GEN2_NO_ITEM 0xFF
|
||||
#define GEN2_MAIL 0xFE
|
||||
|
||||
#define M_GENDER 0
|
||||
#define F_GENDER 1
|
||||
#define U_GENDER 2
|
||||
|
|
@ -82,6 +86,7 @@
|
|||
#define NAME_SIZE 11
|
||||
#define ITEM_NAME_SIZE 15
|
||||
#define NICKNAME_GEN3_SIZE 10
|
||||
#define NICKNAME_JP_GEN3_SIZE 5
|
||||
#define OT_NAME_GEN3_SIZE 7
|
||||
#define OT_NAME_JP_GEN3_SIZE 5
|
||||
#define STRING_GEN2_INT_SIZE 11
|
||||
|
|
@ -92,7 +97,15 @@
|
|||
#define GEN2_EGG 253
|
||||
#define GEN2_NO_MON 255
|
||||
|
||||
#define POKEBALL_ID 4
|
||||
|
||||
#define EGG_ENCOUNTER 0
|
||||
#define STATIC_ENCOUNTER 1
|
||||
#define ROAMER_ENCOUNTER 2
|
||||
#define UNOWN_ENCOUNTER 3
|
||||
|
||||
#define JAPANESE_LANGUAGE 1
|
||||
#define ENGLISH_LANGUAGE 2
|
||||
|
||||
struct mail_gen3 {
|
||||
u16 words[MAIL_WORDS_SIZE];
|
||||
|
|
@ -263,6 +276,8 @@ struct gen1_party {
|
|||
void process_gen3_data(struct gen3_mon*, struct gen3_mon_data_unenc*, u8, u8);
|
||||
u8 gen3_to_gen2(struct gen2_mon*, struct gen3_mon_data_unenc*, u32);
|
||||
u8 gen3_to_gen1(struct gen1_mon*, struct gen3_mon_data_unenc*, u32);
|
||||
u8 gen2_to_gen3(struct gen2_mon*, struct gen3_mon_data_unenc*, u8, u8*, u8*, u8);
|
||||
u8 gen1_to_gen3(struct gen1_mon*, struct gen3_mon_data_unenc*, u8, u8*, u8*, u8);
|
||||
|
||||
const u8* get_pokemon_name_raw(struct gen3_mon_data_unenc*);
|
||||
u16 get_mon_index_raw(struct gen3_mon_data_unenc*);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
#include "optimized_swi.h"
|
||||
#include "print_system.h"
|
||||
|
||||
#include "shiny_unown_banned_tsv_bin.h"
|
||||
#include "shiny_unown_banned_tsv_letter_table_bin.h"
|
||||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline)) static inline
|
||||
|
||||
#define TEST_WORST_CASE 0
|
||||
|
|
@ -36,6 +39,40 @@ void init_unown_tsv() {
|
|||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE __attribute__ ((optimize(3))) u8 is_bad_tsv(u16 tsv) {
|
||||
tsv = (tsv >> 3) << 3;
|
||||
const u32* shiny_unown_banned_tsv_bin_32 = (const u32*)shiny_unown_banned_tsv_bin;
|
||||
for(int i = 0; i < (shiny_unown_banned_tsv_bin_size >> 2); i++) {
|
||||
if(tsv == (shiny_unown_banned_tsv_bin_32[i] & 0xFFFF))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE __attribute__ ((optimize(3))) void get_letter_valid_natures(u16 tsv, u8 letter, u8* valid_natures) {
|
||||
tsv = (tsv >> 3) << 3;
|
||||
for(int i = 0; i < NUM_NATURES; i++)
|
||||
valid_natures[i] = 1;
|
||||
u8 letter_kind = shiny_unown_banned_tsv_letter_table_bin[letter] >> 4;
|
||||
u8 letter_dist = shiny_unown_banned_tsv_letter_table_bin[letter] & 0xF;
|
||||
if(letter_kind == 0xF)
|
||||
return;
|
||||
const u32* shiny_unown_banned_tsv_bin_32 = (const u32*)shiny_unown_banned_tsv_bin;
|
||||
for(int i = 0; i < (shiny_unown_banned_tsv_bin_size >> 2); i++) {
|
||||
if(tsv == (shiny_unown_banned_tsv_bin_32[i] & 0xFFFF)) {
|
||||
u8 letter_kind_table = (shiny_unown_banned_tsv_bin_32[i]>>0x14)&0xF;
|
||||
u8 letter_dist_table = (shiny_unown_banned_tsv_bin_32[i]>>0x10)&0xF;
|
||||
if(letter_kind == letter_kind_table) {
|
||||
letter_dist += letter_dist_table;
|
||||
if(letter_dist >= 5)
|
||||
letter_dist -= 5;
|
||||
for(int j = 0; j < 5; j++)
|
||||
valid_natures[letter_dist + (j*5)] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE __attribute__ ((optimize(3))) u32 get_prev_seed(u32 seed) {
|
||||
return (seed-0x6073) * 0xEEB9EB65;
|
||||
}
|
||||
|
|
@ -49,10 +86,9 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 generate_ot(u16 tid, u8* name) {
|
|||
// This should NOT be random...
|
||||
// All Pokémon from a trainer should have the same TID/SID!
|
||||
|
||||
// Put Unown V and I checks here!
|
||||
|
||||
u16 accumulator = 0;
|
||||
u32 seed = 0;
|
||||
u16 sid = 0;
|
||||
seed = get_next_seed(seed);
|
||||
|
||||
for(int i = 0; i < OT_NAME_GEN3_SIZE; i++) {
|
||||
|
|
@ -63,12 +99,17 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 generate_ot(u16 tid, u8* name) {
|
|||
}
|
||||
|
||||
seed += tid;
|
||||
seed = get_next_seed(seed);
|
||||
do {
|
||||
// Unown V and I checks here!
|
||||
seed = get_next_seed(seed);
|
||||
sid = seed >> 0x10;
|
||||
}
|
||||
while(is_bad_tsv(sid^tid));
|
||||
|
||||
return (seed & 0xFFFF0000) | tid;
|
||||
return (sid << 0x10) | tid;
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_egg_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv, u8 gender, u8 gender_kind, u32 start_seed) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void _generate_egg_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv, u8 gender, u8 gender_kind, u32* dst_pid, u32* dst_ivs, u32 start_seed) {
|
||||
// Worst case: 0, 0x2113, 0, 0, 0, 34
|
||||
u8 atk_ivs = ((wanted_ivs<<(4-gender_useful_atk_ivs[gender_kind])) & 0xF)<<1;
|
||||
u8 def_ivs = ((wanted_ivs>>4) & 0xF)<<1;
|
||||
|
|
@ -109,9 +150,10 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_egg_info(u8 wanted_nature
|
|||
u8 new_def_ivs = (((generated_ivs >> 10)&0x1F)>>1) << 1;
|
||||
|
||||
if(new_atk_ivs == atk_ivs && new_def_ivs == def_ivs) {
|
||||
ivs = (generated_ivs & 0x7FFF) | (((seed>>16) & 0x7FFF)<<15);
|
||||
seed = get_prev_seed(seed);
|
||||
seed = get_prev_seed(seed);
|
||||
u16 high_pid = seed & 0xFFFF0000;
|
||||
u16 high_pid = seed >> 16;
|
||||
u32 inner_seed = get_prev_seed(start_seed>>0x10);
|
||||
u16 lower_pid = 0;
|
||||
do {
|
||||
|
|
@ -146,8 +188,9 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_egg_info(u8 wanted_nature
|
|||
if((gender == F_GENDER) && (gender_values[gender_kind] == 0x1F) && ((lower_pid & 0xFF) == 0x1F))
|
||||
lower_pid -= NUM_NATURES;
|
||||
}
|
||||
|
||||
return 1 + l + (NUM_SEEDS*pass_counter);
|
||||
*dst_ivs |= ivs;
|
||||
*dst_pid = lower_pid | (high_pid << 0x10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
pass_counter++;
|
||||
|
|
@ -157,15 +200,13 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_egg_info(u8 wanted_nature
|
|||
if(initial_spa == i)
|
||||
initial_spa += (limit-start);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 generate_egg_info(u8 index, u8 wanted_nature, u16 wanted_ivs, u16 tsv, u8 curr_gen) {
|
||||
return _generate_egg_info(wanted_nature, wanted_ivs, tsv, get_pokemon_gender_gen2(index, wanted_ivs&0xF, 0, curr_gen), get_pokemon_gender_kind_gen2(index, 0, curr_gen), get_rng());
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void generate_egg_info(u8 index, u8 wanted_nature, u16 wanted_ivs, u16 tsv, u8 curr_gen, u32* dst_pid, u32* dst_ivs) {
|
||||
_generate_egg_info(wanted_nature, wanted_ivs, tsv, get_pokemon_gender_gen2(index, wanted_ivs&0xF, 0, curr_gen), get_pokemon_gender_kind_gen2(index, 0, curr_gen), dst_pid, dst_ivs, get_rng());
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_egg_shiny_info(u8 wanted_nature, u16 tsv, u8 gender, u8 gender_kind, u32 start_seed) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void _generate_egg_shiny_info(u8 wanted_nature, u16 tsv, u8 gender, u8 gender_kind, u32* dst_pid, u32* dst_ivs, u32 start_seed) {
|
||||
// Worst case: ANY
|
||||
u16 lower_pid = start_seed &0xFFFF;
|
||||
|
||||
|
|
@ -204,16 +245,18 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_egg_shiny_info(u8 wanted_
|
|||
pid = (higher_pid << 0x10) | lower_pid;
|
||||
|
||||
u32 seed = (higher_pid << 16) | (start_seed >> 16);
|
||||
seed = get_prev_seed(seed);
|
||||
seed = get_next_seed(seed);
|
||||
u16 generated_ivs = (seed >> 16) & 0x7FFF;
|
||||
|
||||
return pid;
|
||||
*dst_ivs |= generated_ivs | (((get_next_seed(seed)>>16)&0x7FFF)<<15);
|
||||
*dst_pid = pid;
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 generate_egg_shiny_info(u8 index, u8 wanted_nature, u16 wanted_ivs, u16 tsv, u8 curr_gen) {
|
||||
return _generate_egg_shiny_info(wanted_nature, tsv, get_pokemon_gender_gen2(index, wanted_ivs&0xF, 0, curr_gen), get_pokemon_gender_kind_gen2(index, 0, curr_gen), get_rng());
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void generate_egg_shiny_info(u8 index, u8 wanted_nature, u16 wanted_ivs, u16 tsv, u8 curr_gen, u32* dst_pid, u32* dst_ivs) {
|
||||
_generate_egg_shiny_info(wanted_nature, tsv, get_pokemon_gender_gen2(index, wanted_ivs&0xF, 0, curr_gen), get_pokemon_gender_kind_gen2(index, 0, curr_gen), dst_pid, dst_ivs, get_rng());
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_static_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv, u32 start_seed) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void _generate_static_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv, u32* dst_pid, u32* dst_ivs, u32 start_seed) {
|
||||
// Worst case: 6, 12706, 0xA30E, 0
|
||||
u8 atk_ivs = ((wanted_ivs) & 0xF)<<1;
|
||||
u8 def_ivs = ((wanted_ivs>>4) & 0xF)<<1;
|
||||
|
|
@ -254,6 +297,7 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_static_info(u8 wanted_nat
|
|||
u8 new_def_ivs = (((generated_ivs >> 10)&0x1F)>>1) << 1;
|
||||
|
||||
if(new_atk_ivs == atk_ivs && new_def_ivs == def_ivs) {
|
||||
ivs = (generated_ivs & 0x7FFF) | (((seed>>16) & 0x7FFF)<<15);
|
||||
seed = get_prev_seed(seed);
|
||||
seed = get_prev_seed(seed);
|
||||
pid |= seed & 0xFFFF0000;
|
||||
|
|
@ -262,8 +306,9 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_static_info(u8 wanted_nat
|
|||
u16 shiny_pid = (pid>>16) ^ (pid & 0xFFFF) ^ tsv;
|
||||
u8 nature = get_nature_fast(pid);
|
||||
if((nature == wanted_nature) && (shiny_pid >= 8)) {
|
||||
seed = get_prev_seed(seed);
|
||||
return 1 + l + (NUM_SEEDS*pass_counter);
|
||||
*dst_pid = pid;
|
||||
*dst_ivs |= ivs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -274,15 +319,13 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_static_info(u8 wanted_nat
|
|||
if(initial_spa == i)
|
||||
initial_spa += (limit-start);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 generate_static_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv) {
|
||||
return _generate_static_info(wanted_nature, wanted_ivs, tsv, get_rng());
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void generate_static_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv, u32* dst_pid, u32* dst_ivs) {
|
||||
_generate_static_info(wanted_nature, wanted_ivs, tsv, dst_pid, dst_ivs, get_rng());
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_static_shiny_info(u8 wanted_nature, u16 tsv, u32 given_seed) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void _generate_static_shiny_info(u8 wanted_nature, u16 tsv, u32* dst_pid, u32* dst_ivs, u32 given_seed) {
|
||||
// Worst case: 0, 0x2088, (base_increment = 1, initial_pos = 0x6D0, set TEST_WORST_CASE to 1 to test it, with seed 0x36810000)
|
||||
s32 base_increment;
|
||||
u16 initial_pos;
|
||||
|
|
@ -304,15 +347,21 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_static_shiny_info(u8 want
|
|||
|
||||
generating_seed = get_next_seed(generating_seed);
|
||||
low_pid = generating_seed >> 16;
|
||||
generating_seed = get_next_seed(generating_seed);
|
||||
generating_seed = get_next_seed(generating_seed);
|
||||
high_pid = generating_seed >> 16;
|
||||
|
||||
u16 shiny_pid = (high_pid ^ low_pid ^ tsv);
|
||||
|
||||
nature = get_nature_fast((high_pid<<16) | low_pid);
|
||||
|
||||
if((shiny_pid < 8) && (nature == wanted_nature))
|
||||
return 1;
|
||||
if((shiny_pid < 8) && (nature == wanted_nature)) {
|
||||
generating_seed = get_next_seed(generating_seed);
|
||||
u16 generated_ivs = (generating_seed >> 16)&0x7FFF;
|
||||
generating_seed = get_next_seed(generating_seed);
|
||||
*dst_pid = low_pid | (high_pid<<16);
|
||||
*dst_ivs |= generated_ivs | (((generating_seed>>16)&0x7FFF)<<15);
|
||||
return;
|
||||
}
|
||||
|
||||
high_pid = pos<<3;
|
||||
|
||||
|
|
@ -335,8 +384,14 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_static_shiny_info(u8 want
|
|||
|
||||
u16 generated_high_pid = get_next_seed(seed) >> 16;
|
||||
|
||||
if(high_pid == generated_high_pid) {
|
||||
return 1 + j + (i*NUM_SEEDS);
|
||||
if(high_pid == generated_high_pid) {
|
||||
seed = get_next_seed(seed);
|
||||
seed = get_next_seed(seed);
|
||||
u16 generated_ivs = (seed>>16)&0x7FFF;
|
||||
seed = get_next_seed(seed);
|
||||
*dst_pid = low_pid | (high_pid<<16);
|
||||
*dst_ivs |= generated_ivs | (((seed>>16)&0x7FFF)<<15);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -355,14 +410,13 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_static_shiny_info(u8 want
|
|||
pos -= NUM_DIFFERENT_PSV;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 generate_static_shiny_info(u8 wanted_nature, u16 tsv) {
|
||||
return _generate_static_shiny_info(wanted_nature, tsv, get_rng());
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void generate_static_shiny_info(u8 wanted_nature, u16 tsv, u32* dst_pid, u32* dst_ivs) {
|
||||
_generate_static_shiny_info(wanted_nature, tsv, dst_pid, dst_ivs, get_rng());
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_info(u8 wanted_nature, u8 letter, u8 rest_of_ivs, u16 tsv, u32 start_seed) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void _generate_unown_info(u8 wanted_nature, u8 letter, u8 rest_of_ivs, u16 tsv, u32* dst_pid, u32* dst_ivs, u32 start_seed) {
|
||||
// Worst case: 15, 4, 0xCE, 0xA021, 0x1AA
|
||||
u8 atk_ivs = (((rest_of_ivs>>0)&1) | (((rest_of_ivs>>0)&2)<<2))<<1;
|
||||
u8 def_ivs = (((rest_of_ivs>>2)&1) | (((rest_of_ivs>>2)&2)<<2))<<1;
|
||||
|
|
@ -392,6 +446,7 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_info(u8 wanted_natu
|
|||
u8 new_spa_ivs = (((((generated_ivs >> 5) & 0x1F) + ((generated_ivs >> 10) & 0x1F))>>1) & 0x12);
|
||||
|
||||
if(new_spa_ivs == spa_ivs && new_spe_ivs == spe_ivs) {
|
||||
ivs = ((generated_ivs & 0x7FFF)<<15) | ((seed>>16) & 0x7FFF);
|
||||
seed = get_prev_seed(seed);
|
||||
pid |= seed >> 16;
|
||||
seed = get_prev_seed(seed);
|
||||
|
|
@ -400,8 +455,9 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_info(u8 wanted_natu
|
|||
u8 nature = get_nature_fast(pid);
|
||||
u8 generated_letter = get_unown_letter_gen3_fast(pid);
|
||||
if((nature == wanted_nature) && (letter == generated_letter) && (shiny_pid >= 8)) {
|
||||
seed = get_prev_seed(seed);
|
||||
return 1 + l + (NUM_SEEDS*k) + (2*NUM_SEEDS*u) + (0x10*NUM_SEEDS*j) + (0x80*NUM_SEEDS*i);
|
||||
*dst_ivs |= ivs;
|
||||
*dst_pid = pid;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -415,21 +471,19 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_info(u8 wanted_natu
|
|||
if(i == base_hp)
|
||||
base_hp += 0x20;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 generate_unown_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void generate_unown_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv, u32* dst_pid, u32* dst_ivs) {
|
||||
u8 atk_ivs = ((wanted_ivs) & 0xF);
|
||||
u8 def_ivs = ((wanted_ivs>>4) & 0xF);
|
||||
u8 spe_ivs = ((wanted_ivs>>8) & 0xF);
|
||||
u8 spa_ivs = ((wanted_ivs>>12) & 0xF);
|
||||
u8 letter = get_unown_letter_gen2_fast(wanted_ivs);
|
||||
u8 rest_of_ivs = (((atk_ivs & 1) | ((atk_ivs>>2)&2))<<0) | (((def_ivs & 1) | ((def_ivs>>2)&2))<<2) | (((spe_ivs & 1) | ((spe_ivs>>2)&2))<<4) | (((spa_ivs & 1) | ((spa_ivs>>2)&2))<<6);
|
||||
return _generate_unown_info(wanted_nature, letter, rest_of_ivs, tsv, get_rng());
|
||||
_generate_unown_info(wanted_nature, letter, rest_of_ivs, tsv, dst_pid, dst_ivs, get_rng());
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 search_unown_with_mask(u32 mask, u16 new_high, u16 new_low, u8* success) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u8 search_unown_with_mask(u32 mask, u16 new_high, u16 new_low, u32* dst_pid, u32* dst_ivs) {
|
||||
new_high = new_high ^ (mask>>16);
|
||||
new_low = new_low ^ (mask&0xFFFF);
|
||||
for(int u = 0; u < NUM_SEEDS; u++) {
|
||||
|
|
@ -443,22 +497,21 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 search_unown_with_mask(u32 mask, u1
|
|||
u32 ivs = (seed >> 16) & 0x7FFF;
|
||||
seed = get_next_seed(seed);
|
||||
ivs |= ((seed >> 16) & 0x7FFF)<<15;
|
||||
*success = 1;
|
||||
return u;
|
||||
*dst_pid = (new_high<<16) | generated_low_pid;
|
||||
*dst_ivs |= ivs;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
*success = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_shiny_info(u8 wanted_nature, u16 tsv, u8 letter, u32 given_seed) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void _generate_unown_shiny_info(u8 wanted_nature, u16 tsv, u8 letter, u32* dst_pid, u32* dst_ivs, u32 given_seed) {
|
||||
// Worst case: 5, 0x4FF8, 5, 0x8FC00000
|
||||
u16 high_pid;
|
||||
u16 low_pid;
|
||||
u8 nature;
|
||||
u16 shiny_pid;
|
||||
u32 pid = 0;
|
||||
u32 failures = 0;
|
||||
|
||||
u8 tsv_flag = ((tsv>>8)&3);
|
||||
u8 num_valid_values = unown_tsv_numbers[tsv_flag][letter];
|
||||
|
|
@ -492,8 +545,14 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_shiny_info(u8 wante
|
|||
nature = get_nature_fast(pid);
|
||||
|
||||
// Basically, asking for a miracle
|
||||
if((nature == wanted_nature) && (get_unown_letter_gen3_fast(pid) == letter) && (shiny_pid < 8))
|
||||
return 1;
|
||||
if((nature == wanted_nature) && (get_unown_letter_gen3_fast(pid) == letter) && (shiny_pid < 8)) {
|
||||
generating_seed = get_next_seed(generating_seed);
|
||||
u16 generated_ivs = (generating_seed >> 16)&0x7FFF;
|
||||
generating_seed = get_next_seed(generating_seed);
|
||||
*dst_pid = pid;
|
||||
*dst_ivs |= generated_ivs | (((generating_seed>>16)&0x7FFF)<<15);
|
||||
return;
|
||||
}
|
||||
|
||||
low_pid = ((pos << 3) & 0xF8) | (((pos>>5)<<(8+2)));
|
||||
|
||||
|
|
@ -505,8 +564,6 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_shiny_info(u8 wante
|
|||
high_pid = converted_high_pid_flag | ((inside_low_pid ^ tsv)&0xFCF8);
|
||||
|
||||
for(int k = 0; k < 4; k++) {
|
||||
u8 finished;
|
||||
u32 ivs;
|
||||
u16 new_high = high_pid;
|
||||
u16 new_low = inside_low_pid;
|
||||
|
||||
|
|
@ -538,14 +595,9 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_shiny_info(u8 wante
|
|||
if((i>>k)&1)
|
||||
mask += 0x01000100 << (3+k);
|
||||
u8 xor_mod_change = get_nature_fast(pid ^ mask);
|
||||
if(xor_mod_change == wanted_nature) {
|
||||
finished = 0;
|
||||
ivs = search_unown_with_mask(mask, new_high, new_low, &finished);
|
||||
if(finished)
|
||||
return ivs + failures;
|
||||
else
|
||||
failures += NUM_SEEDS;
|
||||
}
|
||||
if(xor_mod_change == wanted_nature)
|
||||
if(search_unown_with_mask(mask, new_high, new_low, dst_pid, dst_ivs))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -564,16 +616,22 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 _generate_unown_shiny_info(u8 wante
|
|||
pos -= (0x10000>>5);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 generate_unown_shiny_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) void generate_unown_shiny_info(u8 wanted_nature, u16 wanted_ivs, u16 tsv, u32* dst_pid, u32* dst_ivs) {
|
||||
u8 letter = get_unown_letter_gen2_fast(wanted_ivs);
|
||||
// Put Unown TSV restrictions here
|
||||
return _generate_unown_shiny_info(wanted_nature, letter, tsv, get_rng());
|
||||
u8 valid_natures[NUM_NATURES];
|
||||
get_letter_valid_natures(tsv, letter, valid_natures);
|
||||
// Unown TSV checks
|
||||
while(!valid_natures[wanted_nature]){
|
||||
wanted_nature++;
|
||||
if(wanted_nature >= NUM_NATURES)
|
||||
wanted_nature -= NUM_NATURES;
|
||||
}
|
||||
return _generate_unown_shiny_info(wanted_nature, letter, tsv, dst_pid, dst_ivs, get_rng());
|
||||
}
|
||||
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u32 get_roamer_ivs(u32 pid, u8 hp_ivs, u8 atk_ivs) {
|
||||
IWRAM_CODE __attribute__ ((optimize(3))) u8 get_roamer_ivs(u32 pid, u8 hp_ivs, u8 atk_ivs, u32* dst_ivs) {
|
||||
atk_ivs &= 7;
|
||||
|
||||
for(u32 l = 0; l < NUM_SEEDS; l++) {
|
||||
|
|
@ -590,11 +648,11 @@ IWRAM_CODE __attribute__ ((optimize(3))) u32 get_roamer_ivs(u32 pid, u8 hp_ivs,
|
|||
if((((ivs >> 0)&0x1F) == hp_ivs) && (((ivs >> 5)&7) == atk_ivs)) {
|
||||
seed = get_next_seed(seed);
|
||||
ivs |= ((seed & 0x7FFF0000) >> 1);
|
||||
return 1 + ivs;
|
||||
dst_ivs = ivs;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -603,98 +661,74 @@ void worst_case_conversion_tester(u32* counter) {
|
|||
|
||||
int curr_counter = *counter;
|
||||
int max_counter = 0;
|
||||
u32 success;
|
||||
u32 pid, ivs;
|
||||
|
||||
curr_counter = *counter;
|
||||
max_counter = 0;
|
||||
|
||||
success = _generate_egg_info(0, 0x2113, 0, 0, 0, 34);
|
||||
_generate_egg_info(0, 0x2113, 0, 0, 0, &pid, &ivs, 34);
|
||||
|
||||
max_counter = 0;
|
||||
if(max_counter < ((*counter)-curr_counter))
|
||||
max_counter = ((*counter)-curr_counter);
|
||||
curr_counter = *counter;
|
||||
|
||||
if(!success)
|
||||
PRINT_FUNCTION("Failed!\n");
|
||||
|
||||
PRINT_FUNCTION("Max time 1 alt: 0x%X\n", max_counter);
|
||||
PRINT_FUNCTION("Max value 1 alt: %d\n", success);
|
||||
|
||||
curr_counter = *counter;
|
||||
max_counter = 0;
|
||||
|
||||
success = _generate_static_info(6, 12706, 0xA30E, 0);
|
||||
_generate_static_info(6, 12706, 0xA30E, &pid, &ivs, 0);
|
||||
|
||||
if(max_counter < ((*counter)-curr_counter))
|
||||
max_counter = ((*counter)-curr_counter);
|
||||
curr_counter = *counter;
|
||||
|
||||
if(!success)
|
||||
PRINT_FUNCTION("Failed!\n");
|
||||
|
||||
PRINT_FUNCTION("Max time 2 alt: 0x%X\n", max_counter);
|
||||
PRINT_FUNCTION("Max value 2 alt: %d\n", success);
|
||||
|
||||
curr_counter = *counter;
|
||||
max_counter = 0;
|
||||
|
||||
success = _generate_unown_info(15, 4, 0xCE, 0xA021, 0x1AA);
|
||||
_generate_unown_info(15, 4, 0xCE, 0xA021, &pid, &ivs, 0x1AA);
|
||||
max_counter = 0;
|
||||
if(max_counter < ((*counter)-curr_counter))
|
||||
max_counter = ((*counter)-curr_counter);
|
||||
curr_counter = *counter;
|
||||
|
||||
if(!success)
|
||||
PRINT_FUNCTION("Failed!\n");
|
||||
|
||||
PRINT_FUNCTION("Max time 4: 0x%X\n", max_counter);
|
||||
PRINT_FUNCTION("Max value 4: %d\n", success);
|
||||
|
||||
curr_counter = *counter;
|
||||
max_counter = 0;
|
||||
|
||||
success = _generate_egg_shiny_info(0, 0x0, 1, 0, 0);
|
||||
_generate_egg_shiny_info(0, 0x0, 1, 0, &pid, &ivs, 0);
|
||||
|
||||
if(max_counter < ((*counter)-curr_counter))
|
||||
max_counter = ((*counter)-curr_counter);
|
||||
curr_counter = *counter;
|
||||
|
||||
if(!success)
|
||||
PRINT_FUNCTION("Failed!\n");
|
||||
|
||||
PRINT_FUNCTION("Max time 1 s: 0x%X\n", max_counter);
|
||||
PRINT_FUNCTION("Max value 1 s: 0x%X\n", success);
|
||||
|
||||
curr_counter = *counter;
|
||||
max_counter = 0;
|
||||
|
||||
success = _generate_static_shiny_info(0, 0x2088, 0x36810000);
|
||||
_generate_static_shiny_info(0, 0x2088, &pid, &ivs, 0x36810000);
|
||||
|
||||
if(max_counter < ((*counter)-curr_counter))
|
||||
max_counter = ((*counter)-curr_counter);
|
||||
curr_counter = *counter;
|
||||
|
||||
if(!success)
|
||||
PRINT_FUNCTION("Failed!\n");
|
||||
|
||||
PRINT_FUNCTION("Max time 2 s: 0x%X\n", max_counter);
|
||||
PRINT_FUNCTION("Max value 2 s: 0x%X\n", success);
|
||||
|
||||
curr_counter = *counter;
|
||||
max_counter = 0;
|
||||
|
||||
success = _generate_unown_shiny_info(5, 0x4FF8, 5, 0x8FC00000);
|
||||
_generate_unown_shiny_info(5, 0x4FF8, 5, &pid, &ivs, 0x8FC00000);
|
||||
|
||||
if(max_counter < ((*counter)-curr_counter))
|
||||
max_counter = ((*counter)-curr_counter);
|
||||
curr_counter = *counter;
|
||||
|
||||
if(!success)
|
||||
PRINT_FUNCTION("Failed!\n");
|
||||
|
||||
PRINT_FUNCTION("Max time 4 s: 0x%X\n", max_counter);
|
||||
PRINT_FUNCTION("Max value 4 s: 0x%X\n", success);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
@ -6,13 +6,13 @@
|
|||
void worst_case_conversion_tester(u32*);
|
||||
void init_unown_tsv();
|
||||
|
||||
u32 get_roamer_ivs(u32, u8, u8);
|
||||
u32 generate_unown_shiny_info(u8, u16, u16);
|
||||
u32 generate_unown_info(u8, u16, u16);
|
||||
u32 generate_static_shiny_info(u8, u16);
|
||||
u32 generate_static_info(u8, u16, u16);
|
||||
u32 generate_egg_shiny_info(u8, u8, u16, u16, u8);
|
||||
u32 generate_egg_info(u8, u8, u16, u16, u8);
|
||||
u8 get_roamer_ivs(u32, u8, u8, u32*);
|
||||
void generate_unown_shiny_info(u8, u16, u16, u32*, u32*);
|
||||
void generate_unown_info(u8, u16, u16, u32*, u32*);
|
||||
void generate_static_shiny_info(u8, u16, u32*, u32*);
|
||||
void generate_static_info(u8, u16, u16, u32*, u32*);
|
||||
void generate_egg_shiny_info(u8, u8, u16, u16, u8, u32*, u32*);
|
||||
void generate_egg_info(u8, u8, u16, u16, u8, u32*, u32*);
|
||||
u32 generate_ot(u16, u8*);
|
||||
|
||||
#endif
|
||||
|
|
@ -40,6 +40,22 @@ void get_game_id(struct game_identity* identifier){
|
|||
}
|
||||
}
|
||||
|
||||
u8 id_to_version(struct game_identity* identifier){
|
||||
|
||||
u8 base_game = S_VERSION_ID;
|
||||
if(identifier->game_main_version == FRLG_GAME_CODE)
|
||||
base_game = FR_VERSION_ID;
|
||||
if(identifier->game_main_version == E_MAIN_GAME_CODE)
|
||||
base_game = E_VERSION_ID;
|
||||
|
||||
if((base_game == S_VERSION_ID) && (identifier->game_sub_version == R_SUB_GAME_CODE))
|
||||
base_game += 1;
|
||||
if((base_game == FR_VERSION_ID) && (identifier->game_sub_version == LG_SUB_GAME_CODE))
|
||||
base_game += 1;
|
||||
|
||||
return base_game;
|
||||
}
|
||||
|
||||
void determine_game_with_save(struct game_identity* identifier, u8 slot, u8 section_pos, u16 total_bytes) {
|
||||
u32 game_code = -1;
|
||||
if(identifier->game_main_version == UNDETERMINED) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
#define E_MAIN_GAME_CODE 0x2
|
||||
#define E_SUB_GAME_CODE 0x0
|
||||
|
||||
#define S_VERSION_ID 1
|
||||
#define E_VERSION_ID 3
|
||||
#define FR_VERSION_ID 4
|
||||
|
||||
struct game_identity {
|
||||
u8 game_is_jp;
|
||||
u8 game_main_version;
|
||||
|
|
@ -21,5 +25,6 @@ struct game_identity {
|
|||
void init_game_identifier(struct game_identity*);
|
||||
void get_game_id(struct game_identity*);
|
||||
void determine_game_with_save(struct game_identity*, u8, u8, u16);
|
||||
u8 id_to_version(struct game_identity*);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user