pokemon_pokerus.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include <gui/modules/variable_item_list.h>
  2. #include <furi.h>
  3. #include <src/include/pokemon_app.h>
  4. #include <src/scenes/include/pokemon_scene.h>
  5. #include <src/include/pokemon_attribute.h>
  6. static const char* strains[] = {
  7. "None",
  8. "A",
  9. "B",
  10. "C",
  11. "D",
  12. "",
  13. };
  14. struct pokerus_itemlist {
  15. VariableItem* strain;
  16. VariableItem* days;
  17. };
  18. static struct pokerus_itemlist pokerus = {0};
  19. static void select_pokerus_rebuild_list(PokemonFap* pokemon_fap);
  20. static void select_strain_callback(VariableItem* item) {
  21. uint8_t index = variable_item_get_current_value_index(item);
  22. PokemonFap* pokemon_fap = variable_item_get_context(item);
  23. /* Need to set the new text from the mangled index */
  24. variable_item_set_current_value_text(item, strains[index]);
  25. /* demangle the index to the value we need to set in trade struct */
  26. if(index == 0)
  27. ;
  28. else if(index == 0x01)
  29. index = 0x04; // Map this back to the A strain
  30. else
  31. index--;
  32. pokerus_set_strain(pokemon_fap->pdata, index);
  33. select_pokerus_rebuild_list(pokemon_fap);
  34. variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 0);
  35. }
  36. static void select_days_callback(VariableItem* item) {
  37. uint8_t index = variable_item_get_current_value_index(item);
  38. PokemonFap* pokemon_fap = variable_item_get_context(item);
  39. pokerus_set_days(pokemon_fap->pdata, index);
  40. select_pokerus_rebuild_list(pokemon_fap);
  41. variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 1);
  42. }
  43. static void select_pokerus_rebuild_list(PokemonFap* pokemon_fap) {
  44. uint8_t strain;
  45. uint8_t days;
  46. FuriString* daystring = NULL;
  47. days = pokemon_stat_get(pokemon_fap->pdata, STAT_POKERUS, NONE);
  48. strain = (days >> 4);
  49. days &= 0x0f;
  50. variable_item_list_reset(pokemon_fap->variable_item_list);
  51. pokerus.strain = variable_item_list_add(
  52. pokemon_fap->variable_item_list, "Strain:", 5, select_strain_callback, pokemon_fap);
  53. pokerus.days = variable_item_list_add(
  54. pokemon_fap->variable_item_list,
  55. "Days remain:",
  56. (strain == 0 ? 0 : 16),
  57. select_days_callback,
  58. pokemon_fap);
  59. /* Strain is a bit weird in that there are only 4 strains, but, a strain of
  60. * 0 with a days remaining of 0 means the pokemon never had the pokerus.
  61. * To combat this, we only ever set nibble values 4-7 for the 4 strains,
  62. * with a value of 0 being specifically reserved for having never had it.
  63. */
  64. /* A
  65. * 0000
  66. * 0100
  67. * 1000
  68. * 1100
  69. *
  70. * B
  71. * 0001
  72. * 0101
  73. * 1001
  74. * 1101
  75. *
  76. * C
  77. * 0010
  78. * 0110
  79. * 1010
  80. * 1110
  81. *
  82. * D
  83. * 0011
  84. * 0111
  85. * 1011
  86. * 1111
  87. *
  88. * So, if the whole thing is 0, then it should be considered "Clean"
  89. * If the lower bits are cleared, but any of the upper bits are set, modify
  90. * it to be equal to 0100 for our housekeeping.
  91. * Anything else, we just clear the upper bits and are now in a known good
  92. * state.
  93. *
  94. * So everything is in order, at this point, make a value of 0x04 == 0x1 "A",
  95. * leave 0x0 as 0, and add 1 to the remaining.
  96. *
  97. * When setting, we need to translate this back to the above bit values.
  98. */
  99. if(strain == 0)
  100. ;
  101. else if(((strain & 0x03) == 0) && ((strain & 0xc0) != 0))
  102. strain = 0x01; // This would be A
  103. else {
  104. strain &= 0x03;
  105. strain++;
  106. }
  107. daystring = furi_string_alloc_printf("%d", days);
  108. variable_item_set_current_value_index(pokerus.strain, strain);
  109. variable_item_set_current_value_text(pokerus.strain, strains[strain]);
  110. variable_item_set_current_value_index(pokerus.days, (strain == 0 ? 0 : days));
  111. variable_item_set_current_value_text(pokerus.days, furi_string_get_cstr(daystring));
  112. furi_string_free(daystring);
  113. }
  114. void pokemon_scene_select_pokerus_on_enter(void* context) {
  115. PokemonFap* pokemon_fap = (PokemonFap*)context;
  116. select_pokerus_rebuild_list(pokemon_fap);
  117. view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewVariableItem);
  118. }
  119. bool pokemon_scene_select_pokerus_on_event(void* context, SceneManagerEvent event) {
  120. UNUSED(context);
  121. UNUSED(event);
  122. return false;
  123. }
  124. void pokemon_scene_select_pokerus_on_exit(void* context) {
  125. UNUSED(context);
  126. }