private void RemoveGridTarget(IMyCubeGrid grid)
        {
            foreach (var item in m_validBeaconedGrids)
            {
                if (item.MainGrid == grid)
                {
                    using (Lock.AcquireExclusiveUsing())
                    {
                        foreach (var block in item.RemoveList)
                        {
                            PotentialTargetList.Remove(block);
                            TargetList.Remove(block);
                        }
                    }

                    m_validBeaconedGrids.Remove(item);
                    break;
                }
            }

            if (m_areaTargetBlocks.ContainsKey(grid))
            {
                m_areaTargetBlocks.Remove(grid);
            }
        }
Example #2
0
        public virtual void Remove(object target)
        {
            TargetList.Remove(target);

            using (Lock.AcquireExclusiveUsing())
                PotentialTargetList.Remove(target);
        }
        private bool AddPotentialBlock(IMySlimBlock block, bool remote = false, NaniteAreaBeacon beacon = null)
        {
            if (TargetList.Contains(block))
            {
                return(false);
            }

            if (!remote && block.FatBlock != null && block.FatBlock is IMyTerminalBlock && block.FatBlock.OwnerId != 0)
            {
                IMyTerminalBlock terminal = (IMyTerminalBlock)block.FatBlock;
                MyRelationsBetweenPlayerAndBlock relation = terminal.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);

                if (relation == MyRelationsBetweenPlayerAndBlock.Neutral ||
                    relation == MyRelationsBetweenPlayerAndBlock.Enemies)
                {
                    return(false);
                }
            }
            else if (remote)
            {
                //if (block.CubeGrid.BigOwners.Count < 1)
                //    return false;

                foreach (var item in block.CubeGrid.BigOwners)
                {
                    MyRelationsBetweenPlayerAndBlock relation = m_constructionBlock.ConstructionBlock.GetUserRelationToOwner(item);

                    if (relation == MyRelationsBetweenPlayerAndBlock.Neutral ||
                        relation == MyRelationsBetweenPlayerAndBlock.Enemies)
                    {
                        return(false);
                    }
                }
            }

            if (!block.IsFullIntegrity || block.HasDeformation)
            {
                using (Lock.AcquireExclusiveUsing())
                {
                    if (beacon != null)
                    {
                        if (!m_areaTargetBlocks.ContainsKey(block))
                        {
                            m_areaTargetBlocks.Add(block, beacon);
                        }
                        else
                        {
                            m_areaTargetBlocks[block] = beacon;
                        }
                    }

                    PotentialTargetList.Add(block);
                    return(true);
                }
            }

            return(false);
        }
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <IMySlimBlock> blocks)
        {
            using (Lock.AcquireExclusiveUsing())
            {
                PotentialTargetList.Clear();
            }

            var remoteList = new HashSet <IMySlimBlock>();

            if (!IsEnabled())
            {
                return;
            }

            foreach (var block in blocks)
            {
                AddPotentialBlock(block);
            }

            foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x is NaniteBeaconConstruct && 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;
                }

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

                List <IMyCubeGrid>  beaconGridList = GridHelper.GetGridGroup((IMyCubeGrid)item.CubeGrid);
                List <IMySlimBlock> beaconBlocks   = new List <IMySlimBlock>();
                foreach (var grid in beaconGridList)
                {
                    grid.GetBlocks(beaconBlocks);
                }

                foreach (var block in beaconBlocks)
                {
                    if (AddPotentialBlock(block, true))
                    {
                        remoteList.Add(block);
                    }
                }
            }

            CheckAreaBeacons();

            using (m_remoteLock.AcquireExclusiveUsing())
            {
                m_remoteTargets = remoteList;
            }
        }
        public void CancelTarget(IMySlimBlock obj)
        {
            Logging.Instance.WriteLine(string.Format("CANCELLING Deconstruction Target: {0} - {1} (EntityID={2},Position={3})", m_constructionBlock.ConstructionBlock.EntityId, obj.GetType().Name, obj.FatBlock != null ? obj.FatBlock.EntityId : 0, obj.Position));
            if (Sync.IsServer)
            {
                m_constructionBlock.SendCancelTarget(obj, TargetTypes.Deconstruction);
            }

            m_constructionBlock.ParticleManager.CancelTarget(obj);
            m_constructionBlock.ToolManager.Remove(obj);
            Remove(obj);

            using (Lock.AcquireExclusiveUsing())
                PotentialTargetList.Add(obj);
        }
        private void ProcessProjector(IMyProjector projector)
        {
            MyCubeGrid grid = (MyCubeGrid)projector.ProjectedGrid;

            foreach (IMySlimBlock block in grid.GetBlocks())
            {
                if (projector.CanBuild(block, false) == BuildCheckResult.OK)
                {
                    using (Lock.AcquireExclusiveUsing())
                    {
                        if (!PotentialTargetList.Contains(block))
                        {
                            PotentialTargetList.Add(block);
                        }
                    }
                }
            }
        }
