Ejemplo n.º 1
0
        internal static bool TargetAligned(Weapon weapon, Target target, out Vector3D targetPos)
        {
            Vector3 targetLinVel = Vector3.Zero;
            Vector3 targetAccel  = Vector3.Zero;

            var targetCenter    = weapon.Comp.TrackReticle ? weapon.Comp.Ai.DummyTarget.Position : target.Projectile?.Position ?? target.Entity.PositionComp.WorldAABB.Center;
            var needsPrediction = weapon.System.Prediction != Prediction.Off && (!weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0);

            if (needsPrediction)
            {
                if (weapon.Comp.TrackReticle)
                {
                    targetLinVel = weapon.Comp.Ai.DummyTarget.LinearVelocity;
                    targetAccel  = weapon.Comp.Ai.DummyTarget.Acceleration;
                }
                else
                {
                    var topMostEnt = target.Entity?.GetTopMostParent();
                    if (target.Projectile != null)
                    {
                        targetLinVel = target.Projectile.Velocity;
                        targetAccel  = target.Projectile.AccelVelocity;
                    }
                    else if (topMostEnt?.Physics != null)
                    {
                        targetLinVel = topMostEnt.Physics.LinearVelocity;
                        targetAccel  = topMostEnt.Physics.LinearAcceleration;
                    }
                }

                if (Vector3D.IsZero(targetLinVel, 5E-03))
                {
                    targetLinVel = Vector3.Zero;
                }
                if (Vector3D.IsZero(targetAccel, 5E-03))
                {
                    targetAccel = Vector3.Zero;
                }
                targetPos = weapon.GetPredictedTargetPosition(targetCenter, targetLinVel, targetAccel);
            }
            else
            {
                targetPos = targetCenter;
            }

            var targetDir = targetPos - weapon.MyPivotPos;

            double rangeToTarget;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTarget);
            var inRange = rangeToTarget <= weapon.MaxTargetDistanceSqr;

            var isAligned = (inRange || weapon.Comp.TrackReticle) && MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotDir, ref targetDir, weapon.AimingTolerance);

            weapon.Target.TargetPos = targetPos;
            weapon.Target.IsAligned = isAligned;
            return(isAligned);
        }
Ejemplo n.º 2
0
        internal static bool CanShootTarget(Weapon weapon, ref Vector3D targetCenter, Vector3D targetLinVel, Vector3D targetAccel, out Vector3D targetPos)
        {
            var prediction     = weapon.System.Values.HardPoint.AimLeadingPrediction;
            var trackingWeapon = weapon.TurretMode ? weapon : weapon.Comp.TrackingWeapon;

            if (Vector3D.IsZero(targetLinVel, 5E-03))
            {
                targetLinVel = Vector3.Zero;
            }
            if (Vector3D.IsZero(targetAccel, 5E-03))
            {
                targetAccel = Vector3.Zero;
            }

            var validEstimate = true;

            if (prediction != Prediction.Off && !weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0)
            {
                targetPos = TrajectoryEstimation(weapon, targetCenter, targetLinVel, targetAccel, out validEstimate);
            }
            else
            {
                targetPos = targetCenter;
            }
            var targetDir = targetPos - weapon.MyPivotPos;

            double rangeToTarget;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTarget);

            var inRange = rangeToTarget <= weapon.MaxTargetDistanceSqr && rangeToTarget >= weapon.MinTargetDistanceSqr;

            bool canTrack;
            bool isTracking;

            if (weapon == trackingWeapon)
            {
                canTrack = validEstimate && MathFuncs.WeaponLookAt(weapon, ref targetDir, rangeToTarget, false, true, out isTracking);
            }
            else
            {
                canTrack = validEstimate && MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotDir, ref targetDir, weapon.AimingTolerance);
            }

            return((inRange && canTrack) || weapon.Comp.Data.Repo.Base.State.TrackingReticle);
        }
Ejemplo n.º 3
0
        internal void RunSmart()
        {
            Vector3D newVel;

            if (DeltaVelocityPerTick <= 0 || Vector3D.DistanceSquared(Info.Origin, Position) >= Info.ConsumableDef.Const.SmartsDelayDistSqr)
            {
                var fake            = Info.Target.IsFakeTarget;
                var gaveUpChase     = !fake && Info.Age - ChaseAge > MaxChaseTime && HadTarget;
                var validTarget     = fake || Info.Target.IsProjectile || Info.Target.Entity != null && !Info.Target.Entity.MarkedForClose;
                var isZombie        = Info.ConsumableDef.Const.CanZombie && HadTarget && !fake && !validTarget && ZombieLifeTime > 0 && (ZombieLifeTime + SmartSlot) % 30 == 0;
                var seekFirstTarget = !HadTarget && !validTarget && Info.Age > 120 && (Info.Age + SmartSlot) % 30 == 0;

                if ((PickTarget && (Info.Age + SmartSlot) % 30 == 0 || gaveUpChase && validTarget || isZombie || seekFirstTarget) && NewTarget() || validTarget)
                {
                    HadTarget = true;
                    if (ZombieLifeTime > 0)
                    {
                        ZombieLifeTime = 0;
                        OffSetTarget();
                    }
                    var targetPos = Vector3D.Zero;
                    if (fake)
                    {
                        targetPos = Info.DummyTarget.Position;
                    }
                    else if (Info.Target.IsProjectile)
                    {
                        targetPos = Info.Target.Projectile.Position;
                    }
                    else if (Info.Target.Entity != null)
                    {
                        targetPos = Info.Target.Entity.PositionComp.WorldAABB.Center;
                    }

                    if (Info.ConsumableDef.Const.TargetOffSet && WasTracking)
                    {
                        if (Info.Age - LastOffsetTime > 300)
                        {
                            double dist;
                            Vector3D.DistanceSquared(ref Position, ref targetPos, out dist);
                            if (dist < OffsetSqr + VelocityLengthSqr && Vector3.Dot(Info.Direction, Position - targetPos) > 0)
                            {
                                OffSetTarget();
                            }
                        }
                        targetPos += TargetOffSet;
                    }

                    PredictedTargetPos = targetPos;

                    var physics = Info.Target.Entity?.Physics ?? Info.Target.Entity?.Parent?.Physics;
                    if (!(Info.Target.IsProjectile || fake) && (physics == null || Vector3D.IsZero(targetPos)))
                    {
                        PrevTargetPos = PredictedTargetPos;
                    }
                    else
                    {
                        PrevTargetPos = targetPos;
                    }

                    var tVel = Vector3.Zero;
                    if (fake)
                    {
                        tVel = Info.DummyTarget.LinearVelocity;
                    }
                    else if (Info.Target.IsProjectile)
                    {
                        tVel = Info.Target.Projectile.Velocity;
                    }
                    else if (physics != null)
                    {
                        tVel = physics.LinearVelocity;
                    }
                    if (Info.ConsumableDef.Const.TargetLossDegree > 0 && Vector3D.DistanceSquared(Info.Origin, Position) >= Info.ConsumableDef.Const.SmartsDelayDistSqr)
                    {
                        if (WasTracking && (Info.System.Session.Tick20 || Vector3.Dot(Info.Direction, Position - targetPos) > 0) || !WasTracking)
                        {
                            var targetDir = -Info.Direction;
                            var refDir    = Vector3D.Normalize(Position - targetPos);
                            if (!MathFuncs.IsDotProductWithinTolerance(ref targetDir, ref refDir, Info.ConsumableDef.Const.TargetLossDegree))
                            {
                                if (WasTracking)
                                {
                                    PickTarget = true;
                                }
                            }
                            else if (!WasTracking)
                            {
                                WasTracking = true;
                            }
                        }
                    }

                    PrevTargetVel = tVel;
                }
                else
                {
                    var roam = Info.ConsumableDef.Trajectory.Smarts.Roam;
                    PrevTargetPos = roam ? PredictedTargetPos : Position + (Info.Direction * Info.MaxTrajectory);

                    if (ZombieLifeTime++ > Info.ConsumableDef.Const.TargetLossTime && !Info.ConsumableDef.Trajectory.Smarts.KeepAliveAfterTargetLoss && (Info.ConsumableDef.Trajectory.Smarts.NoTargetExpire || HadTarget))
                    {
                        DistanceToTravelSqr = Info.DistanceTraveled * Info.DistanceTraveled;
                        EarlyEnd            = true;
                    }

                    if (roam && Info.Age - LastOffsetTime > 300 && HadTarget)
                    {
                        double dist;
                        Vector3D.DistanceSquared(ref Position, ref PrevTargetPos, out dist);
                        if (dist < OffsetSqr + VelocityLengthSqr && Vector3.Dot(Info.Direction, Position - PrevTargetPos) > 0)
                        {
                            OffSetTarget(true);
                            PrevTargetPos     += TargetOffSet;
                            PredictedTargetPos = PrevTargetPos;
                        }
                    }
                }

                var missileToTarget           = Vector3D.Normalize(PrevTargetPos - Position);
                var relativeVelocity          = PrevTargetVel - Velocity;
                var normalMissileAcceleration = (relativeVelocity - (relativeVelocity.Dot(missileToTarget) * missileToTarget)) * Info.ConsumableDef.Trajectory.Smarts.Aggressiveness;

                Vector3D commandedAccel;
                if (Vector3D.IsZero(normalMissileAcceleration))
                {
                    commandedAccel = (missileToTarget * AccelInMetersPerSec);
                }
                else
                {
                    var maxLateralThrust = AccelInMetersPerSec * Math.Min(1, Math.Max(0, Info.ConsumableDef.Const.MaxLateralThrust));
                    if (normalMissileAcceleration.LengthSquared() > maxLateralThrust * maxLateralThrust)
                    {
                        Vector3D.Normalize(ref normalMissileAcceleration, out normalMissileAcceleration);
                        normalMissileAcceleration *= maxLateralThrust;
                    }
                    commandedAccel = Math.Sqrt(Math.Max(0, AccelInMetersPerSec * AccelInMetersPerSec - normalMissileAcceleration.LengthSquared())) * missileToTarget + normalMissileAcceleration;
                }

                newVel   = Velocity + (commandedAccel * StepConst);
                AccelDir = commandedAccel / AccelInMetersPerSec;
                Vector3D.Normalize(ref newVel, out Info.Direction);
            }
            else
            {
                newVel = Velocity += (Info.Direction * DeltaVelocityPerTick);
            }
            VelocityLengthSqr = newVel.LengthSquared();

            if (VelocityLengthSqr > MaxSpeedSqr)
            {
                newVel = Info.Direction * MaxSpeed;
            }
            Velocity = newVel;
        }
