#include "./../../system/functions/functions_enemy.txt"
#include "./../../system/functions/functions_stage.txt"

let BossScene;

@Initialize{TMain;}
@MainLoop{yield;}

task TMain
	{
	loop(30){yield;}
	
	local //Chapter 1
		{
		ascent(dir in 0..2)
			{
			dir = dir*2-1;
			descent(i in 0..12)
				{
				CreateEnemyA1(GetStgFrameWidth*(0.5+dir*0.5)+dir*(120-((i*3)%8)*24),-64-floor(i/3)*16,90+dir*75,dir,0);
				loop(12){yield;}
				}
			loop(135){yield;}
			}
		}
	loop(175){yield;}
	local //title
		{
		let backA = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture(backA,GetCurrentScriptDirectory ~ "./boss/img/background/title.png");
		ObjSprite2D_SetSourceRect(backA,0,0,316,80);
		ObjSprite2D_SetDestRect(backA,-158,-40,158,40);
		Obj_SetRenderPriority(backA,0.6);	
		ObjRender_SetPosition(backA,GetStgFrameWidth*0.5,120,0);
		ascent(t in 0..75)
			{
			ObjRender_SetAlpha(backA,t*255/74);
			yield;	
			}
		loop(100){yield;}
		Obj_SetValue(GetPlayerObjectID,"BACKGROUND_CHANGE",2);
		PlaySound("se_Thunder1",100);
		loop(175){yield;}
		descent(t in 0..75)
			{
			ObjRender_SetAlpha(backA,t*255/74);
			yield;	
			}
		loop(100){yield;}
		}
	local //Chapter 2
		{
		let spread = 13;
		ascent(dir in 0..2)
			{
			dir = dir*2-1;
			TPhase2(spread,dir,0);
			loop(170){yield;}
			loop(135){yield;}
			}
		}
	loop(15){yield;}
	local //Chapter 3
		{
		ascent(n in 0..2)
			{
			descent(dir in 0..2)
				{
				dir = dir*2-1;
				if(n == 1)
					{
					TPhase2(8,dir,-32);
					}
				CreateEnemyA3(GetStgFrameWidth*(0.5+dir*0.5)+dir*32,100,dir);
				loop(150){yield;}
				if(dir == -1 && n == 0)
					{
					dir*=-1;
					descent(i in 0..6)
						{
						CreateEnemyA1(GetStgFrameWidth*(0.5+dir*0.5)+dir*(120-((i*3)%8)*24),-64-floor(i/3)*16,90+dir*75,dir,1);
						loop(12){yield;}
						}
					}
				loop(105){yield;}
				}
			loop(60){yield;}
			}	
		loop(45){yield;}
		TPhase2(13,1,0);
		loop(225){yield;}	
		descent(i in 1..9)
			{
			descent(dir in 0..2)
				{
				dir = dir*2-1;
				CreateEnemyA1(GetStgFrameWidth*(0.5+dir*0.5)+dir*(120-((i*3)%8)*24),-64-floor(i/3)*16,90+dir*75,dir,0);
				loop(12){yield;}
				}
			}
		loop(180){yield;}
		}
	ascent(t in 0..25)	
		{
		yield;
		if(t >= 24)
			{
			DeleteShotInCircle(TARGET_ENEMY,TYPE_FADE,GetStgFrameWidth*0.5,GetStgFrameHeight*0.5,GetStgFrameHeight*1.5);
			}
		}
	Obj_SetValue(GetPlayerObjectID,"BACKGROUND_CHANGE",1);
	local
		{
		let array = GetAllEnemyID;
		ascent(i in 0..length(array))
			{
			Obj_Delete(array[i]);
			}	
		PlaySound("se_Thunder2",100);
		}
	loop(60){yield;}
	loop(60){yield;}
	local //Chapter 4
		{
		let spread = 1;
		let spreadM = [8,11,14,17][Dif];
		let t = 45;
		let tM = 14;
		let c = -1;	
		let a = trunc(rand(0,spreadM));
		let aa = 0;
		let tAM = 70;
		let tA = 180;
		let cA = tA;
		let sM = [2,2.625,3.125,3.5][Dif];
		ascent(cM in 0..2300)
			{
			c+=1;
			cA+=1;
			if(c >= t)
				{
				PlaySound("se_Shot1",60);
				if(t > tM)
					{
					t-=1;
					}
				else 
					{
					t = tM;
					}
				if(spread < spreadM)
					{
					spread+=1;
					}
				else 
					{
					spread = spreadM;
					}
				c = 0;
				ascent(i in 0..spread)
					{
					i = ((i+a)%spread)-spread*0.5+0.5;
					let d = i*GetStgFrameHeight*3/spread;
					let x = max(0,min(GetStgFrameWidth,GetStgFrameWidth+d*cos(45)));
					let y = max(0,min(GetStgFrameHeight,d*sin(45)));
					CreateBulletA1(x,y,sM-(aa%2)*0.1,125+rand(-1,1)*0.5-(i+5)*5,DROP,6,1.325,SHOT_BLUE);
					}
				aa+=1;
				if(aa%2 == 0)
					{
					a+=0.5;
					}
				}
			if(cM >= 1110 && cA >= tA)
				{
				if(tA > tAM)
					{
					tA -=15;
					}
				else
					{
					tA = tAM;
					}
				cA = 0;
				let spread = 1;
				let x = rand(50,GetStgFrameWidth*0.5-75);		
				if(GetPlayerX < GetStgFrameWidth*0.5)
					{
					x = GetStgFrameWidth-x;
					}
				let y = 0;
				let a = atan2(GetPlayerY-y,GetPlayerX-x);
				TBolt(x,y,a,1);
				}
			yield;
			}
		}
	loop(360){yield;}
	CloseScript(GetOwnScriptID);
	}
