示例#1
0
        private void HandleRaycastOutput(IHitInfo info)
        {
            if (info?.HitEntity is IMyVoxelBase)
            {
                if (Definition.VoxelDamageMultiplier <= 0)
                {
                    info = null;
                }
                else
                {
                    info = new RaycastShortcuts.ExtraHitInfo()
                    {
                        Position  = info.Position,
                        HitEntity = ((MyVoxelBase)info.HitEntity)?.RootVoxel ?? info.HitEntity,
                        Normal    = info.Normal,
                        Fraction  = (float)((info.Position - _dispatchedRay.From).Dot(_dispatchedRay.Direction) /
                                            (_dispatchedRay.Length * _dispatchedRay.Length))
                    };
                }
            }

            if (info != null)
            {
                _raycastResult = new RaycastShortcuts.RaycastPrediction(info, _dispatchedRay, Definition.RaycastPrediction);
            }
            else
            {
                _raycastResult = null;
            }
        }
示例#2
0
        private bool findFirstNonNPC(List <IHitInfo> hits, out IHitInfo hit, bool findEnemies = false)
        {
            foreach (var elem in hits)
            {
                if (elem.HitEntity?.Name == null)
                {
                    continue;
                }
                if (elem.HitEntity.Name.StartsWith("npc_"))
                {
                    if (!findEnemies)
                    {
                        continue;
                    }
                    if (isEnemy(elem.HitEntity))
                    {
                        hit = elem;
                        return(true);
                    }

                    continue;
                }

                hit = elem;
                return(true);
            }

            hit = null;
            return(false);
        }
示例#3
0
        public static IMySlimBlock Block(this IHitInfo hit, Vector3 rayDirection, float maxPrediction = 10f)
        {
            if (hit == null)
            {
                return(null);
            }
            var fat = hit.HitEntity as IMyCubeBlock;

            if (fat != null)
            {
                return(fat.SlimBlock);
            }
            var grid = hit.HitEntity as IMyCubeGrid;

            if (grid == null)
            {
                return(null);
            }
            var local = Vector3.Transform(hit.Position, grid.WorldMatrixNormalizedInv);
            var test  = grid.GetCubeBlock(Vector3I.Round(local / grid.GridSize));

            if (test != null)
            {
                return(test);
            }
            return(grid.FirstBlock(hit.Position, hit.Position + maxPrediction * rayDirection));
        }
示例#4
0
 public void OnHitboxExit(IHitInfo hit)
 {
     if (hit is Stim)
     {
         RemoveStim((Stim)hit);
     }
 }
示例#5
0
 public void OnHitboxEnter(IHitInfo hit)
 {
     if (hit is Stim)
     {
         ReceiveStim(((Stim)hit));
     }
 }
示例#6
0
 bool IMyPhysics.CastRay(Vector3D from, Vector3D to, out IHitInfo hitInfo, uint raycastCollisionFilter, bool ignoreConvexShape)
 {
     Sandbox.Engine.Physics.MyPhysics.HitInfo hitinfo;
     var hit = Engine.Physics.MyPhysics.CastRay(from, to, out hitinfo, raycastCollisionFilter, ignoreConvexShape);
     hitInfo = hitinfo;
     return hit;
 }
示例#7
0
 private void GiveDamage(IHitInfo h)
 {
     try
     {
         itemComponent.GiveDamage(((HitInfo <IDamageable>)h).Get());
     }
     finally { }
 }
示例#8
0
 private void GiveDamage(IHitInfo h)
 {
     try
     {
         GiveDamage(((HitInfo <IDamageable>)h).Get());
     }
     finally { }
 }
示例#9
0
        bool IMyPhysics.CastRay(Vector3D from, Vector3D to, out IHitInfo hitInfo, uint raycastCollisionFilter, bool ignoreConvexShape)
        {
            Sandbox.Engine.Physics.MyPhysics.HitInfo hitinfo;
            var hit = Engine.Physics.MyPhysics.CastRay(from, to, out hitinfo, raycastCollisionFilter, ignoreConvexShape);

            hitInfo = hitinfo;
            return(hit);
        }
示例#10
0
 bool IMyPhysics.CastLongRay(Vector3D from, Vector3D to, out IHitInfo hitInfo, bool any)
 {
     var hitinfo = Engine.Physics.MyPhysics.CastLongRay(from, to, any);
     if( hitinfo.HasValue )
     {
         hitInfo = hitinfo;
         return true;
     }
     hitInfo = null;
     return false;
 }
示例#11
0
 bool IMyPhysics.CastRay(Vector3D from, Vector3D to, out IHitInfo hitInfo, int raycastFilterLayer)
 {
     var hit = Engine.Physics.MyPhysics.CastRay(from, to, raycastFilterLayer);
     if( hit.HasValue )
     {
         hitInfo = hit;
         return true;
     }
     hitInfo = null;
     return false;
 }
示例#12
0
        bool IMyPhysics.CastLongRay(Vector3D from, Vector3D to, out IHitInfo hitInfo, bool any)
        {
            var hitinfo = Engine.Physics.MyPhysics.CastLongRay(from, to, any);

            if (hitinfo.HasValue)
            {
                hitInfo = hitinfo;
                return(true);
            }
            hitInfo = null;
            return(false);
        }
