#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Boss Spellcard 5"]
#Background["./Scene/Background.txt"]
#Text[" \"Crystallized Silver\" "]
#Player["./Player/Reimu/Reimu.txt"]
#System["./System/Default_System.txt"]

let bossObj;
let pobj = GetPlayerObjectID;

#include "./Lib/AllStarShot_Const.dnh"
#include "./Functions/Functions_Index.dnh"

@Initialize{
	// Initialize: Works when starting up Danmakufu PH3

	//  Defines a Boss and Registers it.
	bossObj = CreateBoss;
	
	let LettyPath = GetCurrentScriptDirectory ~ "./Img/Boss/Letty Sprite.png"; //Place to select sprite 
	AnimateBossA1_CtC(bossObj,LettyPath);
	
	if(GetCommonData("Is Plural Script",false) == false){
		ObjMove_SetPosition(bossObj,GetStgFrameWidth/2,128);
	}
	
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	
	
	mainTask; //Runs Maintask
	
}

@Event{
	// Event: Sets the Boss's Specs
	
		// Sets Boss's Life and Timer
		alternative(GetEventType() )
		case(EV_REQUEST_LIFE) {
			SetScriptResult(10000);
		}
		case(EV_REQUEST_SPELL_SCORE) {
			SetScriptResult(200000);
		}
		case(EV_REQUEST_TIMER) {
			SetScriptResult(70);
			Timeout;
		}

}

@MainLoop{
	// MainLoop: Runs throughout the script.
	
	yield;

}

@Finalize{
}

task mainTask{
	end;	
	if(GetCommonData("Is Plural Script",false) == false){
		wait(30);
	}
	ObjMove_SetDestAtWeight(bossObj,GetStgFrameWidth/2,GetStgFrameHeight/2-72,10,5);
	wait(60);
	ConcentrateA1_Rainbow(bossObj,"Snow",320);
	wait(120);
	Burst_Rainbow(bossObj,"Snow","Long");
	SetCommonData("Boss Type","LETTY");
	let sceneObj = GetEnemyBossSceneObjectID;
	ObjEnemyBossScene_StartSpell(sceneObj);
	CutIn("\"Crystallized Silver\""); 		
	summon;
	wait(75);
	SetBossHitbox(32,32);
	ConcentrateA1(bossObj,"Snow","AQUA",300,"Long");
	wait(120);
	Burst(bossObj,"Snow","AQUA","Long");
	phase1;
	wait(480);
	ConcentrateA1(bossObj,"Snow","AQUA",300,"Short");
	wait(60);
	Burst(bossObj,"Snow","AQUA","Long");
	phase2;
	wait(480);
	ConcentrateA1(bossObj,"Snow","AQUA",300,"Short");
	wait(60);
	Burst(bossObj,"Snow","AQUA","Long");
	phase3;
}

task phase1{
	let inc = 0;
	while(!Obj_IsDeleted(bossObj)){
		ascent(i in 0..24){
			let t = mist(BossX+(96-i*2.5)*cos(inc),BossY+(96-i*2.5)*sin(inc),0,inc+180);
			SetMistGraphic(t,rand(118,126),70);
			let t1 = mist(BossX+(96-i*2.5)*cos(inc+180),BossY+(96-i*2.5)*sin(inc+180),0,inc);
			SetMistGraphic(t1,rand(118,126),70);
			inc+=196;
			wait(2);
		}
		wait(120);
	}
}