Ejemplo n.º 4
0
        internal static bool CanShootTargetObb(Weapon weapon, MyEntity entity, Vector3D targetLinVel, Vector3D targetAccel)
        {
            var      prediction     = weapon.System.Values.HardPoint.AimLeadingPrediction;
            var      trackingWeapon = weapon.TurretMode ? weapon : weapon.Comp.TrackingWeapon;
            Vector3D targetPos;

            if (Vector3D.IsZero(targetLinVel, 5E-03))
            {
                targetLinVel = Vector3.Zero;
            }
            if (Vector3D.IsZero(targetAccel, 5E-03))
            {
                targetAccel = Vector3.Zero;
            }

            var rotMatrix = Quaternion.CreateFromRotationMatrix(entity.PositionComp.WorldMatrix);
            var obb       = new MyOrientedBoundingBoxD(entity.PositionComp.WorldAABB.Center, entity.PositionComp.LocalAABB.HalfExtents, rotMatrix);

            if (prediction != Prediction.Off && !weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0)
            {
                targetPos = weapon.GetPredictedTargetPosition(obb.Center, targetLinVel, targetAccel);
            }
            else
            {
                targetPos = obb.Center;
            }

            obb.Center       = targetPos;
            weapon.TargetBox = obb;

            var maxRangeSqr = obb.HalfExtent.AbsMax() + weapon.MaxTargetDistance;

            maxRangeSqr *= maxRangeSqr;
            double rangeToTarget;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTarget);

            bool canTrack = false;

            if (rangeToTarget <= maxRangeSqr)
            {
                var targetDir = targetPos - weapon.MyPivotPos;
                if (weapon == trackingWeapon)
                {
                    double checkAzimuth;
                    double checkElevation;

                    MathFuncs.GetRotationAngles(ref targetDir, ref weapon.WeaponConstMatrix, out checkAzimuth, out checkElevation);

                    var azConstraint = Math.Min(weapon.MaxAzimuthRadians, Math.Max(weapon.MinAzimuthRadians, checkAzimuth));
                    var elConstraint = Math.Min(weapon.MaxElevationRadians, Math.Max(weapon.MinElevationRadians, checkElevation));

                    Vector3D constraintVector;
                    Vector3D.CreateFromAzimuthAndElevation(azConstraint, elConstraint, out constraintVector);
                    constraintVector = Vector3D.Rotate(constraintVector, weapon.WeaponConstMatrix);

                    var testRay = new RayD(weapon.MyPivotPos, constraintVector);
                    if (obb.Intersects(ref testRay) != null)
                    {
                        canTrack = true;
                    }

                    if (weapon.Comp.Debug)
                    {
                        weapon.LimitLine = new LineD(weapon.MyPivotPos, weapon.MyPivotPos + (constraintVector * weapon.ActiveAmmoDef.AmmoDef.Const.MaxTrajectory));
                    }
                }
                else
                {
                    canTrack = MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotDir, ref targetDir, weapon.AimingTolerance);
                }
            }
            return(canTrack);
        }
