Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
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));
        }
Exemplo n.º 4
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);
        }