#include"./lib/lib_shot/shot_const.txt"
#include"./lib/lib_sound/_PathSound.txt"
#include"./lib/lib_img/_PathImage.txt"
#include"./function.txt"

let BossObj;
let BossObjX = 0;
let BossObjY = 0;

let BossAlpha = 255;
let hitbox = [64,54];
let imgBossObj 	= bossSprite;

let bossHitbox = true;
let damage = 0;
let life = 4000;
let alive = true;

let objScene = GetEnemyBossSceneObjectID();

@Initialize 
{
	SetAutoDeleteObject	(true);
	BossObj = ObjEnemy_Create	(OBJ_ENEMY_BOSS);
	ObjEnemy_Regist				(BossObj);
	ObjRender_SetPosition		(BossObj,320,120,0);
	mainTask;
} 

@Event
{
	alternative(GetEventType())
	case(EV_REQUEST_LIFE)
	{
		SetScriptResult(life);
	}
}

@MainLoop 
{
	ObjEnemy_SetDamageRate	(BossObj,damage,damage);
	ObjRender_SetAlpha		(BossObj,BossAlpha);
	BossObjX = ObjMove_GetX	(BossObj);
	BossObjY = ObjMove_GetY	(BossObj);
	if(bossHitbox == true)
	{
		ObjEnemy_SetIntersectionCircleToShot(BossObj,BossObjX,BossObjY,hitbox[0]/2);
		ObjEnemy_SetIntersectionCircleToPlayer(BossObj,BossObjX,BossObjY,hitbox[1]/2);
	}
	if(ObjEnemy_GetInfo(BossObj, INFO_LIFE) > 0){alive = true;}
	if(ObjEnemy_GetInfo(BossObj, INFO_LIFE) <= 0){alive = false;}
	yield;
} 

@Finalize 
{ 
} 

task mainTask
{
	spriteIdle(BossObj,GetCommonData("bgModeTime",0),imgBossObj,1);
	SetCommonData("bgMode",1);
	loop(GetCommonData("bgModeTime",0)){yield;}
	magicCircle;
	enemyMarker(BossObj);
	ObjEnemyBossScene_SetSpellTimer(objScene,3600);
	spawnShapes;
	mainMove;
	TEnd;
}

task magicCircle
{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture			(obj,sfxMagicCircle);
	ObjSprite2D_SetSourceRect	(obj,0,0,512,512);
	ObjSprite2D_SetDestCenter	(obj);
	ObjRender_SetColor			(obj,240,60,60);
	ObjRender_SetBlendType		(obj,BLEND_ADD_ARGB);
	let c = 0.5;
	let ang = rand(0,360);
	visibility;
	task visibility
	{
		let alpha = 0;
		while(alive == true)
		{
			if(alpha < 240 && damage > 0){alpha += 4;}
			ObjRender_SetAlpha(obj,alpha);
			yield;
		}
		while(alpha > 0)
		{
			alpha -= 4;
			ObjRender_SetAlpha(obj,alpha);
		}
		Obj_Delete(obj);
	}
	let mm = 1;
	while(!Obj_IsDeleted(obj))
	{
		loop(60)
		{
			c += 1/60*mm;
			ObjRender_SetScaleXYZ	(obj,(128/512)*(0.8+c*0.2/0.5),128/512*(0.8+c*0.2/0.5),1);
			ObjRender_SetAngleZ		(obj,ang);
			ObjRender_SetPosition	(obj,BossObjX,BossObjY,0);
			ang += 6 *c;
			yield;
		}
		mm *= -1;
	}
}

task TEnd
{
	while(alive == true){yield;}
	SetCommonData("autoSnap",true);
	bossHitbox = false;
	damage = 0;
	let ang = -(atan2(BossObjY-120,BossObjX-320))-90;
	let spd = GetDistance(320,120,BossObjX,BossObjY)/60;
	let sp = spd;
	let r = sp * 120;
	spriteIdle(BossObj,120,imgBossObj,1);
	if(BossObjX + r * sin(ang) < BossObjX-16)	{spriteHold(BossObj,120,imgBossObj,0,1);} // Going Left
	if(BossObjX + r * sin(ang) > BossObjX+16)	{spriteHold(BossObj,120,imgBossObj,1,1);} // Going Right
	let c = 0;
	loop(120)
	{
		c += 1/180;
		DeleteShotInCircle(TYPE_SHOT,TYPE_FADE,BossObjX,BossObjY,1280 * c);
		ObjMove_SetDestAtSpeed(BossObj,BossObjX+r*sin(ang),BossObjY+r*cos(ang),sp);
		sp -= spd/120;
		yield;
	}
	spriteIdle(BossObj,60,imgBossObj,1);
	loop(60)
	{
		c += 1/180;
		DeleteShotInCircle(TYPE_SHOT,TYPE_FADE,BossObjX,BossObjY,1280 * c);
		yield;
	}
	Obj_Delete(BossObj);
	CloseScript(GetOwnScriptID());
}

