private static float GetVisualRange(float visionRange, AbstractActor source) { float visualRange; if (source.IsShutDown) { visualRange = visionRange * source.Combat.Constants.Visibility.ShutdownSpottingDistanceMultiplier; } else if (source.IsProne) { visualRange = visionRange * source.Combat.Constants.Visibility.ProneSpottingDistanceMultiplier; } else { float multipliers = VisualLockHelper.GetAllSpotterMultipliers(source); float absolutes = VisualLockHelper.GetAllSpotterAbsolutes(source); visualRange = visionRange * multipliers + absolutes; //Mod.Log.Trace?.Write($" -- source:{CombatantUtils.Label(source)} has spotting " + // $"multi:x{multipliers} absolutes:{absolutes} visionRange:{visionRange}"); } if (visualRange < Mod.Config.Vision.MinimumVisionRange()) { visualRange = Mod.Config.Vision.MinimumVisionRange(); } // Round up to the nearest full hex float normalizedRange = HexUtils.CountHexes(visualRange, false) * 30f; //LowVisibility.Logger.Trace($" -- source:{CombatantUtils.Label(source)} visual range is:{normalizedRange}m normalized from:{visualRange}m"); return(normalizedRange); }
// WARNING: DUPLICATE OF HBS CODE. THIS IS LIKELY TO BREAK IF HBS CHANGES THE SOURCE FUNCTIONS public static float GetAdjustedSpotterRange(AbstractActor source, ICombatant target) { float targetVisibility = 1f; AbstractActor targetActor = target as AbstractActor; if (targetActor != null) { EWState sourceState = source.GetEWState(); targetVisibility = VisualLockHelper.GetTargetVisibility(targetActor, sourceState); } float spotterRange = VisualLockHelper.GetSpotterRange(source); float modifiedRange = spotterRange * targetVisibility; if (modifiedRange < Mod.Config.Vision.MinimumVisionRange()) { modifiedRange = Mod.Config.Vision.MinimumVisionRange(); } // Round up to the nearest full hex float normalizedRange = HexUtils.CountHexes(modifiedRange, true) * 30f; Mod.Log.Trace?.Write($" -- source:{CombatantUtils.Label(source)} adjusted spotterRange:{normalizedRange}m normalized from:{modifiedRange}m"); return(normalizedRange); }
// Determines if a source has visual lock to a target from a given position. Because units have differnet positions, check all of them. // Typically from head-to-head for mechs, but buildings have multiple positions. public static bool CanSpotTarget(AbstractActor source, Vector3 sourcePos, ICombatant target, Vector3 targetPos, Quaternion targetRot, LineOfSight los) { float spottingRangeVsTarget = VisualLockHelper.GetAdjustedSpotterRange(source, target); float distance = Vector3.Distance(sourcePos, targetPos); //Mod.Log.Info?.Write($" COMPARING SPOTTING_RANGE: {spottingRangeVsTarget} VS DISTANCE: {distance}"); // Check range first if (distance > spottingRangeVsTarget) { return(false); } // I think this is what prevents you from seeing things from behind you - the rotation is set to 0? Vector3 forward = targetPos - sourcePos; forward.y = 0f; Quaternion rotation = Quaternion.LookRotation(forward); if (distance <= spottingRangeVsTarget) { Vector3[] lossourcePositions = source.GetLOSSourcePositions(sourcePos, rotation); Vector3[] lostargetPositions = target.GetLOSTargetPositions(targetPos, targetRot); for (int i = 0; i < lossourcePositions.Length; i++) { for (int j = 0; j < lostargetPositions.Length; j++) { if (los.HasLineOfSight(lossourcePositions[i], lostargetPositions[j], spottingRangeVsTarget, target.GUID)) { return(true); } } } } return(false); }