mirror of
https://github.com/Lorenzooone/Pokemon-Gen3-to-Gen-X.git
synced 2026-04-26 08:37:40 -05:00
Implement better gender-iv conversion
This commit is contained in:
parent
d4901a4324
commit
29084a8bf7
|
|
@ -17,6 +17,7 @@ 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 get_gender_thresholds_gen12(u8);
|
||||
u8 get_gender_useless_atk_ivs_gen12(u8);
|
||||
u8 get_pokemon_gender_gen2(u8, u8, u8, u8);
|
||||
u8 get_pokemon_gender_kind_gen2(u8, u8, u8);
|
||||
const u8* get_pokemon_name_gen2(int, u8, u8, u8*);
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@
|
|||
#define M_GENDER 0
|
||||
#define F_GENDER 1
|
||||
#define U_GENDER 2
|
||||
#define M_INDEX 1
|
||||
#define F_INDEX 6
|
||||
#define U_INDEX 7
|
||||
#define M_GENDER_INDEX 1
|
||||
#define F_GENDER_INDEX 6
|
||||
#define U_GENDER_INDEX 7
|
||||
#define NIDORAN_M_GENDER_INDEX 8
|
||||
#define NIDORAN_F_GENDER_INDEX 9
|
||||
#define TOTAL_GENDER_KINDS 10
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
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};
|
||||
u8 gender_useful_atk_ivs[TOTAL_GENDER_KINDS] = {3, 4, 1, 2, 2, 1, 4, 4, 4, 4};
|
||||
|
||||
const struct stats_gen_23* stats_table_gen2 = (const struct stats_gen_23*)pokemon_stats_bin;
|
||||
const struct stats_gen_1* stats_table_gen1 = (const struct stats_gen_1*)pokemon_stats_gen1_bin;
|
||||
|
|
@ -160,6 +161,12 @@ u8 get_gender_thresholds_gen12(u8 gender_kind) {
|
|||
return gender_thresholds_gen12[gender_kind];
|
||||
}
|
||||
|
||||
u8 get_gender_useless_atk_ivs_gen12(u8 gender_kind) {
|
||||
if(gender_kind >= TOTAL_GENDER_KINDS)
|
||||
gender_kind = 0;
|
||||
return 4-gender_useful_atk_ivs[gender_kind];
|
||||
}
|
||||
|
||||
u8 get_pokemon_gender_kind_gen2(u8 index, u8 is_egg, u8 curr_gen) {
|
||||
if(curr_gen == 1)
|
||||
return pokemon_gender_bin[get_mon_index_gen2_1(index)];
|
||||
|
|
@ -183,13 +190,13 @@ const u8* get_pokemon_name_gen2(int index, u8 is_egg, u8 is_jp, u8* buffer) {
|
|||
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){
|
||||
case M_INDEX:
|
||||
case M_GENDER_INDEX:
|
||||
case NIDORAN_M_GENDER_INDEX:
|
||||
return M_GENDER;
|
||||
case F_INDEX:
|
||||
case F_GENDER_INDEX:
|
||||
case NIDORAN_F_GENDER_INDEX:
|
||||
return F_GENDER;
|
||||
case U_INDEX:
|
||||
case U_GENDER_INDEX:
|
||||
return U_GENDER;
|
||||
default:
|
||||
if(atk_ivs >= get_gender_thresholds_gen12(gender_kind))
|
||||
|
|
|
|||
|
|
@ -307,11 +307,15 @@ void convert_evs_to_gen3(struct gen3_mon_evs* evs, u16* UNUSED(old_evs)) {
|
|||
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;
|
||||
|
||||
// Prepare gender related data
|
||||
u8 gender_threshold = get_gender_thresholds_gen12(gender_kind);
|
||||
u8 gender_useless_ivs = get_gender_useless_atk_ivs_gen12(gender_kind);
|
||||
|
||||
// Assign IVs
|
||||
// Keep in mind: Unown letter, gender and shinyness
|
||||
// Hidden Power calculations are too restrictive
|
||||
u8 atk_ivs = misc->atk_ivs >> 1;
|
||||
u8 atk_ivs = (((misc->atk_ivs >> 1)>>gender_useless_ivs) | ((misc->atk_ivs >> 1)<<gender_useless_ivs)) & 0xF;
|
||||
u8 def_ivs = misc->def_ivs >> 1;
|
||||
u8 spa_ivs = (misc->spa_ivs + misc->spd_ivs) >> 2;
|
||||
u8 spe_ivs = misc->spe_ivs >> 1;
|
||||
|
|
@ -347,12 +351,26 @@ u16 convert_ivs_of_gen3(struct gen3_mon_misc* misc, u16 species, u32 pid, u8 is_
|
|||
}
|
||||
|
||||
// Gender
|
||||
// TODO: Remake this to offer a more fair conversion
|
||||
if(gender != U_GENDER && gender_kind != M_INDEX && gender_kind != F_INDEX) {
|
||||
if(gender == F_GENDER && atk_ivs >= get_gender_thresholds_gen12(gender_kind))
|
||||
atk_ivs = get_gender_thresholds_gen12(gender_kind) - 1;
|
||||
else if(gender == M_GENDER && atk_ivs < get_gender_thresholds_gen12(gender_kind))
|
||||
atk_ivs = get_gender_thresholds_gen12(gender_kind);
|
||||
if((gender_threshold > 0) && (gender_threshold < 16)) {
|
||||
if(gender == F_GENDER) {
|
||||
if(atk_ivs >= gender_threshold) {
|
||||
u8 is_power_of_2 = 0;
|
||||
for(int i = 0; i < 4; i++)
|
||||
if(gender_threshold == (1 << i)) {
|
||||
is_power_of_2 = 1;
|
||||
break;
|
||||
}
|
||||
if(is_power_of_2)
|
||||
atk_ivs &= (gender_threshold - 1);
|
||||
else {
|
||||
if(is_shiny && (gender_useless_ivs > (4-2)))
|
||||
gender_useless_ivs = 4-2;
|
||||
atk_ivs &= ~(1<<(4-gender_useless_ivs));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
atk_ivs |= gender_threshold;
|
||||
}
|
||||
|
||||
// Shinyness
|
||||
|
|
@ -362,6 +380,7 @@ u16 convert_ivs_of_gen3(struct gen3_mon_misc* misc, u16 species, u32 pid, u8 is_
|
|||
spa_ivs = 10;
|
||||
spe_ivs = 10;
|
||||
}
|
||||
|
||||
if(!is_shiny && is_shiny_gen2(atk_ivs, def_ivs, spa_ivs, spe_ivs))
|
||||
spe_ivs = 11;
|
||||
|
||||
|
|
|
|||
|
|
@ -347,13 +347,13 @@ u8 make_moves_legal_gen3(struct gen3_mon_attacks* attacks){
|
|||
u8 get_pokemon_gender_gen3(int index, u32 pid, u8 is_egg, u8 deoxys_form){
|
||||
u8 gender_kind = get_pokemon_gender_kind_gen3(index, pid, is_egg, deoxys_form);
|
||||
switch(gender_kind){
|
||||
case M_INDEX:
|
||||
case M_GENDER_INDEX:
|
||||
case NIDORAN_M_GENDER_INDEX:
|
||||
return M_GENDER;
|
||||
case F_INDEX:
|
||||
case F_GENDER_INDEX:
|
||||
case NIDORAN_F_GENDER_INDEX:
|
||||
return F_GENDER;
|
||||
case U_INDEX:
|
||||
case U_GENDER_INDEX:
|
||||
return U_GENDER;
|
||||
default:
|
||||
if((pid & 0xFF) >= gender_thresholds_gen3[gender_kind])
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ u8 search_unown_pid_masks(u32, u8, u32*, u32*);
|
|||
void _generate_unown_shiny_info(u8, u16, u8, u32*, u32*, u32);
|
||||
|
||||
// Nidoran M is special, it has to have 0x8000 set in the lower PID
|
||||
u8 gender_useful_atk_ivs[] = {3, 4, 1, 2, 2, 1, 4, 4, 4, 4};
|
||||
u16 gender_values[] = {0x7F, 0, 0x1F, 0x3F, 0xBF, 0xDF, 0, 0, 0x7FFF, 0};
|
||||
const u8 wanted_nature_shiny_table[NUM_NATURES] = {0, 1, 2, 3, 4, 5, 6, 7, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x15, 0x16, 0x17, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45};
|
||||
|
||||
|
|
@ -123,7 +122,7 @@ IWRAM_CODE MAX_OPTIMIZE u32 generate_ot(u16 tid, u8* name) {
|
|||
|
||||
IWRAM_CODE MAX_OPTIMIZE 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) & 0xF)<<(4-gender_useful_atk_ivs[gender_kind])) & 0xF)<<1;
|
||||
u8 atk_ivs = ((((wanted_ivs>>4) & 0xF)<<get_gender_useless_atk_ivs_gen12(gender_kind)) & 0xF)<<1;
|
||||
u8 def_ivs = ((wanted_ivs) & 0xF)<<1;
|
||||
u8 spe_ivs = ((wanted_ivs>>12) & 0xF)<<1;
|
||||
u8 spa_ivs = ((wanted_ivs>>8) & 0xF)<<1;
|
||||
|
|
@ -158,7 +157,7 @@ IWRAM_CODE MAX_OPTIMIZE void _generate_egg_info(u8 wanted_nature, u16 wanted_ivs
|
|||
u32 seed = (k<<31) | (new_spe_ivs << 16) | (new_spa_ivs << 21) | (new_spd_ivs << 26) | l;
|
||||
|
||||
u16 generated_ivs = get_prev_seed(seed) >> 16;
|
||||
u8 new_atk_ivs = (((generated_ivs >> 5)&0x1F)>>(1+(4-gender_useful_atk_ivs[gender_kind]))) << (1+(4-gender_useful_atk_ivs[gender_kind]));
|
||||
u8 new_atk_ivs = (((generated_ivs >> 5)&0x1F)>>(1+get_gender_useless_atk_ivs_gen12(gender_kind))) << (1+get_gender_useless_atk_ivs_gen12(gender_kind));
|
||||
u8 new_def_ivs = (((generated_ivs >> 10)&0x1F)>>1) << 1;
|
||||
|
||||
if(new_atk_ivs == atk_ivs && new_def_ivs == def_ivs) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user