//#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Spatial warp"]
#System["./../../system/NSystem.dnh"]
#Player["./../../player/Reimu by plasmaflame22/Reimu_A.txt", "./../../player/Reimu by plasmaflame22/Reimu_C.txt"]
#include "./../../ZUNShot/ZUNShot_Const.txt"
#include "./../sharedFuncSaul.dnh"


let objBoss;
let width = 444;
let height = 448;
let life = 4200;
let time= 80;
let scene = GetEnemyBossSceneObjectID();
let path = GetCurrentScriptDirectory~"./../../SFX/";

let shot4 = LoadEffect(path~"ATTACK4.WAV", 65);
let shot5 = LoadEffect(path~"ATTACK5.WAV", 80);
let charge = LoadEffect(path~"Charge.WAV", 80);

@Event{
    alternative(GetEventType())
    case(EV_REQUEST_LIFE){
        SetScriptResult(life);
    }
    case(EV_REQUEST_TIMER){
        SetScriptResult(time);
    }
}


@Initialize{
    objBoss = ObjEnemy_Create(OBJ_ENEMY_BOSS);
    ObjEnemy_Regist(objBoss);
	ObjEnemyBossScene_StartSpell(scene);
	SetCommonData("non1", "yes");
	SetCommonData("spell", "Size 1");
	
	animSpell(objBoss, 1);
	TFinalizeSpell(scene, objBoss, false);
	
	ObjMove_SetDestAtFrame(objBoss, width/2, height/3, 60);
	Main;
}

@MainLoop{
    ObjEnemy_SetIntersectionCircleToShot(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 32); 
    ObjEnemy_SetIntersectionCircleToPlayer(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 28);
    yield;
}




task Main{
    Name(1, objBoss);
    Indicator(objBoss, 1);
    takeDamage(objBoss, scene, life);
    ObjEnemy_SetDamageRate(objBoss, 0, 0);
	Spell("Mind twist: Spatial warp", objBoss, 1);
    wait(180);
	ObjSound_Play(LoadEffect(path~"POWER UP.WAV", 90));
	wait(120);
	ObjEnemy_SetDamageRate(objBoss, 20, 0);
	move(width/3, 2*width/3, height/5, 3*height/10, 0, 180, 240, objBoss, 0, scene, 0);
	ObjSound_Play(shot5);
	let r= rand(-10,10);
	ascent(i in -2.. 3){
		circleWarp(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), floor(rand(14,16)), rand(1,1.5), GetAngleToPlayer(objBoss)+r + 30*i, 70, 50, 100, 60, 255);
	}
	wait(140);
	ObjEnemy_SetDamageRate(objBoss, 60, 20);
	while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
		ObjSound_Play(charge);
		wait(60);
		ascent(j in 0..5){
		    if(ObjEnemy_GetInfo(objBoss, INFO_LIFE)<=0){return;}
		    ObjSound_Play(shot5);
			r = rand(-10,10);
			ascent(i in 0.. 12){
				circleWarp(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), floor(rand(9,11)), rand(1.4,1.6), GetAngleToPlayer(objBoss)+r + 30*i, 60, 50, 90, 60 + 3*j, 255);
			}
			wait(60);
		}
		wait(150);
		ObjSound_Play(charge);
		wait(60);
		bigCircles(360, 60);
		wait(100);
		littleCir(12, 260, 25);
		wait(340);
		ObjSound_Play(charge);
		wait(60);
		spir(4, 1, 240, 1, GetAngleToPlayer(objBoss)+rand(10,30));
		wait(180);
		spir(2, -1, 60, 2, GetAngleToPlayer(objBoss)+90);
		wait(60);
		spir(4, -1, 120, 2, GetAngleToPlayer(objBoss)+90);
		wait(210);
		ObjSound_Play(charge);
		wait(60);
		random(380);
		wait(440);
	}
}