Ejemplo n.º 5
0
        internal static bool TrackingTarget(Weapon weapon, Target target)
        {
            Vector3D targetPos;
            Vector3  targetLinVel = Vector3.Zero;
            Vector3  targetAccel  = Vector3.Zero;
            var      system       = weapon.System;
            Vector3D targetCenter;

            var rayCheckTest = !weapon.Comp.Session.IsClient && weapon.Comp.State.Value.CurrentPlayerControl.ControlType == ControlType.None && weapon.ActiveAmmoDef.AmmoDef.Trajectory.Guidance == GuidanceType.None && (!weapon.Casting && weapon.Comp.Session.Tick - weapon.Comp.LastRayCastTick > 29 || weapon.System.Values.HardPoint.Other.MuzzleCheck && weapon.Comp.Session.Tick - weapon.LastMuzzleCheck > 29);

            if (rayCheckTest && !weapon.RayCheckTest())
            {
                return(false);
            }

            if (weapon.Comp.TrackReticle)
            {
                targetCenter = weapon.Comp.Ai.DummyTarget.Position;
            }
            else if (target.IsProjectile)
            {
                if (target.Projectile == null)
                {
                    Log.Line($"TrackingTarget: is projectile and it is null");
                    targetCenter = Vector3D.Zero;
                }
                else
                {
                    targetCenter = target.Projectile.Position;
                }
            }
            else if (!target.IsFakeTarget)
            {
                if (target.Entity == null)
                {
                    Log.Line($"TrackingTarget: is entity and it is null");
                    targetCenter = Vector3D.Zero;
                }
                else
                {
                    targetCenter = target.Entity.PositionComp.WorldAABB.Center;
                }
            }
            else
            {
                targetCenter = Vector3D.Zero;
            }

            var needsPrediction = weapon.System.Prediction != Prediction.Off && (!weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0);

            if (needsPrediction)
            {
                if (weapon.Comp.TrackReticle)
                {
                    targetLinVel = weapon.Comp.Ai.DummyTarget.LinearVelocity;
                    targetAccel  = weapon.Comp.Ai.DummyTarget.Acceleration;
                }
                else
                {
                    var topMostEnt = target.Entity?.GetTopMostParent();
                    if (target.Projectile != null)
                    {
                        targetLinVel = target.Projectile.Velocity;
                        targetAccel  = target.Projectile.AccelVelocity;
                    }
                    else if (topMostEnt?.Physics != null)
                    {
                        targetLinVel = topMostEnt.Physics.LinearVelocity;
                        targetAccel  = topMostEnt.Physics.LinearAcceleration;
                    }
                }
                if (Vector3D.IsZero(targetLinVel, 5E-03))
                {
                    targetLinVel = Vector3.Zero;
                }
                if (Vector3D.IsZero(targetAccel, 5E-03))
                {
                    targetAccel = Vector3.Zero;
                }
                targetPos = weapon.GetPredictedTargetPosition(targetCenter, targetLinVel, targetAccel);
            }
            else
            {
                targetPos = targetCenter;
            }

            weapon.Target.TargetPos = targetPos;

            double rangeToTargetSqr;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTargetSqr);
            var targetDir = targetPos - weapon.MyPivotPos;
            var locked    = true;

            if (weapon.Comp.TrackReticle || rangeToTargetSqr <= weapon.MaxTargetDistanceSqr)
            {
                var maxAzimuthStep   = system.AzStep;
                var maxElevationStep = system.ElStep;

                Vector3D currentVector;
                Vector3D.CreateFromAzimuthAndElevation(weapon.Azimuth, weapon.Elevation, out currentVector);
                currentVector = Vector3D.Rotate(currentVector, weapon.WeaponConstMatrix);

                var up   = weapon.MyPivotUp;
                var left = Vector3D.Cross(up, currentVector);
                if (!Vector3D.IsUnit(ref left) && !Vector3D.IsZero(left))
                {
                    left.Normalize();
                }
                var forward          = Vector3D.Cross(left, up);
                var constraintMatrix = new MatrixD {
                    Forward = forward, Left = left, Up = up,
                };

                double desiredAzimuth;
                double desiredElevation;
                MathFuncs.GetRotationAngles(ref targetDir, ref constraintMatrix, out desiredAzimuth, out desiredElevation);

                var azConstraint  = Math.Min(weapon.MaxAzimuthRadians, Math.Max(weapon.MinAzimuthRadians, desiredAzimuth));
                var elConstraint  = Math.Min(weapon.MaxElevationRadians, Math.Max(weapon.MinElevationRadians, desiredElevation));
                var elConstrained = Math.Abs(elConstraint - desiredElevation) > 0.0000001;
                var azConstrained = Math.Abs(azConstraint - desiredAzimuth) > 0.0000001;
                weapon.Target.IsTracking = !azConstrained && !elConstrained;

                if (weapon.Target.IsTracking && weapon.Comp.State.Value.CurrentPlayerControl.ControlType != ControlType.Camera && !weapon.Comp.ResettingSubparts)
                {
                    var oldAz   = weapon.Azimuth;
                    var oldEl   = weapon.Elevation;
                    var epsilon = target.IsProjectile ? 1E-06d : rangeToTargetSqr <= 640000 ? 1E-03d : rangeToTargetSqr <= 3240000 ? 1E-04d : 1E-05d;
                    var az      = weapon.Azimuth + MathHelperD.Clamp(desiredAzimuth, -maxAzimuthStep, maxAzimuthStep);
                    var el      = weapon.Elevation + MathHelperD.Clamp(desiredElevation - weapon.Elevation, -maxElevationStep, maxElevationStep);

                    var azDiff   = oldAz - az;
                    var elDiff   = oldEl - el;
                    var azLocked = MyUtils.IsZero(azDiff, (float)epsilon);
                    var elLocked = MyUtils.IsZero(elDiff, (float)epsilon);

                    locked = azLocked && elLocked;
                    var aim = !azLocked || !elLocked;
                    if (aim)
                    {
                        if (!azLocked)
                        {
                            weapon.Azimuth = az;
                        }
                        if (!elLocked)
                        {
                            weapon.Elevation = el;
                        }
                        weapon.IsHome = false;
                        weapon.AimBarrel(azDiff, elDiff, !azLocked, !elLocked);
                    }
                }
            }
            else
            {
                weapon.Target.IsTracking = false;
            }

            if (weapon.Comp.State.Value.CurrentPlayerControl.ControlType == ControlType.Camera)
            {
                return(weapon.Target.IsTracking);
            }

            var isAligned = false;

            if (weapon.Target.IsTracking)
            {
                isAligned = locked || MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotDir, ref targetDir, weapon.AimingTolerance);
            }

            var wasAligned = weapon.Target.IsAligned;

            weapon.Target.IsAligned = isAligned;
            var alignedChange = wasAligned != isAligned;

            if (alignedChange && isAligned)
            {
                if (weapon.System.DesignatorWeapon)
                {
                    for (int i = 0; i < weapon.Comp.Platform.Weapons.Length; i++)
                    {
                        var w = weapon.Comp.Platform.Weapons[i];
                        w.Target.StateChange(false, Target.States.Expired);
                        w.Target.CheckTick -= 240;
                    }
                }
            }
            else if (alignedChange && !weapon.System.DelayCeaseFire)
            {
                weapon.StopShooting();
            }

            weapon.Target.TargetLock = weapon.Target.IsTracking && weapon.Target.IsAligned;
            return(weapon.Target.IsTracking);
        }
Ejemplo n.º 6
0
        internal static bool CanShootTarget(Weapon weapon, Vector3D targetCenter, Vector3D targetLinVel, Vector3D targetAccel, out Vector3D targetPos)
        {
            var prediction     = weapon.System.Values.HardPoint.AimLeadingPrediction;
            var trackingWeapon = weapon.TurretMode ? weapon : weapon.Comp.TrackingWeapon;

            if (Vector3D.IsZero(targetLinVel, 5E-03))
            {
                targetLinVel = Vector3.Zero;
            }
            if (Vector3D.IsZero(targetAccel, 5E-03))
            {
                targetAccel = Vector3.Zero;
            }

            if (prediction != Prediction.Off && !weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0)
            {
                targetPos = weapon.GetPredictedTargetPosition(targetCenter, targetLinVel, targetAccel);
            }
            else
            {
                targetPos = targetCenter;
            }
            var targetDir = targetPos - weapon.MyPivotPos;

            double rangeToTarget;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTarget);

            var inRange = rangeToTarget <= weapon.MaxTargetDistanceSqr;

            bool canTrack;

            if (weapon == trackingWeapon)
            {
                Vector3D currentVector;
                Vector3D.CreateFromAzimuthAndElevation(weapon.Azimuth, weapon.Elevation, out currentVector);
                currentVector = Vector3D.Rotate(currentVector, weapon.WeaponConstMatrix);

                var up   = weapon.MyPivotUp;
                var left = Vector3D.Cross(up, currentVector);
                if (!Vector3D.IsUnit(ref left) && !Vector3D.IsZero(left))
                {
                    left.Normalize();
                }
                var forward = Vector3D.Cross(left, up);

                var matrix = new MatrixD {
                    Forward = forward, Left = left, Up = up,
                };

                double desiredAzimuth;
                double desiredElevation;
                MathFuncs.GetRotationAngles(ref targetDir, ref matrix, out desiredAzimuth, out desiredElevation);

                var azConstraint  = Math.Min(weapon.MaxAzimuthRadians, Math.Max(weapon.MinAzimuthRadians, desiredAzimuth));
                var elConstraint  = Math.Min(weapon.MaxElevationRadians, Math.Max(weapon.MinElevationRadians, desiredElevation));
                var azConstrained = Math.Abs(elConstraint - desiredElevation) > 0.0000001;
                var elConstrained = Math.Abs(azConstraint - desiredAzimuth) > 0.0000001;
                canTrack = !azConstrained && !elConstrained;
            }
            else
            {
                canTrack = MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotDir, ref targetDir, weapon.AimingTolerance);
            }

            return((inRange && canTrack) || weapon.Comp.TrackReticle);
        }
