#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Spell 5 - Restless Research \"Four Seasons\""]
#Text[""]
#BGM["./../bgm/Boss.ogg"]
#Background["./../BG.txt"]
#Player["./../player/Ultima's DDC Reimu B/ReimuH.dnh", "./../player/gt_medicine/PracticeP.txt"]
#System["./../System/Default_System.txt"]

#include "./../lib/Shot/ZUNShot/ZUNShot_Const.txt"

#include "./../lib/Render/EnemyMark.txt"
#include "./../FxnSFX.dnh"
#include "./../lib/Funcs.txt"
#include "./../lib/GoodLib.txt"
#include "./../lib/Render/MagicCircle.txt"

#include "./../lib/Render/Gizmo's Touhou Boss Sprite Library/GizmoSpriteLibrary.txt"
#include "./../lib/Render/Gizmo's Touhou Boss Sprite Library/GizmoFSpriteLibrary.txt"
#include "./../lib/Cutins/Cutin/Cutin.txt"

let objBoss;
let pass;

let count = 0;

let objScene = GetEnemyBossSceneObjectID();
let shot = SoundSFX(GetCurrentScriptDirectory~"./../lib/se/shot1.wav");
let shot2 = SoundSFX(GetCurrentScriptDirectory~"./../lib/se/shot2.wav");
let charge = SoundSFX(GetCurrentScriptDirectory~"./../lib/se/charge2.wav");
let discharge = SoundSFX(GetCurrentScriptDirectory~"./../lib/se/famdie.wav");
let boom = SoundSFX(GetCurrentScriptDirectory~"./../lib/se/morri.wav");
let ll = SoundSFX(GetCurrentScriptDirectory~"./../lib/se/laser1.wav");

@Event{
    alternative(GetEventType())
    case(EV_REQUEST_LIFE){
        SetScriptResult(2000);
    }
    case(EV_REQUEST_TIMER){
        SetScriptResult(102);
    }
	case(EV_REQUEST_IS_DURABLE_SPELL){
		SetScriptResult(true);
	}
    case(EV_REQUEST_SPELL_SCORE){
        SetScriptResult(1000000);
    }
}

@Initialize{
    objBoss = ObjEnemy_Create(OBJ_ENEMY_BOSS);
    ObjEnemy_Regist(objBoss);
	
	SetCommonData("Sun", false);
	SetCommonData("Out", true);
	BFX_Init();
	
    ObjMove_SetDestAtFrame(objBoss, gx(), 130, 50);
	StartSpell;
	TDrawLoop;
    TFinalize;
}

@MainLoop{
    ObjEnemy_SetIntersectionCircleToShot(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 32); 
    ObjEnemy_SetIntersectionCircleToPlayer(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 24);
    if(count == 0){
        round_bullets;
        count = 0;
    } 
    count++;
    yield;
}

task StartSpell{
wait(60*3);
	ObjEnemyBossScene_StartSpell(objScene);
	
	let objEnemy = GetEnemyBossObjectID[0];
	wait(30);
	
	let rumia = GetCurrentScriptDirectory() ~ "../img/Cutin.png";
	ObjCutin_SetSpellcardS4("Restless Research \"Four Seasons\"", rumia, BYAKUREN, 255, 153, 255);
	ObjCutin_LaunchS3(BYAKUREN, rumia, "Normal");
}

task TDrawLoop{
	renderAlicePCB(objBoss);
	EnemyMarker(objBoss);
	magiccircle(objBoss, 1, 0, 150, 100, true);
	DrawName("Alice Margatroid", "YELLOW");
}

