//#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Spell #4"]
#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 bossImg = GetCurrentScriptDirectory ~ "IMG/Yabusame.png";

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);
	SetCommonData("LastSpell", true);

	//Move the boss onto the game field
	ObjMove_SetPosition(bossObj, -512, -512);
	ObjEnemy_SetDamageRate(bossObj, 0, 0);
	mainTask;

	SetShotAutoDeleteClip(128, 128, 128, 128);
}

@Event{
	alternative(GetEventType())
	case(EV_REQUEST_LIFE){
		SetScriptResult(3000);
	}
	case(EV_REQUEST_TIMER){
		SetScriptResult(65);
	}
	case(EV_REQUEST_SPELL_SCORE){
		SetScriptResult(6000000 + diff*100000);
	}
	case(EV_REQUEST_IS_DURABLE_SPELL){
		SetScriptResult(true);
	}
}

@Loading{
}

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

@Finalize{

}

task mainTask{
	EnemyName(bossObj, "Sumireko & Doremy", 255, 0, 192);
	wait(240);
	NotifyEventAll(EV_USER+5, 0);

	wait(60);
	Cracks;

	CutinPythonA1("*There's No Need to See Visions of the Dream World Anymore!*", ["Easy", "Normal", "Hard", "Lunatic"][diff], GetCurrentScriptDirectory ~ "IMG/TwoCut.png", [192, 0, 128]);
	ObjEnemyBossScene_StartSpell(GetEnemyBossSceneObjectID);
	PlaySoundA1(13, 70, 0);

	BottomEnemyMarker(bossObj, bossObj);
	wait(90);
	PlaySoundA1(17, 70, 0);
	ConcentrationEffect(bossObj, "Maple", 60, 5, 128, [255, 0, 192], BLEND_ADD_ARGB);
	wait(60);
	PlaySoundA1(30, 70, 0);
	loop(30){
		BossExplodeObject(bossX, bossY, "Maple", rand(3, 6), rand(0, 360), [255, 0, 192], BLEND_ADD_ARGB);
		BossExplodeObject(bossX, bossY, "Maple", rand(3, 6), rand(0, 360), [255, 255, 255], BLEND_ADD_ARGB);
	}
	wait(90);

	alternative(diff)
	case(0){
		fireE;
	}
	case(1){
		fireN;
	}
	case(2){
		fireH;
	}
	case(3){
		fireL;
	}

	endTask;
	wait(120);

	ObjEnemy_SetDamageRate(bossObj, 60, 50);
	ObjEnemy_PlayHitSound(bossObj);
}

task fireE{
	let dir = 0;
	let dir2 = 0;

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	let x = GetPlayerX;
	ApocalypseBeam(x, 0, 90, 45, 150, 120, true);
	wait(60);

	loop(5){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(x, 0, GetPointAngle(GetPlayerX, GetPlayerY, x, 0), 25, 80, 60, false);
		wait(20);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(x, 0, -GetPointAngle(GetPlayerX, GetPlayerY, x, 0) + 180, 25, 80, 60, false);
		wait(20);
	}
	wait(120);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");
	
	loop(35){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(3){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PINK, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 1);
				ObjMove_AddPatternA2(obj, 240, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/3;
		}
		dir += 2;
		wait(4);
	}
	wait(120);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	ascent(x in 0 .. 3){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetClipMaxX/2 * x, 0, 90, 45, 80, 300, false);
		wait(10);
		
	}
	ascent(y in 0 .. 3){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(0, GetClipMaxY/2 * y, 0, 45, 80, 300, false);
		wait(10);
	}
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");

	loop(35){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(3){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PURPLE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 1);
				ObjMove_AddPatternA2(obj, 240, NO_CHANGE, NO_CHANGE, 0.1, 0, 3);
				dir2 += 360/3;
			}
			dir += 360/3;
		}
		dir -= 2;
		wait(4);
	}
	wait(240);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	dir = GetPointAngle(GetCenterX, GetCenterY, GetPlayerX, GetPlayerY);
	loop(5){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, false);
		dir += 360/5;
		wait(10);
	}
	dir += 360/10;
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(5){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, true);
		dir -= 360/5;
	}
	dir += 360/10;
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(5){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, true);
		dir -= 360/5;
	}
	wait(540);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");

	loop(50){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(2){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_BLUE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 1.5);
				ObjMove_AddPatternA2(obj, 240, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/2;
		}
		dir += 3.5;
		wait(3);
	}
	wait(150);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(50){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(2){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_AQUA, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 1.5);
				ObjMove_AddPatternA2(obj, 240, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/2;
		}
		dir -= 3.5;
		wait(3);
	}
	wait(120);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");
	let w = 70;
	dir = 0;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		if(w > 5){w -= 5;}
		ApocalypseBeam(GetCenterX, GetCenterY, GetPointAngle(GetPlayerX, GetPlayerY, GetCenterX, GetCenterY) + dir, 10, 60, 30, true);
		dir += rand(85, 95);
		wait(w);
	}
}

