//Uses to make a boss using the Gen_Explode_Waitframe wait for a certain number of frames before doing something. void Gen_Explode_Waitframes(ffc this, npc ghost,int frames){ for(;frames>0;frames--){ Gen_Explode_Waitframe(this,ghost); } } //A general utility function to make a boss explode on death. void Gen_Explode_Waitframe(ffc this, npc ghost){ if(!Ghost_Waitframe(this, ghost, false, false)){ Ghost_DeathAnimation(this, ghost, 2); Quit(); } } const int BLIZZETA_BARRIER = 185;//Enemy ID of ice barriers that surround main boss. const int BLIZZETA_EXTRA_COMBO = 32281;//Combo of top half of boss. const int CHUNK_SPRITE = 83;//Sprite used by ice chunk attacks. ffc script Blizzeta{ void run(int enemyID){ npc n = Ghost_InitAutoGhost(this, enemyID); npc n2 = Screen->CreateNPC(BLIZZETA_BARRIER); npc n3 = Screen->CreateNPC(BLIZZETA_BARRIER); npc n4 = Screen->CreateNPC(BLIZZETA_BARRIER); npc n5 = Screen->CreateNPC(BLIZZETA_BARRIER); bool isAlive1 = true; bool isAlive2 = true; bool isAlive3 = true; bool isAlive4 = true; n->Extend = 3; Ghost_TileWidth = 4; Ghost_TileHeight = 3; bool StartTimer = false; int timer = 0; int combo = n->Attributes[10]; Ghost_Transform(this,n,combo,-1,4,3); Ghost_AddCombo(BLIZZETA_EXTRA_COMBO,-16,-31,6,2); n2->Extend = 3; n3->Extend = 3; n4->Extend = 3; n5->Extend = 3; n2->TileWidth = 2; n2->TileHeight = 2; n3->TileWidth = 2; n3->TileHeight = 2; n4->TileWidth = 2; n4->TileHeight = 2; n5->TileWidth = 2; n5->TileHeight = 2; n2->HitWidth = 32; n2->HitHeight = 32; n3->HitWidth = 32; n3->HitHeight = 32; n4->HitWidth = 32; n4->HitHeight = 32; n5->HitWidth = 32; n5->HitHeight = 32; n2->X = n->X - 32; n2->Y = n->Y +16; n3->X = n->X + 32; n3->Y = n->Y + 16; n4->X = n->X + 16; n4->Y = n->Y + 32; n5->X = n->X + 16; n5->Y = n->Y - 32; float ice_angle; float angle = 45; float speed = n->Step * 0.01; float step = speed; int angle_change; bool BarrierUp = true; int direction = 1; eweapon chunk; while(n->HP > 0){ //Track the HP of the barriers and if any die, start moving faster. if(n5->HP <= 0 && isAlive4){ isAlive4 = false; StartTimer = true; } if (n4->HP <=0 && isAlive3){ isAlive3 = false; StartTimer = true; } if (n3->HP<= 0 && isAlive2){ isAlive2 = false; StartTimer = true; } if (n2->HP <= 0 && isAlive1){ isAlive1 = false; StartTimer = true; } if(StartTimer){ timer = 600; StartTimer = false; } //Rotate the barriers constantly. ice_angle = (ice_angle + 1) % 360; //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) % 240; Ghost_MoveAtAngle(angle, step, 3); //While any of the barriers are alive, keep the core invulnerable. if(BarrierUp){ n2->X = (n->X+16) + 48 * Cos(ice_angle); n2->Y = (n->Y+24) + 48 * Sin(ice_angle); n3->X = (n->X+16) + 48 * Cos(ice_angle+90); n3->Y = (n->Y+24) + 48 * Sin(ice_angle+90); n4->X = (n->X+16) + 48 * Cos(ice_angle+180); n4->Y = (n->Y+24) + 48 * Sin(ice_angle+180); n5->X = (n->X+16) + 48 * Cos(ice_angle+270); n5->Y = (n->Y+24) + 48 * Sin(ice_angle+270); if((n2->HP <= 0 && n3->HP <= 0 && n4->HP <= 0 && n5->HP<=0) ||(!n2->isValid() && !n3->isValid() && !n4->isValid() && !n5->isValid()))BarrierUp = false; } //The barriers are dead. Make the core vulnerable. else if (!BarrierUp){ n->Defense[NPCD_MAGIC]=NPCDT_NONE; step = speed; } //When a barrier dies, make it move faster and render the other parts invulnerable. while(timer > 0){ ice_angle = (ice_angle + 1) % 360; step = 2* speed; n2->Defense[NPCD_MAGIC]= NPCDT_IGNORE; n3->Defense[NPCD_MAGIC]= NPCDT_IGNORE; n4->Defense[NPCD_MAGIC]= NPCDT_IGNORE; n5->Defense[NPCD_MAGIC]= NPCDT_IGNORE; n2->X = (n->X+16) + 48 * Cos(ice_angle); n2->Y = (n->Y+24) + 48 * Sin(ice_angle); n3->X = (n->X+16) + 48 * Cos(ice_angle+90); n3->Y = (n->Y+24) + 48 * Sin(ice_angle+90); n4->X = (n->X+16) + 48 * Cos(ice_angle+180); n4->Y = (n->Y+24) + 48 * Sin(ice_angle+180); n5->X = (n->X+16) + 48 * Cos(ice_angle+270); n5->Y = (n->Y+24) + 48 * Sin(ice_angle+270); 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) % 240; chunk = FireAimedEWeapon(n->Weapon, (n->X+16)+ 1 * Cos(ice_angle), (n->Y+24) + 1 * Sin(ice_angle), ice_angle, 100, n->WeaponDamage, CHUNK_SPRITE, 40, EWF_ROTATE); SetEWeaponLifespan(chunk,EWL_TIMER, 90); SetEWeaponDeathEffect(chunk,EWD_VANISH, 0); Ghost_MoveAtAngle(angle, step, 3); timer--; if(timer <= 0){ n2->Defense[NPCD_MAGIC]=NPCDT_NONE; n3->Defense[NPCD_MAGIC]=NPCDT_NONE; n4->Defense[NPCD_MAGIC]=NPCDT_NONE; n5->Defense[NPCD_MAGIC]=NPCDT_NONE; step = speed; break; } Gen_Explode_Waitframe(this, n); } //The boss is dead. Gen_Explode_Waitframe(this, n); } } }