No Description

entry_hazards.c 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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 entry_hazards.c
  24. * @author Sturmvogel
  25. * @date 15 dec 2016
  26. * @brief Handle entry hazards
  27. */
  28. /* === INCLUDE === */
  29. #include <battle_help.h>
  30. #include <battle_locations.h>
  31. #include <moves.h>
  32. #include <battle_structs.h>
  33. #include <battle_custom_structs.h>
  34. #include <pkmn_types.h>
  35. #include <battle_common.h>
  36. /* === EXTERN STATICS === */
  37. extern void* bs_stealth_rock;
  38. extern void* bs_toxic_spikes;
  39. extern void* bs_toxic_spikes_bad;
  40. extern void* bs_sticky_web;
  41. extern void* bs_toxic_resolve;
  42. extern void* bs_spikes_lain;
  43. extern void* bs_rocks_lain;
  44. extern void* bs_toxic_lain;
  45. extern void* bs_sticky_lain;
  46. extern void* bs_lunar_dance_exec;
  47. extern void* str_lunardance_executed_ref;
  48. /* === PROTOTYPES === */
  49. /**
  50. * @brief execute entry hazards scripts if they are lain
  51. * @return true if there was an effect, false otherwise
  52. */
  53. u8 execute_entry_hazards();
  54. /**
  55. * @brief execute a lay script for entry hazards
  56. * @return true
  57. */
  58. u8 lay_entry_hazards();
  59. /* === IMPLEMENTATIONS === */
  60. u8 execute_entry_hazards() {
  61. u8 active_side = get_side_from_bank(battle_active_bank);
  62. u8 has_effect = 0;
  63. struct side_affecting* active_side_affecting = &custom_battle_elements.ptr->side_affecting[active_side];
  64. if (active_side_affecting->lunardance && !(active_side_affecting->lunardance_done)) {
  65. battle_damage_store = ((s32)battle_participants[battle_active_bank].max_hp - (s32)battle_participants[battle_active_bank].current_hp) * -1;
  66. active_side_affecting->lunardance = 0;
  67. battle_participants[battle_active_bank].status.int_status = 0;
  68. prepare_setattributes_in_battle(0, REQUEST_STATUS_BATTLE, 0, 4, &battle_participants[battle_active_bank].status);
  69. mark_buffer_bank_for_execution(battle_active_bank);
  70. battle_script_push();
  71. battle_string_chooser = str_lunardance_executed_ref;
  72. battlescript_cursor = bs_lunar_dance_exec;
  73. has_effect = 1;
  74. } else if (side_affecting_halfword[active_side].spikes_on && !(side_affecting_halfword[active_side].spikes_damage_done)) {
  75. //spikes lay down, deal spiky damage
  76. u32 damage = (battle_participants[battle_active_bank].max_hp) / ((5 - battle_side_timers[active_side].spikes_amount) * 2);
  77. if (damage == 0)
  78. damage = 1;
  79. battle_damage_store = damage;
  80. side_affecting_halfword[active_side].spikes_damage_done = 1;
  81. battle_script_push();
  82. battlescript_cursor = (void*) (0x081D8CBE);
  83. has_effect = 1;
  84. } else if (active_side_affecting->stealth_rock && !(active_side_affecting->stealth_rock_done)) {
  85. active_side_affecting->stealth_rock_done = 1;
  86. //check for magic guard here
  87. u32 damage = battle_participants[battle_active_bank].max_hp;
  88. switch (battle_type_effectiveness_calc(MOVE_STEALTH_ROCK, TYPE_ROCK, battle_active_bank^1, battle_active_bank, 0) >> 4) {
  89. case 1:
  90. damage = damage >> 5;
  91. break;
  92. case 2:
  93. damage = damage >> 4;
  94. break;
  95. case 4:
  96. damage = damage >> 3;
  97. break;
  98. case 8:
  99. damage = damage >> 2;
  100. break;
  101. case 16:
  102. damage = damage >> 1;
  103. break;
  104. }
  105. if (damage == 0)
  106. damage = 1;
  107. battle_damage_store = damage;
  108. battle_script_push();
  109. battlescript_cursor = bs_stealth_rock;
  110. has_effect = 1;
  111. } else if (active_side_affecting->toxic_spikes_psn && !(active_side_affecting->toxic_spikes_done)) {
  112. active_side_affecting->toxic_spikes_done = 1;
  113. if (battle_bank_has_type(battle_active_bank, TYPE_POISON)) {
  114. has_effect = 1;
  115. active_side_affecting->toxic_spikes_psn = 0;
  116. active_side_affecting->toxic_spikes_badpsn = 0;
  117. battle_script_push();
  118. battlescript_cursor = bs_toxic_resolve;
  119. } else if (!battle_bank_is_poison_resistant(battle_active_bank, 0)) {
  120. if (active_side_affecting->toxic_spikes_badpsn) {
  121. battle_participants[battle_active_bank].status.flags.toxic_poison = 1;
  122. battle_script_push();
  123. battlescript_cursor = bs_toxic_spikes_bad;
  124. } else {
  125. battle_participants[battle_active_bank].status.flags.poison = 1;
  126. battle_script_push();
  127. battlescript_cursor = bs_toxic_spikes;
  128. }
  129. prepare_setattributes_in_battle(0, REQUEST_STATUS_BATTLE, 0, 4, &battle_participants[battle_active_bank].status.flags);
  130. mark_buffer_bank_for_execution(battle_active_bank);
  131. has_effect = 1;
  132. }
  133. } else if (active_side_affecting->sticky_web && !(active_side_affecting->sticky_web_done) && battle_participants[battle_active_bank].spd_buff != 0) {
  134. active_side_affecting->sticky_web_done = 1;
  135. battle_script_push();
  136. battlescript_cursor = bs_sticky_web;
  137. battle_stat_changer = 0x93;
  138. has_effect = 1;
  139. }
  140. if (has_effect) {
  141. custom_battle_elements.ptr->various.var1 = battle_active_bank;
  142. battle_participants[battle_active_bank].status2.destinny_bond = 0;
  143. battle_hitmarker &= 0xFFFFFFBF;
  144. }
  145. return has_effect;
  146. }
  147. u8 lay_entry_hazards() {
  148. u8 target_side = get_side_from_bank(battle_defender_bank);
  149. u8 fail = 0;
  150. struct side_affecting* target_side_struct = &custom_battle_elements.ptr->side_affecting[target_side];
  151. switch (battle_executed_move) {
  152. case MOVE_SPIKES:
  153. if (battle_side_timers[target_side].spikes_amount < 3) {
  154. battle_side_timers[target_side].spikes_amount++;
  155. side_affecting_halfword[target_side].spikes_on = 1;
  156. battlescript_cursor = bs_spikes_lain;
  157. } else {
  158. fail = 1;
  159. }
  160. break;
  161. case MOVE_STEALTH_ROCK:
  162. if (target_side_struct->stealth_rock == 0) {
  163. target_side_struct->stealth_rock = 1;
  164. battlescript_cursor = bs_rocks_lain;
  165. } else
  166. fail = 1;
  167. break;
  168. case MOVE_TOXIC_SPIKES:
  169. if (target_side_struct->toxic_spikes_psn == 0) {
  170. target_side_struct->toxic_spikes_psn = 1;
  171. battlescript_cursor = bs_toxic_lain;
  172. } else if (target_side_struct->toxic_spikes_badpsn == 0) {
  173. target_side_struct->toxic_spikes_badpsn = 1;
  174. battlescript_cursor = bs_toxic_lain;
  175. } else
  176. fail = 1;
  177. break;
  178. case MOVE_STICKY_WEB:
  179. if (target_side_struct->sticky_web == 0) {
  180. target_side_struct->sticky_web = 1;
  181. battlescript_cursor = bs_sticky_lain;
  182. } else
  183. fail = 1;
  184. break;
  185. default:
  186. fail = 1;
  187. break;
  188. }
  189. if (fail) {
  190. //failed execution
  191. battlescript_cursor = (void*) (0x081D7DF0);
  192. }
  193. return 1;
  194. }