task fireN{
	let dir = 0;
	let dir2 = 0;

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	let x = GetPlayerX;
	ApocalypseBeam(x, 0, 90, 45, 250, 120, true);
	wait(60);

	loop(10){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(x, 0, GetPointAngle(GetPlayerX, GetPlayerY, x, 0), 25, 80, 60, false);
		wait(10);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(x, 0, -GetPointAngle(GetPlayerX, GetPlayerY, x, 0) + 180, 25, 80, 60, false);
		wait(10);
	}
	wait(120);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");
	
	loop(75){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(4){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PINK, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 1.5);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/4;
		}
		dir += 2;
		wait(2);
	}
	wait(120);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	ascent(x in 0 .. 3){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetClipMaxX/2 * x, 0, 90, 45, 80, 300, false);
		wait(10);
		
	}
	ascent(y in 0 .. 3){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(0, GetClipMaxY/2 * y, 0, 45, 80, 300, false);
		wait(10);
	}
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");

	loop(75){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(4){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PURPLE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 1.5);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/4;
		}
		dir -= 2;
		wait(2);
	}
	wait(240);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	dir = GetPointAngle(GetCenterX, GetCenterY, GetPlayerX, GetPlayerY);
	loop(6){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, false);
		dir += 360/6;
		wait(10);
	}
	dir += 360/12;
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(6){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, true);
		dir -= 360/6;
	}
	dir += 360/12;
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(6){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, true);
		dir -= 360/6;
	}
	wait(540);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");

	loop(50){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(3){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_BLUE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 2.5);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/3;
		}
		dir += 5;
		wait(3);
	}
	wait(120);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(50){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(3){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_AQUA, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 2.5);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/3;
		}
		dir -= 5;
		wait(3);
	}
	wait(120);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");
	let w = 60;
	dir = 0;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		if(w > 5){w -= 5;}
		ApocalypseBeam(GetCenterX, GetCenterY, GetPointAngle(GetPlayerX, GetPlayerY, GetCenterX, GetCenterY) + dir, 10, 100, 30, true);
		dir += rand(85, 95);
		wait(w);
	}
}

task fireH{
	let dir = 0;
	let dir2 = 0;

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	let x = GetPlayerX;
	ApocalypseBeam(x, 0, 90, 45, 300, 120, true);
	wait(60);

	loop(10){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(x, 0, GetPointAngle(GetPlayerX, GetPlayerY, x, 0), 25, 80, 60, false);
		wait(10);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(x, 0, -GetPointAngle(GetPlayerX, GetPlayerY, x, 0) + 180, 25, 80, 60, false);
		wait(10);
	}
	wait(120);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");
	
	loop(75){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(4){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PINK, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 1.75);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/4;
		}
		dir += 2;
		wait(2);
	}
	wait(120);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	ascent(x in 0 .. 3){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetClipMaxX/2 * x, 0, 90, 45, 80, 300, false);
		wait(10);
		
	}
	ascent(y in 0 .. 3){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(0, GetClipMaxY/2 * y, 0, 45, 80, 300, false);
		wait(10);
	}
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");

	loop(75){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(4){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PURPLE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 1.75);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/4;
		}
		dir -= 2;
		wait(2);
	}
	wait(240);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	dir = GetPointAngle(GetCenterX, GetCenterY, GetPlayerX, GetPlayerY);
	loop(6){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 150, 120, false);
		dir += 360/6;
		wait(10);
	}
	dir += 360/12;
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(6){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 150, 120, true);
		dir -= 360/6;
	}
	dir += 360/12;
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(6){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 150, 120, true);
		dir -= 360/6;
	}
	wait(540);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");

	loop(50){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(4){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_BLUE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 2.75);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/4;
		}
		dir += 5;
		wait(3);
	}
	wait(120);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(50){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(4){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_AQUA, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 2.75);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/4;
		}
		dir -= 5;
		wait(3);
	}
	wait(120);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");
	let w = 60;
	dir = 0;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		if(w > 5){w -= 5;}
		ApocalypseBeam(GetCenterX, GetCenterY, GetPointAngle(GetPlayerX, GetPlayerY, GetCenterX, GetCenterY) + dir, 10, 100, 30, true);
		dir += rand(85, 95);
		wait(w);
	}
}

