예제 #1
0
        public static bool IsAirtightBetweenPositions(IMyCubeGrid grid, Vector3I startPos, Vector3I endPos)
        {
            var b1 = grid.GetCubeBlock(startPos);
            var b2 = grid.GetCubeBlock(endPos);

            if (b1 == b2)
            {
                if (b1 != null)
                {
                    var def = b1.BlockDefinition as MyCubeBlockDefinition;

                    if (def != null)
                    {
                        return(IsAirtightFromDefinition(def, b1.BuildLevelRatio) == AirTightMode.SEALED);
                    }

                    return(false);
                }

                return(false);
            }

            if (b1 != null && IsAirtightBlock(b1, startPos, endPos - startPos))
            {
                return(true);
            }

            if (b2 != null)
            {
                return(IsAirtightBlock(b2, endPos, startPos - endPos));
            }

            return(false);
        }
예제 #2
0
        // TODO update this code when changed in game
        // all these are from Sandbox.Game.GameSystems.MyGridGasSystem
        // since that namespace is prohibited I have to copy it and convert it to work with modAPI

        private bool IsPressurized(IMyCubeGrid grid, Vector3I startPos, Vector3I endPos)
        {
            IMySlimBlock b1 = grid.GetCubeBlock(startPos);
            IMySlimBlock b2 = grid.GetCubeBlock(endPos);

            if (b1 == b2)
            {
                return(b1 != null && ((MyCubeBlockDefinition)b1.BlockDefinition).IsAirTight);
            }

            return((b1 != null && (((MyCubeBlockDefinition)b1.BlockDefinition).IsAirTight || IsPressurized(b1, startPos, endPos - startPos))) || (b2 != null && (((MyCubeBlockDefinition)b2.BlockDefinition).IsAirTight || IsPressurized(b2, endPos, startPos - endPos))));
        }
예제 #3
0
        /// <summary>
        /// Non-allocating version of Sandbox.Game.Entities.MyCubeGrid.GetBlocksInsideSphere()
        /// </summary>
        public void GetBlocksInsideSphere(IMyCubeGrid grid, List <IMySlimBlock> blockList, ref BoundingSphereD sphere)
        {
            if (grid.PositionComp != null)
            {
                MatrixD  matrix = grid.PositionComp.WorldMatrixNormalizedInv;
                Vector3D result;

                Vector3D.Transform(ref sphere.Center, ref matrix, out result);
                BoundingSphere localSphere = new BoundingSphere(result, (float)sphere.Radius);
                BoundingBox    boundingBox = BoundingBox.CreateFromSphere(localSphere);
                double         gridSizeR   = 1d / grid.GridSize;

                Vector3I searchMin = new Vector3I
                                     (
                    (int)Math.Round(boundingBox.Min.X * gridSizeR),
                    (int)Math.Round(boundingBox.Min.Y * gridSizeR),
                    (int)Math.Round(boundingBox.Min.Z * gridSizeR)
                                     );
                Vector3I searchMax = new Vector3I
                                     (
                    (int)Math.Round(boundingBox.Max.X * gridSizeR),
                    (int)Math.Round(boundingBox.Max.Y * gridSizeR),
                    (int)Math.Round(boundingBox.Max.Z * gridSizeR)
                                     );

                Vector3I start = Vector3I.Max(Vector3I.Min(searchMin, searchMax), grid.Min);
                Vector3I end   = Vector3I.Min(Vector3I.Max(searchMin, searchMax), grid.Max);

                var      gridIterator = new Vector3I_RangeIterator(ref start, ref end);
                Vector3I next         = gridIterator.Current;

                blockHashBuffer.Clear();

                while (gridIterator.IsValid())
                {
                    IMySlimBlock cube         = grid.GetCubeBlock(next);
                    float        gridSizeHalf = grid.GridSize / 2f;

                    if (cube != null)
                    {
                        var cubeBounds = new BoundingBox((cube.Min * grid.GridSize) - gridSizeHalf, (cube.Max * grid.GridSize) + gridSizeHalf);

                        if (cubeBounds.Intersects(localSphere))
                        {
                            blockHashBuffer.Add(cube);
                        }
                    }

                    gridIterator.GetNext(out next);
                }

                blockList.Clear();
                blockList.EnsureCapacity(blockHashBuffer.Count);

                foreach (IMySlimBlock block in blockHashBuffer)
                {
                    blockList.Add(block);
                }
            }
        }
        private void Cleanup()
        {
            HashSet <TargetEntity> remove = new HashSet <TargetEntity>();

            foreach (var item in m_particles)
            {
                IMyEntity entity;
                if (!MyAPIGateway.Entities.TryGetEntityById(item.TargetGridId, out entity))
                {
                    remove.Add(item);
                    continue;
                }

                IMyCubeGrid  grid      = entity as IMyCubeGrid;
                IMySlimBlock slimBlock = grid.GetCubeBlock(item.TargetPosition);
                if (slimBlock == null)
                {
                    remove.Add(item);
                    continue;
                }

                if (slimBlock.IsDestroyed || slimBlock.IsFullyDismounted || (slimBlock.FatBlock != null && slimBlock.FatBlock.Closed))
                {
                    remove.Add(item);
                    continue;
                }
            }

            foreach (var item in remove)
            {
                item.Unload();
                m_particles.Remove(item);
            }
        }
