let GCSD = GetCurrentScriptDirectory();

function GetPointAngle(x1,y1,x2,y2){
	let angle=atan2(y1-y2,x1-x2);
	return angle;
}

task BossCharge(boss,num,color){
	let value = [0,0,0];
	value = GetColor(color);
	ascent(i in 0..num){
	FakeLaser;
	if(i%7==0){Bright(boss,11,30,color);}
	wait(1+i%2);
	}
	task FakeLaser{
	let ang = rand(0,360);
	let length = round(rand(250,300));
	let l = length;
	let obj = CreateStraightLaserA1(ObjMove_GetX(boss),ObjMove_GetY(boss),ang,length,5,120,48,0);
	ObjRender_SetColor(obj,value[0],value[1],value[2]);
	ObjShot_SetIntersectionEnable(obj,false);
	ObjShot_SetSpellResist(obj,true);
	ObjStLaser_SetSource(obj,false);
		while(length>0){
		ObjLaser_SetLength(obj,length);
		length -=l/20;
		yield;
		}
		Obj_Delete(obj);
	}
}

	task DrawDifficulty{
	let path = GetCurrentScriptDirectory() ~ "img/front00.png";
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let value = 0;
	ObjPrim_SetTexture(obj, path);
	ObjRender_SetScaleXYZ(obj,0,0,0);
	while(value==0){
	if(GetCommonData("Difficulty","Easy")=="Hard"){value = 2;}
	if(GetCommonData("Difficulty","Easy")=="Lunatic"){value = 3;}
	yield;
	}
	MinorEffect;
	while(!Obj_IsDeleted(obj)){
	ObjSprite2D_SetSourceRect(obj, 520, 608+32*value, 520+144, 640+32*value);
	Obj_SetRenderPriority(obj, 1);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj,530,30,0);
	yield;
	}
		task MinorEffect{
			ascent(i in 0..60){
			ObjRender_SetScaleXYZ(obj,0.55,i*0.01,0);
			yield;
			}
			ascent(i in 0..90){
			ObjRender_SetColor(obj,192+63*sin(i*20+90),192+63*sin(i*20+90),192+63*sin(i*20+90));
			yield;
			}
		}
	}


function GetColor(type){
	if(type=="RED"){return [255,32,32];}
	if(type=="ORANGE"){return [255,128,32];}
	if(type=="YELLOW"){return [255,255,32];}
	if(type=="GREEN"){return [32,255,32];}
	if(type=="BLUE"){return [32,32,255];}
	if(type=="PURPLE"){return [255,32,255];}
	if(type=="PINK"){return [255,32,128];}
	if(type=="WHITE"){return [255,255,255];}
	if(type=="AQUA"){return [0,255,255];}
	if(type=="WHITE"){return [255,255,255];}
	}
	
task Bright(boss,size,t,color){ // task for draw light circle , I can't describe it, so try it yourself
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img=GCSD~"img/bright.png";
	let c = 0;
	let set = 360/(t*3);
	let value = [0,0,0];
	let speed = 90/t;
	let size_speed = size/t;
	value = GetColor(color);
	ObjPrim_SetTexture(obj,img);
	ObjSprite2D_SetSourceRect(obj,0,0,64,64);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj,ObjRender_GetX(boss),ObjRender_GetY(boss),0);
	ObjRender_SetBlendType(obj,BLEND_ADD_RGB);
	ObjRender_SetScaleXYZ(obj,0,0,0);
	Obj_SetRenderPriorityI(obj,25);
		ascent(i in 0..t){
		if(Obj_IsDeleted(boss)){break;}
		ObjRender_SetColor(obj,value[0]*sin(i*speed)/2,value[1]*sin(i*speed)/2,value[2]*sin(i*speed)/2);
		ObjRender_SetScaleXYZ(obj,11-i*size_speed,11-i*size_speed,0);
		yield;
		}
		Obj_Delete(obj);
	}
	
task MapleExplode(px,py,speed,c){
	let color = GetColor(c);
	let st = rand(0,30);
	TExpan(px,py,12,30,color[0],color[1],color[2]);
	ascent(i in 0..12){
		Maple(px,py,speed+speed/(5/3)*sin(i*177),i*30+st,color[0],color[1],color[2]);
	}
}