task Enemy(type, x, y, frame, gg){
	let objEnemy;
	objEnemy = ObjEnemy_Create(OBJ_ENEMY);
    ObjEnemy_Regist(objEnemy);
	
	ObjMove_SetX(objEnemy, bx);
	ObjMove_SetY(objEnemy, by);
	
	hitbox(objEnemy, 20);
	
	pass = 0;
	Obj_SetValue(pass, "die", 1);
	
	let ex = 0;
	let ey = 0;
	let ang;
	let rang = 90;
	
	let b = 40;
	
	let anv = ObjMove_GetAngle(objEnemy);
	
	let rgb = [0, 0, 0];
	let part = 0;

	if(type == "0"){
		renderTinyGoreF(objEnemy, 4);
		
		rgb[0] = 255;
		rgb[1] = 194;
		rgb[2] = 102;
		
		part = 5;
		
	} //Aut
	
	if(type == "1"){
		renderTinyGoreF(objEnemy, 1);
		
		rgb[0] = 204;
		rgb[1] = 255;
		rgb[2] = 255;
		
		part = 7;
		
	} //Win
	
	if(type == "2"){
		renderTinyGoreF(objEnemy, 3);
		
		rgb[0] = 217;
		rgb[1] = 102;
		rgb[2] = 255;
		
		part = 2;
		
	} //Spr
	
	if(type == "3"){
		renderTinyGoreF(objEnemy, 2);
		
		rgb[0] = 179;
		rgb[1] = 179;
		rgb[2] = 0;
		
		part = 8;
		
	} //Sum
	
	magiccircle(objEnemy, 0.5, 191, 64, 64, false);
	
	ObjMove_SetX(objEnemy, bx);
	ObjMove_SetY(objEnemy, by);
	
	ObjMove_SetDestAtFrame(objEnemy, x, y, frame);
	
	wait(frame*2);
	
	while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 0){
		if(Obj_GetValueD(pass, "die", 1) == 0){Obj_Delete(objEnemy);}
		if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
		if(Obj_IsDeleted(objBoss)){return;}
		if(Obj_IsDeleted(objEnemy)){return;}
		
		anv = ObjMove_GetAngle(objEnemy);
		
		ex = ObjMove_GetX(objEnemy);
		ey = ObjMove_GetY(objEnemy);
		
		PlaySFX(discharge);
		ConcentrationExplosion(bx, by, 60*1.5, 80, 8/4, 1, BLEND_ADD_ARGB, rgb[0], rgb[1], rgb[2], part);
		
		spawn(objEnemy, type);
		ascent(A in 0..1){
			if(Obj_GetValueD(pass, "die", 1) == 0){Obj_Delete(objEnemy);}
			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
			
			ex = ObjMove_GetX(objEnemy);
			ey = ObjMove_GetY(objEnemy);
			
			ascent(i in 0..b){
				ang = anv + 360/b*i;
				
				//ObjMove_SetDestAtFrame(objEnemy, gx+gg, 30, 60*1);
			}
			
			//anv += turn;
			wait(60*1);
		}
		
		//Obj_Delete(objEnemy);
		wait(60*8);
	}
	
	
	
	task hitbox(obj, rad){
		wait(frame*2);
		while(!Obj_IsDeleted(obj)){
			if(ObjMove_GetX(objEnemy) <= 0){Obj_Delete(objEnemy);}
			if(ObjMove_GetX(objEnemy) >= stgw){Obj_Delete(objEnemy);}
			
			if(ObjMove_GetY(objEnemy) <= 0){Obj_Delete(objEnemy);}
			if(ObjMove_GetY(objEnemy) >= stgh){Obj_Delete(objEnemy);}
			
			if(Obj_IsDeleted(objBoss)){Obj_Delete(objEnemy);}
		
			ObjEnemy_SetIntersectionCircleToShot(objEnemy, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), rad); 
			ObjEnemy_SetIntersectionCircleToPlayer(objEnemy, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), rad);
			yield;
		}
	}
}

task round_bullets{
ObjEnemy_SetDamageRate(objBoss, 0, 0);
wait(90);
PlaySFX(charge);
Concentration(bx, by, 60*3, 300, 2, 10/2, 1, BLEND_ADD_ARGB, 102, 153, 153, 4);
wait(60*3.25);
PlaySFX(discharge);
ConcentrationExplosion(bx, by, 60*1.5, 250, 8/4, 1, BLEND_ADD_ARGB, 209, 224, 224, 4);
wait(60*1.5);
ObjEnemy_SetDamageRate(objBoss, 14, 25);
    if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;} //Default kill to prevent (0,0) spawning
    let rang = GetAngleToPlayer(objBoss);
	
	//{
		let ang;
		
		let l = 100;
		let b = 1;
		let v = 7;
		let n = 50;
		
		let vt = 0;
		let time = 7;
	//}

    while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 0){
		ascent(a in 0..4){
			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
			if(vt >= 4){ vt = 0;}
			Obj_SetValue(objBoss, "cast", 1);
			wait(60*1);
			
			rang = rand(180,360);
			l = rand(50,100);
			ascent(i in 0..b){
				if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
				ang = rang + 360/b*i;
				
				Enemy(IntToString(vt), bx + l*cos(ang), by + l*sin(ang), 60*1, n);
				
				
			}
			
			vt++;
			n = rand(-150,150);
			
			wait(60*time);
		}
		
		time -= 2;
		wait(60*5);
		yield;
    }
}	