示例#13
0
        bool IMyPhysics.CastRay(Vector3D from, Vector3D to, out IHitInfo hitInfo, int raycastFilterLayer)
        {
            var hit = Engine.Physics.MyPhysics.CastRay(from, to, raycastFilterLayer);

            if (hit.HasValue)
            {
                hitInfo = hit;
                return(true);
            }
            hitInfo = null;
            return(false);
        }
示例#14
0
        /// <summary>
        /// Tries to find a targeted grid within a given distance.
        /// </summary>
        public static bool TryGetTargetedGrid(LineD line, out IMyCubeGrid grid, out IHitInfo rayInfo)
        {
            grid    = null;
            rayInfo = null;

            if (PlyEnt != null)
            {
                MyAPIGateway.Physics.CastRay(line.From, line.To, out rayInfo, CollisionLayers.CollisionLayerWithoutCharacter);
                grid = rayInfo?.HitEntity.GetTopMostParent() as IMyCubeGrid;
            }

            return(grid != null);
        }
示例#15
0
 internal void TargetLostCallBack(IHitInfo hitInfo)
 {
     if (hitInfo?.HitEntity?.Physics != null && MyAi != null)
     {
         var hitEnt = (MyEntity)hitInfo.HitEntity;
         if (hitEnt != Target && hitEnt is MyVoxelBase)
         {
             if (++LosHits >= 2 && MyAi?.Construct.RootAi != null)
             {
                 MyAi.Construct.RootAi.NoTargetLos[Target] = MyAi.Session.Tick;
             }
         }
     }
 }
示例#16
0
        public void ManualShootRayCallBack(IHitInfo hitInfo)
        {
            Casting = false;
            var masterWeapon = TrackTarget ? this : Comp.TrackingWeapon;

            var grid = hitInfo.HitEntity as MyCubeGrid;

            if (grid != null)
            {
                if (grid.IsSameConstructAs(Comp.MyCube.CubeGrid))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed, false);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed, false);
                    }
                }
            }
        }
示例#17
0
            public RaycastPrediction(IHitInfo hit, LineD ray, float maxPrediction)
            {
                _hit           = hit;
                _ray           = ray;
                _hitPosition   = _hit.Position;
                _maxPrediction = maxPrediction;

                var root = hit?.HitEntity;

                while (root?.Parent != null)
                {
                    root = root.Parent;
                }
                _root = root;

                _block = null;
                // ReSharper disable once ExpressionIsAlwaysNull
                UpdateSlimBlock();
            }
示例#18
0
        internal bool NewResult(out IHitInfo cachedPlanetResult)
        {
            cachedPlanetResult = null;
            var thisTick = (uint)(MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds * Session.TickTimeDiv);

            if (HitInfo == null)
            {
                _miss++;
                return(false);
            }

            if (thisTick > RequestTick + _maxDelay)
            {
                return(false);
            }

            //Log.Line($"newResult: {thisTick} - {RequestTick} - {_maxDelay} - {RequestTick + _maxDelay} - {thisTick - (RequestTick + _maxDelay)}");
            cachedPlanetResult = HitInfo;
            return(true);
        }
示例#19
0
        internal void Results(IHitInfo info)
        {
            ResultTick = (uint)(MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds * Session.TickTimeDiv);
            if (info == null)
            {
                _miss++;
                HitInfo = null;
                return;
            }

            var voxel = info.HitEntity as MyVoxelBase;

            if (voxel?.RootVoxel is MyPlanet)
            {
                HitInfo = info;
                _miss   = 0;
                return;
            }
            _miss++;
            HitInfo = null;
        }