예제 #5
0
파일: Projector.cs 프로젝트: zrisher/ARMS
        private void Actual_OnBlockAdded(IMySlimBlock obj)
        {
            SeenHolo sh;

            if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh))
            {
                Log.DebugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR);
                obj.CubeGrid.OnBlockAdded   -= Actual_OnBlockAdded;
                obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved;
                return;
            }

            IMyCubeGrid holo = (IMyCubeGrid)sh.Holo;
            MyObjectBuilder_CubeBlock objBuilder = obj.GetObjectBuilder();

            objBuilder.EntityId = 0L;
            holo.AddBlock(objBuilder, false);

            IMyCubeBlock cubeBlock = holo.GetCubeBlock(obj.Position).FatBlock;

            if (cubeBlock != null)
            {
                SetupProjection(cubeBlock);
            }
        }
예제 #6
0
        /*============|   IMyCubeGrid  |============*/
        public static void GetCubesOfType <T>(this IMyCubeGrid cubegrid, List <T> cubeList) where T : class
        {
            for (int x = cubegrid.Min.X; x <= cubegrid.Max.X; x++)
            {
                for (int y = cubegrid.Min.Y; y <= cubegrid.Max.Y; y++)
                {
                    for (int z = cubegrid.Min.Z; z <= cubegrid.Max.Z; z++)
                    {
                        var vec       = new Vector3I(x, y, z);
                        var slimblock = cubegrid.GetCubeBlock(vec);
                        T   stator    = null;

                        if (slimblock != null)
                        {
                            stator = slimblock.FatBlock as T;
                        }

                        if (stator != null)
                        {
                            cubeList.Add(stator);
                        }
                    }
                }
            }
        }