Example #7
0
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <IMySlimBlock> blocks)
        {
            using (Lock.AcquireExclusiveUsing())
            {
                PotentialTargetList.Clear();
            }

            if (!IsEnabled())
            {
                return;
            }

            foreach (var block in blocks)
            {
                AddPotentialBlock(block);
            }
            CheckBeacons();
            CheckAreaBeacons();
        }
        public override void FindTargets(ref Dictionary <string, int> available)
        {
            if (!IsEnabled())
            {
                return;
            }

            if (TargetList.Count >= GetMaximumTargets())
            {
                if (PotentialTargetList.Count > 0)
                {
                    m_lastInvalidTargetReason = "Maximum targets reached.  Add more upgrades!";
                }

                return;
            }

            using (Lock.AcquireExclusiveUsing())
            {
                for (int r = PotentialTargetList.Count - 1; r >= 0; r--)
                {
                    if (m_constructionBlock.IsUserDefinedLimitReached())
                    {
                        m_lastInvalidTargetReason = "User defined maximum nanite limit reached";
                        return;
                    }

                    var item = (IMyPlayer)PotentialTargetList[r];
                    if (TargetList.Contains(item))
                    {
                        continue;
                    }

                    if (item.Controller == null || item.Controller.ControlledEntity == null || item.Controller.ControlledEntity.Entity == null)
                    {
                        PotentialTargetList.RemoveAt(r);
                        continue;
                    }

                    var  blockList = NaniteConstructionManager.GetConstructionBlocks((IMyCubeGrid)m_constructionBlock.ConstructionBlock.CubeGrid);
                    bool found     = false;
                    foreach (var block in blockList)
                    {
                        if (block.Targets.First(x => x is NaniteMedicalTargets).TargetList.Contains(item))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        m_lastInvalidTargetReason = "Another factory has this block as a target";
                        continue;
                    }

                    if (Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), item.GetPosition()) < m_maxDistance * m_maxDistance &&
                        NaniteConstructionPower.HasRequiredPowerForNewTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock, this))
                    {
                        TargetList.Add(item);
                        Logging.Instance.WriteLine(string.Format("ADDING Medical Target: conid={0} type={1} playerName={2} position={3}", m_constructionBlock.ConstructionBlock.EntityId, item.GetType().Name, item.DisplayName, item.GetPosition()));
                        if (TargetList.Count >= GetMaximumTargets())
                        {
                            break;
                        }
                    }
                }
            }
        }
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <IMySlimBlock> gridBlocks)
        {
            using (Lock.AcquireExclusiveUsing())
                PotentialTargetList.Clear();

            List <IMyPlayer> players = new List <IMyPlayer>();

            try
            {
                MyAPIGateway.Players.GetPlayers(players);
            }
            catch
            {
                Logging.Instance.WriteLine(string.Format("Error getting players, skipping"));
                return;
            }

            if (!IsEnabled())
            {
                return;
            }

            foreach (var item in players)
            {
                var functional = m_constructionBlock.ConstructionBlock as IMyFunctionalBlock;
                MyRelationsBetweenPlayerAndBlock relations = functional.GetUserRelationToOwner(item.IdentityId);
                if (relations != MyRelationsBetweenPlayerAndBlock.Owner && relations != MyRelationsBetweenPlayerAndBlock.FactionShare)
                {
                    continue;
                }

                if (item.Controller == null || item.Controller.ControlledEntity == null || item.Controller.ControlledEntity.Entity == null)
                {
                    continue;
                }

                bool damaged = false;
                foreach (var component in item.Controller.ControlledEntity.Entity.Components)
                {
                    var stat = component as MyCharacterStatComponent;
                    if (stat != null)
                    {
                        if (stat.Health.Value < stat.Health.MaxValue)
                        {
                            damaged = true;
                        }

                        break;
                    }
                }

                if (!damaged)
                {
                    continue;
                }

                if (Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), item.GetPosition()) < m_maxDistance * m_maxDistance)
                {
                    using (m_lock.AcquireExclusiveUsing())
                        PotentialTargetList.Add(item);
                }
            }
        }