task Maple(px,py,sizespeed,dir,red,green,blue){
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img=GCSD~"img/effect1.png";
	let spd = sizespeed*7;
	let acc = spd/60;
	let acc2 = acc/100;
	let r = 0;
	let a = [0,0,0];
	let angle_s = [0,0,0];
	let alpha = 255;
	let result = 0;
	let color_ratio = [red/90,green/90,blue/90];
	ascent(i in 0..3){
	result = rand(-1,1);
	if(result>0){result = 1;}
	else{result = -1;}
	angle_s[i] = rand(2,4)*result;
	}
	LoadTexture(img);
	ObjPrim_SetTexture(obj,img);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 64, 64);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetBlendType(obj,BLEND_ADD_RGB);
	ObjRender_SetScaleXYZ(obj,sizespeed,sizespeed,sizespeed);
		while(alpha>0){
		ObjRender_SetAngleXYZ(obj,a[0],a[1],a[2]);
		ObjRender_SetPosition(obj,px+r*cos(dir),py+r*sin(dir),0);
		ObjRender_SetColor(obj,red,green,blue);
		r+=spd;
		if(spd>1.5){
		red -= color_ratio[0];
		green -= color_ratio[1];
		blue -= color_ratio[2];
		spd -=acc;
		acc += acc2;
		}
		else{
		red -= color_ratio[0]*4;
		green -= color_ratio[1]*4;
		blue -= color_ratio[2]*4;
		}
		ascent(i in 0..3){
		a[i] = a[i]+angle_s[i];
		}
		yield;
		}
		Obj_Delete(obj);
}

function TExpan(px,py,maxv,t,r,g,b){
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img=GCSD~"img/charge.png";
	let scale = 0;
	let v = 0;
	let malpha = 255/t;
	ObjPrim_SetTexture(obj,img);
	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,25);
	Expan;
		task Expan{
			descent(i in 0..t){
			ObjRender_SetAlpha(obj,malpha*i);
			v = (i*maxv/2)/(t*t);
			scale += v;
			ObjRender_SetScaleXYZ(obj,scale,scale,0);
			yield;
			}
			Obj_Delete(obj);
		}
	}
	

function Sound(path){
	ObjSound_Load(song,path);
	ObjSound_SetSoundDivision(song, SOUND_BGM);
	ObjSound_SetRestartEnable(song, true);
	ObjSound_SetLoopTime(song, 0,600);
	ObjSound_Play(song);
	}
	
task StopS(obj){
	descent(i in 0..100){
	ObjSound_SetVolumeRate(song,i);
	loop(1){yield;}
	}
	}

function enemy(name,x,y,life,size,collision){
	let obj = ObjEnemy_Create(OBJ_ENEMY);
	let shot;
	let c = 0;
	let color = [0,0,0];
	ObjEnemy_Regist(obj);
	ObjMove_SetPosition(obj,x,y);
	ObjEnemy_SetLife(obj,life);
	ObjEnemy_SetDamageRate(obj,100,100);
	Control;
	DrawEnemy(obj,name);
	return obj;
		task Control{	
			while(!Obj_IsDeleted(obj)){
			c++;
			if(ObjEnemy_GetInfo(obj,INFO_LIFE) <=0){
			PlaySound("Enep2",100,0);
			Obj_Delete(obj);
			}
			if(collision==true){
			ObjEnemy_SetIntersectionCircleToShot(obj,ObjMove_GetX(obj),ObjMove_GetY(obj),18*size);
			ObjEnemy_SetIntersectionCircleToPlayer(obj,ObjMove_GetX(obj),ObjMove_GetY(obj),12*size);
			}
			yield;
			}
			Obj_Delete(obj);
		}
	}
	
