//Graphical Effect Script

let CSD = GetCurrentScriptDirectory;
let MD = GetModuleDirectory;

#include"./Event_Const.dnh"
#include"../lib/includes/Function_Audio.dnh"
#include"../lib/includes/ItemFunctions.dnh"

@MainLoop { yield; }

@Event {
	alternative(GetEventType)
	case(EV_EFFECT) {
		let eventParam = GetEventArgument(0);
		let type = eventParam[0][0];
		alternative(type)
			case(0.1){ CreateDelayCloud(eventParam[1][0],eventParam[2][0],eventParam[3][0],eventParam[4][0],eventParam[5][0],eventParam[6][0],eventParam[7][0]); }
			case(9.1) { AlertZone01(eventParam[1][0],eventParam[2][0],eventParam[3][0],eventParam[4][0],eventParam[5][0]); }
			case(9.2) { AlertZone02(eventParam[1][0],eventParam[2][0],eventParam[3][0],eventParam[4][0]); }
			case(69.1) { TCharge01(eventParam[1][0],eventParam[2][0],eventParam[3][0],eventParam[4][0],eventParam[5][0],eventParam[6][0],eventParam[7][0],eventParam[8][0],eventParam[9][0]); }
			case(69.2) { TExpan(eventParam[1][0],eventParam[2][0],eventParam[3][0],eventParam[4][0],eventParam[5][0],eventParam[6][0],eventParam[7][0],eventParam[8][0]); }
			case(99.1) {ScreenShake(eventParam[1][0],eventParam[2][0]); }
			case(99.8) { BossExplosionQuick(eventParam[1][0],eventParam[2][0],eventParam[3][0]); }
			case(99.9) { BossExplosion(eventParam[1][0],eventParam[2][0],eventParam[3][0]); }
			case(99.99) { BossExplosionTricky(eventParam[1][0],eventParam[2][0],eventParam[3][0]); }
			case(100.0){ BossCircle; }
			case(100.1){ BossShadow; }
	}
}

task BossCircle(){
	let spin = 0;
	let size = 0.7;
	let size2 = 0;
	let s = 0;
	let alpha = 0;
	let objEnemy = ID_INVALID;
	let objScene = GetEnemyBossSceneObjectID;
	
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, CSD ~ "img/MG.png");
	
	ObjSprite2D_SetSourceRect(obj,0,0,256,256);
	ObjSprite2D_SetDestCenter(obj);
	Obj_SetRenderPriorityI(obj, 28);
	ObjRender_SetBlendType(obj,BLEND_ADD_RGB);
	
	while(!Obj_IsDeleted(objScene)) {
		if(length(GetEnemyBossObjectID)>0) { objEnemy = GetEnemyBossObjectID[0]; }
		if(ObjMove_GetX(objEnemy)>0 && ObjMove_GetX(objEnemy)<GetStgFrameWidth){
			ObjRender_SetPosition(obj,ObjMove_GetX(objEnemy),ObjMove_GetY(objEnemy), 0);
		}
		if(GetCommonData("timestop", false)==false){
			spin += 2;
		}
		if(size2<size){ size2+=0.02; }
		if(alpha<192){ alpha++; }
		ObjRender_SetAlpha(obj, alpha); 
		ObjRender_SetAngleXYZ(obj,0,0,spin*2);
		ObjRender_SetColor(obj,1*(192+42*sin(spin+180)),1*(192+42*sin(spin)),0);
		ObjRender_SetScaleXYZ(obj,size2*1.1+0.1*sin(spin),size2*1.1+0.1*sin(spin),0);
		yield;
	}
	Obj_Delete(obj);
}
	
	
task BossShadow(){
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, CSD ~ "img/shadow.png");
	WriteLog(CSD ~ "img/shadow.png");
	Obj_SetRenderPriorityI(obj, 1);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 64, 16);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetY(obj, GetStgFrameHeight+24);
	
	let objEnemy = ID_INVALID;
	let objScene = GetEnemyBossSceneObjectID;
	let alpha = 0;
	
	while(!Obj_IsDeleted(objScene)) {
		if(length(GetEnemyBossObjectID)>0) { objEnemy = GetEnemyBossObjectID[0]; }
		if(ObjMove_GetX(objEnemy)!=0 && ObjMove_GetX(objEnemy)<GetStgFrameWidth+GetStgFrameLeft){
			ObjRender_SetX(obj,ObjMove_GetX(objEnemy)+GetStgFrameLeft);
		}
		else if(ObjRender_GetX(objEnemy)!=0) { ObjRender_SetX(obj,-500); }
		ObjRender_SetAlpha(obj, alpha);
		if(alpha<255) { alpha+=255/30; }
		yield;
	}
	Obj_Delete(obj);
}

