Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const int ARRGHUS_EYE = 279;//Enemy Id for Eyes.
- const int EYE_STRUCK_MISC_INDEX = 2;//Misc index to tell if eye was struck by hookshot.
- ffc script Arrghus{
- void run(int enemyID){
- npc ghost = Ghost_InitAutoGhost(this, enemyID);
- npc eyes[25];//All eyes.
- int i;//Iterative variable.
- int combo = ghost->Attributes[10];//Combo for main boss.
- //Set up size and appearance.
- Ghost_Transform(this,ghost,-1,-1,2,3);
- Ghost_Data = combo;
- //Position boss.
- Ghost_X = 100;
- Ghost_Y = 64;
- //Track if an eye is dead.
- bool EyesDead[25];
- //Create and position eyes.
- //Set up array.
- for(i = 0;i<24;i++){
- eyes[i]= Screen->CreateNPC(ARRGHUS_EYE);
- eyes[i]->X = Ghost_X + 48 * Cos(i*15);
- eyes[i]->Y = Ghost_Y + 48 * Sin(i*15);
- EyesDead[i]= false;
- }
- int mode = 0;//Handles behavior.
- int NumEyes;//Tracks total eyes killed.
- float angle = Choose(45,135,225,315);//Regulates movement.
- float angle_change;//Regulates rate at which direction of movement changes.
- float step = ghost->Step/100;//Remember enemy speed so we can change it.
- //Used to calculate where to jump to.
- float targetX;
- float targetY;
- //Handles rotation of eyes.
- float eye_angle;
- //Handes frequency of jumps.
- int JumpTimer;
- //Determines what pattern eyes move in.
- int EyePath = Choose(0,1);
- //Determines how often that pattern changes.
- int EyeTimer = Rand(60,150);
- //X and Y radius of rotation, so they can be altered.
- float RadiusX;
- float RadiusY;
- //Tells code whether radius is increasing or not.
- bool Increase = ChooseBool();
- //Set value of variables depending on path of eyes.
- if(EyePath ==0){
- RadiusX = 32;
- RadiusY = 32;
- }
- else{
- RadiusX = 64;
- RadiusY = 32;
- }
- //Used to rotate figure 8.
- float prov_x;
- float prov_y;
- float prov_angle;
- float prov_rad;
- //Times changes in radius.
- int RadiusTimer;
- while(true){
- //Eyes are circling core.
- if(mode ==0){
- //Track all eyes.
- for(i = 0;i<24;i++){
- //If in a circular path.
- if(EyePath ==0){
- //Time to change radius.
- if(RadiusTimer == 0){
- //Radius is increasing.
- if(Increase){
- //Radius is less than 64.
- if(RadiusX<64){
- //Increase both X and Y radius.
- RadiusX++;
- RadiusY++;
- }
- //Don't increase radius any farther.
- else Increase = false;
- }
- //Radius is decreasing.
- else if(!Increase){
- //Radius is more than 32.
- if(RadiusX>32){
- //Decrease X and Y radius.
- RadiusX--;
- RadiusY--;
- }
- //Stop decreasing radius.
- else Increase = true;
- }
- }
- //Only rotate if they haven't been struck by the hookshot.
- if(eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]==0){
- eyes[i]->X = (Ghost_X+8) + RadiusX * Cos((i*15)+eye_angle);
- eyes[i]->Y = (Ghost_Y+8) + RadiusY * Sin((i*15)+eye_angle);
- }
- //Rotate every 10 frames.
- if(RadiusTimer%10 ==0)
- eye_angle = (eye_angle+1)%360;
- }
- //A horizontal figure 8.
- else if(EyePath ==1){
- if(eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]==0){
- prov_x = (Ghost_X+8) + RadiusX * Cos((i*15)+eye_angle);
- prov_y = (Ghost_Y+8) + RadiusY * Sin(2 *((i*15)+eye_angle));
- prov_rad = Distance(prov_x, prov_y, Ghost_X+8,Ghost_Y+8);
- prov_angle = RadtoDeg(ArcSin((prov_y - (Ghost_Y+8)) / prov_rad));
- if (prov_x - (Ghost_X+8) < 0)
- prov_angle = 180 - prov_angle;
- eyes[i]->X = (Ghost_X+8) + (prov_rad * Cos(prov_angle + eye_angle));
- eyes[i]->Y = (Ghost_Y+8)+ (prov_rad * Sin(prov_angle + eye_angle));
- }
- if(RadiusTimer%10 ==0)
- eye_angle = (eye_angle+1)%360;
- }
- //Track all lweapons.
- for(int j = 1;j<=Screen->NumLWeapons();j++){
- lweapon lw = Screen->LoadLWeapon(j);
- //The weapon is a hookshot.
- //It hit an eye.
- //This eye wasn't hit recently.
- if(lw->ID ==LW_HOOKSHOT && Collision(lw,eyes[i]) && eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]==0){
- eyes[i]->Defense[NPCD_SWORD]= NPCDT_NONE;
- eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]= 120;
- lw->DeadState = WDS_BOUNCE;
- if(Distance(lw->X,lw->Y,Link->X+8,Link->Y+8)>16 && lw->isValid()){
- eyes[i]->X= lw->X;
- eyes[i]->Y =lw->Y;
- }
- }
- }
- //All eyes are dead.
- if(NumNPCsOf(ARRGHUS_EYE)==0){
- mode =1;//Change behavior.
- //Alter appearance.
- Ghost_Transform(this,ghost,-1,-1,2,2);
- Ghost_Data = combo+1;
- //Lower defenses.
- Ghost_SetAllDefenses(ghost,NPCDT_NONE);
- }
- //Time to change eye behavior.
- if(EyeTimer<0){
- EyePath = Choose(0,1);//Choose movement pattern.
- //Position according to pattern chosen.
- if(EyePath ==0){
- RadiusX = 32;
- RadiusY = 32;
- }
- else{
- RadiusX = 64;
- RadiusY = 32;
- }
- //Reset timer.
- EyeTimer = Rand(60,150);
- }
- //If the eye has been struck, decrease the internal timer.
- //Also, lower defenses.
- if(eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]>0){
- eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]--;
- eyes[i]->Defense[NPCD_SWORD]= NPCDT_NONE;
- }
- //Set timer to zero.
- //Restore defenses.
- else{
- eyes[i]->Misc[EYE_STRUCK_MISC_INDEX]= 0;
- eyes[i]->Defense[NPCD_SWORD]= NPCDT_IGNORE;
- }
- //Rotate every 10 frames.
- RadiusTimer = (RadiusTimer+1)%30;
- }
- //Every few seconds, change from current angle to one of 3 others.
- if (angle_change == 0 && angle == 45)
- angle = Choose(135,225,315);
- else if(angle_change == 0 && angle == 135)
- angle = Choose(45, 225,315);
- else if(angle_change == 0 && angle == 225)
- angle = Choose(45,135,315);
- else if(angle_change == 0 && angle == 315)
- angle = Choose(45,135,225);
- angle_change = (angle_change + 1) % 60;
- Ghost_MoveAtAngle(angle, step, 3);
- }
- //Jumping mode.
- else if(mode ==1){
- //Time to jump.
- if(JumpTimer < 0){
- //Set jump destination to above Link.
- targetX=Link->X-8;
- targetY=Link->Y-16;
- Game->PlaySound(SFX_JUMP);//Make a sound.
- //Jump in the air.
- while(Ghost_Jump<6){
- Ghost_Jump++;
- //Move towards target.
- if(Ghost_X >targetX)
- Ghost_X--;
- else
- Ghost_X++;
- if(Ghost_Y>targetY)
- Ghost_Y--;
- else
- Ghost_Y++;
- Gen_Explode_Waitframe(this,ghost);
- }
- Game->PlaySound(SFX_FALL);//Make a sound.
- //While in the air, drop to Link's last position.
- while(Ghost_Z>0){
- //Keep moving towards target.
- if(Ghost_X >targetX)
- Ghost_X--;
- else
- Ghost_X++;
- if(Ghost_Y>targetY)
- Ghost_Y--;
- else
- Ghost_Y++;
- Ghost_Z--;
- Gen_Explode_Waitframe(this,ghost);
- }
- //Reset jump timer.
- JumpTimer = Rand(120,150);
- }
- //Every 5 seconds, change from current angle to one of 3 others.
- if (angle_change == 0 && angle == 45)
- angle = Choose(135,225,315);
- else if(angle_change == 0 && angle == 135)
- angle = Choose(45, 225,315);
- else if(angle_change == 0 && angle == 225)
- angle = Choose(45,135,315);
- else if(angle_change == 0 && angle == 315)
- angle = Choose(45,135,225);
- angle_change = (angle_change + 1) % 60;
- Ghost_MoveAtAngle(angle, step*2, 3);
- }
- JumpTimer--;//Reduce jump timer.
- EyeTimer--;//Reduce eye timer.
- Gen_Explode_Waitframe(this,ghost);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement