1
0

BossHexAI.gml 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. function hex_ai()
  2. {
  3. if state != "IDLE" && global.speedrun
  4. global.speedrun_timer++;
  5. switch(state)
  6. {
  7. case "IDLE":
  8. if hp < max_hp
  9. {
  10. if global.speedrun
  11. {
  12. timer_active = true;
  13. global.speedrun_timer = 0;
  14. }
  15. cnt = 0;
  16. roll_init();
  17. bgm_play("battle");
  18. }
  19. break;
  20. case "WAIT":
  21. cooldown -= global.time_scale;
  22. if cooldown <= 0
  23. {
  24. cooldown = 0;
  25. switch(current_attack)
  26. {
  27. case 0:
  28. cnt = 0;
  29. roll_init();
  30. break;
  31. case 1:
  32. cnt = 3;
  33. smash_init();
  34. break;
  35. case 2:
  36. cnt = 5;
  37. bounce_init();
  38. break;
  39. case 3:
  40. cnt = 2;
  41. spawn_init();
  42. break;
  43. }
  44. }
  45. break;
  46. case "ROLL":
  47. rebounce_timer--;
  48. var _roll_spd;
  49. if abs(roll_angle + roll_spd) >= 60
  50. _roll_spd = (60 - abs(roll_angle)) * sign(roll_angle);
  51. else if sign(roll_angle) == -sign(roll_angle + roll_spd)
  52. _roll_spd = -roll_angle;
  53. else
  54. _roll_spd = roll_spd;
  55. if collision_line(x, y, x + 144 * sign(-_roll_spd), y, oParentSolid, false, false) != noone
  56. && rebounce_timer <= 0
  57. {
  58. roll_spd *= -1;
  59. _roll_spd *= -1;
  60. rebounce_timer = 10;
  61. screen_shake(20);
  62. ++cnt;
  63. if cnt == 1
  64. roll_acc *= -1;
  65. if cnt == 3
  66. {
  67. cnt = 1;
  68. smash_init();
  69. }
  70. }
  71. if abs(roll_angle) == 60 || roll_angle == 0
  72. {
  73. roll_angle = 0;
  74. y = base_y;
  75. var _base_angle;
  76. if _roll_spd > 0
  77. _base_angle = 240;
  78. else if _roll_spd < 0
  79. _base_angle = 300;
  80. else
  81. _base_angle = (roll_acc > 0) ? 240 : 300;
  82. pivot_x = x + lengthdir_x(side_len, _base_angle);
  83. pivot_y = y + lengthdir_y(side_len, _base_angle);
  84. }
  85. roll_angle += _roll_spd;
  86. image_angle += _roll_spd;
  87. var _current_angle = point_direction(pivot_x, pivot_y, x, y);
  88. var _new_angle = _current_angle + _roll_spd;
  89. x = pivot_x + lengthdir_x(side_len, _new_angle);
  90. y = pivot_y + lengthdir_y(side_len, _new_angle);
  91. roll_spd += roll_acc;
  92. break;
  93. case "SMASH_BEGIN":
  94. x += x_spd;
  95. y += y_spd;
  96. image_angle += 0.4 * spd;
  97. if y < target_y
  98. {
  99. state = "SMASH";
  100. image_angle = round(image_angle / 60) * 60;
  101. y_spd = 20;
  102. y_acc = 1;
  103. break;
  104. }
  105. spd += acc;
  106. x_spd = lengthdir_x(spd, dir);
  107. y_spd = lengthdir_y(spd, dir);
  108. break;
  109. case "SMASH":
  110. y += y_spd;
  111. if collision_line(x, y, x, y + 108 + y_spd, oParentSolid, false, false) != noone
  112. {
  113. while collision_line(x, y, x, y + 108, oParentSolid, false, false) == noone
  114. y++;
  115. hex_var_erase();
  116. screen_shake(20);
  117. if !--cnt
  118. current_attack = hex_pick_attack();
  119. else
  120. smash_init();
  121. }
  122. y_spd += y_acc;
  123. var _x_alter = global.player.x - x
  124. x += max(4, _x_alter / 200) * sign(_x_alter);
  125. break;
  126. case "SPAWN":
  127. image_angle += abs(y_spd);
  128. y += y_spd;
  129. if y_spd == 15
  130. {
  131. image_angle -= abs(y_spd);
  132. hex_var_erase();
  133. screen_shake(15);
  134. icd(oEnemyHex, x, 998, depth + 1);
  135. if !--cnt
  136. current_attack = hex_pick_attack();
  137. else
  138. spawn_init();
  139. }
  140. y_spd += y_acc;
  141. break;
  142. case "BOUNCE":
  143. if collision_line(x, y, x + 144 * sign(x_spd), y, oParentSolid, false, false) != noone
  144. x_spd = 0;
  145. if y_spd == 20
  146. {
  147. image_angle += facing * 9;
  148. hex_var_erase();
  149. screen_shake(15);
  150. if !--cnt
  151. current_attack = hex_pick_attack();
  152. else
  153. bounce_init();
  154. break;
  155. }
  156. image_angle += facing * 9;
  157. x += x_spd;
  158. y += y_spd;
  159. y_spd += y_acc;
  160. break;
  161. }
  162. }
  163. function roll_init()
  164. {
  165. state = "ROLL";
  166. roll_spd = 5 * sign(global.player.x - x);
  167. roll_acc = -0.1 * sign(global.player.x - x);
  168. var _base_angle = (roll_spd > 0) ? 240 : 300;
  169. pivot_x = x + lengthdir_x(side_len, _base_angle);
  170. pivot_y = y + lengthdir_y(side_len, _base_angle);
  171. }
  172. function smash_init()
  173. {
  174. state = "SMASH_BEGIN";
  175. target_x = clamp(global.player.x, 200, 1920 - 200 - 64);
  176. target_y = y - 480;
  177. dir = point_direction(x, y, target_x, target_y);
  178. spd = 15;
  179. acc = 0.3;
  180. x_spd = lengthdir_x(spd, dir);
  181. y_spd = lengthdir_y(spd, dir);
  182. }
  183. function spawn_init()
  184. {
  185. y_spd = -15;
  186. y_acc = 0.6;
  187. state = "SPAWN";
  188. }
  189. function bounce_init()
  190. {
  191. state = "BOUNCE";
  192. y_spd = -20;
  193. y_acc = 1;
  194. facing = sign(global.player.x - x);
  195. x_spd = facing * 9;
  196. }
  197. function hex_pick_attack()
  198. {
  199. hex_var_erase();
  200. cooldown = _cooldown[global.difficulty];
  201. state = "WAIT";
  202. var _row = attack_matrix[last_attack];
  203. var _atk = weighted_pick(_row);
  204. if _atk == 3 && instance_number(oEnemyHex) > 1
  205. {
  206. var _fallback = array_create(array_length(_row));
  207. array_copy(_fallback, 0, _row, 0, array_length(_row));
  208. _fallback[3] = 0;
  209. _atk = weighted_pick(_fallback);
  210. }
  211. last_attack = _atk;
  212. return _atk;
  213. }
  214. function hex_var_erase()
  215. {
  216. spd = 0;
  217. acc = 0;
  218. dir = 0;
  219. x_spd = 0;
  220. y_spd = 0;
  221. x_acc = 0;
  222. y_acc = 0;
  223. roll_spd = 0;
  224. roll_acc = 0;
  225. roll_angle = 0;
  226. y = base_y;
  227. image_angle = round(image_angle / 60) * 60;
  228. }