public void RemoveAttachedParts(HashSet <PartSim> partSims) { // Loop through the attached parts for (int i = 0; i < this.attachNodes.Count; i++) { AttachNodeSim attachSim = this.attachNodes[i]; // If the part is in the set then "remove" it by clearing the PartSim reference if (partSims.Contains(attachSim.attachedPartSim)) { attachSim.attachedPartSim = null; } } // Loop through the fuel targets (fuel line sources) for (int i = 0; i < this.fuelTargets.Count; i++) { PartSim fuelTargetSim = this.fuelTargets[i]; // If the part is in the set then "remove" it by clearing the PartSim reference if (fuelTargetSim != null && partSims.Contains(fuelTargetSim)) { this.fuelTargets[i] = null; } } // Loop through the surface attached fuel targets (surface attached parts for new flow modes) for (int i = 0; i < this.surfaceMountFuelTargets.Count; i++) { PartSim fuelTargetSim = this.surfaceMountFuelTargets[i]; // If the part is in the set then "remove" it by clearing the PartSim reference if (fuelTargetSim != null && partSims.Contains(fuelTargetSim)) { this.surfaceMountFuelTargets[i] = null; } } }
public static AttachNodeSim New(PartSim partSim, String newId, AttachNode.NodeType newNodeType) { AttachNodeSim nodeSim = pool.Borrow(); nodeSim.attachedPartSim = partSim; nodeSim.nodeType = newNodeType; nodeSim.id = newId; return(nodeSim); }
public void RemoveAttachedParts(HashSet <PartSim> partSims) { // Loop through the attached parts for (int i = 0; i < this.attachNodes.Count; i++) { AttachNodeSim attachSim = this.attachNodes[i]; // If the part is in the set then "remove" it by clearing the PartSim reference if (partSims.Contains(attachSim.attachedPartSim)) { attachSim.attachedPartSim = null; } } }
static private void Reset(AttachNodeSim attachNodeSim) { }
public void SetupAttachNodes(Dictionary <Part, PartSim> partSimLookup, LogMsg log) { if (log != null) { log.AppendLine("SetupAttachNodes for ", name, ":", partId); } attachNodes.Clear(); for (int i = 0; i < part.attachNodes.Count; ++i) { AttachNode attachNode = part.attachNodes[i]; if (log != null) { log.AppendLine("AttachNode ", attachNode.id, " = ", (attachNode.attachedPart != null ? attachNode.attachedPart.partInfo.name : "null")); } if (attachNode.attachedPart != null && attachNode.id != "Strut") { PartSim attachedSim; if (partSimLookup.TryGetValue(attachNode.attachedPart, out attachedSim)) { if (log != null) { log.AppendLine("Adding attached node ", attachedSim.name, ":", attachedSim.partId); } attachNodes.Add(AttachNodeSim.New(attachedSim, attachNode.id, attachNode.nodeType)); } else { if (log != null) { log.AppendLine("No PartSim for attached part (", attachNode.attachedPart.partInfo.name, ")"); } } } } for (int i = 0; i < part.fuelLookupTargets.Count; ++i) { Part p = part.fuelLookupTargets[i]; if (p != null) { PartSim targetSim; if (partSimLookup.TryGetValue(p, out targetSim)) { if (log != null) { log.AppendLine("Fuel target: ", targetSim.name, ":", targetSim.partId); } fuelTargets.Add(targetSim); } else { if (log != null) { log.AppendLine("No PartSim for fuel target (", p.name, ")"); } } } } }
// This is the old recursive function for STACK_PRIORITY_SEARCH public void GetSourceSet_Old(int type, bool includeSurfaceMountedParts, List <PartSim> allParts, HashSet <PartSim> visited, HashSet <PartSim> allSources, LogMsg log, String indent) { if (log != null) { log.Append(indent, "GetSourceSet_Old(", ResourceContainer.GetResourceName(type), ") for ") .AppendLine(name, ":", partId); indent += " "; } // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns as is. if (visited.Contains(this)) { if (log != null) { log.Append(indent, "Returning empty set, already visited (", name, ":") .AppendLine(partId + ")"); } return; } if (log != null) { log.AppendLine(indent, "Adding this to visited"); } visited.Add(this); // Rule 2: Part performs scan on start of every fuel pipe ending in it. This scan is done in order in which pipes were installed. // Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result. //MonoBehaviour.print("for each fuel line"); int lastCount = allSources.Count; for (int i = 0; i < this.fuelTargets.Count; i++) { PartSim partSim = this.fuelTargets[i]; if (partSim != null) { if (visited.Contains(partSim)) { if (log != null) { log.Append(indent, "Fuel target already visited, skipping (", partSim.name, ":") .AppendLine(partSim.partId, ")"); } } else { if (log != null) { log.Append(indent, "Adding fuel target as source (", partSim.name, ":") .AppendLine(partSim.partId, ")"); } partSim.GetSourceSet_Old(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent); } } } // check surface mounted fuel targets if (includeSurfaceMountedParts) { for (int i = 0; i < surfaceMountFuelTargets.Count; i++) { PartSim partSim = this.surfaceMountFuelTargets[i]; if (partSim != null) { if (visited.Contains(partSim)) { if (log != null) { log.Append(indent, "Fuel target already visited, skipping (", partSim.name, ":") .AppendLine(partSim.partId, ")"); } } else { if (log != null) { log.Append(indent, "Adding fuel target as source (", partSim.name, ":") .AppendLine(partSim.partId, ")"); } partSim.GetSourceSet_Old(type, true, allParts, visited, allSources, log, indent); } } } } if (allSources.Count > lastCount) { if (log != null) { log.Append(indent, "Returning ", (allSources.Count - lastCount), " fuel target sources (") .AppendLine(this.name, ":", this.partId, ")"); } return; } // Rule 3: This rule has been removed and merged with rules 4 and 7 to fix issue with fuel tanks with disabled crossfeed // Rule 4: Part performs scan on each of its axially mounted neighbors. // Couplers (bicoupler, tricoupler, ...) are an exception, they only scan one attach point on the single attachment side, // skip the points on the side where multiple points are. [Experiment] // Again, the part creates union of scan lists from each of its neighbor and if it is not empty, returns this list. // The order in which mount points of a part are scanned appears to be fixed and defined by the part specification file. [Experiment] if (fuelCrossFeed) { lastCount = allSources.Count; //MonoBehaviour.print("for each attach node"); for (int i = 0; i < this.attachNodes.Count; i++) { AttachNodeSim attachSim = this.attachNodes[i]; if (attachSim.attachedPartSim != null) { if (attachSim.nodeType == AttachNode.NodeType.Stack) { if ((string.IsNullOrEmpty(noCrossFeedNodeKey) == false && attachSim.id.Contains(noCrossFeedNodeKey)) == false) { if (visited.Contains(attachSim.attachedPartSim)) { if (log != null) { log.Append(indent, "Attached part already visited, skipping (", attachSim.attachedPartSim.name, ":") .AppendLine(attachSim.attachedPartSim.partId, ")"); } } else { if (log != null) { log.Append(indent, "Adding attached part as source (", attachSim.attachedPartSim.name, ":") .AppendLine(attachSim.attachedPartSim.partId, ")"); } attachSim.attachedPartSim.GetSourceSet_Old(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent); } } } } } if (allSources.Count > lastCount) { if (log != null) { log.Append(indent, "Returning " + (allSources.Count - lastCount) + " attached sources (") .AppendLine(this.name, ":", this.partId, ")"); } return; } } // Rule 5: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel // type was not disabled [Experiment]) and it contains fuel, it returns itself. // Rule 6: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel // type was not disabled) but it does not contain the requested fuel, it returns empty list. [Experiment] if (resources.HasType(type) && resourceFlowStates[type] > 0.0) { if (resources[type] > SimManager.RESOURCE_MIN) { allSources.Add(this); if (log != null) { log.Append(indent, "Returning enabled tank as only source (", name, ":") .AppendLine(partId, ")"); } return; } } else { if (log != null) { log.Append(indent, "Not fuel tank or disabled. HasType = ", resources.HasType(type)) .AppendLine(" FlowState = " + resourceFlowStates[type]); } } // Rule 7: If the part is radially attached to another part and it is child of that part in the ship's tree structure, it scans its // parent and returns whatever the parent scan returned. [Experiment] [Experiment] if (parent != null && parentAttach == AttachModes.SRF_ATTACH) { if (fuelCrossFeed) { if (visited.Contains(parent)) { if (log != null) { log.Append(indent, "Parent part already visited, skipping (", parent.name, ":") .AppendLine(parent.partId, ")"); } } else { lastCount = allSources.Count; this.parent.GetSourceSet_Old(type, includeSurfaceMountedParts, allParts, visited, allSources, log, indent); if (allSources.Count > lastCount) { if (log != null) { log.Append(indent, "Returning ", (allSources.Count - lastCount), " parent sources (") .AppendLine(this.name, ":", this.partId, ")"); } return; } } } } // Rule 8: If all preceding rules failed, part returns empty list. if (log != null) { log.Append(indent, "Returning empty set, no sources found (", name, ":") .AppendLine(partId, ")"); } return; }
public void GetSourceSet_Internal(int type, bool includeSurfaceMountedParts, List <PartSim> allParts, HashSet <PartSim> visited, HashSet <PartSim> allSources, ref int priMax, LogMsg log, String indent) { if (log != null) { log.Append(indent, "GetSourceSet_Internal(", ResourceContainer.GetResourceName(type), ") for ") .AppendLine(name, ":", partId); indent += " "; } // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns as is. if (visited.Contains(this)) { if (log != null) { log.Append(indent, "Nothing added, already visited (", name, ":") .AppendLine(partId + ")"); } return; } if (log != null) { log.AppendLine(indent, "Adding this to visited"); } visited.Add(this); // Rule 2: Part performs scan on start of every fuel pipe ending in it. This scan is done in order in which pipes were installed. // Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result. //MonoBehaviour.print("for each fuel line"); int lastCount = allSources.Count; for (int i = 0; i < this.fuelTargets.Count; i++) { PartSim partSim = this.fuelTargets[i]; if (partSim != null) { if (visited.Contains(partSim)) { if (log != null) { log.Append(indent, "Fuel target already visited, skipping (", partSim.name, ":") .AppendLine(partSim.partId, ")"); } } else { if (log != null) { log.Append(indent, "Adding fuel target as source (", partSim.name, ":") .AppendLine(partSim.partId, ")"); } partSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, ref priMax, log, indent); } } } if (fuelCrossFeed) { if (includeSurfaceMountedParts) { // check surface mounted fuel targets for (int i = 0; i < surfaceMountFuelTargets.Count; i++) { PartSim partSim = this.surfaceMountFuelTargets[i]; if (partSim != null) { if (visited.Contains(partSim)) { if (log != null) { log.Append(indent, "Surface part already visited, skipping (", partSim.name, ":") .AppendLine(partSim.partId, ")"); } } else { if (log != null) { log.Append(indent, "Adding surface part as source (", partSim.name, ":") .AppendLine(partSim.partId, ")"); } partSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, ref priMax, log, indent); } } } } lastCount = allSources.Count; //MonoBehaviour.print("for each attach node"); for (int i = 0; i < this.attachNodes.Count; i++) { AttachNodeSim attachSim = this.attachNodes[i]; if (attachSim.attachedPartSim != null) { if (attachSim.nodeType == AttachNode.NodeType.Stack) { if ((string.IsNullOrEmpty(noCrossFeedNodeKey) == false && attachSim.id.Contains(noCrossFeedNodeKey)) == false) { if (visited.Contains(attachSim.attachedPartSim)) { if (log != null) { log.Append(indent, "Attached part already visited, skipping (", attachSim.attachedPartSim.name, ":") .AppendLine(attachSim.attachedPartSim.partId, ")"); } } else { if (log != null) { log.Append(indent, "Adding attached part as source (", attachSim.attachedPartSim.name, ":") .AppendLine(attachSim.attachedPartSim.partId, ")"); } attachSim.attachedPartSim.GetSourceSet_Internal(type, includeSurfaceMountedParts, allParts, visited, allSources, ref priMax, log, indent); } } } } } } // If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel // type was not disabled) and it contains fuel, it adds itself. if (resources.HasType(type) && resourceFlowStates[type] > 0.0) { if (resources[type] > resRequestRemainingThreshold) { // Get the priority of this tank int pri = GetResourcePriority(); if (pri > priMax) { // This tank is higher priority than the previously added ones so we clear the sources // and set the priMax to this priority allSources.Clear(); priMax = pri; } // If this is the correct priority then add this to the sources if (pri == priMax) { if (log != null) { log.Append(indent, "Adding enabled tank as source (", name, ":") .AppendLine(partId, ")"); } allSources.Add(this); } } } else { if (log != null) { log.Append(indent, "Not fuel tank or disabled. HasType = ", resources.HasType(type)) .AppendLine(" FlowState = " + resourceFlowStates[type]); } } }
static private void Reset(AttachNodeSim attachNodeSim) { attachNodeSim.attachedPartSim = null; }
public void SetupAttachNodes(Dictionary <Part, PartSim> partSimLookup, LogMsg log) { if (log != null) { log.buf.AppendLine("SetupAttachNodes for " + this.name + ":" + this.partId + ""); } this.attachNodes.Clear(); for (int i = 0; i < this.part.attachNodes.Count; i++) { AttachNode attachNode = this.part.attachNodes[i]; if (log != null) { log.buf.AppendLine( "AttachNode " + attachNode.id + " = " + (attachNode.attachedPart != null ? attachNode.attachedPart.partInfo.name : "null")); } if (attachNode.attachedPart != null && attachNode.id != "Strut") { PartSim attachedSim; if (partSimLookup.TryGetValue(attachNode.attachedPart, out attachedSim)) { if (log != null) { log.buf.AppendLine("Adding attached node " + attachedSim.name + ":" + attachedSim.partId + ""); } AttachNodeSim attachnode = AttachNodeSim.New(attachedSim, attachNode.id, attachNode.nodeType); this.attachNodes.Add(attachnode); } else { if (log != null) { log.buf.AppendLine("No PartSim for attached part (" + attachNode.attachedPart.partInfo.name + ")"); } } } } for (int i = 0; i < this.part.fuelLookupTargets.Count; i++) { Part p = this.part.fuelLookupTargets[i]; if (p != null) { PartSim targetSim; if (partSimLookup.TryGetValue(p, out targetSim)) { if (log != null) { log.buf.AppendLine("Fuel target: " + targetSim.name + ":" + targetSim.partId); } this.fuelTargets.Add(targetSim); } else { if (log != null) { log.buf.AppendLine("No PartSim for fuel target (" + p.name + ")"); } } } } }
private static void Reset(AttachNodeSim attachNodeSim) { attachNodeSim.attachedPartSim = null; }