Example #1
0
        public static void CreateMissionProfile(Vessel vessel, FlightRecording recording)
        {
            var profile = MissionProfile.CreateFromRecording(vessel, recording);

            // Make the profile-name unique to use it as a key:
            profile.profileName = MissionController.GetUniqueProfileName(profile.profileName);

            MissionController.missionProfiles.Add(profile.profileName, profile);
            Log.Warning("saved new mission profile '" + profile.profileName + "'" + "   Total of " + MissionController.missionProfiles.Count + " missions saved");
        }
Example #2
0
        public static void CreateMissionProfile(Vessel vessel, FlightRecording recording)
        {
            var profile = MissionProfile.CreateFromRecording(vessel, recording);

            // Make the profile-name unique to use it as a key:
            profile.profileName = MissionController.GetUniqueProfileName(profile.profileName);

            MissionController.missionProfiles.Add(profile.profileName, profile);
            Debug.Log("[KSTS] saved new mission profile '" + profile.profileName + "'");
        }
Example #3
0
        public static void ChangeMissionProfileName(string name, string newName)
        {
            MissionProfile profile = null;

            if (!MissionController.missionProfiles.TryGetValue(name, out profile))
            {
                return;
            }
            MissionController.missionProfiles.Remove(name);
            profile.profileName = MissionController.GetUniqueProfileName(newName);
            MissionController.missionProfiles.Add(profile.profileName, profile);
        }
Example #4
0
 public override void OnSave(ConfigNode node)
 {
     try
     {
         FlightRecoorder.SaveRecordings(node);
         MissionController.SaveMissions(node);
     }
     catch (Exception e)
     {
         Debug.LogError("[KSTS] OnSave(): " + e.ToString());
     }
 }
Example #5
0
 public override void OnLoad(ConfigNode node)
 {
     try
     {
         FlightRecorder.LoadRecordings(node);
         MissionController.LoadMissions(node);
         GUI.Reset();
     }
     catch (Exception e)
     {
         Debug.LogError("[KSTS] OnLoad(): " + e.ToString());
     }
 }
Example #6
0
        // Is called when this Addon is first loaded to initializes all values (eg registration of event-handlers and creation
        // of original-stats library).
        public void Awake()
        {
            try
            {
                FlightRecoorder.Initialize();
                MissionController.Initialize();

                // Build dictionary of all parts for easier access:
                if (KSTS.partDictionary == null)
                {
                    KSTS.partDictionary = new Dictionary <string, AvailablePart>();
                    foreach (AvailablePart part in PartLoader.LoadedPartsList)
                    {
                        if (KSTS.partDictionary.ContainsKey(part.name.ToString()))
                        {
                            Debug.LogError("[KSTS] duplicate part-name '" + part.name.ToString() + "'");
                            continue;
                        }
                        KSTS.partDictionary.Add(part.name.ToString(), part);
                    }
                }

                // Build a dictionay of all resources for easier access:
                if (KSTS.resourceDictionary == null)
                {
                    KSTS.resourceDictionary = new Dictionary <string, PartResourceDefinition>();
                    foreach (PartResourceDefinition resourceDefinition in PartResourceLibrary.Instance.resourceDefinitions)
                    {
                        KSTS.resourceDictionary.Add(resourceDefinition.name.ToString(), resourceDefinition);
                    }
                }

                // Invoke the timer-function every second to run background-code:
                if (!IsInvoking("Timer"))
                {
                    InvokeRepeating("Timer", 1, 1);
                }

                // Execute the following code only once:
                if (KSTS.initialized)
                {
                    return;
                }
                DontDestroyOnLoad(this);
                KSTS.initialized = true;
            }
            catch (Exception e)
            {
                Debug.LogError("[KSTS] Awake(): " + e.ToString());
            }
        }
Example #7
0
        public static bool Display()
        {
            currentCost = 0;
            var ready  = DisplayInner();
            var launch = DisplayFooter(currentCost, ready);

            if (launch)
            {
                // Start the mission:
                MissionController.StartMission(Mission.CreateConstruction(shipName, payloadShipSelector.payload.template, targetVesselSelector.targetVessel, missionProfileSelector.selectedProfile, crewTransferSelector.crewToDeliver, flagSelector.flagURL, constructionTime));
                KSTS.AddFunds(-currentCost);
                Reset();
                return(true);
            }
            return(false);
        }