task spawn(obj, type){
Obj_SetValue(objBoss, "cast", 0);
wait(60*1);
	if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
		let ang = 0;
		let any = 0;
		let n = 2;
		
		let aut = 5;
		let win = [80, 2];
		let spr = [7, 2];
		let sum = [8, 40, 100];
	
	while(!Obj_IsDeleted(obj)){
			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
			if(Obj_IsDeleted(obj)){return;}
			
			if(type == "0"){
				WriteLog("Autmun");
				let rang = ObjMove_GetAngle(obj);
				
				ascent(tt in 0..180){
					if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
					if(Obj_IsDeleted(obj)){return;}
					
					PlaySFX(shot);
					ascent(j in 0..aut){
						ang = rang + 360/aut*j;
					
						let g = CreateShotA2(ObjMove_GetX(obj), ObjMove_GetY(obj), 0, ang, +1/40, 7, 283, 5);
						ObjMove_SetAngularVelocity(g, n);
						
						n *= -1;
						ObjMove_AddPatternA2(g, 60*3, 2, NO_CHANGE, 0, 0, 0);				
					}
					
					
					rang += 29;
					wait(60*1/60);
				}
			}
			
			if(type == "1"){
				WriteLog("Winter");
				let rang = ObjMove_GetAngle(obj);
				
				miko;
				ascent(tt in 0..8){
					if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
					if(Obj_IsDeleted(obj)){return;}
					
					PlaySFX(shot2);
					ascent(j in 0..win[0]){
						ang = rang + 360/win[0]*j;
					
						CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), rand(1,3), ang, 144, 5);
					}
					
					rang += 2;
					wait(60*1/2);
				}
				
				task miko(){
					ascent(tt in 0..180){
						if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
						if(Obj_IsDeleted(obj)){return;}
						
						PlaySFX(shot);
						ascent(j in 0..win[1]){
							ang = rang + 360/win[1]*j;
					
							CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 2, ang, 404, 5);
						}
					
						rang += 13;
						wait(60*1/24);
					}
				}
			}
			
			if(type == "2"){
				WriteLog("Spring");
				let rang = ObjMove_GetAngle(obj);
				let ranx = ObjMove_GetAngle(obj);
				
				miko;
				
				ascent(tt in 0..20){
					if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
					if(Obj_IsDeleted(obj)){return;}
					
					PlaySFX(shot);
					ascent(j in 0..spr[0]){
						ang = rang + 360/spr[0]*j;
						any = ranx + 360/spr[0]*j;
					
						CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 4, ang, 337, 5);
						CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 4, any, 337, 5);
					}
					
					rang += 8;
					ranx -= 8;
					
					wait(60*1/16);
				}
				
				task miko(){
					let r = GetAngleToPlayer(obj);
					ascent(tt in 0..15){
						if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
						if(Obj_IsDeleted(obj)){return;}
						
						r = GetAngleToPlayer(obj);
						bitch();
						ascent(j in 0..spr[1]){
							ang = r + 360/spr[1]*j;
					
							CreateStraightLaserA1(ObjMove_GetX(obj), ObjMove_GetY(obj), ang, 500, 100, 60*1/2, 23, 60*1.5);
						}

						wait(60*1/6);
					}
				}
				
				task bitch(){
					wait(60 * 1.5);
					PlaySFX(ll);
				}
			}
			
			if(type == "3"){
				WriteLog("Summer");
				let rang = ObjMove_GetAngle(obj);
				let ranx = ObjMove_GetAngle(obj);
				let l = 6;
				
				ascent(tt in 0..90){
					if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
					if(Obj_IsDeleted(obj)){return;}
					if(l < 1/16){l = 6;}
					
					PlaySFX(shot);
					ascent(j in 0..sum[0]){
						ang = rang + 360/sum[0]*j;
						any = ranx + 360/sum[0]*j;
					
						CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), l, ang, 75, 5);
						CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), l, any, 76, 5);
					}
					
					l -= 1/16;
					
					rang += 57;
					ranx -= 57;
					
					wait(60*1/16);
				}
				
				PlaySFX(discharge);
				ascent(j in 0..sum[2]){
					ang = rang + 360/sum[2]*j;
					
					//Smol Fire
					CreateShotA2(ObjMove_GetX(obj), ObjMove_GetY(obj), 0, ang, 1/3, rand(1/3,3), 374, 5);
					CreateShotA2(ObjMove_GetX(obj), ObjMove_GetY(obj), 0, ang, 1/4, rand(1/4,4), 371, 5);
				}
				
				PlaySFX(boom);
				ObjSound_SetVolumeRate(boom, 40);
				ascent(j in 0..sum[1]){
					ang = rang + 360/sum[1]*j;
					
					//Big Fire
					CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 4, ang, 376, 5);
					CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 3, ang, 378, 5);
					CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 2, ang, 380, 5);
				}
			}
		
		Obj_Delete(obj);
		yield;
	}
	
	wait(60*2);
}

task DelayLaser(x, y, ang, l, w, dt, graph, delay){
	let objlaser = CreateStraightLaserA1(x, y , ang, l, w, dt, graph, delay);
	ObjStLaser_SetSource(objlaser, false);
	//ObjStLaser_SetAngle(objlaser, angtoP(objBoss));
	
	loop(delay-1){
		if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){Obj_Delete(objlaser); return;}
		yield;
	}
	Obj_Delete(objlaser);
}

