#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Spell 4 E"]
#Text["Void Card \"Tortoise Army Encampment\""]
#Background["./Background.txt"] 

let bossObj;
let bossX = 0;
let bossY = 0;

#include "./Expanded CTC (Darkness1)/Expanded_ShotConst.txt"
#include"./FX/Bloom VFX darkwalker247/BloomFX.txt"
#include"./lib.txt"
#include"./FX/Effects.cs"
#include"./Cutin/cutin.txt"
@Initialize {
	bossObj = ObjEnemy_Create(OBJ_ENEMY_BOSS);
	ObjEnemy_Regist(bossObj);
	ObjMove_SetDestAtSpeed(bossObj,GetCenterX,GetCenterY,5);
	SFXload;
	mainTask;
} 

@Event { 
	alternative(GetEventType()) 
	case(EV_REQUEST_LIFE) { 
		SetScriptResult(3656);
	}
	case(EV_REQUEST_TIMER) { 
		SetScriptResult(87);
	}
} 

@MainLoop {
	bossX = ObjMove_GetX(bossObj);
	bossY = ObjMove_GetY(bossObj);

	/*
	ObjEnemy_SetIntersectionCircleToShot(bossObj,bossX,bossY,32);
	ObjEnemy_SetIntersectionCircleToPlayer(bossObj,bossX,bossY,20);
	*/
	
	yield;
} 

@Finalize {
} 

task mainTask {
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);	
	ObjEnemy_SetDamageRate(bossObj,1,1);
	//Insert Cut-in task
	BossRender;
	movement;
	end;
} 


task movement {

let a = 255;	
wait(60);
	
PlaySE(charge4);
BFX_FocusA1(bossX,bossY,100,VFX_Smoke,VFX_Beams,45);

loop(60){
	ObjRender_SetAlpha(bossObj,a);
	a-=255/60;
	yield;
}

wait(60);

ObjEnemyBossScene_StartSpell(GetEnemyBossSceneObjectID()); 
ObjCutin_Name("Void Card \"Tortoise Army Encampment\"");

BeginCircle;
}

task BeginCircle{
	let posX = GetCenterX;
	let posY = GetCenterY;
	let ang = 90;
	let delay = 60;
	let Delay_no = 120;
	let init_distance = 180;
	let Dist = init_distance * 2;
	
	let star_no = 45;
	let star_Delay_Time = 115;
	
	let init_distance_Star = init_distance;
	let Dist2 = init_distance_Star*2;
	let Dist3 = init_distance_Star/8;
	let Dist4 = init_distance_Star/4; // SHRINK ========================
	
	loop(45){
	loop(2){
		let ang2 = rand(0,360);
		let Warn_Star = CreateShotA1(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 248, 30);
		ObjDelete_Delay(Warn_Star, 29);}
	Dist2-= init_distance_Star/star_no;
	yield;
	}
	
	loop(115){
	loop(2){
		let ang2 = rand(0,360);
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 30);
		ObjDelete_Delay(Warn_Star, 29);
	}
		yield;
	}
	
	PlaySE(laser2);

	loop(Delay_no){ //RING=================================
		let Warn_Circle = CreateShotA1(posX + Dist * cos(ang), posY + Dist * sin(ang), 0, ang, 248, 0);
		ObjShot_SetAutoDelete(Warn_Circle, false);
		ObjShot_SetSpellResist(Warn_Circle, true);
		Move_warn(Warn_Circle, init_distance, Dist, Dist3, Dist4, ang, posX, posY);
	ang+=360/Delay_no;
	}
	
	init_distance_Star = init_distance;
	Dist2 = init_distance_Star * 2;
	
	//PHASE 1================= 

	loop(45){
		let ang2 = rand(0,360);
		if(GetObjectDistance(GetPlayerObjectID, bossObj) >= Dist2){ang2 = GetAngleToPlayer(bossObj) + rand(-45,45);}
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 10);
	Dist2-= init_distance_Star/star_no;
	yield;
	}
	
	Fire(Dist2, Dist3, Dist4);
	
	loop(1275){
		let ang2 = rand(0,360);
		if(GetObjectDistance(GetPlayerObjectID, bossObj) >= Dist2){ang2 = GetAngleToPlayer(bossObj) + rand(-45,45);}
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 10);
		yield;
	}
	
	//PHASE 2================= 

	loop(45){
		let ang2 = rand(0,360);
		if(GetObjectDistance(GetPlayerObjectID, bossObj) >= Dist2){ang2 = GetAngleToPlayer(bossObj) + rand(-45,45);}
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 10);
	Dist2-= Dist3/star_no;
	yield;
	}
	
	loop(1215){
		let ang2 = rand(0,360);
		if(GetObjectDistance(GetPlayerObjectID, bossObj) >= Dist2){ang2 = GetAngleToPlayer(bossObj) + rand(-45,45);}
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 10);
		yield;
	}
	
	//PHASE 3================= 
	
	loop(45){
		let ang2 = rand(0,360);
		if(GetObjectDistance(GetPlayerObjectID, bossObj) >= Dist2){ang2 = GetAngleToPlayer(bossObj) + rand(-45,45);}
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 10);
	Dist2-= Dist3/star_no;
	yield;
	}
	
	loop(1095){
		let ang2 = rand(0,360);
		if(GetObjectDistance(GetPlayerObjectID, bossObj) >= Dist2){ang2 = GetAngleToPlayer(bossObj) + rand(-45,45);}
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 10);
		yield;
	}
	
	loop(900){
		let ang2 = rand(0,360);
		if(GetObjectDistance(GetPlayerObjectID, bossObj) >= Dist2){ang2 = GetAngleToPlayer(bossObj) + rand(-45,45);}
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 10);
	Dist2-= Dist4/900;
	yield;
	}
	
	loop{
		if(Obj_IsDeleted(bossObj)){return;}
		let ang2 = rand(0,360);
		if(GetObjectDistance(GetPlayerObjectID, bossObj) >= Dist2){ang2 = GetAngleToPlayer(bossObj) + rand(-45,45);}
		let Warn_Star = CreateShotA2(posX + Dist2 * cos(ang2), posY + Dist2 * sin(ang2), 1, ang2, 0.03, 5, 128, 10);
		yield;
	}
	
	}