Example #8
0
        public static bool Display()
        {
            currentCost = 0;
            var ready  = DisplayInner();
            var launch = DisplayFooter(currentCost, ready);

            if (launch)
            {
                // Start the mission:
                MissionController.StartMission(Mission.CreateDeployment(shipName, payloadShipSelector.payload.template, orbitEditor.GetOrbit(), missionProfileSelector.selectedProfile, crewTransferSelector.crewToDeliver, flagSelector.flagURL));
                KSTS.AddFunds(-currentCost);
                Reset();
                return(true);
            }
            return(false);
        }
Example #9
0
        public void Timer()
        {
            try
            {
                // Don't update while not in game:
                if (HighLogic.LoadedScene == GameScenes.MAINMENU || HighLogic.LoadedScene == GameScenes.CREDITS || HighLogic.LoadedScene == GameScenes.SETTINGS)
                {
                    return;
                }

                // Call all background-jobs:
                FlightRecorder.Timer();
                MissionController.Timer();
            }
            catch (Exception e)
            {
                Debug.LogError("[KSTS] Timer(): " + e.ToString());
            }
        }
Example #10
0
        public static bool Display()
        {
            currentCost = 0;
            var ready  = DisplayInner();
            var launch = DisplayFooter(currentCost, ready);

            if (launch)
            {
                MissionController.StartMission(Mission.CreateTransport(
                                                   targetVesselSelector.targetVessel,
                                                   missionProfileSelector.selectedProfile,
                                                   payloadResourceSelector.selectedResources,
                                                   payloadResourceSelector.selectedCrewTransfers
                                                   ));
                KSTS.AddFunds(-currentCost);
                Reset();
                return(true);
            }
            return(false);
        }
Example #11
0
        // Closes the active recording for the given vessel and creates a mission-profile from it:
        public static void SaveRecording(Vessel vessel)
        {
            try
            {
                FlightRecording recording;
                if (!FlightRecorder.flightRecordings.TryGetValue(vessel.id.ToString(), out recording))
                {
                    return;
                }
                if (!recording.CanFinish())
                {
                    return;
                }

                MissionController.CreateMissionProfile(vessel, recording);
                FlightRecorder.flightRecordings.Remove(vessel.id.ToString());
            }
            catch (Exception e)
            {
                Debug.LogError("[KSTS] SaveRecording(): " + e.ToString());
            }
        }
Example #12
0
        public override void OnLoad(ConfigNode node)
        {
            Log.Warning("KSTS: OnLoad");
            try
            {
                FlightRecorder.LoadRecordings(node);
                MissionController.LoadMissions(node);

                if (node.HasValue("useKACifAvailable"))
                {
                    MissionController.useKACifAvailable = bool.Parse(node.GetValue("useKACifAvailable"));
                }
                if (node.HasValue("useStockAlarmClock"))
                {
                    MissionController.useStockAlarmClock = bool.Parse(node.GetValue("useStockAlarmClock"));
                }

                GUI.Reset();
            }
            catch (Exception e)
            {
                Debug.LogError("OnLoad(): " + e.ToString());
            }
        }
Example #13
0
        public static bool Display()
        {
            currentCost = 0;
            bool ready  = DisplayInner();
            bool launch = DisplayFooter(currentCost, ready);

            if (launch)
            {
                if (!GUIOrbitEditor.CheckOrbitClear(orbitEditor.GetOrbit()))
                {
                    // The selected orbit is used by another vessel, abort:
                    ScreenMessages.PostScreenMessage("Selected orbit already in use by another vessel, aborting mission!");
                }
                else
                {
                    // The orbit is clear, start the mission:
                    MissionController.StartMission(Mission.CreateDeployment(shipName, payloadShipSelector.payload.template, orbitEditor.GetOrbit(), missionProfileSelector.selectedProfile, crewTransferSelector.crewToDeliver, flagSelector.flagURL));
                    KSTS.AddFunds(-currentCost);
                    Reset();
                    return(true);
                }
            }
            return(false);
        }
