
#ScriptVersion[3]
#Title["FinalSpell"]
#Text["FinalSpell"]
#Player[DEFAULT]
#System["./system/Default_System.txt"]
#Background["./BG.txt"]
#Player["./MoF_Reimu/Reimu.txt"]
#include"./Functions/Index.txt"
#include"./SetBoss.txt"
#include"./Shot/AllStarShot_Const.dnh"
#include"./system/Default_Effect.Txt"


let objBoss;
let GCSD=GetCurrentScriptDirectory~"";
let enemy;
let bSpell=false;
let stgx=GetStgFrameWidth()/2;
let stgy=GetStgFrameHeight()/2;
let idle = true;
let atk = false;
let fog = 0;
let action = false;
let objScene=GetEnemyBossSceneObjectID();
let soularray = [];
let count = 0;
let a_count = 0;
let totalangle = 0;
let mainangle = 0;
let cangle = 0;
let dienumber = 0;
let plusarray = [12,18,30,60,180];
let killerappear = 0;
let plusangle = 0;
let r = 0;
let immune = 0;
@Initialize
{
Sound(GCSD ~ "Little.mp3");
SetBoss("?",true);
}

@MainLoop
{
	/*ObjEnemy_SetIntersectionCircleToPlayer(objBoss,ObjMove_GetX(objBoss),ObjMove_GetY(objBoss),25);
	ObjEnemy_SetIntersectionCircleToShot(objBoss,ObjMove_GetX(objBoss),ObjMove_GetY(objBoss),26);
	if(GetCommonData("IsFan",false)==true){
	ObjEnemy_SetIntersectionCircleToShot(objBoss,ObjMove_GetX(objBoss)-90,ObjMove_GetY(objBoss),26*3.5);
	ObjEnemy_SetIntersectionCircleToShot(objBoss,ObjMove_GetX(objBoss)+90,ObjMove_GetY(objBoss),26*3.5);
	}*/
	yield;

}

@Event
{
	alternative(GetEventType())
	case(EV_REQUEST_LIFE)
	{
		SetScriptResult(3000);
	}
	case(EV_REQUEST_TIMER)
	{
		SetScriptResult(101);
	}
		case(EV_REQUEST_SPELL_SCORE)
	{
		SetScriptResult(35000000);
	}
		case(EV_PLAYER_REBIRTH)
	{
		if(GetPlayerLife>=0)
		{
			dienumber = 0;
			ascent(i in 0..length(soularray))
			{
			Obj_SetValue(soularray[i],"alive",1);
			}
			count = 0;
			r = 0;
		}
	}
}

//----------------------------------------------------
task mainTask{
	ObjMove_SetPosition(objBoss,stgx,120);
	SetCommonData("YuyukoIllusion",2);
	PlaySound("Charge3",100,0);
	RayCharge("WHITE",2,60);
	RayCharge("WHITE",2,60);
	Sound(GCSD ~ "Demetori.mp3");
	wait(120);
	PlaySound("Boon1",100,0);
	SetCommonData("YuyukoIllusion",1);
	wait(170);
	PlaySound("Charge5",100,0);
	ShinkiCharge(45,"RED");
	wait(60);
	Cutin("Life Limit \"Ticket to the Netherworld\"",15,"SHINKI");
	ObjEnemyBossScene_StartSpell(objScene);
	SetCommonData("FanAtYuyuko",2);
	if(GetCommonData("IsFan",false)==true)
	{
		CallFan(0);
	}
	else
	{
		CallFan(1);
	}
	wait(60);
	TShot1;
	wait(2400);
	DamageRateAtFrame(57,10,180);
	}
//----------------------------------------------------

task TShot1
{	
	PlaySound("Charge3",100,0);
	RayCharge("WHITE",2,60);
	RayCharge("WHITE",2,60);
	wait(120);
	//YuyukoMainAttack;
	
	FlashScreen;
	FixedPlayer;
	MagicCirclePlayer(0);
	wait(60);
	ShinkiCharge(45,"WHITE");
	PlaySound("Charge5",95,0);
	wait(60);
	FireEffect;
	wait(150);
	CreateSoul;
}

