#TouhouDanmakufu[Single]
#ScriptVersion[3]
#System["./system/Default_System.txt"]

#include"./Effects_Main.txt"

let current = GetCurrentScriptDirectory;
let enm = ID_INVALID;
let GetX = 0;
let GetY = 0;
let EnemyX = 0;
let EnemyY = 0;
let OkinaX=0;
let OkinaY=0;
let JunkoX=0;
let JunkoY=0;

let s=1;
let angle2=0;
let c=6; let c2=15; let c3=7;
let ang=0;


let objScene=GetEnemyBossSceneObjectID();
let Okina;
let Junko;

@Event{
	alternative(GetEventType)
	//1;500;2500
	case(EV_REQUEST_LIFE){SetScriptResult(6000);}
	case(EV_REQUEST_TIMER){SetScriptResult(82);}

}

@Initialize{
ObjEnemy_SetDamageRate(enm, 100, 100);
Okina=Clone;
Junko=Clone;
	
	SetAutoDeleteObject(true);
	enm = ObjEnemy_Create(OBJ_ENEMY_BOSS);
	ObjEnemy_Regist(enm);
	//CreateLifeBar(enm, 50, 54, 41, 0, [255,255,255], "Normal" , [false,false] );
	
	CreateLifeBar(Okina, 50, 54, 41, 0, [255,255,255], "Normal" , [false,false] );
	
	CreateLifeBar(Junko, 50, 54, 41, 0, [255,255,255], "Normal" , [false,false] );
	
renderOkinaExHSiFS(Okina);
TAura(Okina,0);
	
renderEXJunkoLoLK(Junko);
TAura(Junko,6);
	
	ObjRender_SetPosition(enm,-250,-300,0);	
	
ObjMove_SetPosition(Okina, Obj_GetValueD(objScene,"OkinaX", 0), Obj_GetValueD(objScene,"OkinaY", 0));
ObjMove_SetPosition(Junko, Obj_GetValueD(objScene,"JunkoX", 0), Obj_GetValueD(objScene,"JunkoY", 0));
		
ObjMove_SetDestAtWeight(Okina, GetStgFrameWidth/2,  GetStgFrameHeight/2-60, 7, 4);
ObjMove_SetDestAtWeight(Junko, GetStgFrameWidth/2, GetStgFrameHeight/2-190, 7, 4);
	
	
	BossActions;
}


@MainLoop{
	GetX = ObjMove_GetX(enm);
	GetY = ObjMove_GetY(enm);
	EnemyX = ObjMove_GetX(enm);
	EnemyY = ObjMove_GetY(enm);
	
	JunkoX=ObjMove_GetX(Junko);
	JunkoY= ObjMove_GetY(Junko);
	
	OkinaX=ObjMove_GetX(Okina);
	OkinaY= ObjMove_GetY(Okina);
	
	yield;
}

function angleToPlayer {
	let dir = atan2(GetPlayerY-GetY,GetPlayerX-GetX);
	return dir;
}


task BossActions{

	wait(20);
	ExplosionA2(Junko, "white");
	JunkoBG(Junko);
	PerformActions;
	
	while(ObjEnemy_GetInfo(enm, INFO_LIFE) > 0){
		yield;
	}
	
	Obj_Delete(enm);
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	Obj_SetValue(objScene,"JunkoX", ObjMove_GetX(Junko));//To pass on starting values
	Obj_SetValue(objScene,"JunkoY", ObjMove_GetY(Junko));
	
	Obj_SetValue(objScene,"OkinaX", ObjMove_GetX(Okina));//To pass on starting values
	Obj_SetValue(objScene,"OkinaY", ObjMove_GetY(Okina));
	
	yield;
	CloseScript(GetOwnScriptID);
	
	task PerformActions{

let angle = -90;
let x=0; let y=0; 
let s=1;
let t=0;
if (GetCommonData("rank", "Normal")=="Normal"){c=6; c2=3; c3=10;}
else{c=8; c2=4; c3=12;}
let a =0;

let array=GetShotIdInCircleA1(320, 240, 1000); //get all shots ID into an array
let D=150;
	wait(110);
	//ChargeUp(enm, [ObjMove_GetX(enm), ObjMove_GetY(enm)], -2, 2, angle, 120, 20, [232, 0, 0], "DARK");
	JunkoWork;
	OkinaWork;
	

}}