예제 #7
0
        private bool WalkLine(Vector3I start, Vector3I end, IMyCubeGrid grid)
        {
            var it = new MathUtility.Vector3ILineIterator(start, end);

            while (it.IsValid())
            {
                IMySlimBlock block = grid.GetCubeBlock(it.Current);
                it.MoveNext();

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

                if (!block.BlockDefinition.Id.SubtypeName.Contains("Shipyard"))
                {
                    return(false);
                }

                if (block.BuildPercent() < ((MyCubeBlockDefinition)block.BlockDefinition).CriticalIntegrityRatio)
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #8
0
    public GridStats(IMyCubeGrid grid)
    {
        this.grid = grid;
        var tot       = 0;
        var termblock = 0;
        var damaged   = 0;

        for (var z = grid.Min.Z; z <= grid.Max.Z; z++)
        {
            for (var y = grid.Min.Y; y <= grid.Max.Y; y++)
            {
                for (var x = grid.Min.X; x <= grid.Max.X; x++)
                {
                    if (grid.CubeExists(new Vector3I(x, y, z)))
                    {
                        tot++;
                        var block = grid.GetCubeBlock(new Vector3I(x, y, z));
                        if (block != null)
                        {
                            termblock++;
                            if (!block.IsFullIntegrity)
                            {
                                damaged++;
                            }
                        }
                    }
                }
            }
        }
        this.total          = tot;
        this.terminal_block = termblock;
        this.damaged        = damaged;
    }
예제 #9
0
        public static byte[] SerializeAndSign(IMyCubeGrid grid, IMyPlayer player, Vector3I block)
        {
            var          c     = grid.GetCubeBlock(block)?.FatBlock as IMyCockpit;
            IMyCharacter pilot = c?.Pilot;

            c?.RemovePilot();

            var ob = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder();

            if (pilot != null)
            {
                c.AttachPilot(pilot);
            }

            IMyFaction fac  = MyAPIGateway.Session.Factions.TryGetPlayerFaction(player.IdentityId);
            var        data = new ClientData(ob, fac, block, Settings.Instance.HubIP);

            string obStr    = MyAPIGateway.Utilities.SerializeToXML(data);
            string totalStr = DateTime.UtcNow.Ticks + obStr;
            string evalStr  = totalStr + Settings.Instance.Password;

            var m = new MD5();

            m.Value   = evalStr;
            totalStr += m.FingerPrint;

            return(Encoding.UTF8.GetBytes(totalStr));
        }
예제 #10
0
파일: Painting.cs 프로젝트: THDigi/PaintGun
        /// <summary>
        /// <param name="sync"></param> arg determines if it sends the paint request using the API, and automatically checks skin ownership. Must be false for mod-added skins.
        /// </summary>
        public void PaintBlock(bool sync, IMyCubeGrid grid, Vector3I gridPosition, PaintMaterial paint, ulong originalSenderSteamId)
        {
            IMySlimBlock slim = grid.GetCubeBlock(gridPosition);

            if (sync)
            {
                grid.SkinBlocks(gridPosition, gridPosition, paint.ColorMask, paint.Skin?.String);

                if (paint.Skin.HasValue)
                {
                    // check if skin was applied to alert player
                    CheckSkinned[slim] = new CheckData(paint.Skin.Value); // add or replace

                    SetUpdateMethods(UpdateFlags.UPDATE_AFTER_SIM, true);
                }
            }
            else
            {
                // NOTE getting a MySlimBlock and sending it straight to arguments avoids getting prohibited errors.
                MyCubeGrid gridInternal = (MyCubeGrid)grid;
                gridInternal.ChangeColorAndSkin(gridInternal.GetCubeBlock(gridPosition), paint.ColorMask, paint.Skin);

                if (paint.Skin.HasValue)
                {
                    CheckSkinned.Remove(slim); // prevent alerting if skin gets changed into an always-owned one
                }
            }
        }
            public static IMyMotorStator Selector(IMyCubeGrid cubegrid)
            {
                if (cubegrid == null)
                {
                    return(null);
                }

                for (int x = cubegrid.Min.X; x <= cubegrid.Max.X; x++)
                {
                    for (int y = cubegrid.Min.Y; y <= cubegrid.Max.Y; y++)
                    {
                        for (int z = cubegrid.Min.Z; z <= cubegrid.Max.Z; z++)
                        {
                            var            vec       = new Vector3I(x, y, z);
                            var            slimblock = cubegrid.GetCubeBlock(vec);
                            IMyMotorStator stator    = null;

                            if (slimblock != null)
                            {
                                stator = slimblock.FatBlock as IMyMotorStator;
                            }

                            if (stator != null && !stator.CustomName.Contains("[Ignore]"))
                            {
                                return(stator);
                            }
                        }
                    }
                }

                return(null);
            }
예제 #12
0
파일: Projector.cs 프로젝트: zrisher/ARMS
        /// <summary>
        /// Updates the appearance of the block if the integrity has changed. Only used for welding/griding.
        /// </summary>
        private static void UpdateBlockModel(IMySlimBlock realBlock, IMyCubeGrid holoGrid)
        {
            IMySlimBlock holoBlock = holoGrid.GetCubeBlock(realBlock.Position);

            Logger.DebugLog("holoBlock == null", Logger.severity.FATAL, condition: holoBlock == null);

            float realIntegrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity;
            float holoIntegrityRatio = (holoBlock.BuildIntegrity - holoBlock.CurrentDamage) / holoBlock.MaxIntegrity;

            if (realIntegrityRatio == holoIntegrityRatio)
            {
                return;
            }

            float min, max;

            if (realIntegrityRatio > holoIntegrityRatio)
            {
                max = realIntegrityRatio;
                min = holoIntegrityRatio;
            }
            else
            {
                max = holoIntegrityRatio;
                min = realIntegrityRatio;
            }

            if (((MyCubeBlockDefinition)realBlock.BlockDefinition).ModelChangeIsNeeded(min, max))
            {
                holoGrid.RemoveBlock(holoBlock);

                MyObjectBuilder_CubeBlock objBuilder = realBlock.GetObjectBuilder();
                objBuilder.EntityId = 0L;
                holoGrid.AddBlock(objBuilder, false);

                IMyCubeBlock cubeBlock = holoGrid.GetCubeBlock(realBlock.Position).FatBlock;
                if (cubeBlock != null)
                {
                    SetupProjection(cubeBlock);
                }
            }
        }
예제 #13
0
    public void draw(IScaledPixelDrawer drawer)
    {
        Func <Vector3I, Vector2I> project = v => new Vector2I(v.X, v.Z);

        var armor    = new List <Vector2I>();
        var pristine = new List <Vector2I>();
        var dented   = new List <Vector2I>();
        var damaged  = new List <Vector2I>();
        var broken   = new List <Vector2I>();

        var lengths = gridMax - gridMin + new Vector3I(1, 1, 1);

        drawer.setScale(project(lengths).X, project(lengths).Y);

        foreach (var pos in gridBlocks)
        {
            var      block = grid.GetCubeBlock(pos);
            Vector2I ppos  = project(pos - gridMin);

            if (grid.CubeExists(pos))
            {
                if (block == null)                   // Armor block
                {
                    armor.Add(ppos);
                }
                else if (block.IsFullIntegrity)
                {
                    pristine.Add(ppos);
                }
                else
                {
                    var health = (block.BuildIntegrity - block.CurrentDamage) / block.MaxIntegrity;
                    if (health < DENT_LIMIT)
                    {
                        damaged.Add(ppos);
                    }
                    else
                    {
                        dented.Add(ppos);
                    }
                }
            }
            else
            {
                broken.Add(ppos);
            }
        }

        armor.ForEach(p => drawer.drawPixel(p.X, p.Y, ARMOR_COLOR));
        pristine.ForEach(p => drawer.drawPixel(p.X, p.Y, PRISTINE_COLOR));
        dented.ForEach(p => drawer.drawPixel(p.X, p.Y, DENTED_COLOR));
        damaged.ForEach(p => drawer.drawPixel(p.X, p.Y, DAMAGED_COLOR));
        broken.ForEach(p => drawer.drawPixel(p.X, p.Y, BROKEN_COLOR));
    }
예제 #14
0
        /// <summary>
        /// Rejection test for intersection with the profiled grid.
        /// </summary>
        /// <param name="grid">Grid whose cells will be rejected and compared to the profiled grid's rejections.</param>
        /// <returns>True iff there is a collision</returns>
        public bool rejectionIntersects(IMyCubeGrid grid, IMyCubeBlock ignore, out MyEntity entity, out Vector3?pointOfObstruction)
        {
            m_logger.debugLog("m_grid == null", Logger.severity.FATAL, condition: m_grid == null);

            //m_logger.debugLog("testing grid: " + grid.getBestName(), "rejectionIntersects()");

            GridCellCache gridCache = GridCellCache.GetCellCache(grid);
            MatrixD       toLocal   = m_grid.WorldMatrixNormalizedInv;
            Line          pathLine  = Path.get_Line();

            float minDist = m_grid.GridSize + grid.GridSize;
            //if (!m_landing)
            //	minDist += NotLandingBuffer;
            float pathRadius     = Path.Radius + minDist;
            float minDistSquared = minDist * minDist;

            MyEntity entity_in             = null;
            Vector3? pointOfObstruction_in = null;

            using (m_lock_rejcectionCells.AcquireSharedUsing())
                gridCache.ForEach(cell => {
                    Vector3 world = grid.GridIntegerToWorld(cell);
                    //m_logger.debugLog("checking position: " + world, "rejectionIntersects()");
                    if (pathLine.PointInCylinder(pathRadius, world))
                    {
                        //m_logger.debugLog("point in cylinder: " + world, "rejectionIntersects()");
                        Vector3 local = Vector3.Transform(world, toLocal);
                        if (rejectionIntersects(local, minDistSquared))
                        {
                            entity_in = grid.GetCubeBlock(cell).FatBlock as MyEntity ?? grid as MyEntity;
                            if (ignore != null && entity_in == ignore)
                            {
                                return(false);
                            }

                            pointOfObstruction_in = pathLine.ClosestPoint(world);
                            return(true);
                        }
                    }
                    return(false);
                });

            if (pointOfObstruction_in.HasValue)
            {
                entity             = entity_in;
                pointOfObstruction = pointOfObstruction_in;
                return(true);
            }

            entity             = null;
            pointOfObstruction = null;
            return(false);
        }
예제 #15
0
        public void UpdateAfterBuild()
        {
            Vector3D     pos      = Block.GetPosition();
            IMyCubeGrid  grid     = Projector.CubeGrid;
            Vector3I     gridPos  = grid.WorldToGridInteger(pos);
            IMySlimBlock newBlock = grid.GetCubeBlock(gridPos);

            if (newBlock != null)
            {
                Block = newBlock;
            }
        }
예제 #16
0
        /// <summary>
        ///     Finds a random block facing the sky. Raycast is slightly randomized to simulate wind blowing rain
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="blocks"></param>
        /// <param name="gravityDirection"></param>
        /// <param name="physicsCast"></param>
        /// <returns></returns>
        public static IMySlimBlock GetRandomSkyFacingBlock(IMyCubeGrid grid, List <IMySlimBlock> blocks, Vector3D gravityDirection, out LineD line, bool physicsCast = false)
        {
            Vector3D posInt = grid.GridIntegerToWorld(blocks.GetRandomItemFromList().Position) + -gravityDirection * 2;
            Vector3D posExt = posInt + gravityDirection * Math.Max(25, grid.WorldVolume.Radius * 2);

            posExt = RandomPositionFromPoint(ref posExt, grid.WorldVolume.Radius);
            line   = new LineD();

            Vector3I?blockPos = grid.RayCastBlocks(posExt, posInt);

            if (!blockPos.HasValue)
            {
                return(null);
            }

            IMySlimBlock block = grid.GetCubeBlock(blockPos.Value);

            if (block == null)
            {
                return(null);
            }

            if (physicsCast)
            {
                var hits = new List <IHitInfo>();
                MyAPIGateway.Physics.CastRay(posExt, grid.GridIntegerToWorld(blockPos.Value), hits);
                foreach (IHitInfo hit in hits)
                {
                    if (hit?.HitEntity?.GetTopMostParent() == null)
                    {
                        continue;
                    }

                    if (hit.HitEntity.GetTopMostParent().EntityId != grid.EntityId)
                    {
                        return(null);
                    }
                }
            }

            if (Debug)
            {
                Lines.Add(new LineD {
                    From = posExt, To = grid.GridIntegerToWorld(blockPos.Value)
                });
            }
            line = new LineD {
                From = posExt, To = grid.GridIntegerToWorld(blockPos.Value)
            };

            return(block);
        }
예제 #17
0
        Vector3I?MirrorHighlight(IMyCubeGrid grid, int axis, Vector3I originalPosition, List <Vector3I> alreadyMirrored)
        {
            Vector3I?mirrorPosition = null;

            switch (axis)
            {
            case 0:
                if (grid.XSymmetryPlane.HasValue)
                {
                    mirrorPosition = originalPosition + new Vector3I(((grid.XSymmetryPlane.Value.X - originalPosition.X) * 2) - (grid.XSymmetryOdd ? 1 : 0), 0, 0);
                }
                break;

            case 1:
                if (grid.YSymmetryPlane.HasValue)
                {
                    mirrorPosition = originalPosition + new Vector3I(0, ((grid.YSymmetryPlane.Value.Y - originalPosition.Y) * 2) - (grid.YSymmetryOdd ? 1 : 0), 0);
                }
                break;

            case 2:
                if (grid.ZSymmetryPlane.HasValue)
                {
                    mirrorPosition = originalPosition + new Vector3I(0, 0, ((grid.ZSymmetryPlane.Value.Z - originalPosition.Z) * 2) + (grid.ZSymmetryOdd ? 1 : 0));     // reversed on odd
                }
                break;
            }

            if (mirrorPosition.HasValue && mirrorPosition.Value != originalPosition && !alreadyMirrored.Contains(mirrorPosition.Value))
            {
                alreadyMirrored.Add(mirrorPosition.Value);

                IMySlimBlock block = grid.GetCubeBlock(mirrorPosition.Value);

                if (block != null)
                {
                    mirroredValidTotal++;

                    PaintMaterial paintMaterial  = Main.Palette.GetLocalPaintMaterial();
                    bool          validSelection = Main.LocalToolHandler.IsMirrorBlockValid(block, paintMaterial);

                    if (validSelection)
                    {
                        mirroredValid++;
                    }

                    DrawBlockSelection(block, (validSelection ? SelectionState.Valid : SelectionState.Invalid));
                }
            }

            return(mirrorPosition); // this must be returned regardless if block exists or not
        }
        public bool tryFindCargoAtPosition(Vector3I Position, IMyCubeGrid Grid, out IMyTerminalBlock Match)
        {
            IMySlimBlock SlimBlock = Grid.GetCubeBlock(Position);

            if (SlimBlock != null && SlimBlock.FatBlock != null && SlimBlock.FatBlock is IMyTerminalBlock && SlimBlock.FatBlock.HasInventory)
            {
                Match = SlimBlock.FatBlock as IMyTerminalBlock;
                return(true);
            }
            else
            {
                Match = null;
                return(false);
            }
        }
예제 #19
0
        public bool TryFindButtonPanel(Vector3I Position, IMyCubeGrid Grid, out IMyButtonPanel Match)
        {
            IMySlimBlock SlimBlock = Grid.GetCubeBlock(Position);

            if (SlimBlock != null && SlimBlock.FatBlock != null && SlimBlock.FatBlock is IMyTerminalBlock && SlimBlock.FatBlock is IMyButtonPanel)
            {
                Match = SlimBlock.FatBlock as IMyButtonPanel;
                return(true);
            }
            else
            {
                Match = null;
                return(false);
            }
        }
예제 #20
0
 public static IMySlimBlock FirstBlock(this IMyCubeGrid grid, Vector3D worldStart, Vector3D worldEnd,
                                       Func <IMySlimBlock, bool> pred = null, Vector3I?gridSizeInflate = null)
 {
     for (var itr = CellEnumerator.EnumerateGridCells(grid, worldStart, worldEnd, gridSizeInflate);
          itr.IsValid;
          itr.MoveNext())
     {
         var block = grid.GetCubeBlock(itr.Current);
         if (block != null && (pred == null || pred.Invoke(block)))
         {
             return(block);
         }
     }
     return(null);
 }
예제 #21
0
        public static IMySlimBlock ProjectionResult(this IMySlimBlock block)
        {
            IMyProjector projector = block.CubeGrid.Projector();

            if (projector == null)
            {
                return(null);
            }

            Vector3D    pos     = block.GetPosition();
            IMyCubeGrid grid    = projector.CubeGrid;
            Vector3I    gridPos = grid.WorldToGridInteger(pos);

            return(grid.GetCubeBlock(gridPos));
        }
예제 #22
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);
        }