task BossExplosion(objEnemy, spellbg, scriptid){
	StartSlow(TARGET_ALL, 30);
	PlaySoundEffect("se_enep01", 100, ObjMove_GetX(objEnemy));
	loop(15){ TExpan(ObjMove_GetX(objEnemy)+rand(-25, 25), ObjMove_GetY(objEnemy)+rand(-25, 25), 8, 25, 255, 255, 255, 100); wait(5); }
	PlaySoundEffect("se_enep01", 100, ObjMove_GetX(objEnemy));
	ScreenShake(60, 15);
	TExpan(ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 55, 120, 224, 255, 255, 255);
	NotifyEventAll(EV_SPELLBGEND, spellbg);
	DeleteShotAll(TYPE_ALL,TYPE_ITEM);
	CreateItems02(24, ITEM_POINT_S, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 0, -50, 40, 40, 10000);
	Obj_Delete(objEnemy);
	CloseScript(scriptid);
	wait(60);
	SetCommonData("pausebeforebonus", false);
	StopSlow(TARGET_ALL);
	SetShotAutoDeleteClip(64, 64, 64, 64);
}

task BossExplosionTricky(objEnemy, spellbg, scriptid){
	let angle = 0;
	StartSlow(TARGET_ALL, 30);
	PlaySoundEffect("se_enep01", 100, ObjMove_GetX(objEnemy));
	loop(15){ TExpan(ObjMove_GetX(objEnemy)+rand(-25, 25), ObjMove_GetY(objEnemy)+rand(-25, 25), 8, 25, 255, 255, 255, 100); wait(5); }
	PlaySoundEffect("se_enep01", 100, ObjMove_GetX(objEnemy));
	ScreenShake(60, 15);
	TExpan(ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 55, 120, 224, 255, 255, 255);
	NotifyEventAll(EV_SPELLBGEND, spellbg);
	DeleteShotAll(TYPE_ALL,TYPE_ITEM);
	loop(6){
		CreateItems02(1, ITEM_1UP, ObjMove_GetX(objEnemy)+50*cos(angle), ObjMove_GetY(objEnemy)+50*sin(angle), 0, -50, 0, 0, 10000);
		angle+=360/6;
	}
	Obj_Delete(objEnemy);
	CloseScript(scriptid);
	wait(60);
	SetCommonData("pausebeforebonus", false);
	StopSlow(TARGET_ALL);
	SetShotAutoDeleteClip(64, 64, 64, 64);
}

task BossExplosionQuick(objEnemy, spellbg, scriptid){
	PlaySoundEffect("se_enep01", 100, ObjMove_GetX(objEnemy));
	ScreenShake(60, 15);
	TExpan(ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 55, 120, 224, 255, 255, 255);
	NotifyEventAll(EV_SPELLBGEND, spellbg);
	DeleteShotAll(TYPE_ALL,TYPE_ITEM);
	let angle = 0;
	loop(30){
		CreateItems02(1, ITEM_POINT_S, ObjMove_GetX(objEnemy)+40*cos(angle), ObjMove_GetY(objEnemy)+40*sin(angle), 0, -50, 0, 0, 10000);
		angle+=360/30;
	}
	CreateItems02(1, ITEM_1UP, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 0, -50, 0, 0, 69);
	Obj_Delete(objEnemy);
	CloseScript(scriptid);
	wait(60);
}

