#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Spell 4 - The Raging Puppeter \"Overheated Dolls\""]
#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/charge.wav");
let discharge = SoundSFX(GetCurrentScriptDirectory~"./../lib/se/famdie.wav");
let boom = SoundSFX(GetCurrentScriptDirectory~"./../lib/se/morri.wav");

@Event{
    alternative(GetEventType())
    case(EV_REQUEST_LIFE){
        SetScriptResult(2000);
    }
    case(EV_REQUEST_TIMER){
        SetScriptResult(82);
    }
	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("Pretty", false);
	SetCommonData("Sun", 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("The Raging Puppeter \"Overheated Dolls\"", 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);
	//1=B; 2=R
	renderTinyGoreF(objEnemy, type);
	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;}
		
		anv = ObjMove_GetAngle(objEnemy);
		spawn(objEnemy);
		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);}
		
			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*1.5, 150, 2, 10/2, 1, BLEND_ADD_ARGB, 255, 255, 0, 8);
wait(60*1.25);
PlaySFX(discharge);
ConcentrationExplosion(bx, by, 60*1.5, 250, 8/4, 1, BLEND_ADD_ARGB, 179, 179, 0, 8);
wait(60*1.5);
ObjEnemy_SetDamageRate(objBoss, 40, 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 = 4;
		let v = 7;
		let n = 50;
	//}

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

task spawn(obj){
wait(60*1);
	if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
	let rang = ObjMove_GetAngle(obj);
	
		let ang = 0;
		let b = [10, 120];
	
	while(!Obj_IsDeleted(obj)){
		rang = angtoP(obj);
		BFX_Release(ObjMove_GetX(obj), ObjMove_GetY(obj), 150, 60);
		
			if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}
			if(Obj_IsDeleted(obj)){return;}
			
			//rang += n;
			
			PlaySFX(discharge);
			ascent(j in 0..b[1]){
				ang = rang + 360/b[1]*j;
				
				//Smol Fire
				CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), rand(1/3,3), ang, 44, 5);
				CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), rand(1/4,4), ang, 54, 5);
			}
			
			PlaySFX(boom);
			ObjSound_SetVolumeRate(boom, 40);
			ascent(j in 0..b[0]){
				ang = angtoP(obj) + 360/b[0]*j;
				
				//Big Fire
				let u = CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 4, ang, 363, 5);
				let uu = CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 3, ang, 366, 5);
				let uuu = CreateShotA1(ObjMove_GetX(obj), ObjMove_GetY(obj), 2, ang, 369, 5);
				
				Obj_SetRenderPriority(u, 0.3);
				Obj_SetRenderPriority(uu, 0.3);
				Obj_SetRenderPriority(uuu, 0.3);
			}
		
		Obj_Delete(obj);
		yield;
	}
	
	wait(60*2);
	Obj_SetValue(objBoss, "cast", 0);
}

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));
    }
	
    Obj_Delete(objBoss);
    DeleteShotAll(TYPE_ALL, TYPE_ITEM);
    SetAutoDeleteObject(true);
    CloseScript(GetOwnScriptID());
    return;
}