예제 #23
0
        /// <summary>
        ///     Gets a block on the exterior hull of a ship
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="blocks"></param>
        /// <returns></returns>
        public static IMySlimBlock GetRandomExteriorBlock(IMyCubeGrid grid, List <IMySlimBlock> blocks)
        {
            Vector3D posInt = grid.GridIntegerToWorld(blocks.GetRandomItemFromList().Position);
            Vector3D posExt = RandomPositionFromPoint(ref posInt, grid.WorldAABB.HalfExtents.Length());

            if (Debug)
            {
                Lines.Add(new LineD {
                    From = posExt, To = posInt
                });
            }

            Vector3I?blockPos = grid.RayCastBlocks(posExt, posInt);

            return(blockPos.HasValue ? grid.GetCubeBlock(blockPos.Value) : null);
        }
예제 #24
0
파일: Projector.cs 프로젝트: zrisher/ARMS
        private void Actual_OnBlockRemoved(IMySlimBlock obj)
        {
            SeenHolo sh;

            if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh))
            {
                Log.DebugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR);
                obj.CubeGrid.OnBlockAdded   -= Actual_OnBlockAdded;
                obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved;
                return;
            }

            Vector3I    position = obj.Position;
            IMyCubeGrid holo     = (IMyCubeGrid)sh.Holo;

            holo.RemoveBlock(holo.GetCubeBlock(position));
        }