task fireL{
	let dir = 0;
	let dir2 = 0;

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	let x = GetPlayerX;
	ApocalypseBeam(x, 0, 90, 45, 300, 120, true);
	wait(60);

	loop(10){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(x, 0, GetPointAngle(GetPlayerX, GetPlayerY, x, 0), 25, 80, 60, false);
		wait(10);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(x, 0, -GetPointAngle(GetPlayerX, GetPlayerY, x, 0) + 180, 25, 80, 60, false);
		wait(10);
	}
	wait(120);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");
	
	loop(75){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(5){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PINK, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 2);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/5;
		}
		dir += 1.5;
		wait(2);
	}
	wait(120);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	ascent(x in 0 .. 4){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetClipMaxX/3 * x, 0, 90, 45, 50, 300, false);
		wait(10);
		
	}
	ascent(y in 0 .. 4){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(0, GetClipMaxY/3 * y, 0, 45, 50, 300, false);
		wait(10);
	}
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");

	loop(75){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(5){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PURPLE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 2);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/5;
		}
		dir -= 1.5;
		wait(2);
	}
	wait(240);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");

	dir = GetPointAngle(GetCenterX, GetCenterY, GetPlayerX, GetPlayerY);
	loop(8){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, false);
		dir += 360/8;
		wait(10);
	}
	dir += 360/16;
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(8){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, true);
		dir -= 360/8;
	}
	dir += 360/16;
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(8){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ApocalypseBeam(GetCenterX, GetCenterY, dir, 45, 100, 120, true);
		dir -= 360/8;
	}
	wait(540);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "doremy");

	loop(50){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(4){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_BLUE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 2.75);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/4;
		}
		dir += 5;
		wait(3);
	}
	wait(120);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	loop(50){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(95, 40, 0);
		PlaySoundA1(54, 50, 60);
		loop(4){
			loop(3){
				let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_AQUA, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.05, 0, 2.75);
				ObjMove_AddPatternA2(obj, 210, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
				dir2 += 360/3;
			}
			dir += 360/4;
		}
		dir -= 5;
		wait(3);
	}
	wait(120);



	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	SetCommonData("Boss", "usami");
	let w = 50;
	dir = 0;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		if(w > 5){w -= 5;}
		ApocalypseBeam(GetCenterX, GetCenterY, GetPointAngle(GetPlayerX, GetPlayerY, GetCenterX, GetCenterY) + dir, 10, 100, 30, true);
		dir += rand(85, 95);
		wait(w);
	}
}

task fireDoremy{
	let dir = 0;
	let dir2 = 0;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		if(GetCommonData("Boss", "usami") == "doremy"){
			PlaySoundA1(95, 40, 0);
			PlaySoundA1(54, 50, 60);
			loop(4){
				loop(3){
					let obj = ShotA1(GetPlayerX + 96*cos(dir), GetPlayerY + 96*sin(dir), 0.1, dir2 + dir + 180, PELLET_PURPLE, 10);
					ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0.1, 0, 1.5);
					ObjMove_AddPatternA2(obj, 150, NO_CHANGE, NO_CHANGE, 0.1, 0, 5);
					dir2 += 360/3;
				}
				dir += 360/4;
			}
			dir -= 3;
		}
		wait(3);
	}
}