示例#20
0
        public void NormalShootRayCallBack(IHitInfo hitInfo)
        {
            Casting = false;
            var masterWeapon  = TrackTarget ? this : Comp.TrackingWeapon;
            var ignoreTargets = Target.IsProjectile || Target.Entity is IMyCharacter;
            var hitTopEnt     = (MyEntity)hitInfo.HitEntity?.GetTopMostParent();

            if (hitTopEnt == null)
            {
                if (ignoreTargets)
                {
                    return;
                }

                masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                if (masterWeapon != this)
                {
                    Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                }
                return;
            }

            var targetTopEnt = Target.Entity?.GetTopMostParent();

            if (targetTopEnt == null)
            {
                return;
            }

            var unexpectedHit = ignoreTargets || targetTopEnt != hitTopEnt;
            var topAsGrid     = hitTopEnt as MyCubeGrid;

            if (unexpectedHit)
            {
                if (topAsGrid == null)
                {
                    return;
                }

                if (topAsGrid.IsSameConstructAs(Comp.Ai.MyGrid))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return;
                }

                if (!GridAi.GridEnemy(Comp.Ai.MyOwner, topAsGrid))
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return;
                }
                return;
            }
            if (System.ClosestFirst && topAsGrid != null)
            {
                var maxChange = hitInfo.HitEntity.PositionComp.LocalAABB.HalfExtents.Min();
                var targetPos = Target.Entity.PositionComp.WorldMatrixRef.Translation;
                var weaponPos = MyPivotPos;

                double rayDist;
                Vector3D.Distance(ref weaponPos, ref targetPos, out rayDist);
                var newHitShortDist  = rayDist * (1 - hitInfo.Fraction);
                var distanceToTarget = rayDist * hitInfo.Fraction;

                var shortDistExceed  = newHitShortDist - Target.HitShortDist > maxChange;
                var escapeDistExceed = distanceToTarget - Target.OrigDistance > Target.OrigDistance;
                if (shortDistExceed || escapeDistExceed)
                {
                    masterWeapon.Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != this)
                    {
                        Target.Reset(Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                }
            }
        }
        public static bool CalculateLunarTravelPath(MySpawnGroupDefinition spawnGroup, Vector3D startCoords, out Vector3D startPathCoords, out Vector3D endPathCoords)
        {
            startPathCoords = Vector3D.Zero;
            endPathCoords   = Vector3D.Zero;
            SpawnResources.RefreshEntityLists();
            MyPlanet planet = SpawnResources.GetNearestPlanet(startCoords);

            if (planet == null)
            {
                return(false);
            }

            var planetEntity = planet as IMyEntity;

            for (int i = 0; i < Settings.SpaceCargoShips.MaxSpawnAttempts; i++)
            {
                var spawnAltitude = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinLunarSpawnHeight, (int)Settings.SpaceCargoShips.MaxLunarSpawnHeight);
                var abovePlayer   = SpawnResources.CreateDirectionAndTarget(planetEntity.GetPosition(), startCoords, startCoords, spawnAltitude);
                var midpointDist  = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistanceFromPlayer, (int)Settings.SpaceCargoShips.MaxPathDistanceFromPlayer);
                var pathMidpoint  = SpawnResources.GetRandomCompassDirection(abovePlayer, planet) * midpointDist + abovePlayer;
                var pathDist      = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistance, (int)Settings.SpaceCargoShips.MaxPathDistance);
                var pathDir       = SpawnResources.GetRandomCompassDirection(abovePlayer, planet);
                var pathHalfDist  = pathDist / 2;

                var tempPathStart = pathDir * pathHalfDist + pathMidpoint;
                pathDir = pathDir * -1;
                var tempPathEnd = pathDir * pathHalfDist + pathMidpoint;

                bool badPath = false;

                IHitInfo hitInfo = null;

                if (MyAPIGateway.Physics.CastLongRay(tempPathStart, tempPathEnd, out hitInfo, true) == true)
                {
                    continue;
                }


                foreach (var entity in SpawnResources.EntityList)
                {
                    if (Vector3D.Distance(tempPathStart, entity.GetPosition()) < Settings.SpaceCargoShips.MinSpawnDistFromEntities)
                    {
                        badPath = true;
                        break;
                    }
                }

                if (badPath == true)
                {
                    continue;
                }

                var upDir      = Vector3D.CalculatePerpendicularVector(pathDir);
                var pathMatrix = MatrixD.CreateWorld(tempPathStart, pathDir, upDir);

                foreach (var prefab in spawnGroup.Prefabs)
                {
                    double stepDistance    = 0;
                    var    tempPrefabStart = Vector3D.Transform((Vector3D)prefab.Position, pathMatrix);

                    while (stepDistance < pathDist)
                    {
                        stepDistance += Settings.SpaceCargoShips.PathCheckStep;
                        var pathCheckCoords = pathDir * stepDistance + tempPrefabStart;

                        if (SpawnResources.IsPositionInSafeZone(pathCheckCoords) == true || SpawnResources.IsPositionInGravity(pathCheckCoords, planet) == true)
                        {
                            badPath = true;
                            break;
                        }
                    }

                    if (badPath == true)
                    {
                        break;
                    }
                }

                if (badPath == true)
                {
                    continue;
                }

                startPathCoords = tempPathStart;
                endPathCoords   = tempPathEnd;

                return(true);
            }

            return(false);
        }
        public static bool CalculateRegularTravelPath(MySpawnGroupDefinition spawnGroup, Vector3D startCoords, out Vector3D startPathCoords, out Vector3D endPathCoords)
        {
            startPathCoords = Vector3D.Zero;
            endPathCoords   = Vector3D.Zero;
            SpawnResources.RefreshEntityLists();
            MyPlanet         planet         = SpawnResources.GetNearestPlanet(startCoords);
            List <IMyEntity> nearbyEntities = new List <IMyEntity>();

            for (int i = 0; i < Settings.SpaceCargoShips.MaxSpawnAttempts; i++)
            {
                var randDir = Vector3D.Normalize(MyUtils.GetRandomVector3D());

                var closestPathDist  = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistanceFromPlayer, (int)Settings.SpaceCargoShips.MaxPathDistanceFromPlayer);
                var closestPathPoint = randDir * closestPathDist + startCoords;

                bool tryInvertedDir = SpawnResources.IsPositionInGravity(closestPathPoint, planet);

                if (tryInvertedDir == true)
                {
                    randDir          = randDir * -1;
                    closestPathPoint = randDir * closestPathDist + startCoords;

                    if (SpawnResources.IsPositionInGravity(closestPathPoint, planet) == true)
                    {
                        continue;
                    }
                }

                var pathDist     = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistance, (int)Settings.SpaceCargoShips.MaxPathDistance);
                var pathDir      = Vector3D.Normalize(MyUtils.GetRandomPerpendicularVector(ref randDir));
                var pathHalfDist = pathDist / 2;

                var tempPathStart = pathDir * pathHalfDist + closestPathPoint;
                pathDir = pathDir * -1;
                var tempPathEnd = pathDir * pathHalfDist + closestPathPoint;

                bool badPath = false;

                IHitInfo hitInfo = null;

                if (MyAPIGateway.Physics.CastLongRay(tempPathStart, tempPathEnd, out hitInfo, true) == true)
                {
                    continue;
                }

                foreach (var entity in SpawnResources.EntityList)
                {
                    if (Vector3D.Distance(tempPathStart, entity.GetPosition()) < Settings.SpaceCargoShips.MinSpawnDistFromEntities)
                    {
                        badPath = true;
                        break;
                    }
                }

                if (badPath == true)
                {
                    continue;
                }

                var upDir      = Vector3D.CalculatePerpendicularVector(pathDir);
                var pathMatrix = MatrixD.CreateWorld(tempPathStart, pathDir, upDir);

                foreach (var prefab in spawnGroup.Prefabs)
                {
                    double stepDistance    = 0;
                    var    tempPrefabStart = Vector3D.Transform((Vector3D)prefab.Position, pathMatrix);

                    while (stepDistance < pathDist)
                    {
                        stepDistance += Settings.SpaceCargoShips.PathCheckStep;
                        var pathCheckCoords = pathDir * stepDistance + tempPrefabStart;

                        if (SpawnResources.IsPositionInSafeZone(pathCheckCoords) == true || SpawnResources.IsPositionInGravity(pathCheckCoords, planet) == true)
                        {
                            badPath = true;
                            break;
                        }
                    }

                    if (badPath == true)
                    {
                        break;
                    }
                }

                if (badPath == true)
                {
                    continue;
                }

                startPathCoords = tempPathStart;
                endPathCoords   = tempPathEnd;
                return(true);
            }

            return(false);
        }
