Esempio n. 1
0
bool CCannon::HaveFreeLineOfFire(const float3& pos, bool userTarget, const CUnit* unit) const
{
	if (!weaponDef->waterweapon && TargetUnitOrPositionInUnderWater(pos, unit))
		return false;

	if (projectileSpeed == 0) {
		return true;
	}

	float3 dif(pos - weaponMuzzlePos);
	float3 dir(GetWantedDir2(dif));

	if (dir.SqLength() == 0) {
		return false;
	}

	float3 flatDir(dif.x, 0, dif.z);
	float flatLength = flatDir.Length();
	if (flatLength == 0) {
		return true;
	}
	flatDir /= flatLength;

	const float linear = dir.y;
	const float quadratic = gravity / (projectileSpeed * projectileSpeed) * 0.5f;
	const float gc = ((collisionFlags & Collision::NOGROUND) == 0)?
		ground->TrajectoryGroundCol(weaponMuzzlePos, flatDir, flatLength - 10, linear, quadratic):
		-1.0f;

	if (gc > 0.0f) {
		return false;
	}

	const float spread =
		((accuracy + sprayAngle) * 0.6f) *
		((1.0f - owner->limExperience * weaponDef->ownerExpAccWeight) * 0.9f);
	const float modFlatLength = flatLength - 30.0f;

	//FIXME add a forcedUserTarget (a forced fire mode enabled with meta key or something) and skip the test below then
	if (TraceRay::TestTrajectoryCone(weaponMuzzlePos, flatDir, modFlatLength,
		dir.y, quadratic, spread, owner->allyteam, avoidFlags, owner)) {
		return false;
	}

	return true;
}
Esempio n. 2
0
bool CCannon::HaveFreeLineOfFire(const float3& pos, bool userTarget, const CUnit* unit) const
{
	// assume we can still fire at partially submerged targets
	if (!weaponDef->waterweapon && TargetUnitOrPositionUnderWater(pos, unit))
		return false;

	if (projectileSpeed == 0) {
		return true;
	}

	float3 dif(pos - weaponMuzzlePos);
	float3 dir(GetWantedDir2(dif));

	if (dir.SqLength() == 0) {
		return false;
	}

	float3 flatDir(dif.x, 0, dif.z);
	float flatLength = flatDir.Length();
	if (flatLength == 0) {
		return true;
	}
	flatDir /= flatLength;

	const float linear = dir.y;
	const float quadratic = gravity / (projectileSpeed * projectileSpeed) * 0.5f;
	const float groundDist = ((avoidFlags & Collision::NOGROUND) == 0)?
		CGround::TrajectoryGroundCol(weaponMuzzlePos, flatDir, flatLength - 10, linear, quadratic):
		-1.0f;
	const float spread = (AccuracyExperience() + SprayAngleExperience()) * 0.6f * 0.9f;

	if (groundDist > 0.0f) {
		return false;
	}

	//FIXME add a forcedUserTarget (a forced fire mode enabled with meta key or something) and skip the test below then
	if (TraceRay::TestTrajectoryCone(weaponMuzzlePos, flatDir, flatLength,
		dir.y, quadratic, spread, owner->allyteam, avoidFlags, owner)) {
		return false;
	}

	return true;
}
Esempio n. 3
0
bool CMissileLauncher::HaveFreeLineOfFire(const float3& pos, bool userTarget, const CUnit* unit) const
{
	// do a different test depending on if the missile has high
	// trajectory (parabolic vs. linear ground intersection)
	if (weaponDef->trajectoryHeight <= 0.0f)
		return CWeapon::HaveFreeLineOfFire(pos, userTarget, unit);

	float3 dir(pos - weaponMuzzlePos);

	float3 flatDir(dir.x, 0, dir.z);
	dir.SafeNormalize();
	float flatLength = flatDir.Length();

	if (flatLength == 0)
		return true;

	flatDir /= flatLength;

	const float linear = dir.y + weaponDef->trajectoryHeight;
	const float quadratic = -weaponDef->trajectoryHeight / flatLength;
	const float groundDist = ((avoidFlags & Collision::NOGROUND) == 0)?
		ground->TrajectoryGroundCol(weaponMuzzlePos, flatDir, flatLength - 30, linear, quadratic):
		-1.0f;
	// FIXME: _WHY_ the 30-elmo subtraction?
	const float modFlatLength = flatLength - 30.0f;

	if (groundDist > 0.0f)
		return false;

	if (TraceRay::TestTrajectoryCone(weaponMuzzlePos, flatDir, modFlatLength,
		linear, quadratic, 0, owner->allyteam, avoidFlags, owner)) {
		return false;
	}

	return true;
}