#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Dj non-spell 03 hard"]
#Text["Dj non-spell 03 hard"]

let famTex = "script/thdcs/system/effects/fammer.png";

#include "script/thdcs/system/shotlibrary.txt"
#include "script/thdcs/functions/function_common.txt"
#include "script/thdcs/functions/function_global.txt"
#include "script/thdcs/functions/function_bosseff.txt"

@Initialize {
	renderBoss(3);
	setAura(bossObj,64,255,128);
	SetCommonData("bossAttackType",1);
	SetCommonData("bossCircleType",0);
	setInvulnerableTime(bossObj,120);
	
	ObjMove_SetDestAtSpeed(bossObj,192,120,5);
	SetShotAutoDeleteClip(16,16,16,16);
	SetAutoDeleteObject(true);
	mainTask;
} 

@Event { 
	alternative(GetEventType()) 
	case(EV_REQUEST_LIFE) { 
		SetScriptResult(270);
	}
	case(EV_REQUEST_TIMER) { 
		SetScriptResult(52);
	}
} 

@MainLoop { yield; } 
@Finalize { } 


task mainTask { 
	yield;
	scriptEnding;	
	wait(120);
	control;
	vuur;
	beweeg;
} 

task beweeg { 
	while(!Obj_IsDeleted(bossObj)) { 
		ObjMove_RandomPosWeight(bossObj,rand(60,80),rand(60,80),15,30,GetClipMinX+72,GetClipMinY+64,GetClipMaxX-72,GetCenterY-120);		
		wait(90); 
		ObjMove_SetDestAtSpeed(bossObj,GetPlayerX,120,5);
		wait(90);
	}
}

task control { 
	while(!Obj_IsDeleted(bossObj)) { 
		fam(GetEnemyX,GetEnemyY,0,121);
		wait(160);
		fam(GetEnemyX,GetEnemyY,1,122);
		wait(160);
	}
}	

task vuur { 
	while(!Obj_IsDeleted(bossObj)) {  
		amulets;
		wait(60);
	}
}

function amulets {
	let dir = GetAngleToPlayer(bossObj);
	PlaySFX(SFX_TAN01);
	ascent(i in 0..16) { 
		let amuletShot = CreateShotA(GetEnemyX,GetEnemyY,15);
		SetShotDataA(amuletShot,0,5,dir,0,0,5,100);
		SetShotDataA(amuletShot,35,0,dir,0,0,0,100);
		SetShotDataA(amuletShot,35,1,dir,i/6,0.1,2,100);
		SetShotDataA(amuletShot,90,1,dir,0,0.1,2,100);			

		let amuletShot2 = CreateShotA(GetEnemyX,GetEnemyY,15);
		SetShotDataA(amuletShot2,0,5,dir,0,0,5,100);
		SetShotDataA(amuletShot2,35,0,dir,0,0,0,100);
		SetShotDataA(amuletShot2,35,1,dir,-i/6,0.1,2,100);		
		SetShotDataA(amuletShot2,90,1,dir,0,0.1,2,100);				
	}
	wait(60);
	PlaySFX(SFX_KIRA00);
}

