public bool InterceptTarget(DetectedUnit targetDet) { if (targetDet != null && !targetDet.IsMarkedForDeletion) { TargetDetectedUnit = targetDet; if(targetDet.RefersToUnit != null) { TargetUnitClassId = targetDet.RefersToUnit.UnitClass.Id; } MovementOrder = null; //var wp = new Waypoint(targetDet); //if (MovementOrder == null) //{ // MovementOrder = new MovementOrder(wp); //} //else //{ // MovementOrder.ClearAllWaypoints(); // //MovementOrder.AddWaypoint(wp); //} ReCalculateEta(); SetDirty(GameConstants.DirtyStatus.UnitChanged); GameManager.Instance.Log.LogDebug( string.Format("MissileUnit->InterceptTarget. Missile {0} set to intercept target {1}", ToShortString(), targetDet)); return true; } return false; }
public void AddUnit(DetectedUnit detectedUnit) { if (!DetectedUnits.Exists(u => u.Id == detectedUnit.Id)) { DetectedUnits.Add(detectedUnit); detectedUnit.DetectedGroupId = this.Id; SetDirty(GameConstants.DirtyStatus.UnitChanged); } }
public List <EngagementStatus> GetAllWeaponEngagementStatuses(string weaponClassId, DetectedUnit detectedUnit, bool primaryWeaponOnly) { var statuses = _units.Select(u => u.GetBestAvailableWeapon(weaponClassId, detectedUnit, primaryWeaponOnly)).Where(status => status != null).ToList(); var statusesSorted = from s in statuses orderby s.Score descending select s; return(statusesSorted.ToList()); }
public bool RemoveUnit(DetectedUnit detectedUnit) { bool result = DetectedUnits.Remove(detectedUnit); if (result) { detectedUnit.DetectedGroupId = string.Empty; SetDirty(GameConstants.DirtyStatus.UnitChanged); } return(result); }
public override bool AttemptDetectUnit(BaseUnit unit, double distanceM) { // CZ etc: http://www.fas.org/man/dod-101/navy/docs/es310/SNR_PROP/snr_prop.htm //calculate blind zone: if (!IsAbleToDetectUnit(unit, distanceM)) { return(false); } double bearingDegSensor = GetCurrentSensorBearingDeg(); double bearingDegToTarget = MapHelper.CalculateCombinedBearingDeg(bearingDegSensor, MapHelper.CalculateBearingDegrees(OwnerUnit.Position.Coordinate, unit.Position.Coordinate)); //needs to distinguish sensors: dipping, hull mounted, towed, etc: switch (this.SensorClass.SonarType) //accounting for baffle arcs ie blind zones { case GameConstants.SonarType.HullMountedBow: if (MapHelper.IsAngleWithinRangeDeg(bearingDegToTarget, 150, 210)) { return(false); } break; case GameConstants.SonarType.HullMountedKeel: if (MapHelper.IsAngleWithinRangeDeg(bearingDegToTarget, 135, 225)) { return(false); } break; case GameConstants.SonarType.HullMountedFlankArray: //assumes both starbord and port if (MapHelper.IsAngleWithinRangeDeg(bearingDegToTarget, 330, 30)) { return(false); } if (MapHelper.IsAngleWithinRangeDeg(bearingDegToTarget, 150, 210)) { return(false); } break; case GameConstants.SonarType.DippingOrSonobuoy: //no bafflezones if (OwnerUnit.ActualSpeedKph > 30) //these sonars do not operate if moving { return(false); } break; case GameConstants.SonarType.TowedArray: if (MapHelper.IsAngleWithinRangeDeg(bearingDegToTarget, 315, 45)) //MapHelper.IsAngleWithinRangeDeg(bearingDegToTarget, 135, 225)) { return(false); } if (OwnerUnit.ActualSpeedKph > GameConstants.DEFAULT_SLOW_SPEED) //do not operate above 15 kph { return(false); } break; default: break; } double noiseLevelTargetPercent = unit.GetCurrentNoiseLevelPercentage(); double noiseLevelPlatformPercent = OwnerUnit.GetCurrentNoiseLevelPercentage(); double detectionRangeM = 0; int currentSeaState = 0; var weather = unit.GetWeatherSystem(); if (weather != null) { currentSeaState = weather.SeaState; } double sensorDepthM = (double)OwnerUnit.Position.HeightOverSeaLevelM - unit.UnitClass.DraftM; double targetDepthM = (double)unit.Position.HeightOverSeaLevelM; if (this.SensorClass.IsVariableDepthSensor && this.IsDeployedIntermediateDepth && sensorDepthM < GameConstants.DEFAULT_DEPTH_THERMAL_LAYER_M) { sensorDepthM = GameConstants.DEFAULT_DEPTH_THERMAL_LAYER_M - 10; } TerrainLineSummary terrainLineSummary = GetTerrainHeightSummaryToTarget(unit); if (sensorDepthM < terrainLineSummary.MaxHeightM && targetDepthM < terrainLineSummary.MaxHeightM) { return(false); //higher terrain between objects - cannot detect } if (this.IsActive) { detectionRangeM = this.SensorClass.SonarActiveReferenceRangeM; if (OwnerUnit.Position.HeightOverSeaLevelM > GameConstants.DEPTH_SHALLOW_MIN_M || unit.Position.HeightOverSeaLevelM > GameConstants.DEPTH_SHALLOW_MIN_M) { if (currentSeaState > 8) { detectionRangeM *= 0.1; } else if (currentSeaState > 6) { detectionRangeM *= 0.25; } else if (currentSeaState > 4) { detectionRangeM *= 0.5; } } CurrentEffectiveActiveDetectionRangeM = detectionRangeM; if (terrainLineSummary.MaxHeightBehindM > targetDepthM) { detectionRangeM *= 0.5; } if (unit.UnitClass.IsSonarShielded) { detectionRangeM *= 0.5; } detectionRangeM = (detectionRangeM / noiseLevelPlatformPercent) * 100.0; //hmm double detectionStrength = detectionRangeM / distanceM; if (IsOnDifferentSidesOfThermalLayer(unit.Position)) //TODO: Calculate angle to layer and calculate detection based on it { detectionStrength *= 0.5; } if (detectionStrength > 1) { DetectedUnit detect = CreateOrUpdateDetectionReport(unit, detectionStrength, distanceM, 0, 0); //check! return(detect != null); } //unit.UnitClass.IsSonarShielded //remember, cannot identify } else //passive detection { detectionRangeM = this.SensorClass.SonarPassiveReferenceRangeM; if (unit.HasActiveSonar) { noiseLevelTargetPercent = 800; } detectionRangeM = (detectionRangeM / noiseLevelPlatformPercent) * 100.0; //hmm if (distanceM > detectionRangeM) { return(false); } if (sensorDepthM <= GameConstants.DEFAULT_DEPTH_THERMAL_LAYER_M && unit.Position.HeightOverSeaLevelM >= GameConstants.DEPTH_PERISCOPE_MIN_M) //sound channels { detectionRangeM *= 3.0; } if (OwnerUnit.Position.HeightOverSeaLevelM > GameConstants.DEPTH_SHALLOW_MIN_M || unit.Position.HeightOverSeaLevelM > GameConstants.DEPTH_SHALLOW_MIN_M) { if (currentSeaState > 8) { detectionRangeM *= 0.1; } else if (currentSeaState > 6) { detectionRangeM *= 0.25; } else if (currentSeaState > 4) { detectionRangeM *= 0.5; } else if (currentSeaState > 2) { detectionRangeM *= 0.8; } } if (terrainLineSummary.MaxHeightBehindM > targetDepthM) { detectionRangeM *= 0.5; } CurrentEffectivePassiveDetectionRangeM = detectionRangeM; detectionRangeM *= noiseLevelTargetPercent / 100.0; double detectionStrength = detectionRangeM / distanceM; if (IsOnDifferentSidesOfThermalLayer(unit.Position)) { detectionStrength *= 0.5; } if (detectionStrength > 1) { DetectedUnit detect = CreateOrUpdateDetectionReport(unit, detectionStrength, distanceM, 0, 0); //check! return(detect != null); } //can identify, but not fix } return(false); //return base.AttemptDetectUnit(unit, distanceM); }
//ESM detection calculator: http://www.y1pwe.co.uk/AppletCD/Prop2.htm public override bool AttemptDetectUnit(BaseUnit unit, double distanceM) { if (!IsAbleToDetectUnit(unit, distanceM)) { return(false); } if ((double)OwnerUnit.Position.HeightOverSeaLevelM < GameConstants.DEPTH_PERISCOPE_MIN_M || (double)unit.Position.HeightOverSeaLevelM < GameConstants.DEPTH_PERISCOPE_MIN_M) //under sea level { return(false); } //TODO: Take into account over-the horizon capabilities of some radars double sensorHeightOverSeaLevelM = (double)OwnerUnit.Position.HeightOverSeaLevelM + OwnerUnit.UnitClass.HeightM; double targetMaxHeightOverSeaLevelM = (double)unit.Position.HeightOverSeaLevelM + unit.UnitClass.HeightM; double LineOfSightM = MapHelper.CalculateMaxRadarLineOfSightM(sensorHeightOverSeaLevelM, targetMaxHeightOverSeaLevelM); TerrainLineSummary terrainLineSummary = null; if (IsActive) { if (distanceM <= LineOfSightM) { GameConstants.DirectionCardinalPoints direction = MapHelper.CalculateBearingDegrees(OwnerUnit.Position.Coordinate, unit.Position.Coordinate).ToCardinalMark(); double targetApparentSizeArcSec = unit.CalculateRadarCorrectedSizeArcSec(direction, distanceM); double minDetectableSizeArcSec = SensorClass.MinimumTargetSurfaceSizeArcSec; double degradationPercent = 0; if (targetMaxHeightOverSeaLevelM > 90) { minDetectableSizeArcSec = SensorClass.MinimumTargetAirSizeArcSec; } else { degradationPercent = GameManager.Instance.GetRadarDegradationFromSeaStatePercent( OwnerUnit.GetEffectiveSeaState()); } terrainLineSummary = GetTerrainHeightSummaryToTarget(unit); if (sensorHeightOverSeaLevelM < GameConstants.MAX_HEIGHT_TERRAIN_M) { if (sensorHeightOverSeaLevelM < terrainLineSummary.MaxHeightM && targetMaxHeightOverSeaLevelM < terrainLineSummary.MaxHeightM) { return(false); //no radar detection through terrain } if (targetMaxHeightOverSeaLevelM < terrainLineSummary.MaxHeightM * 1.2 && terrainLineSummary.HeightVarianceM > 0) { degradationPercent += 10; } } if (targetMaxHeightOverSeaLevelM < terrainLineSummary.MaxHeightBehindM) { degradationPercent += 75; } if (OwnerUnit.Position.HeightOverSeaLevelM < GameConstants.HEIGHT_MEDIUM_MIN_M || unit.Position.HeightOverSeaLevelM < GameConstants.HEIGHT_MEDIUM_MIN_M) //only if any below cloud cover { degradationPercent += GameManager.Instance.GetRadarDegradationFromWeatherPercent( unit.GetWeatherSystem()); } degradationPercent += OwnerUnit.GetDegradationFromJammingPercent(this.SensorClass.SensorType); if (unit.UnitClass.UnitType == GameConstants.UnitType.Missile && unit.Position.HeightOverSeaLevelM < 20) { degradationPercent += 40; //make sea skimming missiles much harder to detect } if (degradationPercent > 100) { degradationPercent = 100; } var degradationFactor = (1.0 - (degradationPercent / 100.0)); if (degradationFactor < 0.001) { degradationFactor = 0.001; } minDetectableSizeArcSec = minDetectableSizeArcSec * degradationFactor; if (targetApparentSizeArcSec >= minDetectableSizeArcSec) { double detectionStrength = targetApparentSizeArcSec / minDetectableSizeArcSec; //(SensorClass.MaxRangeM - DistanceM) / SensorClass.MaxRangeM; DetectedUnit detect = CreateOrUpdateDetectionReport(unit, detectionStrength, distanceM, targetApparentSizeArcSec, minDetectableSizeArcSec); if (detect != null) { return(true); } } } } //Even if active detection attempt has been made and failed, test for esm (passive) if (SensorClass.IsEsmDetector) { GameConstants.EsmRadiationLevel esmRad = unit.GetCurrentEsmRadiation(); if (esmRad == GameConstants.EsmRadiationLevel.EsmNone) { return(false); } else { LineOfSightM = (LineOfSightM * SensorClass.EsmDetectionOverHorizonPercent) / 100.0; if (esmRad == GameConstants.EsmRadiationLevel.EsmLow) { LineOfSightM *= 0.1; } else if (esmRad == GameConstants.EsmRadiationLevel.EsmMedium) { LineOfSightM *= 0.25; } if (sensorHeightOverSeaLevelM < GameConstants.MAX_HEIGHT_TERRAIN_M) { // Get terrain summary if not already gotten if (terrainLineSummary == null) { terrainLineSummary = GetTerrainHeightSummaryToTarget(unit); } if (sensorHeightOverSeaLevelM < terrainLineSummary.MaxHeightM && targetMaxHeightOverSeaLevelM < terrainLineSummary.MaxHeightM) { return(false); //no radar detection through terrain } if (targetMaxHeightOverSeaLevelM < terrainLineSummary.MaxHeightM * 1.2 && terrainLineSummary.HeightVarianceM > 0) { LineOfSightM *= 0.75; } } if (unit.UnitClass.UnitType == GameConstants.UnitType.Missile && unit.Position.HeightOverSeaLevelM < 20) //sea skimmers { LineOfSightM *= 0.25; } var degrJammingPercent = OwnerUnit.GetDegradationFromJammingPercent(this.SensorClass.SensorType); LineOfSightM *= (100.0 - degrJammingPercent); if (distanceM <= LineOfSightM) { DetectedUnit detect = CreateOrUpdateDetectionReport(unit, (LineOfSightM / distanceM), distanceM, 3600, 60); return(detect != null); } } } return(false); }
public virtual DetectedUnit CreateOrUpdateDetectionReport(BaseUnit unit, double detectionStrength, double distanceM, double targetApparentSizeArcSec, double minDetectableSizeArcSec) { DetectedUnit detect = OwnerPlayer.DetectedUnits.Find(d => d.RefersToUnit.Id == unit.Id); DetectedUnitSensor sensor; if (detect != null) //detected previously { detect.IsMarkedForDeletion = false; sensor = detect.AddOrUpdateSensor(unit, this, detectionStrength, distanceM, targetApparentSizeArcSec, minDetectableSizeArcSec); detect.DetectedGameWorldTimeSec = GameManager.Instance.Game.GameWorldTimeSec; if (!unit.Position.Equals(detect.Position)) { detect.SetDirty(GameConstants.DirtyStatus.PositionOnlyChanged); if (detect.IsFixed) { detect.Position = unit.Position.Clone(); //TODO: Add uncertainty if applicable } } if (unit.DirtySetting == GameConstants.DirtyStatus.UnitChanged) { detect.SetDirty(GameConstants.DirtyStatus.UnitChanged); } if (detectionStrength >= SensorClass.IdentifyDetectionStrength && !detect.IsFixed && !detect.IsIdentified) { detect.IsFixed = true; detect.IsIdentified = true; detect.SetDirty(GameConstants.DirtyStatus.UnitChanged); if (this.OwnerPlayer.IsEnemy(unit.OwnerPlayer)) { detect.FriendOrFoeClassification = GameConstants.FriendOrFoe.Foe; } else if (OwnerPlayer.IsAlly(unit.OwnerPlayer)) { detect.FriendOrFoeClassification = GameConstants.FriendOrFoe.Friend; } GameManager.Instance.Log.LogDebug("CreateOrUpdateDetectionReport: UPDATE: " + detect.ToLongString()); } if (detect.IsIdentified) { if (this.OwnerPlayer.IsEnemy(unit.OwnerPlayer)) { detect.FriendOrFoeClassification = GameConstants.FriendOrFoe.Foe; } else if (OwnerPlayer.IsAlly(unit.OwnerPlayer)) { detect.FriendOrFoeClassification = GameConstants.FriendOrFoe.Friend; } //detect.SetDirty(GameConstants.DirtyStatus.UnitChanged); } if (OwnerPlayer.AIHandler != null && detect.DirtySetting == GameConstants.DirtyStatus.UnitChanged) { OwnerPlayer.AIHandler.DetectionUpdated(detect); } return(detect); //otherwise unchanged } //NEW DETECTION: detect = new DetectedUnit(); detect.OwnerPlayer = this.OwnerPlayer; detect.ThreatClassification = GameConstants.ThreatClassification.U_Undecided; sensor = detect.AddOrUpdateSensor(unit, this, detectionStrength, distanceM, targetApparentSizeArcSec, minDetectableSizeArcSec); if (!unit.UnitClass.CanBeTargeted) { detect.CanBeTargeted = false; } if (detect.IsIdentified) { if (this.OwnerPlayer.IsEnemy(unit.OwnerPlayer)) { detect.FriendOrFoeClassification = GameConstants.FriendOrFoe.Foe; } else { if (this.OwnerPlayer.IsAlly(unit.OwnerPlayer)) { detect.FriendOrFoeClassification = GameConstants.FriendOrFoe.Friend; } } } if (detect.FriendOrFoeClassification == GameConstants.FriendOrFoe.Undetermined) { if (detect.RefersToUnit != null && detect.RefersToUnit.UnitClass.IsMissileOrTorpedo) //missiles assumed hostile { if (!this.OwnerPlayer.IsAlly(unit.OwnerPlayer)) { detect.FriendOrFoeClassification = GameConstants.FriendOrFoe.Foe; } } if (detect.FriendOrFoeClassification == GameConstants.FriendOrFoe.Undetermined && !detect.IsIdentified && OwnerPlayer.IsAllUnknownContactsHostile) { detect.FriendOrFoeClassification = GameConstants.FriendOrFoe.Foe; } } GameManager.Instance.Log.LogDebug(string.Format( "CreateOrUpdateDetectionReport NEW Player: {0}: Detection {1} ", OwnerPlayer.ToString(), detect.ToLongString())); if (!this.SensorClass.IsTargetingSensorOnly) { OwnerPlayer.DetectedUnits.Add(detect); } detect.SetDetectedGroup(); if (OwnerPlayer.AIHandler != null) { OwnerPlayer.AIHandler.NewDetection(detect); } return(detect); }
//public virtual void Sweep() //{ // if (!IsReady) // { // return; // } // if (OwnerUnit.CarriedByUnit != null) // { // return; // } // System.Diagnostics.Debug.Assert(OwnerPlayer != null, "BaseSensor.Sweep: Sensor OwnerPlayer should never be null."); // System.Diagnostics.Debug.Assert(OwnerUnit != null, "BaseSensor.Sweep: Sensor OwnerUnit should never be null."); // System.Diagnostics.Debug.Assert(SensorClass != null, "BaseSensor.Sweep: Sensor SensorClass should never be null."); //} public virtual bool AttemptDetectUnit(BaseUnit unit, double distanceM) { //TODO: Hit test on detection if (!IsAbleToDetectUnit(unit, distanceM)) { return(false); } if (SensorClass.MaxHeightDeployedM > 0 && OwnerUnit.ActualHeightOverSeaLevelM > SensorClass.MaxHeightDeployedM) { ReadyInSec = 120; return(false); } if (SensorClass.MaxSpeedDeployedKph > 0 && OwnerUnit.ActualSpeedKph > SensorClass.MaxSpeedDeployedKph) { ReadyInSec = 120; return(false); } //if (!OwnerPlayer.IsComputerPlayer) //{ // GameManager.Instance.Log.LogDebug(string.Format( // "PLAYER {0}, UNIT {1}, SENSOR {2} attemtping to detect unit {3}.", // OwnerPlayer.ToString(), OwnerUnit.ToString(), this.ToString(), unit.ToString())); //} GameConstants.DirectionCardinalPoints DirectionToTarget = MapHelper.CalculateBearingDegrees(OwnerUnit.Position.Coordinate, unit.Position.Coordinate).ToCardinalMark(); TerrainLineSummary terrainLineSummary = GetTerrainHeightSummaryToTarget(unit); //No sensor can see through terrain if (terrainLineSummary.MaxHeightM > OwnerUnit.Position.HeightOverSeaLevelM && terrainLineSummary.MaxHeightM > unit.Position.HeightOverSeaLevelM) { return(false); } double targetApparentSizeArcSec = unit.CalculateRadarCorrectedSizeArcSec(DirectionToTarget, distanceM); if (SensorClass.SensorType == GameConstants.SensorType.Visual) { if ((double)OwnerUnit.Position.HeightOverSeaLevelM < GameConstants.DEPTH_PERISCOPE_MIN_M || (double)unit.Position.HeightOverSeaLevelM < GameConstants.DEPTH_SHALLOW_MIN_M) //under sea level { return(false); } double lineOfSightM = MapHelper.CalculateMaxLineOfSightM( (double)OwnerUnit.Position.HeightOverSeaLevelM + OwnerUnit.UnitClass.HeightM, (double)unit.Position.HeightOverSeaLevelM + unit.UnitClass.HeightM); double minimumTargetSizeArcSec = SensorClass.MinimumTargetSurfaceSizeArcSec; if (unit.Position.HeightOverSeaLevelM > 10) { minimumTargetSizeArcSec = SensorClass.MinimumTargetAirSizeArcSec; } if (distanceM <= lineOfSightM && targetApparentSizeArcSec >= minimumTargetSizeArcSec) { double degradationPercent = 0; WeatherSystem wsystem = OwnerUnit.GetWeatherSystem(); if (wsystem != null && SensorClass.SensorType == GameConstants.SensorType.Visual) { degradationPercent = 100 - wsystem.TotalLightPercent; } if (OwnerUnit.Position.HeightOverSeaLevelM < GameConstants.HEIGHT_MEDIUM_MIN_M || unit.Position.HeightOverSeaLevelM < GameConstants.HEIGHT_MEDIUM_MIN_M) //only if any below cloud cover { degradationPercent += GameManager.Instance.GetRadarDegradationFromWeatherPercent(wsystem); } //double MinDetectableSizeArcSec = SensorClass.MinimumTargetSurfaceSizeArcSec; minimumTargetSizeArcSec = minimumTargetSizeArcSec * (1.0 + (degradationPercent / 100)); double DetectionStrength = targetApparentSizeArcSec / minimumTargetSizeArcSec; //(LineOfSightM - DistanceM) / LineOfSightM; DetectedUnit detect = CreateOrUpdateDetectionReport(unit, DetectionStrength, distanceM, targetApparentSizeArcSec, minimumTargetSizeArcSec); return(detect != null); } else { return(false); //does not detect it } } else if (SensorClass.SensorType == GameConstants.SensorType.Infrared) { if ((double)OwnerUnit.Position.HeightOverSeaLevelM < GameConstants.DEPTH_PERISCOPE_MIN_M || (double)unit.Position.HeightOverSeaLevelM < GameConstants.DEPTH_SHALLOW_MIN_M) //under sea level { return(false); } double irDegradationPercent = 0; WeatherSystem weatherSystem = OwnerUnit.GetWeatherSystem(); if (OwnerUnit.Position.HeightOverSeaLevelM < GameConstants.HEIGHT_MEDIUM_MIN_M || unit.Position.HeightOverSeaLevelM < GameConstants.HEIGHT_MEDIUM_MIN_M) //only if any below cloud cover { irDegradationPercent += GameManager.Instance.GetIRDegradationFromWeatherPercent(weatherSystem); } double maxTargetDetectionDistanceM = unit.GetMaxIrDetectionDistanceM(); double LineOfSightM = MapHelper.CalculateMaxLineOfSightM( (double)OwnerUnit.Position.HeightOverSeaLevelM + OwnerUnit.UnitClass.HeightM, (double)unit.Position.HeightOverSeaLevelM) + unit.UnitClass.HeightM; if (maxTargetDetectionDistanceM > LineOfSightM) { maxTargetDetectionDistanceM = LineOfSightM; } double detectionStrength = distanceM / maxTargetDetectionDistanceM; if (detectionStrength > 1.0) { DetectedUnit detect = CreateOrUpdateDetectionReport(unit, detectionStrength, distanceM, 0, 0); return(detect != null); } else { return(false); } } else if (SensorClass.SensorType == GameConstants.SensorType.MAD) { if (unit.Position == null || !unit.Position.HasHeightOverSeaLevel || unit.Position.HeightOverSeaLevelM >= GameConstants.DEPTH_SHALLOW_MIN_M) { return(false); } var unitDepthM = (double)unit.Position.HeightOverSeaLevelM; if (OwnerUnit.Position == null || !OwnerUnit.Position.HasHeightOverSeaLevel || OwnerUnit.Position.HeightOverSeaLevelM >= GameConstants.HEIGHT_MEDIUM_MIN_M) { return(false); } if (unitDepthM <= GameConstants.DEPTH_DEEP_MIN_M) { return(false); } double maxDetectionDistanceM = 1000.0; if (unitDepthM <= GameConstants.DEPTH_MEDIUM_MIN_M) { maxDetectionDistanceM = 500; } double detectionStrength = distanceM / maxDetectionDistanceM; if (detectionStrength > 1.0) { DetectedUnit detect = CreateOrUpdateDetectionReport(unit, detectionStrength, distanceM, 0, 0); return(detect != null); } else { return(false); } } return(false); }