internal double MaxPumpAmt() { double maxPumpAmount = 0; if (FromParts == null || ToParts == null || FromParts.Count == 0 || ToParts.Count == 0) { return(maxPumpAmount); } List <Part> .Enumerator toList = ToParts.GetEnumerator(); List <Part> .Enumerator fromList = FromParts.GetEnumerator(); double fromAmount = 0; double toCapacityRemaining = 0; while (fromList.MoveNext()) { if (fromList.Current == null) { continue; } fromAmount += fromList.Current.Resources[Resource].amount; } fromList.Dispose(); while (toList.MoveNext()) { if (toList.Current == null) { continue; } toCapacityRemaining += PartRemainingCapacity(toList.Current, Resource); } toList.Dispose(); maxPumpAmount = toCapacityRemaining - fromAmount; maxPumpAmount = maxPumpAmount > fromAmount ? fromAmount : maxPumpAmount; maxPumpAmount = maxPumpAmount < SMSettings.Tolerance ? 0 : maxPumpAmount; return(maxPumpAmount); }
internal void CrewTransferStopAction() { // This adds the kerbal(s) to the destination part(s) if (FromCrewMember != null) { try { // Add Source Crewmember to target part if (FromCrewMember != null && ToPart.CrewCapacity > ToPart.protoModuleCrew.Count) { AddCrewMember(FromCrewMember, ToPart, ToSeat); } // Add Target Crewmember to source part if (ToCrewMember != null && FromPart.CrewCapacity > FromPart.protoModuleCrew.Count) { AddCrewMember(ToCrewMember, FromPart, FromSeat); } } catch (Exception ex) { SmUtils.LogMessage( $"in CrewTransferAction. Error moving crewmember. Error: {ex.Message} \r\n\r\n{ex.StackTrace}", SmUtils.LogType.Error, true); } } else { // Must be multi-crew... try { List <Part> .Enumerator toPart = ToParts.GetEnumerator(); int crewIdx = 0; while (toPart.MoveNext()) { if (toPart.Current == null) { continue; } // Add Source Crewmember(s) to target part if (toPart.Current.CrewCapacity <= toPart.Current.protoModuleCrew.Count) { continue; } int space = toPart.Current.CrewCapacity - toPart.Current.protoModuleCrew.Count; for (int idx = 0; idx < space; idx++) { if (crewIdx > FromCrewMembers.Count - 1) { break; } AddCrewMember(FromCrewMembers[crewIdx], toPart.Current); crewIdx++; } } toPart.Dispose(); } catch (Exception ex) { SmUtils.LogMessage( $"in CrewTransferAction. Error moving crewmember. Error: {ex.Message} \r\n\r\n{ex.StackTrace}", SmUtils.LogType.Error, true); } } }
/// <summary> /// Fill the ToParts with the cycleAmount /// This method assumes the cycleAmount can be applied. /// </summary> /// <param name="cycleAmount"></param> internal void FillParts(double cycleAmount) { //Utilities.LogMessage("Entering: TransferPump.FillParts", Utilities.LogType.Info, SMSettings.VerboseLogging); // To parts. Used only by Transfers if (cycleAmount < SMSettings.Tolerance) { return; } double cycleBalance = cycleAmount; while (cycleBalance > SMSettings.Tolerance) { // calc average of parts in list. double toPartAvgAmt = cycleAmount / ToParts.Count; // reduce to the smallest container. double minAmt = toPartAvgAmt; int remainingPartsCount = 0; List <Part> .Enumerator theseParts = ToParts.GetEnumerator(); while (theseParts.MoveNext()) { if (theseParts.Current == null) { continue; } double thisPartCap = PartRemainingCapacity(theseParts.Current, Resource); if (thisPartCap <= SMSettings.Tolerance) { continue; } if (thisPartCap >= minAmt) { remainingPartsCount++; continue; } minAmt = thisPartCap; remainingPartsCount++; } theseParts.Dispose(); //Utilities.LogMessage(string.Format("Inside: TransferPump.FillParts: toPartAmt = {0}, minAmt = {1}, PartsLeft = {2}, cycleBalance = {3}", toPartAmt, minAmt[0], toPartCount, cycleBalance), Utilities.LogType.Info, SMSettings.VerboseLogging); // Calculate pump amounts for each To part and Increment. if (remainingPartsCount > 0) { List <Part> .Enumerator toParts = ToParts.GetEnumerator(); while (toParts.MoveNext()) { if (toParts.Current == null) { continue; } if (PartRemainingCapacity(toParts.Current, Resource) <= SMSettings.Tolerance) { continue; } Part part = toParts.Current; part.Resources[Resource].amount += minAmt; cycleBalance -= minAmt; // Ensure part is capped and does not contain more than allowed. if (part.Resources[Resource].amount > part.Resources[Resource].maxAmount) { part.Resources[Resource].amount = part.Resources[Resource].maxAmount; } } toParts.Dispose(); } //Utilities.LogMessage(string.Format("Inside: TransferPump.FillParts: toPartAmt = {0}, minAmt = {1}, PartsLeft = {2}, cycleBalance = {3}", toPartAmt, minAmt[0], toPartCount, cycleBalance), Utilities.LogType.Info, SMSettings.VerboseLogging); if (remainingPartsCount == 0 && cycleBalance > SMSettings.Tolerance) { cycleBalance = 0; } } }
/// <summary> /// Fill the ToParts with the cycleAmount /// This method assumes the cycleAmount can be applied. /// </summary> /// <param name="cycleAmount"></param> internal void FillParts(double cycleAmount) { //Utilities.LogMessage("Entering: TransferPump.FillParts", Utilities.LogType.Info, SMSettings.VerboseLogging); // To parts. Used only by Transfers if (cycleAmount < SMSettings.Tolerance) { return; } double cycleBalance = cycleAmount; while (cycleBalance > SMSettings.Tolerance) { // find minimum but positive remaining capacity or single tank! double minAmt = Double.MaxValue; List <Part> .Enumerator theseParts = ToParts.GetEnumerator(); List <Part> nonFullParts = new List <Part>(); while (theseParts.MoveNext()) { Part part = theseParts.Current; if (part == null) { continue; } double thisPartCap = PartRemainingCapacity(part, Resource); if (thisPartCap <= SMSettings.Tolerance) { continue; } if (thisPartCap < minAmt) { minAmt = thisPartCap; } nonFullParts.Add(part); } theseParts.Dispose(); //Utilities.LogMessage(string.Format("Inside: TransferPump.FillParts: toPartAmt = {0}, minAmt = {1}, PartsLeft = {2}, cycleBalance = {3}", toPartAmt, minAmt[0], toPartCount, cycleBalance), Utilities.LogType.Info, SMSettings.VerboseLogging); // Calculate pump amounts for each To part and Increment. if (nonFullParts.Count > 0) { double toTransfer = Math.Min(cycleBalance / nonFullParts.Count, minAmt); List <Part> .Enumerator toParts = nonFullParts.GetEnumerator(); while (toParts.MoveNext()) { Part part = toParts.Current; part.Resources[Resource].amount += toTransfer; cycleBalance -= toTransfer; // Ensure part is capped and does not contain more than allowed. if (part.Resources[Resource].amount > part.Resources[Resource].maxAmount) { part.Resources[Resource].amount = part.Resources[Resource].maxAmount; } } toParts.Dispose(); } //Utilities.LogMessage(string.Format("Inside: TransferPump.FillParts: toPartAmt = {0}, minAmt = {1}, PartsLeft = {2}, cycleBalance = {3}", toPartAmt, minAmt[0], toPartCount, cycleBalance), Utilities.LogType.Info, SMSettings.VerboseLogging); if (nonFullParts.Count == 0 && cycleBalance > SMSettings.Tolerance) { cycleBalance = 0; } } }