pokemon_data.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. #include <pokemon_icons.h>
  2. #include <storage/storage.h>
  3. #include "pokemon_data.h"
  4. #include "pokemon_data_i.h"
  5. #include "pokemon_app.h"
  6. #include "pokemon_char_encode.h"
  7. #include "pokemon_table.h"
  8. #include <named_list.h>
  9. #include <item_nl.h>
  10. #include <stat_nl.h>
  11. #include <type_nl.h>
  12. #include <move_nl.h>
  13. #include <missingno_i.h>
  14. #define RECALC_NONE 0x00
  15. #define RECALC_EXP 0x01
  16. #define RECALC_EVS 0x02
  17. #define RECALC_IVS 0x04
  18. #define RECALC_STATS 0x08
  19. #define RECALC_NICKNAME 0x10
  20. #define RECALC_MOVES 0x20
  21. #define RECALC_TYPES 0x40
  22. #define RECALC_ALL 0xFF
  23. #define FXBM_SPRITE_SIZE 404 // Each 56x56 sprite
  24. /* Text lookups to make debug output cleaner and easier to parse as a human */
  25. static char* stat_text_get(DataStat stat) {
  26. switch(stat) {
  27. case STAT_ATK:
  28. return "ATK";
  29. case STAT_DEF:
  30. return "DEF";
  31. case STAT_SPD:
  32. return "SPD";
  33. case STAT_SPC:
  34. return "SPC";
  35. case STAT_SPC_ATK:
  36. return "SPC_ATK";
  37. case STAT_SPC_DEF:
  38. return "SPC_DEF";
  39. case STAT_HP:
  40. return "HP";
  41. case STAT_TYPE:
  42. return "Type";
  43. case STAT_MOVE:
  44. return "Move";
  45. case STAT_ATK_EV:
  46. return "ATK_EV";
  47. case STAT_DEF_EV:
  48. return "DEF_EV";
  49. case STAT_SPD_EV:
  50. return "SPD_EV";
  51. case STAT_SPC_ATK_EV:
  52. case STAT_SPC_DEF_EV:
  53. case STAT_SPC_EV:
  54. return "SPC_EV";
  55. case STAT_HP_EV:
  56. return "HP_EV";
  57. case STAT_IV:
  58. return "IV";
  59. case STAT_ATK_IV:
  60. return "ATK_IV";
  61. case STAT_DEF_IV:
  62. return "DEF_IV";
  63. case STAT_SPD_IV:
  64. return "SPD_IV";
  65. case STAT_SPC_ATK_IV:
  66. case STAT_SPC_DEF_IV:
  67. case STAT_SPC_IV:
  68. return "SPC_IV";
  69. case STAT_HP_IV:
  70. return "HP_IV";
  71. case STAT_LEVEL:
  72. return "Lvl.";
  73. case STAT_INDEX:
  74. return "Idx.";
  75. case STAT_NUM:
  76. return "Num.";
  77. case STAT_CONDITION:
  78. return "Cond.";
  79. case STAT_NICKNAME:
  80. return "Nick.";
  81. case STAT_OT_NAME:
  82. return "OT Name";
  83. case STAT_OT_ID:
  84. return "OT ID";
  85. case STAT_TRAINER_NAME:
  86. return "Trainer Name";
  87. case STAT_SEL:
  88. return "EV/IV Sel."; // which EV/IV calc to use
  89. case STAT_EXP:
  90. return "Exp.";
  91. case STAT_HELD_ITEM:
  92. return "Held Item";
  93. case STAT_POKERUS:
  94. return "Pokerus";
  95. default:
  96. return "UNKNOWN STAT";
  97. }
  98. }
  99. /* Allocates a chunk of memory for the trade data block and sets up some
  100. * default values.
  101. */
  102. PokemonData* pokemon_data_alloc(uint8_t gen) {
  103. PokemonData* pdata;
  104. pdata = malloc(sizeof(PokemonData));
  105. pdata->gen = gen;
  106. /* Set up lists */
  107. pdata->move_list = move_list;
  108. pdata->type_list = type_list;
  109. pdata->stat_list = stat_list;
  110. pdata->item_list = item_list;
  111. pdata->pokemon_table = table_pointer_get();
  112. pdata->storage = furi_record_open(RECORD_STORAGE);
  113. pdata->asset_path = furi_string_alloc_set(APP_ASSETS_PATH());
  114. storage_common_resolve_path_and_ensure_app_directory(pdata->storage, pdata->asset_path);
  115. switch(gen) {
  116. case GEN_I:
  117. /* Allocate trade block and set its size for the trade view to use */
  118. pdata->trade_block_sz = sizeof(TradeBlockGenI);
  119. pdata->party_sz = sizeof(PokemonPartyGenI) * 6;
  120. pdata->trade_block = malloc(pdata->trade_block_sz);
  121. /* The party_members element needs to be 0xff for unused */
  122. memset(
  123. ((TradeBlockGenI*)pdata->trade_block)->party_members,
  124. 0xFF,
  125. sizeof(((TradeBlockGenI*)pdata->trade_block)->party_members));
  126. pdata->party = ((TradeBlockGenI*)pdata->trade_block)->party;
  127. /* Set party count to 1 */
  128. ((TradeBlockGenI*)pdata->trade_block)->party_cnt = 1;
  129. /* Set the max pokedex number, 0 indexed */
  130. pdata->dex_max = 150;
  131. break;
  132. case GEN_II:
  133. /* Allocate trade block and set its size for the trade view to use */
  134. pdata->trade_block_sz = sizeof(TradeBlockGenII);
  135. pdata->party_sz = sizeof(PokemonPartyGenII) * 6;
  136. pdata->trade_block = malloc(pdata->trade_block_sz);
  137. /* The party_members element needs to be 0xff for unused */
  138. memset(
  139. ((TradeBlockGenII*)pdata->trade_block)->party_members,
  140. 0xFF,
  141. sizeof(((TradeBlockGenII*)pdata->trade_block)->party_members));
  142. pdata->party = ((TradeBlockGenII*)pdata->trade_block)->party;
  143. /* Set party count to 1 */
  144. ((TradeBlockGenII*)pdata->trade_block)->party_cnt = 1;
  145. /* Set the max pokedex number, 0 indexed */
  146. pdata->dex_max = 250;
  147. break;
  148. default:
  149. furi_crash("Invalid Gen");
  150. break;
  151. }
  152. /* Trainer/OT name, not to exceed 7 characters! */
  153. pokemon_name_set(pdata, STAT_TRAINER_NAME, "Flipper");
  154. pokemon_name_set(pdata, STAT_OT_NAME, "Flipper");
  155. /* OT trainer ID# */
  156. pokemon_stat_set(pdata, STAT_OT_ID, NONE, 42069);
  157. /* Notes:
  158. * Move pp isn't explicitly set up, should be fine
  159. * Catch/held isn't explicitly set up, should be okay for only Gen I support now
  160. * Status condition isn't explicity let up, would you ever want to?
  161. */
  162. /* Set up initial pokemon and level */
  163. /* This causes all other stats to be recalculated */
  164. pokemon_stat_set(pdata, STAT_NUM, NONE, 0); // First Pokemon
  165. pokemon_stat_set(pdata, STAT_LEVEL, NONE, 2); // Minimum level of 2
  166. return pdata;
  167. }
  168. void pokemon_data_free(PokemonData* pdata) {
  169. furi_record_close(RECORD_STORAGE);
  170. free(pdata->trade_block);
  171. if(pdata->bitmap && pdata->bitmap_num != 0) free(pdata->bitmap);
  172. furi_string_free(pdata->asset_path);
  173. free(pdata);
  174. }
  175. /* Recalculate values and stats based on their dependencies.
  176. * The order of the if statements are in order of dependence from
  177. * depending on no other value, to dpeneding on multiple other values.
  178. *
  179. * level: depends on: none
  180. * iv: depends on: none (only what the EV/IV general setting is, which recalculates EV/IV at time of set)
  181. * ev: depends on: level (sometimes)
  182. * exp: depends on: level, index
  183. * moves: depends on: index
  184. * types: depends on: index
  185. * nickname: depends on: index
  186. * atk/def/etc: depends on: level, iv, ev, index
  187. */
  188. void pokemon_recalculate(PokemonData* pdata, uint8_t recalc) {
  189. furi_assert(pdata);
  190. int i;
  191. if(recalc == RECALC_NONE) return;
  192. /* Ordered in order of priority for calculating other stats */
  193. if(recalc & RECALC_NICKNAME) pokemon_default_nickname_set(NULL, pdata, 0);
  194. if(recalc & RECALC_MOVES) {
  195. for(i = MOVE_0; i <= MOVE_3; i++) {
  196. pokemon_stat_set(
  197. pdata,
  198. STAT_MOVE,
  199. i,
  200. table_stat_base_get(
  201. pdata->pokemon_table,
  202. pokemon_stat_get(pdata, STAT_NUM, NONE),
  203. STAT_BASE_MOVE,
  204. i));
  205. }
  206. }
  207. if(recalc & RECALC_TYPES) {
  208. for(i = TYPE_0; i <= TYPE_1; i++) {
  209. pokemon_stat_set(
  210. pdata,
  211. STAT_TYPE,
  212. i,
  213. table_stat_base_get(
  214. pdata->pokemon_table,
  215. pokemon_stat_get(pdata, STAT_NUM, NONE),
  216. STAT_BASE_TYPE,
  217. i));
  218. }
  219. }
  220. if(recalc & RECALC_EXP) pokemon_exp_calc(pdata);
  221. if(recalc & RECALC_EVS) pokemon_stat_ev_calc(pdata, pdata->stat_sel);
  222. /* This just rerolls the IVs, nothing really to calculate */
  223. if(recalc & RECALC_IVS) pokemon_stat_iv_calc(pdata, pdata->stat_sel);
  224. /* Note: This will still end up calculating spc_def on gen i pokemon.
  225. * However, the way the accessors are set up the calculated value will
  226. * never be written anywhere. This is just wasted CPU time.
  227. */
  228. if(recalc & RECALC_STATS) {
  229. for(i = STAT; i < STAT_END; i++) {
  230. pokemon_stat_calc(pdata, i);
  231. }
  232. }
  233. }
  234. /* This needs to convert to encoded characters */
  235. void pokemon_name_set(PokemonData* pdata, DataStat stat, char* name) {
  236. furi_assert(pdata);
  237. size_t len;
  238. uint8_t gen = pdata->gen;
  239. uint8_t* ptr = NULL;
  240. switch(stat) {
  241. case STAT_NICKNAME:
  242. if(gen == GEN_I) ptr = ((TradeBlockGenI*)pdata->trade_block)->nickname[0].str;
  243. if(gen == GEN_II) ptr = ((TradeBlockGenII*)pdata->trade_block)->nickname[0].str;
  244. len = 10;
  245. break;
  246. case STAT_OT_NAME:
  247. if(gen == GEN_I) ptr = ((TradeBlockGenI*)pdata->trade_block)->ot_name[0].str;
  248. if(gen == GEN_II) ptr = ((TradeBlockGenII*)pdata->trade_block)->ot_name[0].str;
  249. len = 7;
  250. break;
  251. case STAT_TRAINER_NAME:
  252. if(gen == GEN_I) ptr = ((TradeBlockGenI*)pdata->trade_block)->trainer_name.str;
  253. if(gen == GEN_II) ptr = ((TradeBlockGenII*)pdata->trade_block)->trainer_name.str;
  254. len = 7;
  255. break;
  256. default:
  257. furi_crash("name");
  258. break;
  259. }
  260. /* Clear the buffer with TERM character */
  261. memset(ptr, TERM_, LEN_NAME_BUF);
  262. /* Set the encoded name in the buffer */
  263. pokemon_str_to_encoded_array(ptr, name, len);
  264. FURI_LOG_D(TAG, "[data] %s name set to %s", stat_text_get(stat), name);
  265. }
  266. void pokemon_name_get(PokemonData* pdata, DataStat stat, char* dest, size_t len) {
  267. furi_assert(pdata);
  268. uint8_t* ptr = NULL;
  269. uint8_t gen = pdata->gen;
  270. switch(stat) {
  271. case STAT_NICKNAME:
  272. if(gen == GEN_I) ptr = ((TradeBlockGenI*)pdata->trade_block)->nickname[0].str;
  273. if(gen == GEN_II) ptr = ((TradeBlockGenII*)pdata->trade_block)->nickname[0].str;
  274. break;
  275. case STAT_OT_NAME:
  276. if(gen == GEN_I) ptr = ((TradeBlockGenI*)pdata->trade_block)->ot_name[0].str;
  277. if(gen == GEN_II) ptr = ((TradeBlockGenII*)pdata->trade_block)->ot_name[0].str;
  278. break;
  279. default:
  280. furi_crash("name_get invalid");
  281. break;
  282. }
  283. pokemon_encoded_array_to_str(dest, ptr, len);
  284. }
  285. /* If dest is not NULL, a copy of the default name is written to it as well */
  286. void pokemon_default_nickname_set(char* dest, PokemonData* pdata, size_t n) {
  287. furi_assert(pdata);
  288. unsigned int i;
  289. char buf[LEN_NAME_BUF];
  290. /* First, get the default name */
  291. strncpy(
  292. buf,
  293. table_stat_name_get(pdata->pokemon_table, pokemon_stat_get(pdata, STAT_NUM, NONE)),
  294. sizeof(buf));
  295. /* Next, walk through and toupper() each character */
  296. for(i = 0; i < sizeof(buf); i++) {
  297. buf[i] = toupper(buf[i]);
  298. }
  299. pokemon_name_set(pdata, STAT_NICKNAME, buf);
  300. FURI_LOG_D(TAG, "[data] Set default nickname");
  301. if(dest != NULL) {
  302. strncpy(dest, buf, n);
  303. }
  304. }
  305. /* Each sprite 56x56 is 404 bytes long */
  306. uint8_t* pokemon_icon_get(PokemonData* pdata, int num) {
  307. furi_assert(pdata);
  308. File* file;
  309. FuriString* path;
  310. uint32_t size;
  311. bool is_error = true;
  312. if(pdata->bitmap_num != num) {
  313. if(pdata->bitmap) {
  314. free(pdata->bitmap);
  315. pdata->bitmap = NULL;
  316. }
  317. file = storage_file_alloc(pdata->storage);
  318. path = furi_string_alloc_set(pdata->asset_path);
  319. furi_string_cat_printf(path, "all_sprites.fxbm");
  320. if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
  321. storage_file_seek(file, (num - 1) * FXBM_SPRITE_SIZE, true);
  322. if(storage_file_read(file, &size, sizeof(size)) == sizeof(size)) {
  323. pdata->bitmap = malloc(size);
  324. if(storage_file_read(file, pdata->bitmap, size) ==
  325. FXBM_SPRITE_SIZE - sizeof(size)) {
  326. FURI_LOG_D(TAG, "Opened file \'%s\'", furi_string_get_cstr(path));
  327. is_error = false;
  328. } else {
  329. free(pdata->bitmap);
  330. }
  331. }
  332. }
  333. if(is_error) {
  334. FURI_LOG_E(
  335. TAG, "Failed to open \'%s\' or access sprite data", furi_string_get_cstr(path));
  336. pdata->bitmap = (struct fxbm_sprite*)((uint8_t*)(__000_fxbm) + sizeof(size));
  337. num = 0;
  338. }
  339. storage_file_free(file);
  340. furi_string_free(path);
  341. pdata->bitmap_num = num;
  342. }
  343. return (uint8_t*)pdata->bitmap;
  344. }
  345. uint16_t pokemon_stat_get(PokemonData* pdata, DataStat stat, DataStatSub which) {
  346. furi_assert(pdata);
  347. void* party = pdata->party;
  348. int gen = pdata->gen;
  349. uint16_t val = 0;
  350. uint8_t hp_iv = 0;
  351. switch(stat) {
  352. case STAT_ATK:
  353. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->atk;
  354. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->atk;
  355. break;
  356. case STAT_DEF:
  357. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->def;
  358. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->def;
  359. break;
  360. case STAT_SPD:
  361. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->spd;
  362. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->spd;
  363. break;
  364. case STAT_SPC:
  365. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->spc;
  366. break;
  367. case STAT_SPC_ATK:
  368. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->spc_atk;
  369. break;
  370. case STAT_SPC_DEF:
  371. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->spc_def;
  372. break;
  373. case STAT_HP:
  374. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->hp;
  375. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->hp;
  376. break;
  377. case STAT_ATK_EV:
  378. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->atk_ev;
  379. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->atk_ev;
  380. break;
  381. case STAT_DEF_EV:
  382. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->def_ev;
  383. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->def_ev;
  384. break;
  385. case STAT_SPD_EV:
  386. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->spd_ev;
  387. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->spd_ev;
  388. break;
  389. case STAT_SPC_EV:
  390. case STAT_SPC_ATK_EV:
  391. case STAT_SPC_DEF_EV:
  392. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->spc_ev;
  393. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->spc_ev;
  394. break;
  395. case STAT_HP_EV:
  396. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->hp_ev;
  397. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->hp_ev;
  398. break;
  399. case STAT_IV:
  400. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->iv;
  401. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->iv;
  402. break;
  403. /* The IVs in GB byte order, are always:
  404. * atk, def, spd, spc
  405. * Like every other 16 bit quantity that the Flipper acts on, we need to
  406. * bytw swap them normally. However, the below accessors for individual
  407. * IV nibbles directly pull from the data structures which will always
  408. * be in GB endianness.
  409. */
  410. case STAT_SPD_IV:
  411. if(gen == GEN_I) return (((PokemonPartyGenI*)party)->iv >> 12) & 0x0F;
  412. if(gen == GEN_II) return (((PokemonPartyGenII*)party)->iv >> 12) & 0x0F;
  413. break;
  414. /* In order to line up all of the dynamic stat accessors used as part of the
  415. * stat calculation loop, we need to overload the SPC IV accessor to allow
  416. * accessing SPC, SPC_ATK, and SPC_DEF. Note that only SPC exists, the ATK
  417. * and DEF are the overloaded values. This is so when, for example, gen i
  418. * calculates its SPC value, or gen ii calculates is SPC_DEF value, it will
  419. * always grab the same IV nibble.
  420. */
  421. case STAT_SPC_IV:
  422. case STAT_SPC_ATK_IV:
  423. case STAT_SPC_DEF_IV:
  424. if(gen == GEN_I) return (((PokemonPartyGenI*)party)->iv >> 8) & 0x0F;
  425. if(gen == GEN_II) return (((PokemonPartyGenII*)party)->iv >> 8) & 0x0F;
  426. break;
  427. case STAT_ATK_IV:
  428. if(gen == GEN_I) return (((PokemonPartyGenI*)party)->iv >> 4) & 0x0F;
  429. if(gen == GEN_II) return (((PokemonPartyGenII*)party)->iv >> 4) & 0x0F;
  430. break;
  431. case STAT_DEF_IV:
  432. if(gen == GEN_I) return ((PokemonPartyGenI*)party)->iv & 0x0F;
  433. if(gen == GEN_II) return ((PokemonPartyGenII*)party)->iv & 0x0F;
  434. break;
  435. case STAT_HP_IV:
  436. /* NOTE:
  437. * HP IV is calculated as the LSB of each other IV, assembled in the
  438. * same bit order down to a single nibble.
  439. */
  440. if(gen == GEN_I) val = (((PokemonPartyGenI*)party)->iv);
  441. if(gen == GEN_II) val = (((PokemonPartyGenII*)party)->iv);
  442. /* NOTE:
  443. * As noted above, we store the IV in the trade struct in the byte order
  444. * of the gameboy which is swapped from the Flipper's byte order.
  445. */
  446. hp_iv |= ((val & 0x0010) >> 1); // ATK IV, MSbit of the hp_iv nibble
  447. hp_iv |= ((val & 0x0001) << 2); // DEF IV, right of ATK IV in hp_iv nibble
  448. hp_iv |= ((val & 0x1000) >> 11); // SPD IV, right of DEF IV in hp_iv nibble
  449. hp_iv |= ((val & 0x0100) >> 8); // SPC IV, right of SPD IV in hp_iv nibble
  450. return hp_iv;
  451. break;
  452. case STAT_LEVEL:
  453. if(gen == GEN_I) return ((PokemonPartyGenI*)party)->level;
  454. if(gen == GEN_II) return ((PokemonPartyGenII*)party)->level;
  455. break;
  456. case STAT_INDEX:
  457. if(gen == GEN_I) return ((PokemonPartyGenI*)party)->index;
  458. if(gen == GEN_II) return ((PokemonPartyGenII*)party)->index - 1;
  459. break;
  460. /* In Gen I, index is not relative at all to dex num.
  461. * In Gen II, index is the same as the dex num.
  462. */
  463. case STAT_NUM:
  464. if(gen == GEN_I) {
  465. val = ((PokemonPartyGenI*)party)->index;
  466. return table_pokemon_pos_get(pdata->pokemon_table, val);
  467. }
  468. if(gen == GEN_II) return ((PokemonPartyGenII*)party)->index - 1;
  469. break;
  470. case STAT_MOVE:
  471. if(gen == GEN_I) return ((PokemonPartyGenI*)party)->move[which];
  472. if(gen == GEN_II) return ((PokemonPartyGenII*)party)->move[which];
  473. break;
  474. case STAT_TYPE:
  475. if(gen == GEN_I) return ((PokemonPartyGenI*)party)->type[which];
  476. break;
  477. case STAT_OT_ID:
  478. if(gen == GEN_I) val = ((PokemonPartyGenI*)party)->ot_id;
  479. if(gen == GEN_II) val = ((PokemonPartyGenII*)party)->ot_id;
  480. break;
  481. case STAT_POKERUS:
  482. if(gen == GEN_II) return ((PokemonPartyGenII*)party)->pokerus;
  483. break;
  484. case STAT_SEL:
  485. if(gen == GEN_I) return pdata->stat_sel;
  486. if(gen == GEN_II) return pdata->stat_sel;
  487. break;
  488. case STAT_CONDITION:
  489. if(gen == GEN_I) return ((PokemonPartyGenI*)party)->status_condition = val;
  490. if(gen == GEN_II) return ((PokemonPartyGenII*)party)->status_condition = val;
  491. break;
  492. case STAT_HELD_ITEM:
  493. if(gen == GEN_II) return ((PokemonPartyGenII*)party)->held_item;
  494. break;
  495. default:
  496. furi_crash("STAT_GET: invalid stat");
  497. break;
  498. }
  499. return __builtin_bswap16(val);
  500. }
  501. void pokemon_stat_set(PokemonData* pdata, DataStat stat, DataStatSub which, uint16_t val) {
  502. furi_assert(pdata);
  503. void* party = pdata->party;
  504. int gen = pdata->gen;
  505. uint8_t recalc = 0;
  506. uint16_t val_swap = __builtin_bswap16(val);
  507. switch(stat) {
  508. case STAT_ATK:
  509. if(gen == GEN_I) ((PokemonPartyGenI*)party)->atk = val_swap;
  510. if(gen == GEN_II) ((PokemonPartyGenII*)party)->atk = val_swap;
  511. break;
  512. case STAT_DEF:
  513. if(gen == GEN_I) ((PokemonPartyGenI*)party)->def = val_swap;
  514. if(gen == GEN_II) ((PokemonPartyGenII*)party)->def = val_swap;
  515. break;
  516. case STAT_SPD:
  517. if(gen == GEN_I) ((PokemonPartyGenI*)party)->spd = val_swap;
  518. if(gen == GEN_II) ((PokemonPartyGenII*)party)->spd = val_swap;
  519. break;
  520. case STAT_SPC:
  521. if(gen == GEN_I) ((PokemonPartyGenI*)party)->spc = val_swap;
  522. break;
  523. case STAT_SPC_ATK:
  524. if(gen == GEN_II) ((PokemonPartyGenII*)party)->spc_atk = val_swap;
  525. break;
  526. case STAT_SPC_DEF:
  527. if(gen == GEN_II) ((PokemonPartyGenII*)party)->spc_def = val_swap;
  528. break;
  529. case STAT_HP:
  530. if(gen == GEN_I) {
  531. ((PokemonPartyGenI*)party)->hp = val_swap;
  532. ((PokemonPartyGenI*)party)->max_hp = val_swap;
  533. }
  534. if(gen == GEN_II) {
  535. ((PokemonPartyGenII*)party)->hp = val_swap;
  536. ((PokemonPartyGenII*)party)->max_hp = val_swap;
  537. }
  538. break;
  539. case STAT_ATK_EV:
  540. if(gen == GEN_I) ((PokemonPartyGenI*)party)->atk_ev = val_swap;
  541. if(gen == GEN_II) ((PokemonPartyGenII*)party)->atk_ev = val_swap;
  542. break;
  543. case STAT_DEF_EV:
  544. if(gen == GEN_I) ((PokemonPartyGenI*)party)->def_ev = val_swap;
  545. if(gen == GEN_II) ((PokemonPartyGenII*)party)->def_ev = val_swap;
  546. break;
  547. case STAT_SPD_EV:
  548. if(gen == GEN_I) ((PokemonPartyGenI*)party)->spd_ev = val_swap;
  549. if(gen == GEN_II) ((PokemonPartyGenII*)party)->spd_ev = val_swap;
  550. break;
  551. /* The SPC ATK/DEF EVs are not real values, we just pretend they are */
  552. case STAT_SPC_EV:
  553. case STAT_SPC_ATK_EV:
  554. case STAT_SPC_DEF_EV:
  555. if(gen == GEN_I) ((PokemonPartyGenI*)party)->spc_ev = val_swap;
  556. if(gen == GEN_II) ((PokemonPartyGenII*)party)->spc_ev = val_swap;
  557. break;
  558. case STAT_HP_EV:
  559. if(gen == GEN_I) ((PokemonPartyGenI*)party)->hp_ev = val_swap;
  560. if(gen == GEN_II) ((PokemonPartyGenII*)party)->hp_ev = val_swap;
  561. break;
  562. case STAT_IV:
  563. if(gen == GEN_I) ((PokemonPartyGenI*)party)->iv = val_swap;
  564. if(gen == GEN_II) ((PokemonPartyGenII*)party)->iv = val_swap;
  565. break;
  566. /* The IVs in GB byte order, are always:
  567. * atk, def, spd, spc
  568. * Like every other 16 bit quantity that the Flipper acts on, we need to
  569. * bytw swap them normally. However, the below accessors for individual
  570. * IV nibbles directly manipulate the data structures which will always
  571. * be in GB endianness.
  572. */
  573. case STAT_SPD_IV:
  574. if(gen == GEN_I) {
  575. ((PokemonPartyGenI*)party)->iv &= ~(0x0F << 12);
  576. ((PokemonPartyGenI*)party)->iv |= ((val & 0x0F) << 12);
  577. }
  578. if(gen == GEN_II) {
  579. ((PokemonPartyGenII*)party)->iv &= ~(0x0F << 12);
  580. ((PokemonPartyGenII*)party)->iv |= ((val & 0x0F) << 12);
  581. }
  582. break;
  583. /* In order to line up all of the dynamic stat accessors used as part of the
  584. * stat calculation loop, we need to overload the SPC IV accessor to allow
  585. * accessing SPC, SPC_ATK, and SPC_DEF. Note that only SPC exists, the ATK
  586. * and DEF are the overloaded values. This is so when, for example, gen i
  587. * calculates its SPC value, or gen ii calculates is SPC_DEF value, it will
  588. * always grab the same IV nibble.
  589. */
  590. case STAT_SPC_IV:
  591. case STAT_SPC_ATK_IV:
  592. case STAT_SPC_DEF_IV:
  593. if(gen == GEN_I) {
  594. ((PokemonPartyGenI*)party)->iv &= ~(0x0F << 8);
  595. ((PokemonPartyGenI*)party)->iv |= ((val & 0x0F) << 8);
  596. }
  597. if(gen == GEN_II) {
  598. ((PokemonPartyGenII*)party)->iv &= ~(0x0F << 8);
  599. ((PokemonPartyGenII*)party)->iv |= ((val & 0x0F) << 8);
  600. }
  601. break;
  602. case STAT_ATK_IV:
  603. if(gen == GEN_I) {
  604. ((PokemonPartyGenI*)party)->iv &= ~(0x0F << 4);
  605. ((PokemonPartyGenI*)party)->iv |= ((val & 0x0F) << 4);
  606. }
  607. if(gen == GEN_II) {
  608. ((PokemonPartyGenII*)party)->iv &= ~(0x0F << 4);
  609. ((PokemonPartyGenII*)party)->iv |= ((val & 0x0F) << 4);
  610. }
  611. break;
  612. case STAT_DEF_IV:
  613. if(gen == GEN_I) {
  614. ((PokemonPartyGenI*)party)->iv &= ~(0x0F);
  615. ((PokemonPartyGenI*)party)->iv |= (val & 0x0F);
  616. }
  617. if(gen == GEN_II) {
  618. ((PokemonPartyGenII*)party)->iv &= ~(0x0F);
  619. ((PokemonPartyGenII*)party)->iv |= (val & 0x0F);
  620. }
  621. break;
  622. case STAT_MOVE:
  623. if(gen == GEN_I) ((PokemonPartyGenI*)party)->move[which] = val;
  624. if(gen == GEN_II) ((PokemonPartyGenII*)party)->move[which] = val;
  625. break;
  626. case STAT_TYPE:
  627. /* Gen II doesn't have type assignment */
  628. if(gen == GEN_I) ((PokemonPartyGenI*)party)->type[which] = val;
  629. break;
  630. case STAT_LEVEL:
  631. if(gen == GEN_I) {
  632. ((PokemonPartyGenI*)party)->level = val;
  633. ((PokemonPartyGenI*)party)->level_again = val;
  634. }
  635. if(gen == GEN_II) ((PokemonPartyGenII*)party)->level = val;
  636. recalc = (RECALC_STATS | RECALC_EXP | RECALC_EVS);
  637. break;
  638. /* In Gen I, index is not relative at all to dex num.
  639. * In Gen II, index is the same as the dex num.
  640. */
  641. case STAT_INDEX:
  642. if(gen == GEN_I) {
  643. ((PokemonPartyGenI*)party)->index = val;
  644. ((TradeBlockGenI*)pdata->trade_block)->party_members[0] = val;
  645. }
  646. if(gen == GEN_II) {
  647. ((PokemonPartyGenII*)party)->index = val + 1;
  648. ((TradeBlockGenII*)pdata->trade_block)->party_members[0] = val + 1;
  649. }
  650. recalc = RECALC_ALL; // Always recalculate everything if we selected a different pokemon
  651. break;
  652. case STAT_NUM:
  653. if(gen == GEN_I)
  654. pokemon_stat_set(
  655. pdata,
  656. STAT_INDEX,
  657. NONE,
  658. table_stat_base_get(pdata->pokemon_table, val, STAT_BASE_INDEX, NONE));
  659. if(gen == GEN_II) pokemon_stat_set(pdata, STAT_INDEX, NONE, val);
  660. break;
  661. case STAT_OT_ID:
  662. if(gen == GEN_I) ((PokemonPartyGenI*)party)->ot_id = val_swap;
  663. if(gen == GEN_II) ((PokemonPartyGenII*)party)->ot_id = val_swap;
  664. break;
  665. case STAT_POKERUS:
  666. if(gen == GEN_II) ((PokemonPartyGenII*)party)->pokerus = val;
  667. break;
  668. case STAT_SEL:
  669. pdata->stat_sel = val;
  670. recalc = (RECALC_EVS | RECALC_IVS | RECALC_STATS);
  671. break;
  672. case STAT_EXP:
  673. if(gen == GEN_I) ((PokemonPartyGenI*)party)->exp[which] = val;
  674. if(gen == GEN_II) ((PokemonPartyGenII*)party)->exp[which] = val;
  675. break;
  676. case STAT_CONDITION:
  677. if(gen == GEN_I) ((PokemonPartyGenI*)party)->status_condition = val;
  678. if(gen == GEN_II) ((PokemonPartyGenII*)party)->status_condition = val;
  679. break;
  680. case STAT_HELD_ITEM:
  681. if(gen == GEN_II) ((PokemonPartyGenII*)party)->held_item = val;
  682. break;
  683. default:
  684. furi_crash("STAT_SET: invalid stat");
  685. break;
  686. }
  687. FURI_LOG_D(TAG, "[data] stat %s:%d set to 0x%X", stat_text_get(stat), which, val);
  688. pokemon_recalculate(pdata, recalc);
  689. }
  690. static void pokemon_stat_ev_calc(PokemonData* pdata, EvIv val) {
  691. furi_assert(pdata);
  692. int level;
  693. uint16_t ev;
  694. DataStat i;
  695. level = pokemon_stat_get(pdata, STAT_LEVEL, NONE);
  696. /* Generate STATEXP */
  697. switch(val) {
  698. case RANDIV_LEVELEV:
  699. case MAXIV_LEVELEV:
  700. ev = (0xffff / 100) * level;
  701. break;
  702. case RANDIV_MAXEV:
  703. case MAXIV_MAXEV:
  704. ev = 0xffff;
  705. break;
  706. default:
  707. ev = 0;
  708. break;
  709. }
  710. for(i = STAT_EV; i < STAT_EV_END; i++) {
  711. pokemon_stat_set(pdata, i, NONE, ev);
  712. }
  713. }
  714. static void pokemon_stat_iv_calc(PokemonData* pdata, EvIv val) {
  715. furi_assert(pdata);
  716. uint16_t iv;
  717. /* Set up IVs */
  718. switch(val) {
  719. case RANDIV_ZEROEV:
  720. case RANDIV_LEVELEV:
  721. case RANDIV_MAXEV:
  722. iv = (uint16_t)rand();
  723. break;
  724. default:
  725. iv = 0xFFFF;
  726. break;
  727. }
  728. pokemon_stat_set(pdata, STAT_IV, NONE, iv);
  729. }
  730. #define UINT32_TO_EXP(input, output_array) \
  731. do { \
  732. (output_array)[2] = (uint8_t)((input) & 0xFF); \
  733. (output_array)[1] = (uint8_t)(((input) >> 8) & 0xFF); \
  734. (output_array)[0] = (uint8_t)(((input) >> 16) & 0xFF); \
  735. } while(0)
  736. void pokemon_exp_set(PokemonData* pdata, uint32_t exp) {
  737. furi_assert(pdata);
  738. uint8_t exp_tmp[3];
  739. int i;
  740. UINT32_TO_EXP(exp, exp_tmp);
  741. for(i = EXP_0; i <= EXP_2; i++) {
  742. pokemon_stat_set(pdata, STAT_EXP, i, exp_tmp[i]);
  743. }
  744. FURI_LOG_D(TAG, "[data] Set pkmn exp %d", (int)exp);
  745. }
  746. void pokemon_exp_calc(PokemonData* pdata) {
  747. furi_assert(pdata);
  748. int level;
  749. uint32_t exp;
  750. uint8_t growth = table_stat_base_get(
  751. pdata->pokemon_table, pokemon_stat_get(pdata, STAT_NUM, NONE), STAT_BASE_GROWTH, NONE);
  752. level = (int)pokemon_stat_get(pdata, STAT_LEVEL, NONE);
  753. /* Calculate exp */
  754. switch(growth) {
  755. case GROWTH_FAST:
  756. // https://bulbapedia.bulbagarden.net/wiki/Experience#Fast
  757. exp = (4 * level * level * level) / 5;
  758. break;
  759. case GROWTH_MEDIUM_FAST:
  760. // https://bulbapedia.bulbagarden.net/wiki/Experience#Medium_Fast
  761. exp = (level * level * level);
  762. break;
  763. case GROWTH_MEDIUM_SLOW:
  764. // https://bulbapedia.bulbagarden.net/wiki/Experience#Medium_Slow
  765. exp = (((level * level * level) * 6 / 5) - (15 * level * level) + (100 * level) - 140);
  766. break;
  767. case GROWTH_SLOW:
  768. // https://bulbapedia.bulbagarden.net/wiki/Experience#Slow
  769. exp = (5 * level * level * level) / 4;
  770. break;
  771. default:
  772. furi_crash("incorrect growth val");
  773. break;
  774. }
  775. pokemon_exp_set(pdata, exp);
  776. }
  777. /* Calculates stat from current level */
  778. void pokemon_stat_calc(PokemonData* pdata, DataStat stat) {
  779. furi_assert(pdata);
  780. uint8_t iv;
  781. uint16_t ev;
  782. uint8_t base;
  783. uint8_t level;
  784. uint16_t calc;
  785. level = pokemon_stat_get(pdata, STAT_LEVEL, NONE);
  786. base = table_stat_base_get(
  787. pdata->pokemon_table, pokemon_stat_get(pdata, STAT_NUM, NONE), stat, NONE);
  788. ev = pokemon_stat_get(pdata, stat + STAT_EV_OFFS, NONE);
  789. iv = pokemon_stat_get(pdata, stat + STAT_IV_OFFS, NONE);
  790. /* Gen I and II calculation */
  791. // https://bulbapedia.bulbagarden.net/wiki/Stat#Generations_I_and_II
  792. calc = floor((((2 * (base + iv)) + floor(sqrt(ev) / 4)) * level) / 100);
  793. if(stat == STAT_HP)
  794. calc += (level + 10);
  795. else
  796. calc += 5;
  797. pokemon_stat_set(pdata, stat, NONE, calc);
  798. }
  799. /* Copy the traded-in Pokemon's main data to our struct */
  800. void pokemon_stat_memcpy(PokemonData* dst, PokemonData* src, uint8_t which) {
  801. if(dst->gen == GEN_I) {
  802. ((TradeBlockGenI*)dst->trade_block)->party_members[0] =
  803. ((TradeBlockGenI*)src->trade_block)->party_members[which];
  804. memcpy(
  805. &(((TradeBlockGenI*)dst->trade_block)->party[0]),
  806. &(((TradeBlockGenI*)src->trade_block)->party[which]),
  807. sizeof(PokemonPartyGenI));
  808. memcpy(
  809. &(((TradeBlockGenI*)dst->trade_block)->nickname[0]),
  810. &(((TradeBlockGenI*)src->trade_block)->nickname[which]),
  811. sizeof(struct name));
  812. memcpy(
  813. &(((TradeBlockGenI*)dst->trade_block)->ot_name[0]),
  814. &(((TradeBlockGenI*)src->trade_block)->ot_name[which]),
  815. sizeof(struct name));
  816. } else if(dst->gen == GEN_II) {
  817. ((TradeBlockGenI*)dst->trade_block)->party_members[0] =
  818. ((TradeBlockGenI*)src->trade_block)->party_members[which];
  819. memcpy(
  820. &(((TradeBlockGenII*)dst->trade_block)->party[0]),
  821. &(((TradeBlockGenII*)src->trade_block)->party[which]),
  822. sizeof(PokemonPartyGenI));
  823. memcpy(
  824. &(((TradeBlockGenII*)dst->trade_block)->nickname[0]),
  825. &(((TradeBlockGenII*)src->trade_block)->nickname[which]),
  826. sizeof(struct name));
  827. memcpy(
  828. &(((TradeBlockGenII*)dst->trade_block)->ot_name[0]),
  829. &(((TradeBlockGenII*)src->trade_block)->ot_name[which]),
  830. sizeof(struct name));
  831. }
  832. }