Nenhuma descrição

trainerbattle_init.c 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include <pokeagb/pokeagb.h>
  2. #include <agb_debug.h>
  3. #include <trainer_rival_encounters.h>
  4. #include <pymap_constants.h>
  5. void battle_intro_launch(u8 environment) {
  6. TaskCallback introTask;
  7. if (battle_type_flags & BATTLE_FLAG_LINK) {
  8. introTask = (TaskCallback)(0x080BCC4C | 1);
  9. } else if (battle_type_flags & 0x1000 && build_edition_identifier != 2) {
  10. introTask = (TaskCallback)(0x080BC6C8 | 1);
  11. } else {
  12. introTask = task00_battle_intro_by_env[environment];
  13. }
  14. struct Task *livingTask = &tasks[task_add(introTask, 0)];
  15. for (u8 i = 0; i <= 6; ++i)
  16. livingTask->priv[i] = 0;
  17. livingTask->priv[1] = environment;
  18. }
  19. union TrainerPokemonPtr battle_trainer_get_rival(u8 chosenStarterValue, u8 encounterNumber, enum TrainerPartyFlag flag) {
  20. u8 partyCount = rival_encounters[encounterNumber].partyCount;
  21. u8 structureSize = 0;
  22. switch(flag)
  23. {
  24. case TRAINER_PARTY_NONE:
  25. structureSize = sizeof(struct TrainerPokemonBase);
  26. break;
  27. case TRAINER_PARTY_HELD_ITEM:
  28. structureSize = sizeof(struct TrainerPokemonItem);
  29. break;
  30. case TRAINER_PARTY_MOVESET:
  31. structureSize = sizeof(struct TrainerPokemonMoves);
  32. break;
  33. case TRAINER_PARTY_HELD_ITEM_MOVESET:
  34. structureSize = sizeof(struct TrainerPokemonItemMoves);
  35. break;
  36. default:
  37. structureSize = sizeof(struct TrainerPokemonBase);
  38. break;
  39. }
  40. return (union TrainerPokemonPtr)(rival_encounters[encounterNumber].partyArray.undefinedStructure + (chosenStarterValue * partyCount * structureSize));
  41. }
  42. union TrainerPokemonPtr battle_trainer_get_rival_or_null(u8 tid) {
  43. for(u16 i = 0; i < RIVAL_ENCOUNTER_COUNT; ++i) {
  44. if(rival_encounters[i].trainerId == tid) {
  45. return battle_trainer_get_rival(var_load(VAR_STARTER_PLAYER_POKEMON), i, trainer_data[tid].flags);
  46. }
  47. }
  48. union TrainerPokemonPtr nullPokemon = {.undefinedStructure = NULL};
  49. return nullPokemon;
  50. }
  51. u8 battle_trainer_build_party(struct Pokemon *party, u16 tid) {
  52. if(tid == 0x400)
  53. return 0;
  54. //ignore some type of battles like old man or trainer tower where the party is determined otherwise
  55. dprintf("battle_type_flags: %x, tid: %d\n", battle_type_flags, tid);
  56. if ((battle_type_flags & 0x80908) == 8) {
  57. party_opponent_purge();
  58. for(u8 i = 0; i < trainer_data[tid].party_size; ++i) {
  59. u32 personalityValue;
  60. if(trainer_data[tid].is_double)
  61. personalityValue = 0x80;
  62. else if (trainer_data[tid].gender & 0x80)
  63. personalityValue = 0x78;
  64. else
  65. personalityValue = 0x88;
  66. u32 nameHash = 0;
  67. for(u8 j = 0; trainer_data[tid].name[j] != 0xFF; ++j){
  68. nameHash += trainer_data[tid].name[j];
  69. }
  70. //has custom items etc
  71. switch(trainer_data[tid].flags)
  72. {
  73. case TRAINER_PARTY_NONE:
  74. {
  75. //nothing
  76. const struct TrainerPokemonBase *pokeData = battle_trainer_get_rival_or_null(tid).noItemDefaultMoves;
  77. if(pokeData == NULL)
  78. pokeData = trainer_data[tid].party.noItemDefaultMoves;
  79. dprintf("making pokemon with species: %d, struct: 0x%x\n", pokeData[i].species, pokeData);
  80. for(u8 j = 0; pokemon_names[pokeData[i].species][j] != 0xFF; ++j) {
  81. nameHash += pokemon_names[pokeData[i].species][j];
  82. }
  83. personalityValue += nameHash << 8;
  84. u8 iv = pokeData[i].iv * 31 / 255;
  85. //no idea about the last 2 parameters, just do what the game does I guess
  86. pokemon_make_full(&party[i], pokeData[i].species, pokeData[i].level, iv, true, personalityValue, 2, 0);
  87. break;
  88. }
  89. case TRAINER_PARTY_MOVESET:
  90. {
  91. const struct TrainerPokemonMoves *pokeData = battle_trainer_get_rival_or_null(tid).noItemCustomMoves;
  92. if(pokeData == NULL)
  93. pokeData = trainer_data[tid].party.noItemCustomMoves;
  94. dprintf("making pokemon with species: %d\n", pokeData[i].species);
  95. //custom moveset
  96. for(u8 j = 0; pokemon_names[pokeData[i].species][j] != 0xFF; ++j)
  97. nameHash += pokemon_names[pokeData[i].species][j];
  98. personalityValue += nameHash << 8;
  99. u8 iv = pokeData[i].iv * 31 / 255;
  100. pokemon_make_full(&party[i], pokeData[i].species, pokeData[i].level, iv, true, personalityValue, 2, 0);
  101. for(u8 j = 0; j < 4; ++j) {
  102. pokemon_setattr(&party[i], REQUEST_MOVE1 + j, (void*)&pokeData[i].moves[j]);
  103. pokemon_setattr(&party[i], REQUEST_PP1 + j, (void*)&pokemon_moves[pokeData[i].moves[j]].pp);
  104. }
  105. break;
  106. }
  107. case TRAINER_PARTY_HELD_ITEM:
  108. {
  109. //custom item
  110. const struct TrainerPokemonItem *pokeData = battle_trainer_get_rival_or_null(tid).itemDefaultMoves;
  111. if(pokeData == NULL)
  112. pokeData = trainer_data[tid].party.itemDefaultMoves;
  113. dprintf("making pokemon with species: %d\n", pokeData[i].species);
  114. for(u8 j = 0; pokemon_names[pokeData[i].species][j] != 0xFF; ++j)
  115. nameHash += pokemon_names[pokeData[i].species][j];
  116. personalityValue += nameHash << 8;
  117. u8 iv = pokeData[i].iv * 31 / 255;
  118. pokemon_make_full(&party[i], pokeData[i].species, pokeData[i].level, iv, true, personalityValue, 2, 0);
  119. pokemon_setattr(&party[i], REQUEST_HELD_ITEM, (void*)&pokeData[i].Item);
  120. break;
  121. }
  122. case TRAINER_PARTY_HELD_ITEM | TRAINER_PARTY_MOVESET:
  123. {
  124. //custom all the things
  125. const struct TrainerPokemonItemMoves *pokeData = battle_trainer_get_rival_or_null(tid).customItemCustomMoves;
  126. if(pokeData == NULL)
  127. pokeData = trainer_data[tid].party.customItemCustomMoves;
  128. dprintf("making pokemon with species: %d\n", pokeData[i].species);
  129. for(u8 j = 0; pokemon_names[pokeData[i].species][j] != 0xFF; ++j)
  130. nameHash += pokemon_names[pokeData[i].species][j];
  131. personalityValue += nameHash << 8;
  132. u8 iv = pokeData[i].iv * 31 / 255;
  133. pokemon_make_full(&party[i], pokeData[i].species, pokeData[i].level, iv, true, personalityValue, 2, 0);
  134. pokemon_setattr(&party[i], REQUEST_HELD_ITEM, (void*)&pokeData[i].Item);
  135. for(u8 j = 0; j < 4; ++j) {
  136. pokemon_setattr(&party[i], REQUEST_MOVE1 + j, (void*)&pokeData[i].moves[j]);
  137. pokemon_setattr(&party[i], REQUEST_PP1 + j, (void*)&pokemon_moves[pokeData[i].moves[j]].pp);
  138. }
  139. break;
  140. }
  141. }
  142. }
  143. battle_type_flags |= trainer_data[tid].is_double;
  144. }
  145. (void) party;
  146. return trainer_data[tid].party_size;
  147. }