task random(period){
    let t=0; let ang; let radmin= rand(40,50); let radmax = rand(70,80); let time = 40;
	while(t<period && ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
	    ObjSound_Play(shot5);
	    ang= rand(0,360); let col =rand(59,73);
	    ascent(i in 0.. 6){
		    if(ObjEnemy_GetInfo(objBoss, INFO_LIFE)<=0){return;}
		 	circleWarp(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), floor(rand(10,12)), rand(1.2,1.5), ang + 60*i, 75, radmin, radmax, col, 255);
		}
		wait(30); t+=30;
	}
}
   
		    


task spir(numBranches, dir, period, cas, ang){
    let t=0; let r; let col = floor(rand(65,69)); if(cas ==2){col =floor(rand(69,73));}
	while(t<period && ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
	    ObjSound_Play(shot4);
	    r = rand(3, 3.6);
	    ascent(i in 0..numBranches){
		    if(ObjEnemy_GetInfo(objBoss, INFO_LIFE)<=0){return;}
			circleWarp(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 10, rand(5,6), ang + 360/numBranches *i, rand(10,20), 10, 35, col, 255);
		}
		wait(8); ang+= 8*r*dir; t+=8;
	}
}

task bigCircles(period, pause){
    let t=0;
	while(t<period && ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
	    ObjSound_Play(shot5);
		ascent(i in -1..2){
		    if(ObjEnemy_GetInfo(objBoss, INFO_LIFE)<=0){return;}
			circleWarp(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), floor(rand(9,11)), rand(1.3,1.6), GetAngleToPlayer(objBoss) + 25*i, 60, 50, 90, 60, 255);
		}
		wait(pause); t+=pause;
	}
}

task littleCir(numCir, period, pause){
	let t=0;
	while(t<period && ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
	    ObjSound_Play(shot4);
	    let r = rand(-10,10);
		ascent(i in 0.. numCir){
		    if(ObjEnemy_GetInfo(objBoss, INFO_LIFE)<=0){return;}
			circleWarp(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 8, rand(4,5), GetAngleToPlayer(objBoss)+r+25 +310/(numCir-1) *i, 30, 20, 40, 66, 180);
		}
		wait(pause); t+=pause;
	}
}


// Time represents time from radmin to radmax or vice-versa (not both).

task circleWarp(x,y, numBul, speed, angle, time, radmin, radmax, graphic, alpha){
	ascent(i in 0..numBul){
	    if(ObjEnemy_GetInfo(objBoss, INFO_LIFE)<=0){return;}
	    let obj= CreateShotA1(x +radmin*cos(360/numBul *i), y +radmin*sin(360/ numBul *i), 0, 360/numBul *i, graphic, 5);
		del(obj);
		ObjRender_SetAlpha(obj, alpha);
		warp(obj, x, y, numBul, speed, angle, time, radmin, radmax, i);
	}
}


task del(obj){
    while(ObjMove_GetX(obj)>-10 && ObjMove_GetX(obj)<width+10 && ObjMove_GetY(obj)>-10 && ObjMove_GetY(obj)<height+10){yield;}
	Obj_Delete(obj);
}
		
			

task warp(obj, xini, yini, numBul, speed, angle, time, radmin, radmax, i){
    let t; let x; let y; let p=0; let c= cos(360/numBul *i); let s=sin (360/numBul *i); let r = (radmax-radmin)/time;
	let co = cos(angle); let si = sin(angle); let u; let v;
	ObjMove_SetAngle(obj, 360/numBul *i + angle);
	wait(5);
	while(!Obj_IsDeleted(obj)){
	    t=0;
		while(t<time){
		    if(Obj_IsDeleted(obj)){return;}
			u= ((p+1)*speed + (radmin + (t+1)*r)*c); v = ((radmin + (t+1)*r)*s);
			x = xini + u * co - v*si;
			y = yini + u * si + v * co;
			ObjMove_SetPosition(obj, x, y);
			t+=2; p+=2; wait(2);
		}
		t=0;
		while(t<time){
		    if(Obj_IsDeleted(obj)){return;}
			u= ((p+1)*speed + (radmax - (t+1)*r)*c); v= ((radmax - (t+1)*r)*s);
			x = xini + u *co - v * si;
			y = yini + u * si + v * co;
			ObjMove_SetPosition(obj, x, y);
			t+=2; p+=2; wait(2);
		}
		yield;
	}
}


