//*------------------------------------------------*\\
//|        Another Function Library!               |\\
//|                                                |\\
//| Compiled by Darkness1, Functions made by the   |\\
//| many great members of MoTK.                    |\\
//|                                                |\\
//|                                                |\\
//*------------------------------------------------*\\

//Function for objects: TurnToPoint (Version 2. Made by Darkness1, greatly improved by Blargel).

//Four Parameters, which are id, speed, PointX and PointY.

//Makes an object bullet/laser turn till it points at a certain point at the playing field. Doesn't loop by itself. Speed is the speed it //turns at. Inputting a negative value for speed gives you awkward results. Id is (obviously) the id of the object.

function TurnToPoint(id, speed, PointX, PointY){
    let current_angle = Obj_GetAngle(id);
    let target_angle = atan2(PointY-Obj_GetY(id), PointX-Obj_GetX(id));
    let adist = AngularDistance(current_angle, target_angle);

    if(absolute(adist) < speed){
        Obj_SetAngle(id, target_angle);
    }
    else {
        if(adist > 0){
            Obj_SetAngle(id, Obj_GetAngle(id)+speed);
        }
        else if(adist < 0){
            Obj_SetAngle(id, Obj_GetAngle(id)-speed);
        }
    }
}
//|--------------------------------------------------------------------------------------------------|

//NormalizeAngle(angle). Made by Blargel.

//Converts the passed in angle into an angle between 0 and 360, not including 360.
//Examples: NormalizeAngle(540) = 180, NormalizeAngle(-270) = 90, NormalizeAngle(360) = 0.


function NormalizeAngle(angle){
  angle %= 360;
  if(angle<0){ angle += 360; }
  return angle;
}

//|--------------------------------------------------------------------------------------------------|

//IsSameAngle(angle1, angle2). Made by Blargel.

//Checks if angle1 is the same angle as angle2. Returns true if they are, false if they are not. 
//Makes use of the NormalizeAngle function above.
//Examples: IsSameAngle(0, 360) = true, IsSameAngle(-90, 270) = true, IsSameAngle(-30, 30) = false.

function IsSameAngle(angle1, angle2){
  angle1 = NormalizeAngle(angle1);
  angle2 = NormalizeAngle(angle2);
  return angle1==angle2;
}


//|--------------------------------------------------------------------------------------------------|

//AngularDistance(angle1, angle2). Made by Blargel.

//Gets the smallest angle between angle1 and angle2. Will always return a number between -180 and 180, not including -180. A positive //number means the shortest way from angle1 to angle2 goes clockwise, a negative number means the shortest way goes counterclockwise. Also //uses the NormalizeAngle function from above.
//Examples: AngularDistance(90, 180) = 90, AngularDistance(180, 90) = -90, AngularDistance(1, 359) = -2.


function AngularDistance(angle1, angle2){
  let distance = NormalizeAngle(angle2 - angle1);
  if(distance>180){ distance-=360; }
  return distance;
}

//|--------------------------------------------------------------------------------------------------|

//wait function, made by Suikama (no, not really).
//Stalls for t number of frames
//Only usable in tasks. Make sure to have "yield;" somewhere in your @MainLoop.

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

//|--------------------------------------------------------------------------------------------------|

//GetPreviousScriptDirectoryEx, made by Blargel.
//Similar to the previous function, but now you can specify how many levels to go up. Putting 1 will have the same effect as the last //function. Putting 0 will return the exact same thing as GetCurrentScriptDirectory().


function GetPreviousScriptDirectoryEx(num){
  let current = GetCurrentScriptDirectory();
  loop(num){
    current = erase(current, length(current)-1);
    while(current[length(current)-1] != '\'){
      current = erase(current, length(current)-1);
    }
  }
  return current;
}

//|--------------------------------------------------------------------------------------------------|

//Alot of useful functions for stage scripts, made(?) by Mewkyuu.

