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

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

let sheepify = false;
let psychokinesis = true;

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

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

	CutinPythonA1("Psychokinesis Dream Sign \"Telekinesis: Sheep Pasture\"", ["Easy", "Normal", "Hard", "Lunatic"][diff], GetCurrentScriptDirectory ~ "IMG/TwoCut.png", [192, 0, 128]);
	ObjEnemyBossScene_StartSpell(GetEnemyBossSceneObjectID);
	PlaySoundA1(13, 70, 0);

	//Move the boss onto the game field
	ObjMove_SetDestAtWeight(bossObj, GetCenterX, GetCenterY - 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(128, 128, 128, 128);
}

@Event{
	alternative(GetEventType())
	case(EV_REQUEST_LIFE){
		SetScriptResult(3000);
	}
	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(90);
	PlaySoundA1(17, 70, 0);
	ConcentrationEffect(bossObj, "Cherry", 60, 5, 128, [255, 0, 192], BLEND_ADD_ARGB);
	wait(60);
	PlaySoundA1(30, 70, 0);
	loop(30){
		BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 0, 192], BLEND_ADD_ARGB);
		BossExplodeObject(bossX, bossY, "Cherry", 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 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 fireE{
	let dir = 0;
	let switch = 1;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ObjAnim_SetAttackA2(bossObj, 150);
		psychokinesis = true;
		PlaySoundA1(15, 60, 0);

		ascent(i in 1 .. 4){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			loop(5){
				Trash(48*i, dir, rand(0.125, 0.25), round(rand(-0.4, 2.4)));
				dir += 360/5;
			}
			dir += 360/15;
			wait(6);
		}
		wait(60);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(17, 70, 0);
		ConcentrationEffect(bossObj, "Cherry", 60, 5, 128, [255, 0, 192], BLEND_ADD_ARGB);
		wait(60);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(30, 70, 0);
		loop(15){
			BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 0, 192], BLEND_ADD_ARGB);
			BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 255, 255], BLEND_ADD_ARGB);
		}
		Tag;
		PlaySoundA1(115, 100, 0);
		psychokinesis = false;
		sheepify = true;
		wait(30);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		moveDeceleration(bossObj, GetCenterX + rand(-96, 96), GetCenterY + rand(-64, -128), 60, true);
		sheepify = false;
		wait(180);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		Tag;
		wait(60);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		dir = GetAngleToPlayer(bossObj);
		loop(20){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			PlaySoundA1(95, 50, 0);
			loop(6){
				let obj = ShotA1(bossX, bossY, 2, dir, AMULET_PURPLE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0, 2*switch, 0);
				ObjMove_AddPatternA2(obj, 120, NO_CHANGE, NO_CHANGE, 0, 0, 0);
				dir += 360/6;
			}
			dir += ((360/18) + 1) * switch;
			wait(5);
		}
		switch *= (-1);
		wait(90);
	}
}

task fireN{
	let dir = 0;
	let switch = 1;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ObjAnim_SetAttackA2(bossObj, 150);
		psychokinesis = true;
		PlaySoundA1(15, 60, 0);

		ascent(i in 1 .. 4){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			loop(6){
				Trash(48*i, dir, rand(0.25, 0.5), round(rand(-0.4, 2.4)));
				dir += 360/6;
			}
			dir += 360/18;
			wait(6);
		}
		wait(60);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(17, 70, 0);
		ConcentrationEffect(bossObj, "Cherry", 60, 5, 128, [255, 0, 192], BLEND_ADD_ARGB);
		wait(60);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(30, 70, 0);
		loop(15){
			BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 0, 192], BLEND_ADD_ARGB);
			BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 255, 255], BLEND_ADD_ARGB);
		}
		Tag;
		PlaySoundA1(115, 100, 0);
		psychokinesis = false;
		sheepify = true;
		wait(30);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		moveDeceleration(bossObj, GetCenterX + rand(-96, 96), GetCenterY + rand(-64, -128), 60, true);
		sheepify = false;
		wait(180);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		Tag;
		wait(60);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		dir = GetAngleToPlayer(bossObj);
		loop(20){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			PlaySoundA1(95, 50, 0);
			loop(8){
				let obj = ShotA1(bossX, bossY, 2, dir, AMULET_PURPLE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0, 2*switch, 0);
				ObjMove_AddPatternA2(obj, 120, NO_CHANGE, NO_CHANGE, 0, 0, 0);
				dir += 360/8;
			}
			dir += ((360/24) + 1) * switch;
			wait(5);
		}
		switch *= (-1);
		wait(90);
	}
}

task fireH{
	let dir = 0;
	let switch = 1;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ObjAnim_SetAttackA2(bossObj, 150);
		psychokinesis = true;
		PlaySoundA1(15, 60, 0);

		ascent(i in 1 .. 5){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			loop(6){
				Trash(32*i, dir, rand(0.25, 0.75), round(rand(-0.4, 2.4)));
				dir += 360/6;
			}
			dir += 360/18;
			wait(6);
		}
		wait(60);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(17, 70, 0);
		ConcentrationEffect(bossObj, "Cherry", 60, 5, 128, [255, 0, 192], BLEND_ADD_ARGB);
		wait(60);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(30, 70, 0);
		loop(15){
			BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 0, 192], BLEND_ADD_ARGB);
			BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 255, 255], BLEND_ADD_ARGB);
		}
		Tag;
		PlaySoundA1(115, 100, 0);
		psychokinesis = false;
		sheepify = true;
		wait(30);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		moveDeceleration(bossObj, GetCenterX + rand(-96, 96), GetCenterY + rand(-64, -128), 60, true);
		sheepify = false;
		wait(180);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		Tag;
		wait(60);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		dir = GetAngleToPlayer(bossObj);
		loop(20){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			PlaySoundA1(95, 50, 0);
			loop(8){
				let obj = ShotA1(bossX, bossY, 2, dir, AMULET_PURPLE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0, 2*switch, 0);
				ObjMove_AddPatternA2(obj, 120, NO_CHANGE, NO_CHANGE, 0, 0, 0);

				let obj2 = ShotA1(bossX, bossY, 1, -dir, AMULET_MAGENTA, 10);
				ObjMove_AddPatternA2(obj2, 60, NO_CHANGE, NO_CHANGE, 0, -1*switch, 0);
				ObjMove_AddPatternA2(obj2, 120, NO_CHANGE, NO_CHANGE, 0, 0, 0);
				dir += 360/8;
			}
			dir += ((360/24) + 1.5) * switch;
			wait(5);
		}
		switch *= (-1);
		wait(90);
	}
}

task fireL{
	let dir = 0;
	let switch = 1;
	loop{
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		ObjAnim_SetAttackA2(bossObj, 150);
		psychokinesis = true;
		PlaySoundA1(15, 60, 0);
		ascent(i in 1 .. 6){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			loop(5){
				Trash(32*i, dir, rand(0.25, 0.75), round(rand(-0.4, 2.4)));
				dir += 360/5;
			}
			dir += 360/15;
			wait(6);
		}
		wait(60);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(17, 70, 0);
		ConcentrationEffect(bossObj, "Cherry", 60, 5, 128, [255, 0, 192], BLEND_ADD_ARGB);
		wait(60);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		PlaySoundA1(30, 70, 0);
		loop(15){
			BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 0, 192], BLEND_ADD_ARGB);
			BossExplodeObject(bossX, bossY, "Cherry", rand(3, 6), rand(0, 360), [255, 255, 255], BLEND_ADD_ARGB);
		}
		Tag;
		PlaySoundA1(115, 100, 0);
		psychokinesis = false;
		sheepify = true;
		wait(30);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		moveDeceleration(bossObj, GetCenterX + rand(-96, 96), GetCenterY + rand(-64, -128), 60, true);
		sheepify = false;
		wait(180);
		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		Tag;
		wait(60);

		if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
		dir = GetAngleToPlayer(bossObj);
		loop(20){
			if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){return;}
			PlaySoundA1(95, 50, 0);
			loop(10){
				let obj = ShotA1(bossX, bossY, 2, dir, AMULET_PURPLE, 10);
				ObjMove_AddPatternA2(obj, 60, NO_CHANGE, NO_CHANGE, 0, 2*switch, 0);
				ObjMove_AddPatternA2(obj, 120, NO_CHANGE, NO_CHANGE, 0, 0, 0);

				let obj2 = ShotA1(bossX, bossY, 1, -dir, AMULET_MAGENTA, 10);
				ObjMove_AddPatternA2(obj2, 60, NO_CHANGE, NO_CHANGE, 0, -1*switch, 0);
				ObjMove_AddPatternA2(obj2, 120, NO_CHANGE, NO_CHANGE, 0, 0, 0);
				dir += 360/10;
			}
			dir += ((360/30) + 1.5) * switch;
			wait(5);
		}
		switch *= (-1);
		wait(90);
	}
}