task DrawEnemy(obj,name){
	let img;
	img = GetCurrentScriptDirectory~"img/enm3.png";
	let f = 0;
	let t = 0;
	let px = 64;
	let py = 96;
	let c = 0;
	let idle = true;
	let atk = false;
	let ang = 0;
	let mc = 0;
	let m_time = 0;
	LoadTexture(img);
	ObjPrim_SetTexture(obj, img);
	ObjRender_SetAlpha(obj,192);
	ObjRender_SetScaleXYZ(obj,1.1,1.1,1);
	while(!Obj_IsDeleted(obj))
	{
		let angle = ObjMove_GetAngle(obj);
		let speed = ObjMove_GetSpeed(obj);
		if(speed>0 && idle == true){MarisaTail(obj,name,0,0,px,py,ang);}
		if(speed <= 0 && idle == true && atk == false){
		if(f<8){SetImageAndTail(obj, name,px*0, py*0, px*1, py*1,ang);}
		if(f>=8 && f<16) {SetImageAndTail(obj, name,px*1, py*0, px*2, py*1,ang);}
		if(f>=16 && f<24){SetImageAndTail(obj, name,px*2, py*0, px*3, py*1,ang);}
		if(f>=24 && f<32){SetImageAndTail(obj, name,px*3, py*0, px*4, py*1,ang);}
		if(f==32){f=0;}
		f++;
		c++;
		ObjRender_SetY(obj,ObjMove_GetY(obj)+0.1*sin(c*5));
		t = 0;
		}
		else if(cos(angle) > 0 || cos(angle) < 0 && t == 0){
		idle = false;
		if(cos(angle)>0){ang=180;}
		else{ang=0;}
		manageEnemy(obj,ang,name);
		t = 1;
		}
		ObjSprite2D_SetDestCenter(obj);
		yield;
	}
	task manageEnemy(obj,ang,name){ // Manage movement sprite
		let f = 0;
		let mx = 0;
		let px = 128; 
		let py = 128;
		idle = false;  
		while(f<=16 && idle == false  && atk == false){
		if(f<8){SetImageAndTail(obj, name,px*2, py*0, px*3, py*1,ang);}
		if(f>=8 && f<=16){SetImageAndTail(obj, name,px*2, py*1, px*3, py*2,ang);}
		f+=1;
		yield;
		}
		while(ObjMove_GetSpeed(obj)>1){
		SetImageAndTail(obj, name,px*2, py*1, px*3, py*2,ang);
		yield;
		}
		while(f>=0 && idle == false  && atk == false){
		if(f<8){SetImageAndTail(obj, name,px*2, py*0, px*3, py*1,ang);}
		if(f>=8 && f<=16){SetImageAndTail(obj, name,px*2, py*1, px*3, py*2,ang);}
		f-=1;
		yield;
		}
		idle = true;
	}
	
	task SetImageAndTail(obj,name,r1,r2,r3,r4,angleY){ // Set images rects for the boss, also set the auras
	ObjSprite2D_SetSourceRect(obj,r1,r2,r3,r4);
	MarisaTail(obj,name,r1,r2,r3,r4,angleY);
	ObjRender_SetAngleY(obj,angleY);
	}
	task MarisaTail(boss,name,r1,r2,r3,r4,ang){ // task for the aura (rainbow aura)
	m_time++;
	mc+=+1;
	if(m_time%2==0){
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	let img;
	img = GetCurrentScriptDirectory~"img/enm3.png";
	LoadTexture(img);
	ObjPrim_SetTexture(obj,img);
	ObjSprite2D_SetSourceRect(obj, r1, r2, r3, r4);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetBlendType(obj,BLEND_ADD_ARGB);
	ObjRender_SetScaleXYZ(obj,1,1,1);
	ObjRender_SetAngleXYZ(obj,0,ang,0);
	if(!Obj_IsDeleted(boss)){
	ObjRender_SetPosition(obj,ObjRender_GetX(boss),ObjRender_GetY(boss),0);
	}
	if(ObjRender_GetX(boss)==0 && ObjRender_GetY(boss) ==0){Obj_Delete(obj);}
	Obj_SetRenderPriority(obj,0.3);
	ManageScale;
	ManageAlpha;
	task ManageScale{
		ascent(i in -5..15){
		ObjRender_SetScaleXYZ(obj,1+i*0.12,1+i*0.12,1);
		yield;
		}
		Obj_Delete(obj);
	}
	task ManageAlpha{
		descent(i in 0..20){
		if(!Obj_IsDeleted(boss)){
		ObjRender_SetColor(obj,i*9+60*sin(mc%180),i*9,i*9+60*sin(mc%180));
		yield;
		}
		}
		Obj_Delete(obj);
	}
	}
	}
}

// Custom delay function for AllStarShot.png

function ShotA1(x,y,spd,dir,graphic,cloud,delay){
	let shot = CreateShotA1(x,y,spd,dir,graphic,delay);
	DelayCloud(shot,x,y,spd,dir,graphic,cloud,delay);
	return shot;
	}
	
function TShotA1(x,y,spd,dir,graphic,delay){ // FOR ZUN DELAY CLOUD
	let cloud = CheckDelayColor(graphic);
	let shot = ShotA1(x,y,spd,dir,graphic,cloud,delay);
	return shot;
	}
	
