/// <summary> /// Given a weapon (countermeasures type), determines if this weapon can work on this missile. Returns bool. /// Takes into account remaining ammunition on soft kill weapon, but does not deduct from it. If MaxAmmunition==0, /// this is interpreted as unlimited ammo. /// </summary> /// <param name="wpn"></param> /// <returns></returns> public bool CanBeSoftKilled(BaseWeapon wpn) { if (wpn.MaxAmmunition > 0 && wpn.AmmunitionRemaining < 1) { return false; //soft kill is out of ammo } try { switch (wpn.WeaponClass.EwCounterMeasures) { case GameConstants.EwCounterMeasuresType.None: return false; case GameConstants.EwCounterMeasuresType.Flare: return Sensors.Any(s => s.SensorClass.SensorType == GameConstants.SensorType.Infrared); case GameConstants.EwCounterMeasuresType.Chaff: //Missiles without any sensors is considered semiactive radar seeking (uses radar transmitter from launch platform) if (UnitClass.UnitType == GameConstants.UnitType.Missile) { return Sensors.Any(s => s.SensorClass.SensorType == GameConstants.SensorType.Radar) || !Sensors.Any(s => s.SensorClass.SensorType != GameConstants.SensorType.Radar); } return false; case GameConstants.EwCounterMeasuresType.TorpedoDecoy: return UnitClass.UnitType == GameConstants.UnitType.Torpedo; default: return false; } } catch (Exception ex) { GameManager.Instance.Log.LogError("MissileUnit->CanBeSoftKilled error " + ex.Message); return false; } }
public void UpdateParents() { if (Units != null && Units.Any()) { Units.ForEach(u => { u.Parent = this; u.UpdateParents(); }); } if (Sensors != null && Sensors.Any()) { Sensors.ForEach(s => s.Parent = this); } if (Commands != null && Commands.Any()) { Commands.ForEach(c => c.Parent = this); } }
public void SearchForTarget(string targetId, string classId, bool doSensorSweep) { if (IsMarkedForDeletion) { return; } //first, see if targetdetectedunit is still known var targetDet = OwnerPlayer.GetDetectedUnitById(targetId); if (targetDet != null) { InterceptTarget(targetDet); return; } GameManager.Instance.Log.LogDebug( string.Format("MissileUnit->SearchForTarget Missile {0} looks for detid={1} or classid={2}", this.ToShortString(), targetId, classId)); if (doSensorSweep && Sensors.Any()) { if (UnitClass.UnitType == GameConstants.UnitType.Missile) { SetSensorsActivePassive(GameConstants.SensorType.Radar, true); } else if (UnitClass.UnitType == GameConstants.UnitType.Torpedo) { SetSensorsActivePassive(GameConstants.SensorType.Sonar, true); } this.SensorSweep(); } //otherwise, see if target with same unitclass can be found. UnitClass in var unitClassTarget = GameManager.Instance.GetUnitClassById(classId); // Get ordered list by distance of detected units within our fuel distance IEnumerable<DetectedUnit> detectedUnitsOrdered; // Filter out targets outside the max search sector range if (MaxSectorRangeSearchDeg < 360) { var bearing = ActualBearingDeg.HasValue ? ActualBearingDeg.Value : 0.0; var maxDistanceM = FuelDistanceRemainingM; if (TargetPosition != null) { bearing = MapHelper.CalculateBearingDegrees(Position.Coordinate, TargetPosition.Coordinate); maxDistanceM = MapHelper.CalculateDistanceRoughM(Position.Coordinate, TargetPosition.Coordinate); } detectedUnitsOrdered = from d in OwnerPlayer.DetectedUnits where !d.IsMarkedForDeletion && d.Position != null && d.CanBeTargeted && MapHelper.IsWithinSector(Position.Coordinate, bearing, MaxSectorRangeSearchDeg, d.Position.Coordinate) let distanceToTargetM = MapHelper.CalculateDistance3DM(d.Position, this.Position) where distanceToTargetM <= maxDistanceM orderby distanceToTargetM ascending select d; } else { detectedUnitsOrdered = from d in OwnerPlayer.DetectedUnits where !d.IsMarkedForDeletion && d.Position != null && d.CanBeTargeted let distanceToTargetM = MapHelper.CalculateDistance3DM(d.Position, this.Position) where distanceToTargetM <= FuelDistanceRemainingM orderby distanceToTargetM ascending select d; } //var weaponClass = GameManager.Instance.GetWeaponClassById(this.WeaponClassId); foreach (var det in detectedUnitsOrdered) { if (unitClassTarget != null) { if (det.IsIdentified && det.RefersToUnit != null) { if (det.RefersToUnit.UnitClass.Id == unitClassTarget.Id) { InterceptTarget(det); return; } } else { if (LaunchWeapon != null && det.RefersToUnit != null && LaunchWeapon.CanTargetDetectedUnit(det.RefersToUnit, true)) { InterceptTarget(det); return; } } } else if (this.LaunchWeapon != null && this.LaunchWeapon.CanTargetDetectedUnit(det, true)) { InterceptTarget(det); return; } } if (TargetDetectedUnit == null || TargetDetectedUnit.IsMarkedForDeletion) { if (MovementOrder != null && MovementOrder.CountWaypoints == 1) { var wp = MovementOrder.PeekNextWaypoint(); if (MapHelper.CalculateDistance3DM(Position, wp.Position) < GameConstants.DISTANCE_TO_TARGET_IS_HIT_M) { GameManager.Instance.Log.LogDebug(string.Format("SearchForTarget: Missile {0} waypoint was close: deleted.", this)); MovementOrder = null; //this.ActiveWaypoint = null; } } } if ((TargetDetectedUnit == null || TargetDetectedUnit.IsMarkedForDeletion) && (MovementOrder == null || MovementOrder.CountWaypoints == 0 || GetActiveWaypoint() == null)) //can't find anything. self-destruct { GameManager.Instance.Log.LogDebug( string.Format("MissileUnit->SearchForTarget Missile {0} found no target and is being deleted.", this.ToShortString())); this.IsMarkedForDeletion = true; } }
public void Impact() { if (Position == null) { IsMarkedForDeletion = true; return; } if (IsMarkedForDeletion) { return; } GameManager.Instance.Log.LogDebug("MissileUnit->Impact called for unit " + Id); if (TargetDetectedUnit != null && TargetDetectedUnit.RefersToUnit != null && TargetDetectedUnit.Position != null) { if (TargetDetectedUnit.RefersToUnit.IsMarkedForDeletion) { this.IsMarkedForDeletion = true; return; } //double distanceM = MapHelper.CalculateDistance3DM(this.Position, TargetDetectedUnit.Position); double distanceM = MapHelper.CalculateDistanceM(this.Position.Coordinate, TargetDetectedUnit.Position.Coordinate); if (distanceM > GameConstants.DISTANCE_TO_TARGET_IS_HIT_M) { if (!InterceptTarget(TargetDetectedUnit)) //try again IsMarkedForDeletion = true; } else { BaseUnit unit = TargetDetectedUnit.RefersToUnit; unit.InflictDamageFromProjectileHit(this); IsMarkedForDeletion = true; } } else { if (TargetPosition != null) { var distanceM = MapHelper.CalculateDistanceM(this.Position.Coordinate, TargetPosition.Coordinate); if (distanceM <= GameConstants.DISTANCE_TO_TARGET_IS_HIT_M) { IsMarkedForDeletion = true; return; } } if (Sensors.Any()) { TargetDetectedUnit = null; SearchForTarget(); if (TargetDetectedUnit == null && TargetPosition == null && (MovementOrder == null || MovementOrder.GetActiveWaypoint() == null)) { IsMarkedForDeletion=true; } } else { IsMarkedForDeletion = true; } } }