task Trash(rad, a, aplus, type){
	let renderRect = [];
	let sheepScale = 1;
	let isSheep = false;

	alternative(type)
	case(0){ //wall thing
		renderRect = [0, 0, 80, 80];
		sheepScale = 1;
	}
	case(1){ //computer
		renderRect = [96, 0, 192, 88];
		sheepScale = 1.25;
	}
	case(2){ //brick
		renderRect = [192, 0, 240, 48];
		sheepScale = 0.625;
	}

	let obj = ShotA1(bossX + rad*cos(a), bossY + rad*sin(a), 0, a, 1, 0);
	Obj_SetVisible(obj, false);
	ObjShot_SetSpellResist(obj, true);
	ObjShot_SetIntersectionCircleA1(obj, 22 * sheepScale * 0.5);

	let render = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(render, 60);

	Render;

	let wasPsychic = true;
	let bounceCount = [1, 2, 2, 2][diff];
	while(!Obj_IsDeleted(obj)){
		if(psychokinesis){
			if(!wasPsychic){
				if(isSheep){PlaySoundA1(114, 60, 0);}
				a = GetPointAngle(ObjMove_GetX(obj), ObjMove_GetY(obj), bossX, bossY);
				rad = GetDistance(ObjMove_GetX(obj), ObjMove_GetY(obj), bossX, bossY);
				wasPsychic = true;
			}

			ObjMove_SetSpeed(obj, 0);
			ObjMove_SetAngle(obj, a + 90*(aplus/(|aplus|)));
			ObjMove_SetPosition(obj, bossX + rad*cos(a), bossY + rad*sin(a));
			a += aplus;
		}else{
			wasPsychic = false;
			ObjMove_SetSpeed(obj, [rand(1, 2), rand(1, 3), rand(1.5, 4), rand(2, 4)][diff]);

			if((ObjMove_GetX(obj) < 0 || ObjMove_GetX(obj) > GetClipMaxX) && bounceCount > 0){
				PlaySoundA1(112, 60, 0);
				ObjMove_SetAngle(obj, -ObjMove_GetAngle(obj) + 180);
				ObjMove_SetPosition(obj, ObjMove_GetX(obj) + 8*cos(ObjMove_GetAngle(obj)), ObjMove_GetY(obj) + 8*sin(ObjMove_GetAngle(obj)));
				bounceCount--;

				let dir = rand(0, 360);
				loop(5){
					ShotB2(ObjMove_GetX(obj), ObjMove_GetY(obj), 2*cos(dir), 2*sin(dir), -0.005*cos(dir), 0.02, 0, 3, [DOT_WHITE, SMALL_WHITE][bounceCount], 10);
					dir += 360/5;
				}

			}
			if(ObjMove_GetY(obj) < 0 && bounceCount > 0){
				PlaySoundA1(112, 60, 0);
				ObjMove_SetAngle(obj, -ObjMove_GetAngle(obj));
				ObjMove_SetPosition(obj, ObjMove_GetX(obj) + 8*cos(ObjMove_GetAngle(obj)), ObjMove_GetY(obj) + 8*sin(ObjMove_GetAngle(obj)));
				bounceCount--;

				let dir = rand(0, 360);
				let num = [3, 4, 5, 6][diff];
				loop(num){
					ShotB2(ObjMove_GetX(obj), ObjMove_GetY(obj), 2*cos(dir), 2*sin(dir), -0.005*cos(dir), 0.02, 0, 3, [DOT_WHITE, SMALL_WHITE][bounceCount], 10);
					dir += 360/num;
				}
			}
		}
		yield;
	}

	task Render{
		ObjPrim_SetTexture(render, GetCurrentScriptDirectory ~ "IMG/garbage_00.png");
		ObjSprite2D_SetSourceRect(render, renderRect[0], renderRect[1], renderRect[2], renderRect[3]);
		ObjSprite2D_SetDestCenter(render);
		ObjRender_SetAlpha(render, 0);
		ObjRender_SetScaleXYZ(render, 0.5, 0.5, 0);

		let c = 0;
		while(!Obj_IsDeleted(obj)){
			if(sheepify && !isSheep){
				EnemyExplosionEffect(obj, "Cherry", [255, 255, 255], [255, 255, 255]);

				isSheep = true;
				ObjPrim_SetTexture(render, GetCurrentScriptDirectory ~ "IMG/sheep.png");
				ObjSprite2D_SetSourceRect(render, 0, 0, 128, 64);
				ObjSprite2D_SetDestCenter(render);
				ObjRender_SetScaleXYZ(render, sheepScale * 0.5, sheepScale * 0.5, 0);
			}

			if(isSheep){
				ObjRender_SetAngleZ(render, ObjMove_GetAngle(obj));
			}

			if(c <= 60){
				ObjRender_SetAlpha(render, linear(0, 255, c/60));
				c++;
			}else{
				ObjShot_SetIntersectionCircleA1(obj, 22 * sheepScale * 0.5);
			}


			ObjRender_SetPosition(render, ObjMove_GetX(obj), ObjMove_GetY(obj), 0);
			yield;
		}
		Obj_Delete(render);
	}
}

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