task TBolt(x,y,a,p)
	{
	let d = 110*p;
	let w = 6+24*p;
	a += rand(-1,1)*(0+min(30,(1-p)*360));
	
	let n = rand(0,1);
	TBoltA;
	loop(3){yield;}
	if(n < p)
		{
		TBolt(x+d*cos(a),y+d*sin(a),a,p*0.875);
		}
	if(p == 1 && x+d*cos(a) > 0 && x+d*cos(a) < GetStgFrameWidth && y+d*sin(a) > 0 && y+d*sin(a) < GetStgFrameHeight)
		{
		TBolt(x+d*cos(a),y+d*sin(a),a,1);
		}
	task TBoltA
		{
		let tB = [0,6,3,2][Dif];
		let tA = [60,55,50,45][Dif];
		let tC = [0,3,2,1][Dif];
		let tD = [0,0,1,2][Dif];
		let beam = CreateLaserA2(x,y,d/3,a,d+8,w,6,C_LASER,tA,SHOT_YELLOW);
		ObjStLaser_SetSource(beam,false);
		loop(tA){yield;}
		if(Obj_IsDeleted(beam)){return;}
		ascent(t in 0..6)
			{
			let shot = CreateBulletA1(x-t*((d/6)/6)*cos(a),y-t*((d/6)/6)*sin(a),d/6,a,SCALE,0,1,SHOT_YELLOW);
			ObjShot_SetGraphic(shot,SCALE[SHOT_YELLOW]-1);
			if(t%tB != 0)
				{
				Obj_DelayDelete(shot,6);
				}
			else
				{
				ObjMove_SetSpeed(shot,tC+tD*(1-t/6));
				ObjMove_SetAngle(shot,ObjMove_GetAngle(shot));
				}
			yield;
			}
		}
	}
task TPhase2(spread,dir,y)
	{
	descent(i in 0..spread)
		{
		let x = GetStgFrameWidth*(0.5+dir*(-0.5+i/spread));
		CreateEnemyA2(x,y-16,x+dir*32,y+128,dir,(spread-i)*13+1,spread-i-1);
		loop(170/spread){yield;}
		}
	}