Example #14
0
        // Shows a list of all available crew-members which the player can choose to transport and returns true, if the selection is valid:
        public bool DisplayList()
        {
            var targetCrewCapacity = 0;

            if (targetVessel != null)
            {
                targetCrewCapacity = TargetVessel.GetCrewCapacity(targetVessel);
            }
            else if (targetTemplate != null)
            {
                targetCrewCapacity = targetTemplate.GetCrewCapacity();
            }

            if (missionProfile.crewCapacity == 0 && missionProfile.missionType == MissionProfileType.TRANSPORT) // We only care about the seats on the transport-vessel during transport-missions.
            {
                GUILayout.Label("There are no available seats in the selected mission-profile.");
                return(true);
            }
            else if (targetCrewCapacity == 0) // If the target has no seats, we can't transport anyone.
            {
                GUILayout.Label("The selected target-vessel can not hold any crew-members.");
                return(true);
            }
            else
            {
                // Target-vessel summary:
                var    targetOverload = false;
                string headline;
                if (targetVessel != null) // Existing vessel (in- & outboud transfers possible)
                {
                    // Display capacity and transfer deltas:
                    var targetVesselCrew = TargetVessel.GetCrew(targetVessel);
                    if (targetVesselCrew.Count + crewToDeliver.Count - crewToCollect.Count > targetCrewCapacity)
                    {
                        targetOverload = true;
                    }
                    headline = "<b>" + targetVessel.vesselName + ":</b> " + targetVesselCrew.Count.ToString() + "/" + targetCrewCapacity.ToString();
                    var transfers = " inbound: " + crewToDeliver.Count.ToString("+#;-#;0") + ", outbound: " + (-crewToCollect.Count).ToString("+#;-#;0");
                    if (targetOverload)
                    {
                        transfers = "<color=#FF0000>" + transfers + "</color>";
                    }
                    GUILayout.Label(headline + transfers);

                    // Display Crew that is stationed on the target vessel:
                    foreach (var kerbonaut in targetVesselCrew)
                    {
                        var details = " <b>" + kerbonaut.name + "</b> (Level " + kerbonaut.experienceLevel.ToString() + " " + kerbonaut.trait + ")";
                        if (missionProfile.oneWayMission || MissionController.GetKerbonautsMission(kerbonaut.name) != null || missionProfile.missionType != MissionProfileType.TRANSPORT)
                        {
                            GUILayout.Label(" • " + details);                                                                                                                                                               // Do not transport kerbals, which are flagged for another mission or there isn't even a return-trip or transport happening
                        }
                        else
                        {
                            var selected = GUILayout.Toggle(crewToCollect.Contains(kerbonaut.name), details);
                            if (selected && !crewToCollect.Contains(kerbonaut.name))
                            {
                                crewToCollect.Add(kerbonaut.name);
                            }
                            else if (!selected && crewToCollect.Contains(kerbonaut.name))
                            {
                                crewToCollect.Remove(kerbonaut.name);
                            }
                        }
                    }
                    GUILayout.Label("");
                }
                else if (targetTemplate != null) // New vessel (only inbound transfers possible)
                {
                    // Display capacity:
                    if (crewToDeliver.Count > targetCrewCapacity)
                    {
                        targetOverload = true;
                    }
                    headline = "<b>" + targetTemplate.template.shipName + ":</b> ";
                    var seats = crewToDeliver.Count.ToString() + " / " + targetCrewCapacity.ToString() + " seat";
                    if (targetCrewCapacity != 1)
                    {
                        seats += "s";
                    }
                    if (targetOverload)
                    {
                        seats = "<color=#FF0000>" + seats + "</color>";
                    }
                    GUILayout.Label(headline + seats);
                }

                // Display Transport-vessel summary, if this is a transport-mission:
                var transportOutboundOverload = false;
                var transportInboundOverload  = false;
                if (missionProfile.missionType == MissionProfileType.TRANSPORT)
                {
                    if (crewToDeliver.Count > missionProfile.crewCapacity)
                    {
                        transportOutboundOverload = true;
                    }
                    if (crewToCollect.Count > missionProfile.crewCapacity)
                    {
                        transportInboundOverload = true;
                    }

                    headline = "<b>" + missionProfile.vesselName + ":</b> ";
                    var outbound = "outbound: " + crewToDeliver.Count.ToString() + "/" + missionProfile.crewCapacity.ToString();
                    if (transportOutboundOverload)
                    {
                        outbound = "<color=#FF0000>" + outbound + "</color>";
                    }
                    var inbound = "";
                    if (!missionProfile.oneWayMission)
                    {
                        inbound = ", inbound: " + crewToCollect.Count.ToString() + "/" + missionProfile.crewCapacity.ToString();
                        if (transportInboundOverload)
                        {
                            inbound = "<color=#FF0000>" + inbound + "</color>";
                        }
                    }
                    else
                    {
                        inbound += ", inbound: -";
                    }
                    GUILayout.Label(headline + outbound + inbound);
                }

                // Display crew-rowster:
                foreach (var kerbonaut in GetCrewRoster())
                {
                    var details = " <b>" + kerbonaut.name + "</b> (Level " + kerbonaut.experienceLevel.ToString() + " " + kerbonaut.trait.ToString() + ")";
                    if (MissionController.GetKerbonautsMission(kerbonaut.name) != null)
                    {
                        GUILayout.Label(" • " + details);                                                                 // Do not transport kerbals, which are flagged for another mission
                    }
                    else
                    {
                        var selected = GUILayout.Toggle(crewToDeliver.Contains(kerbonaut.name), details);
                        if (selected && !crewToDeliver.Contains(kerbonaut.name))
                        {
                            crewToDeliver.Add(kerbonaut.name);
                        }
                        else if (!selected && crewToDeliver.Contains(kerbonaut.name))
                        {
                            crewToDeliver.Remove(kerbonaut.name);
                        }
                    }
                }

                // Check if the selection is valid (it neither overloads the target nor the transport):
                if (!targetOverload && !transportOutboundOverload && !transportInboundOverload)
                {
                    return(true);
                }
                return(false);
            }
        }
