Advertisement
ywkls

Arrghus

Jul 18th, 2020
37
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const int ARRGHUS_EYE = 279;//Enemy Id for Eyes.
  2. const int EYE_STRUCK_MISC_INDEX = 2;//Misc index to tell if eye was struck by hookshot.
  3.  
  4. ffc script Arrghus{
  5. void run(int enemyID){
  6. npc ghost = Ghost_InitAutoGhost(this, enemyID);
  7. npc eyes[25];//All eyes.
  8. int i;//Iterative variable.
  9. int combo = ghost->Attributes[10];//Combo for main boss.
  10. //Set up size and appearance.
  11. Ghost_Transform(this,ghost,-1,-1,2,3);
  12. Ghost_Data = combo;
  13. //Position boss.
  14. Ghost_X = 100;
  15. Ghost_Y = 64;
  16. //Track if an eye is dead.
  17. bool EyesDead[25];
  18. //Create and position eyes.
  19. //Set up array.
  20. for(i = 0;i<24;i++){
  21. eyes[i]= Screen->CreateNPC(ARRGHUS_EYE);
  22. eyes[i]->X = Ghost_X + 48 * Cos(i*15);
  23. eyes[i]->Y = Ghost_Y + 48 * Sin(i*15);
  24. EyesDead[i]= false;
  25. }
  26. int mode = 0;//Handles behavior.
  27. int NumEyes;//Tracks total eyes killed.
  28. float angle = Choose(45,135,225,315);//Regulates movement.
  29. float angle_change;//Regulates rate at which direction of movement changes.
  30. float step = ghost->Step/100;//Remember enemy speed so we can change it.
  31. //Used to calculate where to jump to.
  32. float targetX;
  33. float targetY;
  34. //Handles rotation of eyes.
  35. float eye_angle;
  36. //Handes frequency of jumps.
  37. int JumpTimer;
  38. //Determines what pattern eyes move in.
  39. int EyePath = Choose(0,1);
  40. //Determines how often that pattern changes.
  41. int EyeTimer = Rand(60,150);
  42. //X and Y radius of rotation, so they can be altered.
  43. float RadiusX;
  44. float RadiusY;
  45. //Tells code whether radius is increasing or not.
  46. bool Increase = ChooseBool();
  47. //Set value of variables depending on path of eyes.
  48. if(EyePath ==0){
  49. RadiusX = 32;
  50. RadiusY = 32;
  51. }
  52. else{
  53. RadiusX = 64;
  54. RadiusY = 32;
  55. }
  56. //Used to rotate figure 8.
  57. float prov_x;
  58. float prov_y;
  59. float prov_angle;
  60. float prov_rad;
  61. //Times changes in radius.
  62. int RadiusTimer;
  63. while(true){
  64. //Eyes are circling core.
  65. if(mode ==0){
  66. //Track all eyes.
  67. for(i = 0;i<24;i++){
  68. //If in a circular path.
  69. if(EyePath ==0){
  70. //Time to change radius.
  71. if(RadiusTimer == 0){
  72. //Radius is increasing.
  73. if(Increase){
  74. //Radius is less than 64.
  75. if(RadiusX<64){
  76. //Increase both X and Y radius.
  77. RadiusX++;
  78. RadiusY++;
  79. }
  80. //Don't increase radius any farther.
  81. else Increase = false;
  82. }
  83. //Radius is decreasing.
  84. else if(!Increase){
  85. //Radius is more than 32.
  86. if(RadiusX>32){
  87. //Decrease X and Y radius.
  88. RadiusX--;
  89. RadiusY--;
  90. }
  91. //Stop decreasing radius.
  92. else Increase = true;
  93. }
  94. }
  95. //Only rotate if they haven't been struck by the hookshot.
  96. if(eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]==0){
  97. eyes[i]->X = (Ghost_X+8) + RadiusX * Cos((i*15)+eye_angle);
  98. eyes[i]->Y = (Ghost_Y+8) + RadiusY * Sin((i*15)+eye_angle);
  99. }
  100. //Rotate every 10 frames.
  101. if(RadiusTimer%10 ==0)
  102. eye_angle = (eye_angle+1)%360;
  103. }
  104. //A horizontal figure 8.
  105. else if(EyePath ==1){
  106. if(eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]==0){
  107. prov_x = (Ghost_X+8) + RadiusX * Cos((i*15)+eye_angle);
  108. prov_y = (Ghost_Y+8) + RadiusY * Sin(2 *((i*15)+eye_angle));
  109. prov_rad = Distance(prov_x, prov_y, Ghost_X+8,Ghost_Y+8);
  110. prov_angle = RadtoDeg(ArcSin((prov_y - (Ghost_Y+8)) / prov_rad));
  111. if (prov_x - (Ghost_X+8) < 0)
  112. prov_angle = 180 - prov_angle;
  113. eyes[i]->X = (Ghost_X+8) + (prov_rad * Cos(prov_angle + eye_angle));
  114. eyes[i]->Y = (Ghost_Y+8)+ (prov_rad * Sin(prov_angle + eye_angle));
  115. }
  116. if(RadiusTimer%10 ==0)
  117. eye_angle = (eye_angle+1)%360;
  118. }
  119. //Track all lweapons.
  120. for(int j = 1;j<=Screen->NumLWeapons();j++){
  121. lweapon lw = Screen->LoadLWeapon(j);
  122. //The weapon is a hookshot.
  123. //It hit an eye.
  124. //This eye wasn't hit recently.
  125. if(lw->ID ==LW_HOOKSHOT && Collision(lw,eyes[i]) && eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]==0){
  126. eyes[i]->Defense[NPCD_SWORD]= NPCDT_NONE;
  127. eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]= 120;
  128. lw->DeadState = WDS_BOUNCE;
  129. if(Distance(lw->X,lw->Y,Link->X+8,Link->Y+8)>16 && lw->isValid()){
  130. eyes[i]->X= lw->X;
  131. eyes[i]->Y =lw->Y;
  132. }
  133. }
  134. }
  135. //All eyes are dead.
  136. if(NumNPCsOf(ARRGHUS_EYE)==0){
  137. mode =1;//Change behavior.
  138. //Alter appearance.
  139. Ghost_Transform(this,ghost,-1,-1,2,2);
  140. Ghost_Data = combo+1;
  141. //Lower defenses.
  142. Ghost_SetAllDefenses(ghost,NPCDT_NONE);
  143. }
  144. //Time to change eye behavior.
  145. if(EyeTimer<0){
  146. EyePath = Choose(0,1);//Choose movement pattern.
  147. //Position according to pattern chosen.
  148. if(EyePath ==0){
  149. RadiusX = 32;
  150. RadiusY = 32;
  151. }
  152. else{
  153. RadiusX = 64;
  154. RadiusY = 32;
  155. }
  156. //Reset timer.
  157. EyeTimer = Rand(60,150);
  158. }
  159. //If the eye has been struck, decrease the internal timer.
  160. //Also, lower defenses.
  161. if(eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]>0){
  162. eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]--;
  163. eyes[i]->Defense[NPCD_SWORD]= NPCDT_NONE;
  164. }
  165. //Set timer to zero.
  166. //Restore defenses.
  167. else{
  168. eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]= 0;
  169. eyes[i]->Defense[NPCD_SWORD]= NPCDT_IGNORE;
  170. }
  171. //Rotate every 10 frames.
  172. RadiusTimer = (RadiusTimer+1)%30;
  173. }
  174. //Every few seconds, change from current angle to one of 3 others.
  175. if (angle_change == 0 && angle == 45)
  176. angle = Choose(135,225,315);
  177. else if(angle_change == 0 && angle == 135)
  178. angle = Choose(45, 225,315);
  179. else if(angle_change == 0 && angle == 225)
  180. angle = Choose(45,135,315);
  181. else if(angle_change == 0 && angle == 315)
  182. angle = Choose(45,135,225);
  183. angle_change = (angle_change + 1) % 60;
  184. Ghost_MoveAtAngle(angle, step, 3);
  185. }
  186. //Jumping mode.
  187. else if(mode ==1){
  188. //Time to jump.
  189. if(JumpTimer < 0){
  190. //Set jump destination to above Link.
  191. targetX=Link->X-8;
  192. targetY=Link->Y-16;
  193. Game->PlaySound(SFX_JUMP);//Make a sound.
  194. //Jump in the air.
  195. while(Ghost_Jump<6){
  196. Ghost_Jump++;
  197. //Move towards target.
  198. if(Ghost_X >targetX)
  199. Ghost_X--;
  200. else
  201. Ghost_X++;
  202. if(Ghost_Y>targetY)
  203. Ghost_Y--;
  204. else
  205. Ghost_Y++;
  206. Gen_Explode_Waitframe(this,ghost);
  207. }
  208. Game->PlaySound(SFX_FALL);//Make a sound.
  209. //While in the air, drop to Link's last position.
  210. while(Ghost_Z>0){
  211. //Keep moving towards target.
  212. if(Ghost_X >targetX)
  213. Ghost_X--;
  214. else
  215. Ghost_X++;
  216. if(Ghost_Y>targetY)
  217. Ghost_Y--;
  218. else
  219. Ghost_Y++;
  220. Ghost_Z--;
  221. Gen_Explode_Waitframe(this,ghost);
  222. }
  223. //Reset jump timer.
  224. JumpTimer = Rand(120,150);
  225. }
  226. //Every 5 seconds, change from current angle to one of 3 others.
  227. if (angle_change == 0 && angle == 45)
  228. angle = Choose(135,225,315);
  229. else if(angle_change == 0 && angle == 135)
  230. angle = Choose(45, 225,315);
  231. else if(angle_change == 0 && angle == 225)
  232. angle = Choose(45,135,315);
  233. else if(angle_change == 0 && angle == 315)
  234. angle = Choose(45,135,225);
  235. angle_change = (angle_change + 1) % 60;
  236. Ghost_MoveAtAngle(angle, step*2, 3);
  237. }
  238. JumpTimer--;//Reduce jump timer.
  239. EyeTimer--;//Reduce eye timer.
  240. Gen_Explode_Waitframe(this,ghost);
  241. }
  242. }
  243. }
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement