//#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Nonspell #2"]
#Background["./BG/BG.dnh"]
#Player["./Player/AoCF_YukariReimu/AoCF_YukariReimu.dnh"]
#System["./System/System.dnh"]
#include "./LIB/Library_Index.dnh"

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

let diff = GetCommonData("Difficulty", 0);

@Initialize{//Declare the boss and assign the texture
	bossObj = ObjEnemy_Create(OBJ_ENEMY_BOSS);
	ObjEnemy_Regist(bossObj);

	SetAreaCommonData("System", "CurrentActiveScript", GetOwnScriptID);

	//Move the boss onto the game field
	ObjMove_SetDestAtWeight(bossObj, GetCenterX, 96, 10, 10);
	ObjEnemy_SetDamageRate(bossObj, 0, 0);
	mainTask;
	
	if(GetCommonData("Boss", "usami") == "doremy"){Tag;} //switch to Sumireko
	else{
		SetCommonData("Boss", "usami");
		AnimateBoss_Usami(bossObj);
	}
	SetShotAutoDeleteClip(96, 96, 96, 96);
}

@Event{
	alternative(GetEventType())
	case(EV_REQUEST_LIFE){
		SetScriptResult(12000);
	}
	case(EV_REQUEST_TIMER){
		SetScriptResult(60);
	}
	case(EV_REQUEST_SPELL_SCORE){
		SetScriptResult(6000000 + diff*100000);
	}
}

@Loading{
}

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

	ObjEnemy_SetIntersectionCircleToShot(bossObj, bossX, bossY, 40);
	ObjEnemy_SetIntersectionCircleToPlayer(bossObj, bossX, bossY, 20);
	yield;
}

@Finalize{

}

task mainTask{
	EnemyName(bossObj, "Sumireko & Doremy", 255, 0, 192);

	FlameAura(bossObj, [255, 0, 192], 2);
	BottomEnemyMarker(bossObj, bossObj);
	wait(120);

	alternative(diff)
	case(0, 1){
		fireEN;
	}
	case(2, 3){
		fireHL;
	}


	endTask;
	wait(180);

	ObjEnemy_SetDamageRate(bossObj, 240, 100);
	ObjEnemy_PlayHitSound(bossObj);
}

task Tag{
	if(GetCommonData("Boss", "usami") == "usami"){
		PossessionTag(ObjMove_GetX(bossObj), ObjMove_GetY(bossObj));
		ObjAnim_ForceStop(bossObj);
		Obj_SetValue(bossObj, "anim_forcestop", false);

		SetCommonData("Boss", "doremy");
		AnimateBoss_Doremy(bossObj);
	}else if(GetCommonData("Boss", "usami") == "doremy"){
		PossessionTag(ObjMove_GetX(bossObj), ObjMove_GetY(bossObj));
		ObjAnim_ForceStop(bossObj);
		Obj_SetValue(bossObj, "anim_forcestop", false); 

		SetCommonData("Boss", "usami");
		AnimateBoss_Usami(bossObj);
	}
}

task fireEN{
	let dir = 0;
	let dir2 = 0;
	let pos = [];
	let rad = 96;

	loop{
		loop(2){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			PlaySoundA1(17, 70, 0);
			ConcentrationEffect(bossObj, "Cherry", 60, 4, 128, [255, 0, 192], BLEND_ADD_ARGB);
			wait(60);
			DreamClone(bossX, bossY + 96);
			wait(120);
			
			wait(60);
			moveDeceleration(bossObj, GetCenterX + rand(-64, 64), GetCenterY + rand(-64, -128), 90, true);
			wait(120);
		}

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		Tag;
		wait(240);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		Tag;
		wait(30);
	}
}


task fireHL{
	let dir = 0;
	let dir2 = 0;
	let pos = [];
	let rad = 96;

	loop{
		loop(2){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			PlaySoundA1(17, 70, 0);
			ConcentrationEffect(bossObj, "Cherry", 60, 4, 128, [255, 0, 192], BLEND_ADD_ARGB);
			wait(60);
			DreamClone(bossX - 96, bossY);
			DreamClone(bossX + 96, bossY);
			wait(120);
			
			wait(60);
			moveDeceleration(bossObj, GetCenterX + rand(-64, 64), GetCenterY + rand(-64, -128), 90, true);
			wait(120);
		}

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		Tag;
		wait(240);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		Tag;
		wait(30);
	}
}

task DreamClone(x, y){
	let obj = Clonemireko(x, y, [0, 0]);
	KillSwitch;

	alternative(diff)
	case(0){
		shootE;
	}
	case(1){
		shootN;
	}
	case(2){
		shootH;
	}
	case(3){
		shootL;
	}

	task KillSwitch{
		while(GetCommonData("Boss", "usami") == "usami"){yield;}
		let pos = [ObjMove_GetX(obj), ObjMove_GetY(obj)];

		PlaySoundA1(117, 70, 0);
		let dream = DreamPortal(pos[0], pos[1], 3);
		ObjEnemy_SetLife(obj, -1);

		let dir = 90;
		let num = [5, 7, 5, 7][diff];

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ShotA2(pos[0] + 96*cos(dir), pos[1] + 96*sin(dir), 0, 90, 0.025, 3.5, OVAL_PURPLE+1000, 10);
		ShotA2(pos[0] + 96*cos(dir), pos[1] + 96*sin(dir), 0, GetPointAngle(GetPlayerX, GetPlayerY, pos[0] + 96*cos(dir), pos[1] + 96*sin(dir)), 0.025, 3.5, OVAL_PINK+1000, 10);
		wait(5);
		dir += 180/(num+1);
		loop(num){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			ShotA2(pos[0] + 96*cos(dir), pos[1] + 96*sin(dir), 0, 90,  0.025, 3.5, OVAL_PURPLE+1000, 10);
			ShotA2(pos[0] + 96*cos(dir), pos[1] + 96*sin(dir), 0, GetPointAngle(GetPlayerX, GetPlayerY, pos[0] + 96*cos(dir), pos[1] + 96*sin(dir)),  0.025, 3.5, OVAL_PINK+1000, 10);
			wait(5);

			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			ShotA2(pos[0] + 96*cos(-dir + 180), pos[1] + 96*sin(-dir + 180), 0, 90,  0.025, 3.5, OVAL_PURPLE+1000, 10);
			ShotA2(pos[0] + 96*cos(-dir + 180), pos[1] + 96*sin(-dir + 180), 0, GetPointAngle(GetPlayerX, GetPlayerY, pos[0] + 96*cos(-dir + 180), pos[1] + 96*sin(-dir + 180)),  0.025, 3.5, OVAL_PINK+1000, 10);
			wait(5);
			dir += 180/(num+1);
		}
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ShotA2(pos[0] + 96*cos(dir), pos[1] + 96*sin(dir), 0, 90,  0.025, 3.5, OVAL_PURPLE+1000, 10);
		ShotA2(pos[0] + 96*cos(dir), pos[1] + 96*sin(dir), 0, GetPointAngle(GetPlayerX, GetPlayerY, pos[0] + 96*cos(dir), pos[1] + 96*sin(dir)),  0.025, 3.5, OVAL_PINK+1000, 10);
		wait(150);

		Obj_SetValue(dream, "KillSwitch", true);
	}

	task shootE{
		let dir = 0;
		let switch = 1;
		while(!Obj_IsDeleted(obj)){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){return;}
			ObjAnim_SetAttackA2(obj, 90);
			loop(15){
				if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){return;}
				PlaySoundA1(95, 50, 0);
				loop(6){
					let shot = ShotA1(ObjMove_GetX(obj) - 24, ObjMove_GetY(obj), 2.5, dir, PELLET_PURPLE, 10);
					ObjMove_AddPatternA2(shot, 11, NO_CHANGE, NO_CHANGE, -0.05, 0.5, 0);
					ObjMove_AddPatternA2(shot, 91, NO_CHANGE, NO_CHANGE, 0.05, -0.5, 2.5);
					ObjMove_AddPatternA2(shot, 151, NO_CHANGE, NO_CHANGE, 0.05, 0, 2.5);

					let shot2 = ShotA1(ObjMove_GetX(obj) + 24, ObjMove_GetY(obj), 2.5, dir, PELLET_PINK, 10);
					ObjMove_AddPatternA2(shot2, 11, NO_CHANGE, NO_CHANGE, -0.05, -0.5, 0);
					ObjMove_AddPatternA2(shot2, 91, NO_CHANGE, NO_CHANGE, 0.05, 0.5, 2.5);
					ObjMove_AddPatternA2(shot2, 151, NO_CHANGE, NO_CHANGE, 0.05, 0, 2.5);

					dir += 360/6;
				}
				dir += switch*0.75;
				wait(4);
			}
			switch *= (-1);
			wait(60);

			moveDeceleration(obj, GetCenterX + rand(-128, 128), GetCenterY + rand(-64, -128), 90, true);
			wait(120);
		}
	}

	task shootN{
		let dir = 0;
		let switch = 1;
		while(!Obj_IsDeleted(obj)){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){return;}
			ObjAnim_SetAttackA2(obj, 90);
			loop(25){
				if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){return;}
				PlaySoundA1(95, 50, 0);
				loop(7){
					let shot = ShotA1(ObjMove_GetX(obj) - 24, ObjMove_GetY(obj), 3, dir, PELLET_PURPLE, 10);
					ObjMove_AddPatternA2(shot, 11, NO_CHANGE, NO_CHANGE, -0.05, 1, 0);
					ObjMove_AddPatternA2(shot, 91, NO_CHANGE, NO_CHANGE, 0.05, -1, 3);
					ObjMove_AddPatternA2(shot, 151, NO_CHANGE, NO_CHANGE, 0.05, 0, 3);

					let shot2 = ShotA1(ObjMove_GetX(obj) + 24, ObjMove_GetY(obj), 3, dir, PELLET_PINK, 10);
					ObjMove_AddPatternA2(shot2, 11, NO_CHANGE, NO_CHANGE, -0.05, -1, 0);
					ObjMove_AddPatternA2(shot2, 91, NO_CHANGE, NO_CHANGE, 0.05, 1, 3);
					ObjMove_AddPatternA2(shot2, 151, NO_CHANGE, NO_CHANGE, 0.05, 0, 3);

					dir += 360/7;
				}
				dir += switch*0.75;
				wait(3);
			}
			switch *= (-1);
			wait(60);

			moveDeceleration(obj, GetCenterX + rand(-128, 128), GetCenterY + rand(-64, -128), 90, true);
			wait(120);
		}
	}

	task shootH{
		let dir = 0;
		let switch = 1;
		while(!Obj_IsDeleted(obj)){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){return;}
			ObjAnim_SetAttackA2(obj, 90);
			loop(25){
				if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){return;}
				PlaySoundA1(95, 50, 0);
				loop(7){
					let shot = ShotA1(ObjMove_GetX(obj) - 24, ObjMove_GetY(obj), 4, dir, PELLET_PURPLE, 10);
					ObjMove_AddPatternA2(shot, 11, NO_CHANGE, NO_CHANGE, -0.05, 1.25, 0);
					ObjMove_AddPatternA2(shot, 91, NO_CHANGE, NO_CHANGE, 0.05, -1.25, 4);
					ObjMove_AddPatternA2(shot, 151, NO_CHANGE, NO_CHANGE, 0.05, 0, 4);

					let shot2 = ShotA1(ObjMove_GetX(obj) + 24, ObjMove_GetY(obj), 4, dir, PELLET_PINK, 10);
					ObjMove_AddPatternA2(shot2, 11, NO_CHANGE, NO_CHANGE, -0.05, -1.25, 0);
					ObjMove_AddPatternA2(shot2, 91, NO_CHANGE, NO_CHANGE, 0.05, 1.25, 4);
					ObjMove_AddPatternA2(shot2, 151, NO_CHANGE, NO_CHANGE, 0.05, 0, 4);

					dir += 360/7;
				}
				dir += switch*1;
				wait(3);
			}
			switch *= (-1);
			wait(60);

			moveDeceleration(obj, GetCenterX + rand(-128, 128), GetCenterY + rand(-64, -128), 90, true);
			wait(120);
		}
	}

	task shootL{
		let dir = 0;
		let switch = 1;
		while(!Obj_IsDeleted(obj)){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){return;}
			ObjAnim_SetAttackA2(obj, 90);
			loop(25){
				if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){return;}
				PlaySoundA1(95, 50, 0);
				loop(8){
					let shot = ShotA1(ObjMove_GetX(obj) - 24, ObjMove_GetY(obj), 4, dir, PELLET_PURPLE, 10);
					ObjMove_AddPatternA2(shot, 11, NO_CHANGE, NO_CHANGE, -0.05, 1.5, 0);
					ObjMove_AddPatternA2(shot, 91, NO_CHANGE, NO_CHANGE, 0.05, -1.5, 4);
					ObjMove_AddPatternA2(shot, 151, NO_CHANGE, NO_CHANGE, 0.05, 0, 4);

					let shot2 = ShotA1(ObjMove_GetX(obj) + 24, ObjMove_GetY(obj), 4, dir, PELLET_PINK, 10);
					ObjMove_AddPatternA2(shot2, 11, NO_CHANGE, NO_CHANGE, -0.05, -1.5, 0);
					ObjMove_AddPatternA2(shot2, 91, NO_CHANGE, NO_CHANGE, 0.05, 1.5, 4);
					ObjMove_AddPatternA2(shot2, 151, NO_CHANGE, NO_CHANGE, 0.05, 0, 4);

					dir += 360/8;
				}
				dir += switch*1;
				wait(3);
			}
			switch *= (-1);
			wait(60);

			moveDeceleration(obj, GetCenterX + rand(-128, 128), GetCenterY + rand(-64, -128), 90, true);
			wait(120);
		}
	}
}

function Clonemireko(x, y, rate){
	let obj = ObjEnemy_Create(OBJ_ENEMY);
	ObjEnemy_Regist(obj);
	ObjEnemy_SetLife(obj, 1000);
	AnimateBoss_Usami(obj);
	ObjRender_SetColor(obj, 128, 128, 128);
	ObjRender_SetScaleXYZ(obj, 0, 3, 0);

	ObjRender_SetPosition(obj, x, y, 0);

	CloneHitbox;
	Render;

	return obj;

	task CloneHitbox{
		ObjEnemy_SetDamageRate(obj, rate[0], rate[1]);
		ObjEnemy_PlayHitSound(obj);
		while(!Obj_IsDeleted(obj)){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0 && ObjEnemy_GetInfo(obj, INFO_LIFE) > 0){
				ObjEnemy_SetIntersectionCircleToShot(obj, ObjMove_GetX(obj), ObjMove_GetY(obj), 40);
				ObjEnemy_SetIntersectionCircleToPlayer(obj, ObjMove_GetX(obj), ObjMove_GetY(obj), 20);
			}
			yield;
		}
	}

	task Render{
		let sx = 0;
		let sy = 2;

		ascent(i in 0 .. 31){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || ObjEnemy_GetInfo(obj, INFO_LIFE) <= 0){
				break;
			}

			sx = linear(0, 1, i/30);
			sy = linear(3, 1, i/30);

			ObjRender_SetScaleXYZ(obj, sx, sy, 0);
			yield;
		}
		while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0 && ObjEnemy_GetInfo(obj, INFO_LIFE) > 0){
			yield;
		}

		let temp_sx = sx;
		let temp_sy = sy;

		ascent(i in 0 .. 31){
			sx = linear(temp_sx, 0, i/30);
			sy = linear(temp_sy, 3, i/30);

			ObjRender_SetScaleXYZ(obj, sx, sy, 0);
			yield;
		}
		Obj_Delete(obj);
	}
}

