설명 없음

battle_help.c 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /****************************************************************************
  2. * Copyright (C) 2015-2016 by the SotS Team *
  3. * *
  4. * This file is part of Sovereign of the Skies. *
  5. * *
  6. * Sovereign of the Skies is free software: you can redistribute it *
  7. * and/or modify it *
  8. * under the terms of the GNU Lesser General Public License as published *
  9. * by the Free Software Foundation, either version 3 of the License, or *
  10. * (at your option) any later version provided you include a copy of the *
  11. * licence and this header. *
  12. * *
  13. * Sovereign of the Skies is distributed in the hope that it will be *
  14. * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU Lesser General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU Lesser General Public *
  19. * License along with Sovereign of the Skies. *
  20. * If not, see <http://www.gnu.org/licenses/>. *
  21. ****************************************************************************/
  22. /**
  23. * @file battle_help.c
  24. * @author Sturmvogel
  25. * @date 15 dec 2016
  26. * @brief Some general helper methods for battle
  27. */
  28. /* === INCLUDE === */
  29. #include <battle_help.h>
  30. #include <battle_locations.h>
  31. #include <battle_custom_structs.h>
  32. #include <game_engine.h>
  33. #include <pkmn_types.h>
  34. #include <pkmn_abilities.h>
  35. #include <pkmn_item_effects.h>
  36. #include <pkmn_items.h>
  37. #include <pkmn_attributes.h>
  38. #include <battle_common.h>
  39. /* === STATICS === */
  40. /* from kds emerald battle engine upgrade */
  41. u8 type_effectiveness_table[TYPE_FAIRY - 0x4][TYPE_FAIRY - 0x4] = {
  42. {10, 10, 10, 10, 10, 05, 10, 00, 05, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, //normal
  43. {20, 10, 05, 05, 10, 20, 05, 00, 20, 10, 10, 10, 10, 10, 05, 20, 10, 20, 05}, //fight
  44. {10, 20, 10, 10, 10, 05, 20, 10, 05, 10, 10, 10, 20, 05, 10, 10, 10, 10, 10}, //flying
  45. {10, 10, 10, 05, 05, 05, 10, 05, 00, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20}, //poison
  46. {10, 10, 00, 20, 10, 20, 05, 10, 20, 10, 20, 10, 05, 20, 10, 10, 10, 10, 10}, //ground
  47. {10, 05, 20, 10, 05, 10, 20, 10, 05, 10, 20, 10, 10, 10, 10, 20, 10, 10, 10}, //rock
  48. {10, 05, 05, 05, 10, 10, 10, 05, 05, 10, 05, 10, 20, 10, 20, 10, 10, 20, 05}, //bug
  49. {00, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 20, 10, 10, 05, 10}, //ghost
  50. {10, 10, 10, 10, 10, 20, 10, 10, 05, 10, 05, 05, 10, 05, 10, 20, 10, 10, 20}, //steel
  51. {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, //egg
  52. {10, 10, 10, 10, 10, 05, 20, 10, 20, 10, 05, 05, 20, 10, 10, 20, 05, 10, 10}, //fire
  53. {10, 10, 10, 10, 20, 20, 10, 10, 10, 10, 20, 05, 05, 10, 10, 10, 05, 10, 10}, //water
  54. {10, 10, 05, 05, 20, 20, 05, 10, 05, 10, 05, 20, 05, 10, 10, 10, 05, 10, 10}, //grass
  55. {10, 10, 20, 10, 00, 10, 10, 10, 10, 10, 10, 20, 05, 05, 10, 10, 05, 10, 10}, //electric
  56. {10, 20, 10, 20, 10, 10, 10, 10, 05, 10, 10, 10, 10, 10, 05, 10, 10, 00, 10}, //psychic
  57. {10, 10, 20, 10, 20, 10, 10, 10, 05, 10, 05, 05, 20, 10, 10, 05, 20, 10, 10}, //ice
  58. {10, 10, 10, 10, 10, 10, 10, 10, 05, 10, 10, 10, 10, 10, 10, 10, 20, 10, 00}, //dragon
  59. {10, 05, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 20, 10, 10, 05, 05}, //dark
  60. {10, 20, 10, 05, 10, 10, 10, 10, 05, 10, 05, 10, 10, 10, 10, 10, 20, 20, 10} //fairy
  61. };
  62. /* === IMPLEMENTATIONS === */
  63. u16 battle_damage_type_effectiveness_update(u8 attacking_type, u8 defending_type, u8 atk_bank, u8 def_bank, u16 chained_effect, u8 airstatus) {
  64. u8 effect, atype = attacking_type, dtype = defending_type;
  65. if (!chained_effect || atype == TYPE_EGG || dtype == TYPE_EGG)
  66. return chained_effect;
  67. if (atype >= TYPE_FAIRY)
  68. atype = atype - 5;
  69. if (dtype >= TYPE_FAIRY)
  70. dtype = dtype - 5;
  71. effect = type_effectiveness_table[atype][dtype];
  72. if (custom_battle_elements.ptr->various.inverse_battle) {
  73. if (effect == 20) {
  74. effect = 5;
  75. } else if (effect == 5 || effect == 0) {
  76. effect = 20;
  77. }
  78. }
  79. /* handle normal / fighting on ghost */
  80. if ((((attacking_type == TYPE_NORMAL || attacking_type == TYPE_FIGHTING) && defending_type == TYPE_GHOST && ((battle_participants[def_bank].status2.foresight))) || battle_participants[atk_bank].ability_id == ABILITY_SCRAPPY) && effect == 0) {
  81. effect = 10;
  82. }
  83. /* handle other effectiveness changers here */
  84. switch (effect) {
  85. case 0:
  86. chained_effect = 0;
  87. break;
  88. case 5:
  89. chained_effect = chained_effect >> 1;
  90. break;
  91. case 20:
  92. chained_effect = chained_effect << 1;
  93. break;
  94. }
  95. return chained_effect;
  96. }
  97. u16 battle_apply_type_effectiveness(u16 chained_effect, u8 move_type, u8 target_bank, u8 atk_bank, u8 airstatus) {
  98. u8 defender_type1 = battle_participants[target_bank].type1;
  99. u8 defender_type2 = battle_participants[target_bank].type2;
  100. /* set different types */
  101. if (defender_type2 == defender_type1)
  102. defender_type2 = TYPE_EGG;
  103. chained_effect = battle_damage_type_effectiveness_update(move_type, defender_type1, atk_bank, target_bank, chained_effect, airstatus);
  104. chained_effect = battle_damage_type_effectiveness_update(move_type, defender_type2, atk_bank, target_bank, chained_effect, airstatus);
  105. return chained_effect;
  106. }
  107. u16 battle_type_effectiveness_calc(u16 move, u8 move_type, u8 atk_bank, u8 def_bank, u8 effects_handling_and_recording) {
  108. u16 chained_effect = 64;
  109. //TODO: double_type moves
  110. //TODO: get air status
  111. chained_effect = battle_apply_type_effectiveness(chained_effect, move_type, def_bank, atk_bank, 2);
  112. //TODO: save into structs
  113. //TODO: effect_handling_and_recording
  114. return chained_effect;
  115. }
  116. u8 battle_bank_has_type(u8 bank, u8 type) {
  117. return battle_participants[bank].type1 == type || battle_participants[bank].type2 == type;
  118. }
  119. u8 battle_item_get_effect(u8 bank, u8 check_negating_effects) {
  120. if (check_negating_effects) {
  121. if (battle_participants[bank].ability_id == ABILITY_KLUTZ || custom_battle_elements.ptr->bank_affecting[bank].embargo)
  122. return ITEM_EFFECT_NOEFFECT;
  123. }
  124. if (battle_participants[bank].held_item == ITEM_ENIGMABERRY) {
  125. return battle_enigma_berry[bank].battle_effect_x12;
  126. } else {
  127. return item_get_x12(battle_participants[bank].held_item);
  128. }
  129. }
  130. u8 battle_bank_is_poison_resistant(u8 bank, u8 self_inflicted) { //0 == can poison
  131. //1 == is already poisoned
  132. //2 == has other major condition
  133. //3 == type doesn't allow it
  134. //4 == ability doesn't allow it
  135. //5 == safeguard protection
  136. //8 == misty terrain doesn't allow it !TODO!
  137. if (battle_participants[bank].status.flags.poison || battle_participants[bank].status.flags.toxic_poison)
  138. return 1;
  139. if (battle_participants[bank].status.int_status)
  140. return 2;
  141. if (battle_bank_has_type(bank, TYPE_POISON) || battle_bank_has_type(bank, TYPE_STEEL))
  142. return 3;
  143. if (((battle_participants[bank].ability_id == ABILITY_IMMUNITY || (battle_participants[bank].ability_id == ABILITY_LEAF_GUARD && (battle_weather.flags.sun || battle_weather.flags.permament_sun || battle_weather.flags.harsh_sun)))))
  144. return 4;
  145. if (side_affecting_halfword[get_side_from_bank(bank)].safeguard_on && !self_inflicted)
  146. return 5;
  147. return 0;
  148. }
  149. u8 battle_count_party_pokemon(u8 bank)
  150. {
  151. struct pokemon* poke;
  152. if (get_side_from_bank(bank))
  153. poke = &party_opponent[0];
  154. else
  155. poke = &party_player[0];
  156. u8 usable_pokes = 0;
  157. for (u8 i = 0; i < 6; i ++)
  158. {
  159. if (pokemon_get_attribute(&poke[i], ATTR_CURRENT_HP, 0) != 0 && pokemon_get_attribute(&poke[i], ATTR_IS_EGG, 0) != 1 && pokemon_get_attribute(&poke[i], ATTR_SPECIES, 0) != 0)
  160. usable_pokes++;
  161. }
  162. return usable_pokes;
  163. }