Пример #1
0
bool CLightningCannon::TryTarget(const float3& pos, bool userTarget, CUnit* unit)
{
	if (!CWeapon::TryTarget(pos, userTarget, unit))
		return false;

	if (!weaponDef->waterweapon && TargetUnitOrPositionInWater(pos, unit))
		return false;

	float3 dir = pos - weaponMuzzlePos;
	float length = dir.Length();
	if (length == 0)
		return true;

	dir /= length;

	if (!HaveFreeLineOfFire(weaponMuzzlePos, dir, length, unit)) {
		return false;
	}

	if (avoidFeature && TraceRay::LineFeatureCol(weaponMuzzlePos, dir, length)) {
		return false;
	}
	if (avoidFriendly && TraceRay::TestAllyCone(weaponMuzzlePos, dir, length, (accuracy + sprayAngle), owner->allyteam, owner)) {
		return false;
	}
	if (avoidNeutral && TraceRay::TestNeutralCone(weaponMuzzlePos, dir, length, (accuracy + sprayAngle), owner)) {
		return false;
	}

	return true;
}
Пример #2
0
bool CBeamLaser::TryTarget(const float3& pos, bool userTarget, CUnit* unit)
{
	if (!CWeapon::TryTarget(pos, userTarget, unit))
		return false;

	if (!weaponDef->waterweapon) {
		if (unit) {
			if (unit->isUnderWater)
				return false;
		} else {
			if (pos.y < 0)
				return false;
		}
	}

	float3 dir = pos - weaponMuzzlePos;
	float length = dir.Length();

	if (length == 0)
		return true;

	dir /= length;

	if (!onlyForward) {
		if (!HaveFreeLineOfFire(weaponMuzzlePos, dir, length, unit)) {
			return false;
		}
	}

	const float spread =
		(accuracy + sprayAngle) *
		(1.0f - owner->limExperience * weaponDef->ownerExpAccWeight);

	if (avoidFeature && TraceRay::LineFeatureCol(weaponMuzzlePos, dir, length)) {
		return false;
	}
	if (avoidFriendly && TraceRay::TestAllyCone(weaponMuzzlePos, dir, length, spread, owner->allyteam, owner)) {
		return false;
	}
	if (avoidNeutral && TraceRay::TestNeutralCone(weaponMuzzlePos, dir, length, spread, owner)) {
		return false;
	}

	return true;
}
Пример #3
0
bool CMissileLauncher::TryTarget(const float3& pos, bool userTarget, CUnit* unit)
{
	if (!CWeapon::TryTarget(pos, userTarget, unit))
		return false;

	if (!weaponDef->waterweapon) {
		if (unit) {
			if (unit->isUnderWater) {
				return false;
			}
		} else {
			if (pos.y < 0)
				return false;
		}
	}

	float3 dir = pos - weaponMuzzlePos;

	if (weaponDef->trajectoryHeight > 0) {
		// do a different test depending on if the missile has a high trajectory or not
		float3 flatdir(dir.x, 0, dir.z);
		dir.Normalize();
		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 gc = ((collisionFlags & Collision::NOGROUND) == 0)?
			ground->TrajectoryGroundCol(weaponMuzzlePos, flatdir, flatlength - 30, linear, quadratic):
			-1.0f;

		if (gc > 0.0f)
			return false;

		if (avoidFriendly && TraceRay::TestTrajectoryAllyCone(weaponMuzzlePos, flatdir, flatlength - 30, linear, quadratic, 0, 8, owner->allyteam, owner)) {
			return false;
		}
		if (avoidNeutral && TraceRay::TestTrajectoryNeutralCone(weaponMuzzlePos, flatdir, flatlength - 30, linear, quadratic, 0, 8, owner)) {
			return false;
		}
	} else {
		float length = dir.Length();
		if (length == 0)
			return true;

		dir /= length;

		if (!onlyForward) {
			if (!HaveFreeLineOfFire(weaponMuzzlePos, dir, length)) {
				return false;
			}
		} else {
			float3 goaldir = pos - owner->pos;
			goaldir.Normalize();
			if (owner->frontdir.dot(goaldir) < maxAngleDif)
				return false;
		}

		if (avoidFriendly && TraceRay::TestAllyCone(weaponMuzzlePos, dir, length, (accuracy + sprayAngle), owner->allyteam, owner)) {
			return false;
		}
		if (avoidNeutral && TraceRay::TestNeutralCone(weaponMuzzlePos, dir, length, (accuracy + sprayAngle), owner)) {
			return false;
		}
	}
	return true;
}