function CheckDelayColor(graphic){ // ZUN DELAY CLOUD
	let color = GetShotDataInfoA1(graphic,TARGET_ENEMY,INFO_DELAY_COLOR);
	let cloud = 0;
	if(color[0]==128 && color[1]==128 && color[2]==128){cloud = 201;} // GRAY
	if(color[0]==255 && color[1]==64 && color[2]==64){cloud = 202;} // RED
	if(color[0]==255 && color[1]==64 && color[2]==255){cloud = 203;} // PURPLE
	if(color[0]==64 && color[1]==64 && color[2]==255){cloud = 204;} // BLUE
	if(color[0]==64 && color[1]==255 && color[2]==255){cloud = 205;} // AQUA
	if(color[0]==64 && color[1]==255 && color[2]==64){cloud = 206;} // GREEN
	if(color[0]==255 && color[1]==255 && color[2]==64){cloud = 207;} // YELLOW
	if(color[0]==192 && color[1]==255 && color[2]==64){cloud = 207;} // YELLOW 2
	if(color[0]==255 && color[1]==128 && color[2]==64){cloud = 208;} // ORANGE
	if(graphic>500){cloud+=500;}
	return cloud;
}
	
function ShotA2(x,y,spd,dir,acc,maxacc,graphic,cloud,delay){
	let shot = CreateShotA2(x,y,spd,dir,acc,maxacc,graphic,delay);
	DelayCloud(shot,x,y,spd,dir,graphic,cloud,delay);
	return shot;
	}
	
function TShotA2(x,y,spd,dir,acc,maxacc,graphic,delay){ // FOR ZUN DELAY CLOUD
	let cloud = CheckDelayColor(graphic);
	let shot = ShotA2(x,y,spd,dir,acc,maxacc,graphic,cloud,delay);
	return shot;
	}

function ShotOA1(obj,spd,dir,graphic,cloud,delay){
	let shot = CreateShotOA1(obj,spd,dir,graphic,delay);
	DelayCloud(shot,ObjMove_GetX(obj),ObjMove_GetY(obj),spd,dir,graphic,cloud,delay);
	return shot;
	}
	
function TShotOA1(obj,spd,dir,graphic,delay){ // FOR ZUN DELAY CLOUD
	let cloud = CheckDelayColor(graphic);
	let shot = ShotOA1(obj,spd,dir,graphic,cloud,delay);
	return shot;
}
	
function ShotB2(x,y,xspd,yspd,xacc,yacc,xmax,ymax,graphic,cloud,delay){
	let angle = atan2(yspd,xspd);
	let shot = CreateShotB2(x,y,xspd,yspd,xacc,yacc,xmax,ymax,graphic,delay);
	DelayCloud(shot,x,y,0,angle,graphic,cloud,delay);
	return shot;
}