task phase2{
	FormLaserAttack("LEFT");
	FormLaserAttack("RIGHT");
	
	task FormLaserAttack(side){

		BossPhase = 2;
			let dir = 0;
		if(side == "LEFT"){
			PlaySnd("se_lazer01",55);
			ascent(i in 0..2){
				let obj = CreateDNHCurveLaserA1(BossX,BossY,8,dir,30,23,1017,0);
				CircleCurve(obj,8,"LEFT");
				ObjCrLaser_SetTipDecrement(obj,0.1);
				dir+=360/2;
			}
		}
		if(side == "RIGHT"){
			PlaySnd("se_lazer01",55);
			ascent(i in 0..2){
				let obj = CreateDNHCurveLaserA1(BossX,BossY,8,180-dir,30,23,1017,0);
				CircleCurve(obj,-8,"RIGHT");
				ObjCrLaser_SetTipDecrement(obj,0.1);
				dir+=360/2;
			}
		}
		wait(30);
		
		
		task CircleCurve(id, curve, side){ //id = Bullet id, curve = Angular Velocity

			ObjMove_SetAngularVelocity(id, curve); 
			ObjMove_SetSpeed(id, 0);
			ObjMove_SetAcceleration(id,curve/100);
			ObjMove_SetMaxSpeed(id,curve);
			ObjShot_SetIntersectionEnable(id,false);
			
			wait((360/curve)/2);
			
			ObjMove_SetAngularVelocity(id, curve/2); 
			wait(70);
			fireshots(id,side);
			
			task fireshots(ob,side){
				alternative(side)
				case("LEFT"){
					while(!Obj_IsDeleted(ob) && !Obj_IsDeleted(bossObj)){
						PlaySnd("se_tan02",20);
						let ads = CreateDNHShotA1(ObjMove_GetX(ob),ObjMove_GetY(ob),0,ObjMove_GetAngle(ob)+90,27,5);
						ObjMove_SetAcceleration(ads,0.075);
						ObjMove_SetMaxSpeed(ads,3.5);
						
						wait(7);
					}
				}
				
				case("RIGHT"){
					while(!Obj_IsDeleted(ob) && !Obj_IsDeleted(bossObj)){
						PlaySnd("se_tan02",20);
						let ads = CreateDNHShotA1(ObjMove_GetX(ob),ObjMove_GetY(ob),0,180+ObjMove_GetAngle(ob)-90,27,5);
						ObjMove_SetAcceleration(ads,0.075);
						ObjMove_SetMaxSpeed(ads,3.5);
						
						wait(7);
					}
				}
				kill(ob);
			}
			
			task kill(o){
				ascent(j in 0..64){
					ObjRender_SetAlpha(o,255-j*4);
					yield;
				}
				Obj_Delete(o);
			}
		}
	}
}

task phase3{
	CreateIceSpot(75,5,"LEFT");			
	CreateIceSpot(105,5,"RIGHT");
}

function CreateIceSpot(ang,sp,dire){
	let shotObj = ObjShot_Create(OBJ_SHOT);
	ObjShot_Regist(shotObj);
	
	ObjMove_SetSpeed(shotObj,sp);
	ObjMove_SetAngle(shotObj,ang);
	ObjMove_SetAcceleration(shotObj,-0.1);
	ObjMove_SetMaxSpeed(shotObj,0);
	ObjShot_SetDelay(shotObj,0);
	ObjShot_SetSpellResist(shotObj,true);
	Obj_SetVisible(shotObj,false);
	ObjShot_SetIntersectionEnable(shotObj,false);
	ObjShot_SetAutoDelete(shotObj,false);
	
	ObjMove_SetPosition(shotObj,BossX,BossY);
	PlaySnd("se_kira00",50);
	SetIceGraphic(shotObj,ang,dire,32);
	return shotObj;
}