function WaitForNoEnemy { while(GetEnemyNum!=0) { yield; } }

function WaitToNumOfEnemy(num) { while(GetEnemyNum!=num) { yield; } }

function WaitForFrames(framestowait) { loop(framestowait) { yield; } }

function WaitForNoBomb { while(OnBomb) { yield; } }

function WaitForAlive { while(OnPlayerMissed) { yield; } }

function WaitForDead { while(!OnPlayerMissed) { yield; } }

function WaitForNoInvincibility { while(GetTimeOfSuperNaturalBorder != 0 && GetTimeOfPlayerInvincibility != 0) { yield; } }

function WaitForNoEvent { while(OnEvent) { yield; } }

//|--------------------------------------------------------------------------------------------------|

//Function: GetLineBorderPoint(px, py, tx, ty) made by Iryan.

//What it does: returns [a, b], which are the coordinates of the point of intersection between the playing field's border and a ray from one //point in the direction of another point.

//Parameters: 

//px, py: source point
//tx, ty: target point


function GetLineBorderPoint(px, py, tx, ty){

	let ta = atan2(ty-py, tx-px);

	if( ta>= atan2(GetClipMinY - py, GetClipMinX - px) && ta<=  atan2(GetClipMinY - py, GetClipMaxX - px)){
		return [px - (GetClipMinY-py)*tan(ta+90), GetClipMinY];
	}
	if( ta>= atan2(GetClipMinY - py, GetClipMaxX - px) && ta<=  atan2(GetClipMaxY - py, GetClipMaxX - px)){
		return [GetClipMaxX, py + (GetClipMaxX-px)*tan(ta)];
	}
	if( ta>= atan2(GetClipMaxY - py, GetClipMaxX - px) && ta<=  atan2(GetClipMaxY - py, GetClipMinX - px)){
		return [px - (GetClipMaxY-py)*tan(ta-90), GetClipMaxY];
	}
	if( ta> atan2(GetClipMaxY - py, GetClipMinX - px) || ta<  atan2(GetClipMinY - py, GetClipMinX - px)){
		return [GetClipMinX, py + (GetClipMinX-px)*tan(ta+180)];
	}
}


//|--------------------------------------------------------------------------------------------------|

//ObjEffect_SetAlpha(obj,vertices,alpha). Made by Azure Lazuline, modified to contain colors as well.

//Since Obj_SetAlpha doesn't work with effect objects, you need to loop through each vertex with ObjEffect_SetVertexColor instead. That's //boring, so I made a function for it. obj is the object to apply it to, vertices is the number of vertices of the object, and alpha is the //alpha value to set it to. You can also easily modify this to allow color setting in addition to alpha.


function ObjEffect_SetAlpha(obj,vertices,alpha,color1,color2,color3){
	let k=0;
	loop(vertices){
		ObjEffect_SetVertexColor(obj,k,alpha,color1,color2,color3);
		k++;
	}
}


//|--------------------------------------------------------------------------------------------------|

//Function for objects: TurnToAngle (Made by Darkness1).

//Three Parameters, which are id, speed and angle.

//Makes an object bullet/laser turn till it's angle is equal to the number input as the parameter angle. Doesn't loop by itself. Speed is //the speed it turns at. Inputting a negative value for speed gives you awkward results. Id is (obviously) the id of the object.


function TurnToAngle(id, speed, angle){
    let current_angle = Obj_GetAngle(id);
    let target_angle = angle;
    let adist = AngularDistance(current_angle, target_angle);

    if(absolute(adist) < speed){
        Obj_SetAngle(id, target_angle);
    }
    else {
        if(adist > 0){
            Obj_SetAngle(id, Obj_GetAngle(id)+speed);
        }
        else if(adist < 0){
            Obj_SetAngle(id, Obj_GetAngle(id)-speed);
        }
    }
}


//|--------------------------------------------------------------------------------------------------|
