//--------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------
//Functions useful for both bosses and small fry. Is automatically included in functions_boss.txt
//--------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------

#include "./functions_general_stage.txt"
#include "./functions_enemy.txt"
#include "./../AllStarShot_Const.txt"

task SetSpellBack(g)
	{
	Obj_SetValue(objPlayer,"SPELL_BACK",g);
	}
function GetSpellBack
	{
	return Obj_GetValueD(objPlayer,"SPELL_BACK",SHOT_GRAY);
	}

//--------------------------------------------------------------------------------------------------------
//Basic bullet creation functions. Now includes scale and damage. Should be used instead of CreateShot.
//--------------------------------------------------------------------------------------------------------
function CreateBulletA1(x,y,speed,angle,graph,delay,scale,damage)
	{	
	if(damage > SHOT_BLACK)
		{
		damage = SHOT_GRAY;
		}
	if(damage < SHOT_BLUE)
		{
		damage = SHOT_BLUE;
		}
	let shot = CreateShotA1(x,y,speed,angle,graph[damage],delay);
	ObjRender_SetScaleXYZ(shot,scale,scale,0);
	ObjShot_SetStrength(shot,damage);
	ObjShot_SetScale(shot,scale);	
	return shot;
	}
function CreateBulletA2(x,y,speed,angle,accel,velo,max,graph,delay,scale,damage)
	{
	let shot = CreateBulletA1(x,y,speed,angle,graph,delay,scale,damage);
	ObjMove_SetAcceleration(shot,accel);
	ObjMove_SetAngularVelocity(shot,velo);
	ObjMove_SetMaxSpeed(shot,max);
	return shot;
	}
function CreateBulletB1(x,y,xS,yS,graph,delay,scale,damage)
	{
	let shot = CreateBulletA1(x,y,0,0,graph,delay,scale,damage);;
	ObjMove_AddPatternB1(shot,0,xS,yS);
	return shot;
	}
function CreateBulletB2(x,y,xS,yS,xA,yA,xM,yM,graph,delay,scale,damage)
	{
	let shot = CreateBulletA1(x,y,0,0,graph,delay,scale,damage);
	ObjMove_AddPatternB2(shot,0,xS,yS,xA,yA,xM,yM);
	return shot;
	}

//--------------------------------------------------------------------------------------------------------
//Laser functions.----------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------
//Loose Laser-----------------------
function CreateLaserA1(x,y,speed,angle,dist,width,graph,delay,damage)
{
	if(damage > SHOT_BLACK)
		{
		damage = SHOT_GRAY;
		}
	if(damage < SHOT_BLUE)
		{
		damage = SHOT_BLUE;
		}
	let shot = CreateStraightLaserA1(x,y,angle,0,width,10^10,graph[damage],delay);
	Obj_SetValue(shot,"LASER",true);
	ObjLaser_SetSpeed(shot,speed);
	ObjLaser_SetMaxLength(shot,dist);
	ObjShot_SetStrength(shot,damage);
	ObjShot_SetScale(shot,width);
	ObjLaserIntersectionRender(shot,10^10);
	ObjShot_SetIntersectionEnable(shot,false);
	TMove;
	return shot;

	task TMove
		{
		while(ObjLaser_GetLength(shot) < dist){if(Obj_IsDeleted(shot)){return;}yield;}
		ObjStLaser_SetSource(shot,false);
		ObjMove_SetAngle(shot,ObjStLaser_GetAngle(shot));
		ObjMove_SetSpeed(shot,ObjLaser_GetSpeed(shot));	
		ObjMove_SetAcceleration(shot,ObjLaser_GetAcceleration(shot));
		ObjMove_SetMaxSpeed(shot,ObjLaser_GetMaxSpeed(shot));
		}
}
//Straight laser. Starts out with a length of 0. The length increases by "speed" every frame until it equals "dist".
function CreateLaserA2(x,y,speed,angle,dist,width,del,graph,delay,damage)
{
	if(damage > SHOT_BLACK)
		{
		damage = SHOT_GRAY;
		}
	if(damage < SHOT_BLUE)
		{
		damage = SHOT_BLUE;
		}
	let shot = CreateStraightLaserA1(x,y,angle,0,width,10^10,graph[damage],0);
	Obj_SetValue(shot,"LASER",true);
	ObjLaser_SetSpeed(shot,speed);
	ObjLaser_SetMaxLength(shot,dist);
	ObjShot_SetStrength(shot,damage);
	ObjShot_SetScale(shot,width);
	ObjLaser_SetDelay(shot,delay);
	ObjLaserIntersectionRender(shot,del);
	ObjShot_SetIntersectionEnable(shot,false);
	return shot;
}
//Straight laser. Starts out with a length of 0. The length increases by "speed" every frame until it equals "dist". Has acceleration.
function CreateLaserA3(x,y,speed,angle,accel,mspeed,dist,width,del,graph,delay,damage)
{
	if(damage > SHOT_BLACK)
		{
		damage = SHOT_GRAY;
		}
	if(damage < SHOT_BLUE)
		{
		damage = SHOT_BLUE;
		}
	let shot = CreateStraightLaserA1(x,y,angle,0,width,10^10,graph[damage],0);
	Obj_SetValue(shot,"LASER",true);
	ObjLaser_SetSpeed(shot,speed);
	ObjLaser_SetAcceleration(shot,accel);
	ObjLaser_SetMaxSpeed(shot,mspeed);
	ObjLaser_SetMaxLength(shot,dist);
	ObjShot_SetStrength(shot,damage);
	ObjShot_SetScale(shot,width);
	ObjLaser_SetDelay(shot,delay);
	ObjLaserIntersectionRender(shot,del);
	ObjShot_SetIntersectionEnable(shot,false);
	return shot;
}
task ObjLaser_SetDelay(shot,val)
	{
	Obj_SetValue(shot,"LASER_DELAY",val);
	}