task SetIceGraphic(obj,ang,dire,size){
	let path = GetCurrentScriptDirectory ~ "./Img/Boss/Ice Sprite.png";
	let mistObj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(mistObj,path);
	Freeze(obj,size);
	
	ObjSprite2D_SetSourceRect(mistObj,0,0,(size+2)*2,(size+2)*2);
	ObjSprite2D_SetDestCenter(mistObj);
	ObjSprite2D_SetSourceRect(mistObj,0,0,512,512);
	ObjRender_SetBlendType(mistObj,BLEND_ADD_ARGB);
	ObjRender_SetAlpha(mistObj,0);
	ObjRender_SetColor(mistObj,160,255,255);
	ObjRender_SetScaleXYZ(mistObj,1,1,0);
	Obj_SetRenderPriorityI(mistObj,30);
	
	form(mistObj);
	stick;
	yield;
	wait(119);
	move(obj,ang);
	
	task stick{
		while(!Obj_IsDeleted(obj) && !Obj_IsDeleted(mistObj) && !Obj_IsDeleted(bossObj)){
			ObjRender_SetPosition(mistObj,ObjMove_GetX(obj),ObjMove_GetY(obj),0);
			yield;
		}
		Obj_Delete(obj);
		Obj_Delete(mistObj);
	}
	
	task form(obj1){
		let s = 2;
		let rs = 0;
		
		loop(192/s){
			ObjRender_SetAlpha(obj1,rs);
			rs+=s;
			yield;
		}
		ObjRender_SetAlpha(obj1,192);
	}
	
	task move(obje,ang){
		if(dire == "LEFT"){
			ObjMove_SetAngle(obje,ang+135);
		}
		if(dire == "RIGHT"){
			ObjMove_SetAngle(obje,ang-135);
		}
		ObjMove_SetAcceleration(obje,0.04);
		ObjMove_SetMaxSpeed(obje,2.5);
		reflect(obje,mistObj);
	}
	
	
}

task reflect(obj,obj2){ 
		while(!Obj_IsDeleted(obj) && !Obj_IsDeleted(obj2) && !Obj_IsDeleted(bossObj)){
			if(ObjMove_GetX(obj) <= 0){
				ObjMove_SetAngle(obj, -ObjMove_GetAngle(obj) + 180);
			}

			if(ObjMove_GetX(obj) >= GetStgFrameWidth){
				ObjMove_SetAngle(obj, -ObjMove_GetAngle(obj) + 180);
			}
			
			if(ObjMove_GetY(obj) <= 0){
				ObjMove_SetAngle(obj, -ObjMove_GetAngle(obj));
			}
			
			if(ObjMove_GetY(obj) >= GetStgFrameHeight){
				ObjMove_SetAngle(obj, -ObjMove_GetAngle(obj));
			}
			
			yield;
		}
	}

task Freeze(obj,siz){
		let PX = ObjMove_GetX(pobj);
		let PY = ObjMove_GetY(pobj);
		while(!Obj_IsDeleted(obj) && !Obj_IsDeleted(bossObj)){
			if(GetDistance(ObjMove_GetX(pobj), ObjMove_GetY(pobj), ObjMove_GetX(obj), ObjMove_GetY(obj)) <= siz){
				SetCommonData("IsFrozen",true);
				if(GetCommonData("IsFrozen",true) == true && GetCommonData("AlreadyFrozen",false) == false){
				let objText = FrozenText(obj,PX-16,PY-24,siz);
				}
				SetCommonData("AlreadyFrozen",true);
				
				while(GetDistance(ObjMove_GetX(pobj), ObjMove_GetY(pobj), ObjMove_GetX(obj), ObjMove_GetY(obj)) <= siz){
					ObjRender_SetPosition(pobj,PX,PY,0);
					yield;
				}
				SetCommonData("AlreadyFrozen",false);
				SetCommonData("IsFrozen",false);
			}
			else{
				PX = ObjMove_GetX(pobj);
				PY = ObjMove_GetY(pobj);
				SetCommonData("AlreadyFrozen",false);
				SetCommonData("IsFrozen",false);
			}
			yield;
		}
	}

function FrozenText(obj,x,y,s){
		InstallFont(GetCurrentScriptDirectory ~ "./Lib/RussoOne-Regular.ttf");
		let textObj = ObjText_Create;
		ObjText_SetText(textObj,"Frozen!!");
		ObjText_SetFontType(textObj,"Russo One");
		
		ObjText_SetFontSize(textObj,18);
		ObjText_SetFontBold(textObj, true);
		ObjText_SetAutoTransCenter(textObj, true);		
		ObjText_SetHorizontalAlignment(textObj, ALIGNMENT_CENTER);
		ObjText_SetMaxWidth(textObj, 96);
		ObjText_SetFontColorTop(textObj,128,128,255);
		ObjText_SetFontColorBottom(textObj,0,255,255);
		ObjText_SetFontBorderColor(textObj,0,0,0);
		ObjText_SetFontBorderType(textObj,BORDER_FULL);
		ObjText_SetFontBorderWidth(textObj,1);
		
		Obj_SetRenderPriorityI(textObj,91);
		ObjRender_SetPosition(textObj,x,y,0);
		check;
		task check{
			while(GetDistance(ObjMove_GetX(pobj), ObjMove_GetY(pobj), ObjMove_GetX(obj), ObjMove_GetY(obj)) <= s){
				ObjRender_SetColor(pobj,64,64,255);
				yield;
			}
			SetCommonData("AlreadyFrozen",false);
			SetCommonData("IsFrozen",false);
			if(GetCommonData("IsFrozen",false) == false){
				ObjRender_SetColor(pobj,255,255,255);
				Obj_Delete(textObj);
			}
		}
		return textObj;
	}