예제 #25
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);
        }
예제 #26
0
        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);
        }
        private void Cleanup()
        {
            // Old method caused a race condition when the background process was still removing entities but the in-game class was already unloaded.
            // Also a lot of other nasty bugs (leaks, crashes, hangs and SE not closing) appear to be caused by this.
            MyAPIGateway.Parallel.ForEach(new HashSet <TargetEntity>(m_particles), item =>
            { // Invocation 0
                try
                {
                    if (item == null)
                    {
                        RemoveEntity(item);
                        return;
                    }
                    IMyEntity entity;
                    if (!MyAPIGateway.Entities.TryGetEntityById(item.TargetGridId, out entity))
                    {
                        RemoveEntity(item);
                        return;
                    }

                    IMyCubeGrid grid       = entity as IMyCubeGrid;
                    IMySlimBlock slimBlock = grid.GetCubeBlock(item.TargetPosition);
                    if (slimBlock == null)
                    {
                        RemoveEntity(item);
                        return;
                    }

                    if (slimBlock.IsDestroyed || slimBlock.IsFullyDismounted || (slimBlock.FatBlock != null && slimBlock.FatBlock.Closed))
                    {
                        RemoveEntity(item);
                        return;
                    }
                }
                catch (System.Exception e) when(e.ToString().Contains("IndexOutOfRangeException"))
                {
                    Logging.Instance.WriteLine("IndexOutOfRangeException occurred in ParticleEffectManager.Cleanup. This is likely harmless and can be ignored.");
                }
                catch (System.Exception e)
                { VRage.Utils.MyLog.Default.WriteLineAndConsole($"NaniteConstructionSystem.Particles.ParticleEffectManager.Cleanup (Invocation 0): \n{e}"); }
            });
        }
