Convert Pokerus between gen 3 and gen 2

This commit is contained in:
Lorenzooone 2023-07-07 22:45:33 +02:00
parent 0b7c40d159
commit 98dcd9a8d5
7 changed files with 88 additions and 28 deletions

View File

@ -16,6 +16,7 @@ u16 get_mon_index_gen2(int, u8);
u16 get_mon_index_gen1_to_3(u8);
u16 calc_stats_gen1(u16, u8, u8, u8, u16);
u16 calc_stats_gen2(u16, u32, u8, u8, u8, u16);
u8 sanitize_pokerus_gen2(u8);
u8 get_gender_thresholds_gen12(u8);
u8 get_gender_useless_atk_ivs_gen12(u8);
u8 get_pokemon_gender_gen2(u8, u8, u8, u8);

View File

@ -422,6 +422,7 @@ u16 get_possible_abilities_pokemon(int, u32, u8, u8);
u8 get_pokemon_gender_gen3(int, u32, u8, u8);
u16 calc_stats_gen3(u16, u32, u8, u8, u8, u8, u8);
void place_and_encrypt_gen3_data(struct gen3_mon_data_unenc*, struct gen3_mon*);
u8 sanitize_pokerus_gen3(u8);
u8 get_valid_language(u8);
u8 get_pp_of_move(u16, u8, u16);

View File