function mist(x,y,v,dir){
	let shotObj = ObjShot_Create(OBJ_SHOT);
	ObjShot_Regist(shotObj);
	
	ObjMove_SetSpeed(shotObj,v);
	ObjMove_SetAngle(shotObj,dir);
	ObjShot_SetDelay(shotObj,0);
	ObjShot_SetSpellResist(shotObj,true);
	ObjShot_SetAutoDelete(shotObj,false);
	Obj_SetVisible(shotObj,false);
	ObjShot_SetIntersectionEnable(shotObj,false);
	
	PlaySnd("se_kira00",30);
	
	ObjMove_SetPosition(shotObj,x,y);
	return shotObj;
}

task SetMistGraphic(obj,ran,dur){
	let path = GetCurrentScriptDirectory ~ "./Img/Boss/Mist Sprite.png";
	let mistObj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(mistObj,path);
	
	ObjSprite2D_SetSourceRect(mistObj,0,0,128,128);
	ObjSprite2D_SetDestCenter(mistObj);
	ObjRender_SetBlendType(mistObj,BLEND_ADD_ARGB);
	ObjRender_SetAlpha(mistObj,0);
	ObjRender_SetColor(mistObj,160,255,255);
	ObjRender_SetScaleXYZ(mistObj,1.3,1.3,0);
	Obj_SetRenderPriorityI(mistObj,50);
	
	form(mistObj,ran);
	stick;
	
	task stick{
		while(!Obj_IsDeleted(obj) && !Obj_IsDeleted(mistObj) && !Obj_IsDeleted(bossObj)){
			ObjRender_SetPosition(mistObj,ObjMove_GetX(obj),ObjMove_GetY(obj),0);
			yield;
		}
		Obj_Delete(obj);
		Obj_Delete(mistObj);
	}
	wait(dur-10);
	randomshoot;
	wait(10);
	dissolve(mistObj,ran);
	
	task form(obj,r){
		let s = 8;
		let rs = 0;
		
		loop(r/s){
			ObjRender_SetAlpha(obj,rs);
			rs+=s;
			yield;
		}
		ObjRender_SetAlpha(obj,r);
	}
	
	task dissolve(obj,r){
		let s = 8;
		let rs = 0;
		
		loop(r/s){
			ObjRender_SetAlpha(obj,r-rs);
			rs+=s;
			yield;
		}
		ObjRender_SetAlpha(obj,0);
		Obj_Delete(obj);
		delete;
	}
	
	task randomshoot{
		ascent(i in 0..3){
			if(!Obj_IsDeleted(obj) && !Obj_IsDeleted(mistObj) && !Obj_IsDeleted(bossObj)){
				PlaySnd("se_tan01",20);
				let bulletObj = CreateDNHShotA1(ObjMove_GetX(obj),ObjMove_GetY(obj),8,ObjMove_GetAngle(obj)+i*120,rand(39,41),0);
				ObjMove_SetAcceleration(bulletObj,-1);
				ObjMove_SetMaxSpeed(bulletObj,0.75);
				accel;
				task accel{
					wait(90);
					ObjMove_SetAcceleration(bulletObj,0.0375);
					ObjMove_SetMaxSpeed(bulletObj,5);
				}
				if(i % 3 == 0){yield;}
			}
		}
	}

	task delete{	
		Obj_Delete(obj);
	}
	
	
}