예제 #28
0
        public static double?GridHitCheck(IMyCubeGrid cubeGrid, LineD lineCheck, Vector3D lineStartPoint, Vector3D lineEndPoint)
        {
            // Hit a grid, do a raycast to it for block hit.
            Vector3I?gridBlockHit = cubeGrid.RayCastBlocks(lineStartPoint, lineEndPoint);

            if (gridBlockHit.HasValue)
            {
                // Get the block on hit grid
                IMySlimBlock blk = cubeGrid.GetCubeBlock(gridBlockHit.Value);
                if (blk.FatBlock != null)
                {
                    var blockBBox = blk.FatBlock.LocalAABB;
                    MyOrientedBoundingBoxD blockOBB = new MyOrientedBoundingBoxD(blockBBox, blk.FatBlock.WorldMatrix);
                    double?blockIntersect           = blockOBB.Intersects(ref lineCheck);
                    if (blockIntersect != null)
                    {
                        var hitDist = blockOBB.Intersects(ref lineCheck);
                        return(hitDist);
                    }

                    //DrawOBB(blockOBB, Color.Red, MySimpleObjectRasterizer.Wireframe, 0.01f);
                }
                else
                {
                    var center = blk.GetPosition();

                    Vector3 halfExt;
                    blk.ComputeScaledHalfExtents(out halfExt);

                    BoundingBoxD           blockBBox = new BoundingBoxD(-halfExt, halfExt);
                    Quaternion             rotMatrix = Quaternion.CreateFromRotationMatrix(blk.CubeGrid.WorldMatrix);
                    MyOrientedBoundingBoxD blockOBB  = new MyOrientedBoundingBoxD(center, blockBBox.HalfExtents, rotMatrix);

                    var hitDist = blockOBB.Intersects(ref lineCheck);
                    return(hitDist);

                    //DrawOBB(blockOBB, Color.Green, MySimpleObjectRasterizer.Wireframe, 0.01f);
                }
            }

            return(double.MaxValue);
        }
