示例#1
0
        public static List <IMySlimBlock> GetBlocksOnRay(this IMyCubeGrid Grid, Vector3D From, Vector3D To)
        {
            List <IMySlimBlock> Blocks         = new List <IMySlimBlock>();
            List <Vector3I>     BlockPositions = new List <Vector3I>();

            Grid.RayCastCells(From, To, BlockPositions);
            foreach (Vector3I Position in BlockPositions)
            {
                IMySlimBlock Block = Grid.GetCubeBlock(Position);
                if (Block != null)
                {
                    Blocks.Add(Block);
                }
            }
            return(Blocks);
        }
        public static void ApplyRegularDamage(IMyCubeGrid cubeGrid, Vector3D startCoords, Vector3D endCoords, float damageAmount, long damageOwner)
        {
            var newStartCoords = Vector3D.Normalize(startCoords - endCoords) * 50 + endCoords;
            var newEndCoords   = Vector3D.Normalize(endCoords - startCoords) * 50 + endCoords;
            var cellList       = new List <Vector3I>();

            cubeGrid.RayCastCells(newStartCoords, newEndCoords, cellList);

            IMySlimBlock closestBlock     = null;
            double       closestBlockDist = 0;

            foreach (var cell in cellList)
            {
                var block = cubeGrid.GetCubeBlock(cell);

                if (block == null)
                {
                    continue;
                }

                var blockPosition = Vector3D.Zero;
                block.ComputeWorldCenter(out blockPosition);
                var thisBlockDist = Vector3D.Distance(blockPosition, endCoords);

                if (closestBlock == null)
                {
                    closestBlock     = block;
                    closestBlockDist = thisBlockDist;
                }

                if (thisBlockDist < closestBlockDist)
                {
                    closestBlock     = block;
                    closestBlockDist = thisBlockDist;
                }
            }

            if (closestBlock == null)
            {
                return;
            }

            closestBlock.DoDamage(damageAmount, MyStringHash.GetOrCompute("Laser"), true, null, damageOwner);
        }
示例#3
0
        private bool IsObstructing(IMyCubeGrid grid, Vector3D target)
        {
            List <Vector3I> cells = new List <Vector3I>();

            grid.RayCastCells(turretPosition, target, cells, null, true);
            if (cells.Count == 0)
            {
                return(false);
            }
            if (grid != myCubeBlock.CubeGrid)
            {
                return(true);
            }

            //myLogger.debugLog("testing " + cells.Count + " of " + grid.getBestName() + " cells for obstruction", "IsObstructing()");
            foreach (Vector3I pos in cells)
            {
                //if (pos == myCubeBlock.Position)
                //{
                //	//myLogger.debugLog("my cell: " + pos + ", world:" + grid.GridIntegerToWorld(pos), "IsObstructing()");
                //	continue;
                //}

                IMySlimBlock block = grid.GetCubeBlock(pos);
                if (block != null)
                {
                    if (block.FatBlock == null)
                    {
                        //myLogger.debugLog("obstructing slim pos = " + pos + ", world = " + grid.GridIntegerToWorld(pos), "IsObstructing()");
                    }
                    else
                    {
                        if (block.FatBlock == myCubeBlock)
                        {
                            continue;
                        }
                        //myLogger.debugLog("obstructing cube: " + block.FatBlock.DisplayNameText + ", pos = " + pos + ", world = " + grid.GridIntegerToWorld(pos), "IsObstructing()");
                    }
                    return(true);
                }
                //myLogger.debugLog("empty cell: " + pos + ", world:" + grid.GridIntegerToWorld(pos), "IsObstructing()");
            }
            return(false);
        }
