private void ProcessItem(object target)
        {
            var floating = target as IMyEntity;

            if (floating == null)
            {
                return;
            }

            if (Sync.IsServer)
            {
                if (!IsEnabled())
                {
                    Logging.Instance.WriteLine("CANCELLING Cleanup Target due to being disabled");
                    CancelTarget(floating);
                    return;
                }

                if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active)
                {
                    return;
                }

                if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock))
                {
                    Logging.Instance.WriteLine("CANCELLING Cleanup Target due to power shortage");
                    CancelTarget(floating);
                    return;
                }

                if (floating.Closed)
                {
                    CompleteTarget(floating);
                    return;
                }

                if (!m_targetTracker.ContainsKey(floating))
                {
                    m_constructionBlock.SendAddTarget(floating);
                }

                if (m_targetTracker.ContainsKey(floating))
                {
                    var trackedItem = m_targetTracker[floating];
                    if (MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - trackedItem.StartTime >= trackedItem.CarryTime &&
                        MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - trackedItem.LastUpdate > 2000)
                    {
                        trackedItem.LastUpdate = MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds;
                        if (!TransferFromTarget((IMyEntity)target))
                        {
                            Logging.Instance.WriteLine("CANCELLING Cleanup Target due to insufficient storage");
                            CancelTarget(floating);
                        }
                    }
                }
            }

            CreateFloatingParticle(floating);
        }
        private void ProcessProjectedItem(IMySlimBlock target)
        {
            if (Sync.IsServer)
            {
                if (target.CubeGrid.GetPosition() == Vector3D.Zero)
                {
                    Logging.Instance.WriteLine("CANCELLING Projection Target due to invalid position");
                    CancelTarget(target);
                    return;
                }

                if (!IsEnabled())
                {
                    Logging.Instance.WriteLine("CANCELLING Projection Target due to being disabled");
                    CancelTarget(target);
                    return;
                }

                if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock))
                {
                    Logging.Instance.WriteLine("CANCELLING Projection Target due to power shortage");
                    CancelTarget(target);
                    return;
                }

                if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active)
                {
                    return;
                }

                double distance = EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target);
                int    time     = (int)Math.Max(GetMinTravelTime() * 1000f, (distance / GetSpeed()) * 1000f);
                if (!m_targetBlocks.ContainsKey(target))
                {
                    NaniteProjectionTarget projectionTarget = new NaniteProjectionTarget();
                    projectionTarget.ParticleCount = 0;
                    projectionTarget.StartTime     = (int)MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds;
                    m_targetBlocks.Add(target, projectionTarget);
                    m_constructionBlock.SendAddTarget(target, TargetTypes.Projection, GetProjectorByBlock(target));
                }

                if (MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - m_targetBlocks[target].StartTime >= time / 2.5 && !m_targetBlocks[target].CheckInventory)
                {
                    m_targetBlocks[target].CheckInventory = true;
                    if (!m_constructionBlock.InventoryManager.ProcessMissingComponents(target))
                    {
                        Logging.Instance.WriteLine("CANCELLING Projection Target due to missing components");
                        CancelTarget(target);
                        return;
                    }
                }

                if (MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - m_targetBlocks[target].StartTime >= time / 2)
                {
                    //BuildBlock(target, (MyCubeBlock)m_constructionBlock.ConstructionBlock);
                    ProcessBuildBlock(target);
                    CompleteTarget(target);
                    return;
                }

                if (!m_potentialTargetList.Contains(target))
                {
                    Logging.Instance.WriteLine("COMPLETING Projection Target since potential target is missing");
                    CompleteTarget(target);
                    return;
                }
            }

            CreateProjectionParticle(target);
        }
        public override void FindTargets(ref Dictionary <string, int> available)
        {
            ComponentsRequired.Clear();

            if (!IsEnabled())
            {
                return;
            }

            if (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 (m_lock.AcquireExclusiveUsing())
            {
                foreach (var item in PotentialTargetList.OrderBy(x => Vector3D.Distance(sourcePosition, EntityHelper.GetBlockPosition((IMySlimBlock)x))))
                {
                    if (m_constructionBlock.IsUserDefinedLimitReached())
                    {
                        m_lastInvalidTargetReason = "User defined maximum nanite limit reached";
                        return;
                    }

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

                    missing = inventoryManager.GetProjectionComponents((IMySlimBlock)item);
                    bool haveComponents = inventoryManager.CheckComponentsAvailable(ref missing, ref available);
                    if (haveComponents && NaniteConstructionPower.HasRequiredPowerForNewTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock, this))
                    {
                        if (((IMySlimBlock)item).CubeGrid.GetPosition() == Vector3D.Zero)
                        {
                            m_lastInvalidTargetReason = "Target blocks grid is in an invalid position (Vector3D.Zero, this shouldn't happen!)";
                            continue;
                        }

                        var  blockList = NaniteConstructionManager.GetConstructionBlocks((IMyCubeGrid)m_constructionBlock.ConstructionBlock.CubeGrid);
                        bool found     = false;
                        foreach (var block in blockList)
                        {
                            if (block.GetTarget <NaniteProjectionTargets>().TargetList.Contains(item))
                            {
                                found = true;
                                break;
                            }
                        }

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

                        TargetList.Add(item);
                        IMySlimBlock slimBlock = (IMySlimBlock)item;
                        var          def       = slimBlock.BlockDefinition as MyCubeBlockDefinition;
                        Logging.Instance.WriteLine(string.Format("ADDING Projection Target: conid={0} subtypeid={1} entityID={2} position={3}", m_constructionBlock.ConstructionBlock.EntityId, def.Id.SubtypeId, slimBlock.FatBlock != null ? slimBlock.FatBlock.EntityId : 0, slimBlock.Position));
                        if (TargetList.Count >= GetMaximumTargets())
                        {
                            break;
                        }
                    }
                    else if (!haveComponents)
                    {
                        m_lastInvalidTargetReason = "Missing components to start projected block";
                    }
                    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)
        {
            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;
                        }
                    }
                }
            }
        }
