Example #1
0
float3 CCannon::GetWantedDir(const float3& diff)
{
	// try to cache results, sacrifice some (not much too much even for a pewee) accuracy
	// it saves a dozen or two expensive calculations per second when 5 guardians
	// are shooting at several slow- and fast-moving targets
	if (math::fabs(diff.x - lastDiff.x) < (SQUARE_SIZE / 4.0f) &&
		math::fabs(diff.y - lastDiff.y) < (SQUARE_SIZE / 4.0f) &&
		math::fabs(diff.z - lastDiff.z) < (SQUARE_SIZE / 4.0f)) {
		return lastDir;
	}

	const float3 dir = GetWantedDir2(diff);
	lastDiff = diff;
	lastDir  = dir;
	return dir;
}
Example #2
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;
}
Example #3
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;
}