Example #10
0
        public override void FindTargets(ref Dictionary <string, int> available)
        {
            if (!IsEnabled())
            {
                return;
            }

            if (TargetList.Count >= GetMaximumTargets())
            {
                if (PotentialTargetList.Count > 0)
                {
                    m_lastInvalidTargetReason = "Maximum targets reached.  Add more upgrades!";
                }

                return;
            }

            DateTime start = DateTime.Now;

            using (Lock.AcquireExclusiveUsing())
            {
                if (m_constructionBlock.IsUserDefinedLimitReached())
                {
                    m_lastInvalidTargetReason = "User defined maximum nanite limit reached";
                    return;
                }

                //foreach (NaniteMiningItem item in PotentialTargetList)
                for (int r = PotentialTargetList.Count - 1; r >= 0; r--)
                {
                    var item = (NaniteMiningItem)PotentialTargetList[r];
                    if (TargetList.Contains(item))
                    {
                        continue;
                    }

                    if (m_globalPositionList.Contains(item.Position))
                    {
                        m_lastInvalidTargetReason = "Another factory has this voxel as a target";
                        continue;
                    }

                    var  blockList = NaniteConstructionManager.GetConstructionBlocks((IMyCubeGrid)m_constructionBlock.ConstructionBlock.CubeGrid);
                    bool found     = false;
                    foreach (var block in blockList)
                    {
                        // This can be sped up if necessary by indexing items by position
                        if (block.GetTarget <NaniteMiningTargets>().TargetList.FirstOrDefault(x => ((NaniteMiningItem)x).Position == item.Position) != null)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        m_lastInvalidTargetReason = "Another factory has this voxel as a target";
                        continue;
                    }

                    if (!NaniteMining.CheckVoxelContent(item.VoxelId, item.Position))
                    {
                        continue;
                    }

                    if (Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), item.Position) < m_maxDistance * m_maxDistance &&
                        NaniteConstructionPower.HasRequiredPowerForNewTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock, this))
                    {
                        Logging.Instance.WriteLine(string.Format("ADDING Mining Target: conid={0} pos={1} type={2}", m_constructionBlock.ConstructionBlock.EntityId, item.Position, MyDefinitionManager.Static.GetVoxelMaterialDefinition(item.VoxelMaterial).MinedOre));

                        //PotentialTargetList.Remove(item);
                        TargetList.Add(item);
                        m_globalPositionList.Add(item.Position);
                        if (TargetList.Count >= GetMaximumTargets())
                        {
                            break;
                        }
                    }
                }
            }

            //Logging.Instance.WriteLine(string.Format("FindTargets took {0}ms", (DateTime.Now - start).TotalMilliseconds));
        }