Example #15
0
        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();
            }
        }
Example #16
0
        // Is called when this Addon is first loaded to initializes all values (eg registration of event-handlers and creation
        // of original-stats library).
        public void Awake()
        {
            try
            {
                FlightRecorder.Initialize();
                MissionController.Initialize();

                // Build dictionary of all parts for easier access:
                if (KSTS.partDictionary == null)
                {
                    KSTS.partDictionary = new Dictionary <string, AvailablePart>();
                    foreach (var part in PartLoader.LoadedPartsList)
                    {
                        if (KSTS.partDictionary.ContainsKey(part.name.ToString()))
                        {
                            Debug.LogError("duplicate part-name '" + part.name.ToString() + "'");
                            continue;
                        }
                        KSTS.partDictionary.Add(part.name.ToString(), part);
                    }
                }

                // Build a dictionay of all resources for easier access:
                if (KSTS.resourceDictionary == null)
                {
                    KSTS.resourceDictionary = new Dictionary <string, PartResourceDefinition>();
                    foreach (var resourceDefinition in PartResourceLibrary.Instance.resourceDefinitions)
                    {
                        KSTS.resourceDictionary.Add(resourceDefinition.name.ToString(), resourceDefinition);
                    }
                }

                // Invoke the timer-function every second to run background-code:
                if (!IsInvoking("Timer"))
                {
                    InvokeRepeating("Timer", 1, 1);
                }

                // In case the Stage Recovery Mod is installed, add lists and handlers to track the separation and recovery of stages:
                if (StageRecoveryAPI.StageRecoveryAvailable && KSTS.stageParentDictionary == null)
                {
                    Log.Warning("detected stage recovery mod");
                    stageParentDictionary = new Dictionary <string, string>();
                    StageRecoveryAPI.AddRecoverySuccessEvent((vessel, array, str) =>
                    {
                        if (StageRecoveryAPI.StageRecoveryEnabled)
                        {
                            FlightRecorder.OnStageRecovered(vessel.id.ToString(), array[1]);
                        }
                    });

                    GameEvents.onStageSeparation.Add(new EventData <EventReport> .OnEvent(this.onStageSeparation));
                    GameEvents.onVesselWasModified.Add(new EventData <Vessel> .OnEvent(this.onVesselModified));
                }

                // Execute the following code only once:
                if (KSTS.initialized)
                {
                    return;
                }
                DontDestroyOnLoad(this);
                KSTS.initialized = true;
            }
            catch (Exception e)
            {
                Debug.LogError("Awake(): " + e.ToString());
            }
        }
Example #17
0
        // Is called when this Addon is first loaded to initializes all values (eg registration of event-handlers and creation
        // of original-stats library).
        public void Awake()
        {
            try
            {
                FlightRecorder.Initialize();
                MissionController.Initialize();

                // Build dictionary of all parts for easier access:
                if (KSTS.partDictionary == null)
                {
                    KSTS.partDictionary = new Dictionary <string, AvailablePart>();
                    foreach (AvailablePart part in PartLoader.LoadedPartsList)
                    {
                        if (KSTS.partDictionary.ContainsKey(part.name.ToString()))
                        {
                            Debug.LogError("[KSTS] duplicate part-name '" + part.name.ToString() + "'");
                            continue;
                        }
                        KSTS.partDictionary.Add(part.name.ToString(), part);
                    }
                }

                // Build a dictionay of all resources for easier access:
                if (KSTS.resourceDictionary == null)
                {
                    KSTS.resourceDictionary = new Dictionary <string, PartResourceDefinition>();
                    foreach (PartResourceDefinition resourceDefinition in PartResourceLibrary.Instance.resourceDefinitions)
                    {
                        KSTS.resourceDictionary.Add(resourceDefinition.name.ToString(), resourceDefinition);
                    }
                }

                // Invoke the timer-function every second to run background-code:
                if (!IsInvoking("Timer"))
                {
                    InvokeRepeating("Timer", 1, 1);
                }



                parentDictionary = new Dictionary <string, string>();
                if (StageRecoveryAPI.StageRecoveryAvailable)
                {
                    StageRecoveryAPI.AddRecoverySuccessEvent((vessel, array, str) =>
                    {
                        if (StageRecoveryAPI.StageRecoveryEnabled)
                        {
                            StageRecovered?.Invoke(this, new StageRecoveredEventArgs {
                                Vessel = vessel, FundsRecovered = array[1]
                            });
                        }
                    });

                    GameEvents.onStageSeparation.Add(new EventData <EventReport> .OnEvent(this.onStageSeparation));
                    GameEvents.onVesselWasModified.Add(new EventData <Vessel> .OnEvent(this.onVesselModified));
                }

                // Execute the following code only once:
                if (KSTS.initialized)
                {
                    return;
                }
                DontDestroyOnLoad(this);
                KSTS.initialized = true;
            }
            catch (Exception e)
            {
                Debug.LogError("[KSTS] Awake(): " + e.ToString());
            }
        }