task CreateDelayCloud (let obj, let v, let angle, let vAcc, let vF, let graphic, let delay ) {
	let rects = GetShotDataInfoA1(graphic, TARGET_ENEMY, INFO_RECT);
	//WriteLog(graphic);
	let pathShotsheet;
	alternative(graphic)
		if(graphic < 500){
			pathShotsheet = GetCurrentScriptDirectory~"../lib/UNL_Shot/ShotsheetBasic.png";
		}
		else if(graphic >= 500 && graphic < 1000){
			pathShotsheet = GetCurrentScriptDirectory~"../lib/UNL_Shot/ShotsheetSpecial.png";
		}
		else if(graphic >= 1000 && graphic < 1500){
			pathShotsheet = GetCurrentScriptDirectory~"../lib/UNL_Shot/ShotsheetSpecial2.png"; 
		}
		else if(graphic >= 1500 && graphic < 2000){
			pathShotsheet = GetCurrentScriptDirectory~"../lib/UNL_Shot/ShotsheetSpecial3.png";
		}
		else if(graphic >= 2000){
			pathShotsheet =  GetCurrentScriptDirectory~"../lib/UNL_Shot/ShotsheetAnimated.png";
		}
	let frames = 0;
	let objCloud = CreateSprite (pathShotsheet, GetShotRenderPriorityI, rects, [(rects[2]-rects[0])/2, (rects[3]-rects[1])/2] );
	if(delay > 0) {
		ObjRender_SetBlendType(objCloud, GetShotDataInfoA1(graphic, TARGET_ENEMY, INFO_BLEND));
		ObjRender_SetAngleZ(objCloud, ObjMove_GetAngle(obj)+90);
		descent(i in 0..delay) {
			ObjRender_SetPosition(objCloud, ObjMove_GetX(obj), ObjMove_GetY(obj), NULL);
			ObjRender_SetAlpha(objCloud, 255*cos(i*90/delay));
			ObjRender_SetScaleXYZ(objCloud, 2-cos(i*90/delay), 2-cos(i*90/delay), NULL);
			if(Obj_IsDeleted(obj)) { Obj_Delete(objCloud); yield; return; }
			yield;
		}
	} else {
		yield;
		frames++;
	}
	Obj_Delete(objCloud);
	ObjRender_SetAlpha(obj, 255);
	ObjMove_SetSpeed(obj, v);
	ObjMove_SetAcceleration(obj, vAcc);
	ObjMove_SetMaxSpeed(obj, vF);
}

function CreateSprite ( let texture, let priorityInt, let rects, let center ) {
		// rects = 1-dimensional, size 4
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture(obj, texture);
		Obj_SetRenderPriorityI(obj, priorityInt);
		ObjSprite2D_SetSourceRect(obj, rects[0], rects[1], rects[2], rects[3]);
		ObjSprite2D_SetDestRect(obj, -center[0], -center[1], rects[2]-rects[0]-center[0], rects[3]-rects[1]-center[1]);
		return obj;
}

task TCharge01(x,y,size,frame,r,g,b,blend,priority){ // Draw a charge circle that has an acceleration on shrinking
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img= GetCurrentScriptDirectory~"./../sprites/charge.png";
	let set = 360/(frame*4);
	ObjPrim_SetTexture(obj,img);
	ObjSprite2D_SetSourceRect(obj,0,0,128,128);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj,x,y,0);
	ObjRender_SetAlpha(obj,0);
	ObjRender_SetColor(obj, r, g, b);
	ObjRender_SetScaleXYZ(obj,size,size,0);
	ObjRender_SetBlendType(obj,blend);
	Obj_SetRenderPriorityI(obj,priority);
	TAlpha;
	TShrink;
	task TAlpha{
		let l=10;
		let alpha=255/l;
		loop(l){
			ObjRender_SetAlpha(obj,alpha);
			alpha+=255/(l*2);
			yield;
			}
		}
	task TShrink{
		let l=frame;
		let a = size*2/l/l;
		ascent(i in 0..l){
			ObjRender_SetScaleXYZ(obj,size,size,0);
			//ObjRender_SetColor(obj,0,128+64*sin(i*set+240),64+64*sin(i*set+0));
			size = size-i*a;
			yield;
			}
		Obj_Delete(obj);
	}
}

task TExpan(px,py,maxv,t,r,g,b,alpha){
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img=GetCurrentScriptDirectory~"./../sprites/charge.png";
	let scale = 0;
	let v = 0;
	let time = 0;
	let alpha2 = 255;
	let alpha3 = 0;
	let malpha = 255/t;
	ObjPrim_SetTexture(obj,img);
	ObjRender_SetAlpha(obj, alpha);
	ObjSprite2D_SetSourceRect(obj,0,0,128,128);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj,px,py,0);
	ObjRender_SetColor(obj,r,g,b);
	Obj_SetRenderPriorityI(obj,55);
	Expan;
		task Expan{
			descent(i in 0..t){
			if(time>=50){ alpha2 = malpha*i; alpha3 = alpha2; loop(10){ alpha2-=alpha3/10; ObjRender_SetAlpha(obj, alpha2); wait(1); } break;}
			ObjRender_SetAlpha(obj,malpha*i);
			v = (i*maxv/2)/(t*t);
			scale += v;
			ObjRender_SetScaleXYZ(obj,scale,scale,0);
			yield;
			time++;
			}
			Obj_Delete(obj);
		}
}
	