Example #11
0
        public override void ParallelUpdate(List <IMyCubeGrid> gridList, List <IMySlimBlock> gridBlocks)
        {
            using (Lock.AcquireExclusiveUsing())
                PotentialTargetList.Clear();

            DateTime      start        = DateTime.Now;
            List <object> finalAddList = new List <object>();
            int           listCount    = 0;

            foreach (var miningBlock in NaniteConstructionManager.MiningList.Where(x => x.IsWorking && Vector3D.DistanceSquared(m_constructionBlock.ConstructionBlock.GetPosition(), x.MiningBlock.GetPosition()) < m_maxDistance * m_maxDistance).OrderBy(x => rnd.Next(100)))
            {
                IMyCubeBlock item = (IMyCubeBlock)miningBlock.MiningBlock;
                MyRelationsBetweenPlayerAndBlock relation = item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId);
                if (!(relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare || (MyAPIGateway.Session.CreativeMode && relation == MyRelationsBetweenPlayerAndBlock.NoOwnership)))
                {
                    continue;
                }

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

                if (miningBlock.OreList == null || miningBlock.OreList.Count < 1)
                {
                    continue;
                }

                int sum = miningBlock.OreList.Sum(x => x.Value.Count);
                Dictionary <MyVoxelMaterialDefinition, List <NaniteMiningItem> > lookup = null;
                using (miningBlock.Lock.AcquireExclusiveUsing())
                {
                    lookup = miningBlock.OreList.ToDictionary(x => x.Key, x => x.Value);
                }

                List <object> addList = new List <object>();
                int           count   = 0;
                int           pos     = 0;

                while (true)
                {
                    var group = lookup.ElementAt(count % miningBlock.OreList.Count);
                    if (pos < group.Value.Count)
                    {
                        addList.Insert(0, group.Value[pos]);
                    }

                    count++;
                    if (count % miningBlock.OreList.Count == 0)
                    {
                        pos++;
                    }

                    if (count >= 1000)
                    {
                        break;
                    }

                    if (count >= sum)
                    {
                        break;
                    }
                }

                DistributeList(addList, finalAddList, listCount);
                listCount++;

                if (listCount > 5)
                {
                    break;
                }
            }

            var listToAdd = finalAddList.Take(1000).ToList();

            listToAdd.Reverse();
            using (Lock.AcquireExclusiveUsing())
            {
                PotentialTargetList.AddRange(listToAdd);
            }

            //Logging.Instance.WriteLine(string.Format("ParallelUpdate() took {0} ms", (DateTime.Now - start).TotalMilliseconds));
        }