Example #18
0
        public override void OnSave(ConfigNode node)
        {
            try
            {
                /*
                 * When transporting an available kerbal to a ship or recovering one from orbit, we manipulate the (unloaded) vessel's crew
                 * as well as the roster-status of the kerbal. This is apparently not expected by KSP's core functionality, because there
                 * seems to be a secret list of roster-status which is enforced when the game is safed:
                 *
                 * [WRN 15:16:14.678] [ProtoCrewMember Warning]: Crewmember Sierina Kerman found inside a part but status is set as missing. Vessel must have failed to save earlier. Restoring assigned status.
                 * [WRN 15:17:42.913] [ProtoCrewMember Warning]: Crewmember Sierina Kerman found assigned but no vessels reference him. Sierina Kerman set as missing.
                 *
                 * Afterwards these kerbals would be lost for the player, which is why we have to use the workaround below to revert these
                 * changes and make sure each kerbal has the correct status. This effectively disables the "missing" status as these kerbals
                 * will always respawn, but I haven't seen a valid use-case for this thus far, so it is probably fine.
                 */
                if (HighLogic.CurrentGame.CrewRoster.Count > 0 && FlightGlobals.Vessels.Count > 0)
                {
                    // Build a list of all Kerbals which are assigned to vessels:
                    List <string> vesselCrewNames = new List <string>();
                    foreach (Vessel vessel in FlightGlobals.Vessels)
                    {
                        foreach (ProtoCrewMember crewMember in TargetVessel.GetCrew(vessel))
                        {
                            vesselCrewNames.Add(crewMember.name);
                        }
                    }

                    // Build a list of all kerbals which we could have manipulated:
                    List <ProtoCrewMember> kerbals = new List <ProtoCrewMember>();
                    foreach (ProtoCrewMember kerbal in HighLogic.CurrentGame.CrewRoster.Kerbals(ProtoCrewMember.KerbalType.Crew))
                    {
                        kerbals.Add(kerbal);
                    }
                    foreach (ProtoCrewMember kerbal in HighLogic.CurrentGame.CrewRoster.Kerbals(ProtoCrewMember.KerbalType.Tourist))
                    {
                        kerbals.Add(kerbal);
                    }

                    // Check those kerbals against our vessel-list and maybe restore their correct status:
                    foreach (ProtoCrewMember kerbal in kerbals)
                    {
                        if (kerbal.rosterStatus == ProtoCrewMember.RosterStatus.Dead)
                        {
                            continue;
                        }
                        if (vesselCrewNames.Contains(kerbal.name) && kerbal.rosterStatus != ProtoCrewMember.RosterStatus.Assigned)
                        {
                            Debug.Log("[KSTS] setting kerbal " + kerbal.name + " from " + kerbal.rosterStatus.ToString() + " to Assigned (see code for more info)");
                            kerbal.rosterStatus = ProtoCrewMember.RosterStatus.Assigned;
                        }
                        else if (!vesselCrewNames.Contains(kerbal.name) && kerbal.rosterStatus != ProtoCrewMember.RosterStatus.Available)
                        {
                            Debug.Log("[KSTS] setting kerbal " + kerbal.name + " from " + kerbal.rosterStatus.ToString() + " to Available (see code for more info)");
                            kerbal.rosterStatus = ProtoCrewMember.RosterStatus.Available;
                        }
                    }
                }

                FlightRecorder.SaveRecordings(node);
                MissionController.SaveMissions(node);
            }
            catch (Exception e)
            {
                Debug.LogError("[KSTS] OnSave(): " + e.ToString());
            }
        }