task JunkoWork{
	let ang=rand(0,360);
	let angB=5;
	
		homing(Junko,ang);
		while(!Obj_IsDeleted(Okina) && ObjEnemy_GetInfo(Junko,INFO_LIFE)>2 && ObjEnemy_GetInfo(Junko,INFO_LIFE)<=3100){
			CreateShotPatternB(50,2.5,-0.07,50);
			wait(20);
		}
		
		while(ObjEnemy_GetInfo(enm,INFO_LIFE)<=6000&& !Obj_IsDeleted(Junko)&& ObjEnemy_GetInfo(Junko,INFO_LIFE)>=2){
			CreateShotPatternB2(45,4,-0.25,0.5,15);
			wait(90);

		}
		
		task CreateShotPatternB(bShot,spd,accel,cdr){
			let g = BL_SMALL_RED+500;
			
			PlaySoundEffect("se_tan01");
			ascent(i in 0..bShot){
				CreateShotA4(JunkoX+5*cos(ang), JunkoY+5*sin(ang), spd, ang,accel,0,g, 15,cdr);
				ang+=360/bShot;
			}
		}
		
		task CreateShotPatternB2(bShot,spd,accel,maxspd,cdr){
			let g = BL_SMALL_RED+500;
			
			PlaySoundEffect("se_tan01");
			ascent(i in 0..bShot){
				CreateShotA5(JunkoX+5*cos(ang), JunkoY+5*sin(ang), spd, ang,accel,maxspd,g, 15,30,110);
				ang+=360/bShot;
			}
		}

		
task CreateShotA4(x, y, speed, angle,accel,maxspd,graphic, delay,cdr){
DelayShot(x, y, graphic, angle, speed, BLEND_ADD_ARGB, 3, delay);
wait(delay);
let shota1=CreateShotA2(x+speed*delay*cos(angle), y+speed*delay*sin(angle), speed, angle,accel,maxspd,graphic, 0);

if(ObjEnemy_GetInfo(Junko,INFO_LIFE)<=2){Obj_Delete(shota1);}
wait(cdr);
//CallShot(shota1);
ObjShot_FadeDelete(shota1);

}

task CreateShotA5(x, y, speed, angle,accel,maxspd,graphic, delay,cdr,cdr2){
DelayShot(x, y, graphic, angle, speed, BLEND_ADD_ARGB, 3, delay);
wait(delay);
let shota1=CreateShotA2(x+speed*delay*cos(angle), y+speed*delay*sin(angle), speed, angle,accel,maxspd,graphic, 0);

if(ObjEnemy_GetInfo(Junko,INFO_LIFE)<=2){Obj_Delete(shota1);}
wait(cdr);
ascent(i in 0..3){
CreateShotMiniA(ObjMove_GetX(shota1), ObjMove_GetY(shota1), 0, ObjMove_GetAngle(shota1),0.01,4,graphic, delay,cdr2-25*i);}
ObjShot_FadeDelete(shota1);

task CreateShotMiniA(x, y, speed, angle,accel,maxspd,graphic, delay,cdr2){
DelayShot(x, y, graphic, angle, speed, BLEND_ADD_ARGB, 3, delay);
wait(delay);

let shota1=CreateShotA2(x+speed*delay*cos(angle), y+speed*delay*sin(angle), 0, angle,0,0,graphic, 0);
ObjMove_AddPatternA2(shota1,cdr2,NO_CHANGE,NO_CHANGE,accel,0,maxspd);
}


}

task homing(ene,angle){
let a_spd = rand(1.5,2.5);
let a = angle;
let speed = rand(1,1.25);
wait(50);
while(!Obj_IsDeleted(Okina) && ObjEnemy_GetInfo(Junko,INFO_LIFE)>2 && ObjEnemy_GetInfo(Junko,INFO_LIFE)<=3100){
		let angle_to = GetAngleToPlayer(ene);

		// choose to increase or decrease angle depending on which is closer
		let da = [a_spd, -a_spd][((a - angle_to) % 360) < 180]; 

		// if the angles are close enough, just snap instead
		if( (|a - angle_to|) < a_spd){
			a = angle_to;
		}else{
			a = (a + da) % 360;
		}

		ObjMove_SetAngle(ene, a);

		// optionally scale speed so it slows down to adjust angle
		let scale = (|(a - angle_to) % 360 - 180|) / 160; // ranges [0,1]; is 1 when angles are equal
		ObjMove_SetSpeed(ene, speed * scale); // squaring also optional, increases slowdown
		yield;
	}
	
while(ObjEnemy_GetInfo(enm,INFO_LIFE)<=6000&& !Obj_IsDeleted(Junko)&& ObjEnemy_GetInfo(Junko,INFO_LIFE)>=2){
		let angle_to = GetAngleToPlayer(ene);

		// choose to increase or decrease angle depending on which is closer
		let da = [a_spd, -a_spd][((a - angle_to) % 360) < 180]; 

		// if the angles are close enough, just snap instead
		if( (|a - angle_to|) < a_spd){
			a = angle_to;
		}else{
			a = (a + da) % 360;
		}

		ObjMove_SetAngle(ene, a);

		// optionally scale speed so it slows down to adjust angle
		let scale = (|(a - angle_to) % 360 - 180|) / 160; // ranges [0,1]; is 1 when angles are equal
		ObjMove_SetSpeed(ene, speed * scale); // squaring also optional, increases slowdown
		yield;
	}

}

	
}