Ejemplo n.º 7
0
        internal bool GetTargetState(Session s)
        {
            var ai            = s.TrackingAi;
            var validFocus    = false;
            var maxNameLength = 18;

            if (s.Tick - MasterUpdateTick > 300 || MasterUpdateTick < 300 && _masterTargets.Count == 0)
            {
                BuildMasterCollections(ai);
            }

            for (int i = 0; i < ai.Construct.Data.Repo.FocusData.Target.Length; i++)
            {
                var      targetId = ai.Construct.Data.Repo.FocusData.Target[i];
                float    offenseRating;
                MyEntity target;
                if (targetId <= 0 || !MyEntities.TryGetEntityById(targetId, out target) || !_masterTargets.TryGetValue(target, out offenseRating))
                {
                    continue;
                }
                validFocus = true;
                if (!s.Tick20)
                {
                    continue;
                }
                var    grid      = target as MyCubeGrid;
                var    partCount = 1;
                var    largeGrid = false;
                GridAi targetAi  = null;
                if (grid != null)
                {
                    largeGrid = grid.GridSizeEnum == MyCubeSize.Large;
                    GridMap gridMap;
                    if (s.GridToMasterAi.TryGetValue(grid, out targetAi))
                    {
                        partCount = targetAi.Construct.BlockCount;
                    }
                    else if (s.GridToInfoMap.TryGetValue(grid, out gridMap))
                    {
                        partCount = gridMap.MostBlocks;
                    }
                }

                var state = ai.TargetState[i];

                state.Aware = targetAi != null?AggressionState(ai, targetAi) : TargetStatus.Awareness.WONDERING;

                var displayName = target.DisplayName;
                var name        = string.IsNullOrEmpty(displayName) ? string.Empty : displayName.Length <= maxNameLength ? displayName : displayName.Substring(0, maxNameLength);

                var targetVel = target.Physics?.LinearVelocity ?? Vector3.Zero;
                if (MyUtils.IsZero(targetVel, 1E-01F))
                {
                    targetVel = Vector3.Zero;
                }
                var targetDir    = Vector3D.Normalize(targetVel);
                var targetRevDir = -targetDir;
                var targetPos    = target.PositionComp.WorldAABB.Center;
                var myPos        = ai.MyGrid.PositionComp.WorldAABB.Center;
                var myHeading    = Vector3D.Normalize(myPos - targetPos);

                var intercept = MathFuncs.IsDotProductWithinTolerance(ref targetDir, ref myHeading, s.ApproachDegrees);
                var retreat   = MathFuncs.IsDotProductWithinTolerance(ref targetRevDir, ref myHeading, s.ApproachDegrees);

                var distanceFromCenters = Vector3D.Distance(ai.MyGrid.PositionComp.WorldAABB.Center, target.PositionComp.WorldAABB.Center);
                distanceFromCenters -= ai.MyGrid.PositionComp.LocalVolume.Radius;
                distanceFromCenters -= target.PositionComp.LocalVolume.Radius;
                distanceFromCenters  = distanceFromCenters <= 0 ? 0 : distanceFromCenters;

                var speed = (float)Math.Round(target.Physics?.Speed ?? 0, 1);

                state.Name = name;

                state.RealDistance = distanceFromCenters;

                state.SizeExtended = (float)Math.Round(partCount / (largeGrid ? 100f : 500f), 1);

                state.Speed = speed;

                if (intercept)
                {
                    state.Engagement = 0;
                }
                else if (retreat)
                {
                    state.Engagement = 1;
                }
                else
                {
                    state.Engagement = 2;
                }

                MyTuple <bool, bool, float, float, float, int> shieldInfo = new MyTuple <bool, bool, float, float, float, int>();
                if (s.ShieldApiLoaded)
                {
                    shieldInfo = s.SApi.GetShieldInfo(target);
                }
                if (shieldInfo.Item1)
                {
                    var modInfo  = s.SApi.GetModulationInfo(target);
                    var modValue = MyUtils.IsEqual(modInfo.Item3, modInfo.Item4) ? 0 : modInfo.Item3 > modInfo.Item4 ? modInfo.Item3 : -modInfo.Item4;
                    var faceInfo = s.SApi.GetFacesFast(target);
                    state.ShieldFaces  = faceInfo.Item1 ? faceInfo.Item2 : Vector3I.Zero;
                    state.ShieldHeat   = shieldInfo.Item6 / 10;
                    state.ShieldMod    = modValue;
                    state.ShieldHealth = (float)Math.Round(shieldInfo.Item5);
                }
                else
                {
                    state.ShieldHeat   = 0;
                    state.ShieldMod    = 0;
                    state.ShieldHealth = -1;
                    state.ShieldFaces  = Vector3I.Zero;
                }

                var friend = false;
                if (grid != null && grid.BigOwners.Count != 0)
                {
                    var relation = MyIDModule.GetRelationPlayerBlock(ai.AiOwner, grid.BigOwners[0], MyOwnershipShareModeEnum.Faction);
                    if (relation == MyRelationsBetweenPlayerAndBlock.FactionShare || relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.Friends)
                    {
                        friend = true;
                    }
                }

                if (friend)
                {
                    state.ThreatLvl = -1;
                }
                else
                {
                    int shieldBonus = 0;
                    if (s.ShieldApiLoaded)
                    {
                        var myShieldInfo = s.SApi.GetShieldInfo(ai.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;
                        }
                    }

                    if (offenseRating > 5)
                    {
                        state.ThreatLvl = shieldBonus < 0 ? 8 : 9;
                    }
                    else if (offenseRating > 4)
                    {
                        state.ThreatLvl = 8 + shieldBonus;
                    }
                    else if (offenseRating > 3)
                    {
                        state.ThreatLvl = 7 + shieldBonus;
                    }
                    else if (offenseRating > 2)
                    {
                        state.ThreatLvl = 6 + shieldBonus;
                    }
                    else if (offenseRating > 1)
                    {
                        state.ThreatLvl = 5 + shieldBonus;
                    }
                    else if (offenseRating > 0.5)
                    {
                        state.ThreatLvl = 4 + shieldBonus;
                    }
                    else if (offenseRating > 0.25)
                    {
                        state.ThreatLvl = 3 + shieldBonus;
                    }
                    else if (offenseRating > 0.125)
                    {
                        state.ThreatLvl = 2 + shieldBonus;
                    }
                    else if (offenseRating > 0.0625)
                    {
                        state.ThreatLvl = 1 + shieldBonus;
                    }
                    else if (offenseRating > 0)
                    {
                        state.ThreatLvl = shieldBonus > 0 ? 1 : 0;
                    }
                    else
                    {
                        state.ThreatLvl = -1;
                    }
                }
            }
            return(validFocus);
        }