task Move_warn(warn_Circle, init_distance, Dist, Dist3, Dist4, ang, posX, posY){
	loop(45){
	Dist-=init_distance/45;
	ObjMove_SetPosition(warn_Circle, posX + Dist * cos(ang), posY + Dist * sin(ang));
	yield;
	}
	
	wait(1275);
	
	PlaySE(boon1);
	loop(45){
	Dist-=Dist3/45;
	ObjMove_SetPosition(warn_Circle, posX + Dist * cos(ang), posY + Dist * sin(ang));
	yield;
	}
	
	wait(1215);
	PlaySE(boon1);
	loop(45){
	Dist-=Dist3/45;
	ObjMove_SetPosition(warn_Circle, posX + Dist * cos(ang), posY + Dist * sin(ang));
	yield;
	}
	
	wait(1095);
	PlaySE(boon1);
	loop(900){//Phase 4 Shrinking
	Dist-=Dist4/(900);
	ObjMove_SetPosition(warn_Circle, posX + Dist * cos(ang), posY + Dist * sin(ang));
	yield;
	}
}

task Fire(Dist, Dist2, Dist3){
	let P1_Ring_Num = 10;
	let P1_Wave_Num = 15;
	
	let P1_Stream_Bul = 30;
	let P1_Stream_Bul_Time = 90;
	let P1_Stream_Bul_Ang = 100;
	let P1_Stream_Repeat = 3;
	
	let P2_Stream_Num = 60;
	let P2_Stream_wave = 4;
	
	let P2_Flower_Num = 15;
	let P2_Flower_wave = 4;
	let P2_Flower_petal = 45;
	
	let P3_Wall_Num = 180;
	let P3_Wall_Wav = 2;
	let P3_Wall_dist = P3_Wall_Num/3;
	
	let P3_RNG_Num = 30;
	let P3_RNG_wav = P3_Wall_Wav;
	let P3_RNG_dist = P3_Wall_Num/3;
	let P3_RNG_angadd = 40;
	
	let P4_Ring_Max = 10; 
	let P4_Ring_Min = 7; 
	let P4_Ring_Num = 10; 
	
	wait(120);
	PlaySE(charge4);
	Ring_Charge(bossX, bossY, 180, 60);
	wait(60);
	
	Phase1(Dist, P1_Ring_Num, P1_Wave_Num, P1_Stream_Bul, P1_Stream_Bul_Time, P1_Stream_Bul_Ang, P1_Stream_Repeat);
	wait(900);
	
	
	wait(120);
	PlaySE(charge4);
	Ring_Charge(bossX, bossY, Dist-Dist2, 120);
	wait(180);
	
	Phase2(Dist-Dist2, P2_Stream_Num, P2_Stream_wave, P2_Flower_Num, P2_Flower_wave, P2_Flower_petal);
	wait(900);
	
	wait(120);
	PlaySE(charge4);
	Ring_Charge(bossX, bossY, Dist-(Dist2*2), 120);
	wait(180);
	
	Phase3(Dist-Dist2*2, P3_Wall_Num, P3_Wall_Wav, P3_Wall_dist, P3_RNG_Num, P3_RNG_wav, P3_RNG_dist, P3_RNG_angadd);
	wait(900);
	
	wait(120);
	PlaySE(charge4);
	Ring_Charge(bossX, bossY, Dist-(Dist2*2), 120);
	wait(180);
	
	Phase4(Dist-Dist2*2, Dist3, P4_Ring_Max, P4_Ring_Min, P4_Ring_Num);
	
}	
	
