//Moosh
//v0.3 - Added SafeSqrt - Requires std_functions.zh for 2.50.2

void DrawLaser(int layer, int x, int y, int width, int rotation, int color){
	Screen->Circle(layer, x+width, y, width, color, 1, x, y, rotation, true, 128);
	Screen->Rectangle(layer, x+width, y-width, x+width+512, y+width, color, 1, x, y, rotation, true, 128);
}

void LaserDetect(int x, int y, int width, int rotation, int damage){
	if(RotRectCollision(x+VectorX(128, rotation), y+VectorY(128, rotation), width, 128, rotation, CenterLinkX(), CenterLinkY(), 6, 6, 0)){
		eweapon dmg=FireEWeapon(EW_SCRIPT1, Link->X+InFrontX(Link->Dir, 10), Link->Y+InFrontY(Link->Dir, 10), 0, 0, damage, -1, 0, EWF_UNBLOCKABLE);
		dmg->Dir = Link->Dir;
		SetEWeaponLifespan(dmg, EWL_TIMER, 2);
		SetEWeaponDeathEffect(dmg, EWD_VANISH, 0);
		dmg->DrawYOffset=-1000;
	}
}

bool LaserDetect2(int x, int y, int width, int rotation){
	if(RotRectCollision(x+VectorX(128, rotation), y+VectorY(128, rotation), width, 128, rotation, CenterLinkX(), CenterLinkY(), 6, 6, 0)){
		return true;
	}
	return false;
}

void Laser(int layer, int x, int y, int width, int rotation, int damage, int color){
	DrawLaser(layer, x, y, width, rotation, color);
	if(damage>0)LaserDetect(x, y, width, rotation, damage);
}

void Laser3Color(int layer, int x, int y, int width, int rotation, int damage, int color){
	DrawLaser(layer, x, y, width, rotation, color+2);
	DrawLaser(layer, x, y, width/4*3, rotation, color+1);
	DrawLaser(layer, x, y, width/2, rotation, color);
	if(damage>0)LaserDetect(x, y, width, rotation, damage);
}

void Laser3Color(int layer, int x, int y, int width, int rotation, int damage, int color1, int color2, int color3){
	DrawLaser(layer, x, y, width, rotation, color1);
	DrawLaser(layer, x, y, width/4*3, rotation, color2);
	DrawLaser(layer, x, y, width/2, rotation, color3);
	if(damage>0)LaserDetect(x, y, width, rotation, damage);
}

bool RotRectCollision(float x1c, float y1c, float height1, float width1, float rot1, float x2c, float y2c, float height2, float width2, float rot2){
	float rad1=SafeSqrt(height1*height1+width1*width1);
	float rad2=SafeSqrt(height2*height2+width2*width2);
	float angle1=RadtoDeg(ArcSin(height1/rad1));
	float angle2=RadtoDeg(ArcSin(height2/rad2));
	float x1[4];
	float y1[4];
	float x2[4];
	float y2[4];
	float axisX[4];
	float axisY[4];
	float proj;
	float minProj1;
	float maxProj1;
	float minProj2;
	float maxProj2;
	x1[0]=x1c+rad1*Cos(rot1-angle1);
	y1[0]=y1c+rad1*Sin(rot1-angle1);
	x1[1]=x1c+rad1*Cos(rot1+angle1);
	y1[1]=y1c+rad1*Sin(rot1+angle1);
	x1[2]=x1c+rad1*Cos(rot1+180-angle1);
	y1[2]=y1c+rad1*Sin(rot1+180-angle1);
	x1[3]=x1c+rad1*Cos(rot1+180+angle1);
	y1[3]=y1c+rad1*Sin(rot1+180+angle1);
	x2[0]=x2c+rad2*Cos(rot2-angle2);
	y2[0]=y2c+rad2*Sin(rot2-angle2);
	x2[1]=x2c+rad2*Cos(rot2+angle2);
	y2[1]=y2c+rad2*Sin(rot2+angle2);
	x2[2]=x2c+rad2*Cos(rot2+180-angle2);
	y2[2]=y2c+rad2*Sin(rot2+180-angle2);
	x2[3]=x2c+rad2*Cos(rot2+180+angle2);
	y2[3]=y2c+rad2*Sin(rot2+180+angle2);
	axisX[0]=x1[0]-x1[1];
	axisY[0]=y1[0]-y1[1];
	axisX[1]=x1[2]-x1[1];
	axisY[1]=y1[2]-y1[1];
	axisX[2]=x2[0]-x2[1];
	axisY[2]=y2[0]-y2[1];
	axisX[3]=x2[2]-x2[1];
	axisY[3]=y2[2]-y2[1];
	for(int i=0; i<4; i++){
		proj=x1[0]*axisX[i]+y1[0]*axisY[i];
		minProj1=proj;
		maxProj1=proj;
		for(int j=1; j<4; j++){
			proj=x1[j]*axisX[i]+y1[j]*axisY[i];
			if(proj<minProj1)
				minProj1=proj;
			if(proj>maxProj1)
				maxProj1=proj;
		}
		proj=x2[0]*axisX[i]+y2[0]*axisY[i];
		minProj2=proj;
		maxProj2=proj;
		for(int j=1; j<4; j++){
			proj=x2[j]*axisX[i]+y2[j]*axisY[i];
			if(proj<minProj2)
				minProj2=proj;
			if(proj>maxProj2)
				maxProj2=proj;
		}
		if(maxProj2<minProj1 || maxProj1<minProj2)
			return false;
	}
	return true;
}


