private int GetMissingComponentCount(NaniteConstructionInventory inventoryManager, IMySlimBlock block) { Dictionary <string, int> missing = new Dictionary <string, int>(); block.GetMissingComponents(missing); if (missing.Count == 0) { return(0); } Dictionary <string, int> available = new Dictionary <string, int>(); inventoryManager.GetAvailableComponents(ref available); for (int r = missing.Count - 1; r >= 0; r--) { var item = missing.ElementAt(r); if (available.ContainsKey(item.Key)) { int amount = Math.Min(item.Value, available[item.Key]); available[item.Key] -= amount; missing[item.Key] -= amount; } } return(missing.Sum(x => x.Value)); }
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, 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) { 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."; } } } }