Example #12
0
        private void ScanVoxelWork()
        {
            try
            {
                if (m_oreList != null && DateTime.Now - m_lastRefresh < TimeSpan.FromMinutes(5))
                {
                    return;
                }

                m_lastRefresh = DateTime.Now;
                Vector3D        position = m_block.GetPosition();
                BoundingSphereD sphere   = new BoundingSphereD(position, 2f);
                var             entities = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere);

                if (!NaniteConstructionManager.HammerTerminalSettings.ContainsKey(m_block.EntityId))
                {
                    NaniteConstructionManager.HammerTerminalSettings.Add(m_block.EntityId, new NaniteHammerTerminalSettings(true));
                }

                var allowedOreList = new HashSet <string>(NaniteConstructionManager.HammerTerminalSettings[m_block.EntityId].SelectedOres);

                DateTime start = DateTime.Now;
                Logging.Instance.WriteLine("MINING Hammer Start Scan");
                Dictionary <Vector3D, NaniteMiningItem> miningItems = new Dictionary <Vector3D, NaniteMiningItem>(100000);
                foreach (var item in entities)
                {
                    var voxelMap = item as MyVoxelBase;
                    if (voxelMap == null)
                    {
                        continue;
                    }

                    if (item.GetType().Name == "MyVoxelPhysics")
                    {
                        continue;
                    }

                    Logging.Instance.WriteLine(string.Format("Item: {0}:{1} - {2}", item.GetType().Name, item.EntityId, item.GetPosition()));
                    //var direction = Vector3D.Normalize(item.GetPosition() - position);
                    var direction = Vector3D.Normalize(-m_block.PositionComp.WorldMatrix.Up);
                    for (int r = NaniteConstructionManager.Settings.MiningDepth - 1; r >= 0; r--)
                    {
                        DateTime readStart = DateTime.Now;
                        ReadVoxel(voxelMap, position + (direction * NaniteConstructionManager.Settings.MiningRadius * r), miningItems, allowedOreList);
                        //Logging.Instance.WriteLine(string.Format("Read Time: {0}", (DateTime.Now - readStart).TotalMilliseconds));
                        //ReadVoxel(voxelMap, position, position + (direction * NaniteConstructionManager.Settings.MiningRadius * NaniteConstructionManager.Settings.MiningDepth), miningItems, allowedOreList);
                    }
                }

                Logging.Instance.WriteLine(string.Format("MINING Hammer Read Voxel Complete: {0}ms", (DateTime.Now - start).TotalMilliseconds));

                Dictionary <MyVoxelMaterialDefinition, List <NaniteMiningItem> > oreList = new Dictionary <MyVoxelMaterialDefinition, List <NaniteMiningItem> >();
                Dictionary <Vector3D, NaniteMiningItem> oreLocations = new Dictionary <Vector3D, NaniteMiningItem>();

                foreach (var item in miningItems.Values)
                {
                    var def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(item.VoxelMaterial);
                    if (!oreList.ContainsKey(def))
                    {
                        oreList.Add(def, new List <NaniteMiningItem>());
                    }

                    //if (oreList[def].Count >= 1000)
                    //    continue;

                    oreList[def].Add(item);
                    //oreLocations.Add(item.Position, item);
                }

                m_oreListCache.Clear();
                if (oreList != null)
                {
                    foreach (var item in oreList)
                    {
                        m_oreListCache.Append(string.Format("{0} - {1:N0} Kg\r\n", item.Key.MinedOre, CalculateAmount(item.Key, item.Value.Sum(x => x.Amount))));
                    }
                }

                //using (LocationLock.AcquireExclusiveUsing())
                //m_oreLocations = oreLocations;

                using (Lock.AcquireExclusiveUsing())
                    m_oreList = oreList;

                Logging.Instance.WriteLine(string.Format("MINING Hammer Scan Complete: {0}ms ({1} groups, {2} items)", (DateTime.Now - start).TotalMilliseconds, oreList.Count, oreList.Sum(x => x.Value.Count)));
            }
            catch (Exception ex)
            {
                Logging.Instance.WriteLine(string.Format("ScanVoxelWork() Error: {0}", ex.ToString()));
            }
        }