function ObjLaser_GetDelay(shot)
	{
	return Obj_GetValueD(shot,"LASER_DELAY",0);
	}
task ObjLaser_SetSpeed(shot,val)
	{
	Obj_SetValue(shot,"LASER_SPEED",val);
	}
function ObjLaser_GetSpeed(shot)
	{
	return Obj_GetValueD(shot,"LASER_SPEED",0);
	}
task ObjLaser_SetAcceleration(shot,val)
	{
	Obj_SetValue(shot,"LASER_ACCEL",val);
	}
function ObjLaser_GetAcceleration(shot)
	{
	return Obj_GetValueD(shot,"LASER_ACCEL",0);
	}
task ObjLaser_SetMaxSpeed(shot,val)
	{
	Obj_SetValue(shot,"LASER_MSPEED",val);
	}
function ObjLaser_GetMaxSpeed(shot)
	{
	return Obj_GetValueD(shot,"LASER_MSPEED",0);
	}
task ObjLaser_SetMaxLength(shot,val)
	{
	Obj_SetValue(shot,"LASER_MAX",val);
	}
function ObjLaser_GetMaxLength(shot)
	{
	return Obj_GetValueD(shot,"LASER_MAX",0);
	}
task ObjLaser_SetScale(shot,scale)
	{
	if(shot == ID_INVALID || Obj_IsDeleted(shot)){return;}
	Obj_SetValue(shot,"SHOT_HITBOX",scale);
	}
function ObjLaser_GetScale(shot)
	{
	if(shot == ID_INVALID || Obj_IsDeleted(shot)){return;}
	return Obj_GetValueD(shot,"SHOT_HITBOX",-1);
	}
task ObjLaser_SetGrazeEnable(obj,val)
	{
	Obj_SetValue(obj,"GRAZE_PERMIT",val);
	}
function ObjLaser_GetGrazeEnable(obj)
	{
	return Obj_GetValueD(obj,"GRAZE_PERMIT",true);
	}
task ObjLaserIntersectionRender(shot,del)
	{
	let delayM = ObjLaser_GetDelay(shot);
	let c = -1;
	let wA = 0.2;
	while(!Obj_IsDeleted(shot))
		{
		c+=1;

		let x = ObjMove_GetX(shot);
		let y = ObjMove_GetY(shot);
		let d = ObjLaser_GetLength(shot);
		let a = ObjStLaser_GetAngle(shot);
		let w = ObjShot_GetScale(shot)*0.5;
		let delay = ObjLaser_GetDelay(shot);
		if(delay != delayM)
			{
			delayM = delay;
			c = 0;
			}

		let ld = ObjLaser_GetMaxLength(shot);
		let ls = ObjLaser_GetSpeed(shot);
		let la = ObjLaser_GetAcceleration(shot);
		let lm = ObjLaser_GetMaxSpeed(shot);

		if((ls < lm && la > 0) || (ls > lm && la < 0))
			{
			ls+=la;
			}
		else if(la != 0)
			{
			ls = lm;
			}
		ObjLaser_SetSpeed(shot,ls);

		if(d < ld)
			{
			d+=ls;
			}
		if(d > ld)
			{
			d = ld;
			}
		ObjLaser_SetLength(shot,d);

		if(c >= del+delay)
			{
			if(w > 0.1)
				{
				w *= 0.875;
				ObjShot_SetScale(shot,w*2);
				}
			else
				{
				Obj_Delete(shot);
				break;
				}
			}

		if(c >= delay)
			{
			if(wA < 1)
				{
				wA+=(1-wA)/4;
				}
			if(Obj_GetValueD(GetPlayerObjectID,"DAMAGE",0) == 0 && GetPlayerInvincibilityFrame <= 0 && w >= 1 && ObjShot_GetIntersection(shot) == true && IsIntersected_Line_Circle(x,y,x+d*cos(a),y+d*sin(a),w*0.4*2*wA,GetPlayerX,GetPlayerY,GetPlayerGrazebox))
				{
				if(IsIntersected_Line_Circle(x,y,x+d*cos(a),y+d*sin(a),w*0.4*2*wA,GetPlayerX,GetPlayerY,GetPlayerHitbox))
					{
					Obj_SetValue(GetPlayerObjectID,"DAMAGE",ObjShot_GetStrength(shot));
					}
				if(ObjLaser_GetGrazeEnable(shot))
					{
					}
				}
			}
		ObjLaser_SetRenderWidth(shot,w*2*wA);
		yield;
		}
	}