task Phase1(Dist, P1_Ring_Num, P1_Wave_Num, P1_Stream_Bul, P1_Stream_Bul_Time, P1_Stream_Bul_Ang, P1_Stream_Repeat){
		
	let P1_Ring_Drag_Time = 120;
	
	let P1_Time = 60*15;
	let P1_Time2 = 60*5;
	
	
	
	Phase1_Ring(Dist, bossX, bossY, P1_Ring_Num, P1_Wave_Num, P1_Ring_Drag_Time, P1_Time);
	
	wait(60*5);
	PlaySE(charge4);
	Ring_Charge(bossX, bossY, Dist, 60);
	wait(60);
	
	loop(P1_Stream_Repeat){
	Phase1_Stream(P1_Stream_Bul, P1_Stream_Bul_Time, P1_Stream_Bul_Ang, P1_Ring_Drag_Time, Dist);
	wait((P1_Time - P1_Time2)/P1_Stream_Repeat);
	}
	}

task Phase1_Ring(Dist, P1_PosX, P1_PosY, P1_Ring_Num, P1_Wave_Num, P1_Ring_Drag_Time, P1_Time){
	let P1_Ang = rand(0,360);
	
	loop(P1_Wave_Num){
		PlaySE(shot1);
		loop(P1_Ring_Num){
			let P1_RingBull = CreateShotA1(P1_PosX + Dist * cos(P1_Ang), P1_PosY + Dist * sin(P1_Ang), 1, P1_Ang-180, 48, 10);
			Bul_Drag(P1_RingBull, P1_Ang, P1_Ring_Drag_Time, 10);
			ObjRender_SetBlendType(P1_RingBull, BLEND_ADD_ARGB);
			P1_Ang += 360/P1_Ring_Num;
		}
		P1_Ang += (360/P1_Ring_Num)/2;
		wait(P1_Time/P1_Wave_Num);
	}
	
}

task Phase1_Stream(P1_Stream_Bul, P1_Stream_Bul_Time, P1_Stream_Bul_Ang, P1_Ring_Drag_Time, Dist){
	let P1_Ang = GetAngleToPlayer(bossObj);
	let P1_PosX = bossX;
	let P1_PosY = bossY;
	let delay = 60;
	let angadd = 0;
	loop(P1_Stream_Bul){
		let P1_StreamBullA = CreateShotA1(P1_PosX + Dist * cos(P1_Ang + angadd), P1_PosY + Dist * sin(P1_Ang + angadd), 1, P1_Ang+angadd, 48, 10);
		ObjRender_SetBlendType(P1_StreamBullA, BLEND_ADD_ARGB);
		
		Bul_Drag(P1_StreamBullA, P1_Ang+angadd, P1_Ring_Drag_Time, 10);
		
		let P1_StreamBullB = CreateShotA1(P1_PosX + Dist * cos(P1_Ang-angadd), P1_PosY + Dist * sin(P1_Ang-angadd), 1, P1_Ang-angadd, 48, 10);
		Bul_Drag(P1_StreamBullB, P1_Ang-angadd, P1_Ring_Drag_Time, 10);
		
		let delayA = CreateStraightLaserA1(P1_PosX + Dist * cos(P1_Ang + angadd), P1_PosY + Dist * sin(P1_Ang + angadd), P1_Ang+angadd-180, Dist, 20, 1, 160, delay);
		let delayB = CreateStraightLaserA1(P1_PosX + Dist * cos(P1_Ang-angadd), P1_PosY + Dist * sin(P1_Ang-angadd), P1_Ang-angadd-180, Dist, 20, 1, 160, delay);
		ObjDelete_Delay(delayA, delay-1);
		ObjDelete_Delay(delayB, delay-1);
		
		PlaySE(Eff1);
		
		angadd+= P1_Stream_Bul_Ang/P1_Stream_Bul;
		wait(P1_Stream_Bul_Time/P1_Stream_Bul);
	}
	
}

//END OF PHASE 1 =====================