示例#4
0
 public static void GetBlocksOnRay(this IMyCubeGrid Grid, ICollection <LineD> Rays, ICollection <IMySlimBlock> Blocks, Func <IMySlimBlock, bool> collect = null)
 {
     foreach (LineD Ray in Rays)
     {
         List <Vector3I> BlockPositions = new List <Vector3I>();
         Grid.RayCastCells(Ray.From, Ray.To, BlockPositions);
         foreach (Vector3I Position in BlockPositions)
         {
             IMySlimBlock Block = Grid.GetCubeBlock(Position);
             if (Block == null)
             {
                 continue;
             }
             if (collect == null || collect(Block))
             {
                 Blocks.Add(Block);
             }
         }
     }
 }
        public static void ApplyPenetrativeDamage(IMyCubeGrid cubeGrid, Vector3D startCoords, Vector3D endCoords, float damageAmount, long damageOwner, double penetrateDistance)
        {
            var newStartCoords = Vector3D.Normalize(startCoords - endCoords) * 50 + endCoords;
            var newEndCoords   = Vector3D.Normalize(endCoords - startCoords) * penetrateDistance + endCoords;
            var cellList       = new List <Vector3I>();

            cubeGrid.RayCastCells(newStartCoords, newEndCoords, cellList);

            var blockList = new List <IMySlimBlock>();

            foreach (var cell in cellList)
            {
                var block = cubeGrid.GetCubeBlock(cell);

                if (block == null)
                {
                    continue;
                }

                var blockPosition = Vector3D.Zero;
                block.ComputeWorldCenter(out blockPosition);
                var thisBlockDist = Vector3D.Distance(blockPosition, endCoords);

                if (thisBlockDist < penetrateDistance)
                {
                    blockList.Add(block);
                }
            }

            foreach (var targetBlock in blockList)
            {
                if (targetBlock == null)
                {
                    continue;
                }

                targetBlock.DoDamage(damageAmount, MyStringHash.GetOrCompute("Laser"), true, null, damageOwner);
            }
        }
        public static IMySlimBlock GetClosestBlock(Vector3D fromCoords, Vector3D coords, IMyCubeGrid cubeGrid)
        {
            IMySlimBlock closestBlock    = null;
            double       closestDistance = 0;
            Vector3D     closestPosition = Vector3D.Zero;

            var directionToGridCenter = Vector3D.Normalize(cubeGrid.GetPosition() - coords);
            var toCoords = directionToGridCenter * 1500 + coords;
            var cellHits = new List <Vector3I>();

            cubeGrid.RayCastCells(coords, toCoords, cellHits);

            foreach (var cell in cellHits)
            {
                var thisBlock = cubeGrid.GetCubeBlock(cell);

                if (thisBlock == null)
                {
                    continue;
                }

                var thisBlockPos = Vector3D.Zero;
                thisBlock.ComputeWorldCenter(out thisBlockPos);
                var distance = Vector3D.Distance(coords, thisBlockPos);

                if (closestBlock == null)
                {
                    closestBlock    = thisBlock;
                    closestDistance = distance;
                    closestPosition = thisBlockPos;
                    continue;
                }

                if (distance < closestDistance)
                {
                    closestBlock    = thisBlock;
                    closestDistance = distance;
                    closestPosition = thisBlockPos;
                }
            }

            if (closestBlock != null)
            {
                return(closestBlock);
            }

            var blockList = new List <IMySlimBlock>();

            cubeGrid.GetBlocks(blockList);

            foreach (var block in blockList)
            {
                var thisBlockPos = Vector3D.Zero;
                block.ComputeWorldCenter(out thisBlockPos);
                var distance = Vector3D.Distance(coords, thisBlockPos);

                if (closestBlock == null)
                {
                    closestBlock    = block;
                    closestDistance = distance;
                    closestPosition = thisBlockPos;
                    continue;
                }

                if (distance < closestDistance)
                {
                    closestBlock    = block;
                    closestDistance = distance;
                    closestPosition = thisBlockPos;
                }
            }

            return(closestBlock);
        }
示例#7
0
        /// <summary>
        /// <para>Test for entities intersecting a line segment.</para>
        /// </summary>
        /// <param name="world">Line to test for entities</param>
        /// <param name="pointOfIntersection">the point of contact between Line and intersecting entity</param>
        /// <param name="collect">Ignore entity if function returns false. Not tested against IMyCubeBlock</param>
        /// <param name="collect_CubeBlock">If null, do not ignore any IMyCubeBlock. Ignore IMyCubeBlock if function returns false</param>
        /// <param name="sort">entities will be sorted according to results of this function</param>
        /// <returns>An entity intersecting the Line</returns>
        /// <remarks>
        /// <para>For IMyCubeGrid, if a cell the line passes through is occupied, the cell is considered to be the point of intersection</para>
        /// <para>For entities that are not IMyCubeGrid, Line will be tested against IMyEntity.WorldVolume</para>
        /// </remarks>
        public static IMyEntity EntityOnLine(LineD world, out Vector3D?pointOfIntersection, Func <IMyEntity, bool> collect, Func <IMyCubeBlock, bool> collect_CubeBlock = null, Func <IMyEntity, double> sort = null)
        {
            if (collect == null)
            {
                throw new ArgumentNullException("collect");
            }

            // Get entities in AABB
            Vector3D[]              points         = { world.From, world.To };
            BoundingBoxD            AABB           = BoundingBoxD.CreateFromPoints(points);
            ICollection <IMyEntity> entitiesInAABB = MyAPIGateway.Entities.GetEntitiesInAABB_Safe(ref AABB);

            RayD worldRay = new RayD(world.From, world.Direction);

            if (sort != null)
            {
                SortedDictionary <double, IMyEntity> sortedEntities = new SortedDictionary <double, IMyEntity>();
                foreach (IMyEntity entity in entitiesInAABB)
                {
                    // filter entities
                    if (entity is IMyCubeBlock || !collect(entity))
                    {
                        continue;
                    }

                    sortedEntities.Add(sort(entity), entity);
                }
                entitiesInAABB = sortedEntities.Values;
            }

            foreach (IMyEntity entity in entitiesInAABB)
            {
                if (sort == null)
                {
                    // filter entities
                    if (entity is IMyCubeBlock || !collect(entity))
                    {
                        continue;
                    }
                }

                // ray cast
                IMyCubeGrid entityAsGrid = entity as IMyCubeGrid;
                if (entityAsGrid != null)
                {
                    // TODO: test GetLineIntersectionExact...

                    List <Vector3I> rayCastCells = new List <Vector3I>();
                    entityAsGrid.RayCastCells(world.From, world.To, rayCastCells);                     // I do not know if rayCastCells will be sorted

                    foreach (Vector3I cell in rayCastCells)
                    {
                        IMySlimBlock block = entityAsGrid.GetCubeBlock(cell);
                        if (block == null)
                        {
                            continue;
                        }
                        IMyCubeBlock FatBlock = block.FatBlock;
                        if (FatBlock == null)
                        {
                            pointOfIntersection = entityAsGrid.GridIntegerToWorld(cell);
                            return(entityAsGrid);
                        }
                        else
                        if (collect_CubeBlock == null || collect_CubeBlock(FatBlock))
                        {
                            pointOfIntersection = entityAsGrid.GridIntegerToWorld(cell);
                            return(entityAsGrid);
                        }
                    }
                }
                else
                {
                    double tMin, tMax;
                    if (entity.WorldVolume.IntersectRaySphere(worldRay, out tMin, out tMax))
                    {
                        pointOfIntersection = tMin * worldRay.Direction + worldRay.Position;
                        return(entity);
                    }
                }
            }

            pointOfIntersection = null;
            return(null);
        }