// fammer
task fam(x,y,side,kleur) {
	let obj = ObjEnemy_Create(OBJ_ENEMY); 
	let obj2 = ObjPrim_Create(OBJ_SPRITE_2D);
	let spin = 0;
	let dir = 0;
	
	// fam base
	ObjEnemy_Regist(obj);
	ObjPrim_SetTexture(obj,famTex); 
	ObjPrim_SetTexture(obj2,famTex); 
	ObjRender_SetAlpha(obj,205);
	ObjRender_SetAlpha(obj2,150);
	Obj_SetRenderPriorityI(obj,40);
	Obj_SetRenderPriorityI(obj2,31);
	ObjRender_SetScaleXYZ(obj,1,1,0);
	ObjRender_SetScaleXYZ(obj2,1,1,0);
	ObjSprite2D_SetSourceRect(obj,31,0,64,31); 
	ObjSprite2D_SetSourceRect(obj2,31,0,64,31); 
	ObjSprite2D_SetDestCenter(obj);
	ObjSprite2D_SetDestCenter(obj2);
	ObjEnemy_SetLife(obj,500);
	ObjMove_SetPosition(obj,x,y);
	
	PlaySFX(SFX_OPTION);

    Obj_SetValue(obj,"isFamiliar",true);

	famShot(obj,kleur);
	ObjMove_SetSpeed(obj,2);
	if(side == 0) { ObjMove_SetAngle(obj, atan2(GetPlayerY-ObjMove_GetY(obj),GetPlayerX-ObjMove_GetX(obj))+45); }
	if(side == 1) { ObjMove_SetAngle(obj, atan2(GetPlayerY-ObjMove_GetY(obj),GetPlayerX-ObjMove_GetX(obj))-45); }
	
	while(!Obj_IsDeleted(obj)) { 	
		ObjEnemy_SetIntersectionCircleToShot(obj,ObjMove_GetX(obj),ObjMove_GetY(obj),16);
		ObjEnemy_SetIntersectionCircleToPlayer(obj,ObjMove_GetX(obj),ObjMove_GetY(obj),16);
		ObjRender_SetAngleZ(obj,-spin/4);	
		ObjRender_SetAngleZ(obj2,spin);	
		spin+=10;

		if(side == 0) { ObjMove_SetAngle(obj,ObjMove_GetAngle(obj)-0.5); } 
		if(side == 1) { ObjMove_SetAngle(obj,ObjMove_GetAngle(obj)+0.5); }
		
		// update sprite loc
		ObjRender_SetPosition(obj2,ObjMove_GetX(obj),ObjMove_GetY(obj),0);

		if(ObjMove_GetX(obj) > GetClipMaxX+32 || ObjMove_GetX(obj) < GetClipMinX-32 || ObjMove_GetY(obj) > GetClipMaxY+32 || ObjMove_GetY(obj) < GetClipMinY-32) { 
			Obj_Delete(obj); Obj_Delete(obj2);
		}
		yield;
	}
	Obj_DeleteValue(obj,"isFamiliar");
}

task famShot(obj,kleur) { 
	wait(1);	
	let dir = 0;
	while(!Obj_IsDeleted(obj)) {	
		PlaySFX(SFX_TAN00);
		CreateShotA1(ObjMove_GetX(obj),ObjMove_GetY(obj),2,ObjMove_GetAngle(obj),95,5);
		CreateShotA1(ObjMove_GetX(obj),ObjMove_GetY(obj),2,ObjMove_GetAngle(obj)-145,kleur,5);
		CreateShotA1(ObjMove_GetX(obj),ObjMove_GetY(obj),2,ObjMove_GetAngle(obj)-120,kleur,5);
		CreateShotA1(ObjMove_GetX(obj),ObjMove_GetY(obj),2,ObjMove_GetAngle(obj)-95,kleur,5);
		CreateShotA1(ObjMove_GetX(obj),ObjMove_GetY(obj),2,ObjMove_GetAngle(obj)-265,kleur,15);	
		CreateShotA1(ObjMove_GetX(obj),ObjMove_GetY(obj),2,ObjMove_GetAngle(obj)-240,kleur,15);	
		CreateShotA1(ObjMove_GetX(obj),ObjMove_GetY(obj),2,ObjMove_GetAngle(obj)-215,kleur,15);	
		wait(5);
	}
}

// Because ObjMove_SetSpeed does not work with Primitive 2D Sprites, I decided to make my own move code.
task famMovePath(obj,obj2,x,y,v) {
	let r = 0;
	let r2 = 40;
	let dir = 0;
	let vx = v * cos(dir);
	let vy = v * sin(dir);
	
	while(!Obj_IsDeleted(obj)) {
		ObjRender_SetPosition(obj,x + r*cos(dir),y + r2 * sin(dir),0);
		ObjRender_SetPosition(obj2,x + r *cos(dir),y + r2 * sin(dir),0);	
		ObjMove_SetAngle(obj,dir);
		dir+=2;
		if(r < 160) { r+=0.4; } 
		//if(r > 160 && r2 < 300) { r2++; }
		//if(r2 >= 300) { PlaySFX(SFX_ENEP00); Obj_Delete(obj); Obj_Delete(obj2); }
		yield;
	}
}

task scriptEnding {
	while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0) {
		yield;
	}

	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	Obj_Delete(bossObj);

	CloseScript(GetOwnScriptID());
}
 