示例#23
0
 public void Remove(IHitInfo hit)
 {
     hits.Remove(hit);
 }
示例#24
0
 public void Add(IHitInfo hit)
 {
     hit.Other = this;
     hits.Add(hit);
 }
示例#25
0
        internal static bool GetClosestHitableBlockOfType(ConcurrentCachingList <MyCubeBlock> cubes, GridAi ai, Target target, Vector3D currentPos, Vector3D targetLinVel, Vector3D targetAccel, ref BoundingSphereD waterSphere, Weapon w = null, bool checkPower = true)
        {
            var minValue  = double.MaxValue;
            var minValue0 = double.MaxValue;
            var minValue1 = double.MaxValue;
            var minValue2 = double.MaxValue;
            var minValue3 = double.MaxValue;

            MyCubeBlock newEntity   = null;
            MyCubeBlock newEntity0  = null;
            MyCubeBlock newEntity1  = null;
            MyCubeBlock newEntity2  = null;
            MyCubeBlock newEntity3  = null;
            var         bestCubePos = Vector3D.Zero;
            var         top5Count   = target.Top5.Count;
            var         testPos     = currentPos;
            var         top5        = target.Top5;
            IHitInfo    hitInfo     = null;

            for (int i = 0; i < cubes.Count + top5Count; i++)
            {
                ai.Session.BlockChecks++;
                var index = i < top5Count ? i : i - top5Count;
                var cube  = i < top5Count ? top5[index] : cubes[index];

                var grid = cube.CubeGrid;
                if (grid == null || grid.MarkedForClose)
                {
                    continue;
                }
                if (!(cube is IMyTerminalBlock) || cube.MarkedForClose || cube == newEntity || cube == newEntity0 || cube == newEntity1 || cube == newEntity2 || cube == newEntity3 || checkPower && !cube.IsWorking)
                {
                    continue;
                }

                var cubePos = grid.GridIntegerToWorld(cube.Position);
                var range   = cubePos - testPos;
                var test    = (range.X * range.X) + (range.Y * range.Y) + (range.Z * range.Z);

                if (ai.Session.WaterApiLoaded && waterSphere.Radius > 2 && waterSphere.Contains(cubePos) != ContainmentType.Disjoint)
                {
                    continue;
                }

                if (test < minValue3)
                {
                    IHitInfo hit      = null;
                    var      best     = test < minValue;
                    var      bestTest = false;
                    if (best)
                    {
                        if (w != null && !(!w.IsTurret && w.ActiveAmmoDef.AmmoDef.Trajectory.Smarts.OverideTarget))
                        {
                            ai.Session.CanShoot++;
                            Vector3D predictedPos;
                            if (Weapon.CanShootTarget(w, ref cubePos, targetLinVel, targetAccel, out predictedPos))
                            {
                                ai.Session.ClosestRayCasts++;
                                if (ai.Session.Physics.CastRay(testPos, cubePos, out hit, CollisionLayers.DefaultCollisionLayer))
                                {
                                    var hitEnt  = hit.HitEntity?.GetTopMostParent() as MyEntity;
                                    var hitGrid = hitEnt as MyCubeGrid;
                                    if (hitGrid != null && grid == hitGrid || hit.HitEntity is MyFloatingObject || hit.HitEntity is IMyCharacter || hitEnt != null && w.Comp.Ai.Targets.ContainsKey(hitEnt))
                                    {
                                        bestTest = true;
                                    }
                                }
                            }
                        }
                        else
                        {
                            bestTest = true;
                        }
                    }

                    if (best && bestTest)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = minValue;
                        newEntity0 = newEntity;
                        minValue   = test;

                        newEntity   = cube;
                        bestCubePos = cubePos;
                        hitInfo     = hit;
                    }
                    else if (test < minValue0)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = test;

                        newEntity0 = cube;
                    }
                    else if (test < minValue1)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = test;

                        newEntity1 = cube;
                    }
                    else if (test < minValue2)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = test;

                        newEntity2 = cube;
                    }
                    else
                    {
                        minValue3  = test;
                        newEntity3 = cube;
                    }
                }
            }
            top5.Clear();
            if (newEntity != null && hitInfo != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist * (1 - hitInfo.Fraction);
                var origDist  = rayDist * hitInfo.Fraction;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, hitInfo.Position, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else if (newEntity != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist;
                var origDist  = rayDist;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, bestCubePos, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else
            {
                target.Reset(ai.Session.Tick, Target.States.NoTargetsSeen, w == null);
            }

            if (newEntity0 != null)
            {
                top5.Add(newEntity0);
            }
            if (newEntity1 != null)
            {
                top5.Add(newEntity1);
            }
            if (newEntity2 != null)
            {
                top5.Add(newEntity2);
            }
            if (newEntity3 != null)
            {
                top5.Add(newEntity3);
            }

            return(top5.Count > 0);
        }
示例#26
0
        internal static bool GetClosestHitableBlockOfType(ConcurrentCachingList <MyCubeBlock> cubes, GridAi ai, Target target, Vector3D currentPos, Vector3D targetLinVel, Vector3D targetAccel, WeaponSystem system, Weapon w = null, bool checkPower = true)
        {
            var minValue  = double.MaxValue;
            var minValue0 = double.MaxValue;
            var minValue1 = double.MaxValue;
            var minValue2 = double.MaxValue;
            var minValue3 = double.MaxValue;

            MyCubeBlock newEntity   = null;
            MyCubeBlock newEntity0  = null;
            MyCubeBlock newEntity1  = null;
            MyCubeBlock newEntity2  = null;
            MyCubeBlock newEntity3  = null;
            var         bestCubePos = Vector3D.Zero;
            var         top5Count   = target.Top5.Count;
            var         testPos     = currentPos;
            var         top5        = target.Top5;
            IHitInfo    hitInfo     = null;
            var         notSelfHit  = false;

            for (int i = 0; i < cubes.Count + top5Count; i++)
            {
                ai.Session.BlockChecks++;
                var index = i < top5Count ? i : i - top5Count;
                var cube  = i < top5Count ? top5[index] : cubes[index];

                var grid = cube.CubeGrid;
                if (grid?.Physics == null || !grid.Physics.Enabled || grid.PositionComp == null)
                {
                    continue;
                }

                if (cube.MarkedForClose || checkPower && !cube.IsWorking || !(cube is IMyTerminalBlock) || cube == newEntity || cube == newEntity0 || cube == newEntity1 || cube == newEntity2 || cube == newEntity3)
                {
                    continue;
                }
                var cubePos = grid.GridIntegerToWorld(cube.Position);
                var range   = cubePos - testPos;
                var test    = (range.X * range.X) + (range.Y * range.Y) + (range.Z * range.Z);
                if (test < minValue3)
                {
                    IHitInfo hit      = null;
                    var      best     = test < minValue;
                    var      bestTest = false;
                    if (best)
                    {
                        if (w != null && !(!w.IsTurret && w.ActiveAmmoDef.AmmoDef.Trajectory.Smarts.OverideTarget))
                        {
                            ai.Session.CanShoot++;
                            var castRay = false;

                            Vector3D predictedPos;
                            Vector3D?hitPos;
                            if (Weapon.CanShootTarget(w, cubePos, targetLinVel, targetAccel, out predictedPos))
                            {
                                castRay = !w.HitOther || !GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref testPos, ref cubePos, out hitPos, w.Comp.MyCube, w.Comp.Ai);
                            }

                            if (castRay)
                            {
                                ai.Session.ClosestRayCasts++;
                                bestTest = MyAPIGateway.Physics.CastRay(testPos, cubePos, out hit, 15, true) && hit?.HitEntity == cube.CubeGrid;

                                if (hit == null && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf()) || (hit.HitEntity != ai.MyGrid))
                                {
                                    notSelfHit = true;
                                }
                            }
                        }
                        else
                        {
                            bestTest = true;
                        }
                    }
                    if (best && bestTest)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = minValue;
                        newEntity0 = newEntity;
                        minValue   = test;

                        newEntity   = cube;
                        bestCubePos = cubePos;
                        hitInfo     = hit;
                    }
                    else if (test < minValue0)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = test;

                        newEntity0 = cube;
                    }
                    else if (test < minValue1)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = test;

                        newEntity1 = cube;
                    }
                    else if (test < minValue2)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = test;

                        newEntity2 = cube;
                    }
                    else
                    {
                        minValue3  = test;
                        newEntity3 = cube;
                    }
                }
            }
            top5.Clear();
            if (newEntity != null && hitInfo != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist * (1 - hitInfo.Fraction);
                var origDist  = rayDist * hitInfo.Fraction;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, hitInfo.Position, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else if (newEntity != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist;
                var origDist  = rayDist;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, bestCubePos, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else
            {
                target.Reset(ai.Session.Tick, Target.States.NoTargetsSeen, w == null);
            }

            if (newEntity0 != null)
            {
                top5.Add(newEntity0);
            }
            if (newEntity1 != null)
            {
                top5.Add(newEntity1);
            }
            if (newEntity2 != null)
            {
                top5.Add(newEntity2);
            }
            if (newEntity3 != null)
            {
                top5.Add(newEntity3);
            }

            if (!notSelfHit && w != null)
            {
                w.HitOther = true;
            }

            return(hitInfo != null);
        }
示例#27
0
 public GrabInfo(IHitInfo info)
 {
     PhysicsEntity = info.HitEntity;
     worldPosition = info.Position;
 }
示例#28
0
        private void doValidMoment(bool skipCast, List <IHitInfo> hits, IMyCubeGrid grid, Vector3D forwardDir,
                                   bool hasTarget,
                                   Vector3D ownPos)
        {
            if (!skipCast)
            {
                cachedSurfaceHit = hits[0];
            }

            rotateRelativeToGround(cachedSurfaceHit.Normal, grid);

            drawDebugDir(animator.grid.WorldMatrix.Translation, forwardDir);

            if (hasTarget)
            {
                if (MainNPCLoop.ticks % 40 == 0)
                {
                    var distToTarget = CurrentMovementTarget - animator.grid.GetPosition();
                    intermediateTarget = getIntermediateMovementTarget(grid, CurrentMovementTarget, distToTarget.Length());
                }


                if (intermediateTarget.Equals(Vector3.Zero))
                {
                    intermediateTarget = CurrentMovementTarget;
                }

                drawDebugLine(grid.WorldMatrix.Translation, intermediateTarget);
                rotateToTarget(ownPos, grid, intermediateTarget);

                var dirToTarget = intermediateTarget - ownPos;
                dirToTarget.Normalize();

                var curDir        = grid.Physics.LinearVelocity;
                var relativeSpeed = curDir - cachedSurfaceHit.HitEntity.Physics.LinearVelocity;
                var speed         = getWantedSpeed();

                var correctedDir = dirToTarget * speed * 1.5 - curDir;
                correctedDir = projectOnPlane(correctedDir, cachedSurfaceHit.Normal);

                animator.relativeMoveSpeed = relativeSpeed.Length();

                var missingVector = dirToTarget * speed - grid.Physics.LinearVelocity;

                if (missingVector.Length() > 0.5f)
                {
                    drawDebugLine(grid.WorldMatrix.Translation, correctedDir);
                    correctedDir.Normalize();
                    grid.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, correctedDir * useForce, null,
                                          null);
                }


                //MyLog.Default.WriteLine("speeds: " + grid.Physics.Speed + " | " + grid.Physics.LinearVelocity + " | " + grid.Physics.LinearVelocityLocal);
            }

            if (MainNPCLoop.DEBUG)
            {
                animator.grid.Physics.DebugDraw();
            }
        }