task ScreenShake(shaketime, intensity){
		let screenx = Get2DCameraX;
		let screeny = Get2DCameraY;
		let x = GetCameraFocusX;
		let y = GetCameraFocusY;
		let z = GetCameraFocusZ;
		let roll = 0;
		while(shaketime>0){
			Set2DCameraFocusX(screenx + rand(-intensity, intensity));
			Set2DCameraFocusY(screeny + rand(-intensity, intensity));
			//SetCameraFocusXYZ(rand(-intensity, intensity),rand(-intensity, intensity),rand(-intensity, intensity));
			//SetCameraRoll(GetCameraRoll+360/25);	
			shaketime--;
			yield;
		}
		Set2DCameraFocusX(screenx);
		Set2DCameraFocusY(screeny);
		yield;
}

task ScreenDistort(EnemyObject, AI, length){
	let renderTexture = GetReservedRenderTargetName(0);

	SetInvalidRenderPriorityA1(20, 79);

	let objCurentFrame = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(objCurentFrame, 80);

	if(length == -1){while(ObjEnemy_GetInfo(EnemyObject, INFO_LIFE) > 0){PerformActions;yield;}}	
	if(length != -1){while(length>0){length--;PerformActions;yield;}}
	
	Obj_Delete(objCurentFrame);
	ClearInvalidRenderPriority;
	
	task PerformActions{
		let currentFrameTexture = renderTexture;
		RenderToTextureA1(currentFrameTexture, 20, 79, true);
		ObjPrim_SetTexture(objCurentFrame, currentFrameTexture);
		ObjSprite2D_SetSourceRect(objCurentFrame, 32, 16, 416, 464);
		ObjSprite2D_SetDestRect(objCurentFrame, rand(32, 36+AI), rand(16, 36+AI), rand(416-AI, 416), rand(464-AI, 464));
	}
}

task Alert(x,y,dir,frames) {
	let objEffect = ObjPrim_Create(OBJ_SPRITE_2D);
		
	ObjRender_SetBlendType(objEffect,BLEND_ALPHA);
	Obj_SetRenderPriorityI(objEffect,39);
	ObjPrim_SetTexture(objEffect, CSD ~ "img/Alert.png");
	ObjSprite2D_SetSourceRect(objEffect,0,0,256,256);
	ObjSprite2D_SetDestCenter(objEffect);
	ObjRender_SetPosition(objEffect,x,y,0);
	//ObjRender_SetScaleXYZ(objEffect,0.25,0.25,0.25);

	let t = 0;
	let alpha = 0;
	let basealpha = 0;
	let scale = 0.5;
	
	loop(frames) {
		if(basealpha<140) { basealpha+=140/10; }
		if(basealpha>=140) { t++; }
		alpha = basealpha + 60*sin(40*t);
		if(scale>0.25) { scale-=0.25/20; }
		ObjRender_SetAlpha(objEffect,alpha);
		ObjRender_SetScaleXYZ(objEffect,scale,scale,scale);
		if(dir>90) { ObjRender_SetAngleZ(objEffect,dir+180); }
		else { ObjRender_SetAngleZ(objEffect, dir); }
		yield;
	}
	basealpha = alpha;
	loop(20) {
		alpha-=basealpha/20;
		ObjRender_SetAlpha(objEffect,alpha);
		yield;
	}
	Obj_Delete(objEffect);
}