task move(x,y,time)
{
	let ang = -(atan2(BossObjY-y,BossObjX-x))-90;
	let spd = GetDistance(x,y,BossObjX,BossObjY)/(time/2);
	let sp = spd;
	let r = sp * time;
	if(BossObjX + r * sin(ang) < BossObjX && alive == true)	{spriteHold(BossObj,time,imgBossObj,0,1);} // Going Left
	if(BossObjX + r * sin(ang) >= BossObjX && alive == true){spriteHold(BossObj,time,imgBossObj,1,1);} // Going Right
	loop(time)
	{
		if(alive == true){ObjMove_SetDestAtSpeed(BossObj,BossObjX+r*sin(ang),BossObjY+r*cos(ang),sp);}
		sp -= spd/time;
		yield;
	}
	ObjMove_SetSpeed(BossObj,0);
}

task swingMove(x,y)
{
	let r = [0,0];
	let ang = [0,0];
	if(BossObjX > 320)
	{
		if(alive == true){spriteHold(BossObj,120,imgBossObj,0,1);}
		ang[0] = -(atan2(y-BossObjY,x-BossObjX))-90;
		r[0] = GetDistance(x,y,BossObjX,BossObjY);
		ang[1] = -(atan2(y-180,x-140))-90;
		r[1] = GetDistance(x,y,140,180);
	}
	if(BossObjX < 320)
	{
		if(alive == true){spriteHold(BossObj,120,imgBossObj,1,1);}
		ang[0] = -(atan2(y-BossObjY,x-BossObjX))-90;
		r[0] = GetDistance(x,y,BossObjX,BossObjY);
		ang[1] = -(atan2(y-180,x-500))-90;
		r[1] = GetDistance(x,y,500,180);
	}
	let angDif = ang[1]-ang[0];
	let rDif = r[1]-r[0];
	loop(120)
	{
		ang[0] = ang[0] + angDif/120;
		r[0] = r[0] + rDif/120;
		if(alive == true){ObjRender_SetPosition(BossObj,x+r[0]*sin(ang[0]),y+r[0]*cos(ang[0]),0);}
		yield;
	}
}

task mainMove
{
	let wave = 1;
	while(alive == true)
	{
		spriteIdle(BossObj,60,imgBossObj,1);loop(60){yield;}
		move(380,90,60);loop(60){yield;}
		if(alive == true && wave > 1)
		{
			playSE(seShot2,80);
			createShotA2ball(BossObjX,BossObjY,2.1,60,-0.01,0,0,180,-1);
		}
		move(410,60,60);loop(60){yield;}
		swingMove(0,0);loop(120){yield;}
		spriteIdle(BossObj,60,imgBossObj,1);loop(60){yield;}
		move(200,150,60);loop(60){yield;}
		if(alive == true && wave > 1)
		{
			playSE(seShot2,80);
			createShotA2ball(BossObjX,BossObjY,1.8,105,-0.01,0,0,180,1);
		}
		move(260,180,60);loop(60){yield;}
		move(320,120,60);loop(60){yield;}
		spriteIdle(BossObj,60,imgBossObj,1);loop(60){yield;}
		if(damage < 100){damage = 100;}
		spriteIdle(BossObj,60,imgBossObj,1);loop(60){yield;}
		move(260,90,60);loop(60){yield;}
		if(alive == true && wave > 1)
		{
			playSE(seShot2,80);
			createShotA2ball(BossObjX,BossObjY,2.1,120,-0.01,0,0,180,1);
		}
		move(230,60,60);loop(60){yield;}
		swingMove(640,0);loop(120){yield;}
		spriteIdle(BossObj,60,imgBossObj,1);loop(60){yield;}
		move(440,150,60);loop(60){yield;}
		if(alive == true && wave > 1)
		{
			playSE(seShot2,80);
			createShotA2ball(BossObjX,BossObjY,1.8,75,-0.01,0,0,180,-1);
		}
		move(380,180,60);loop(60){yield;}
		move(320,120,60);loop(60){yield;}
		spriteIdle(BossObj,60,imgBossObj,1);loop(60){yield;}
		wave ++;
	}
}

