Example #1
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; }
        }
Example #2
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; }
        }