task OkinaWork{
	let graph=ICE_AQUA;
	let ang=270;
	let ang2=25;
	
	let ang3=0;
	let sway = 0;
	let a=0;
		
	while(!Obj_IsDeleted(Junko) && ObjEnemy_GetInfo(Okina,INFO_LIFE)>2 && ObjEnemy_GetInfo(Okina,INFO_LIFE)<=3100){
		
	ascent(i in 0..5){
	BackDoorOkina;
		
	wait(7);}
	
	wait(45);
		
	}
	
	wait(60);
	ObjMove_SetDestAtWeight(Okina,GetStgFrameWidth/2,  GetStgFrameHeight/2+190,3,3);
	
	wait(80);
	
	while(ObjEnemy_GetInfo(enm,INFO_LIFE)<=6000&& !Obj_IsDeleted(Okina)&& ObjEnemy_GetInfo(Okina,INFO_LIFE)>=2){
		
		BackDoorOkina2;	
		a+=2.5;
		sway+=5*((-1)^3);
		wait(8);
		}
	
	task BackDoorOkina{
	
			PlaySoundEffect("se_tan01");
		ascent(i in -2..3){
			ang=270+180/5*i;
			CreateShotA4(OkinaX+35*cos(ang),OkinaY+35*sin(ang),2.5,270+55/5*i,AMULET_RED,15);

		}
	}
	
	task BackDoorOkina2{
	
			PlaySoundEffect("se_tan01");
		ascent(i in -4..5){
			ang3=270+180/9*i;
			CreateShotA4(OkinaX+35*cos(ang3),OkinaY+55*sin(ang3),2.5,270+90/9*i+60*sin(sway)+i*20,AMULET_AQUA,15);

		}
	}
		
	
	task CreateShotA4(x, y, speed, angle,graphic, delay){
		
DelayShot(x, y, graphic, angle, speed, BLEND_ADD_ARGB, 3, delay);
wait(delay);
let shota1=CreateShotA1(x+speed*delay*cos(angle), y+speed*delay*sin(angle), speed, angle,graphic, 0);
ObjShot_SetSpellResist(shota1,true);
if(ObjEnemy_GetInfo(Okina,INFO_LIFE)<=2){Obj_Delete(shota1);}
ObjMove_WarpVertical(shota1, 1);

}

		task ObjMove_WarpVertical(obj, limit){
	let count = 0;
	while(!Obj_IsDeleted(obj)){
		if(ObjMove_GetY(obj) <= -32 && count < limit){
			ObjRender_SetBlendType(obj,BLEND_ALPHA_INV);
			ObjMove_SetY(obj, GetStgFrameHeight + 30);
			count++;
		}

		if(ObjMove_GetY(obj) >= GetStgFrameHeight + 32 && count < limit){
			ObjRender_SetBlendType(obj,BLEND_ALPHA_INV);
			ObjMove_SetY(obj, -30);
			count++;
		}
		yield;
	}
}
}


	
//BulletBreak([ObjMove_GetX(obj2), ObjMove_GetY(obj2)],rand(0,360),ObjShot_GetImageID(obj2),BLEND_ALPHA);

function Clone{
	let BaseObj = ObjEnemy_Create(OBJ_ENEMY);
	let c = 0;	
	let color = [0,0,0];
	ObjEnemy_Regist(BaseObj);
	ObjEnemy_SetLife(BaseObj,3100);
	ObjEnemy_SetDamageRate(BaseObj,100,100);
	Control(BaseObj);
	Invincible(BaseObj,120);
	return BaseObj;

	
		task Control(BaseObj)
	{	
			while(!Obj_IsDeleted(BaseObj)){
			c++;
			ObjEnemy_SetIntersectionCircleToShot(BaseObj,ObjMove_GetX(BaseObj),ObjMove_GetY(BaseObj),24);
			ObjEnemy_SetIntersectionCircleToPlayer(BaseObj,ObjMove_GetX(BaseObj),ObjMove_GetY(BaseObj),30);
			yield;
			
			if(ObjEnemy_GetInfo(BaseObj,INFO_LIFE) <=0){

			//NotifyEventAll(EV_USER+10, [ObjMove_GetX(BaseObj), ObjMove_GetY(BaseObj)]);
			//Obj_Delete(BaseObj);
			ControlFlight(BaseObj);
			ObjEnemy_AddLife(BaseObj,1);
			ObjEnemy_AddLife(enm,-5000);
			Invincible(BaseObj,300);
			Invincible(Junko,450);
			Invincible(Okina,450);
			//wait(10);
			
			DeleteShotAll(TYPE_ALL,TYPE_ITEM);
			wait(90);
			
			Obj_Delete(BaseObj);
			}

			if(Obj_IsDeleted(enm)){Obj_Delete(BaseObj);}
			}
			
			task ControlFlight(BaseObj){
			while(!Obj_IsDeleted(BaseObj)){
			ObjMove_SetDestAtWeight(BaseObj, 0-250, 0-250,4,9);
			
			yield;
			}
		}
			
			
	}
}

	task Invincible(Obj,frame){
		SetInvincibility(Obj, frame);
		
	}


task BulletCommands(obj){
   
    ObjMove_SetAngle(obj, GetAngleToPlayer(obj));
}