task spawnShapes
{
	while(alive == true)
	{
		spawn(1);
		loop(600){yield;}
		spawn(-1);
		loop(600){yield;}
	}
	
	task spawn(m)
	{
		let objC = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture			(objC,sfxShapes);
		ObjSprite2D_SetSourceRect	(objC,1,515,513,1027);
		ObjSprite2D_SetDestCenter	(objC);
		ObjRender_SetColor			(objC,240,240,90);
		ObjRender_SetScaleXYZ		(objC,14/512,14/512,1);
		spin(objC);
		visibility(objC);
		
		let objT = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture			(objT,sfxShapes);
		ObjSprite2D_SetSourceRect	(objT,515,1,1027,513);
		ObjSprite2D_SetDestCenter	(objT);
		ObjRender_SetColor			(objT,240,105,105);
		ObjRender_SetScaleXYZ		(objT,16/512,16/512,1);
		spin(objT);
		visibility(objT);
		
		let objS = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture			(objS,sfxShapes);
		ObjSprite2D_SetSourceRect	(objS,1,1,513,513);
		ObjSprite2D_SetDestCenter	(objS);
		ObjRender_SetColor			(objS,90,240,240);
		ObjRender_SetScaleXYZ		(objS,12/512,12/512,1);
		spin(objS);
		visibility(objS);
		
		task spin(obj)
		{
			let ang = rand(0,360);
			while(!Obj_IsDeleted(obj))
			{
				ObjRender_SetAngleZ	(obj,ang);
				ang += 3 * m;
				yield;
			}
		}
		
		task visibility(obj)
		{
			let timer = 240;
			let alpha = 0;
			loop(60)
			{
				alpha += 255 / 60;
				ObjRender_SetAlpha(obj,alpha);
				if(alive == true){yield;}
			}
			loop(timer){if(alive == true){yield;}}
			while(alpha > 0)
			{
				alpha -= 255 / 60;
				ObjRender_SetAlpha(obj,alpha);
				yield;
			}
		}
		
		let c = 0;
		let ang = rand(0,360);
		loop(180)
		{
			c += 1/180;
			ObjRender_SetPosition(objC,BossObjX+48*c*sin(ang),BossObjY+24*c*cos(ang),0);
			ObjRender_SetPosition(objT,BossObjX+48*c*sin(ang+180*m),BossObjY+24*c*cos(ang+180*m),0);
			ObjRender_SetPosition(objS,BossObjX+60*c*sin(-ang-180*m),BossObjY+30*c*cos(-ang-180*m),0);
			ang += 12*(1-c)*m;
			ang = ang%360;
			yield;
		}
		let cc = 3;
		let d = 30;
		loop(120)
		{
			ObjRender_SetPosition(objC,BossObjX+48*c*sin(ang),BossObjY+24*c*cos(ang),0);
			ObjRender_SetPosition(objT,BossObjX+48*c*sin(ang+180*m),BossObjY+24*c*cos(ang+180*m),0);
			ObjRender_SetPosition(objS,BossObjX+60*c*sin(-ang-180*m),BossObjY+30*c*cos(-ang-180*m),0);
			if(cc%5 == 0 && alive ==true)
			{
				playSE(seShot1,20);
				let pos = [ObjRender_GetX(objC),ObjRender_GetY(objC)];
				createShotA1flower(pos[0],pos[1],0.3,-ang,SMALL_YELLOW,180,m);
			}
			if(cc%2 == 0 && alive ==true)
			{
				playSE(seShot0,10);
				let pos = [ObjRender_GetX(objT),ObjRender_GetY(objT)];
				createShotA2(pos[0],pos[1],4.2,-ang+180*m,-0.18,1.5,SMALL_RED,d+5);
				createShotA2(pos[0],pos[1],4.2,-ang+180*m,-0.2,1.2,SMALL_RED,d+5);
				createShotA2(pos[0],pos[1],4.2,-ang+180*m,-0.22,0.9,SMALL_RED,d+5);
			}
			if(cc%2 == 0 && alive ==true)
			{
				let pos = [ObjRender_GetX(objS),ObjRender_GetY(objS)];
				createShotA2(pos[0],pos[1],6.3,ang-180*m,-0.3,1.8,DOT_PURPLE,d+10);
				createShotA2(pos[0],pos[1],6.3,ang-180*m,-0.32,1.5,DOT_PURPLE,d+10);
				createShotA2(pos[0],pos[1],6.3,ang-180*m,-0.34,1.2,DOT_PURPLE,d+10);
				createShotA2(pos[0],pos[1],6.3,ang-180*m,-0.36,0.9,DOT_PURPLE,d+10);
			}
			d += 30/120;
			ang += 12*m;
			ang = ang%360;
			cc ++;
			yield;
		}
		loop(60)
		{
			c -= 1/60;
			ObjRender_SetPosition(objC,BossObjX+48*c*sin(ang),BossObjY+24*c*cos(ang),0);
			ObjRender_SetPosition(objT,BossObjX+48*c*sin(ang+180*m),BossObjY+24*c*cos(ang+180*m),0);
			ObjRender_SetPosition(objS,BossObjX+60*c*sin(-ang-180*m),BossObjY+30*c*cos(-ang-180*m),0);
			ang += 12*(1-c)*m;
			ang = ang%360;
			yield;
		}
		Obj_Delete(objC);
		Obj_Delete(objT);
		Obj_Delete(objS);
	}
}