Ejemplo n.º 8
0
        internal static bool TrackingTarget(Weapon w, Target target, out bool targetLock)
        {
            Vector3D targetPos;
            Vector3  targetLinVel = Vector3.Zero;
            Vector3  targetAccel  = Vector3.Zero;
            Vector3D targetCenter;

            targetLock = false;

            var baseData = w.Comp.Data.Repo.Base;
            var session  = w.System.Session;
            var ai       = w.Comp.Ai;

            FakeWorldTargetInfo fakeTargetInfo = null;

            if (baseData.Set.Overrides.Control != GroupOverrides.ControlModes.Auto && w.ValidFakeTargetInfo(baseData.State.PlayerId, out fakeTargetInfo))
            {
                targetCenter = fakeTargetInfo.WorldPosition;
            }
            else if (target.IsProjectile)
            {
                targetCenter = target.Projectile?.Position ?? Vector3D.Zero;
            }
            else if (!target.IsFakeTarget)
            {
                targetCenter = target.Entity?.PositionComp.WorldAABB.Center ?? Vector3D.Zero;
            }
            else
            {
                targetCenter = Vector3D.Zero;
            }

            var validEstimate = true;

            if (w.System.Prediction != Prediction.Off && !w.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && w.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0)
            {
                if (fakeTargetInfo != null)
                {
                    targetLinVel = fakeTargetInfo.LinearVelocity;
                    targetAccel  = fakeTargetInfo.Acceleration;
                }
                else
                {
                    var cube       = target.Entity as MyCubeBlock;
                    var topMostEnt = cube != null ? cube.CubeGrid : target.Entity;

                    if (target.Projectile != null)
                    {
                        targetLinVel = target.Projectile.Velocity;
                        targetAccel  = target.Projectile.AccelVelocity;
                    }
                    else if (topMostEnt?.Physics != null)
                    {
                        targetLinVel = topMostEnt.Physics.LinearVelocity;
                        targetAccel  = topMostEnt.Physics.LinearAcceleration;
                    }
                }
                if (Vector3D.IsZero(targetLinVel, 5E-03))
                {
                    targetLinVel = Vector3.Zero;
                }
                if (Vector3D.IsZero(targetAccel, 5E-03))
                {
                    targetAccel = Vector3.Zero;
                }
                targetPos = TrajectoryEstimation(w, targetCenter, targetLinVel, targetAccel, out validEstimate);
            }
            else
            {
                targetPos = targetCenter;
            }

            w.Target.TargetPos = targetPos;

            double rangeToTargetSqr;

            Vector3D.DistanceSquared(ref targetPos, ref w.MyPivotPos, out rangeToTargetSqr);

            var targetDir    = targetPos - w.MyPivotPos;
            var readyToTrack = validEstimate && !w.Comp.ResettingSubparts && (baseData.State.TrackingReticle || rangeToTargetSqr <= w.MaxTargetDistanceSqr && rangeToTargetSqr >= w.MinTargetDistanceSqr);

            var locked     = true;
            var isTracking = false;

            if (readyToTrack && baseData.State.Control != CompStateValues.ControlMode.Camera)
            {
                if (MathFuncs.WeaponLookAt(w, ref targetDir, rangeToTargetSqr, true, false, out isTracking))
                {
                    w.ReturingHome = false;
                    locked         = false;
                    w.AimBarrel();
                }
            }

            w.Rotating = !locked;

            if (baseData.State.Control == CompStateValues.ControlMode.Camera)
            {
                return(isTracking);
            }

            var isAligned = false;

            if (isTracking)
            {
                isAligned = locked || MathFuncs.IsDotProductWithinTolerance(ref w.MyPivotFwd, ref targetDir, w.AimingTolerance);
            }

            var wasAligned = w.Target.IsAligned;

            w.Target.IsAligned = isAligned;
            var alignedChange = wasAligned != isAligned;

            if (w.System.DesignatorWeapon && session.IsServer && alignedChange)
            {
                for (int i = 0; i < w.Comp.Platform.Weapons.Length; i++)
                {
                    var weapon = w.Comp.Platform.Weapons[i];
                    if (isAligned && !weapon.System.DesignatorWeapon)
                    {
                        weapon.Target.Reset(session.Tick, Target.States.Designator);
                    }
                    else if (!isAligned && weapon.System.DesignatorWeapon)
                    {
                        weapon.Target.Reset(session.Tick, Target.States.Designator);
                    }
                }
            }

            targetLock = isTracking && w.Target.IsAligned;

            if (session.IsServer && baseData.Set.Overrides.Repel && ai.TargetingInfo.DroneInRange && !target.IsDrone && (session.AwakeCount == w.Acquire.SlotId || ai.Construct.RootAi.Construct.LastDroneTick == session.Tick) && GridAi.SwitchToDrone(w))
            {
                return(true);
            }

            var rayCheckTest = !w.Comp.Session.IsClient && targetLock && (baseData.State.Control == CompStateValues.ControlMode.None || baseData.State.Control == CompStateValues.ControlMode.Ui) && w.ActiveAmmoDef.AmmoDef.Trajectory.Guidance != GuidanceType.Smart && (!w.Casting && session.Tick - w.Comp.LastRayCastTick > 29 || w.System.Values.HardPoint.Other.MuzzleCheck && session.Tick - w.LastMuzzleCheck > 29);

            if (rayCheckTest && !w.RayCheckTest())
            {
                return(false);
            }

            return(isTracking);
        }
Ejemplo n.º 9
0
        internal static bool TargetAligned(Weapon weapon, Target target, out Vector3D targetPos)
        {
            Vector3  targetLinVel = Vector3.Zero;
            Vector3  targetAccel  = Vector3.Zero;
            Vector3D targetCenter;

            FakeWorldTargetInfo fakeTargetInfo = null;

            if (weapon.Comp.Data.Repo.Base.Set.Overrides.Control != GroupOverrides.ControlModes.Auto && weapon.ValidFakeTargetInfo(weapon.Comp.Data.Repo.Base.State.PlayerId, out fakeTargetInfo))
            {
                targetCenter = fakeTargetInfo.WorldPosition;
            }
            else if (target.IsProjectile)
            {
                targetCenter = target.Projectile?.Position ?? Vector3D.Zero;
            }
            else if (!target.IsFakeTarget)
            {
                targetCenter = target.Entity?.PositionComp.WorldAABB.Center ?? Vector3D.Zero;
            }
            else
            {
                targetCenter = Vector3D.Zero;
            }

            var validEstimate = true;

            if (weapon.System.Prediction != Prediction.Off && (!weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0))
            {
                if (fakeTargetInfo != null)
                {
                    targetLinVel = fakeTargetInfo.LinearVelocity;
                    targetAccel  = fakeTargetInfo.Acceleration;
                }
                else
                {
                    var cube       = target.Entity as MyCubeBlock;
                    var topMostEnt = cube != null ? cube.CubeGrid : target.Entity;

                    if (target.Projectile != null)
                    {
                        targetLinVel = target.Projectile.Velocity;
                        targetAccel  = target.Projectile.AccelVelocity;
                    }
                    else if (topMostEnt?.Physics != null)
                    {
                        targetLinVel = topMostEnt.Physics.LinearVelocity;
                        targetAccel  = topMostEnt.Physics.LinearAcceleration;
                    }
                }
                if (Vector3D.IsZero(targetLinVel, 5E-03))
                {
                    targetLinVel = Vector3.Zero;
                }
                if (Vector3D.IsZero(targetAccel, 5E-03))
                {
                    targetAccel = Vector3.Zero;
                }
                targetPos = TrajectoryEstimation(weapon, targetCenter, targetLinVel, targetAccel, out validEstimate);
            }
            else
            {
                targetPos = targetCenter;
            }

            var targetDir = targetPos - weapon.MyPivotPos;

            double rangeToTarget;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTarget);
            var inRange = rangeToTarget <= weapon.MaxTargetDistanceSqr && rangeToTarget >= weapon.MinTargetDistanceSqr;

            var isAligned = validEstimate && (inRange || weapon.Comp.Data.Repo.Base.State.TrackingReticle) && MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotFwd, ref targetDir, weapon.AimingTolerance);

            weapon.Target.TargetPos = targetPos;
            weapon.Target.IsAligned = isAligned;
            return(isAligned);
        }