task CreateSoul
{
	ascent(i in 0..5)
	{
		let core = CreateShotA1(GetPlayerX+0*cos(i*72),GetPlayerY+0*sin(i*72),0,0,701,12);
		ObjShot_SetAutoDelete(core,false);
		ObjShot_SetSpellResist(core,true);
		Obj_SetValue(core,"num",i);
		Obj_SetValue(core,"alive",1);
		soularray = soularray ~ [core];
	}
	FamiliarHandler;
	while(ObjEnemy_GetInfo(objBoss,INFO_LIFE)>0)
	{
		a_count = 0;
		ascent(i in 0..length(soularray))
		{
			if(Obj_GetValueD(soularray[i],"alive",0)==1)
			{
				a_count++;
			}
		}
		totalangle = 72;
		ascent(i in 0..length(soularray))
		{
			if(count<90)
			{
				r = 75*sin(count);
			}
			mainangle = i*totalangle+cangle+plusangle;
			ObjMove_SetPosition(soularray[i],GetPlayerX+r*cos(mainangle),GetPlayerY+r*sin(mainangle));
			if(Obj_GetValueD(soularray[i],"alive",0)==0)
			{
				Obj_SetVisible(soularray[i],0);
			}
			else
			{
				Obj_SetVisible(soularray[i],1);
				if(count%2==0){TrailBullet(ObjMove_GetX(soularray[i]),ObjMove_GetY(soularray[i]),701);}
			}
		}
		cangle += 2;
		if(killerappear==0 && GetPlayerState==STATE_NORMAL && immune==0){count++;}
		if(count%90==0 && killerappear==0 && dienumber<5 && GetPlayerLife>=0 && immune==0)
		{
			SoulExplosion;
			count++;
		}
		yield;
	}
	task FamiliarHandler
	{
		wait(180);
		ChargeSet("WHITE");
		wait(60);
		ascent(i in 0..4)
		{
			SpawnFam(GetEnemyX,GetEnemyY,1.5,i*90+45,855,150);
		}
		wait(240);
		ChargeSet("RED");
		wait(60);
		ascent(i in 0..6)
		{
			SpawnFam(GetEnemyX,GetEnemyY,1.5,i*60+15,856,150);
		}
		wait(300);
		ChargeSet("BLUE");
		wait(60);
		ascent(i in 0..6)
		{
			SpawnFam(GetEnemyX,GetEnemyY,1.5,i*60+15,858,150);
		}
		wait(300);
		ChargeSet("YELLOW");
		wait(60);
		ascent(i in 0..6)
		{
			SpawnFam(GetEnemyX,GetEnemyY,1.5,i*60+15,861,150);
		}
		wait(300);
		ChargeSet("GREEN");
		wait(60);
		ascent(i in 0..6)
		{
			SpawnFam(GetEnemyX,GetEnemyY,1.5,i*60+15,860,150);
		}
		wait(300);
		ChargeSet("RED");
		wait(60);
		ascent(i in 0..6)
		{
			SpawnFam(GetEnemyX,GetEnemyY,1.5,i*60+15,856,150);
		}
		wait(60);
		while(length(GetIntersectionRegistedEnemyID)>0 || IsPlayerSpellActive){yield;}
			YuyukoMainAttack;
	}
		task SpawnFam(fx,fy,v,angle,bcolor,life)
		{
			let ene = fam(fx,fy,life,0.7,0,true);
			let fcount = 0;
			let checkshot = 1;
			let way = (round(rand(0,1))-0.5)*2;
			ObjMove_AddPatternA1(ene,0,v,angle);
			CheckBounce;
			while(ObjEnemy_GetInfo(ene,INFO_LIFE)>0)
			{
				fcount++;
				if(fcount%3==0)
				{
					TrailBullet(ObjMove_GetX(ene),ObjMove_GetY(ene),bcolor);
				}
				if(ObjMove_GetX(ene)<-60 || ObjMove_GetX(ene)>384+60 || ObjMove_GetY(ene)<-60 || ObjMove_GetY(ene)>448+60)
				{
					checkshot = 0;
					Obj_Delete(ene);
				}
				if(bcolor==856 && fcount%60==0)
				{
					let bangle = rand(0,30);
					PlaySound("Shot6",100,0);
					ascent(i in 0..6+Level*6)
					{
						TShotA2(ObjMove_GetX(ene),ObjMove_GetY(ene),5,i*360/(6+Level*6)+bangle,-5/30,5/4,51,8);
					}
				}
				if(bcolor==858 && fcount%(8-Level*2)==0)
				{
					PlaySound("Shot6",100,0);
					TShotA2(ObjMove_GetX(ene),ObjMove_GetY(ene),4,fcount*1.7*way,-4/30,4/4,55,8);
				}
				if(bcolor==860 && fcount%30==0)
				{
					PlaySound("Shot6",100,0);
					ascent(j in 0..3+Level*3)
					{
						let bv = 3+j/2;
						TShotA2(ObjMove_GetX(ene),ObjMove_GetY(ene),bv,fcount*2.7*way,-bv/30,bv/3,59,8);
					}
				}
				if(bcolor==861 && fcount%45==0)
				{
					PlaySound("Shot6",100,0);
					ascent(j in 0..2+Level*2)
					{
						let bangle = GetAtanAngle(ene,GetPlayerObjectID);
						let bv = 4+j/2;
						TShotA2(ObjMove_GetX(ene),ObjMove_GetY(ene),bv,bangle,-bv/30,bv/3,62,8);
					}
				}
				yield;
			}
			if(dienumber>0 && checkshot==1)
			{
				//ObjEnemy_SetLife(objBoss,ObjEnemy_GetInfo(objBoss,INFO_LIFE)-40);
				dienumber--;
				SoulReborn(soularray[dienumber],dienumber);
			}
			
			task CheckBounce // 2 times
			{
				while(ObjMove_GetX(ene)>0 && ObjMove_GetX(ene)<384 && ObjMove_GetY(ene)>0 && ObjMove_GetY(ene)<448)
				{
					yield;
				}
				if(ObjMove_GetX(ene)<0 || ObjMove_GetX(ene)>384){ObjMove_SetAngle(ene,180-ObjMove_GetAngle(ene));}
				if(ObjMove_GetY(ene)<0 || ObjMove_GetY(ene)>448){ObjMove_SetAngle(ene,-ObjMove_GetAngle(ene));}
				yield;
				while(ObjMove_GetX(ene)>0 && ObjMove_GetX(ene)<384 && ObjMove_GetY(ene)>0 && ObjMove_GetY(ene)<448)
				{
					yield;
				}
				if(ObjMove_GetX(ene)<0 || ObjMove_GetX(ene)>384){ObjMove_SetAngle(ene,180-ObjMove_GetAngle(ene));}
				if(ObjMove_GetY(ene)<0 || ObjMove_GetY(ene)>448){ObjMove_SetAngle(ene,-ObjMove_GetAngle(ene));}
			}
		}
	task SoulExplosion
	{
		SCharge02(2.5,60,128,0,128);
		wait(60);
		if(immune==0)
		{
			Obj_SetValue(soularray[dienumber],"alive",0);
			PlaySound("Enep2",90,0);
			TExpan(ObjMove_GetX(soularray[dienumber]),ObjMove_GetY(soularray[dienumber]),5,30,255,255,255);
			dienumber++;
			if(dienumber==5)
			{
				KillPlayer;
			}
		}
	}
	
	task SoulReborn(target,round)
	{
		TExpan(ObjMove_GetX(target),ObjMove_GetY(target),5,30,0,255,255);
		Obj_SetValue(target,"alive",1);
		PlaySound("Eff5",85,0);
	}
	
	task TrailBullet(tx,ty,color)
	{
		let obj = TShotA1(tx,ty,0,0,color,0);
		ObjShot_SetAutoDelete(obj,false);
		ObjShot_SetSpellResist(obj,true);
		ObjShot_SetIntersectionEnable(obj,false);
		descent(i in 0..15)
		{
			ObjRender_SetScaleXYZ(obj,i/15,i/15,i/15);
			yield;
		}
		Obj_Delete(obj);
	}
	
	task KillPlayer
	{
		let killer = CreateShotA1(GetPlayerX,GetPlayerY,0,0,201,0);
		killerappear = 1;
		Obj_SetVisible(killer,false);
		ObjShot_SetAutoDelete(killer,false);
		ObjShot_SetSpellResist(killer,true);
		while(GetPlayerState==STATE_NORMAL || GetPlayerState==STATE_HIT)
		{
			ObjMove_SetPosition(killer,GetPlayerX,GetPlayerY);
			yield;
		}
		dienumber = 0;
		wait(GetPlayerDownStateFrame);
		ascent(i in 0..length(soularray))
		{
			Obj_SetValue(soularray[i],"alive",1);
		}
		Obj_Delete(killer);
		killerappear = 0;
		count = 0;
		r = 0;
	}
	function SCharge02(size,frame,r,g,b){ //Draw a charge circle that has no acceleration on shrinking
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img=GCSD~"img/charge.png";
	ObjPrim_SetTexture(obj,img);
	ObjSprite2D_SetSourceRect(obj,0,0,128,128);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetAlpha(obj,0);
	ObjRender_SetScaleXYZ(obj,size,size,0);
	Obj_SetRenderPriorityI(obj,25);
	TAlpha;
	TShrink;
	return obj;
	task TAlpha{
		let l=frame;
		let alpha=255/l;
		let ra = r/l;
		let ga = g/l;
		let ba = b/l;
		loop(l){
			if(Obj_IsDeleted(objBoss)){break;}
			ObjRender_SetAlpha(obj,alpha);
			ObjRender_SetColor(obj,ra,ga,ba);
			alpha+=255/(l);
			ra += r*2/l;
			ga += g*2/l;
			ba += b*2/l;
			yield;
			}
			Obj_Delete(obj);
		}
	task TShrink{
			let a = size/frame;
			loop(frame){
			ObjRender_SetScaleXYZ(obj,size,size,0);
			ObjRender_SetPosition(obj,ObjMove_GetX(soularray[dienumber]),ObjMove_GetY(soularray[dienumber]),0);
			size = size-a;
			if(Obj_IsDeleted(objBoss)){Obj_Delete(obj);}
			yield;
			}
		Obj_Delete(obj);
	}
}

task YuyukoMainAttack // still in Create Soul
{
	let w = 1;
	let increase = -3;
	AutomaticSpawn;
	PlaySound("Charge3",100,0);
	RayCharge("PURPLE",2,60);
	RayCharge("AQUA",2,60);
	wait(120);
	while(ObjEnemy_GetInfo(objBoss,INFO_LIFE)>0)
	{
	UniqueLaser;
	wait(120);
	RedWave;
	wait(210);
	BlueWave;
	wait(180);
	PurpleWave(w);
	wait(150);
	w = -w;
	increase++;
	}

	task RedWave
	{
		let total = 18+Level*3+increase;
		ascent(n in 0..4)
		{
			let rangle = rand(0,360/total);
			PlaySound("Shot1",95,0);
			PlaySound("BulletWave",95,90);
			ascent(i in 0..total)
			{
				let angle = i*360/total+rangle;
				ascent(j in 0..6)
				{
					let obj = TShotA1(GetEnemyX,GetEnemyY,1.75,angle,292,8);
					ObjMove_AddPatternA2(obj,90,NO_CHANGE,NO_CHANGE,0.01+j/80,0,10);
				}
			}
			wait(20);
		}
		wait(10);
		ascent(n in 0..1)
		{	
		let rangle = rand(0,15);
			PlaySound("Shot1",95,0);
			PlaySound("BulletWave",95,75);
			ascent(i in 0..total)
			{
				let angle = i*360/total+rangle;
				ascent(j in 0..6)
				{
					let obj = TShotA1(GetEnemyX,GetEnemyY,1.6,angle,823,8);
					ObjMove_AddPatternA2(obj,75,NO_CHANGE,NO_CHANGE,0.01+j/80,0,10);
				}
			}
			wait(30);
		}
	}

	task BlueWave
	{
		ascent(m in 0..6)
		{
			let total = 21+Level*3+increase;
			let rangle = rand(0,360/total);
			let rangle2 = m*5*(0.5-m%2)*2;
			ascent(n in 0..4)
			{
				PlaySound("Shot1",95,0);
				PlaySound("BulletWave",95,45);
				ascent(i in 0..total)
				{
					let angle = i*360/total+rangle;
					let obj = TShotA2(GetEnemyX,GetEnemyY,10,angle,-10/30,10/10,294,8);
					ObjMove_AddPatternA2(obj,45,NO_CHANGE,angle+rangle2,0.1,0,10);
				}
				wait(5);
			}
		}
	}

	task PurpleWave(w)
	{
			let total = 18+Level*3+increase;
			let rangle = rand(0,360/total);
			ascent(n in 0..20)
			{
				PlaySound("Shot1",95,0);
				ascent(i in 0..total)
				{
					let angle = i*360/total+rangle+n*w;
					CurvyButterfly(angle);
				}
				wait(5);
			}
			ascent(n in 0..3)
			{
				rangle = rand(0,18);
				PlaySound("Shot6",95,0);
				ascent(i in 0..total)
				{
					TShotA1(GetEnemyX,GetEnemyY,2,i*360/total+rangle,827,12)
				}
				wait(30);
			}
		task CurvyButterfly(angle)
		{
			let obj = TShotA1(GetEnemyX,GetEnemyY,3.5,angle,293,8);
			ObjMove_SetAngularVelocity(obj,3*w);
			wait(15);
			while(!Obj_IsDeleted(obj))
			{
				ObjMove_SetAngularVelocity(obj,-3*w);
				wait(30);
				ObjMove_SetAngularVelocity(obj,3*w);
				wait(30);
			}
		}
	}
	task UniqueLaser
	{
		let rangle = rand(0,360);
		PlaySound("Laser2",100,0);
		ascent(i in 0..8+Level*2)
		{
			ULaser(i*360/(8+Level*2)+rangle,1053,1);
			ULaser(i*360/(8+Level*2)+180/(8+Level*2)+rangle,1051,-1);
		}
		
		task ULaser(startangle,color,way)
		{
			let r = 30;
			let newangle;
			let obj = CreateStraightLaserA1(GetEnemyX+r*cos(startangle),GetEnemyY+r*sin(startangle),startangle,500,30,90,color,75);
			ascent(i in 0..60)
			{
				newangle = startangle+way*90*sin(i*90/60);
				ObjStLaser_SetAngle(obj,newangle);
				ObjMove_SetPosition(obj,GetEnemyX+r*cos(newangle),GetEnemyY+r*sin(newangle));
				yield;
			}
			wait(105);
			descent(i in 0..30)
			{
			ObjLaser_SetRenderWidth(obj,i);
			yield;
			}
		}
	}
}
		task AutomaticSpawn // For Yuyuko Attack;
		{
			while(ObjEnemy_GetInfo(objBoss,INFO_LIFE)>0)
			{	
			SpawnFam(GetEnemyX,GetEnemyY,1.25,rand(0,360),855,200);
			wait(90);
			}
		}

}