task ApocalypseBeam(x, y, a, a_off, maxwidth, t, shoot){
	let dir = -a_off;

	PlaySoundA1(8, 60, 0);
	loop(3){
		DelayBeam(x, y, a + dir, a, 90);
		dir += a_off;
	}
	wait(60);

	if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
	let obj = CreateBlastLaserA1(x, y, 30, a, 200, 0, LARGE_MAGENTA, t + 15);
	let width = 0;
	ascent(c in 0 .. t+1){
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){break;}
		PlaySoundA1(57, 40, 0);

		if(c > t/4 && shoot){
			if(c % 3 == 0){
				let randwidth = rand(-(width/2 - 30), (width/2) - 30);
				let randlength = rand(100, 500);

				let shotpos = [x + randwidth*cos(a + 90) + randlength*cos(a), y + randwidth*sin(a + 90) + randlength*sin(a)];
				let shot = ShotA1(shotpos[0], shotpos[1], 0, rand(0, 360), FIRE_PURPLE+1000, 10);
				ObjMove_AddPatternA2(shot, (t - c) + 90, NO_CHANGE, NO_CHANGE, 0.025, 0, 1);
			}
		}


		Obj_SetValue(obj, "BlastLaserWid", width);
		width += maxwidth/t;
		yield;
	}
	loop(15){
		PlaySoundA1(57, 40, 0);
		Obj_SetValue(obj, "BlastLaserWid", width);
		width -= maxwidth/15;
		yield;
	}
	Obj_Delete(obj);

	task DelayBeam(x, y, a, a2, d){
		let obj = StraightLaserA1(x, y, a, 800, 40, 7200, ST_LASER_MAGENTA, d);

		let i = 0;
		loop(d - 30){
			ObjStLaser_SetAngle(obj, deceleration(a, a2, i/(d - 30)));
			i++;
			yield;
		}
		wait(25);
		Obj_Delete(obj);
	}
}

sub Cracks{
	ScreenShakeA1(10, 5);
	PlaySoundA1(118, 60, 0);
	Flash(30);

	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(obj, 29);
	ObjPrim_SetTexture(obj, GetCurrentScriptDirectory ~ "IMG/crack000.png");
	ObjSprite2D_SetSourceRect(obj, 0, 0, 512, 512);
	ObjSprite2D_SetDestCenter(obj);
	//ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
	ObjRender_SetScaleXYZ(obj, 0.75, 0.75, 0);
	ObjRender_SetPosition(obj, GetCenterX, GetCenterY, 0);

	wait(120);

	ScreenShakeA1(10, 5);
	PlaySoundA1(119, 70, 0);
	Flash(30);
	ObjPrim_SetTexture(obj, GetCurrentScriptDirectory ~ "IMG/crack001.png");

	wait(120);

	ScreenShakeA1(10, 5);
	PlaySoundA1(120, 80, 0);
	Flash(30);
	ObjPrim_SetTexture(obj, GetCurrentScriptDirectory ~ "IMG/crack002.png");

	wait(120);

	ScreenShakeA1(60, 5);
	PlaySoundA1(121, 90, 0);
	Flash(90);
	Obj_Delete(obj);
}

task Flash(t){
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(obj, 30);
	ObjPrim_SetTexture(obj, GetCurrentScriptDirectory ~ "IMG/Field.png");
	ObjSprite2D_SetSourceRect(obj, 0, 0, 512, 512);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj, GetCenterX, GetCenterY, 0);

	let a = 256;
	loop(t){
		ObjRender_SetAlpha(obj, a);
		a -= 256/t;
		yield;
	}
	Obj_Delete(obj);
}

task endTask{
	while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0) {
		yield;
	}
	ObjMove_SetPosition(bossObj, GetCenterX, GetCenterY);
	PlaySoundA1(29, 60, 0);
	PlaySoundA1(29, 30, 60);
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	ScreenShakeA1(20, 10);
	StartSlow(TARGET_ALL, 40);
	loop(30){
		PlaySoundA1(95, 50, 0);
		BossExplodeObject(bossX, bossY, "Cherry", rand(3, 5), rand(0, 360), [255, 0, 192], BLEND_ADD_ARGB);
		BossExplodeObject(bossX, bossY, "Cherry", rand(3, 5), rand(0, 360), [255, 255, 255], BLEND_ADD_ARGB);
		wait(4);
	}
	ScreenShakeA1(60, 10);
	BossExplosionEffect(bossObj, "Cherry", [255, 0, 192], [255, 0, 192], BLEND_ADD_ARGB);
	PlaySoundA1(29, 80, 0);

	StopSlow(TARGET_ALL);
	SetAutoDeleteObject(true);
	Obj_Delete(bossObj);
	wait(120);
	CloseScript(GetOwnScriptID());
}