task createShotA2(x,y,s,ang,acc,maxs,st,d)
{
	loop(d-30){yield;}
	let obj = CreateShotA2(x,y,s,ang,acc,maxs,st,0);
	ObjRender_SetAlpha				(obj,0);
	ObjShot_SetIntersectionEnable	(obj,false);
	let alpha = 0;
	while (alpha < 255 && !Obj_IsDeleted(obj))
	{
		alpha += 255/30;
		ObjRender_SetAlpha(obj,alpha);
		yield;
	}
	ObjShot_SetIntersectionEnable	(obj,true);
}

task createShotA2ball(x,y,s,ang,acc,maxs,st,d,mspin)
{
	let obj = CreateShotA2(x,y,s,ang,acc,maxs,st,0);
	ObjRender_SetAlpha				(obj,0);
	ObjShot_SetIntersectionEnable	(obj,false);
	
	if(!Obj_IsDeleted(obj) && alive == true)
	{
		let ag = 0;
		loop(18)
		{
			createShotA1cinder(x,y,0.9,ag,ORB_RED,d,ag,12);
			createShotA1cinder(x,y,1.2,ag,ORB_RED,d,ag+10,28);
			createShotA1cinder(x,y,1.5,ag,LARGE_RED,d,ag,32);
			createShotA1cinder(x,y,1.8,ag,LARGE_RED,d,ag+10,34);
			ag += 20;
		}
		Glow(128);
	}
	task Glow(xyz)
	{
		let objGlow = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture			(objGlow,sfxGlow);
		ObjSprite2D_SetSourceRect	(objGlow,0,0,512,512);
		ObjSprite2D_SetDestCenter	(objGlow);
		ObjRender_SetColor			(objGlow,240,60,60);
		ObjRender_SetBlendType		(objGlow,BLEND_ADD_ARGB);
		let alpha = 0;
		while(!Obj_IsDeleted(obj))
		{
			if(alpha < 240){alpha += 4;}
			xyz += 256/d;
			ObjRender_SetAlpha(objGlow,alpha);
			ObjRender_SetScaleXYZ(objGlow,xyz/512,xyz/512,1);
			ObjRender_SetPosition(objGlow,ObjMove_GetX(obj),ObjMove_GetY(obj),0);
			yield;
		}
		while(alpha > 0)
		{
			alpha -= 4;
			ObjRender_SetAlpha(objGlow,alpha);
			yield;
		}
		Obj_Delete(objGlow);
	}
	loop(d){yield;}
	if(!Obj_IsDeleted(obj) && alive == true){playSE(seShiny0,60);}
	Obj_Delete(obj);
	
	task createShotA1cinder(x,y,s,ang,st,d,aa,r)
	{
		let objAdd = CreateShotA1(x,y,s,ang,st,0);
		ObjRender_SetAlpha				(objAdd,0);
		ObjShot_SetIntersectionEnable	(objAdd,false);
		ObjRender_SetBlendType			(objAdd,BLEND_ADD_ARGB);
		let alpha = 0;
		let c = 0;
		loop(d)
		{
			c += 1/d;
			alpha += 255/d;
			ObjRender_SetAlpha(objAdd,alpha);
			let pos = [ObjMove_GetX(obj)+r*c*sin(ObjMove_GetAngle(obj)+aa),ObjMove_GetY(obj)+r*c*cos(ObjMove_GetAngle(obj)+aa)];
			ObjMove_SetPosition(objAdd,pos[0],pos[1]);
			let agg = atan2(ObjMove_GetY(obj)-ObjRender_GetY(objAdd),ObjMove_GetX(obj)-ObjRender_GetX(objAdd))+180;
			ObjMove_SetAngle(objAdd,agg);
			aa += mspin*(1-c)*6;
			yield;
		}
		ObjShot_SetIntersectionEnable	(objAdd,true);
	}
}

