private void FindPriorityBlocks(NaniteDeconstructionGrid deconstruct, IMySlimBlock startBlock)
        {
            foreach (var grid in MyAPIGateway.GridGroups.GetGroup(startBlock.CubeGrid, GridLinkTypeEnum.Physical))
            {
                List <IMySlimBlock> blocks = new List <IMySlimBlock>();
                grid.GetBlocks(blocks);
                foreach (var block in blocks)
                {
                    if (block.FatBlock == null)
                    {
                        continue;
                    }

                    var functional = block.FatBlock as IMyFunctionalBlock;
                    if (functional == null)
                    {
                        continue;
                    }

                    bool priority = functional.CustomName.ToLower().Contains("deconstruct priority") || functional.CustomData.ToLower().Contains("deconstruct priority");
                    if (!priority)
                    {
                        continue;
                    }

                    if (deconstruct.RemoveList.Contains(block))
                    {
                        deconstruct.RemoveList.Remove(block);
                    }

                    deconstruct.RemoveList.AddStart(block);
                }
            }
        }
        private int GetBlockConnections(NaniteDeconstructionGrid deconstruct, IMySlimBlock currentBlock)
        {
            deconstruct.AddingList.Clear();
            deconstruct.AddingGridList.Clear();

            MyObjectBuilder_CubeBlock block = (MyObjectBuilder_CubeBlock)currentBlock.GetObjectBuilder();
            MyCubeBlockDefinition     blockDefinition;

            MyDefinitionManager.Static.TryGetCubeBlockDefinition(block.GetId(), out blockDefinition);

            // Get real block max
            Vector3I Max = Vector3I.Zero;
            Vector3I Min = block.Min;

            ComputeMax(blockDefinition, block.BlockOrientation, ref Min, out Max);

            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Min.X, Max.Y, Max.Z), -Vector3I.UnitX);
            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Min.Y, Max.Z), -Vector3I.UnitY);
            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Max.Y, Min.Z), -Vector3I.UnitZ);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Max.X, Min.Y, Min.Z), Max, Vector3I.UnitX);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Max.Y, Min.Z), Max, Vector3I.UnitY);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Min.Y, Max.Z), Max, Vector3I.UnitZ);

            // Check if currentBlock is a connector of some kind, then follow it
            // AddConnectedGridBlock(deconstruct, currentBlock);

            return(deconstruct.AddingList.Count + deconstruct.AddingGridList.Count);
        }
        private void CreateGridStack(List <IMyCubeGrid> NaniteGridGroup, NaniteDeconstructionGrid deconstruct, MyCubeGrid grid, MyCubeBlock beacon)
        {
            DateTime    start    = DateTime.Now;
            IMyCubeGrid mainGrid = MyAPIGateway.GridGroups.GetGroup((IMyCubeGrid)grid, GridLinkTypeEnum.Physical).SkipWhile(x => NaniteGridGroup.Contains(x)).OrderByDescending(x => ((MyCubeGrid)x).GetBlocks().Count).FirstOrDefault();

            if (mainGrid == null)
            {
                return;
            }

            List <IMySlimBlock> blocks = new List <IMySlimBlock>();

            mainGrid.GetBlocks(blocks);
            IMySlimBlock block = blocks.OrderBy(x => GetBlockConnections(deconstruct, x)).FirstOrDefault();

            if (block == null)
            {
                return;
            }

            if (beacon != null && mainGrid == beacon.CubeGrid)
            {
                block = (IMySlimBlock)beacon.SlimBlock;
            }

            CreateRemovalOrder(deconstruct, block);
            DateTime end = DateTime.Now;

            deconstruct.AddingGridList.Clear();
            deconstruct.AddingList.Clear();
            Logging.Instance.WriteLine($"[Deconstruction] Creating Grid Stack. Total Process Time: {(end - start).TotalMilliseconds}ms", 1);
        }
        private void AddNeighbour(NaniteDeconstructionGrid deconstruct, IMySlimBlock block, Vector3I pos, Vector3I dir)
        {
            var otherBlock = (IMySlimBlock)block.CubeGrid.GetCubeBlock(pos + dir);

            if (otherBlock != null && otherBlock != block && !deconstruct.AddingList.Contains(otherBlock) && !deconstruct.RemoveList.Contains(otherBlock))
            {
                deconstruct.AddingList.Add(otherBlock);
            }
        }
        private int GetBlockConnections(IMySlimBlock currentBlock)
        {
            if (currentBlock.CubeGrid.Closed)
            {
                return(0);
            }

            NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(currentBlock.CubeGrid);

            deconstruct.AddingList.Clear();
            deconstruct.AddingGridList.Clear();

            MyObjectBuilder_CubeBlock block = (MyObjectBuilder_CubeBlock)currentBlock.GetObjectBuilder();
            MyCubeBlockDefinition     blockDefinition;

            MyDefinitionManager.Static.TryGetCubeBlockDefinition(block.GetId(), out blockDefinition);

            // Get real block max
            Vector3I Max = Vector3I.Zero;
            Vector3I Min = block.Min;

            ComputeMax(blockDefinition, block.BlockOrientation, ref Min, out Max);

            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Min.X, Max.Y, Max.Z), -Vector3I.UnitX);
            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Min.Y, Max.Z), -Vector3I.UnitY);
            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Max.Y, Min.Z), -Vector3I.UnitZ);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Max.X, Min.Y, Min.Z), Max, Vector3I.UnitX);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Max.Y, Min.Z), Max, Vector3I.UnitY);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Min.Y, Max.Z), Max, Vector3I.UnitZ);

            int additional = 0;

            if (currentBlock.FatBlock != null && currentBlock.FatBlock.BlockDefinition.SubtypeName.Contains("NaniteBeaconDeconstruct"))
            {
                additional += 10;
            }

            /*
             * if (currentBlock.FatBlock != null &&
             *      (currentBlock.FatBlock is IMyPistonBase ||
             *       currentBlock.FatBlock is IMyPistonTop ||
             *       currentBlock.FatBlock is IMyMotorRotor ||
             *       currentBlock.FatBlock is IMyMotorStator ||
             *       currentBlock.FatBlock is IMyMotorBase ||
             *       currentBlock.FatBlock is Ingame.IMyShipConnector))
             * {
             *  additional += 10;
             * }
             */

            AddConnectedGridBlock(deconstruct, currentBlock);

            return(deconstruct.AddingList.Count + deconstruct.AddingGridList.Count + additional);
        }
        private void CheckAreaBeacons(List <IMyCubeGrid> NaniteGridGroup)
        {
            foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteAreaBeacon).ToList())
            {
                IMyCubeBlock cubeBlock = (IMyCubeBlock)beaconBlock.Value.BeaconBlock;

                if (!IsAreaBeaconValid(cubeBlock))
                {
                    continue;
                }

                var item = beaconBlock.Value as NaniteAreaBeacon;
                if (!item.Settings.AllowDeconstruction)
                {
                    continue;
                }

                HashSet <IMyEntity> entities = new HashSet <IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entities);
                foreach (var entity in entities)
                {
                    var grid = entity as IMyCubeGrid;
                    if (grid != null && grid.Physics != null && grid.Physics.AngularVelocity.Length() == 0f &&
                        grid.Physics.LinearVelocity.Length() == 0f && m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(grid)) == null &&
                        !MyAPIGateway.GridGroups.GetGroup(grid, GridLinkTypeEnum.Physical).Contains(cubeBlock.CubeGrid) &&
                        (grid.GetPosition() - cubeBlock.GetPosition()).LengthSquared() < m_maxDistance * m_maxDistance && item.IsInsideBox(grid.WorldAABB, false))
                    {
                        NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(grid);
                        m_validBeaconedGrids.Add(deconstruct);
                        CreateGridStack(NaniteGridGroup, deconstruct, (MyCubeGrid)grid, null);

                        if (!m_areaTargetBlocks.ContainsKey(grid))
                        {
                            m_areaTargetBlocks.Add(grid, item);
                        }
                        else
                        {
                            m_areaTargetBlocks[grid] = item;
                        }

                        foreach (var block in deconstruct.RemoveList)
                        {
                            if (!PotentialTargetList.Contains(block))
                            {
                                PotentialTargetList.Add(block);
                            }
                        }
                    }
                }
            }
        }
        private void AddNeighbours(NaniteDeconstructionGrid deconstruct, IMySlimBlock block, Vector3I min, Vector3I max, Vector3I normalDirection)
        {
            Vector3I temp;

            for (temp.X = min.X; temp.X <= max.X; temp.X++)
            {
                for (temp.Y = min.Y; temp.Y <= max.Y; temp.Y++)
                {
                    for (temp.Z = min.Z; temp.Z <= max.Z; temp.Z++)
                    {
                        AddNeighbour(deconstruct, block, temp, normalDirection);
                    }
                }
            }
        }
        private void CreateRemovalOrder(NaniteDeconstructionGrid deconstruct, IMySlimBlock currentBlock)
        {
            deconstruct.AddingList.Clear();
            deconstruct.GridsProcessed.Clear();

            while (true)
            {
                if (!deconstruct.GridsProcessed.Contains(currentBlock.CubeGrid))
                {
                    ((MyCubeGrid)currentBlock.CubeGrid).OnGridSplit += OnGridSplit;
                    deconstruct.GridsProcessed.Add(currentBlock.CubeGrid);
                }

                addNeighboursDeconstruct(ref deconstruct, currentBlock, false);

                // Check if currentBlock is a connector of some kind, then follow it
                AddConnectedGridBlock(deconstruct, currentBlock);

                // Add to removal list
                if (!deconstruct.RemoveList.Contains(currentBlock))
                {
                    deconstruct.RemoveList.AddStart(currentBlock);
                }

                if (deconstruct.AddingList.Count < 1 && deconstruct.AddingGridList.Count < 1)
                {
                    break;
                }

                if (deconstruct.AddingList.Count < 1 && deconstruct.AddingGridList.Count > 0)
                {
                    currentBlock = deconstruct.AddingGridList[0];
                    deconstruct.AddingGridList.Remove(currentBlock);
                }
                else
                {
                    currentBlock = deconstruct.AddingList[0];
                    deconstruct.AddingList.Remove(currentBlock);
                }
            }

            // Find user defined priority blocks for deconstruction.
            FindPriorityBlocks(deconstruct, currentBlock);

            Logging.Instance.WriteLine($"[Deconstruction] Block Count: {deconstruct.RemoveList.Count}", 1);
            Logging.Instance.WriteLine($"[Deconstruction] Grid Count: {deconstruct.GridsProcessed.Count}", 1);
        }
        private void AddNeighbour(NaniteDeconstructionGrid deconstruct, IMySlimBlock block, Vector3I pos, Vector3I dir)
        {
            var otherBlock = (IMySlimBlock)block.CubeGrid.GetCubeBlock(pos + dir);

            if (otherBlock != null && otherBlock != block && !deconstruct.AddingList.Contains(otherBlock) && !deconstruct.RemoveList.Contains(otherBlock))
            {
                deconstruct.AddingList.Add(otherBlock);

                /*
                 * if(deconstruct.GridTree != null)
                 * {
                 *  var parent = deconstruct.GridTree[deconstruct.TreePosition].All.FirstOrDefault(x => x.Value == block);
                 *  parent.Add(otherBlock);
                 * }
                 */
            }
        }
        private int GetBlockConnections(IMySlimBlock currentBlock)
        {
            if (currentBlock.CubeGrid.Closed)
            {
                return(0);
            }

            NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(currentBlock.CubeGrid);

            addNeighboursDeconstruct(ref deconstruct, currentBlock);

            int additional = 0;

            if (currentBlock.FatBlock != null && currentBlock.FatBlock.BlockDefinition.SubtypeName.Contains("NaniteBeaconDeconstruct"))
            {
                additional += 10;
            }

            AddConnectedGridBlock(deconstruct, currentBlock);

            return(deconstruct.AddingList.Count + deconstruct.AddingGridList.Count + additional);
        }
        private void addNeighboursDeconstruct(ref NaniteDeconstructionGrid deconstruct, IMySlimBlock currentBlock, bool clear = true)
        {
            if (clear)
            {
                deconstruct.AddingList.Clear();
                deconstruct.AddingGridList.Clear();
            }

            MyCubeBlockDefinition blockDefinition = (MyCubeBlockDefinition)currentBlock.BlockDefinition;

            // Get real block max
            Vector3I Max = Vector3I.Zero;
            Vector3I Min = currentBlock.Min;

            ComputeMax(blockDefinition, currentBlock.Orientation, ref Min, out Max);

            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Min.X, Max.Y, Max.Z), -Vector3I.UnitX);
            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Min.Y, Max.Z), -Vector3I.UnitY);
            AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Max.Y, Min.Z), -Vector3I.UnitZ);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Max.X, Min.Y, Min.Z), Max, Vector3I.UnitX);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Max.Y, Min.Z), Max, Vector3I.UnitY);
            AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Min.Y, Max.Z), Max, Vector3I.UnitZ);
        }
        private void CreateGridStack(NaniteDeconstructionGrid deconstruct, MyCubeGrid grid, MyCubeBlock beacon)
        {
            DateTime           start    = DateTime.Now;
            List <IMyCubeGrid> gridList = GridHelper.GetGridGroup((IMyCubeGrid)grid);
            IMyCubeGrid        mainGrid = gridList.OrderByDescending(x => ((MyCubeGrid)x).GetBlocks().Count).FirstOrDefault();

            if (mainGrid == null)
            {
                return;
            }

            List <IMySlimBlock> blocks = new List <IMySlimBlock>();

            mainGrid.GetBlocks(blocks);
            IMySlimBlock block = blocks.OrderBy(x => GetBlockConnections(deconstruct, x)).FirstOrDefault();

            if (block == null) // No blocks ?
            {
                return;
            }

            if (beacon != null && mainGrid == beacon.CubeGrid)
            {
                block = (IMySlimBlock)beacon.SlimBlock;
            }

            //deconstruct.GridTree = new List<Node<IMySlimBlock>>();
            //deconstruct.GridTree.Add(new Node<IMySlimBlock>(block));

            CreateRemovalOrder(deconstruct, block);
            DateTime end = DateTime.Now;

            deconstruct.AddingGridList.Clear();
            deconstruct.AddingList.Clear();
            Logging.Instance.WriteLine(string.Format("PROCESS Creating Grid Stack.  Total Process Time: {0}", (end - start).TotalMilliseconds));
        }
        private void CreateRemovalOrder(NaniteDeconstructionGrid deconstruct, IMySlimBlock startBlock)
        {
            IMySlimBlock currentBlock = startBlock;

            deconstruct.AddingList.Clear();
            deconstruct.GridsProcessed.Clear();

            while (true)
            {
                if (!deconstruct.GridsProcessed.Contains(currentBlock.CubeGrid))
                {
                    ((MyCubeGrid)currentBlock.CubeGrid).OnGridSplit += OnGridSplit;
                    deconstruct.GridsProcessed.Add(currentBlock.CubeGrid);
                }

                MyObjectBuilder_CubeBlock block = (MyObjectBuilder_CubeBlock)currentBlock.GetObjectBuilder();
                MyCubeBlockDefinition     blockDefinition;
                MyDefinitionManager.Static.TryGetCubeBlockDefinition(block.GetId(), out blockDefinition);

                // Get real block max
                Vector3I Max = Vector3I.Zero;
                Vector3I Min = block.Min;
                ComputeMax(blockDefinition, block.BlockOrientation, ref Min, out Max);

                AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Min.X, Max.Y, Max.Z), -Vector3I.UnitX);
                AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Min.Y, Max.Z), -Vector3I.UnitY);
                AddNeighbours(deconstruct, currentBlock, Min, new Vector3I(Max.X, Max.Y, Min.Z), -Vector3I.UnitZ);
                AddNeighbours(deconstruct, currentBlock, new Vector3I(Max.X, Min.Y, Min.Z), Max, Vector3I.UnitX);
                AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Max.Y, Min.Z), Max, Vector3I.UnitY);
                AddNeighbours(deconstruct, currentBlock, new Vector3I(Min.X, Min.Y, Max.Z), Max, Vector3I.UnitZ);

                // Check if currentBlock is a connector of some kind, then follow it
                AddConnectedGridBlock(deconstruct, currentBlock);

                // Add to removal list
                if (!deconstruct.RemoveList.Contains(currentBlock))
                {
                    deconstruct.RemoveList.AddStart(currentBlock);
                }

                if (deconstruct.AddingList.Count < 1 && deconstruct.AddingGridList.Count < 1)
                {
                    break;
                }

                if (deconstruct.AddingList.Count < 1 && deconstruct.AddingGridList.Count > 0)
                {
                    currentBlock = deconstruct.AddingGridList[0];
                    deconstruct.AddingGridList.Remove(currentBlock);
                    //deconstruct.TreePosition++;
                    //deconstruct.GridTree.Add(new Node<IMySlimBlock>(currentBlock));
                }
                else
                {
                    currentBlock = deconstruct.AddingList[0];
                    deconstruct.AddingList.Remove(currentBlock);
                }
            }

            // Find user defined priority blocks for deconstruction.
            FindPriorityBlocks(deconstruct, startBlock);

            Logging.Instance.WriteLine(string.Format("Block Count: {0}", deconstruct.RemoveList.Count));
            //Logging.Instance.WriteLine(string.Format("Grid Count: {0}", deconstruct.GridsProcessed.Count));
            //Logging.Instance.WriteLine(string.Format("Tree Size: {0}", deconstruct.GridTree.Sum(x => x.All.Count())));
        }
        private void CheckAreaBeacons()
        {
            foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteAreaBeacon))
            {
                IMyCubeBlock cubeBlock = (IMyCubeBlock)beaconBlock.BeaconBlock;

                if (!((IMyFunctionalBlock)cubeBlock).Enabled || !((IMyFunctionalBlock)cubeBlock).IsFunctional)
                {
                    continue;
                }

                MyRelationsBetweenPlayerAndBlock relation = cubeBlock.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);
                if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                {
                    continue;
                }

                var item = beaconBlock as NaniteAreaBeacon;
                if (!item.Settings.AllowDeconstruction)
                {
                    continue;
                }

                HashSet <IMyEntity> entities = new HashSet <IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entities);
                foreach (var entity in entities)
                {
                    var grid = entity as IMyCubeGrid;
                    if (grid == null)
                    {
                        continue;
                    }

                    if (grid.Physics == null)
                    {
                        continue;
                    }

                    if (grid.Physics.AngularVelocity.Length() != 0f || grid.Physics.LinearVelocity.Length() != 0f)
                    {
                        continue;
                    }

                    if (m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(grid)) != null)
                    {
                        continue;
                    }

                    if (GridHelper.GetGridGroup(grid).Contains(cubeBlock.CubeGrid))
                    {
                        continue;
                    }

                    if ((grid.GetPosition() - cubeBlock.GetPosition()).LengthSquared() < m_maxDistance * m_maxDistance)
                    {
                        if (item.IsInsideBox(grid.WorldAABB, false))
                        {
                            NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(grid);
                            m_validBeaconedGrids.Add(deconstruct);
                            CreateGridStack(deconstruct, (MyCubeGrid)grid, null);
                            if (!m_areaTargetBlocks.ContainsKey(grid))
                            {
                                m_areaTargetBlocks.Add(grid, item);
                            }
                            else
                            {
                                m_areaTargetBlocks[grid] = item;
                            }

                            foreach (var block in deconstruct.RemoveList)
                            {
                                if (!PotentialTargetList.Contains(block))
                                {
                                    PotentialTargetList.Add(block);
                                }
                            }
                        }
                    }
                }
            }
        }
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <IMySlimBlock> gridBlocks)
        {
            try
            {
                if (!IsEnabled())
                {
                    PotentialTargetList.Clear();
                    return;
                }

                // Add
                foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteBeaconDeconstruct && Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), x.BeaconBlock.GetPosition()) < m_maxDistance * m_maxDistance))
                {
                    IMyCubeBlock item = (IMyCubeBlock)beaconBlock.BeaconBlock;

                    if (!((IMyFunctionalBlock)item).Enabled || !((IMyFunctionalBlock)item).IsFunctional)
                    {
                        continue;
                    }

                    if (gridList.Contains(item.CubeGrid))
                    {
                        continue;
                    }

                    MyRelationsBetweenPlayerAndBlock relation = item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);
                    if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                    {
                        continue;
                    }

                    if (m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(item.CubeGrid)) != null)
                    {
                        continue;
                    }

                    NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(item.CubeGrid);
                    m_validBeaconedGrids.Add(deconstruct);
                    CreateGridStack(deconstruct, (MyCubeGrid)item.CubeGrid, (MyCubeBlock)item);

                    using (Lock.AcquireExclusiveUsing())
                    {
                        foreach (var slimBlock in deconstruct.RemoveList)
                        {
                            if (!PotentialTargetList.Contains(slimBlock))
                            {
                                PotentialTargetList.Add(slimBlock);
                            }
                        }
                    }

                    deconstruct.RemoveList.Clear();
                }

                CheckAreaBeacons();

                if (PotentialTargetList.Count > 0)
                {
                    using (Lock.AcquireExclusiveUsing())
                    {
                        foreach (IMySlimBlock item in PotentialTargetList.ToList())
                        {
                            if (item.CubeGrid.Closed || item.IsDestroyed || item.IsFullyDismounted || (item.FatBlock != null && item.FatBlock.Closed))
                            {
                                PotentialTargetList.Remove(item);
                            }

                            if (EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, item) > m_maxDistance)
                            {
                                PotentialTargetList.Remove(item);
                            }
                        }

                        //m_potentialTargetList = m_potentialTargetList.OrderBy(x => GetBlockConnections((IMySlimBlock)(x))).ToList();
                    }
                }
                else if (TargetList.Count == 0 && PotentialTargetList.Count == 0)
                {
                    m_validBeaconedGrids.Clear();
                }
            }
            catch (Exception ex)
            {
                Logging.Instance.WriteLine(string.Format("Parallel Erorr: {0}", ex.ToString()));
            }
        }
 private int GetBlockConnections(NaniteDeconstructionGrid deconstruct, IMySlimBlock currentBlock)
 {
     addNeighboursDeconstruct(ref deconstruct, currentBlock);
     return(deconstruct.AddingList.Count + deconstruct.AddingGridList.Count);
 }
        private void AddConnectedGridBlock(NaniteDeconstructionGrid deconstruct, IMySlimBlock slimBlock)
        {
            if (slimBlock.FatBlock == null)
            {
                return;
            }

            IMyCubeBlock cubeBlock  = (IMyCubeBlock)slimBlock.FatBlock;
            IMySlimBlock otherBlock = null;

            if (cubeBlock is IMyPistonBase)
            {
                IMyPistonBase pistonBase = (IMyPistonBase)cubeBlock;
                if (pistonBase.Top != null)
                {
                    MyCubeBlock cubeOther = (MyCubeBlock)pistonBase.Top;

                    if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid))
                    {
                        return;
                    }

                    if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock))
                    {
                        deconstruct.AddingGridList.Add(cubeOther.SlimBlock);
                        otherBlock = cubeOther.SlimBlock;
                    }
                }
            }
            else if (cubeBlock is Ingame.IMyShipConnector)
            {
                Ingame.IMyShipConnector connector = (Ingame.IMyShipConnector)cubeBlock;
                if (connector.Status == Sandbox.ModAPI.Ingame.MyShipConnectorStatus.Connected)
                {
                    MyCubeBlock cubeOther = (MyCubeBlock)connector.OtherConnector;

                    if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid))
                    {
                        return;
                    }

                    if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock))
                    {
                        deconstruct.AddingGridList.Add(cubeOther.SlimBlock);
                        otherBlock = cubeOther.SlimBlock;
                    }
                }
            }
            else if (cubeBlock is IMyAttachableTopBlock)
            {
                var motorRotor = cubeBlock as IMyAttachableTopBlock;
                if (motorRotor.Base != null)
                {
                    MyCubeBlock cubeOther = motorRotor.Base as MyCubeBlock;

                    if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid))
                    {
                        return;
                    }

                    if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock))
                    {
                        deconstruct.AddingGridList.Add(cubeOther.SlimBlock);
                        otherBlock = cubeOther.SlimBlock;
                    }
                }
            }
            else if (cubeBlock is IMyMechanicalConnectionBlock)
            {
                var motorBase = cubeBlock as IMyMechanicalConnectionBlock;
                if (motorBase.TopGrid != null)
                {
                    var cubeOther = motorBase.Top as MyCubeBlock;

                    if (deconstruct.GridsProcessed.Contains(cubeOther.CubeGrid))
                    {
                        return;
                    }

                    if (!deconstruct.AddingGridList.Contains(cubeOther.SlimBlock))
                    {
                        deconstruct.AddingGridList.Add(cubeOther.SlimBlock);
                        otherBlock = cubeOther.SlimBlock;
                    }
                }
            }
        }
        public override void ParallelUpdate(List <IMyCubeGrid> NaniteGridGroup, List <BlockTarget> gridBlocks)
        {
            try
            {
                // Add
                foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteBeaconDeconstruct))
                {
                    IMyCubeBlock item = (IMyCubeBlock)beaconBlock.Value.BeaconBlock;

                    if (item == null ||
                        item.CubeGrid == null ||
                        !((IMyFunctionalBlock)item).Enabled ||
                        !((IMyFunctionalBlock)item).IsFunctional ||
                        NaniteGridGroup.Contains(item.CubeGrid) ||
                        !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)) ||
                        m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(item.CubeGrid)) != null ||
                        !IsInRange(item.GetPosition(), m_maxDistance)
                        )
                    {
                        continue;
                    }

                    NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(item.CubeGrid);

                    CreateGridStack(NaniteGridGroup, deconstruct, (MyCubeGrid)item.CubeGrid, (MyCubeBlock)item);
                    m_validBeaconedGrids.Add(deconstruct);

                    Logging.Instance.WriteLine($"[Deconstruction] Grid {item.CubeGrid.CustomName} queued for deconstruction", 1);

                    foreach (var slimBlock in deconstruct.RemoveList)
                    {
                        if (slimBlock != null)
                        {
                            PotentialTargetList.Add(slimBlock);
                        }
                    }

                    deconstruct.RemoveList.Clear();
                }

                CheckAreaBeacons(NaniteGridGroup);

                if (PotentialTargetList.Count > 0)
                {
                    foreach (IMySlimBlock item in PotentialTargetList.ToList())
                    {
                        if (item == null || item.CubeGrid == null || item.CubeGrid.Closed || item.IsDestroyed || item.IsFullyDismounted ||
                            (item.FatBlock != null && item.FatBlock.Closed) ||
                            EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, item) > m_maxDistance)
                        {
                            PotentialTargetList.Remove(item);
                        }
                    }
                }
                else if (TargetList.Count == 0 && PotentialTargetList.Count == 0)
                {
                    m_validBeaconedGrids.Clear();
                }
            }
            catch (Exception e)
            { Logging.Instance.WriteLine($"Exception in NaniteDeconstructionTargets.ParallelUpdate:\n{e}"); }
        }