Ejemplo n.º 10
0
        internal static bool CanShootTarget(Weapon weapon, ref Vector3D targetCenter, Vector3D targetLinVel, Vector3D targetAccel, out Vector3D targetPos, bool checkSelfHit = false, MyEntity target = null)
        {
            var prediction     = weapon.System.Values.HardPoint.AimLeadingPrediction;
            var trackingWeapon = weapon.TurretMode ? weapon : weapon.Comp.TrackingWeapon;

            if (Vector3D.IsZero(targetLinVel, 5E-03))
            {
                targetLinVel = Vector3.Zero;
            }
            if (Vector3D.IsZero(targetAccel, 5E-03))
            {
                targetAccel = Vector3.Zero;
            }

            var validEstimate = true;

            if (prediction != Prediction.Off && !weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0)
            {
                targetPos = TrajectoryEstimation(weapon, targetCenter, targetLinVel, targetAccel, out validEstimate);
            }
            else
            {
                targetPos = targetCenter;
            }
            var targetDir = targetPos - weapon.MyPivotPos;

            double rangeToTarget;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTarget);

            var inRange = rangeToTarget <= weapon.MaxTargetDistanceSqr && rangeToTarget >= weapon.MinTargetDistanceSqr;

            bool canTrack;
            bool isTracking;

            if (weapon == trackingWeapon)
            {
                canTrack = validEstimate && MathFuncs.WeaponLookAt(weapon, ref targetDir, rangeToTarget, false, true, out isTracking);
            }
            else
            {
                canTrack = validEstimate && MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotFwd, ref targetDir, weapon.AimingTolerance);
            }

            bool selfHit = false;

            weapon.LastHitInfo = null;
            if (checkSelfHit && target != null)
            {
                var testLine           = new LineD(targetCenter, weapon.BarrelOrigin);
                var predictedMuzzlePos = testLine.To + (-testLine.Direction * weapon.MuzzleDistToBarrelCenter);
                var ai = weapon.Comp.Ai;
                var localPredictedPos = Vector3I.Round(Vector3D.Transform(predictedMuzzlePos, ai.MyGrid.PositionComp.WorldMatrixNormalizedInv) * ai.MyGrid.GridSizeR);

                MyCube cube;
                var    noCubeAtPosition = !ai.MyGrid.TryGetCube(localPredictedPos, out cube);
                if (noCubeAtPosition || cube.CubeBlock == weapon.Comp.MyCube.SlimBlock)
                {
                    var noCubeInLine           = !ai.MyGrid.GetIntersectionWithLine(ref testLine, ref ai.GridHitInfo);
                    var noCubesInLineOrHitSelf = noCubeInLine || ai.GridHitInfo.Position == weapon.Comp.MyCube.Position;

                    if (noCubesInLineOrHitSelf)
                    {
                        weapon.System.Session.Physics.CastRay(predictedMuzzlePos, testLine.From, out weapon.LastHitInfo, CollisionLayers.DefaultCollisionLayer);

                        if (weapon.LastHitInfo != null && weapon.LastHitInfo.HitEntity == ai.MyGrid)
                        {
                            selfHit = true;
                        }
                    }
                }
                else
                {
                    selfHit = true;
                }
            }

            return(!selfHit && (inRange && canTrack || weapon.Comp.Data.Repo.Base.State.TrackingReticle));
        }
Ejemplo n.º 11
0
        internal static bool TrackingTarget(Weapon weapon, Target target, out bool targetLock)
        {
            Vector3D targetPos;
            Vector3  targetLinVel = Vector3.Zero;
            Vector3  targetAccel  = Vector3.Zero;
            Vector3D targetCenter;

            targetLock = false;

            var rayCheckTest = !weapon.Comp.Session.IsClient && (weapon.Comp.Data.Repo.Base.State.Control == CompStateValues.ControlMode.None || weapon.Comp.Data.Repo.Base.State.Control == CompStateValues.ControlMode.Ui) && weapon.ActiveAmmoDef.AmmoDef.Trajectory.Guidance == GuidanceType.None && (!weapon.Casting && weapon.Comp.Session.Tick - weapon.Comp.LastRayCastTick > 29 || weapon.System.Values.HardPoint.Other.MuzzleCheck && weapon.Comp.Session.Tick - weapon.LastMuzzleCheck > 29);

            if (rayCheckTest && !weapon.RayCheckTest())
            {
                return(false);
            }
            if (weapon.Comp.Data.Repo.Base.State.TrackingReticle)
            {
                targetCenter = weapon.Comp.Session.PlayerDummyTargets[weapon.Comp.Data.Repo.Base.State.PlayerId].Position;
            }
            else if (target.IsProjectile)
            {
                targetCenter = target.Projectile?.Position ?? Vector3D.Zero;
            }
            else if (!target.IsFakeTarget)
            {
                targetCenter = target.Entity?.PositionComp.WorldAABB.Center ?? Vector3D.Zero;
            }
            else
            {
                targetCenter = Vector3D.Zero;
            }

            var validEstimate = true;

            if (weapon.System.Prediction != Prediction.Off && !weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0)
            {
                if (weapon.Comp.Data.Repo.Base.State.TrackingReticle)
                {
                    targetLinVel = weapon.Comp.Session.PlayerDummyTargets[weapon.Comp.Data.Repo.Base.State.PlayerId].LinearVelocity;
                    targetAccel  = weapon.Comp.Session.PlayerDummyTargets[weapon.Comp.Data.Repo.Base.State.PlayerId].Acceleration;
                }
                else
                {
                    var cube       = target.Entity as MyCubeBlock;
                    var topMostEnt = cube != null ? cube.CubeGrid : target.Entity;

                    if (target.Projectile != null)
                    {
                        targetLinVel = target.Projectile.Velocity;
                        targetAccel  = target.Projectile.AccelVelocity;
                    }
                    else if (topMostEnt?.Physics != null)
                    {
                        targetLinVel = topMostEnt.Physics.LinearVelocity;
                        targetAccel  = topMostEnt.Physics.LinearAcceleration;
                    }
                }
                if (Vector3D.IsZero(targetLinVel, 5E-03))
                {
                    targetLinVel = Vector3.Zero;
                }
                if (Vector3D.IsZero(targetAccel, 5E-03))
                {
                    targetAccel = Vector3.Zero;
                }
                targetPos = TrajectoryEstimation(weapon, targetCenter, targetLinVel, targetAccel, out validEstimate);
            }
            else
            {
                targetPos = targetCenter;
            }

            weapon.Target.TargetPos = targetPos;

            double rangeToTargetSqr;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTargetSqr);

            var targetDir    = targetPos - weapon.MyPivotPos;
            var readyToTrack = validEstimate && !weapon.Comp.ResettingSubparts && (weapon.Comp.Data.Repo.Base.State.TrackingReticle || rangeToTargetSqr <= weapon.MaxTargetDistanceSqr && rangeToTargetSqr >= weapon.MinTargetDistanceSqr);

            var locked     = true;
            var isTracking = false;

            if (readyToTrack && weapon.Comp.Data.Repo.Base.State.Control != CompStateValues.ControlMode.Camera)
            {
                if (MathFuncs.WeaponLookAt(weapon, ref targetDir, rangeToTargetSqr, true, false, out isTracking))
                {
                    weapon.ReturingHome = false;
                    locked = false;
                    weapon.AimBarrel();

                    /*
                     * weapon.LastRotateTick = weapon.System.Session.Tick;
                     * if (!weapon.Rotating)
                     *  weapon.System.Session.RotateWeapons.Add(weapon);
                     */
                }
            }

            weapon.Rotating = !locked;

            if (weapon.Comp.Data.Repo.Base.State.Control == CompStateValues.ControlMode.Camera)
            {
                return(isTracking);
            }

            var isAligned = false;

            if (isTracking)
            {
                isAligned = locked || MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotDir, ref targetDir, weapon.AimingTolerance);
            }

            var wasAligned = weapon.Target.IsAligned;

            weapon.Target.IsAligned = isAligned;
            var alignedChange = wasAligned != isAligned;

            if (weapon.System.DesignatorWeapon && weapon.System.Session.IsServer && alignedChange)
            {
                for (int i = 0; i < weapon.Comp.Platform.Weapons.Length; i++)
                {
                    var w = weapon.Comp.Platform.Weapons[i];
                    if (isAligned && !w.System.DesignatorWeapon)
                    {
                        w.Target.Reset(weapon.System.Session.Tick, Target.States.Designator);
                    }
                    else if (!isAligned && w.System.DesignatorWeapon)
                    {
                        w.Target.Reset(weapon.System.Session.Tick, Target.States.Designator);
                    }
                }
            }
            targetLock = isTracking && weapon.Target.IsAligned;
            return(isTracking);
        }