task createShotA1flower(x,y,s,ang,st,d,mspin)
{
	let obj = CreateShotA1(x,y,s,ang,st,0);
	ObjRender_SetAlpha				(obj,0);
	ObjShot_SetIntersectionEnable	(obj,false);
	
	if(!Obj_IsDeleted(obj) && alive == true)
	{
		let ag = 0;
		loop(5){createShotA2petal(x,y,0,ag,0.005,2.4,PELLET_PURPLE,d,ag+36,8);ag += 72;}
		loop(5){createShotA2petal(x,y,0,ag,0.005,1.2,PELLET_RED,d,ag,6);ag += 72;}
		Glow(64);
	}
	task Glow(xyz)
	{
		let objGlow = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture			(objGlow,sfxGlow);
		ObjSprite2D_SetSourceRect	(objGlow,0,0,512,512);
		ObjSprite2D_SetDestCenter	(objGlow);
		ObjRender_SetColor			(objGlow,240,60,60);
		ObjRender_SetBlendType		(objGlow,BLEND_ADD_ARGB);
		let alpha = 0;
		while(!Obj_IsDeleted(obj))
		{
			if(alpha < 60){alpha ++;}
			xyz += 128/d;
			ObjRender_SetAlpha(objGlow,alpha);
			ObjRender_SetScaleXYZ(objGlow,xyz/512,xyz/512,1);
			ObjRender_SetPosition(objGlow,ObjMove_GetX(obj),ObjMove_GetY(obj),0);
			yield;
		}
		while(alpha > 0)
		{
			alpha --;
			ObjRender_SetAlpha(objGlow,alpha);
			yield;
		}
		Obj_Delete(objGlow);
	}
	loop(d){yield;}
	if(alive == true && !Obj_IsDeleted(obj)){playSE(seShiny1,30);}
	ObjShot_FadeDelete(obj);
	
	task createShotA2petal(x,y,s,ang,acc,maxs,st,d,aa,r)
	{
		let objAlp = CreateShotA2(x,y,s,ang,acc,maxs,st,0);
		ObjRender_SetAlpha				(objAlp,0);
		ObjShot_SetIntersectionEnable	(objAlp,false);
		let alpha = 0;
		let c = 0;
		loop(d)
		{
			if(c < 1){c += 1/(d-30);}
			if(alpha < 255){alpha += 255/(d-60);if(alpha >= 255){ObjShot_SetIntersectionEnable	(objAlp,true);}}
			ObjRender_SetAlpha(objAlp,alpha);
			let pos = [ObjMove_GetX(obj)+r*c*sin(ObjMove_GetAngle(obj)+aa),ObjMove_GetY(obj)+r*c*cos(ObjMove_GetAngle(obj)+aa)];
			ObjMove_SetPosition(objAlp,pos[0],pos[1]);
			let agg = atan2(ObjMove_GetY(obj)-ObjRender_GetY(objAlp),ObjMove_GetX(obj)-ObjRender_GetX(objAlp))+180;
			ObjMove_SetAngle(objAlp,agg);
			aa += mspin*(1-c)*10;
			yield;
		}
	}
}
