internal void Init(ref DetectInfo detectInfo, MyCubeGrid myGrid, GridAi myAi, GridAi targetAi) { EntInfo = detectInfo.EntInfo; Target = detectInfo.Parent; PartCount = detectInfo.PartCount; FatCount = detectInfo.FatCount; IsStatic = Target.Physics.IsStatic; IsGrid = detectInfo.IsGrid; LargeGrid = detectInfo.LargeGrid; MyGrid = myGrid; MyAi = myAi; TargetAi = targetAi; Velocity = Target.Physics.LinearVelocity; VelLenSqr = Velocity.LengthSquared(); var targetSphere = Target.PositionComp.WorldVolume; TargetPos = targetSphere.Center; TargetRadius = targetSphere.Radius; var myCenter = myAi.GridVolume.Center; if (!MyUtils.IsZero(Velocity, 1E-02F)) { var targetMag = myCenter - TargetPos; Approaching = MathFuncs.IsDotProductWithinTolerance(ref Velocity, ref targetMag, myAi.Session.ApproachDegrees); } else { Approaching = false; TargetHeading = Vector3D.Zero; } if (targetAi != null) { OffenseRating = targetAi.Construct.OptimalDps / myAi.Construct.OptimalDps; if (OffenseRating <= 0 && detectInfo.Armed) { OffenseRating = 0.0001f; } } else if (detectInfo.Armed) { OffenseRating = 0.0001f; } else { OffenseRating = 0; } var myRadius = myAi.MyGrid.PositionComp.LocalVolume.Radius; var sphereDistance = MyUtils.GetSmallestDistanceToSphere(ref myCenter, ref targetSphere); if (sphereDistance <= myRadius) { sphereDistance = 0; } else { sphereDistance -= myRadius; } DistSqr = sphereDistance * sphereDistance; }
public Results GetValue(string name) { Timings times; if (_timings.TryGetValue(name, out times) && times.Values.Count > 0) { var itemCnt = times.Values.Count; var tmpCnt = times.TmpArray.Length; if (itemCnt != tmpCnt) { Array.Resize(ref times.TmpArray, itemCnt); } for (int i = 0; i < itemCnt; i++) { times.TmpArray[i] = times.Values[i]; } times.Values.Clear(); var median = MathFuncs.GetMedian(times.TmpArray); return(new Results { Median = median / 1000000.0, Min = times.Min, Max = times.Max, MaxTick = times.MaxTick }); } return(new Results()); }
internal void Init(ref DetectInfo detectInfo, MyCubeGrid myGrid, GridAi myAi, GridAi targetAi) { EntInfo = detectInfo.EntInfo; Target = detectInfo.Parent; PartCount = detectInfo.PartCount; FatCount = detectInfo.FatCount; IsGrid = detectInfo.IsGrid; LargeGrid = detectInfo.LargeGrid; MyGrid = myGrid; MyAi = myAi; TargetAi = targetAi; Velocity = Target.Physics.LinearVelocity; VelLenSqr = Velocity.LengthSquared(); var targetSphere = Target.PositionComp.WorldVolume; TargetPos = targetSphere.Center; TargetRadius = targetSphere.Radius; if (!MyUtils.IsZero(Velocity, 1E-02F)) { TargetDir = Vector3D.Normalize(Velocity); var refDir = Vector3D.Normalize(myAi.GridVolume.Center - TargetPos); Approaching = MathFuncs.IsDotProductWithinTolerance(ref TargetDir, ref refDir, myAi.Session.ApproachDegrees); } else { TargetDir = Vector3D.Zero; Approaching = false; } if (targetAi != null) { OffenseRating = targetAi.Construct.OptimalDps / myAi.Construct.OptimalDps; } else if (detectInfo.Armed) { OffenseRating = 0.0001f; } else { OffenseRating = 0; } var targetDist = Vector3D.Distance(myAi.GridVolume.Center, TargetPos) - TargetRadius; targetDist -= myAi.GridVolume.Radius; if (targetDist < 0) { targetDist = 0; } DistSqr = targetDist * targetDist; }
public static double GetIntersectingSurfaceArea(MatrixD matrix, Vector3D hitPosLocal) { var surfaceArea = -1d; var boxMax = matrix.Backward + matrix.Right + matrix.Up; var boxMin = -boxMax; var box = new BoundingBoxD(boxMin, boxMax); var maxWidth = box.Max.LengthSquared(); var testLine = new LineD(Vector3D.Zero, Vector3D.Normalize(hitPosLocal) * maxWidth); LineD testIntersection; box.Intersect(ref testLine, out testIntersection); var intersection = testIntersection.To; var epsilon = 1e-6; var projFront = MathFuncs.VectorProjection(intersection, matrix.Forward); if (Math.Abs(projFront.LengthSquared() - matrix.Forward.LengthSquared()) < epsilon) { var a = Vector3D.Distance(matrix.Left, matrix.Right); var b = Vector3D.Distance(matrix.Up, matrix.Down); surfaceArea = a * b; } var projLeft = MathFuncs.VectorProjection(intersection, matrix.Left); if (Math.Abs(projLeft.LengthSquared() - matrix.Left.LengthSquared()) < epsilon) { var a = Vector3D.Distance(matrix.Forward, matrix.Backward); var b = Vector3D.Distance(matrix.Up, matrix.Down); surfaceArea = a * b; } var projUp = MathFuncs.VectorProjection(intersection, matrix.Up); if (Math.Abs(projUp.LengthSquared() - matrix.Up.LengthSquared()) < epsilon) { var a = Vector3D.Distance(matrix.Forward, matrix.Backward); var b = Vector3D.Distance(matrix.Left, matrix.Right); surfaceArea = a * b; } return(surfaceArea); }
private static void AcquireOther(Weapon w, out TargetType targetType, bool attemptReset = false, MyEntity targetGrid = null) { var comp = w.Comp; var overRides = comp.Data.Repo.Base.Set.Overrides; var attackNeutrals = overRides.Neutrals; var attackFriends = overRides.Friendly; var attackNoOwner = overRides.Unowned; var forceFoci = overRides.FocusTargets; var session = w.Comp.Session; var ai = comp.Ai; session.TargetRequests++; var physics = session.Physics; var weaponPos = w.MyPivotPos; var target = w.NewTarget; var s = w.System; var accelPrediction = (int)s.Values.HardPoint.AimLeadingPrediction > 1; var minRadius = overRides.MinSize * 0.5f; var maxRadius = overRides.MaxSize * 0.5f; var minTargetRadius = minRadius > 0 ? minRadius : s.MinTargetRadius; var maxTargetRadius = maxRadius < s.MaxTargetRadius ? maxRadius : s.MaxTargetRadius; var moveMode = overRides.MoveMode; var movingMode = moveMode == GroupOverrides.MoveModes.Moving; var fireOnStation = moveMode == GroupOverrides.MoveModes.Any || moveMode == GroupOverrides.MoveModes.Moored; var stationOnly = moveMode == GroupOverrides.MoveModes.Moored; Water water = null; BoundingSphereD waterSphere = new BoundingSphereD(Vector3D.Zero, 1f); if (session.WaterApiLoaded && !w.ActiveAmmoDef.AmmoDef.IgnoreWater && ai.InPlanetGravity && ai.MyPlanet != null && session.WaterMap.TryGetValue(ai.MyPlanet, out water)) { waterSphere = new BoundingSphereD(ai.MyPlanet.PositionComp.WorldAABB.Center, water.radius); } TargetInfo alphaInfo = null; TargetInfo betaInfo = null; int offset = 0; MyEntity fTarget; if (ai.Construct.Data.Repo.FocusData.Target[0] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[0], out fTarget) && ai.Targets.TryGetValue(fTarget, out alphaInfo)) { offset++; } if (ai.Construct.Data.Repo.FocusData.Target[1] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[1], out fTarget) && ai.Targets.TryGetValue(fTarget, out betaInfo)) { offset++; } TargetInfo gridInfo = null; var forceTarget = false; if (targetGrid != null) { if (ai.Targets.TryGetValue(targetGrid, out gridInfo)) { forceTarget = true; } } var hasOffset = offset > 0; var numOfTargets = ai.SortedTargets.Count; var adjTargetCount = forceFoci && hasOffset ? offset : numOfTargets + offset; var deck = GetDeck(ref target.TargetDeck, ref target.TargetPrevDeckLen, 0, numOfTargets, w.System.Values.Targeting.TopTargets, w.TargetData.WeaponRandom, Acquire); try { for (int x = 0; x < adjTargetCount; x++) { var focusTarget = hasOffset && x < offset; var lastOffset = offset - 1; if (attemptReset && !focusTarget) { break; } TargetInfo info = null; if (forceTarget && !focusTarget) { info = gridInfo; } else { if (focusTarget) { if (x == 0 && alphaInfo != null) { info = alphaInfo; } else if (x == 0 && betaInfo != null) { info = betaInfo; } else if (x == 1) { info = betaInfo; } if (!attackFriends && info.EntInfo.Relationship == MyRelationsBetweenPlayerAndBlock.Friends) { continue; } } else { info = ai.SortedTargets[deck[x - offset]]; } } if (info?.Target == null || info.Target.MarkedForClose || hasOffset && x > lastOffset && (info.Target == alphaInfo?.Target || info.Target == betaInfo?.Target) || !attackNeutrals && info.EntInfo.Relationship == MyRelationsBetweenPlayerAndBlock.Neutral || !attackNoOwner && info.EntInfo.Relationship == MyRelationsBetweenPlayerAndBlock.NoOwnership) { continue; } if (movingMode && info.VelLenSqr < 1 || !fireOnStation && info.IsStatic || stationOnly && !info.IsStatic) { continue; } var character = info.Target as IMyCharacter; var targetRadius = character != null ? info.TargetRadius * 5 : info.TargetRadius; if (targetRadius < minTargetRadius || info.TargetRadius > maxTargetRadius && maxTargetRadius < 8192 || !focusTarget && info.OffenseRating <= 0) { continue; } var targetCenter = info.Target.PositionComp.WorldAABB.Center; var targetDistSqr = Vector3D.DistanceSquared(targetCenter, w.MyPivotPos); if (targetDistSqr > (w.MaxTargetDistance + info.TargetRadius) * (w.MaxTargetDistance + info.TargetRadius) || targetDistSqr < w.MinTargetDistanceSqr) { continue; } if (water != null) { if (new BoundingSphereD(ai.MyPlanet.PositionComp.WorldAABB.Center, water.radius).Contains(new BoundingSphereD(targetCenter, targetRadius)) == ContainmentType.Contains) { continue; } } session.TargetChecks++; Vector3D targetLinVel = info.Target.Physics?.LinearVelocity ?? Vector3D.Zero; Vector3D targetAccel = accelPrediction ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero; if (info.IsGrid) { if (!s.TrackGrids || !focusTarget && info.FatCount < 2) { continue; } session.CanShoot++; Vector3D newCenter; if (!w.AiEnabled) { var validEstimate = true; newCenter = w.System.Prediction != HardPointDef.Prediction.Off && (!w.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && w.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0) ? Weapon.TrajectoryEstimation(w, targetCenter, targetLinVel, targetAccel, out validEstimate) : targetCenter; var targetSphere = info.Target.PositionComp.WorldVolume; targetSphere.Center = newCenter; if (!validEstimate || !MathFuncs.TargetSphereInCone(ref targetSphere, ref w.AimCone)) { continue; } } else if (!Weapon.CanShootTargetObb(w, info.Target, targetLinVel, targetAccel, out newCenter)) { continue; } if (w.Comp.Ai.FriendlyShieldNear) { var targetDir = newCenter - weaponPos; if (w.HitFriendlyShield(newCenter, targetDir)) { continue; } } if (!AcquireBlock(s, w.Comp.Ai, target, info, weaponPos, w.TargetData.WeaponRandom, Acquire, ref waterSphere, w, !focusTarget)) { continue; } targetType = TargetType.Other; target.TransferTo(w.Target, w.Comp.Session.Tick); return; } var meteor = info.Target as MyMeteor; if (meteor != null && !s.TrackMeteors || !overRides.Meteors) { continue; } if (character != null && (!s.TrackCharacters || !overRides.Biologicals || character.IsDead || character.Integrity <= 0 || session.AdminMap.ContainsKey(character))) { continue; } Vector3D predictedPos; if (!Weapon.CanShootTarget(w, ref targetCenter, targetLinVel, targetAccel, out predictedPos)) { continue; } if (w.Comp.Ai.FriendlyShieldNear) { var targetDir = predictedPos - weaponPos; if (w.HitFriendlyShield(predictedPos, targetDir)) { continue; } } session.TopRayCasts++; var targetPos = info.Target.PositionComp.WorldAABB.Center; IHitInfo hitInfo; physics.CastRay(weaponPos, targetPos, out hitInfo, CollisionLayers.DefaultCollisionLayer); if (hitInfo != null && hitInfo.HitEntity == info.Target && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf())) { double rayDist; Vector3D.Distance(ref weaponPos, ref targetPos, out rayDist); var shortDist = rayDist * (1 - hitInfo.Fraction); var origDist = rayDist * hitInfo.Fraction; var topEntId = info.Target.GetTopMostParent().EntityId; target.Set(info.Target, hitInfo.Position, shortDist, origDist, topEntId); targetType = TargetType.Other; target.TransferTo(w.Target, w.Comp.Session.Tick); return; } if (forceTarget) { break; } } if (!attemptReset || !w.Target.HasTarget) { targetType = TargetType.None; } else { targetType = w.Target.IsProjectile ? TargetType.Projectile : TargetType.Other; } } catch (Exception ex) { Log.Line($"Exception in AcquireOther: {ex}"); targetType = TargetType.None; } }
private static void AcquireOther(Weapon w, out TargetType targetType, bool attemptReset = false, MyEntity targetGrid = null) { var comp = w.Comp; var overRides = comp.Set.Value.Overrides; var overActive = overRides.Activate; var attackNeutrals = overActive && overRides.Neutrals; var attackFriends = overActive && overRides.Friendly; var attackNoOwner = overActive && overRides.Unowned; var forceFoci = overActive && overRides.FocusTargets; var session = w.Comp.Session; var ai = comp.Ai; session.TargetRequests++; var physics = session.Physics; var weaponPos = w.MyPivotPos; var weaponRange = w.MaxTargetDistance; var target = w.NewTarget; var s = w.System; var accelPrediction = (int)s.Values.HardPoint.AimLeadingPrediction > 1; TargetInfo alphaInfo = null; TargetInfo betaInfo = null; int offset = 0; if (ai.Focus.Target[0] != null) { if (ai.Targets.TryGetValue(ai.Focus.Target[0], out alphaInfo)) { offset++; } } if (ai.Focus.Target[1] != null) { if (ai.Targets.TryGetValue(ai.Focus.Target[1], out betaInfo)) { offset++; } } TargetInfo gridInfo = null; var forceTarget = false; if (targetGrid != null) { if (ai.Targets.TryGetValue(targetGrid, out gridInfo)) { forceTarget = true; } } var hasOffset = offset > 0; var numOfTargets = ai.SortedTargets.Count; var adjTargetCount = forceFoci && hasOffset ? offset : numOfTargets + offset; var deck = GetDeck(ref target.TargetDeck, ref target.TargetPrevDeckLen, 0, numOfTargets, w.System.Values.Targeting.TopTargets, w.Comp.Seed); try { for (int x = 0; x < adjTargetCount; x++) { var focusTarget = hasOffset && x < offset; var lastOffset = offset - 1; if (attemptReset && !focusTarget) { break; } TargetInfo info = null; if (forceTarget && !focusTarget) { info = gridInfo; } else { if (focusTarget) { if (x == 0 && alphaInfo != null) { info = alphaInfo; } else if (x == 0 && betaInfo != null) { info = betaInfo; } else if (x == 1) { info = betaInfo; } if (!attackFriends && info.EntInfo.Relationship == MyRelationsBetweenPlayerAndBlock.Friends) { continue; } } else { info = ai.SortedTargets[deck[x - offset]]; } } if (info?.Target == null || info.Target.MarkedForClose || hasOffset && x > lastOffset && (info.Target == alphaInfo?.Target || info.Target == betaInfo?.Target) || !attackNeutrals && info.EntInfo.Relationship == MyRelationsBetweenPlayerAndBlock.Neutral || !attackNoOwner && info.EntInfo.Relationship == MyRelationsBetweenPlayerAndBlock.NoOwnership) { continue; } if (info.TargetRadius < s.MinTargetRadius || info.TargetRadius > s.MaxTargetRadius || !focusTarget && info.OffenseRating <= 0) { continue; } var targetCenter = info.Target.PositionComp.WorldAABB.Center; if (Vector3D.DistanceSquared(targetCenter, w.MyPivotPos) > ((weaponRange + info.TargetRadius) * (weaponRange + info.TargetRadius))) { continue; } session.TargetChecks++; Vector3D targetLinVel = info.Target.Physics?.LinearVelocity ?? Vector3D.Zero; Vector3D targetAccel = accelPrediction ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero; if (info.IsGrid) { if (!s.TrackGrids || !focusTarget && info.FatCount < 2) { continue; } session.CanShoot++; if (!w.AiEnabled) { var newCenter = w.System.Prediction != HardPointDef.Prediction.Off && (!w.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && w.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0) ? w.GetPredictedTargetPosition(targetCenter, targetLinVel, targetAccel) : targetCenter; var targetSphere = info.Target.PositionComp.WorldVolume; targetSphere.Center = newCenter; if (!MathFuncs.TargetSphereInCone(ref targetSphere, ref w.AimCone)) { continue; } } else if (!Weapon.CanShootTargetObb(w, info.Target, targetLinVel, targetAccel)) { continue; } if (!AcquireBlock(s, w.Comp.Ai, target, info, weaponPos, w, true, w.Comp.Seed)) { continue; } targetType = TargetType.Other; target.TransferTo(w.Target, w.Comp.Session.Tick); return; } var meteor = info.Target as MyMeteor; if (meteor != null && !s.TrackMeteors) { continue; } var character = info.Target as IMyCharacter; if (character != null && !s.TrackCharacters || character.IsDead || session.AdminMap.ContainsKey(character)) { continue; } Vector3D predictedPos; if (!Weapon.CanShootTarget(w, targetCenter, targetLinVel, targetAccel, out predictedPos)) { continue; } var targetPos = info.Target.PositionComp.WorldAABB.Center; session.TopRayCasts++; IHitInfo hitInfo; physics.CastRay(weaponPos, targetPos, out hitInfo, 15, true); if (hitInfo != null && hitInfo.HitEntity == info.Target && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf())) { double rayDist; Vector3D.Distance(ref weaponPos, ref targetPos, out rayDist); var shortDist = rayDist * (1 - hitInfo.Fraction); var origDist = rayDist * hitInfo.Fraction; var topEntId = info.Target.GetTopMostParent().EntityId; target.Set(info.Target, hitInfo.Position, shortDist, origDist, topEntId); targetType = TargetType.Other; target.TransferTo(w.Target, w.Comp.Session.Tick); return; } if (forceTarget) { break; } } if (!attemptReset || !w.Target.HasTarget) { targetType = TargetType.None; } else { targetType = w.Target.IsProjectile ? TargetType.Projectile : TargetType.Other; } } catch (Exception ex) { Log.Line($"Exception in AcquireOther: {ex}"); targetType = TargetType.None; } }
internal bool GetTargetState() { var validFocus = false; for (int i = 0; i < Focus.Target.Length; i++) { var target = Focus.Target[i]; TargetInfo info; if (target == null || !Targets.TryGetValue(target, out info)) { continue; } validFocus = true; if (!Session.Tick20 && Focus.PrevTargetId[i] == info.EntInfo.EntityId) { continue; } Focus.PrevTargetId[i] = info.EntInfo.EntityId; var targetVel = target.Physics?.LinearVelocity ?? Vector3.Zero; if (MyUtils.IsZero(targetVel, 1E-02F)) { targetVel = Vector3.Zero; } var targetDir = Vector3D.Normalize(targetVel); var targetRevDir = -targetDir; var targetPos = target.PositionComp.WorldAABB.Center; var myPos = MyGrid.PositionComp.WorldAABB.Center; var myHeading = Vector3D.Normalize(myPos - targetPos); if (info.LargeGrid && info.PartCount > 24000) { Focus.TargetState[i].Size = 6; } else if (info.LargeGrid && info.PartCount > 12000) { Focus.TargetState[i].Size = 5; } else if (info.LargeGrid && info.PartCount > 6000) { Focus.TargetState[i].Size = 4; } else if (info.LargeGrid && info.PartCount > 3000) { Focus.TargetState[i].Size = 3; } else if (info.LargeGrid) { Focus.TargetState[i].Size = 2; } else if (info.PartCount > 2000) { Focus.TargetState[i].Size = 1; } else { Focus.TargetState[i].Size = 0; } var intercept = MathFuncs.IsDotProductWithinTolerance(ref targetDir, ref myHeading, Session.ApproachDegrees); var retreat = MathFuncs.IsDotProductWithinTolerance(ref targetRevDir, ref myHeading, Session.ApproachDegrees); if (intercept) { Focus.TargetState[i].Engagement = 0; } else if (retreat) { Focus.TargetState[i].Engagement = 1; } else { Focus.TargetState[i].Engagement = 2; } var distanceFromCenters = Vector3D.Distance(MyGrid.PositionComp.WorldAABB.Center, target.PositionComp.WorldAABB.Center); distanceFromCenters -= MyGrid.PositionComp.LocalVolume.Radius; distanceFromCenters -= target.PositionComp.LocalVolume.Radius; distanceFromCenters = distanceFromCenters <= 0 ? 0 : distanceFromCenters; var distPercent = (distanceFromCenters / MaxTargetingRange) * 100; if (distPercent > 95) { Focus.TargetState[i].Distance = 9; } else if (distPercent > 90) { Focus.TargetState[i].Distance = 8; } else if (distPercent > 80) { Focus.TargetState[i].Distance = 7; } else if (distPercent > 70) { Focus.TargetState[i].Distance = 6; } else if (distPercent > 60) { Focus.TargetState[i].Distance = 5; } else if (distPercent > 50) { Focus.TargetState[i].Distance = 4; } else if (distPercent > 40) { Focus.TargetState[i].Distance = 3; } else if (distPercent > 30) { Focus.TargetState[i].Distance = 2; } else if (distPercent > 20) { Focus.TargetState[i].Distance = 1; } else if (distPercent > 0) { Focus.TargetState[i].Distance = 0; } else { Focus.TargetState[i].Distance = -1; } var speed = Math.Round(target.Physics?.Speed ?? 0, 1); if (speed <= 0) { Focus.TargetState[i].Speed = -1; } else { var speedPercent = (speed / Session.MaxEntitySpeed) * 100; if (speedPercent > 95) { Focus.TargetState[i].Speed = 9; } else if (speedPercent > 90) { Focus.TargetState[i].Speed = 8; } else if (speedPercent > 80) { Focus.TargetState[i].Speed = 7; } else if (speedPercent > 70) { Focus.TargetState[i].Speed = 6; } else if (speedPercent > 60) { Focus.TargetState[i].Speed = 5; } else if (speedPercent > 50) { Focus.TargetState[i].Speed = 4; } else if (speedPercent > 40) { Focus.TargetState[i].Speed = 3; } else if (speedPercent > 30) { Focus.TargetState[i].Speed = 2; } else if (speedPercent > 20) { Focus.TargetState[i].Speed = 1; } else if (speedPercent > 0) { Focus.TargetState[i].Speed = 0; } else { Focus.TargetState[i].Speed = -1; } } MyTuple <bool, bool, float, float, float, int> shieldInfo = new MyTuple <bool, bool, float, float, float, int>(); if (Session.ShieldApiLoaded) { shieldInfo = Session.SApi.GetShieldInfo(target); } if (shieldInfo.Item1) { var shieldPercent = shieldInfo.Item5; if (shieldPercent > 95) { Focus.TargetState[i].ShieldHealth = 9; } else if (shieldPercent > 90) { Focus.TargetState[i].ShieldHealth = 8; } else if (shieldPercent > 80) { Focus.TargetState[i].ShieldHealth = 7; } else if (shieldPercent > 70) { Focus.TargetState[i].ShieldHealth = 6; } else if (shieldPercent > 60) { Focus.TargetState[i].ShieldHealth = 5; } else if (shieldPercent > 50) { Focus.TargetState[i].ShieldHealth = 4; } else if (shieldPercent > 40) { Focus.TargetState[i].ShieldHealth = 3; } else if (shieldPercent > 30) { Focus.TargetState[i].ShieldHealth = 2; } else if (shieldPercent > 20) { Focus.TargetState[i].ShieldHealth = 1; } else if (shieldPercent > 0) { Focus.TargetState[i].ShieldHealth = 0; } else { Focus.TargetState[i].ShieldHealth = -1; } } else { Focus.TargetState[i].ShieldHealth = -1; } var grid = target as MyCubeGrid; var friend = false; if (grid != null && grid.BigOwners.Count != 0) { var relation = MyIDModule.GetRelationPlayerBlock(MyOwner, grid.BigOwners[0], MyOwnershipShareModeEnum.Faction); if (relation == MyRelationsBetweenPlayerAndBlock.FactionShare || relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.Friends) { friend = true; } } if (friend) { Focus.TargetState[i].ThreatLvl = -1; } else { int shieldBonus = 0; if (Session.ShieldApiLoaded) { var myShieldInfo = Session.SApi.GetShieldInfo(MyGrid); if (shieldInfo.Item1 && myShieldInfo.Item1) { shieldBonus = shieldInfo.Item5 > myShieldInfo.Item5 ? 1 : -1; } else if (shieldInfo.Item1) { shieldBonus = 1; } else if (myShieldInfo.Item1) { shieldBonus = -1; } } var offenseRating = info.OffenseRating; if (offenseRating > 5) { Focus.TargetState[i].ThreatLvl = shieldBonus < 0 ? 8 : 9; } else if (offenseRating > 4) { Focus.TargetState[i].ThreatLvl = 8 + shieldBonus; } else if (offenseRating > 3) { Focus.TargetState[i].ThreatLvl = 7 + shieldBonus; } else if (offenseRating > 2) { Focus.TargetState[i].ThreatLvl = 6 + shieldBonus; } else if (offenseRating > 1) { Focus.TargetState[i].ThreatLvl = 5 + shieldBonus; } else if (offenseRating > 0.5) { Focus.TargetState[i].ThreatLvl = 4 + shieldBonus; } else if (offenseRating > 0.25) { Focus.TargetState[i].ThreatLvl = 3 + shieldBonus; } else if (offenseRating > 0.125) { Focus.TargetState[i].ThreatLvl = 2 + shieldBonus; } else if (offenseRating > 0.0625) { Focus.TargetState[i].ThreatLvl = 1 + shieldBonus; } else if (offenseRating > 0) { Focus.TargetState[i].ThreatLvl = shieldBonus > 0 ? 1 : 0; } else { Focus.TargetState[i].ThreatLvl = -1; } } } return(validFocus); }