#TouhouDanmakufu[Single]
#ScriptVersion[3]

#include "./functions.txt"

timer = 90;
life = 12000/3;

@Initialize
{
	objEnemy = ObjEnemy_Create(OBJ_ENEMY_BOSS);
	ObjEnemy_Regist(objEnemy);

	TEnemyWork;
	ObjEnemy_Render(objEnemy);
}

task TEnemyWork
{
	if(Dif <= 1)
		{
		TSpellName("Zhen \"Sprout, Like a Bud from a Seed\"");
		}
	else
		{
		TSpellName("Divinity \"Eternal As the Rock, Transient As the Flower");
		}
	SetBossAura(10,1,1,40);
	TTime;	
	ObjMove_SetDestAtWeight(objEnemy,GetStgFrameWidth/2,GetStgFrameHeight/2-120,15,5);
	loop(90){yield;}
	TLife(0,12,12,160/3,160/3,false);	
	let spread = [[4,6,6,6][Dif],26,8,[3,5,27,27][Dif],[270,270,135,90][Dif],[1,1,1,2][Dif],2];
	let sMA = [[1,1,1.75,1.75][Dif],0.25,2,[1,0.8,0.7,0.7][Dif],[-1,-1,1.05,1.05][Dif]];
	let rad = [32,32,64,64][Dif];
	ascent(i in 0..spread[0])
		{
		ascent(n in 0..spread[6])
			{
			let a = 90+i*360/spread[0]+n*(180-180/spread[0]);
			let d = 100+n*275;
			TNuke(enmx+d*cos(a),enmy+d*sin(a),d,a,-((i%2)*2-1)*(n*2-1)*0.35,a+n*180,-((i%2)*2-1)*(n*2-1)*sMA[3+n],(spread[0]-i)*7+10);
			}
		loop(7){yield;}
		}		
	loop(110){yield;}
	TSoundA;
	loop
		{
		TSound;
		ascent(i in 0..spread[3])
			{
			if(Dif >= 2)
				{
				let a = i*360/spread[3]+GetAngleToPlayer(objEnemy);
				CreateLaserA2(enmx+32*cos(a),enmy+32*sin(a),14,a,GetStgFrameHeight*1.5,16,30,C_LASER,60,SHOT_YELLOW);
				}
			else	
				{
				let a = GetAngleToPlayer(objEnemy)+(i-spread[3]*0.5+0.5)*135/spread[3];
				let shot = CreateBulletA1(enmx,enmy,0.875,a,LARGE,0,1,SHOT_YELLOW);
				TDel(shot);
				}
			}
		loop(spread[4]){yield;}
		}
	task TSoundA
		{		
		loop(180){yield;}
		loop
			{
			PlaySound("se_Shot1",60);
			loop(spread[2]){yield;}
			}
		}
	task TSound
		{
		PlaySound("se_LaserDelay",90);
		if(Dif <=1){return;}
		loop(60){yield;}
		PlaySound("se_Laser",60);
		}
	task TDel(shot)
		{
		let time = 25;	
		ObjShot_SetIntersection(shot,false);
		let aP = atan2(ObjMove_GetY(shot)-enmy,ObjMove_GetX(shot)-enmx);
		if((IsBeyondClip(shot,8) && cos(ObjMove_GetAngle(shot) - aP) < 0.5) || Obj_IsDeleted(objEnemy))
			{
			return;		
			}	
		let sc = ObjShot_GetScale(shot);
		descent(t in 0..time)
			{
			ObjRender_SetAlpha(shot,255*(1-t/time));
			t = (1+2*t/time);
			ObjRender_SetScaleXYZ(shot,sc*t,sc*t,0);
			if(Obj_IsDeleted(objEnemy)){break;}
			yield;
			}
		ObjShot_SetIntersection(shot,true);
		}
	task TNuke(xM,yM,d,aM,dir,aA,dirA,time)
		{
		let xE = enmx;
		let yE = enmy;
		ascent(i in 0..spread[1])
			{
			TShade(i*360/spread[1]);
			}	
		loop(110+time){yield;}
		let radA = rad*1.125;
		let nuke = CreateNukeA1(xM,yM,radA,8);
		ObjMove_SetAngle(nuke,aA);
		let male = CreateMaleA1(xM,yM,radA*1.25/8,aA,radA*1.25,radA*0.5,MALE,1,SHOT_RED);
		ascent(t in 0..8)
			{
			let d = t/7;
			ObjMove_SetPosition(male,xM+radA*d*0.675*cos(aA),yM+radA*d*0.675*sin(aA));
			if(Obj_IsDeleted(objEnemy)){break;}
			yield;
			}
		TDestroy;
		loop(42){yield;}
		TDestroy;
		descent(t in 0..40)
			{
			let sc = t*radA/40;
			ObjShot_SetScale(nuke,sc);
			if(Obj_IsDeleted(objEnemy)){break;}
			yield;
			}
		TDestroy;
		let aAA = 0;
		let c = -1;
		loop
			{
			if(aAA < 1)
				{
				aAA+=1/50;
				}
			aA += dirA*aAA;
			aM+=dir*aAA;
			xM = xE+d*cos(aM);
			yM = yE+d*sin(aM);
			c+=1;
			ObjMove_SetPosition(nuke,xM,yM);
			ObjMove_SetAngle(nuke,aA);
			ObjMove_SetPosition(male,xM+radA*0.675*cos(aA),yM+radA*0.675*sin(aA));	
			ObjStLaser_SetAngle(male,aA);
			if(c >= 90 && c%spread[2] == 0)
				{
				ascent(i in 0..spread[5])
					{
					let shot = CreateBulletA1(ObjMove_GetX(male)+rad*cos(aA),ObjMove_GetY(male)+rad*sin(aA),sMA[0]-i*sMA[1]/spread[5],aA+dir*i*sMA[2]/spread[5],SMALL,0,1,SHOT_RED);
					TDel(shot);
					}
				}
			yield;
			}
		task TShade(aB)
			{	
			let dE = GetDistance(xE,yE,xM,yM);
			let aE = atan2(yM-yE,xM-xE);	
			let timeE = 60;
			let shot = CreateBulletA1(xE,yE,0,0,AMULET,16,1.125,SHOT_GRAY);
			ObjShot_SetIntersection(shot,false);
			ObjShot_SetSpellResist(shot,true);
			ObjShot_SetAutoDelete(shot,false);
			ObjRender_SetAlpha(shot,135);
			ascent(t in 0..timeE+time)
				{
				let dB = (t/(timeE-1))^0.5;
				if(t >= timeE)
					{
					dB=1;
					}				
				aB+=0.5;
				let x = xE+dB*dE*cos(aE)+rad*2*dB*cos(aB);
				let y = yE+dB*dE*sin(aE)+rad*2*dB*sin(aB);
				ObjMove_SetPosition(shot,x,y);
				ObjMove_SetAngle(shot,aB+180);
				yield;
				}
			timeE = 50;
			descent(t in 0..timeE)
				{
				let dB = (t/(timeE-1))^0.75;				
				aB+=0.5;
				let x = xE+dE*cos(aE)+rad*2*dB*cos(aB);
				let y = yE+dE*sin(aE)+rad*2*dB*sin(aB);
				ObjMove_SetPosition(shot,x,y);
				ObjMove_SetAngle(shot,aB+180);
				yield;
				}		
			Obj_Delete(shot);
			}
		task TDestroy
			{
			if(Obj_IsDeleted(objEnemy))
				{
				Obj_Delete(male);
				ascent(t in 0..10)
					{
					ObjShot_SetScale(nuke,32*t/10);
					yield;
					}
				Obj_Delete(nuke);
				return;
				}
			}
		}

	function CreateNukeA1(x,y,rad,delay)
		{	
		PlaySound("se_Die5",100);
		let obj = [];
		let g = SHOT_PURPLE;
		let graph = [240,180,120,60,30,0,285];

		let scale = 0;

		let c = -1;

		ascent(i in 0..2)
			{
			obj = obj ~ [ObjPrim_Create(OBJ_SPRITE_2D)];
			if(i == 0)
				{
				ObjPrim_SetTexture(obj[i],GetCurrentScriptDirectory ~ "img/img_Donut.png");
				ObjSprite2D_SetDestRect(obj[i],-0.5,-0.5,1.5,1.5);
				ObjSprite2D_SetSourceRect(obj[i],0,0,512,512);
				}
			else
				{
				ObjPrim_SetTexture(obj[i],GetCurrentScriptDirectory ~ "img/img_Nuke.png");
				ObjSprite2D_SetDestRect(obj[i],0,0,1,1);
				ObjSprite2D_SetSourceRect(obj[i],0,0,256,256);
				}
			Obj_SetRenderPriority(obj[i],0.55);
			ObjRender_SetBlendType(obj[i],BLEND_ADD_ARGB);
			}
		let shot = CreateBulletA1(x,y,0,0,SMALL,0,rad,SHOT_RED);
		Obj_SetVisible(shot,false);
		ObjShot_SetAutoDelete(shot,false);
		ObjShot_SetSpellResist(shot,true);

		let counter = -1;
		TRender;
		return shot;
		task TRender
			{
			let gcA = 10;
			let gc = -1;
			while(!Obj_IsDeleted(shot))
				{
				c+=1;	
				if(scale < 1)
					{
					scale+=1/delay;
					}
				x=ObjMove_GetX(shot);
				y=ObjMove_GetY(shot);
				let scaleA = ObjShot_GetScale(shot);
				ascent(i in 0..length(obj))
					{
					ObjRender_SetPosition(obj[i],x,y,0);
					ObjRender_SetAngleZ(obj[i],ObjMove_GetAngle(shot)-1);
					}
				ObjRender_SetScaleXYZ(obj[0],scale*rad*2*(1+0.0005*cos(c*10)),scale*rad*2*(1+0.0005*cos(c*10)),0);
				ObjRender_SetScaleXYZ(obj[1],scale*scaleA*2*2,scale*scaleA*2*2,0);
				if(Obj_GetValueD(GetPlayerObjectID,"DAMAGE",0) == 0 && GetPlayerInvincibilityFrame <= 0 && scale >= 1 && ObjShot_GetIntersection(shot) == true && (GetObjectDistance(shot,GetPlayerObjectID) <= rad*0.9+GetPlayerGrazebox || GetObjectDistance(shot,GetPlayerObjectID) <= scaleA*2*0.9+GetPlayerGrazebox))
					{
					if(GetObjectDistance(shot,GetPlayerObjectID) <= rad*0.9+GetPlayerHitbox || GetObjectDistance(shot,GetPlayerObjectID) <= scaleA*2*0.9+GetPlayerHitbox)
						{
						Obj_SetValue(GetPlayerObjectID,"DAMAGE",1);
						}
					if(ObjLaser_GetGrazeEnable(shot) && gc%gcA == 0)
						{
						AddChapterGraze(1);
						AddGraze(1);
						PlaySound("se_Graze",100);
						}
					gc+=1;
					}
				if(Obj_IsDeleted(objEnemy))
					{
					ascent(i in 0..length(obj))
						{
						Obj_Delete(obj[i]);
						}
					}
				yield;
				}
			}
		task TDel(obj,n)
			{
			loop(40){yield;}
			let time = 20;
			let radM = rad;
			descent(t in 0..time)
				{
				ObjRender_SetScaleXYZ(obj,t*1/(time-1),t*1/(time-1),0);
				ObjRender_SetAlpha(obj,t*255/(time-1));
				if(n == 0)
					{
					rad = t*radM/time;
					}
				yield;
				}
			Obj_Delete(obj);
			}
		}

	function CreateMaleA1(x,y,speed,angle,dist,width,graph,delay,damage)
		{
		if(damage > SHOT_BLACK)
			{
			damage = SHOT_GRAY;
			}
		if(damage < SHOT_BLUE)
			{
			damage = SHOT_BLUE;
			}
			let shot = CreateStraightLaserA1(x,y,angle,0,width,INF,graph[damage],0);
			Obj_SetValue(shot,"LASER",true);
			ObjLaser_SetSpeed(shot,speed);
			ObjLaser_SetMaxLength(shot,dist);
			ObjShot_SetStrength(shot,damage);
			ObjShot_SetAutoDelete(shot,false);
			ObjShot_SetScale(shot,width);
			ObjLaser_SetDelay(shot,0);
			ObjMaleIntersectionRender(shot,INF);
			//ObjShot_SetIntersectionEnable(shot,false);
			return shot;
		}	

	task ObjMaleIntersectionRender(shot,del)
		{
		let delayM = ObjLaser_GetDelay(shot);
		let c = -1;
		let wA = 0.2;
		let dn = 0.2;
		let gcA = 20;
		let gc = -1;
		let alph = 1;
		while(!Obj_IsDeleted(shot))
			{
			c+=1;
	
			let x = ObjMove_GetX(shot);
			let y = ObjMove_GetY(shot);
			let d = ObjLaser_GetLength(shot);
			let a = ObjStLaser_GetAngle(shot);	
			let w = ObjShot_GetScale(shot)*0.5;
			let delay = ObjLaser_GetDelay(shot);
			if(delay != delayM)
				{
				delayM = delay;
				c = 0;
				}
	
			let ld = ObjLaser_GetMaxLength(shot);
			let ls = ObjLaser_GetSpeed(shot);
			let la = ObjLaser_GetAcceleration(shot);
			let lm = ObjLaser_GetMaxSpeed(shot);
	
			if((ls < lm && la > 0) || (ls > lm && la < 0))
				{
				ls+=la;
				}
			else if(la != 0)
				{
				ls = lm;
				}
			ObjLaser_SetSpeed(shot,ls);
	
			if(d < ld)
				{
				d+=ls;
				}
			if(d > ld)
				{
				d = ld;
				}
			ObjLaser_SetLength(shot,d);
	
			if(c >= del+delay)
				{
				if(w > 0.1)
					{
					w *= 0.875;
					alph*=0.925;
					ObjShot_SetScale(shot,w*2);
					ObjRender_SetAlpha(shot,alph*255);
					}
				else
					{
					Obj_Delete(shot);
					break;
					}
				}
	
			if(c >= delay)
				{
				let gcSwitch = false;
				if(wA < 1)
					{
					wA+=(1-wA)/4;
					}
				let xL = x+d*(1-dn)*cos(a);
				let yL = y+d*(1-dn)*sin(a);
				let dL = d*(1-dn)*0.65;
				if(Obj_GetValueD(GetPlayerObjectID,"DAMAGE",0) == 0 && GetPlayerInvincibilityFrame <= 0 && w >= 1 && ObjShot_GetIntersection(shot) == true && IsIntersected_Line_Circle(x,y,x+d*cos(a),y+d*sin(a),w*0.4*wA,GetPlayerX,GetPlayerY,GetPlayerGrazebox))
					{
					if(IsIntersected_Line_Circle(x+d*dn*cos(a),y+d*dn*sin(a),x+d*(1-dn)*cos(a),y+d*(1-dn)*sin(a),w*0.4*wA,GetPlayerX,GetPlayerY,GetPlayerHitbox))
						{
						Obj_SetValue(GetPlayerObjectID,"DAMAGE",1);
						}
					if(ObjLaser_GetGrazeEnable(shot) && gc%gcA == 0 && gcSwitch == false)
						{
						AddChapterGraze(1);
						AddGraze(1);
						PlaySound("se_Graze",100);
						}
					gc+=1;
					gcSwitch = true;
					}
				ascent(dir in 0..2)
					{
					dir = dir*2-1;
					let aL = a+dir*130;	
					if(Obj_GetValueD(GetPlayerObjectID,"DAMAGE",0) == 0 && GetPlayerInvincibilityFrame <= 0 && w >= 1 && ObjShot_GetIntersection(shot) == true && IsIntersected_Line_Circle(xL,yL,xL+dL*cos(aL),yL+dL*sin(aL),w*0.3*wA,GetPlayerX,GetPlayerY,GetPlayerGrazebox))
						{
						if(IsIntersected_Line_Circle(xL,yL,xL+dL*cos(aL),yL+dL*sin(aL),w*0.3*wA,GetPlayerX,GetPlayerY,GetPlayerHitbox))
							{	
							Obj_SetValue(GetPlayerObjectID,"DAMAGE",1);
							}
						if(ObjLaser_GetGrazeEnable(shot) && gc%gcA == 0 && gcSwitch == false)
							{
							AddChapterGraze(1);
							AddGraze(1);
							PlaySound("se_Graze",100);
							}
						if(gcSwitch == false)
							{
							gc+=1;
							gcSwitch = true;
							}
						}		
					}
				if(gc%gcA > 0)
					{
					gc+=1;
					}	
				}
			if(wA < 0.9 || (c >= del+delay && w < 3))
				{
				ObjShot_SetIntersectionEnable(shot,false);
				}
			else
				{
				ObjShot_SetIntersectionEnable(shot,true);
				}
			ObjLaser_SetRenderWidth(shot,w*2*4*wA);
			yield;
			}
		}

}