function DreamPortal(x, y, size){
	let v_count = 32;

	let obj = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	Obj_SetRenderPriorityI(obj, 30);
	ObjPrim_SetPrimitiveType(obj, PRIMITIVE_TRIANGLEFAN);
	ObjPrim_SetVertexCount(obj, v_count+2);
	ObjPrim_SetTexture(obj, GetCurrentScriptDirectory ~ "IMG/dream_world.png");
	ObjRender_SetPosition(obj, x, y, 0);
	ObjRender_SetColor(obj, 0, 0, 0);

	Render;

	return obj;

	task Render{
		let sc = 0;
		let c = 255;
		let dir = 0;
		ScaleUp;

		while(!Obj_IsDeleted(obj)){
			ObjPrim_SetVertexUVT(obj, 0, ObjRender_GetX(obj) + GetStgFrameLeft, ObjRender_GetY(obj) + GetStgFrameTop);
			ObjPrim_SetVertexPosition(obj, 0, 0, 0, 0);
			ascent(i in 0 .. v_count+1){
				ObjPrim_SetVertexUVT(obj, i, ObjRender_GetX(obj) + GetStgFrameLeft + sc*32*cos(dir), ObjRender_GetY(obj) + GetStgFrameTop + sc*32*sin(dir));
				ObjPrim_SetVertexPosition(obj, i, sc*32*cos(dir), sc*32*sin(dir), 0);
				dir += 360/v_count;
			}
			yield;
		}

		task ScaleUp{
			ascent(i in 0 .. 21){
				sc = linear(0, size, i/20);

				if(i <= 10){
					c = linear(0, 255, i/10);
					ObjRender_SetColor(obj, c, c, c);
				}
				yield;
			}
			while(Obj_GetValueD(obj, "KillSwitch", false) == false){yield;}

			
			ascent(i in 0 .. 21){
				sc = linear(size, 0, i/20);

				if(i <= 10){
					c = linear(255, 0, i/10);
					ObjRender_SetColor(obj, c, c, c);
				}
				yield;
			}
			Obj_Delete(obj);
		}
	}
}

task endTask{
	while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0) {
		yield;
	}
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	SetAutoDeleteObject(true);
	Obj_Delete(bossObj);
	wait(180);
	CloseScript(GetOwnScriptID());
}