bool RotRectCollision(float x1c, float y1c, float height1, float width1, float rot1, float x2c, float y2c, float height2, float width2, float rot2, bool debug){
	float rad1=SafeSqrt(height1*height1+width1*width1);
	float rad2=SafeSqrt(height2*height2+width2*width2);
	float angle1=RadtoDeg(ArcSin(height1/rad1));
	float angle2=RadtoDeg(ArcSin(height2/rad2));
	float x1[4];
	float y1[4];
	float x2[4];
	float y2[4];
	float axisX[4];
	float axisY[4];
	float proj;
	float minProj1;
	float maxProj1;
	float minProj2;
	float maxProj2;
	x1[0]=x1c+rad1*Cos(rot1-angle1);
	y1[0]=y1c+rad1*Sin(rot1-angle1);
	x1[1]=x1c+rad1*Cos(rot1+angle1);
	y1[1]=y1c+rad1*Sin(rot1+angle1);
	x1[2]=x1c+rad1*Cos(rot1+180-angle1);
	y1[2]=y1c+rad1*Sin(rot1+180-angle1);
	x1[3]=x1c+rad1*Cos(rot1+180+angle1);
	y1[3]=y1c+rad1*Sin(rot1+180+angle1);
	x2[0]=x2c+rad2*Cos(rot2-angle2);
	y2[0]=y2c+rad2*Sin(rot2-angle2);
	x2[1]=x2c+rad2*Cos(rot2+angle2);
	y2[1]=y2c+rad2*Sin(rot2+angle2);
	x2[2]=x2c+rad2*Cos(rot2+180-angle2);
	y2[2]=y2c+rad2*Sin(rot2+180-angle2);
	x2[3]=x2c+rad2*Cos(rot2+180+angle2);
	y2[3]=y2c+rad2*Sin(rot2+180+angle2);
	axisX[0]=x1[0]-x1[1];
	axisY[0]=y1[0]-y1[1];
	axisX[1]=x1[2]-x1[1];
	axisY[1]=y1[2]-y1[1];
	axisX[2]=x2[0]-x2[1];
	axisY[2]=y2[0]-y2[1];
	axisX[3]=x2[2]-x2[1];
	axisY[3]=y2[2]-y2[1];
	if(debug){
		Screen->Rectangle(6, x1c-width1, y1c-height1, x1c+width1, y1c+height1, 1, -1, x1c, y1c, rot1, true, 128);
		Screen->Rectangle(6, x2c-width2, y2c-height2, x2c+width2, y2c+height2, 2, -1, x2c, y2c, rot2, true, 128);
	}
	for(int i=0; i<4; i++){
		proj=x1[0]*axisX[i]+y1[0]*axisY[i];
		minProj1=proj;
		maxProj1=proj;
		for(int j=1; j<4; j++){
			proj=x1[j]*axisX[i]+y1[j]*axisY[i];
			if(proj<minProj1)
				minProj1=proj;
			if(proj>maxProj1)
				maxProj1=proj;
		}
		proj=x2[0]*axisX[i]+y2[0]*axisY[i];
		minProj2=proj;
		maxProj2=proj;
		for(int j=1; j<4; j++){
			proj=x2[j]*axisX[i]+y2[j]*axisY[i];
			if(proj<minProj2)
				minProj2=proj;
			if(proj>maxProj2)
				maxProj2=proj;
		}
		if(maxProj2<minProj1 || maxProj1<minProj2)
			return false;
	}
	return true;
}