示例#29
0
            public void NormalShootRayCallBack(IHitInfo hitInfo)
            {
                Weapon.Casting = false;
                var    masterWeapon          = Weapon.TrackTarget ? Weapon : Weapon.Comp.TrackingWeapon;
                var    ignoreTargets         = Weapon.Target.IsProjectile || Weapon.Target.Entity is IMyCharacter;
                var    trackingCheckPosition = Weapon.GetScope.CachedPos;
                double rayDist = 0;


                if (Weapon.System.Session.DebugLos)
                {
                    var hitPos = hitInfo.Position;
                    if (rayDist <= 0)
                    {
                        Vector3D.Distance(ref trackingCheckPosition, ref hitPos, out rayDist);
                    }

                    Weapon.System.Session.AddLosCheck(new Session.LosDebug {
                        Weapon = Weapon, HitTick = Weapon.System.Session.Tick, Line = new LineD(trackingCheckPosition, hitPos)
                    });
                }


                if (Weapon.Comp.Ai.ShieldNear)
                {
                    var targetPos = Weapon.Target.Projectile?.Position ?? Weapon.Target.Entity.PositionComp.WorldMatrixRef.Translation;
                    var targetDir = targetPos - trackingCheckPosition;
                    if (Weapon.HitFriendlyShield(trackingCheckPosition, targetPos, targetDir))
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFriendly);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFriendly);
                        }
                        return;
                    }
                }

                var hitTopEnt = (MyEntity)hitInfo?.HitEntity?.GetTopMostParent();

                if (hitTopEnt == null)
                {
                    if (ignoreTargets)
                    {
                        return;
                    }
                    masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckMiss);
                    if (masterWeapon != Weapon)
                    {
                        Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckMiss);
                    }
                    return;
                }

                var targetTopEnt = Weapon.Target.Entity?.GetTopMostParent();

                if (targetTopEnt == null)
                {
                    return;
                }

                var unexpectedHit = ignoreTargets || targetTopEnt != hitTopEnt;
                var topAsGrid     = hitTopEnt as MyCubeGrid;

                if (unexpectedHit)
                {
                    if (hitTopEnt is MyVoxelBase)
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckVoxel);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckVoxel);
                        }
                        return;
                    }

                    if (topAsGrid == null)
                    {
                        return;
                    }
                    if (Weapon.Target.Entity != null && (topAsGrid.IsSameConstructAs(Weapon.Comp.Ai.MyGrid) || !topAsGrid.DestructibleBlocks || topAsGrid.Immune || topAsGrid.GridGeneralDamageModifier <= 0))
                    {
                        var      hitPos = Weapon.Target.Entity.PositionComp.WorldAABB.Center;
                        Vector3D pos;
                        if (CheckSelfHit(Weapon, ref trackingCheckPosition, ref hitPos, out pos))
                        {
                            masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckSelfHit);
                            if (masterWeapon != Weapon)
                            {
                                Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckSelfHit);
                            }
                            return;
                        }
                        return;
                    }
                    if (!Session.GridEnemy(Weapon.Comp.Ai.AiOwner, topAsGrid))
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFriendly);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFriendly);
                        }
                        return;
                    }
                    return;
                }
                if (Weapon.System.ClosestFirst && topAsGrid != null && topAsGrid == targetTopEnt)
                {
                    var halfExtMin = topAsGrid.PositionComp.LocalAABB.HalfExtents.Min();
                    var minSize    = topAsGrid.GridSizeR * 8;
                    var maxChange  = halfExtMin > minSize ? halfExtMin : minSize;
                    var targetPos  = Weapon.Target.Entity.PositionComp.WorldAABB.Center;
                    var weaponPos  = trackingCheckPosition;

                    if (rayDist <= 0)
                    {
                        Vector3D.Distance(ref weaponPos, ref targetPos, out rayDist);
                    }
                    var newHitShortDist  = rayDist * (1 - hitInfo.Fraction);
                    var distanceToTarget = rayDist * hitInfo.Fraction;

                    var shortDistExceed  = newHitShortDist - Weapon.Target.HitShortDist > maxChange;
                    var escapeDistExceed = distanceToTarget - Weapon.Target.OrigDistance > Weapon.Target.OrigDistance;
                    if (shortDistExceed || escapeDistExceed)
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckDistOffset);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckDistOffset);
                        }
                    }
                }
            }
