예제 #1
0
        /// <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;

            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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;
                }
            }
        }