示例#8
0
        /// <summary>
        /// <para>Test line segment between startPosition and targetPosition for obstructing entities.</para>
        /// <para>Tests for obstructing voxel map, character, or grid.</para>
        ///// <param name="shortTest">When checking voxels, shortens the line by 1 m, needed to interact with an entity that may be on the surface of the voxel.</param>
        /// </summary>
        public static bool Obstructed <Tobstruct, Tignore>(LineD line, IEnumerable <Tobstruct> potentialObstructions, IEnumerable <Tignore> ignoreList, bool checkVoxel = true, bool checkPlanet = DefaultCheckPlanet)     //, bool shortTest = true)
            where Tobstruct : IMyEntity
            where Tignore : IMyEntity
        {
            Profiler.StartProfileBlock();
            // Test each entity
            foreach (IMyEntity entity in potentialObstructions)
            {
                if (entity.Closed)
                {
                    continue;
                }

                if (ignoreList != null && ignoreList.Contains((Tignore)entity))
                {
                    continue;
                }

                IMyCharacter asChar = entity as IMyCharacter;
                if (asChar != null)
                {
                    double distance;
                    if (entity.WorldAABB.Intersects(ref line, out distance))
                    {
                        Logger.DebugLog("obstructed by character: " + entity.getBestName());
                        Profiler.EndProfileBlock();
                        return(true);
                    }
                    continue;
                }

                IMyCubeGrid asGrid = entity as IMyCubeGrid;
                if (asGrid != null)
                {
                    if (!asGrid.Save)
                    {
                        continue;
                    }

                    ICollection <Vector3I> allHitCells;

                    List <Vector3I> hitCells = new List <Vector3I>();
                    asGrid.RayCastCells(line.From, line.To, hitCells);

                    allHitCells = hitCells;

                    foreach (Vector3I pos in allHitCells)
                    {
                        IMySlimBlock slim = asGrid.GetCubeBlock(pos);
                        if (slim == null)
                        {
                            continue;
                        }

                        MyCubeBlock fatblock = (MyCubeBlock)slim.FatBlock;

                        if (fatblock != null)
                        {
                            if (ignoreList != null && ignoreList.Contains((Tignore)slim.FatBlock))
                            {
                                continue;
                            }

                            Dictionary <string, MyEntitySubpart> subparts = fatblock.Subparts;
                            if (subparts != null && subparts.Count != 0)
                            {
                                Vector3     gsPosition = pos * asGrid.GridSize;
                                BoundingBox gsAABB;
                                fatblock.CombinedAABB(out gsAABB);
                                if (gsAABB.Contains(gsPosition) == ContainmentType.Disjoint)
                                {
                                    continue;
                                }
                            }
                        }

                        Logger.DebugLog("obstructed by block: " + slim.getBestName() + " on " + slim.CubeGrid.DisplayName + ", id: " + slim.CubeGrid.EntityId);
                        Profiler.EndProfileBlock();
                        return(true);
                    }
                }
            }

            if (checkVoxel)
            {
                // Voxel Test
                MyVoxelBase hitVoxel;
                Vector3D    hitPosition;
                if (RayCastVoxels(line, out hitVoxel, out hitPosition, checkPlanet))
                {
                    Logger.DebugLog("obstructed by voxel: " + hitVoxel + " at " + hitPosition);
                    Profiler.EndProfileBlock();
                    return(true);
                }
            }

            // no obstruction found
            Profiler.EndProfileBlock();
            return(false);
        }