示例#30
0
            public void NormalShootRayCallBack(IHitInfo hitInfo)
            {
                Weapon.Casting = false;
                var masterWeapon  = Weapon.TrackTarget ? Weapon : Weapon.Comp.TrackingWeapon;
                var ignoreTargets = Weapon.Target.IsProjectile || Weapon.Target.Entity is IMyCharacter;

                double rayDist = 0;

                if (Weapon.Comp.Ai.ShieldNear)
                {
                    var targetPos = Weapon.Target.Projectile?.Position ?? Weapon.Target.Entity.PositionComp.WorldMatrixRef.Translation;
                    var targetDir = targetPos - Weapon.MyPivotPos;
                    if (Weapon.HitFriendlyShield(targetPos, targetDir))
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        }
                        return;
                    }
                }

                var hitTopEnt = (MyEntity)hitInfo?.HitEntity?.GetTopMostParent();

                if (hitTopEnt == null)
                {
                    if (ignoreTargets)
                    {
                        return;
                    }
                    masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                    if (masterWeapon != Weapon)
                    {
                        Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                    }
                    return;
                }

                var targetTopEnt = Weapon.Target.Entity?.GetTopMostParent();

                if (targetTopEnt == null)
                {
                    return;
                }

                var unexpectedHit = ignoreTargets || targetTopEnt != hitTopEnt;
                var topAsGrid     = hitTopEnt as MyCubeGrid;

                if (unexpectedHit)
                {
                    if (hitTopEnt is MyVoxelBase)
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        }
                        return;
                    }

                    if (topAsGrid == null)
                    {
                        return;
                    }

                    if (topAsGrid.IsSameConstructAs(Weapon.Comp.Ai.MyGrid))
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        }
                        return;
                    }

                    if (!Session.GridEnemy(Weapon.Comp.Ai.MyOwner, topAsGrid))
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        }
                        return;
                    }
                    return;
                }
                if (Weapon.System.ClosestFirst && topAsGrid != null && topAsGrid == targetTopEnt)
                {
                    var halfExtMin = topAsGrid.PositionComp.LocalAABB.HalfExtents.Min();
                    var minSize    = topAsGrid.GridSizeR * 8;
                    var maxChange  = halfExtMin > minSize ? halfExtMin : minSize;
                    var targetPos  = Weapon.Target.Entity.PositionComp.WorldMatrixRef.Translation;
                    var weaponPos  = Weapon.MyPivotPos;

                    if (rayDist <= 0)
                    {
                        Vector3D.Distance(ref weaponPos, ref targetPos, out rayDist);
                    }
                    var newHitShortDist  = rayDist * (1 - hitInfo.Fraction);
                    var distanceToTarget = rayDist * hitInfo.Fraction;

                    var shortDistExceed  = newHitShortDist - Weapon.Target.HitShortDist > maxChange;
                    var escapeDistExceed = distanceToTarget - Weapon.Target.OrigDistance > Weapon.Target.OrigDistance;
                    if (shortDistExceed || escapeDistExceed)
                    {
                        masterWeapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        if (masterWeapon != Weapon)
                        {
                            Weapon.Target.Reset(Weapon.Comp.Session.Tick, Target.States.RayCheckFailed);
                        }
                    }
                }
            }
