Sources/CryGame C++/Solution1/CryGame/ScriptObjectWeaponClass.cpp
//////////////////////////////////////////////////////////////////////
/*! Calculate the needed firing angle to fire a projectile with the
passed properties to the passed spot
@param v Velocity of the projectile
@param g Gravity of the projectile
@param x horizontal distance to the required impact point
@param y vertical distance between shooter and projectile impact point


input: x - horizontal distance to target (always positive), y - vertical distance to target (pisitive or negative), v - initial particle velocity (scalar, positive), g - gravity (positive scalar, assume that it vector points down)

d = sqrt(v^4 - 2*g*y*v^2-g^2*x^2)
(if expression is negative, no solution)
a = v^2-g*y
t = sqrt(2*(a+d)/g^2)
angle = acos(x/(v*t))

then compute y_test = v*sin_tpl(angle)*t-g*t^2/2,
if (y_test*y<0 (false root) && a-d>0), try t = sqrt(2*(a-d)/g^2) (else no solution)
*/
Calculate the needed firing angle to fire a projectile with the
passed properties to the passed spot
Calculate the needed firing angle to fire a projectile with the passed properties to the passed spot
int CScriptObjectWeaponClass::GetProjectileFiringAngle(IFunctionHandler *pH)
{
	float x,y,v,g;
	CHECK_PARAMETERS(4);
	pH->GetParam(1, v);
	pH->GetParam(2, g);
	pH->GetParam(3, x);
	pH->GetParam(4, y);
	float angle=0.0,t,a;
	float d = cry_sqrtf(powf(v,4)-2*g*y*powf(v,2)-powf(g,2)*powf(x,2));
	if(d>=0)
	{
		a=powf(v,2)-g*y;
		if (a-d>0) {
			t=cry_sqrtf(2*(a-d)/powf(g,2));
			angle = (float)acos_tpl(x/(v*t));	
			float y_test;
			y_test=float(-v*sin_tpl(angle)*t-g*powf(t,2)/2);
			if (fabsf(y-y_test)<0.02f)
				return pH->EndFunction(RAD2DEG(-angle));
			y_test=float(v*sin_tpl(angle)*t-g*pow(t,2)/2);
			if (fabsf(y-y_test)<0.02f)
				return pH->EndFunction(RAD2DEG(angle));
		}
		t = cry_sqrtf(2*(a+d)/powf(g,2));
		angle = (float)acos_tpl(x/(v*t));	
		float y_test=float(v*sin_tpl(angle)*t-g*pow(t,2)/2);
		if (fabsf(y-y_test)<0.02f)
			return pH->EndFunction(RAD2DEG(angle));
		return pH->EndFunction(0);
	}
	return pH->EndFunction(0);
}
int CScriptObjectWeaponClass :: GetProjectileFiringAngle ( IFunctionHandler * pH ) { float x , y , v , g ; CHECK_PARAMETERS ( 4 ) ; pH -> GetParam ( 1 , v ) ; pH -> GetParam ( 2 , g ) ; pH -> GetParam ( 3 , x ) ; pH -> GetParam ( 4 , y ) ; float angle = 0.0 , t , a ; float d = cry_sqrtf ( powf ( v , 4 ) - 2 * g * y * powf ( v , 2 ) - powf ( g , 2 ) * powf ( x , 2 ) ) ; if ( d >= 0 ) { a = powf ( v , 2 ) - g * y ; if ( a - d > 0 ) { t = cry_sqrtf ( 2 * ( a - d ) / powf ( g , 2 ) ) ; angle = ( float ) acos_tpl ( x / ( v * t ) ) ; float y_test ; y_test = float ( - v * sin_tpl ( angle ) * t - g * powf ( t , 2 ) / 2 ) ; if ( fabsf ( y - y_test ) < 0.02f ) return pH -> EndFunction ( RAD2DEG ( - angle ) ) ; y_test = float ( v * sin_tpl ( angle ) * t - g * pow ( t , 2 ) / 2 ) ; if ( fabsf ( y - y_test ) < 0.02f ) return pH -> EndFunction ( RAD2DEG ( angle ) ) ; } t = cry_sqrtf ( 2 * ( a + d ) / powf ( g , 2 ) ) ; angle = ( float ) acos_tpl ( x / ( v * t ) ) ; float y_test = float ( v * sin_tpl ( angle ) * t - g * pow ( t , 2 ) / 2 ) ; if ( fabsf ( y - y_test ) < 0.02f ) return pH -> EndFunction ( RAD2DEG ( angle ) ) ; return pH -> EndFunction ( 0 ) ; } return pH -> EndFunction ( 0 ) ; }
Calculate the needed firing angle to fire a projectile with the
passed properties to the passed spot
Calculate the needed firing angle to fire a projectile with the passed properties to the passed spot
// Avoid square root in script