task AlertZone01(num,x,y,dir,frames) { //num must be 2,3,4,or 5
	let disp = 0;
	let num1 = 0;
	let num2 = 0;

	if(num == 2) { num1 = 0; num2 = 0; }
	else if(num == 3) { num1 = 1; num2 = 0; }
	else if(num == 4) { num1 = 1; num2 = 1; }
	else if(num == 5) { num1 = 2; num2 = 1; }
	else { RaiseError("AlertZone01: num must be between 2 and 5"); }
	AlertSound;
	loop(9) {
		disp = 1;
		Alert(x,y,dir,frames);
		loop(num1) {
			Alert(x+70*disp*cos(dir-90),y+70*disp*sin(dir-90),dir,frames);
			Alert(x+70*disp*cos(dir+90),y+70*disp*sin(dir+90),dir,frames);
			disp++;
		}
		wait(2);
		x+=35*cos(dir);
		y+=35*sin(dir);
		disp = 1;
		Alert(x+35*cos(dir-90),y+35*sin(dir-90),dir,frames);
		Alert(x+35*cos(dir+90),y+35*sin(dir+90),dir,frames);
		loop(num2) {
			Alert(x+35*cos(dir-90)*disp+70*cos(dir-90)*disp,y+35*sin(dir-90)+70*sin(dir-90)*disp,dir,frames);
			Alert(x+35*cos(dir+90)*disp+70*cos(dir+90)*disp,y+35*sin(dir+90)+70*sin(dir+90)*disp,dir,frames);
			disp++;
		}
		wait(2);
		x+=35*cos(dir);
		y+=35*sin(dir);
	}
	task AlertSound {
		loop(5) {
			PlaySoundEffect("alert", 100, GetStgFrameWidth/2);
			wait(8);
		}
	}
}
task AlertZone02(num,x,y,frames) {
	AlertSound;
	Alert(x,y,0,frames);
	if(num>1) {
		Alert(x+35,y+35,0,frames);
		Alert(x+35,y-35,0,frames);
		Alert(x-35,y+35,0,frames);
		Alert(x-35,y-35,0,frames);
	}
	wait(3);
	if(num>2) {
		Alert(x+70,y,0,frames);
		Alert(x-70,y,0,frames);
		Alert(x,y+70,0,frames);
		Alert(x,y-70,0,frames);
	}
	wait(3);
	if(num>3) {
		Alert(x+105,y+105,0,frames);
		Alert(x+105,y-105,0,frames);
		Alert(x-105,y+105,0,frames);
		Alert(x-105,y-105,0,frames);
	}
	wait(3);
	if(num>4) {
		Alert(x+140,y,0,frames);
		Alert(x-140,y,0,frames);
		Alert(x,y+140,0,frames);
		Alert(x,y-140,0,frames);
	}
	task AlertSound {
		loop(5) {
			PlaySoundEffect("alert",100, 192);
			wait(8);
		}
	}
}
task AlertZone03(num_width,num_length,x,y,dir,frames) { //num must be 2,3,4,or 5
	let disp = 0;
	let num1 = 0;
	let num2 = 0;

	if(num_width == 2) { num1 = 0; num2 = 0; }
	else if(num_width == 3) { num1 = 1; num2 = 0; }
	else if(num_width == 4) { num1 = 1; num2 = 1; }
	else if(num_width == 5) { num1 = 2; num2 = 1; }
	else { RaiseError("AlertZone03: num_width must be 2, 3, 4, or 5"); }
	AlertSound;
	loop(num_length) {
		disp = 1;
		Alert(x,y,dir,frames);
		loop(num1) {
			Alert(x+70*disp*cos(dir-90),y+70*disp*sin(dir-90),dir,frames);
			Alert(x+70*disp*cos(dir+90),y+70*disp*sin(dir+90),dir,frames);
			disp++;
		}
		wait(2);
		x+=35*cos(dir);
		y+=35*sin(dir);
		disp = 1;
		Alert(x+35*cos(dir-90),y+35*sin(dir-90),dir,frames);
		Alert(x+35*cos(dir+90),y+35*sin(dir+90),dir,frames);
		loop(num2) {
			Alert(x+35*cos(dir-90)*disp+70*cos(dir-90)*disp,y+35*sin(dir-90)+70*sin(dir-90)*disp,dir,frames);
			Alert(x+35*cos(dir+90)*disp+70*cos(dir+90)*disp,y+35*sin(dir+90)+70*sin(dir+90)*disp,dir,frames);
			disp++;
		}
		wait(2);
		x+=35*cos(dir);
		y+=35*sin(dir);
	}
	task AlertSound {
		loop(5) {
			PlaySoundEffect("alert",100, 192);
			wait(8);
		}
	}
}

function wait(w){ loop(w){ yield; } }