Exemplo n.º 5
0
        private void ProcessItem(object miningTarget)
        {
            var target = miningTarget as NaniteMiningItem;

            if (target == null)
            {
                return;
            }

            if (Sync.IsServer)
            {
                if (!IsEnabled())
                {
                    Logging.Instance.WriteLine("CANCELLING Mining Target due to being disabled");
                    CancelTarget(target);
                    return;
                }

                if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active)
                {
                    return;
                }

                if (!target.MiningHammer.IsWorking)
                {
                    Logging.Instance.WriteLine("CANCELLING Mining Target due to hammer functionality change");
                    CancelTarget(target);
                    return;
                }

                if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock))
                {
                    Logging.Instance.WriteLine("CANCELLING Mining Target due to power shortage");
                    CancelTarget(target);
                    return;
                }

                if (!m_targetTracker.ContainsKey(target))
                {
                    m_constructionBlock.SendAddTarget(target);
                }

                if (m_targetTracker.ContainsKey(target))
                {
                    var trackedItem = m_targetTracker[target];
                    if (MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - trackedItem.StartTime >= trackedItem.CarryTime &&
                        MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - trackedItem.LastUpdate > 2000)
                    {
                        trackedItem.LastUpdate = MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds;

                        if (!TransferFromTarget(target))
                        {
                            CancelTarget(target);
                        }
                        else
                        {
                            CompleteTarget(target);
                        }
                    }
                }
            }

            CreateMiningParticles(target);
        }