Ejemplo n.º 12
0
        internal bool GetTargetState(Session s)
        {
            var ai         = s.TrackingAi;
            var validFocus = false;
            var size0      = s.Settings.Enforcement.ShipSizes[0];
            var size1      = s.Settings.Enforcement.ShipSizes[1];
            var size2      = s.Settings.Enforcement.ShipSizes[2];
            var size3      = s.Settings.Enforcement.ShipSizes[3];
            var size4      = s.Settings.Enforcement.ShipSizes[4];
            var size5      = s.Settings.Enforcement.ShipSizes[5];
            var size6      = s.Settings.Enforcement.ShipSizes[6];

            if (s.Tick - MasterUpdateTick > 300 || MasterUpdateTick < 300 && _masterTargets.Count == 0)
            {
                BuildMasterCollections(ai);
            }

            for (int i = 0; i < ai.Construct.Data.Repo.FocusData.Target.Length; i++)
            {
                var      targetId = ai.Construct.Data.Repo.FocusData.Target[i];
                float    offenseRating;
                MyEntity target;
                if (targetId <= 0 || !MyEntities.TryGetEntityById(targetId, out target) || !_masterTargets.TryGetValue(target, out offenseRating))
                {
                    continue;
                }
                validFocus = true;
                if (!s.Tick20)
                {
                    continue;
                }
                var grid      = target as MyCubeGrid;
                var partCount = 1;
                var largeGrid = false;
                var smallGrid = false;
                if (grid != null)
                {
                    largeGrid = grid.GridSizeEnum == MyCubeSize.Large;
                    smallGrid = !largeGrid;
                    GridAi  targetAi;
                    GridMap gridMap;
                    if (s.GridToMasterAi.TryGetValue(grid, out targetAi))
                    {
                        partCount = targetAi.Construct.BlockCount;
                    }
                    else if (s.GridToInfoMap.TryGetValue(grid, out gridMap))
                    {
                        partCount = gridMap.MostBlocks;
                    }
                }

                var targetVel = target.Physics?.LinearVelocity ?? Vector3.Zero;
                if (MyUtils.IsZero(targetVel, 1E-01F))
                {
                    targetVel = Vector3.Zero;
                }
                var targetDir    = Vector3D.Normalize(targetVel);
                var targetRevDir = -targetDir;
                var targetPos    = target.PositionComp.WorldAABB.Center;
                var myPos        = ai.MyGrid.PositionComp.WorldAABB.Center;
                var myHeading    = Vector3D.Normalize(myPos - targetPos);

                if ((size6.LargeGrid && largeGrid || !size6.LargeGrid && smallGrid) && partCount > size6.BlockCount)
                {
                    ai.TargetState[i].Size = 6;
                }
                else if ((size5.LargeGrid && largeGrid || !size5.LargeGrid && smallGrid) && partCount > size5.BlockCount)
                {
                    ai.TargetState[i].Size = 5;
                }
                else if ((size4.LargeGrid && largeGrid || !size4.LargeGrid && smallGrid) && partCount > size4.BlockCount)
                {
                    ai.TargetState[i].Size = 4;
                }
                else if ((size3.LargeGrid && largeGrid || !size3.LargeGrid && smallGrid) && partCount > size3.BlockCount)
                {
                    ai.TargetState[i].Size = 3;
                }
                else if ((size2.LargeGrid && largeGrid || !size2.LargeGrid && smallGrid) && partCount > size2.BlockCount)
                {
                    ai.TargetState[i].Size = 2;
                }
                else if ((size1.LargeGrid && largeGrid || !size1.LargeGrid && smallGrid) && partCount > size1.BlockCount)
                {
                    ai.TargetState[i].Size = 1;
                }
                else
                {
                    ai.TargetState[i].Size = 0;
                }

                ai.TargetState[i].SizeExtended = partCount / (largeGrid ? 100f : 500f);

                var intercept = MathFuncs.IsDotProductWithinTolerance(ref targetDir, ref myHeading, s.ApproachDegrees);
                var retreat   = MathFuncs.IsDotProductWithinTolerance(ref targetRevDir, ref myHeading, s.ApproachDegrees);
                if (intercept)
                {
                    ai.TargetState[i].Engagement = 0;
                }
                else if (retreat)
                {
                    ai.TargetState[i].Engagement = 1;
                }
                else
                {
                    ai.TargetState[i].Engagement = 2;
                }

                var distanceFromCenters = Vector3D.Distance(ai.MyGrid.PositionComp.WorldAABB.Center, target.PositionComp.WorldAABB.Center);
                distanceFromCenters           -= ai.MyGrid.PositionComp.LocalVolume.Radius;
                distanceFromCenters           -= target.PositionComp.LocalVolume.Radius;
                distanceFromCenters            = distanceFromCenters <= 0 ? 0 : distanceFromCenters;
                ai.TargetState[i].RealDistance = distanceFromCenters;

                var distPercent = (distanceFromCenters / ai.MaxTargetingRange) * 100;
                if (distPercent > 95)
                {
                    ai.TargetState[i].Distance = 9;
                }
                else if (distPercent > 90)
                {
                    ai.TargetState[i].Distance = 8;
                }
                else if (distPercent > 80)
                {
                    ai.TargetState[i].Distance = 7;
                }
                else if (distPercent > 70)
                {
                    ai.TargetState[i].Distance = 6;
                }
                else if (distPercent > 60)
                {
                    ai.TargetState[i].Distance = 5;
                }
                else if (distPercent > 50)
                {
                    ai.TargetState[i].Distance = 4;
                }
                else if (distPercent > 40)
                {
                    ai.TargetState[i].Distance = 3;
                }
                else if (distPercent > 30)
                {
                    ai.TargetState[i].Distance = 2;
                }
                else if (distPercent > 20)
                {
                    ai.TargetState[i].Distance = 1;
                }
                else if (distPercent > 0)
                {
                    ai.TargetState[i].Distance = 0;
                }
                else
                {
                    ai.TargetState[i].Distance = -1;
                }

                var speed = Math.Round(target.Physics?.Speed ?? 0, 1);
                if (speed <= 0)
                {
                    ai.TargetState[i].Speed = -1;
                }
                else
                {
                    var speedPercent = (speed / s.MaxEntitySpeed) * 100;
                    if (speedPercent > 95)
                    {
                        ai.TargetState[i].Speed = 9;
                    }
                    else if (speedPercent > 90)
                    {
                        ai.TargetState[i].Speed = 8;
                    }
                    else if (speedPercent > 80)
                    {
                        ai.TargetState[i].Speed = 7;
                    }
                    else if (speedPercent > 70)
                    {
                        ai.TargetState[i].Speed = 6;
                    }
                    else if (speedPercent > 60)
                    {
                        ai.TargetState[i].Speed = 5;
                    }
                    else if (speedPercent > 50)
                    {
                        ai.TargetState[i].Speed = 4;
                    }
                    else if (speedPercent > 40)
                    {
                        ai.TargetState[i].Speed = 3;
                    }
                    else if (speedPercent > 30)
                    {
                        ai.TargetState[i].Speed = 2;
                    }
                    else if (speedPercent > 20)
                    {
                        ai.TargetState[i].Speed = 1;
                    }
                    else if (speedPercent > 0.3)
                    {
                        ai.TargetState[i].Speed = 0;
                    }
                    else
                    {
                        ai.TargetState[i].Speed = -1;
                    }
                }

                MyTuple <bool, bool, float, float, float, int> shieldInfo = new MyTuple <bool, bool, float, float, float, int>();
                if (s.ShieldApiLoaded)
                {
                    shieldInfo = s.SApi.GetShieldInfo(target);
                }
                if (shieldInfo.Item1)
                {
                    var shieldPercent = shieldInfo.Item5;
                    if (shieldPercent > 95)
                    {
                        ai.TargetState[i].ShieldHealth = 9;
                    }
                    else if (shieldPercent > 90)
                    {
                        ai.TargetState[i].ShieldHealth = 8;
                    }
                    else if (shieldPercent > 80)
                    {
                        ai.TargetState[i].ShieldHealth = 7;
                    }
                    else if (shieldPercent > 70)
                    {
                        ai.TargetState[i].ShieldHealth = 6;
                    }
                    else if (shieldPercent > 60)
                    {
                        ai.TargetState[i].ShieldHealth = 5;
                    }
                    else if (shieldPercent > 50)
                    {
                        ai.TargetState[i].ShieldHealth = 4;
                    }
                    else if (shieldPercent > 40)
                    {
                        ai.TargetState[i].ShieldHealth = 3;
                    }
                    else if (shieldPercent > 30)
                    {
                        ai.TargetState[i].ShieldHealth = 2;
                    }
                    else if (shieldPercent > 20)
                    {
                        ai.TargetState[i].ShieldHealth = 1;
                    }
                    else if (shieldPercent > 0)
                    {
                        ai.TargetState[i].ShieldHealth = 0;
                    }
                    else
                    {
                        ai.TargetState[i].ShieldHealth = -1;
                    }
                }
                else
                {
                    ai.TargetState[i].ShieldHealth = -1;
                }

                var friend = false;
                if (grid != null && grid.BigOwners.Count != 0)
                {
                    var relation = MyIDModule.GetRelationPlayerBlock(ai.AiOwner, grid.BigOwners[0], MyOwnershipShareModeEnum.Faction);
                    if (relation == MyRelationsBetweenPlayerAndBlock.FactionShare || relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.Friends)
                    {
                        friend = true;
                    }
                }

                if (friend)
                {
                    ai.TargetState[i].ThreatLvl = -1;
                }
                else
                {
                    int shieldBonus = 0;
                    if (s.ShieldApiLoaded)
                    {
                        var myShieldInfo = s.SApi.GetShieldInfo(ai.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;
                        }
                    }

                    if (offenseRating > 5)
                    {
                        ai.TargetState[i].ThreatLvl = shieldBonus < 0 ? 8 : 9;
                    }
                    else if (offenseRating > 4)
                    {
                        ai.TargetState[i].ThreatLvl = 8 + shieldBonus;
                    }
                    else if (offenseRating > 3)
                    {
                        ai.TargetState[i].ThreatLvl = 7 + shieldBonus;
                    }
                    else if (offenseRating > 2)
                    {
                        ai.TargetState[i].ThreatLvl = 6 + shieldBonus;
                    }
                    else if (offenseRating > 1)
                    {
                        ai.TargetState[i].ThreatLvl = 5 + shieldBonus;
                    }
                    else if (offenseRating > 0.5)
                    {
                        ai.TargetState[i].ThreatLvl = 4 + shieldBonus;
                    }
                    else if (offenseRating > 0.25)
                    {
                        ai.TargetState[i].ThreatLvl = 3 + shieldBonus;
                    }

                    else if (offenseRating > 0.125)
                    {
                        ai.TargetState[i].ThreatLvl = 2 + shieldBonus;
                    }
                    else if (offenseRating > 0.0625)
                    {
                        ai.TargetState[i].ThreatLvl = 1 + shieldBonus;
                    }
                    else if (offenseRating > 0)
                    {
                        ai.TargetState[i].ThreatLvl = shieldBonus > 0 ? 1 : 0;
                    }
                    else
                    {
                        ai.TargetState[i].ThreatLvl = -1;
                    }
                }
            }
            return(validFocus);
        }
