script_enemy_main {
	#include_function ".\..\ShotSheet\shot_replace.dnh"
	#include_function ".\..\functions.txt"
	#include_function ".\..\s3\y_functions.txt"

	SpellID=87;

	let i=0;
	let frame=0;
	let stuff=GCSD~"..\img\yukaristuff.png";

	let phase=0;
	let bulletindex=[];

    @Initialize {
	StartFunctions(1,0,0);
	Randomize;
        SetLife(8000);
        SetTimer2(130);
	SetDamageRate(60,40);
	MagicCircle(false);
	SetEnemyMarker(true);
	SetBG(5);
	YukariInit;

	shotinit;

	CutIn2(5,"[Danmaku of the Outside World]");
	SpellCircle2(6,1,4,250);
	SetShotAutoDeleteClip(20,20,20,20);
	LoadGraphic(stuff);
	DeleteCommonData("nuked");

	MainTask;
    }


function Wait(frames){loop(frames){yield;}}

function percentage{
	return lower(GetTimer2/130,GetLife/8000)*100;
}

task MainTask{
	CalculateBullets;
	let graphicorder=[0,4,5,1,6,2,3,7];
	let flag;
	let random;

	SetMovePosition03(GetCenterX,100,10,5);
	DelayBombTask;
	Wait(40);
	let angle1=rand(180,270);
	let angle2=rand(270,360);
	let angle3=rand(180,270)-360;
	let angle4=rand(270,360);
	let angle5=[90,90,90,90,90];
	let meteorid=0;
	let shots=0;

	let gaparray=Gap(GetX,GetY,GetCenterX,GetCenterY-50,30,40,60000,[0,0]);
	ObjEffect_SetLayer(gaparray[1],5);
	ObjEffect_SetLayer(gaparray[3],5);
	Obj_Delete(gaparray[0]);	//create only one gap
	Obj_Delete(gaparray[2]);

	Wait(60);

	SE("shot2");
	BulletSounds;

	while(percentage>=60){
		YukariBullet(GetCenterX,GetCenterY-50,2+(shots%5)*0.4,angle1,2,graphicorder[bulletindex[0]],false);
		angle1+=prand(8,9);
		if(percentage<94){
			if(phase==0){
				SE("shot2");
				phase++;
			}
			YukariBullet(GetCenterX,GetCenterY-50,2+(shots%3)*0.7,angle2,2,graphicorder[bulletindex[1]],false);
			angle2-=prand(10,11);
		}
		if(percentage<88){
			if(phase==1){
				SE("shot2");
				phase++;
			}
			YukariBullet(GetCenterX,GetCenterY-50,prand(1.5,3),angle3,2,graphicorder[bulletindex[2]],false);
			angle3+=prand(13,14);

		}
		if(percentage<82){
			if(phase==2){
				SE("shot2");
				phase++;
			}
			flag=false;
			i=0;
			while(flag==false){
				random=rand(0,360);
				flag=true;
				while(i<5&&flag==true){
					if(absolute(angle5[i]-random)<10){
						flag=false;
					}
					i++;
				}
			}
			angle5[meteorid%5]=random;
			meteorid++;
			YukariBullet(GetCenterX,GetCenterY-50,2,random,2,graphicorder[bulletindex[3]],false);
		}
		if(percentage<76){
			if(phase==3){
				SE("shot2");
				phase++;
			}
			YukariBullet(GetCenterX,GetCenterY-50,3,angle4,2,graphicorder[bulletindex[4]],false);
			YukariBullet(GetCenterX,GetCenterY-50,3,angle4+180,2,graphicorder[bulletindex[4]],false);
			angle4-=prand(20,21);

		}
		shots++;
		Wait(3);
	}
	phase=5;
	Wait(10);
	SE("shot2");
	random=rand(0,360);
	i=0;
	loop(50){
		NukeBullet(GetCenterX,GetCenterY-50,1.8+(i%2)*0.5,i*(360/50)+random,4,0,true,0,0.7);
		i++;
	}
	SetCommonData("CloseGap",1);
	phase=5;
	Wait(40);
	yield;
	SummonRan;
	while(percentage>45){yield;}
	let gaparray=Gap(GetCenterX-60,GetCenterY-50,GetCenterX+60,GetCenterY-50,30,40,60000,[0,0]);
	i=0;
	loop(4){
		ObjEffect_SetLayer(gaparray[i],5);
		i++;
	}






	Wait(60);
	let dir=rand_int(0,4);
	while(percentage>20){
		i=0;
		if(percentage>15){
			SE("shot2");
			random=rand(0,360);
			loop(30){
				YukariBullet(GetCenterX-60,GetCenterY-50,  sin(i*36)*0.8+1.5,i*(360/30)+random, 2,graphicorder[bulletindex[dir%5]],false);
				YukariBullet(GetCenterX+60,GetCenterY-50,  sin(i*36)*0.8+1.5,i*(360/30)+random, 2,graphicorder[bulletindex[dir%5]],false);
				i++;
			}
			dir++;
			Wait(70+(percentage-15));
		}
		shots++;
	}
	SetCommonData("CloseGap",1);
	SetDamageRate(0,0);
	Wait(40);

	let gaparray=Gap(GetX,GetY,GetCenterX,GetClipMinY,50,200,60000,[0,0]);
	ObjEffect_SetAngle(gaparray[1],0,0,-90);
	ObjEffect_SetAngle(gaparray[3],0,0,-90);
	ObjEffect_SetLayer(gaparray[1],5);
	ObjEffect_SetLayer(gaparray[3],5);
	Obj_Delete(gaparray[0]);	//create only one gap
	Obj_Delete(gaparray[2]);
	Wait(60);

	SetDamageRate(50,30);
	SetShotAutoDeleteClip(30,90,30,90);
	yield;
	let x=-1000;
	let playerxpercent=0;
	let dir=0;
	random=0;
	loop{
		SE("shot2");
		loop(2){
			while(absolute(random-x)<130){
				random=rand(GetClipMinX,GetClipMaxX);
			}
			x=random;
			NukeBullet(x,-40,rand(3,4),90,4,0,true,0,1.8);
		}
		playerxpercent=(center(GetClipMinX+100,GetPlayerX,GetClipMaxX-100)-(GetClipMinX+100))/(GetClipMaxX-GetClipMinX-200);
		loop(2){
			dir=1;
			if(rand(0,1)<playerxpercent){dir=-1;}
			YukariBullet(GetCenterX+dir*215,rand(GetClipMinY,GetClipMaxY),rand(1,2),90+90*dir,2,graphicorder[bulletindex[rand_int(0,4)]],false);
		}
		Wait(25);
	}
}
task SummonRan{
	let dir=3;
	let rantype=[[5,8],[0,4],[9,12],[13,16]];
	loop(2){
		rantype=erase(rantype,rand_int(0,dir));
		dir--;
	}
	if(rand_int(0,1)==0){
		rantype=[rantype[1],rantype[0]];
	}
	dir=1;
	let time;
	let shottype=rand_int(0,1);
	if(GetPlayerX>GetCenterX){dir=-1;}
	loop{
		time=(upper((percentage+15)/3,30)/3-3)*(550/25);
		if(percentage>45){	//just ran
			Ran(GetCenterX+250*dir,GetCenterY+rand(-100,0),-dir*(550/time),rand(-(550/time)*0.3,0),rantype[shottype%2],2,25);
		}else if(percentage<15){	//ran plus nukes
			Ran(GetCenterX+250*dir,GetCenterY+rand(-100,0),-dir*(550/time),rand(-(550/time)*0.3,0),rantype[shottype%2],4,25);
		}else{	//ran plus stuff
			Ran(GetCenterX+250*dir,GetCenterY+rand(-100,0),-dir*(550/time),rand(-(550/time)*0.3,0),rantype[shottype%2],3,20);
		}
		shottype++;
		dir=-dir;
		Wait(time);
	}
}






task BulletSounds{
	while(phase<5){
		SE("shot1");
		Wait(12-phase*2);
	}
}
task CalculateBullets{
	let random;
	let flag=false;
	let waited=0;
	loop(5){
		flag=false;
		while(flag==false){
			random=upper(0,rand_int(-1,2)+length(bulletindex));
			flag=true;
			i=0;
			while(i<length(bulletindex)&&flag==true){
				if(bulletindex[i]==random){
					flag=false;
				}
				i++;
			}
			if(waited<99){	//spread out the calculations so there's not a lag spike
				yield;
				waited++;
			}
		}
		bulletindex=bulletindex~[random];
	}
	if(rand_int(0,10)==0){
		bulletindex[4]=7;
	}
}

let bulletgraphics=[RED01,RED01,RED24,RED24,RED05];
let bulletsizes=[10,10,20,20,40];
let bullety=[0,20,40,80,120];
let bulletz=[4,4,3,3,3];
function YukariBullet(x,y,v,a,row,type,resist){
	let obj1=Obj_Create(OBJ_SHOT);
	let obj2=Obj_Create(OBJ_EFFECT);
	YukariBullet2(obj1,obj2,x,y,v,a,row,type,resist);
	return [obj1,obj2];
}

task YukariBullet2(obj1,obj2,x,y,v,a,row,type,resist){
	if(row==0&&type>=12){
		row++;
		type-=12;
	}
	if(row==2&&type>=6){
		row++;
		type-=6;
	}
	let rotation=[
		[0,0,0,0,0,rand(-3,3),rand(-3,3),rand(-3,3),rand(-3,3),0,0,0],
		[0,rand(-3,3),rand(-3,3),rand(-3,3),rand(-3,3)],
		[-3,0,0,0,rand(1,2)*RandDir,5],
		[rand(-2,2),0],
		[0]];

	Obj_SetPosition(obj1,x,y);
	Obj_SetSpeed(obj1,v);
	Obj_SetAngle(obj1,a);
	ObjShot_SetGraphic(obj1,bulletgraphics[row]);
	ObjShot_SetBombResist(obj1,resist);
	if(row==3){
		Obj_SetCollisionToPlayer(obj1,false);
	}
	Obj_SetAlpha(obj1,0);

	let size=bulletsizes[row];

	ObjEffect_SetTexture(obj2,stuff);
	ObjEffect_CreateVertex(obj2,4);
	ObjEffect_SetLayer(obj2,bulletz[row]);
	ObjEffect_SetPrimitiveType(obj2,PRIMITIVE_TRIANGLEFAN);
	ObjEffect_SetVertexXY(obj2,0,-size,-size);
	ObjEffect_SetVertexXY(obj2,1, size,-size);
	ObjEffect_SetVertexXY(obj2,2, size, size);
	ObjEffect_SetVertexXY(obj2,3,-size, size);
	size*=2;
	ObjEffect_SetVertexUV(obj2,0,0   +type*size,0   +bullety[row]);
	ObjEffect_SetVertexUV(obj2,1,size+type*size,0   +bullety[row]);
	ObjEffect_SetVertexUV(obj2,2,size+type*size,size+bullety[row]);
	ObjEffect_SetVertexUV(obj2,3,0   +type*size,size+bullety[row]);

	ObjEffect_SetAngle(obj2,0,0,a+90);

	let xv=cos(a)*v;
	let yv=sin(a)*v;
	let displaya=0;
	while(!Obj_BeDeleted(obj1)){
		x+=xv;
		y+=yv;
		if(row>1){
			displaya+=rotation[row][type];
			ObjEffect_SetAngle(obj2,0,0,displaya+a+90);
			Obj_SetPosition(obj2,x,y);
		}else{
			displaya+=rotation[row][type];
			ObjEffect_SetAngle(obj2,0,0,displaya+a+90);
			Obj_SetPosition(obj2,round(x),round(y));
		}

		yield;
	}
	if(OnScreen(x,y,16)&&GetCommonDataDefault("nuked",0)==0){
		let alpha=255;
		loop(60){
			x+=xv;
			y+=yv;
			Obj_SetPosition(obj2,x,y);
			Obj_SetColor(obj2,4,alpha,255,255,255);
			alpha-=255/60;
			yield;
		}
	}
	Obj_Delete(obj2);
}
task NukeBullet(x,y,v,a,row,type,resist,angvel,size){
	let obj=YukariBullet(x,y,0,a,row,type,resist);
	let xv=cos(a)*v;
	let yv=sin(a)*v;
	let offsetx=cos(a)*18*size;
	let offsety=sin(a)*18*size;
	let grazed=false;
	ObjEffect_SetScale(obj[1],size,size);
	let collisionnum=0;
	while(OnScreen(x,y,70)&&!Obj_BeDeleted(obj[0])){
		x+=xv;
		y+=yv;
		Obj_SetPosition(obj[1],x,y);
		Obj_SetPosition(obj[0],x,y);
		if(!grazed){
			grazed=CircleGraze(x,y,40*size);
		}
		if(   (CircleCollision(x+offsetx*collisionnum,y+offsety*collisionnum,12*size))   &&GetCommonDataDefault("nuked",0)==0){
			loop(11){
				CreateExplosionEX(1.5+RandDir*1.5,x,y,2,RainbowArray(rand(180,300),120,50),rand(0.3,1.5),rand(60,300));
			}
			Delete(x,y);
			ShakeScreen(15,240);
			SE("nuke4");
			ShootDownPlayer;
		}
		collisionnum=1-collisionnum;
		yield;
	}
	Obj_Delete(obj[0]);
	Obj_Delete(obj[1]);
}
task Ran(x,y,xv,yv,graphicarray,frequency,spreadnum){
	let dir=GetSign(xv);
	let vels=[3,4,3,2];
	let obj=Obj_Create(OBJ_EFFECT);
	ObjEffect_SetTexture(obj,stuff);
	ObjEffect_CreateVertex(obj,4);
	ObjEffect_SetLayer(obj,5);
	ObjEffect_SetScale(obj,-dir,1);
	ObjEffect_SetPrimitiveType(obj,PRIMITIVE_TRIANGLEFAN);
	ObjEffect_SetXYRect(obj,-45,-42,45,42);
	ObjEffect_SetUVRect(obj,74,124,164,210);

	let onscreened=0;
	let spreaded=0;
	let frame=0;
	let random=0;
	let k=0;
	let shots=0;
	let angle=0;
	while(OnScreen(x,y,40)||onscreened==0){
		x+=xv;
		y+=yv;
		Obj_SetPosition(obj,x,y);
		if(OnScreen(x,y,-1)){
			onscreened=1;
			if(frame%frequency==0){
				SE("shot1");
				random=rand(0,360);
				YukariBullet(x+cos(random)*0,y+sin(random)*0,2+sin(shots*22.5),90,0,rand_int(graphicarray[0],graphicarray[1]),false);
				YukariBullet(x+cos(random)*0,y+sin(random)*0,2+sin(shots*22.5),-90,0,rand_int(graphicarray[0],graphicarray[1]),false);
				shots++;
			}
			if(frame%5==0){
				CreateExplosionEX(0,x,y,1,[55,155,255],0.6,10);
			}
		}
		if(!OnScreen(x,y,1)&&onscreened==1&&spreaded==0){
			let angle=180/spreadnum;
			k=rand(0,1);
			loop(spreadnum*2){
				YukariBullet(x,y,3,k*angle,0,rand_int(graphicarray[0],graphicarray[1]),false);				
				k++;
			}
			SE("shot2");
			CreateExplosionEX(3,x,y,1,[25,75,125],0.6,50);
			CreateExplosionFlatEX(3,x,y,1,[25,75,125],0.6,50);
			spreaded=1;
		}
		if(frame%4==0){
			RanGhost(x,y,frame,dir);
		}
		frame++;
		ObjEffect_SetAngle(obj,0,0,frame*15.6*dir);
		yield;
	}
}
task RanGhost(x,y,startframe,dir){
	let obj=Obj_Create(OBJ_EFFECT);
	ObjEffect_SetTexture(obj,stuff);
	ObjEffect_CreateVertex(obj,4);
	ObjEffect_SetLayer(obj,3);
	ObjEffect_SetScale(obj,-dir,1);
	ObjEffect_SetPrimitiveType(obj,PRIMITIVE_TRIANGLEFAN);
	ObjEffect_SetXYRect(obj,-45,-42,45,42);
	ObjEffect_SetUVRect(obj,74,124,164,210);
	ObjEffect_SetAngle(obj,0,0,startframe*15.6*dir);
	Obj_SetPosition(obj,x,y);
	let alpha=250;
	let alphaadd=250/100;
	let color=220;
	let coloradd=220/100;
	loop(100){
		Obj_SetColor(obj,4,alpha,color,color,255);
		alpha-=alphaadd;
		color-=coloradd;
		yield;
	}
	Obj_Delete(obj);
}
task Delete(x,y){
	SetCommonData("nuked",1);
	Overlay(1,0,120,60,7,ADD,255,255,150);
	let radius=20;
	loop(60){
		DeleteEnemyShotImmediatelyInCircle(ALL,x,y,radius);
		radius+=20;
		yield;
	}
	DeleteCommonData("nuked");
}
    @MainLoop {
        SetCollisionA(GetX, GetY, 40);
	SetCollisionB(GetX, GetY, 20);

	HandleGaps;
	YukariDrawLogic;
	yield;
}
    @DrawLoop {
	YukariDrawLoop;
}

    @Finalize {
	YukariFinalize;
	EndingFunc(3);
	DeleteGraphic(stuff);
	PointItems(GetX,GetY,3,1);
	SetShotAutoDeleteClip(64,64,64,64);
    }

}