task CreateEnemyA1(x,y,a,dir,g)
	{	
	let spread = [[0,0,2,4][Dif],[0,0,3,5][Dif]][g];
	let aM = [90,90][g];
	let aA = dir*rand(-1,0)*0;
	let tM = [30,15,11,7][Dif];

	let obj = CreateBasicEnemyA1(x,y,6,a,600,100,type_fairy,fairy_blue,0);
	ObjMove_SetAcceleration(obj,-5.5/120);
	ObjMove_SetMaxSpeed(obj,0);
	ObjMove_SetAngularVelocity(obj,-dir*135/120);
	let counterM = -1;	
	let counter = floor(rand(0,22));
	let switch = false;
	while(!Obj_IsDeleted(obj) && (switch == false || !IsBeyondClip(obj,32)))
		{
		counterM+=1;
		if(counterM == 75)
			{
			ascent(i in 0..spread)
				{
				i = i-spread*0.5+0.5;
				let shot = CreateBulletA2(ObjMove_GetX(obj),ObjMove_GetY(obj),6,270-dir*30+aA+i*aM/spread,-4/15,0,2,[BUBBLE,LARGE][g],8,1,SHOT_BLUE);
				ObjRender_SetBlendType(shot,BLEND_ADD_ARGB);
				Obj_SetRenderPriority(shot,0.51);
				ObjMove_AddPatternB2(shot,15,NO_CHANGE,NO_CHANGE,0,1/(30-g*10),0,10);
				}
			}
		if(counterM >= 120 && (counterM-90)%tM == 0)
			{
			PlaySound("se_Shot1",60);
			CreateBulletA2(ObjMove_GetX(obj),ObjMove_GetY(obj),6,90+rand(-1,1)*5,-4/45,0,rand(1.75,2.25),BL_SMALL,8,1.125,SHOT_BLUE);
			}
		if(counterM == 120)
			{
			ObjMove_SetAcceleration(obj,1/30);
			ObjMove_SetMaxSpeed(obj,5);
			ObjMove_SetAngularVelocity(obj,-dir*285/180);
			switch = true;
			}
		if(counterM == 250-g*25)
			{
			ObjMove_SetAcceleration(obj,1/30);
			ObjMove_SetMaxSpeed(obj,5);
			ObjMove_SetAngularVelocity(obj,0);
			switch = true;
			}
		yield;
		}
	Obj_Delete(obj);
	}

task CreateEnemyA2(x1,y1,x2,y2,dir,tA,a)
	{		
	let tM = [25,25,17,17][Dif];
	let aM = atan2(y2-y1,x2-x1);

	let obj = CreateBasicEnemyA1(x1,y1,0,aM,400,100,type_fairy,fairy_blue,0);
	ObjMove_SetDestAtWeight(obj,x2,y2,40,6);
	let counterM = -1;	
	let switch = false;
	let beam = CreateLaserA1(x1,y1,6,aM,75,18,C_LASER,0,SHOT_AQUA);
	ObjShot_SetAutoDelete(beam,false);
		PlaySound("se_Laser",50);
	let dirA = dir;	
	if(tA%(2*tM) >= tM)
		{
		dirA*=-1;
		}	
	let n = 0;	
	let nA = [0,1,1,2][Dif];
	while(!Obj_IsDeleted(obj) && (switch == false || !IsBeyondClip(obj,64)))
		{
		counterM+=1;
		if((counterM+tA)%tM == 0 && !IsBeyondClip(obj,8))
			{
			CreateBulletA2(ObjMove_GetX(obj),ObjMove_GetY(obj),6,aM+dirA*a*5,-3/20,0,3,PELLET,6,1.125,SHOT_GREEN);
			dirA*=-1;
			}
		if(counterM == 120)
			{
			switch = true;
			ObjShot_SetAutoDelete(beam,true);
			}
		if((counterM == 120 || counterM == 210) && n < nA)
			{
			n+=1;
			CreateLaserA1(ObjMove_GetX(obj),ObjMove_GetY(obj),6,aM,75,18,C_LASER,0,SHOT_AQUA);
			PlaySound("se_Laser",40);
			}
		if(counterM == 120)
			{
			ObjMove_SetAngle(obj,90+dir*105);
			ObjMove_SetAcceleration(obj,1/30);
			ObjMove_SetMaxSpeed(obj,2.5);
			}
		yield;
		}
	ObjShot_SetAutoDelete(beam,true);
	Obj_Delete(obj);
	}

