private bool UpdateProjection(MyCubeBlock projector, MyCubeGrid projectedGrid, MyObjectBuilder_ProjectorBase projectorBuilder)
        {
            // god f*****g damnit object builders
            MyCubeGrid cubeGrid = projector.CubeGrid;
            MyObjectBuilder_CubeGrid gridBuilder = (MyObjectBuilder_CubeGrid)projectedGrid.GetObjectBuilder();
            bool found = false;

            foreach (MyObjectBuilder_CubeBlock blockBuilder in gridBuilder.CubeBlocks)
            {
                Vector3  worldPosition = projectedGrid.GridIntegerToWorld(blockBuilder.Min);
                Vector3I realPosition  = cubeGrid.WorldToGridInteger(worldPosition);
                var      realBlock     = (IMySlimBlock)cubeGrid.GetCubeBlock(realPosition);

                MyCubeBlockDefinition blockDefinition;
                MyDefinitionManager.Static.TryGetCubeBlockDefinition(blockBuilder.GetId(), out blockDefinition);
                if (realBlock != null) // && blockDefinition.Id == new MyDefinitionId(realBlock.GetType()))
                {
                    //Logging.Instance.WriteLine(string.Format("Found overlap - {0} {1}", blockBuilder.GetId(), realBlock.GetObjectBuilder().GetId()));
                }
                else
                {
                    //Logging.Instance.WriteLine(string.Format("No block at position: {0}", blockBuilder.GetId()));
                    if (CanBuildBlock(blockBuilder, projectedGrid, projector, cubeGrid, projectorBuilder))
                    {
                        //Logging.Instance.WriteLine(string.Format("No block at position: {0}", blockBuilder.GetId()));
                        var slimBlock = (IMySlimBlock)projectedGrid.GetCubeBlock(blockBuilder.Min);
                        if (slimBlock != null && slimBlock.CubeGrid.GetPosition() != Vector3D.Zero)
                        {
                            //Logging.Instance.WriteLine(string.Format("Adding block: {0}", blockBuilder.GetId()));
                            PotentialTargetList.Add(slimBlock);
                            found = true;
                        }
                    }
                    else
                    {
                        using (m_lock.AcquireExclusiveUsing())
                        {
                            foreach (var item in blockDefinition.Components)
                            {
                                if (!ComponentsRequired.ContainsKey(item.Definition.Id.SubtypeName))
                                {
                                    ComponentsRequired.Add(item.Definition.Id.SubtypeName, item.Count);
                                }
                                else
                                {
                                    ComponentsRequired[item.Definition.Id.SubtypeName] += item.Count;
                                }
                            }
                        }
                    }
                }
            }

            return(found);
        }
Beispiel #2
0
        public override void FindTargets(ref Dictionary <string, int> available, List <NaniteConstructionBlock> blockList)
        {
            MyAPIGateway.Utilities.InvokeOnGameThread(() =>
            {
                m_lastInvalidTargetReason = "";
                ComponentsRequired.Clear();
            });

            var maxTargets = GetMaximumTargets();

            if (TargetList.Count >= maxTargets)
            {
                if (PotentialTargetList.Count > 0)
                {
                    InvalidTargetReason("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>();
            string LastInvalidTargetReason   = "";

            int TargetListCount = TargetList.Count;

            foreach (var item in PotentialTargetList.OrderBy(x => Vector3D.Distance(sourcePosition, EntityHelper.GetBlockPosition((IMySlimBlock)x))).ToList())
            {
                if (item == null || TargetList.Contains(item))
                {
                    continue;
                }

                missing = inventoryManager.GetProjectionComponents((IMySlimBlock)item);
                bool haveComponents = inventoryManager.CheckComponentsAvailable(ref missing, ref available);
                if ((MyAPIGateway.Session.CreativeMode || haveComponents) && m_constructionBlock.HasRequiredPowerForNewTarget(this) &&
                    ((IMySlimBlock)item).CubeGrid.GetPosition() != Vector3D.Zero)
                {
                    bool found = false;
                    foreach (var block in blockList.ToList())
                    {
                        if (block != null && block.GetTarget <NaniteProjectionTargets>().TargetList.Contains(item))
                        {
                            found = true;
                            LastInvalidTargetReason = "Another factory has this block as a target";
                            break;
                        }
                    }

                    if (found)
                    {
                        continue;
                    }

                    AddTarget(item);

                    IMySlimBlock slimBlock = (IMySlimBlock)item;
                    var          def       = slimBlock.BlockDefinition as MyCubeBlockDefinition;
                    Logging.Instance.WriteLine(string.Format("[Projection] 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), 1);

                    if (++TargetListCount >= maxTargets)
                    {
                        break;
                    }
                }
                else if (!haveComponents)
                {
                    LastInvalidTargetReason = "Missing components to start projected block";
                }

                else if (!m_constructionBlock.HasRequiredPowerForNewTarget(this))
                {
                    LastInvalidTargetReason = "Insufficient power for another target.";
                    break;
                }
            }
            if (LastInvalidTargetReason != "")
            {
                InvalidTargetReason(LastInvalidTargetReason);
            }
        }
        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;
            }

            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.";
                    }
                }
            }
        }