예제 #29
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);
             }
         }
     }
 }
예제 #30
0
            /// <summary>
            /// Searches for two other blocks that are perpendicular to the given one.
            /// If
            /// </summary>
            /// <param name="block">The given block</param>
            /// <returns></returns>
            public static List <IMyCubeBlock> FindPerpendicularTo(IMyTerminalBlock block)
            {
                if (block == null)
                {
                    throw new Exception("The block is null.");
                }

                IMyCubeGrid grid = block.CubeGrid;

                int maxIndex = Math.Max(grid.Min.AbsMax(), grid.Max.AbsMax());
                List <IMyCubeBlock> perpBlocks = new List <IMyCubeBlock>();

                perpBlocks.Add(block);
                int firstIndex = -1;

                // do a kind of first breath search
                for (int i = 1; perpBlocks.Count < 3 && i < maxIndex; ++i)
                {
                    for (int j = 0; j < directions.Count; ++j)
                    {
                        if (j == firstIndex)
                        {
                            continue;
                        }

                        VRageMath.Vector3I v    = new VRageMath.Vector3I(directions[j]);
                        IMySlimBlock       slim = grid.GetCubeBlock(block.Position + i * v);
                        if (slim != null && slim.FatBlock != null)
                        {
                            perpBlocks.Add(slim.FatBlock);
                            if (perpBlocks.Count == 3)
                            {
                                break;
                            }
                            firstIndex = j;
                        }
                    }
                }

                return(perpBlocks);
            }
