pokemon_gender.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include <gui/modules/submenu.h>
  2. #include "../pokemon_app.h"
  3. #include "../pokemon_data.h"
  4. #include "pokemon_menu.h"
  5. static const char* gender_str[] = {
  6. "Unknown",
  7. "Female",
  8. "Male",
  9. };
  10. /* This returns a string pointer if the gender is static, NULL if it is not and
  11. * the gender needs to be calculated.
  12. */
  13. const char* select_gender_is_static(PokemonData* pdata, uint8_t ratio) {
  14. switch(ratio) {
  15. case 0xFF:
  16. return gender_str[0];
  17. case 0xFE:
  18. return gender_str[1];
  19. case 0x00:
  20. if(pokemon_stat_get(pdata, STAT_NUM, NONE) != 0xEB) { // Tyrogue can be either gender
  21. return gender_str[2];
  22. }
  23. break;
  24. default:
  25. break;
  26. }
  27. return NULL;
  28. }
  29. const char* select_gender_get(PokemonData* pdata) {
  30. uint8_t ratio = table_stat_base_get(
  31. pdata->pokemon_table,
  32. pokemon_stat_get(pdata, STAT_NUM, NONE),
  33. STAT_BASE_GENDER_RATIO,
  34. NONE);
  35. uint8_t atk_iv;
  36. const char* rc;
  37. rc = select_gender_is_static(pdata, ratio);
  38. if(rc) return rc;
  39. /* Falling through here means now we need to calculate the gender from
  40. * its ratio and ATK_IV.
  41. */
  42. atk_iv = pokemon_stat_get(pdata, STAT_ATK_IV, NONE);
  43. if(atk_iv * 17 <= ratio)
  44. return gender_str[1];
  45. else
  46. return gender_str[2];
  47. }
  48. static void select_gender_selected_callback(void* context, uint32_t index) {
  49. PokemonFap* pokemon_fap = (PokemonFap*)context;
  50. PokemonData* pdata = pokemon_fap->pdata;
  51. uint8_t ratio = table_stat_base_get(
  52. pdata->pokemon_table,
  53. pokemon_stat_get(pdata, STAT_NUM, NONE),
  54. STAT_BASE_GENDER_RATIO,
  55. NONE);
  56. uint8_t atk_iv = pokemon_stat_get(pdata, STAT_ATK_IV, NONE);
  57. /* If we need to make the pokemon a male, increase atk IV until it exceeds
  58. * the gender ratio.
  59. *
  60. * Note that, there is no checking here for impossible situations as the
  61. * scene enter function will immediately quit if its not possible to change
  62. * the gender (the extremes of gender_ratio value).
  63. *
  64. * The check for gender is a percentage, if ATK_IV*(255/15) <= the ratio,
  65. * then the pokemon is a female. The gender ratio values end up being:
  66. * DEF GENDER_F0 EQU 0 percent
  67. * DEF GENDER_F12_5 EQU 12 percent + 1
  68. * DEF GENDER_F25 EQU 25 percent
  69. * DEF GENDER_F50 EQU 50 percent
  70. * DEF GENDER_F75 EQU 75 percent
  71. * DEF GENDER_F100 EQU 100 percent - 1
  72. * Where percent is (255/100)
  73. */
  74. if(index) {
  75. while((atk_iv * 17) <= ratio) atk_iv++;
  76. } else {
  77. while((atk_iv * 17) > ratio) atk_iv--;
  78. }
  79. pokemon_stat_set(pdata, STAT_ATK_IV, NONE, atk_iv);
  80. scene_manager_previous_scene(pokemon_fap->scene_manager);
  81. }
  82. void select_gender_scene_on_enter(void* context) {
  83. PokemonFap* pokemon_fap = (PokemonFap*)context;
  84. submenu_reset(pokemon_fap->submenu);
  85. submenu_add_item(
  86. pokemon_fap->submenu, "Female", 0, select_gender_selected_callback, pokemon_fap);
  87. submenu_add_item(
  88. pokemon_fap->submenu, "Male", 1, select_gender_selected_callback, pokemon_fap);
  89. }