@ -39,7 +39,7 @@ static u16 applied_ball;
static u8 egg_met_location;
static u8 first_set_egg_met_location;
const struct version_t version = { .main_version = 1, .sub_version = 1, .revision_version = 7, .revision_letter = CONSOLE_LETTER};
const struct version_t version = { .main_version = 1, .sub_version = 1, .revision_version = 8, .revision_letter = CONSOLE_LETTER};
const u8* egg_valid_met_locations[NUMBER_OF_GAMES+FIRST_VERSION_ID] = {valid_egg_locations_rs_bin, valid_egg_locations_rs_bin, valid_egg_locations_rs_bin, valid_egg_locations_e_bin, valid_egg_locations_frlg_bin, valid_egg_locations_frlg_bin};
void set_default_settings() {

View File

@ -12,6 +12,9 @@
const u8* set_buffer_with_gen2(const u8*, u8, u8*);
u16 get_stat_exp_contribution(u16);
u8 is_pokerus_strain_valid_gen2(u8);
u8 get_pokerus_strain_max_days_gen2(u8);
u8 are_pokerus_days_valid_gen2(u8);
u8 stat_index_conversion_gen2[] = {0, 1, 2, 5, 3, 4};
u8 gender_thresholds_gen12[TOTAL_GENDER_KINDS] = {8, 0, 2, 4, 12, 14, 16, 17, 0, 16};
@ -138,6 +141,47 @@ u16 calc_stats_gen2(u16 species, u32 pid, u8 stat_index, u8 level, u8 iv, u16 st
return base + Div((((stats_table_gen2[mon_index].stats[stat_index] + iv)*2) + (get_stat_exp_contribution(stat_exp) >> 2)) * level, 100);
}
u8 is_pokerus_strain_valid_gen2(u8 pokerus_byte) {
if(!pokerus_byte)
return 1;
// Strains 0 <= x <= 8 can generate in gen 2
if((pokerus_byte >> 4) > 8)
return 0;
return 1;
}
u8 get_pokerus_strain_max_days_gen2(u8 pokerus_byte) {
if(!is_pokerus_strain_valid_gen2(pokerus_byte))
return 0;
if(!(pokerus_byte >> 4))
return 1;
return (((pokerus_byte >> 4) - 1) & 3) + 1;
}
u8 are_pokerus_days_valid_gen2(u8 pokerus_byte) {
if(!pokerus_byte)
return 1;
if(!is_pokerus_strain_valid_gen2(pokerus_byte))
return 0;
if((pokerus_byte & 0xF) > get_pokerus_strain_max_days_gen2(pokerus_byte))
return 0;
return 1;
}
u8 sanitize_pokerus_gen2(u8 pokerus_byte) {
// Do nothing if there was no infection
if(!pokerus_byte)
return pokerus_byte;
if(!is_pokerus_strain_valid_gen2(pokerus_byte))
pokerus_byte = ((pokerus_byte & 0xF0) - 0x80) | (pokerus_byte & 0xF);
// Although strain 0 is technically legal, it's buggy, so avoid it
if(!(pokerus_byte >> 4))
pokerus_byte |= 0x10;
if(!are_pokerus_days_valid_gen2(pokerus_byte))
pokerus_byte = ((pokerus_byte) & 0xF0) | get_pokerus_strain_max_days_gen2(pokerus_byte);
return pokerus_byte;
}
u8 get_gender_thresholds_gen12(u8 gender_kind) {
if(gender_kind >= TOTAL_GENDER_KINDS)
gender_kind = 0;

View File

@ -79,6 +79,8 @@ void set_language_gen12_to_gen3(struct gen3_mon*, u16, u8, u8*, u8);
void sanitize_ot_name_gen3_to_gen12(u8*, u8*, u8, u8);
void sanitize_ot_name_gen12_to_gen3(u8*, u8*, u8);
void clean_name_gen12(u8*, u8);
u8 convert_pokerus_gen3_to_gen2(u8);
u8 convert_pokerus_gen2_to_gen3(u8);
u16 swap_endian_short(u16 shrt) {
return ((shrt & 0xFF00) >> 8) | ((shrt & 0xFF) << 8);
@ -1058,6 +1060,14 @@ void convert_strings_of_gen12(struct gen3_mon* dst, u8 species, u8* ot_name, u8*
convert_trainer_name_gen12_to_gen3(ot_name, dst->ot_name, is_jp_gen2, dst->language, OT_NAME_GEN3_MAX_SIZE);
}
u8 convert_pokerus_gen3_to_gen2(u8 pokerus) {
return sanitize_pokerus_gen2(sanitize_pokerus_gen3(pokerus));
}
u8 convert_pokerus_gen2_to_gen3(u8 pokerus) {
return sanitize_pokerus_gen3(sanitize_pokerus_gen2(pokerus));
}
u8 gen3_to_gen2(struct gen2_mon* dst_data, struct gen3_mon_data_unenc* data_src, u32 trainer_id) {
struct gen3_mon* src = data_src->src;
@ -1110,8 +1120,8 @@ u8 gen3_to_gen2(struct gen2_mon* dst_data, struct gen3_mon_data_unenc* data_src,
// Assign IVs
dst->ivs = convert_ivs_of_gen3(misc, growth->species, src->pid, is_shiny, gender, gender_kind, 1, 0);
// Is this really how it works...?
dst->pokerus = misc->pokerus;
// Convert pokerus
dst->pokerus = convert_pokerus_gen3_to_gen2(misc->pokerus);
// Defaults
dst->friendship = BASE_FRIENDSHIP;
@ -1384,7 +1394,8 @@ u8 gen2_to_gen3(struct gen2_mon_data* src, struct gen3_mon_data_unenc* data_dst,
// Set the moves
convert_moves_to_gen3(&data_dst->attacks, &data_dst->growth, src->moves, src->pps, 1);
data_dst->misc.pokerus = src->pokerus;
// Convert pokerus
data_dst->misc.pokerus = convert_pokerus_gen2_to_gen3(src->pokerus);
// Set the PID-Origin-IVs data, they're all connected
set_origin_pid_iv(dst, data_dst, data_dst->growth.species, src->ivs, wanted_nature, src->ot_gender, is_egg, no_restrictions);

View File

@ -993,14 +993,16 @@ void print_pokemon_base_data(u8 load_sprites, struct gen3_mon_data_unenc* mon, u
if(is_shiny && has_pokerus)
PRINT_FUNCTION(" - ");
if(has_pokerus == HAS_POKERUS)
PRINT_FUNCTION("Has Pok\xE9rus");
else if(has_pokerus == HAD_POKERUS)
PRINT_FUNCTION("Had Pok\xE9rus");
}
else
else {
PRINT_FUNCTION("\x05\n", get_pokemon_name_raw(mon), get_pokemon_name_raw_language_limit(mon), IS_SYS_LANGUAGE_JAPANESE);
set_text_x((x>>3) + POKEMON_SPRITE_X_TILES);
}
if(has_pokerus == HAS_POKERUS)
PRINT_FUNCTION("Has Pok\xE9rus");
else if(has_pokerus == HAD_POKERUS)
PRINT_FUNCTION("Had Pok\xE9rus");
}
void print_warning_when_clock_changed() {

View File

@ -88,10 +88,9 @@ const struct learnset_data_mon_moves* extract_learnable_moves(const u16*, u16, u
const u16* get_special_evolutions(u16);
u16 get_trade_evolution(u16, u16, u8, u8*, u8*);
void evolve_mon(struct gen3_mon*, struct gen3_mon_data_unenc*, u16, u8, const u16*);
u8 is_pokerus_strain_valid(u8);
u8 get_pokerus_strain_max_days(u8);
u8 are_pokerus_days_valid(u8);
void sanitize_pokerus(u8*);
u8 is_pokerus_strain_valid_gen3(u8);
u8 get_pokerus_strain_max_days_gen3(u8);
u8 are_pokerus_days_valid_gen3(u8);
// Order is G A E M. Initialized by init_enc_positions
u8 enc_positions[PID_POSITIONS];
@ -603,7 +602,7 @@ void update_pokerus_gen3(struct gen3_mon_data_unenc* data_src, u16 days_increase
u8 give_pokerus_gen3(struct gen3_mon_data_unenc* data_src){
if(data_src->successfully_decrypted)
if((!data_src->misc.pokerus) && (!data_src->is_egg)) {
if(!data_src->misc.pokerus) {
// This is for resolving the issue in FRLG, not for cheating,
// so a non-spreadable Pokérus is given
data_src->misc.pokerus = 0x10;
@ -924,7 +923,7 @@ void recalc_stats_gen3(struct gen3_mon_data_unenc* data_dst, struct gen3_mon* ds
dst->status = 0;
}
u8 is_pokerus_strain_valid(u8 pokerus_byte) {
u8 is_pokerus_strain_valid_gen3(u8 pokerus_byte) {
if(!pokerus_byte)
return 1;
if(!((pokerus_byte >> 4) & 7))
@ -932,27 +931,31 @@ u8 is_pokerus_strain_valid(u8 pokerus_byte) {
return 1;
}
u8 get_pokerus_strain_max_days(u8 pokerus_byte) {
u8 get_pokerus_strain_max_days_gen3(u8 pokerus_byte) {
if(!((pokerus_byte >> 4) & 7))
return 0;
return ((pokerus_byte >> 4) & 3) + 1;
}
u8 are_pokerus_days_valid(u8 pokerus_byte) {
u8 are_pokerus_days_valid_gen3(u8 pokerus_byte) {
if(!pokerus_byte)
return 1;
if(!is_pokerus_strain_valid(pokerus_byte))
if(!is_pokerus_strain_valid_gen3(pokerus_byte))
return 0;
if((pokerus_byte & 0xF) > get_pokerus_strain_max_days(pokerus_byte))
if((pokerus_byte & 0xF) > get_pokerus_strain_max_days_gen3(pokerus_byte))
return 0;
return 1;
}
void sanitize_pokerus(u8* pokerus_byte) {
if(!is_pokerus_strain_valid(*pokerus_byte))
*pokerus_byte |= 0x10;
if(!are_pokerus_days_valid(*pokerus_byte))
*pokerus_byte = ((*pokerus_byte) & 0xF0) | get_pokerus_strain_max_days(*pokerus_byte);
u8 sanitize_pokerus_gen3(u8 pokerus_byte) {
// Do nothing if there was no infection
if(!pokerus_byte)
return pokerus_byte;
if(!is_pokerus_strain_valid_gen3(pokerus_byte))
pokerus_byte |= 0x10;
if(!are_pokerus_days_valid_gen3(pokerus_byte))
pokerus_byte = ((pokerus_byte) & 0xF0) | get_pokerus_strain_max_days_gen3(pokerus_byte);
return pokerus_byte;
}
void place_and_encrypt_gen3_data(struct gen3_mon_data_unenc* src, struct gen3_mon* dst) {
@ -1184,7 +1187,7 @@ void process_gen3_data(struct gen3_mon* src, struct gen3_mon_data_unenc* dst, u8
src->language = DEFAULT_NAME_BAD_LANGUAGE;
// Sanitize pokerus data...
sanitize_pokerus(&misc->pokerus);
misc->pokerus = sanitize_pokerus_gen3(misc->pokerus);
// We reuse this SOOOO much...
dst->is_egg = is_egg_gen3(src, misc);
@ -1194,8 +1197,6 @@ void process_gen3_data(struct gen3_mon* src, struct gen3_mon_data_unenc* dst, u8
// Eggs should not have items or mails
growth->item = NO_ITEM_ID;
src->mail_id = GEN3_NO_MAIL;
// Eggs cannot have pokerus
misc->pokerus = 0;
// Eggs cannot have PP UPs
growth->pp_bonuses = 0;
src->level = EGG_LEVEL_GEN3;