예제 #31
0
        /// <summary>
        /// Rejection test for intersection with the profiled grid.
        /// </summary>
        /// <param name="grid">Grid whose cells will be rejected and compared to the profiled grid's rejections.</param>
        /// <returns>True iff there is a collision</returns>
        public bool rejectionIntersects(IMyCubeGrid grid, IMyCubeBlock ignore, out MyEntity entity, out Vector3? pointOfObstruction)
        {
            m_logger.debugLog(m_grid == null, "m_grid == null", Logger.severity.FATAL);

            //m_logger.debugLog("testing grid: " + grid.getBestName(), "rejectionIntersects()");

            GridCellCache gridCache = GridCellCache.GetCellCache(grid);
            MatrixD toLocal = m_grid.WorldMatrixNormalizedInv;
            Line pathLine = Path.get_Line();

            float minDist = m_grid.GridSize + grid.GridSize;
            //if (!m_landing)
            //	minDist += NotLandingBuffer;
            float pathRadius = Path.Radius + minDist;
            float minDistSquared = minDist * minDist;

            MyEntity entity_in = null;
            Vector3? pointOfObstruction_in = null;
            using (m_lock_rejcectionCells.AcquireSharedUsing())
                gridCache.ForEach(cell => {
                    Vector3 world = grid.GridIntegerToWorld(cell);
                    //m_logger.debugLog("checking position: " + world, "rejectionIntersects()");
                    if (pathLine.PointInCylinder(pathRadius, world))
                    {
                        //m_logger.debugLog("point in cylinder: " + world, "rejectionIntersects()");
                        Vector3 local = Vector3.Transform(world, toLocal);
                        if (rejectionIntersects(local, minDistSquared))
                        {
                            entity_in = grid.GetCubeBlock(cell).FatBlock as MyEntity ?? grid as MyEntity;
                            if (ignore != null && entity_in == ignore)
                                return false;

                            pointOfObstruction_in = pathLine.ClosestPoint(world);
                            return true;
                        }
                    }
                    return false;
                });

            if (pointOfObstruction_in.HasValue)
            {
                entity = entity_in;
                pointOfObstruction = pointOfObstruction_in;
                return true;
            }

            entity = null;
            pointOfObstruction = null;
            return false;
        }
예제 #32
0
        /// <summary>
        /// Updates the appearance of the block if the integrity has changed. Only used for welding/griding.
        /// </summary>
        private static void UpdateBlockModel(IMySlimBlock realBlock, IMyCubeGrid holoGrid)
        {
            IMySlimBlock holoBlock = holoGrid.GetCubeBlock(realBlock.Position);
            Static.logger.debugLog(holoBlock == null, "holoBlock == null", Logger.severity.FATAL);

            float realIntegrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity;
            float holoIntegrityRatio = (holoBlock.BuildIntegrity - holoBlock.CurrentDamage) / holoBlock.MaxIntegrity;

            if (realIntegrityRatio == holoIntegrityRatio)
                return;

            float min, max;
            if (realIntegrityRatio > holoIntegrityRatio)
            {
                max = realIntegrityRatio;
                min = holoIntegrityRatio;
            }
            else
            {
                max = holoIntegrityRatio;
                min = realIntegrityRatio;
            }

            if (((MyCubeBlockDefinition)realBlock.BlockDefinition).ModelChangeIsNeeded(min, max))
            {
                holoGrid.RemoveBlock(holoBlock);

                MyObjectBuilder_CubeBlock objBuilder = realBlock.GetObjectBuilder();
                objBuilder.EntityId = 0L;
                holoGrid.AddBlock(objBuilder, false);

                IMyCubeBlock cubeBlock = holoGrid.GetCubeBlock(realBlock.Position).FatBlock;
                if (cubeBlock != null)
                    SetupProjection(cubeBlock);
            }
        }