sub summon{
	summonsigil(0,[64,160,192],"MIDDLE",90);
	wait(30);
	summonsigil(80,[102,72,128],"LEFT",60);
	summonsigil(280,[102,72,128],"RIGHT",60);
}

task summonsigil(ang,colour,type,duration){
	let path = GetCurrentScriptDirectory ~ "./Img/Boss/Sigil.png";
	let sigilObj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(sigilObj,path);
	
	ObjSprite2D_SetSourceRect(sigilObj,0,0,384,384);
	ObjSprite2D_SetDestRect(sigilObj,-256,-534,256,24);
	ObjSprite2D_SetSourceRect(sigilObj,0,0,512,512);
	ObjRender_SetBlendType(sigilObj,BLEND_ADD_ARGB);
	ObjRender_SetAlpha(sigilObj,0);
	ObjRender_SetColor(sigilObj,colour[0],colour[1],colour[2]);
	ObjRender_SetScaleXYZ(sigilObj,0.4,0.4,0);
	ObjRender_SetAngleZ(sigilObj,ang);
	Obj_SetRenderPriorityI(sigilObj,23);
	PlaySnd("se_boon01",60);
	
	stay;
	task stay{
		let inc = 0;
		alp;
		sca;
		
		task alp{
			ascent(i in 0..12){
				ObjRender_SetPosition(sigilObj,BossX,BossY,0);
				ObjRender_SetAlpha(sigilObj,i*16);
				yield;
			}
		}
		task sca{
			ascent(i in 0..34){
				ObjRender_SetScaleXYZ(sigilObj,1-0.6*sin(i*3),1-0.6*sin(i*3),0);
				yield;
			}
		}
		
		task expand{
			let sigilObj2 = ObjPrim_Create(OBJ_SPRITE_2D);
			ObjPrim_SetTexture(sigilObj2,path);
			
			ObjSprite2D_SetSourceRect(sigilObj2,0,0,384,384);
			ObjSprite2D_SetDestRect(sigilObj2,-256,-534,256,24);
			ObjSprite2D_SetSourceRect(sigilObj2,0,0,512,512);
			ObjRender_SetBlendType(sigilObj2,BLEND_ADD_ARGB);
			ObjRender_SetColor(sigilObj2,colour[0],colour[1],colour[2]);
			ObjRender_SetScaleXYZ(sigilObj2,0.4,0.4,0);
			Obj_SetRenderPriorityI(sigilObj2,24);
			
			ascent(i in 0..32){
				if(!Obj_IsDeleted(bossObj)){
					ObjRender_SetPosition(sigilObj2,ObjRender_GetX(sigilObj),ObjRender_GetY(sigilObj),0);
					ObjRender_SetAngleZ(sigilObj2,ObjRender_GetAngleZ(sigilObj));
					ObjRender_SetScaleXYZ(sigilObj2,0.4+i/135,0.4+i/135,0);
					ObjRender_SetAlpha(sigilObj2,172-i*6);
					yield;
				}
			}
			Obj_Delete(sigilObj2);
		}
		
		wait(duration);
		expand;
		
		PlaySnd("se_kira00",45);
		while(!Obj_IsDeleted(bossObj)){
			ObjRender_SetPosition(sigilObj,BossX,BossY,0);
			if(type == "LEFT"){
				ObjRender_SetAngleZ(sigilObj,ang+12*sin(inc));
			}
			if(type == "RIGHT"){
				ObjRender_SetAngleZ(sigilObj,ang-12*sin(inc));
			}
			yield;
			inc+=1;
			if(inc % 160 == 0){expand;}
		}
		Obj_Delete(sigilObj);
	}
}

task end{
	let px = BossX; let py = BossY;
	while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){ yield;px = BossX;py = BossY;}
	ExplodeA2(px,py,"Snow","AQUA","Long");
	SetCommonData("Is Spell?",false);
	Obj_Delete(bossObj);
	
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	CloseScript(GetOwnScriptID());
}