Ejemplo n.º 13
0
        internal static void LeadTarget(Weapon weapon, MyEntity target, out Vector3D targetPos, out bool couldHit, out bool willHit)
        {
            var vel            = target.Physics.LinearVelocity;
            var accel          = target.Physics.LinearAcceleration;
            var trackingWeapon = weapon.TurretMode || weapon.Comp.TrackingWeapon == null ? weapon : weapon.Comp.TrackingWeapon;

            var box = target.PositionComp.LocalAABB;
            var obb = new MyOrientedBoundingBoxD(box, target.PositionComp.WorldMatrixRef);

            var validEstimate = true;
            var advancedMode  = weapon.ActiveAmmoDef.AmmoDef.Trajectory.AccelPerSec > 0 || weapon.Comp.Ai.InPlanetGravity && weapon.ActiveAmmoDef.AmmoDef.Const.FeelsGravity;

            if (!weapon.ActiveAmmoDef.AmmoDef.Const.IsBeamWeapon && weapon.ActiveAmmoDef.AmmoDef.Const.DesiredProjectileSpeed > 0)
            {
                targetPos = TrajectoryEstimation(weapon, obb.Center, vel, accel, out validEstimate, true, advancedMode);
            }
            else
            {
                targetPos = obb.Center;
            }

            obb.Center       = targetPos;
            weapon.TargetBox = obb;

            var obbAbsMax   = obb.HalfExtent.AbsMax();
            var maxRangeSqr = obbAbsMax + weapon.MaxTargetDistance;
            var minRangeSqr = obbAbsMax + weapon.MinTargetDistance;

            maxRangeSqr *= maxRangeSqr;
            minRangeSqr *= minRangeSqr;
            double rangeToTarget;

            Vector3D.DistanceSquared(ref targetPos, ref weapon.MyPivotPos, out rangeToTarget);
            couldHit = validEstimate && rangeToTarget <= maxRangeSqr && rangeToTarget >= minRangeSqr;

            bool canTrack = false;

            if (validEstimate && rangeToTarget <= maxRangeSqr && rangeToTarget >= minRangeSqr)
            {
                var targetDir = targetPos - weapon.MyPivotPos;
                if (weapon == trackingWeapon)
                {
                    double checkAzimuth;
                    double checkElevation;

                    MathFuncs.GetRotationAngles(ref targetDir, ref weapon.WeaponConstMatrix, out checkAzimuth, out checkElevation);

                    var azConstraint = Math.Min(weapon.MaxAzToleranceRadians, Math.Max(weapon.MinAzToleranceRadians, checkAzimuth));
                    var elConstraint = Math.Min(weapon.MaxElToleranceRadians, Math.Max(weapon.MinElToleranceRadians, checkElevation));

                    Vector3D constraintVector;
                    Vector3D.CreateFromAzimuthAndElevation(azConstraint, elConstraint, out constraintVector);
                    Vector3D.Rotate(ref constraintVector, ref weapon.WeaponConstMatrix, out constraintVector);

                    var testRay = new RayD(ref weapon.MyPivotPos, ref constraintVector);
                    if (obb.Intersects(ref testRay) != null)
                    {
                        canTrack = true;
                    }

                    if (weapon.Comp.Debug)
                    {
                        weapon.LimitLine = new LineD(weapon.MyPivotPos, weapon.MyPivotPos + (constraintVector * weapon.ActiveAmmoDef.AmmoDef.Const.MaxTrajectory));
                    }
                }
                else
                {
                    canTrack = MathFuncs.IsDotProductWithinTolerance(ref weapon.MyPivotFwd, ref targetDir, weapon.AimingTolerance);
                }
            }
            willHit = canTrack;
        }