task Phase2(Dist, P2_Stream_Num, P2_Stream_wave, P2_Flower_Num, P2_Flower_wave, P2_Flower_petal){
		
	let P2_Stream_time = 60*15;
	let P2_Flower_time = 60*11;
	
	PlaySE(Eff1);
	Phase2_Stream(Dist, P2_Stream_Num, P2_Stream_wave,P2_Stream_time);
	
	wait(60*3);
	PlaySE(charge4);
	Ring_Charge(bossX, bossY, Dist, 60);
	wait(60);
	PlaySE(Eff1);
	Phase2_Flower(Dist, P2_Flower_Num, P2_Flower_wave, P2_Flower_petal, P2_Flower_time);
	
}

task Phase2_Stream(Dist, P2_Stream_Num, P2_Stream_wave,P2_Stream_time){
	
	loop(P2_Stream_Num){
		
		let P2_Ang = GetAngleToPlayer(bossObj);
		
		loop(P2_Stream_wave){
			
			let P2_StreamBullA = CreateShotA1(bossX + Dist * cos(P2_Ang), bossY + Dist * sin(P2_Ang), 1, P2_Ang, 16, 10);
			Bul_Drag(P2_StreamBullA, P2_Ang, 180, 10);
			ObjRender_SetBlendType(P2_StreamBullA, BLEND_ADD_ARGB);
			P2_Ang += 360/ P2_Stream_wave;	
		}
		
		wait(P2_Stream_time/P2_Stream_Num);
		
	}
}

task Phase2_Flower(Dist, P2_Flower_Num, P2_Flower_wave, P2_Flower_petal, P2_Flower_time){
	let P2_Ang = rand(0,360);
	let P2_Ang2 = P2_Ang;
	
	loop(P2_Flower_Num){
		loop(P2_Flower_wave){
			let P2_FlowerBullA = CreateShotA1(bossX + Dist * cos(P2_Ang), bossY + Dist * sin(P2_Ang), 1, P2_Ang, 8, 10);//48
			Bul_Drag(P2_FlowerBullA, P2_Ang, 120, 10);
			ObjRender_SetBlendType(P2_FlowerBullA, BLEND_ADD_ARGB);
			
			let P2_FlowerBullB = CreateShotA1(bossX + Dist * cos(P2_Ang2), bossY + Dist * sin(P2_Ang2), 1, P2_Ang2, 8, 10);
			Bul_Drag(P2_FlowerBullB, P2_Ang2, 120, 10);
			ObjRender_SetBlendType(P2_FlowerBullB, BLEND_ADD_ARGB);
			P2_Ang += 360/ P2_Flower_wave;	
			P2_Ang2 -= 360/ P2_Flower_wave;
			
			}
			
			P2_Ang += 360/ P2_Flower_petal;	
			P2_Ang2 -= 360/ P2_Flower_petal;
			
		wait(P2_Flower_time/P2_Flower_Num);
		
	}
}

//END OF PHASE 2 =====================

task Phase3(Dist, P3_Wall_Num, P3_Wall_Wav, P3_Wall_dist, P3_RNG_Num, P3_RNG_wav, P3_RNG_dist, P3_RNG_angadd){	
	
	let P3_Wall_time = 60*15;
	PlaySE(Eff1);
	Phase3_Wall(Dist, P3_Wall_Num, P3_Wall_Wav, P3_Wall_dist, P3_Wall_time);
	Phase3_RNG(Dist, P3_RNG_Num, P3_RNG_wav, P3_RNG_dist, P3_RNG_angadd, P3_Wall_time);
}

task Phase3_Wall(Dist, P3_Wall_Num, P3_Wall_Wav, P3_Wall_dist, P3_Wall_time){
	let P3_Ang = 0;
	loop(P3_Wall_Num){
		loop(P3_Wall_Wav){
			
			let P3_StreamBullA = CreateShotA1(bossX + Dist * cos(P3_Ang), bossY + Dist * sin(P3_Ang), 1, P3_Ang, 40, 10);//48
			
			Bul_Drag(P3_StreamBullA, P3_Ang, 120, 10);
			
			P3_Ang += 360/ P3_Wall_Wav;	
			
			}
			P3_Ang += 360/ P3_Wall_dist;	
			
		wait(P3_Wall_time/P3_Wall_Num);
		
	}
	
}

