pokemon_data.c 31 KB

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