task CreateEnemyA3(x,y,dir)
	{	
	let tM = [[3,3,2,2][Dif],[1,1,8,8][Dif]];
	let spread = [2,3,3,4][Dif];
	let aM = 90+dir*45;

	let obj = CreateBasicEnemyA1(x,y,0,aM,2250,100,type_fairy,fairy_blue,0);
	ObjMove_SetDestAtWeight(obj,x-dir*96,y+48,30,6);
	let counterM = -1;	
	let switch = false;
	let switchA = true;

	let d = 24;
	let aa = dir*15;

	let dirA = -dir;

	while(!Obj_IsDeleted(obj) && (switch == false || !IsBeyondClip(obj,64)))
		{
		counterM+=1;
		if(counterM >= 75 && (counterM-75)%tM[0] == 0 && switchA == true)
			{
			PlaySound("se_Shot1",60);
			ascent(i in 0..spread)
				{
				let a = aM+i*360/spread+dirA*(floor((counterM-75)/tM[0])%tM[1])*(75/spread)/tM[1];
				let x = d*2*cos(a)*cos(aa)-d*sin(a)*sin(aa);
				let y = d*2*cos(a)*sin(aa)+d*sin(a)*cos(aa);
				let shot = CreateBulletA2(ObjMove_GetX(obj)+x,ObjMove_GetY(obj)+y,1.5,a,1/60,0,10,SCALE,6,1.125,SHOT_ORANGE);
				Obj_SetRenderPriority(shot,0.49);
				}
			}
		if(counterM >= 75 && floor((counterM-75)/tM[0])%tM[1] == tM[1]-1)
			{
			dirA*=-1;
			aM+=dir*255/spread;
			if(counterM >= 240 && IsBeyondClip(obj,-96))
				{
				switchA = false;
				}
			}
		if(counterM == 75)
			{
			ObjMove_SetAngle(obj,90+dir*105);
			ObjMove_SetAcceleration(obj,1/30);
			ObjMove_SetMaxSpeed(obj,1.125);
			}
		if(counterM == 120)
			{
			switch = true;
			}
		yield;
		}
	Obj_Delete(obj);
	}

task CreateEnemyA4(a,dir)
	{	
	let time =150;
	let scM = 36;
	let obj = CreateBasicEnemyA1(GetStgFrameWidth*0.5,GetStgFrameHeight*0.5-25,195/time,a,200,0,type_orb,orb_blue,0);
	ObjMove_SetAngularVelocity(obj,-dir*210/time);
	ObjEnemy_SetIntersect(obj,false);
	let c = -1;
	let aM = a-dir*110;
	while(!Obj_IsDeleted(obj) && !IsBeyondClip(obj,64))
		{
		c+=1;
		if(c <= time)
			{
			let sc = c*1/time;
			ObjRender_SetColorHSV(obj,0,0,125);
			ObjEnemy_SetScale(obj,sc*scM);
			}
		if(c == time)
			{
			ObjEnemy_SetIntersect(obj,true);
			ObjRender_SetColorHSV(obj,0,0,255);
			ObjEnemy_SetDamageRate(obj,50,50);
			ObjMove_SetAcceleration(obj,1/60);
			ObjMove_SetMaxSpeed(obj,2);	
			}
		if(c == time+60)
			{
			ObjMove_SetAngularVelocity(obj,0);		
			}
		if(c >= time && !IsBeyondClip(obj,0))
			{
			if((c-time)%5 == 0)
				{
				CreateBulletA1(ObjMove_GetX(obj),ObjMove_GetY(obj),1.5,aM+180,PELLET,6,1.2,SHOT_RED);
				}
			aM+=dir*1.75;
			}
		yield;
		}
	Obj_Delete(obj);
	}