Exemplo n.º 6
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));
        }
        private void ProcessConstructionItem(IMySlimBlock target)
        {
            if (Sync.IsServer)
            {
                if (!IsEnabled())
                {
                    Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to being disabled");
                    CancelTarget(target);
                    return;
                }

                if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock))
                {
                    Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to power shortage");
                    CancelTarget(target);
                    return;
                }

                if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active)
                {
                    return;
                }

                if (!m_targetBlocks.ContainsKey(target))
                {
                    m_targetBlocks.Add(target, 0);
                }

                NaniteWelder welder = (NaniteWelder)m_constructionBlock.ToolManager.Tools.FirstOrDefault(x => x.TargetBlock == target && x is NaniteWelder);
                if (welder == null)
                {
                    double distance = EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target);
                    int    time     = (int)Math.Max(GetMinTravelTime() * 1000f, (distance / GetSpeed()) * 1000f);
                    welder = new NaniteWelder(m_constructionBlock, target, (int)(time / 2.5f), false);
                    m_constructionBlock.ToolManager.Tools.Add(welder);
                    m_constructionBlock.SendAddTarget(target, TargetTypes.Construction);
                }

                if (target.IsFullIntegrity && !target.HasDeformation)
                {
                    CompleteTarget(target);
                    return;
                }

                if (m_areaTargetBlocks.ContainsKey(target))
                {
                    BoundingBoxD bb;
                    target.GetWorldBoundingBox(out bb, true);
                    if (!m_areaTargetBlocks[target].IsInsideBox(bb))
                    {
                        CancelTarget(target);
                        return;
                    }
                }

                if (target.IsDestroyed || target.IsFullyDismounted || (target.FatBlock != null && target.FatBlock.Closed))
                {
                    Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to target being destroyed");
                    CancelTarget(target);
                    return;
                }

                if (welder != null && MyAPIGateway.Session.ElapsedPlayTime.TotalMilliseconds - welder.StartTime >= welder.WaitTime)
                {
                    target.MoveItemsToConstructionStockpile(((MyEntity)m_constructionBlock.ConstructionBlock).GetInventory());
                    Dictionary <string, int> missing = new Dictionary <string, int>();
                    target.GetMissingComponents(missing);

                    if (!target.HasDeformation && !target.CanContinueBuild(((MyEntity)m_constructionBlock.ConstructionBlock).GetInventory()))
                    {
                        if (!MyAPIGateway.Session.CreativeMode)
                        {
                            Logging.Instance.WriteLine("CANCELLING Construction/Repair Target due to missing components");
                            foreach (var item in missing)
                            {
                                Logging.Instance.WriteLine(string.Format("Missing component: {0} - {1}", item.Value, item.Key));
                            }
                            CancelTarget(target);
                        }
                    }

                    return;
                }

                bool isRemote = false;
                using (m_remoteLock.AcquireExclusiveUsing())
                {
                    isRemote = m_remoteTargets.Contains(target);
                }

                if (isRemote && EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target) > m_maxDistance)
                {
                    Logging.Instance.WriteLine("CANCELLING Repair Target due to target being out of range");
                    CancelTarget(target);
                    return;
                }
            }

            CreateConstructionParticle(target);
        }
        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.";
                    }
                }
            }
        }
        private void ProcessItem(IMySlimBlock target)
        {
            if (Sync.IsServer)
            {
                if (!IsEnabled())
                {
                    Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to being disabled");
                    CancelTarget(target);
                    return;
                }

                if (!NaniteConstructionPower.HasRequiredPowerForCurrentTarget((IMyFunctionalBlock)m_constructionBlock.ConstructionBlock))
                {
                    Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to power shortage");
                    CancelTarget(target);
                    return;
                }

                if (m_constructionBlock.FactoryState != NaniteConstructionBlock.FactoryStates.Active)
                {
                    return;
                }

                NaniteGrinder grinder = (NaniteGrinder)m_constructionBlock.ToolManager.Tools.FirstOrDefault(x => x.TargetBlock == target && x is NaniteGrinder);
                if (grinder == null)
                {
                    double distance = EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target);
                    int    time     = (int)Math.Max(GetMinTravelTime() * 1000f, (distance / GetSpeed()) * 1000f);
                    grinder = new NaniteGrinder(m_constructionBlock, target, (int)(time / 2.5f), NaniteConstructionManager.Settings.DeconstructionPerformanceFriendly);
                    m_constructionBlock.ToolManager.Tools.Add(grinder);
                    m_constructionBlock.SendAddTarget(target, TargetTypes.Deconstruction);
                }

                if (m_areaTargetBlocks.ContainsKey(target.CubeGrid))
                {
                    if (!m_areaTargetBlocks[target.CubeGrid].IsInsideBox(target.CubeGrid.WorldAABB, false))
                    {
                        CancelTarget(target);
                        RemoveGridTarget(target.CubeGrid);
                        return;
                    }

                    if (target.CubeGrid.Physics.LinearVelocity.LengthSquared() != 0f || target.CubeGrid.Physics.AngularVelocity.LengthSquared() != 0f)
                    {
                        CancelTarget(target);
                        return;
                    }
                }

                if (target.IsDestroyed || target.IsFullyDismounted || target.CubeGrid.GetCubeBlock(target.Position) == null || (target.FatBlock != null && target.FatBlock.Closed))
                {
                    CompleteTarget(target);
                    return;
                }

                if (target.CubeGrid.Closed)
                {
                    Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to grid being closed");
                    CancelTarget(target);
                    return;
                }

                if (EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, target) > m_maxDistance)
                {
                    Logging.Instance.WriteLine("CANCELLING Deconstruction Target due to target being out of range");
                    CancelTarget(target);
                    return;
                }
            }

            CreateDeconstructionParticle(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;
                    }
                }
            }
        }