task BulletReflectQED(objBullet){
    while(ObjMove_GetX(objBullet)>0&&ObjMove_GetX(objBullet)<GetStgFrameWidth&&ObjMove_GetY(objBullet)>0){yield;} 
	if(ObjMove_GetX(objBullet)<=0){
	    ObjMove_SetX(objBullet, 0);
		ObjMove_SetAngle(objBullet, 180-ObjMove_GetAngle(objBullet));
    }else if(ObjMove_GetX(objBullet)>=GetStgFrameWidth){
	    ObjMove_SetX(objBullet, GetStgFrameWidth);
		ObjMove_SetAngle(objBullet, 180-ObjMove_GetAngle(objBullet));
    }else if(ObjMove_GetY(objBullet)<=0){
	    ObjMove_SetY(objBullet, 0);
		ObjMove_SetAngle(objBullet, -1 * ObjMove_GetAngle(objBullet));

    }		
	ObjMove_SetSpeed(objBullet, 2);
	ObjRender_SetAlpha(objBullet, 255);
	ObjShot_SetIntersectionEnable(objBullet, true);
}

task TFinalize {
    while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 0){yield;}
	
	if(ObjEnemyBossScene_GetInfo(objScene, INFO_PLAYER_SHOOTDOWN_COUNT) + ObjEnemyBossScene_GetInfo(objScene, INFO_PLAYER_SPELL_COUNT) == 0){
		SetPlayerLife(GetPlayerLife() + 1);
		AddScore(ObjEnemyBossScene_GetInfo(objScene, INFO_SPELL_SCORE));
    }
	
	ded();
	wait(60*6);
	
    CloseScript(GetOwnScriptID());
    return;
}

task ded(){
	loop(6){ feathers;}
	wait(60*1/2);
	StartSlow(TARGET_ALL, 30);
		ConcentrationExplosion(bx, by, 60*2, 100, 20/4, 1, BLEND_ADD_ARGB, 255, 0, 0, 1);
		ConcentrationExplosion(bx, by, 60*2, 150, 20/4, 1, BLEND_ADD_ARGB, 0, 255, 0, 1);
		ConcentrationExplosion(bx, by, 60*2, 200, 20/4, 1, BLEND_ADD_ARGB, 0, 0, 255, 1);
		PlaySFX(boom);
		wait(60 * 1);
		
		ConcentrationExplosion(bx, by, 60*2, 250, 20/4, 2, BLEND_ADD_ARGB, 255, 0, 255, 1);
		ConcentrationExplosion(bx, by, 60*2, 100, 20/4, 2, BLEND_ADD_ARGB, 255, 255, 0, 1);
		ConcentrationExplosion(bx, by, 60*2, 250, 20/4, 2, BLEND_ADD_ARGB, 0, 255, 255, 1);
		
	StartSlow(TARGET_ALL, 9);
		SetCommonData("CardD", false);
		SetAutoDeleteObject(true);
		
		PlaySFX(boom);
		wait(60 * 1);
		DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	StopSlow(TARGET_ALL);
	
	PlaySFX(boom);
	ConcentrationExplosion(gx, 130, 60*2, 512, 20/4, 2, BLEND_ADD_ARGB, 255, 255, 153, 1);
	shake(11, 50, 0);
	
	Obj_Delete(objBoss);
	
}

task feathers{
	while(GetCommonData("CardD",true)==true){
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		let p = GetCurrentScriptDirectory ~ "./../img/ded.png";
		ObjPrim_SetTexture(obj,p);
		ObjSprite2D_SetSourceRect(obj,136,2,175,55);
		ObjSprite2D_SetDestRect(obj,-19.5,-26.5,19.5,26.5);	
		ObjRender_SetPosition(obj,bx,by,0);
		
		PlaySFX(shot);
		ObjSound_SetVolumeRate(shot, 40);
		mo(obj);
		
		wait(60*1/30);
	}
}

task mo(obj){
	ObjRender_SetAngleZ(obj,rand(0,360));
	let x = rand(20,-20);
	let y = rand(20,-20);
	let a = 255;
	loop(20){
		ObjRender_SetPosition(obj,ObjRender_GetX(obj)+x,ObjRender_GetY(obj)+y,0);
		a-=255/20;
		ObjRender_SetAlpha(obj,a);
		yield;
	}
	Obj_Delete(obj);
}

task shake(magnitude,duration,delay){
	wait(delay);
	loop(duration){
		Set2DCameraFocusX(GetStgFrameWidth/2+rand(-magnitude,magnitude));
		Set2DCameraFocusY(GetStgFrameHeight/2+rand(-magnitude,magnitude));
		yield;
	}
	Set2DCameraFocusX(GetStgFrameWidth/2);
	Set2DCameraFocusY(GetStgFrameHeight/2);
}