task DelayCloud(shot,x,y,spd,dir,graphic,cloud,delay){
	 let img=GCSD~"Shot/AllStarShot.png";
	 let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	 let c = 0;
	 let v = false;
	 let px = 0;
	 let adc = false;
	 let s;
	 if(!Obj_IsDeleted(shot)){
	 ObjPrim_SetTexture(obj,img);
	 ObjRender_SetBlendType(obj,BLEND_ALPHA);
	 ObjRender_SetAngleXYZ(obj,0,0,dir+90);
	 if(cloud==0){cloud=graphic;}
	 if( (cloud>=201 && cloud<=208) || (cloud>=701 && cloud<=708)){
	 s = GetShotDataInfoA1(cloud,TARGET_ENEMY,INFO_COLLISION)/2.5;
	 }
	 else if ( (cloud>=323 && cloud<=330) || (cloud>=823 && cloud<=830)){
	 s = GetShotDataInfoA1(cloud,TARGET_ENEMY,INFO_COLLISION)/5.5;
	 }
	 else{
	  s = GetShotDataInfoA1(cloud,TARGET_ENEMY,INFO_COLLISION)/2.5;
	 }
	 if(GetShotDataInfoA1(cloud,TARGET_ENEMY,INFO_BLEND)==BLEND_ADD_RGB || GetShotDataInfoA1(cloud,TARGET_ENEMY,INFO_BLEND)==BLEND_ADD_ARGB){
	 adc = true;
	 ObjRender_SetBlendType(obj,BLEND_ADD_ARGB);
	 }
	 let s_value = s-1;
	 let rect = GetShotDataInfoA1(cloud,TARGET_ENEMY,INFO_RECT);
	 ObjSprite2D_SetSourceRect(obj,rect[0],rect[1],rect[2],rect[3]);
	 ObjSprite2D_SetDestCenter(obj);
	 ObjRender_SetPosition(obj,x,y,0);
	 while(c<delay && !Obj_IsDeleted(shot)){
	 ObjRender_SetScaleXYZ(obj,s,s,0);
	 if(v==true){ ObjRender_SetAngleXYZ(obj,0,0,dir+90-c*3)};
	 if(s>=1){s -= s_value/delay;}
	 c++;
	 if(adc==false){ObjRender_SetAlpha(obj,c*255/(delay*1.25));}
	else {ObjRender_SetColor(obj,c*255/(delay*1.25),c*255/(delay*1.25),c*255/(delay*1.25));}
	 yield;
	 }
	 Obj_Delete(obj);
	 }
	 }
	 
	function CurvyLaser(x,y,speed,dir,l,w,graphic,fade){
	let shot = CreateShotA1(x,y,speed,dir,graphic,0);
	Obj_SetVisible(shot,false);
	ObjShot_SetIntersectionEnable(shot,false);
	ObjShot_SetSpellResist(shot,true);
	Trail;
	return shot;
		task Trail{
			while(!Obj_IsDeleted(shot)){
				LaserEffect(fade,l,w);
				wait(1);
			}
				task LaserEffect(fade,l,w){
				let fade_value = 1.25;
				fade *= fade_value;
				l = ObjMove_GetSpeed(shot)*l+l;
				let obj = CreateStraightLaserA1(ObjMove_GetX(shot),ObjMove_GetY(shot),ObjMove_GetAngle(shot),l,w,fade/1.5,graphic,0);
				let original_l = l;
				let original_w = w;
				let alpha = 0;
					loop(fade){
					ObjLaser_SetRenderWidth(obj,w*fade_value);
					ObjLaser_SetIntersectionWidth(obj,(w/2)*fade_value);
					ObjLaser_SetLength(obj,l*fade_value);
					if(alpha<200){alpha+=20;}
					ObjRender_SetColor(obj,alpha,alpha,alpha);
					l -= original_l/fade;
					w -= original_w/fade;
					wait(2);
					}
					Obj_Delete(obj);
				}
		}
}

	function CurvyLaser2(x,y,speed,dir,l,w,graphic,fade){
	let shot = CreateShotA1(x,y,speed,dir,graphic,0);
	Obj_SetVisible(shot,false);
	ObjShot_SetIntersectionEnable(shot,false);
	ObjShot_SetSpellResist(shot,true);
	Trail;
	return shot;
		task Trail{
			let c = 0;
			while(!Obj_IsDeleted(shot)){
				LaserEffect(fade,l,w,c);
				wait(1);
				c+=10;
			}
				task LaserEffect(fade,l,w,c){
				let fade_value = 1.25;
				fade *= fade_value;
				l = ObjMove_GetSpeed(shot)*l+l;
				let obj = CreateStraightLaserA1(ObjMove_GetX(shot),ObjMove_GetY(shot),ObjMove_GetAngle(shot),l,w,fade/1.5,graphic,0);
				let original_l = l;
				let original_w = w;
				let alpha = 0;
					loop(fade){
					ObjLaser_SetRenderWidth(obj,w*fade_value);
					ObjLaser_SetIntersectionWidth(obj,(w/2)*fade_value);
					ObjLaser_SetLength(obj,l*fade_value);
					if(alpha<200){alpha+=20;}
					ObjRender_SetColor(obj,192+32*sin(c),48,128+64*sin(c+180));
					l -= original_l/fade;
					w -= original_w/fade;
					wait(2);
					}
					Obj_Delete(obj);
				}
		}
}
	
function ScalingBullet(x,y,v,dir,graphic,hitbox,scale,cloud,delay){
	let shot = ShotA1(x,y,v,dir,hitbox,0,0);
	Obj_SetVisible(shot,false);
		ManageGraphic;
		return shot;
			task ManageGraphic{
			let dummy = ShotOA1(shot,0,0,graphic,cloud,delay);
			ObjRender_SetScaleXYZ(dummy,scale,scale,scale);
			ObjShot_SetIntersectionEnable(dummy,false);
			Obj_SetValue(dummy,"ShotEffectOrNot",0);
				while(!Obj_IsDeleted(shot) && !Obj_IsDeleted(dummy)){
					ObjMove_SetPosition(dummy,ObjMove_GetX(shot),ObjMove_GetY(shot));
					ObjRender_SetAngleXYZ(dummy,0,0,ObjMove_GetAngle(shot));
					yield;
				}
				Obj_Delete(dummy);
			}
	}

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