#include <a_samp>

stock Float:DistanceCameraTargetToLocation(Float:CamX, Float:CamY, Float:CamZ, Float:ObjX, Float:ObjY, Float:ObjZ, Float:FrX, Float:FrY, Float:FrZ)
{
	new Float:TGTDistance;
	TGTDistance = floatsqroot((CamX - ObjX) * (CamX - ObjX) + (CamY - ObjY) * (CamY - ObjY) + (CamZ - ObjZ) * (CamZ - ObjZ));
	new Float:tmpX, Float:tmpY, Float:tmpZ;
	tmpX = FrX * TGTDistance + CamX;
	tmpY = FrY * TGTDistance + CamY;
	tmpZ = FrZ * TGTDistance + CamZ;
	return floatsqroot((tmpX - ObjX) * (tmpX - ObjX) + (tmpY - ObjY) * (tmpY - ObjY) + (tmpZ - ObjZ) * (tmpZ - ObjZ));
}

stock Float:GetPointAngleToPoint(Float:x2, Float:y2, Float:X, Float:Y)
{
  	new Float:DX, Float:DY;
  	new Float:angle;

  	DX = floatabs(floatsub(x2,X));
  	DY = floatabs(floatsub(y2,Y));

  	if (DY == 0.0 || DX == 0.0)
	{
	    if(DY == 0 && DX > 0) angle = 0.0;
	    else if(DY == 0 && DX < 0) angle = 180.0;
	    else if(DY > 0 && DX == 0) angle = 90.0;
	    else if(DY < 0 && DX == 0) angle = 270.0;
	    else if(DY == 0 && DX == 0) angle = 0.0;
  	}
  	else
	{
    	angle = atan(DX/DY);
    	if(X > x2 && Y <= y2) angle += 90.0;
    	else if(X <= x2 && Y < y2) angle = floatsub(90.0, angle);
    	else if(X < x2 && Y >= y2) angle -= 90.0;
    	else if(X >= x2 && Y > y2) angle = floatsub(270.0, angle);
  	}
  	return floatadd(angle, 90.0);
}

stock GetXYInFrontOfPoint(&Float:x, &Float:y, Float:angle, Float:distance)
{
	x += (distance * floatsin(-angle, degrees));
	y += (distance * floatcos(-angle, degrees));
}

stock IsPlayerAimingAt(playerid, Float:x, Float:y, Float:z, Float:radius)
{
  	new Float:camera_x,Float:camera_y,Float:camera_z,Float:vector_x,Float:vector_y,Float:vector_z;
  	GetPlayerCameraPos(playerid, camera_x, camera_y, camera_z);
  	GetPlayerCameraFrontVector(playerid, vector_x, vector_y, vector_z);
	new Float:vertical, Float:horizontal;
	switch (GetPlayerWeapon(playerid))
	{
	  	case 34,35,36:
	  	{
	  		if (DistanceCameraTargetToLocation(camera_x, camera_y, camera_z, x, y, z, vector_x, vector_y, vector_z) < radius) return true;
	  		return false;
	  	}
	  	case 30,31: {vertical = 4.0; horizontal = -1.6;}
	  	case 33: {vertical = 2.7; horizontal = -1.0;}
	  	default: {vertical = 6.0; horizontal = -2.2;}
	}
  	new Float:angle = GetPointAngleToPoint(0, 0, floatsqroot(vector_x*vector_x+vector_y*vector_y), vector_z) - 270.0;
  	new Float:resize_x, Float:resize_y, Float:resize_z = floatsin(angle+vertical, degrees);
  	GetXYInFrontOfPoint(resize_x, resize_y, GetPointAngleToPoint(0, 0, vector_x, vector_y)+horizontal, floatcos(angle+vertical, degrees));
  	if (DistanceCameraTargetToLocation(camera_x, camera_y, camera_z, x, y, z, resize_x, resize_y, resize_z) < radius) return true;
  	return false;
}

stock IsPlayerAimingAtPlayer(playerid, targetid)
{
 	new Float:x, Float:y, Float:z;
 	GetPlayerPos(targetid, x, y, z);
 	if (IsPlayerAimingAt(playerid, x, y, z-0.75, 0.25)) return true;
 	if (IsPlayerAimingAt(playerid, x, y, z-0.25, 0.25)) return true;
 	if (IsPlayerAimingAt(playerid, x, y, z+0.25, 0.25)) return true;
 	if (IsPlayerAimingAt(playerid, x, y, z+0.75, 0.25)) return true;
 	return false;
}

stock IsHeadshot(playerid, targetplayerid)
{
  	new Float:x, Float:y, Float:z;
  	GetPlayerPos(targetplayerid, x, y, z);
  	return IsPlayerAimingAt(playerid, x, y, z+0.8, 0.2);
}

stock Float:ReturnCamDistanceToPoint(playerid, Float:X, Float:Y, Float:Z)
{
    new Float:camera_x,Float:camera_y,Float:camera_z,Float:vector_x,Float:vector_y,Float:vector_z;
  	GetPlayerCameraPos(playerid, camera_x, camera_y, camera_z);
  	GetPlayerCameraFrontVector(playerid, vector_x, vector_y, vector_z);
  	return DistanceCameraTargetToLocation(camera_x, camera_y, camera_z, X, Y, Z, vector_x, vector_y, vector_z);
}

stock Float:GetAngleToPoint(Float:X, Float:Y, Float:A, Float:x, Float:y)
{
	new Float:angle = 185.0 - atan2(X-x, Y-y);
	A -= (angle - 5.0);
	return A;
}

stock Float:GetVehicleAngleToPoint(vehicleid, Float:x, Float:y)
{
    new Float:ix, Float:iy, Float:iz, Float:a;
	GetVehicleZAngle(vehicleid, a);
	GetVehiclePos(vehicleid, ix, iy, iz);
	return GetAngleToPoint(ix, iy, a, x, y);
}

stock GetPlayerAngleToPoint(playerid, Float:x, Float:y)
{
	new Float:ix, Float:iy, Float:iz, Float:a;
	GetPlayerFacingAngle(playerid, a);
	GetPlayerPos(playerid, ix, iy, iz);
	return floatround(GetAngleToPoint(ix, iy, a, x, y));
}

stock Float:GetPlayerAngleToPlayer(playerid, facingtoid)
{
	new Float:x, Float:y, Float:z;
	GetPlayerPos(facingtoid, x, y, z);
	return float(GetPlayerAngleToPoint(playerid, x, y));
}

stock GetPlayerFaceToPlayer(playerid, targetid, Float:facing)
{
	new Float:radius = GetPlayerAngleToPlayer(playerid, targetid);
	return (radius > -facing && radius < facing);
}

stock TurnPlayerFaceToPlayer(playerid, facingtoid)
{
	new Float:x, Float:y, Float:z;
	GetPlayerPos(facingtoid, x, y, z);
	SetPlayerFaceToPoint(playerid, x, y);
	return true;
}

stock SetPlayerFaceToPoint(playerid, Float:X, Float:Y)
{
    new Float:angle;
	new Float:misc = 5.0;
	new Float:x, Float:y, Float:z;
	GetPlayerPos(playerid, x, y, z);
	angle = 180.0-atan2(x-X,y-Y);
	angle += misc;
	misc *= -1;
	SetPlayerFacingAngle(playerid, angle+misc);
    return true;
}
