Пример #1
0
            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;
            }
Пример #2
0
        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());
        }
Пример #3
0
            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;
            }
Пример #4
0
        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);
        }
Пример #5
0
        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; }
        }
Пример #6
0
        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; }
        }
Пример #7
0
        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);
        }