Example #13
0
        public void Update()
        {
            /*
             * // Debug shows mining area
             * var position = m_block.PositionComp.GetPosition();
             * var direction = Vector3D.Normalize(-m_block.PositionComp.WorldMatrix.Up);
             * var color = Color.Red;
             * for (int r = 0; r < NaniteConstructionManager.Settings.MiningDepth; r++)
             * {
             *  MatrixD matrix = MatrixD.CreateTranslation(position + (direction * NaniteConstructionManager.Settings.MiningRadius * r));
             *  MySimpleObjectDraw.DrawTransparentSphere(ref matrix, NaniteConstructionManager.Settings.MiningRadius, ref color, MySimpleObjectRasterizer.Solid, 20);
             * }
             */

            m_updateCount++;

            if (!m_initialize)
            {
                m_initialize = true;
                Initialize();

                if (!CheckWorking())
                {
                    return;
                }
            }

            if (Sync.IsClient)
            {
                foreach (var item in m_effects)
                {
                    if (IsWorking)
                    {
                        item.ActiveUpdate();
                    }
                    else
                    {
                        item.InactiveUpdate();
                    }
                }
            }

            if (Sync.IsServer)
            {
                if (DateTime.Now - m_syncLastUpdate > TimeSpan.FromSeconds(3))
                {
                    m_syncLastUpdate = DateTime.Now;
                    SendDetails();
                }
            }

            if (m_updateCount % 240 == 0)
            {
                if (!CheckWorking())
                {
                    m_working = false;
                    return;
                }

                m_working = true;
            }

            if (!m_working)
            {
                using (Lock.AcquireExclusiveUsing())
                    m_oreList = null;

                //using(LocationLock.AcquireExclusiveUsing())
                //    m_oreLocations.Clear();

                return;
            }

            if (DateTime.Now - m_lastUpdate > TimeSpan.FromSeconds(30) && !m_busy)
            {
                m_lastUpdate = DateTime.Now;
                m_working    = true;
                m_busy       = true;
                //m_block.SetEmissiveParts("Emissive-Beacon", Color.FromNonPremultiplied(new Vector4(0.3f, 0.15f, 0.0f, 1f)), 1f);
                //MyCubeBlockEmissive.SetEmissiveParts((MyEntity)m_block, 1.0f, Color.FromNonPremultiplied(new Vector4(0.3f, 0.15f, 0.0f, 1f)), Color.White);

                if (Sync.IsServer)
                {
                    MyAPIGateway.Parallel.Start(ScanVoxelWork, ScanVoxelComplete);
                }
            }

            //((IMyFunctionalBlock)m_block).RefreshCustomInfo();
        }
        public override void FindTargets(ref Dictionary <string, int> available)
        {
            if (!IsEnabled())
            {
                return;
            }

            ComponentsRequired.Clear();
            if (m_targetList.Count >= GetMaximumTargets())
            {
                if (PotentialTargetList.Count > 0)
                {
                    m_lastInvalidTargetReason = "Maximum targets reached.  Add more upgrades!";
                }

                return;
            }

            NaniteConstructionInventory inventoryManager = m_constructionBlock.InventoryManager;
            Vector3D sourcePosition = m_constructionBlock.ConstructionBlock.GetPosition();

            Dictionary <string, int> missing = new Dictionary <string, int>();

            using (Lock.AcquireExclusiveUsing())
            {
                var potentialList = m_potentialTargetList.OrderByDescending(x => GetMissingComponentCount(inventoryManager, (IMySlimBlock)x)).ToList();
                for (int r = potentialList.Count - 1; r >= 0; r--)
                {
                    if (m_constructionBlock.IsUserDefinedLimitReached())
                    {
                        m_lastInvalidTargetReason = "User defined maximum nanite limit reached";
                        return;
                    }

                    var item = (IMySlimBlock)potentialList[r];
                    if (TargetList.Contains(item))
                    {
                        continue;
                    }

                    missing.Clear();
                    item.GetMissingComponents(missing);
                    bool foundMissingComponents = true;

                    if (MyAPIGateway.Session.CreativeMode)
                    {
                        foundMissingComponents = true;
                    }
                    else if (missing.Count > 0)
                    {
                        foundMissingComponents = inventoryManager.CheckComponentsAvailable(ref missing, ref available);
                    }

                    if (foundMissingComponents && NaniteConstructionPower.HasRequiredPowerForNewTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock, this))
                    {
                        // Check to see if another block targetting this for construction
                        var  blockList = NaniteConstructionManager.GetConstructionBlocks((IMyCubeGrid)m_constructionBlock.ConstructionBlock.CubeGrid);
                        bool found     = false;
                        foreach (var block in blockList)
                        {
                            if (block.Targets.First(y => y is NaniteConstructionTargets).TargetList.Contains(item as IMySlimBlock))
                            {
                                found = true;
                                break;
                            }
                        }

                        if (found)
                        {
                            m_lastInvalidTargetReason = "Another factory has this block as a target";
                            continue;
                        }

                        m_potentialTargetList.RemoveAt(r);
                        m_targetList.Add(item);
                        var def = item.BlockDefinition as MyCubeBlockDefinition;
                        Logging.Instance.WriteLine(string.Format("ADDING Construction/Repair Target: conid={0} subtype={1} entityID={2} position={3}", m_constructionBlock.ConstructionBlock.EntityId, def.Id.SubtypeId, item.FatBlock != null ? item.FatBlock.EntityId : 0, item.Position));
                        if (m_targetList.Count >= GetMaximumTargets())
                        {
                            break;
                        }
                    }
                    else if (!foundMissingComponents)
                    {
                        foreach (var component in missing)
                        {
                            if (!ComponentsRequired.ContainsKey(component.Key))
                            {
                                ComponentsRequired.Add(component.Key, component.Value);
                            }
                            else
                            {
                                ComponentsRequired[component.Key] += component.Value;
                            }
                        }

                        m_lastInvalidTargetReason = "Missing components";
                    }
                    else if (!NaniteConstructionPower.HasRequiredPowerForNewTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock, this))
                    {
                        m_lastInvalidTargetReason = "Insufficient power for another target.";
                    }
                }
            }
        }
        public override void FindTargets(ref Dictionary <string, int> available)
        {
            m_lastInvalidTargetReason = "";

            if (!IsEnabled())
            {
                return;
            }

            if (TargetList.Count >= GetMaximumTargets())
            {
                if (PotentialTargetList.Count > 0)
                {
                    m_lastInvalidTargetReason = "Maximum targets reached.  Add more upgrades!";
                }

                return;
            }

            using (Lock.AcquireExclusiveUsing())
            {
                foreach (IMySlimBlock item in PotentialTargetList.ToList())
                {
                    if (m_constructionBlock.IsUserDefinedLimitReached())
                    {
                        m_lastInvalidTargetReason = "User defined maximum nanite limit reached";
                        return;
                    }

                    if (TargetList.Contains(item))
                    {
                        continue;
                    }

                    if (!NaniteConstructionPower.HasRequiredPowerForNewTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock, this))
                    {
                        m_lastInvalidTargetReason = "Insufficient power for another target.";
                        break;
                    }

                    if (item.CubeGrid.Closed || item.IsDestroyed || item.IsFullyDismounted || (item.FatBlock != null && item.FatBlock.Closed))
                    {
                        m_lastInvalidTargetReason = "Potential target is destroyed";
                        continue;
                    }

                    var  blockList = NaniteConstructionManager.GetConstructionBlocks((IMyCubeGrid)m_constructionBlock.ConstructionBlock.CubeGrid);
                    bool found     = false;
                    foreach (var block in blockList)
                    {
                        if (block.Targets.First(x => x is NaniteDeconstructionTargets).TargetList.Contains(item as IMySlimBlock))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        m_lastInvalidTargetReason = "Another factory has this block as a target";
                        continue;
                    }

                    /*
                     * var blocks = NaniteConstructionManager.NaniteBlocks.Select(x => x.Value).Where(y => y.ConstructionBlock.CubeGrid == m_constructionBlock.ConstructionBlock.CubeGrid && y.ConstructionBlock != m_constructionBlock.ConstructionBlock);
                     * Logging.Instance.WriteLine(string.Format("Count: {0}", blocks.Count()));
                     * var found = blocks.FirstOrDefault(x => x.Targets.First(y => y is NaniteDeconstructionTargets).TargetList.Contains(item)) != null;
                     * if (found)
                     * {
                     *  Logging.Instance.WriteLine("Found");
                     *  continue;
                     * }
                     */

                    PotentialTargetList.Remove(item);
                    TargetList.Add(item);

                    var def = item.BlockDefinition as MyCubeBlockDefinition;
                    Logging.Instance.WriteLine(string.Format("ADDING Deconstruction Target: conid={0} subtypeid={1} entityID={2} position={3}", m_constructionBlock.ConstructionBlock.EntityId, def.Id.SubtypeId, item.FatBlock != null ? item.FatBlock.EntityId : 0, item.Position));

                    if (TargetList.Count >= GetMaximumTargets())
                    {
                        break;
                    }
                }
            }
        }
        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()));
            }
        }