task Phase3_RNG(Dist, P3_RNG_Num, P3_RNG_wav, P3_RNG_dist, P3_RNG_angadd, P3_RNG_time){
	let P3_Ang = 0;
	loop(P3_RNG_Num){
		let P3_RNG = rand(-P3_RNG_angadd, P3_RNG_angadd);
		loop(P3_RNG_wav){
			
			
			
			let P3_StreamBullA = CreateShotA1(bossX + Dist * cos(P3_Ang+P3_RNG), bossY + Dist * sin(P3_Ang+P3_RNG), 1, P3_Ang+P3_RNG-180, 8, 10);
			
			Bul_Drag(P3_StreamBullA, P3_Ang+P3_RNG, 120, 10);
			
			P3_Ang += 360/ P3_RNG_wav;	
			
			}
			P3_Ang -= 360/ P3_RNG_dist;	
			
		wait(P3_RNG_time/P3_RNG_Num);
		
	}
	
}

//END OF PHASE 3 =====================

task Phase4(Dist, Dist2, P4_Ring_Max, P4_Ring_Min, P4_Ring_Num){
	let P4_Ring_Time = 900; 
	
	let ring = P4_Ring_Max;
	loop(P4_Ring_Num){
		let P4_Ang = rand(0,360);
		PlaySE(shot1);
		loop(round((ring))){
			let P3_StreamBullA = CreateShotA1(bossX + Dist * cos(P4_Ang), bossY + Dist * sin(P4_Ang), 1, P4_Ang, 8, 10);
			Bul_Drag(P3_StreamBullA, P4_Ang, 120, 10);
			P4_Ang += 360/round((ring));
		}
		
		Dist -= Dist2/P4_Ring_Num;
		ring -= (P4_Ring_Max - P4_Ring_Min)/P4_Ring_Num;
		wait(P4_Ring_Time/P4_Ring_Num);
	}
	
}

//END OF PHASE 4 =====================
	
task Bul_Drag(obj, ang, time, Delay){
	wait(Delay);
	let length = GetObjectDistance(obj, bossObj);
	let length2 = length/time;
	loop(time){
		if(Obj_IsDeleted(obj)){return;}
		ObjMove_SetPosition(obj, ObjMove_GetX(bossObj) + length * cos(ang), ObjMove_GetY(bossObj) + length * sin(ang));
	length -= length2;
	yield;
	}
	
	Obj_Delete(obj);
}	

task Ring_Charge(posX, posY, Dist, time){
	loop(time){
	loop(2){
		let ang2 = rand(0,360);
		let Warn_Star = CreateShotA2(posX + Dist * cos(ang2), posY + Dist * sin(ang2), 1, ang2, 0.03, 5, 128, 30);
		ObjDelete_Delay(Warn_Star, 29);
	}
		yield;
	}
}
	
task end {
	while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0) {
		yield;
	}
	PlaySE(SpellOff);
	TMotionBlur();
	BFX_FocusA1(bossX,bossY,250,VFX_Smoke,VFX_Beams,180);
	PlaySE(BossExplode);
	loop(240){
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);	
	yield;
	}
	BFX_ExplosionA1(bossX,bossY,250,VFX_Smoke,60);
	Obj_Delete(bossObj);
	PlaySE(BossExplode);
	loop(120){
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);	
	yield;
	}
	wait(30);	
	CloseScript(GetOwnScriptID());
}

task TMotionBlur(){//from sample scripts
	let renderTexture = [GetReservedRenderTargetName(0), GetReservedRenderTargetName(1)];
	SetInvalidRenderPriorityA1(20, 79);

	let objCurentFrame = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(objCurentFrame, 80);
	ObjRender_SetPermitCamera(objCurentFrame, false);

	let objOldFrame = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(objOldFrame, 0);
	ObjRender_SetPermitCamera(objOldFrame, false);
	ObjRender_SetAlpha(objOldFrame, 224);
	Obj_SetVisible(objOldFrame, false);

	let frame = 0;
	while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0)
	{
		let currentFrameTexture = renderTexture[frame % 2];

		RenderToTextureA1(currentFrameTexture, 20, 79, true);

		if(frame >= 1) 
		{
			
			let oldFrameTexture = renderTexture[(frame - 1) % 2];
			ObjPrim_SetTexture(objOldFrame, oldFrameTexture);
			ObjSprite2D_SetSourceRect(objOldFrame, 32, 16, 416, 464);
			ObjSprite2D_SetDestRect(objOldFrame, 32, 16, 416, 464);
			RenderToTextureB1(currentFrameTexture, objOldFrame, false);
		}

		ObjPrim_SetTexture(objCurentFrame, currentFrameTexture);
		ObjSprite2D_SetSourceRect(objCurentFrame, 32, 16, 416, 464);
		ObjSprite2D_SetDestRect(objCurentFrame, 32, 16, 416, 464);

		frame++;
		yield;
	}

	Obj_Delete(objCurentFrame);
	Obj_Delete(objOldFrame);
	ClearInvalidRenderPriority();
}