示例#31
0
        internal bool GenerateHitInfo(Projectile p)
        {
            var count = p.Info.HitList.Count;

            if (count > 1)
            {
                p.Info.HitList.Sort((x, y) => GetEntityCompareDist(x, y, p.Info));
            }
            else
            {
                GetEntityCompareDist(p.Info.HitList[0], null, p.Info);
            }
            var pulseTrigger = false;

            for (int i = p.Info.HitList.Count - 1; i >= 0; i--)
            {
                var ent = p.Info.HitList[i];
                if (!ent.Hit)
                {
                    if (ent.PulseTrigger)
                    {
                        pulseTrigger = true;
                    }
                    p.Info.HitList.RemoveAtFast(i);
                    HitEntityPool.Return(ent);
                }
                else
                {
                    break;
                }
            }

            if (pulseTrigger)
            {
                p.Info.EwarAreaPulse  = true;
                p.DistanceToTravelSqr = p.Info.DistanceTraveled * p.Info.DistanceTraveled;
                p.Velocity            = Vector3D.Zero;
                p.Info.Hit.SurfaceHit = p.Position + p.Info.Direction * p.Info.ConsumableDef.Const.EwarTriggerRange;
                p.Info.Hit.LastHit    = p.Info.Hit.SurfaceHit;
                p.Info.HitList.Clear();
                return(false);
            }

            var finalCount = p.Info.HitList.Count;

            if (finalCount > 0)
            {
                var hitEntity = p.Info.HitList[0];

                if (hitEntity.EventType == Shield)
                {
                    var cube = hitEntity.Entity as MyCubeBlock;
                    if (cube?.CubeGrid?.Physics != null)
                    {
                        p.LastHitEntVel = cube.CubeGrid.Physics.LinearVelocity;
                    }
                }
                else if (hitEntity.Projectile != null)
                {
                    p.LastHitEntVel = hitEntity.Projectile?.Velocity;
                }
                else if (hitEntity.Entity?.Physics != null)
                {
                    p.LastHitEntVel = hitEntity.Entity?.Physics.LinearVelocity;
                }
                else
                {
                    p.LastHitEntVel = Vector3.Zero;
                }

                var grid = hitEntity.Entity as MyCubeGrid;

                IMySlimBlock hitBlock = null;
                Vector3D?    visualHitPos;
                if (grid != null)
                {
                    if (p.Info.ConsumableDef.Const.VirtualBeams)
                    {
                        hitBlock = hitEntity.Blocks[0];
                    }

                    IHitInfo hitInfo = null;
                    if (p.Info.System.Session.HandlesInput && hitEntity.HitPos.HasValue && Vector3D.DistanceSquared(hitEntity.HitPos.Value, p.Info.System.Session.CameraPos) < 22500 && p.Info.System.Session.CameraFrustrum.Contains(hitEntity.HitPos.Value) != ContainmentType.Disjoint)
                    {
                        var entSphere = hitEntity.Entity.PositionComp.WorldVolume;
                        var from      = hitEntity.Intersection.From + (hitEntity.Intersection.Direction * MyUtils.GetSmallestDistanceToSphereAlwaysPositive(ref hitEntity.Intersection.From, ref entSphere));
                        var to        = hitEntity.HitPos.Value + (hitEntity.Intersection.Direction * 3f);
                        p.Info.System.Session.Physics.CastRay(from, to, out hitInfo, 15);
                    }
                    visualHitPos = hitInfo?.HitEntity != null ? hitInfo.Position : hitEntity.HitPos;
                }
                else
                {
                    visualHitPos = hitEntity.HitPos;
                }

                p.Info.Hit = new Hit {
                    Block = hitBlock, Entity = hitEntity.Entity, LastHit = visualHitPos ?? Vector3D.Zero, SurfaceHit = visualHitPos ?? Vector3D.Zero, HitVelocity = p.LastHitEntVel ?? Vector3D.Zero, HitTick = p.Info.System.Session.Tick
                };
                if (p.EnableAv)
                {
                    p.Info.AvShot.LastHitShield = hitEntity.EventType == Shield;
                    p.Info.AvShot.Hit           = p.Info.Hit;
                }

                return(true);
            }
            return(false);
        }
示例#32
0
 public Destination(ref IHitInfo hitInfo)
 {
     Entity   = hitInfo.HitEntity;
     Position = hitInfo.Position - Entity.GetCentre();
 }