// Shows a list of all available target-vessels and returns true, if the player has selected one: public bool DisplayList() { GUILayout.Label("<size=14><b>Target:</b></size>"); scrollPos = GUILayout.BeginScrollView(scrollPos, GUI.scrollStyle); string green = "#00FF00"; string red = "#FF0000"; // Build a list with all valid vessels: List <Vessel> validTargets = new List <Vessel>(); foreach (Vessel vessel in FlightGlobals.Vessels) { if (!TargetVessel.IsValidTarget(vessel)) { continue; } validTargets.Add(vessel); } if (selectedIndex >= validTargets.Count) { selectedIndex = -1; targetVessel = null; } if (validTargets.Count == 0) { // No valid targest available: GUILayout.Label("No valid targets in orbit."); } else { // Show list with all possible vessels: List <GUIContent> contents = new List <GUIContent>(); List <int> filteredIndices = new List <int>(); // Target-vessels which fall out of the defined filters will get noted here. int index = 0; foreach (Vessel vessel in validTargets) { bool filterThisTarget = false; if (!TargetVessel.IsValidTarget(vessel)) { continue; } List <string> descriptions = new List <string>(); descriptions.Add("<color=#F9FA86><b>" + vessel.vesselName + "</b></color><color=#FFFFFF>"); // Orbital-Parameters: descriptions.Add("<b>Apoapsis:</b> " + GUI.FormatAltitude(vessel.orbit.ApA) + ", <b>Periapsis:</b> " + GUI.FormatAltitude(vessel.orbit.PeA) + ", <b>MET:</b> " + GUI.FormatDuration(vessel.missionTime)); // Docking-Port Types: List <string> dockingPortsTranslated = new List <string>(); foreach (string dockingPortType in TargetVessel.GetVesselDockingPortTypes(vessel)) { dockingPortsTranslated.Add(TargetVessel.TranslateDockingPortName(dockingPortType)); } if (dockingPortsTranslated.Count > 0) { descriptions.Add("<b>Docking-Ports:</b> " + string.Join(", ", dockingPortsTranslated.ToArray())); } // Resources: double capacity = 0; foreach (PayloadResource availableResource in TargetVessel.GetFreeResourcesCapacities(vessel)) { capacity += availableResource.amount * availableResource.mass; } if (capacity > 0) { descriptions.Add("<b>Resource Capacity:</b> " + capacity.ToString("#,##0.00t")); } // Crew: int seats = TargetVessel.GetCrewCapacity(vessel); int crew = TargetVessel.GetCrew(vessel).Count; if (seats > 0) { descriptions.Add("<b>Crew:</b> " + crew.ToString() + "/" + seats.ToString()); } // Maybe apply additional filters and show their attributes: List <string> filterAttributes = new List <string>();; if (filterVesselType != null) { bool isValidType = vessel.vesselType == (VesselType)filterVesselType; string color = isValidType ? green : red; filterAttributes.Add("<b>Type:</b> <color=" + color + ">" + vessel.vesselType.ToString() + "</color>"); if (!isValidType) { filterThisTarget = true; } } if (filterHasCrewTrait != null) { int traitCount = TargetVessel.GetCrewCountWithTrait(vessel, filterHasCrewTrait); int requiredCount = 1; if (filterHasCrewTraitCount != null) { requiredCount = (int)filterHasCrewTraitCount; } string color = traitCount >= requiredCount ? green : red; filterAttributes.Add("<b>" + filterHasCrewTrait + "s:</b> <color=" + color + ">" + traitCount.ToString() + "/" + requiredCount.ToString() + "</color>"); if (traitCount < requiredCount) { filterThisTarget = true; } } if (filterAttributes.Count > 0) { descriptions.Add(String.Join(" ", filterAttributes.ToArray())); } contents.Add(new GUIContent(String.Join("\n", descriptions.ToArray()) + "</color>")); if (filterThisTarget) { filteredIndices.Add(index); // If there were filters, which did not match, we still show the target, but don't allow to select it. } index++; } int newSelection = GUILayout.SelectionGrid(selectedIndex, contents.ToArray(), 1, GUI.selectionGridStyle); if (newSelection >= 0 && !filteredIndices.Contains(newSelection)) { // The player has selected a payload: selectedIndex = newSelection; targetVessel = validTargets[selectedIndex]; } } GUILayout.EndScrollView(); return(targetVessel != null); }
private static bool DisplayInner() { // Payload selection: if (payloadShipSelector == null) { payloadShipSelector = new GUIPayloadShipSelector(); } if (payloadShipSelector.payload == null) { payloadShipSelector.DisplayList(); return(false); } if (payloadShipSelector.DisplaySelected()) { targetVesselSelector = null; missionProfileSelector = null; crewTransferSelector = null; flagSelector = null; return(false); } currentCost += payloadShipSelector.payload.template.totalCost; var dryMass = payloadShipSelector.payload.GetDryMass(); double totalMass = payloadShipSelector.payload.template.totalMass; var engineersRequired = (int)Math.Ceiling(Math.Log(Math.Ceiling(dryMass / 10)) / Math.Log(2)) + 1; // One engineer can construct up to 10t, each additional engineer doubles that number // Target (space-dock) selection: if (targetVesselSelector == null) { targetVesselSelector = new GUITargetVesselSelector(); targetVesselSelector.filterVesselType = VesselType.Station; targetVesselSelector.filterHasCrewTrait = "Engineer"; // There does not seem to be an enum for this. targetVesselSelector.filterHasCrewTraitCount = engineersRequired; } if (targetVesselSelector.targetVessel == null) { targetVesselSelector.DisplayList(); return(false); } if (targetVesselSelector.DisplaySelected()) { missionProfileSelector = null; crewTransferSelector = null; flagSelector = null; return(false); } // Mission-Profile selection: if (missionProfileSelector == null) { missionProfileSelector = new GUIMissionProfileSelector(); missionProfileSelector.filterAltitude = targetVesselSelector.targetVessel.orbit.ApA; missionProfileSelector.filterBody = targetVesselSelector.targetVessel.orbit.referenceBody; missionProfileSelector.filterDockingPortTypes = TargetVessel.GetVesselDockingPortTypes(targetVesselSelector.targetVessel); missionProfileSelector.filterMissionType = MissionProfileType.TRANSPORT; shipName = payloadShipSelector.payload.template.shipName; } if (missionProfileSelector.selectedProfile == null) { missionProfileSelector.DisplayList(); return(false); } if (missionProfileSelector.DisplaySelected()) { crewTransferSelector = null; flagSelector = null; return(false); } if (crewTransferSelector == null) { crewTransferSelector = new GUICrewTransferSelector(payloadShipSelector.payload, missionProfileSelector.selectedProfile); } if (flagSelector == null) { flagSelector = new GUIFlagSelector(); } // Display Construction-Info: scrollPos = GUILayout.BeginScrollView(scrollPos, GUI.scrollStyle); GUILayout.Label("<size=14><b>Construction Info:</b></size>"); GUILayout.BeginHorizontal(); GUILayout.Label("Ship name:", new GUIStyle(GUI.labelStyle) { stretchWidth = true }); shipName = GUILayout.TextField(shipName, new GUIStyle(GUI.textFieldStyle) { alignment = TextAnchor.MiddleRight, stretchWidth = false, fixedWidth = 320 }); GUILayout.EndHorizontal(); // Calculate and display all the construction-parameters: var engineers = TargetVessel.GetCrewCountWithTrait(targetVesselSelector.targetVessel, "Engineer"); var scientists = TargetVessel.GetCrewCountWithTrait(targetVesselSelector.targetVessel, "Scientist"); if (engineers < engineersRequired) { throw new Exception("not enough engineers on target vessel"); } if (missionProfileSelector.selectedProfile.payloadMass <= 0) { throw new Exception("mission profile payload too low"); } var flights = (int)Math.Ceiling(totalMass / missionProfileSelector.selectedProfile.payloadMass); var flightTime = missionProfileSelector.selectedProfile.missionDuration; var totalFlightTime = flightTime * flights; var baseConstructionTime = dryMass * 6 * 60 * 60; // 1 (kerbin-) day / ton var totalFlightCost = missionProfileSelector.selectedProfile.launchCost * flights; currentCost += totalFlightCost; constructionTime = baseConstructionTime; if (scientists > 0) { constructionTime = baseConstructionTime / (scientists + 1); // half the time per scientist } if (totalFlightTime > constructionTime) { constructionTime = totalFlightTime; } var leftLabel = new GUIStyle(GUI.labelStyle) { stretchWidth = true }; var rightLabel = new GUIStyle(GUI.labelStyle) { stretchWidth = false, alignment = TextAnchor.MiddleRight }; GUILayout.BeginHorizontal(); GUILayout.Label("Mass:", leftLabel); GUILayout.Label(totalMass.ToString("#,##0.00t") + " / " + dryMass.ToString("#,##0.00t") + " dry", rightLabel); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Dock-Capacity (" + engineers.ToString() + " engineer" + (engineers != 1 ? "s" : "") + "):", leftLabel); GUILayout.Label((Math.Pow(2, engineers - 1) * 10).ToString("#,##0.00t") + " dry", rightLabel); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Single Flight (" + (missionProfileSelector.selectedProfile.launchCost / missionProfileSelector.selectedProfile.payloadMass).ToString("#,##0 √/t") + "):", leftLabel); GUILayout.Label(missionProfileSelector.selectedProfile.payloadMass.ToString("#,##0.00t") + " in " + GUI.FormatDuration(flightTime) + " for " + missionProfileSelector.selectedProfile.launchCost.ToString("#,##0 √"), rightLabel); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Total Flights:", leftLabel); GUILayout.Label(flights.ToString("#,##0") + " in " + GUI.FormatDuration(totalFlightTime) + " for " + totalFlightCost.ToString("#,##0 √"), rightLabel); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Base Construction Time (6h/t):", leftLabel); GUILayout.Label(GUI.FormatDuration(baseConstructionTime), rightLabel); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Total Construction Time (" + scientists.ToString() + " scientist" + (scientists != 1 ? "s" : "") + "):", leftLabel); GUILayout.Label(GUI.FormatDuration(constructionTime), rightLabel); GUILayout.EndHorizontal(); // Display crew-selector, if the new ship can hold kerbals: var selectionIsValid = true; if (payloadShipSelector.payload.GetCrewCapacity() > 0) { GUILayout.Label(""); GUILayout.Label("<size=14><b>Crew:</b></size>"); if (!crewTransferSelector.DisplayList()) { selectionIsValid = false; } } // Show Button for Flag-Selector: GUILayout.Label(""); flagSelector.ShowButton(); GUILayout.EndScrollView(); return(selectionIsValid); }