public static void Display() { if (!initialized) { Initialize(); } Vessel vessel = FlightGlobals.ActiveVessel; FlightRecording recording = null; if (vessel) { recording = FlightRecoorder.GetFlightRecording(vessel); } if (!vessel || recording == null) { Reset(); // Show list of recorded profiles: missionProfileSelector.DisplayList(); if (missionProfileSelector.selectedProfile != null) { if (missionProfileSelector.selectedProfile != lastSelectedProfile) { // The selecte profile was switched: lastSelectedProfile = missionProfileSelector.selectedProfile; newMissionProfileName = missionProfileSelector.selectedProfile.profileName; } GUILayout.BeginHorizontal(); GUILayout.Label("<size=14><b>Profile name:</b></size>", new GUIStyle(GUI.labelStyle) { stretchWidth = false }); newMissionProfileName = GUILayout.TextField(newMissionProfileName, new GUIStyle(GUI.textFieldStyle) { stretchWidth = true }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Save Profile", GUI.buttonStyle)) { MissionController.ChangeMissionProfileName(missionProfileSelector.selectedProfile.profileName, newMissionProfileName); missionProfileSelector = new GUIMissionProfileSelector(); // Deselect & Reset } if (GUILayout.Button("Delete Profile", GUI.buttonStyle)) { MissionController.DeleteMissionProfile(missionProfileSelector.selectedProfile.profileName); missionProfileSelector = new GUIMissionProfileSelector(); // Deselect & Reset } GUILayout.EndHorizontal(); } } else { // During the recording, allow the player to change the name of the new flight-profile: GUILayout.BeginHorizontal(); GUILayout.Label("<size=14><b>Profile name:</b></size>", new GUIStyle(GUI.labelStyle) { stretchWidth = false }); if (recording.status != FlightRecordingStatus.PRELAUNCH) { recording.profileName = GUILayout.TextField(recording.profileName, new GUIStyle(GUI.textFieldStyle) { stretchWidth = true }); } else { GUILayout.Label(recording.profileName, new GUIStyle(GUI.labelStyle) { stretchWidth = true }); } GUILayout.EndHorizontal(); // Display all Information about the current recording: GUILayout.BeginScrollView(new Vector2(0, 0), new GUIStyle(GUI.scrollStyle) { stretchHeight = true }); List <KeyValuePair <string, string> > displayAttributes = recording.GetDisplayAttributes(); foreach (KeyValuePair <string, string> displayAttribute in displayAttributes) { GUILayout.BeginHorizontal(); GUILayout.Label("<b>" + displayAttribute.Key + "</b>"); GUILayout.Label(displayAttribute.Value + " ", new GUIStyle(GUI.labelStyle) { alignment = TextAnchor.MiddleRight }); GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); // Display payload selector: if (recording.status == FlightRecordingStatus.ASCENDING || recording.status == FlightRecordingStatus.PRELAUNCH) { GUILayout.BeginHorizontal(); GUILayout.Label("<size=14><b>Mission Type:</b></size>"); string[] missionTypeStrings = new string[] { "Deploy", "Transport" }; selectedMissionTypeTab = GUILayout.Toolbar(selectedMissionTypeTab, missionTypeStrings); GUILayout.EndHorizontal(); scrollPos = GUILayout.BeginScrollView(scrollPos, GUI.scrollStyle, GUILayout.Height(210), GUILayout.MaxHeight(210)); if (selectedMissionTypeTab == 0) { // Show all deployable payloads: if (!recording.CanPerformMission(MissionProfileType.DEPLOY)) { GUILayout.Label("Deployment missions can only be performed if the vessel has detachable parts which haven't been used during the flight (no resource consumption, inactive, uncrewed, etc)."); } else { // Show all detachable subassemblies: foreach (PayloadAssembly payloadAssembly in recording.GetPayloadAssemblies()) { GUILayout.BeginHorizontal(); if (GUILayout.Toggle(selectedPayloadAssemblyIds.Contains(payloadAssembly.id), "<b>" + payloadAssembly.name + "</b>")) { if (!selectedPayloadAssemblyIds.Contains(payloadAssembly.id)) { selectedPayloadAssemblyIds.Add(payloadAssembly.id); } } else if (selectedPayloadAssemblyIds.Contains(payloadAssembly.id)) { selectedPayloadAssemblyIds.Remove(payloadAssembly.id); } GUILayout.Label(payloadAssembly.partCount.ToString() + " parts, " + payloadAssembly.mass.ToString("#,##0.00 t") + " ", new GUIStyle(GUI.labelStyle) { alignment = TextAnchor.MiddleRight }); GUILayout.EndHorizontal(); } } } else { if (!recording.CanPerformMission(MissionProfileType.TRANSPORT)) { GUILayout.Label("Transport missions can only be performed with vessels which have at least one docking port as well as RCS thrusters."); } else { // Show all payload-resources: double totalPayloadMass = 0; foreach (PayloadResource payloadResource in recording.GetPayloadResources()) { double selectedAmount = 0; selectedPayloadDeploymentResources.TryGetValue(payloadResource.name, out selectedAmount); GUILayout.BeginHorizontal(); GUILayout.Label("<b>" + payloadResource.name + "</b>"); GUILayout.Label(((selectedAmount / payloadResource.amount) * 100).ToString("0.00") + "% (" + selectedAmount.ToString("#,##0.00") + " / " + payloadResource.amount.ToString("#,##0.00") + "): " + (selectedAmount * payloadResource.mass).ToString("#,##0.00 t") + " ", new GUIStyle(GUI.labelStyle) { alignment = TextAnchor.MiddleRight }); GUILayout.EndHorizontal(); selectedAmount = GUILayout.HorizontalSlider((float)selectedAmount, 0, (float)payloadResource.amount); if (selectedAmount < 0) { selectedAmount = 0; } if (selectedAmount > payloadResource.amount) { selectedAmount = payloadResource.amount; } if (payloadResource.amount - selectedAmount < 0.01) { selectedAmount = payloadResource.amount; } totalPayloadMass += selectedAmount * payloadResource.mass; if (selectedPayloadDeploymentResources.ContainsKey(payloadResource.name)) { selectedPayloadDeploymentResources[payloadResource.name] = selectedAmount; } else { selectedPayloadDeploymentResources.Add(payloadResource.name, selectedAmount); } } GUILayout.BeginHorizontal(); GUILayout.Label("<b>Total Payload</b>"); GUILayout.Label(totalPayloadMass.ToString("#,##0.00 t "), new GUIStyle(GUI.labelStyle) { alignment = TextAnchor.MiddleRight }); GUILayout.EndHorizontal(); } } GUILayout.EndScrollView(); } // Bottom pane with action-buttons: GUILayout.BeginHorizontal(); if (recording.status == FlightRecordingStatus.PRELAUNCH && GUILayout.Button("Record", GUI.buttonStyle)) { // Start Recording: FlightRecoorder.StartRecording(vessel); } if (recording.CanDeploy() && GUILayout.Button("Release Payload", GUI.buttonStyle)) { if (selectedMissionTypeTab == 0) { List <PayloadAssembly> payloadAssemblies = recording.GetPayloadAssemblies(); List <PayloadAssembly> selectedPayloadAssemblies = new List <PayloadAssembly>(); foreach (PayloadAssembly payloadAssembly in recording.GetPayloadAssemblies()) { if (selectedPayloadAssemblyIds.Contains(payloadAssembly.id)) { selectedPayloadAssemblies.Add(payloadAssembly); } } if (selectedPayloadAssemblies.Count > 0) { recording.DeployPayloadAssembly(selectedPayloadAssemblies); } } else { recording.DeployPayloadResources(selectedPayloadDeploymentResources); } } if (recording.CanFinish() && GUILayout.Button("Stop & Save", GUI.buttonStyle)) { // Stop recording and create a mission-profile: FlightRecoorder.SaveRecording(vessel); } if (recording.status != FlightRecordingStatus.PRELAUNCH && GUILayout.Button("Abort", GUI.buttonStyle)) { // Cancel runnig recording: FlightRecoorder.CancelRecording(vessel); } GUILayout.EndHorizontal(); } }
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); }
private static bool DisplayInner() { // Payload selection: if (payloadShipSelector == null) { payloadShipSelector = new GUIPayloadShipSelector(); } if (payloadShipSelector.payload == null) { payloadShipSelector.DisplayList(); return(false); } if (payloadShipSelector.DisplaySelected()) { missionProfileSelector = null; orbitEditor = null; crewTransferSelector = null; flagSelector = null; return(false); } currentCost += payloadShipSelector.payload.template.totalCost; // Mission-Profile selection: if (missionProfileSelector == null) { missionProfileSelector = new GUIMissionProfileSelector(); missionProfileSelector.filterMass = payloadShipSelector.payload.template.totalMass; missionProfileSelector.filterMissionType = MissionProfileType.DEPLOY; shipName = payloadShipSelector.payload.template.shipName; } if (missionProfileSelector.selectedProfile == null) { missionProfileSelector.DisplayList(); return(false); } if (missionProfileSelector.DisplaySelected()) { orbitEditor = null; crewTransferSelector = null; flagSelector = null; return(false); } currentCost += missionProfileSelector.selectedProfile.launchCost; // Mission-Parameters selection: if (orbitEditor == null) { orbitEditor = new GUIOrbitEditor(missionProfileSelector.selectedProfile); } if (crewTransferSelector == null) { crewTransferSelector = new GUICrewTransferSelector(payloadShipSelector.payload, missionProfileSelector.selectedProfile); } if (flagSelector == null) { flagSelector = new GUIFlagSelector(); } scrollPos = GUILayout.BeginScrollView(scrollPos, GUI.scrollStyle); GUILayout.Label("<size=14><b>Mission Parameters:</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(); orbitEditor.DisplayEditor(); // Display crew-selector, if the payload 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); }
private static bool DisplayInner() { // Target selection: if (targetVesselSelector == null) { targetVesselSelector = new GUITargetVesselSelector(); } if (targetVesselSelector.targetVessel == null) { targetVesselSelector.DisplayList(); return(false); } if (targetVesselSelector.DisplaySelected()) { missionProfileSelector = null; payloadResourceSelector = 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; } if (missionProfileSelector.selectedProfile == null) { missionProfileSelector.DisplayList(); return(false); } if (missionProfileSelector.DisplaySelected(GUIMissionProfileSelector.SELECTED_DETAILS_PAYLOAD)) { payloadResourceSelector = null; return(false); } currentCost += missionProfileSelector.selectedProfile.launchCost; // Payload-Resource selection: if (payloadResourceSelector == null) { payloadResourceSelector = new GUITransportSelector(targetVesselSelector.targetVessel, missionProfileSelector.selectedProfile); } payloadResourceSelector.DisplayList(); // Always display this selector (it has to be the last), but return when nothing is selected. if (payloadResourceSelector.selectedResources != null) { // Determine the cost of the selected resources: foreach (var payloadResource in payloadResourceSelector.selectedResources) { currentCost += KSTS.resourceDictionary[payloadResource.name].unitCost * payloadResource.amount; } return(true); } else if (payloadResourceSelector.selectedCrewTransfers != null) { return(true); } return(false); }