task FireEffect
{
	ascent(i in 0..15)
	{
		PlaySound("Eff2",95,0);
		FEffect(GetEnemyX, GetEnemyY, GetPlayerX, GetPlayerY, rand(0,360), rand(0,360),32,80);
		wait(5);
	}
}

task FixedPlayer
{
	loop(270)
	{
		ObjMove_SetPosition(GetPlayerObjectID,stgx,416-30);
		yield;
	}
}

task FlashScreen
{
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img;
	img = GCSD~"img/5.png";
	LoadTexture(img);
	ObjPrim_SetTexture(obj,img);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 256, 256);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetBlendType(obj,BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj,50);
	ObjRender_SetPosition(obj,stgx,stgy,0);
	ObjRender_SetScaleXYZ(obj,2,2,0);
	PlaySound("Slash",100,0);
	descent(i in 0..60)
	{
		ObjRender_SetAlpha(obj,i*4);
		yield;
	}
	Obj_Delete(obj);
}

task MagicCirclePlayer(type)
{
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img;
	let angle = 0;
	img = GCSD~"img/eff_flower.png";
	LoadTexture(img);
	ObjPrim_SetTexture(obj,img);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 128, 128);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetBlendType(obj,BLEND_ADD_ARGB);
	Obj_SetRenderPriorityI(obj,21);
	if(type==0)
	{
		loop(120)
		{
			ObjRender_SetPosition(obj,GetPlayerX,GetPlayerY,0);
			ObjRender_SetScaleXYZ(obj,2,2,2);
			ObjRender_SetColor(obj,255,255,255);
			ObjRender_SetAngleXYZ(obj,0,0,0);
			yield;
		}
		ascent(i in 0..150)
		{
			ObjRender_SetPosition(obj,GetPlayerX,GetPlayerY,0);
			ObjRender_SetScaleXYZ(obj,2-i/75,2-i/75,2-i/75);
			ObjRender_SetColor(obj,255-i*255/150,255-i*255/150,255-i*255/150);
			ObjRender_SetAngleXYZ(obj,0,0,angle);
			angle += i/10;
			yield;
		}
	}
	let ratio = angle/30;
	PlaySound("Boon1",100,0);
	ascent(i in 0..60)
	{
		ObjRender_SetPosition(obj,GetPlayerX,GetPlayerY,0);
		ObjRender_SetScaleXYZ(obj,i/10,i/10,i/10);
		ObjRender_SetColor(obj,255-i*255/60,255-i*255/60,255-i*255/60);
		ObjRender_SetAngleXYZ(obj,0,0,angle);
		angle -= ratio;
		yield;
	}
	Obj_Delete(obj);
}

//----------------------------------------------------

task FEffect(x, y, x2, y2, angle, angle2,color,time){
				let vx=(x2-x)/time;
				let vy=(y2-y)/time;
				let r=0;
				let a=0;
					loop(time){
					//angle+=1; angle2+=1;
					x+=vx; y+=vy;
					a+=360/time; r=150-150*cos(a);
					let sangle = GetPointAngle(x,y,x+r*cos(angle),y+r*sin(angle2));
					let dummy = TShotA1(x+r*cos(angle), y+r*sin(angle2),0,sangle,701,12);
					ObjShot_SetDeleteFrame(dummy,0);
					yield;
					}
}

task ChargeSet(C_color)
{
		ShinkiCharge(45,C_color);
		PlaySound("Charge5",95,0);
		wait(60);
		MapleExplode(GetEnemyX,GetEnemyY,1.25,C_color);
		PlaySound("Eff2",100,0);
}

//----------------------------------------------------

task TEnd{
	while(ObjEnemy_GetInfo(objBoss,INFO_LIFE)>0){yield;}
		EndBoss(1);
		yield;
		CloseScript(GetOwnScriptID());
	}