Beispiel #1
0
        public static PartFlightData FromString(string str)
        {
            // String format is
            // partName:scope,data,0 scope,data scope,data,0 scope,data,0
            PartFlightData newData = null;
            if (str.IndexOf(':') > -1)
            {
                newData = new PartFlightData();
                string[] baseString = str.Split(new char[1]{ ':' });
                newData.partName = baseString[0];
                string[] dataStrings = baseString[1].Split(new char[1]{ ' ' });
                foreach (string dataString in dataStrings)
                {
                    if (newData.flightData == null)
                        newData.flightData = new List<TestFlightData>();

                    if (dataString.Trim().Length > 0)
                    {
                        string[] dataMembers = dataString.Split(new char[1]{ ',' });
                        if (dataMembers.Length == 3)
                        {
                            TestFlightData tfData = new TestFlightData();
                            tfData.scope = dataMembers[0];
                            tfData.flightData = float.Parse(dataMembers[1]);
                            tfData.flightTime = 0;
                            newData.flightData.Add(tfData);
                        }
                    }
                }
            }
            return newData;
        }
Beispiel #2
0
        private void InitializeParts(Vessel vessel)
        {
            Log("TestFlightManager: Initializing parts for vessel " + vessel.GetName());

            // Launch time is equal to current UT unless we have already chached this vessel's launch time
            double launchTime = Planetarium.GetUniversalTime();

            if (knownVessels.ContainsKey(vessel.id))
            {
                launchTime = knownVessels[vessel.id];
            }
            foreach (Part part in vessel.parts)
            {
                ITestFlightCore core = TestFlightUtil.GetCore(part);
                if (core != null)
                {
                    Log("TestFlightManager: Found core.  Getting part data");
                    PartFlightData partData = tfScenario.GetFlightDataForPartName(TestFlightUtil.GetFullPartName(part));
                    if (partData == null)
                    {
                        Log("TestFlightManager: Unable to find part data.  Starting fresh.");
                        core.InitializeFlightData(null);
                    }
                    else
                    {
                        core.InitializeFlightData(partData.GetFlightData());
                    }
                }
            }
        }
Beispiel #3
0
        public override void OnLoad(ConfigNode node)
        {
            base.OnLoad(node);
            if (userSettings != null)
            {
                userSettings.Load();
            }
            if (bodySettings != null)
            {
                bodySettings.Load();
            }
            if (node.HasNode("FLIGHTDATA_PART"))
            {
                if (partsFlightData == null)
                {
                    partsFlightData = new List <PartFlightData>();
                }

                foreach (ConfigNode partNode in node.GetNodes("FLIGHTDATA_PART"))
                {
                    PartFlightData partData = new PartFlightData();
                    partData.Load(partNode);
                    partsFlightData.Add(partData);
                    partsPackedStrings.Add(partData.ToString());
                }
            }
        }
Beispiel #4
0
        public PartFlightData GetFlightDataForPartNameFragment(string partNameFragment)
        {
            PartFlightData returnValue = null;

            // check 1, do we have an exact match?
            returnValue = GetFlightDataForPartName(partNameFragment);
            if (returnValue != null)
            {
                return(returnValue);
            }

            // check 2, is this a base part name or a configuration name?
            foreach (PartFlightData data in partsFlightData)
            {
                string[] split = data.GetPartName().Split(new char[1] {
                    '|'
                });
                if (split[0].ToLower().Trim() == partNameFragment.ToLower().Trim())
                {
                    return(data);
                }
                if (split.Length > 1 && split[1].ToLower().Trim() == partNameFragment.ToLower().Trim())
                {
                    return(data);
                }
            }

            return(returnValue);
        }
Beispiel #5
0
        public void SetFlightDataForPartName(string partName, PartFlightData data)
        {
            int index = partsFlightData.FindIndex(pfd => pfd.GetPartName() == partName);

            if (index == -1)
            {
                partsFlightData.Add(data);
            }
            else
            {
                partsFlightData[index] = data;
            }
        }
        internal void CalculateWindowBounds()
        {
            if (appLauncherButton == null)
            {
                return;
            }
            if (tfScenario == null)
            {
                return;
            }

            float windowWidth  = 350f;
            float left         = Screen.width - windowWidth - 75f;
            float windowHeight = 50f;

            float           numItems = 0;
            ITestFlightCore core     = GetCore();

            if (core != null)
            {
                List <TestFlightData> flightData = null;
                PartFlightData        partData   = tfScenario.GetFlightDataForPartName(TestFlightUtil.GetFullPartName(SelectedPart));
                if (partData == null)
                {
                    numItems = 0;
                }
                else
                {
                    flightData = partData.GetFlightData();
                    if (flightData != null)
                    {
                        numItems = flightData.Count;
                    }
                }
            }

            windowHeight += numItems * 20f;
            float top = Screen.height - windowHeight - 60f;

            if (!tfScenario.userSettings.editorWindowLocked)
            {
                left = tfScenario.userSettings.editorWindowPosition.xMin;
                top  = tfScenario.userSettings.editorWindowPosition.yMin;
            }
            WindowRect = new Rect(left, top, windowWidth, windowHeight);
        }
        public static PartFlightData FromString(string str)
        {
            // String format is
            // partName:scope,data,0 scope,data scope,data,0 scope,data,0
            PartFlightData newData = null;

            if (str.IndexOf(':') > -1)
            {
                newData = new PartFlightData();
                string[] baseString = str.Split(new char[1] {
                    ':'
                });
                newData.partName = baseString[0];
                string[] dataStrings = baseString[1].Split(new char[1] {
                    ' '
                });
                foreach (string dataString in dataStrings)
                {
                    if (newData.flightData == null)
                    {
                        newData.flightData = new List <TestFlightData>();
                    }

                    if (dataString.Trim().Length > 0)
                    {
                        string[] dataMembers = dataString.Split(new char[1] {
                            ','
                        });
                        if (dataMembers.Length == 3)
                        {
                            TestFlightData tfData = new TestFlightData();
                            tfData.scope      = dataMembers[0];
                            tfData.flightData = float.Parse(dataMembers[1]);
                            tfData.flightTime = 0;
                            newData.flightData.Add(tfData);
                        }
                    }
                }
            }
            return(newData);
        }
        public override void OnLoad(ConfigNode node)
        {
            base.OnLoad(node);
            if (userSettings != null)
            {
                userSettings.Load();
            }
            if (bodySettings != null)
            {
                bodySettings.Load();
            }

            InitDataStore();
            if (node.HasValue("saveData"))
            {
                rawSaveData = node.GetValue("saveData");
            }
            else
            {
                rawSaveData = "";
            }
            decodeRawSaveData();

            if (partData == null)
            {
                partData = new Dictionary <String, TestFlightPartData>();
            }
            else
            {
                partData.Clear();
            }
            // TODO: This old method of storing scope specific data is deprecated and needs to be removed in the next major release (Probably 1.4)
            if (node.HasNode("FLIGHTDATA_PART"))
            {
                foreach (ConfigNode partNode in node.GetNodes("FLIGHTDATA_PART"))
                {
                    PartFlightData partFlightData = new PartFlightData();
                    partFlightData.Load(partNode);

                    // migrates old data into new noscope layout
                    TestFlightPartData storedPartData = new TestFlightPartData();
                    storedPartData.PartName = partFlightData.GetPartName();
                    // Add up all the data and time from the old system for each scope, and then save that as the new migrated vales
                    double totalData = 0;
                    double totalTime = 0;
                    List <TestFlightData> allData = partFlightData.GetFlightData();
                    foreach (TestFlightData data in allData)
                    {
                        totalData += data.flightData;
                        totalTime += data.flightTime;
                    }
                    storedPartData.SetValue("flightData", totalData.ToString());
                    storedPartData.SetValue("flightTime", totalTime.ToString());
                    partData.Add(storedPartData.PartName, storedPartData);
                }
            }
            // new noscope
            if (node.HasNode("partData"))
            {
                foreach (ConfigNode partDataNode in node.GetNodes("partData"))
                {
                    TestFlightPartData storedPartData = new TestFlightPartData();
                    storedPartData.Load(partDataNode);
                    partData.Add(storedPartData.PartName, storedPartData);
                }
            }
        }
Beispiel #9
0
        public override void OnLoad(ConfigNode node)
        {
            base.OnLoad(node);
            if (userSettings != null)
            {
                userSettings.Load();
            }
            if (bodySettings != null)
                bodySettings.Load();

            InitDataStore();
            if (node.HasValue("saveData"))
                rawSaveData = node.GetValue("saveData");
            else
                rawSaveData = "";
            decodeRawSaveData();

            if (partData == null)
                partData = new Dictionary<String, TestFlightPartData>();
            else
                partData.Clear();
            // TODO: This old method of storing scope specific data is deprecated and needs to be removed in the next major release (Probably 1.4)
            if (node.HasNode("FLIGHTDATA_PART"))
            {
                foreach (ConfigNode partNode in node.GetNodes("FLIGHTDATA_PART"))
                {
                    PartFlightData partFlightData = new PartFlightData();
                    partFlightData.Load(partNode);

                    // migrates old data into new noscope layout
                    TestFlightPartData storedPartData = new TestFlightPartData();
                    storedPartData.PartName = partFlightData.GetPartName();
                    // Add up all the data and time from the old system for each scope, and then save that as the new migrated vales
                    double totalData = 0;
                    double totalTime = 0;
                    List<TestFlightData> allData = partFlightData.GetFlightData();
                    foreach (TestFlightData data in allData)
                    {
                        totalData += data.flightData;
                        totalTime += data.flightTime;
                    }
                    storedPartData.SetValue("flightData", totalData.ToString());
                    storedPartData.SetValue("flightTime", totalTime.ToString());
                    partData.Add(storedPartData.PartName, storedPartData);
                }
            }
            // new noscope
            if (node.HasNode("partData"))
            {
                foreach (ConfigNode partDataNode in node.GetNodes("partData"))
                {
                    TestFlightPartData storedPartData = new TestFlightPartData();
                    storedPartData.Load(partDataNode);
                    partData.Add(storedPartData.PartName, storedPartData);
                }
            }
        }
Beispiel #10
0
        public override void OnAwake()
        {
            Instance = this;
            if (userSettings == null)
            {
                userSettings = new UserSettings("../settings.cfg");
            }
            if (bodySettings == null)
            {
                bodySettings = new BodySettings("../settings_bodies.cfg");
            }

            if (userSettings.FileExists)
            {
                userSettings.Load();
            }
            else
            {
                userSettings.Save();
            }

            if (bodySettings.FileExists)
            {
                bodySettings.Load();
            }
            else
            {
                bodySettings.bodyAliases.Add("moho", "Moho");
                bodySettings.bodyAliases.Add("eve", "Eve");
                bodySettings.bodyAliases.Add("gilly", "Gilly");
                bodySettings.bodyAliases.Add("kerbin", "Kerbin");
                bodySettings.bodyAliases.Add("mun", "Mun");
                bodySettings.bodyAliases.Add("minmus", "Minmus");
                bodySettings.bodyAliases.Add("duna", "Duna");
                bodySettings.bodyAliases.Add("ike", "Ike");
                bodySettings.bodyAliases.Add("dres", "Dres");
                bodySettings.bodyAliases.Add("jool", "Jool");
                bodySettings.bodyAliases.Add("laythe", "Laythe");
                bodySettings.bodyAliases.Add("vall", "Vall");
                bodySettings.bodyAliases.Add("tylo", "Tylo");
                bodySettings.bodyAliases.Add("bop", "Bop");
                bodySettings.bodyAliases.Add("pol", "Pol");
                bodySettings.bodyAliases.Add("eeloo", "Eeloo");
                bodySettings.Save();
            }

            if (partsFlightData == null)
            {
                partsFlightData = new List <PartFlightData>();
                if (partsPackedStrings != null)
                {
                    foreach (string packedString in partsPackedStrings)
                    {
                        Log(packedString);
                        PartFlightData data = PartFlightData.FromString(packedString);
                        partsFlightData.Add(data);
                    }
                }
            }
            if (partsPackedStrings == null)
            {
                partsPackedStrings = new List <string>();
            }
            base.OnAwake();
        }
Beispiel #11
0
        internal override void Update()
        {
            if (!isReady)
            {
                return;
            }

            if (masterStatus == null)
            {
                masterStatus = new Dictionary <Guid, MasterStatusItem>();
            }

            currentUTC = Planetarium.GetUniversalTime();
            // ensure out vessel list is up to date
            CacheVessels();
            if (currentUTC >= lastMasterStatusUpdate + tfScenario.userSettings.masterStatusUpdateFrequency)
            {
                lastMasterStatusUpdate = currentUTC;
                VerifyMasterStatus();
            }
            // process vessels
            foreach (var entry in knownVessels)
            {
                Vessel vessel = FlightGlobals.Vessels.Find(v => v.id == entry.Key);
                if (vessel.loaded)
                {
                    foreach (Part part in vessel.parts)
                    {
                        ITestFlightCore core = TestFlightUtil.GetCore(part);
                        if (core != null)
                        {
                            // Poll for flight data and part status
                            if (currentUTC >= lastDataPoll + tfScenario.userSettings.masterStatusUpdateFrequency)
                            {
                                TestFlightData currentFlightData = new TestFlightData();
                                currentFlightData.scope      = core.GetScope();
                                currentFlightData.flightData = core.GetFlightData();
                                currentFlightData.flightTime = core.GetFlightTime();

                                PartStatus partStatus = new PartStatus();
                                partStatus.flightCore   = core;
                                partStatus.partName     = TestFlightUtil.GetPartTitle(part);
                                partStatus.partID       = part.flightID;
                                partStatus.flightData   = currentFlightData.flightData;
                                partStatus.flightTime   = currentFlightData.flightTime;
                                partStatus.partStatus   = core.GetPartStatus();
                                partStatus.timeToRepair = core.GetRepairTime();
                                double failureRate = core.GetBaseFailureRate();
                                MomentaryFailureRate momentaryFailureRate = core.GetWorstMomentaryFailureRate();
                                if (momentaryFailureRate.valid && momentaryFailureRate.failureRate > failureRate)
                                {
                                    failureRate = momentaryFailureRate.failureRate;
                                }
                                partStatus.momentaryFailureRate = failureRate;
                                partStatus.repairRequirements   = core.GetRequirementsTooltip();
                                partStatus.acknowledged         = core.IsFailureAcknowledged();
                                partStatus.activeFailure        = core.GetFailureModule();
                                partStatus.mtbfString           = core.FailureRateToMTBFString(failureRate, TestFlightUtil.MTBFUnits.SECONDS, 999);

                                // Update or Add part status in Master Status
                                if (masterStatus.ContainsKey(vessel.id))
                                {
                                    // Vessel is already in the Master Status, so check if part is in there as well
                                    int numItems = masterStatus[vessel.id].allPartsStatus.Count(p => p.partID == part.flightID);
                                    int existingPartIndex;
                                    if (numItems == 1)
                                    {
                                        existingPartIndex = masterStatus[vessel.id].allPartsStatus.FindIndex(p => p.partID == part.flightID);
                                        masterStatus[vessel.id].allPartsStatus[existingPartIndex] = partStatus;
                                    }
                                    else if (numItems == 0)
                                    {
                                        masterStatus[vessel.id].allPartsStatus.Add(partStatus);
                                    }
                                    else
                                    {
                                        existingPartIndex = masterStatus[vessel.id].allPartsStatus.FindIndex(p => p.partID == part.flightID);
                                        masterStatus[vessel.id].allPartsStatus[existingPartIndex] = partStatus;
                                        Log("[ERROR] TestFlightManager: Found " + numItems + " matching parts in Master Status Display!");
                                    }
                                }
                                else
                                {
                                    // Vessel is not in the Master Status so create a new entry for it and add this part
                                    MasterStatusItem masterStatusItem = new MasterStatusItem();
                                    masterStatusItem.vesselID       = vessel.id;
                                    masterStatusItem.vesselName     = vessel.GetName();
                                    masterStatusItem.allPartsStatus = new List <PartStatus>();
                                    masterStatusItem.allPartsStatus.Add(partStatus);
                                    masterStatus.Add(vessel.id, masterStatusItem);
                                }

                                PartFlightData data = tfScenario.GetFlightDataForPartName(TestFlightUtil.GetFullPartName(part));
                                if (data != null)
                                {
                                    data.AddFlightData(part.name, currentFlightData);
                                }
                                else
                                {
                                    data = new PartFlightData();
                                    data.AddFlightData(TestFlightUtil.GetFullPartName(part), currentFlightData);
                                    tfScenario.SetFlightDataForPartName(TestFlightUtil.GetFullPartName(part), data);
                                }
                            }
                        }
                    }
                }
                if (currentUTC >= lastDataPoll + tfScenario.userSettings.minTimeBetweenDataPoll)
                {
                    lastDataPoll = currentUTC;
                }
                if (currentUTC >= lastFailurePoll + tfScenario.userSettings.minTimeBetweenFailurePoll)
                {
                    lastFailurePoll = currentUTC;
                }
            }
        }
        internal override void DrawWindow(int id)
        {
            if (!isReady)
            {
                return;
            }

            if (SelectedPart == null)
            {
                GUILayout.BeginVertical();
                GUILayout.Label("Select a part to display its details", Styles.styleEditorTitle);
                GUILayout.Label("MouseOver part in bin or 3D view to quickview", Styles.styleEditorText);
                GUILayout.Label("RightClick part in bin (not 3D) to toggle window lock on that part", Styles.styleEditorText);
                GUILayout.EndVertical();
                if (DrawToggle(ref tfScenario.userSettings.editorWindowLocked, "Lock Window", Styles.styleToggle))
                {
                    if (tfScenario.userSettings.editorWindowLocked)
                    {
                        CalculateWindowBounds();
                        tfScenario.userSettings.editorWindowPosition = WindowRect;
                        DragEnabled = false;
                    }
                    else
                    {
                        DragEnabled = true;
                    }
                    tfScenario.userSettings.Save();
                }
                return;
            }

            ITestFlightCore core = null;

            GUILayout.BeginVertical();
            GUILayout.Label(String.Format("Selected Part: {0}", TestFlightUtil.GetFullPartName(SelectedPart)), Styles.styleEditorTitle);

            tfScenario.userSettings.currentEditorScrollPosition = GUILayout.BeginScrollView(tfScenario.userSettings.currentEditorScrollPosition);
            PartFlightData partData = tfScenario.GetFlightDataForPartName(TestFlightUtil.GetFullPartName(SelectedPart));

            if (partData != null)
            {
                string configuration;

                if (SelectedPart.Modules.Contains("ModuleEngineConfigs"))
                {
                    configuration = (string)(SelectedPart.Modules["ModuleEngineConfigs"].GetType().GetField("configuration").GetValue(SelectedPart.Modules["ModuleEngineConfigs"]));
                }
                else
                {
                    configuration = "";
                }
                foreach (PartModule pm in SelectedPart.Modules)
                {
                    core = pm as ITestFlightCore;
                    if (core != null && core.Configuration == configuration)
                    {
                        break;
                    }
                }
                if (core != null)
                {
                    List <TestFlightData> flightData = partData.GetFlightData();
                    core.InitializeFlightData(flightData);
                    foreach (TestFlightData data in flightData)
                    {
                        GUILayout.BeginHorizontal();
                        double failureRate = core.GetBaseFailureRateForScope(data.scope);
                        String mtbfString  = core.FailureRateToMTBFString(failureRate, TestFlightUtil.MTBFUnits.SECONDS, 999);
                        // 10 characters for body max plus 10 characters for situation plus underscore = 21 characters needed for longest scope string
                        GUILayout.Label(core.PrettyStringForScope(data.scope), GUILayout.Width(125));
                        GUILayout.Label(String.Format("{0,-7:F2}<b>du</b>", data.flightData), GUILayout.Width(75));
                        GUILayout.Label(String.Format("{0,-5:F2} MTBF", mtbfString), GUILayout.Width(125));
                        GUILayout.EndHorizontal();
                    }
                }
            }
            GUILayout.EndScrollView();
            if (DrawToggle(ref tfScenario.userSettings.editorWindowLocked, "Lock Window", Styles.styleToggle))
            {
                if (tfScenario.userSettings.editorWindowLocked)
                {
                    CalculateWindowBounds();
                    tfScenario.userSettings.editorWindowPosition = WindowRect;
                    DragEnabled = false;
                }
                else
                {
                    DragEnabled = true;
                }
                tfScenario.userSettings.Save();
            }
            GUILayout.EndVertical();
        }
Beispiel #13
0
        internal List <TestFlightData> AttemptTechTransfer()
        {
            // attempts to transfer data from a predecessor part
            // parts can be referenced either by part name, full name, or configuration name
            // multiple branches can be specified with the & character
            // multiple parts in a branch can be specified by separating them with a comma
            // for each branch the first part listed is considered the closest part, and each part after is considered to be one generation removed.  An optional generation penalty is added for each level
            //  for each branch, the flight data from each part is added together including any generation penalties, to create a total for that branch, modifed by the transfer amount for that branch
            // if multiple branches are specified, each branch is then added together
            // an optional maximum data can be enforced for each scope (global setting but applied to each scope, not total)
            // Example
            // techTransfer = rs-27a,rs-27,h1-b,h1:10&lr-89-na-7,lr-89-na-6,lr-89-na-5:25
            // defines two branches, one from the RS-27 branch and one from the LR-89 branch.

            if (techTransfer.Trim() == "")
            {
                return(null);
            }

            List <TestFlightData>       transferredFlightData;
            Dictionary <string, double> dataToTransfer = null;

            string[] branches;
            string[] modifiers;
            int      generation = 0;

            branches = techTransfer.Split(new char[1] {
                '&'
            });

            foreach (string branch in branches)
            {
                modifiers = branch.Split(new char[1] {
                    ':'
                });
                if (modifiers.Length < 2)
                {
                    continue;
                }
                string[] partsInBranch = modifiers[0].Split(new char[1] {
                    ','
                });
                float branchModifier = float.Parse(modifiers[1]);
                branchModifier /= 100f;
                dataToTransfer  = new Dictionary <string, double>();
                foreach (string partNameFragment in partsInBranch)
                {
                    PartFlightData partData = TestFlightManagerScenario.Instance.GetFlightDataForPartNameFragment(partNameFragment);
                    if (partData == null)
                    {
                        continue;
                    }
                    List <TestFlightData> data = partData.GetFlightData();
                    foreach (TestFlightData scopeData in data)
                    {
                        if (dataToTransfer.ContainsKey(scopeData.scope))
                        {
                            dataToTransfer[scopeData.scope] = dataToTransfer[scopeData.scope] + ((scopeData.flightData - (scopeData.flightData * generation * techTransferGenerationPenalty)) * branchModifier);
                        }
                        else
                        {
                            dataToTransfer.Add(scopeData.scope, ((scopeData.flightData - (scopeData.flightData * generation * techTransferGenerationPenalty))) * branchModifier);
                        }
                    }
                    generation++;
                }
            }
            // When that is all done we should have a bunch of data in our dictionary dataToTransfer sorted by scope.  Now we just need to pack it into proper TestFlightData structs
            if (dataToTransfer == null || dataToTransfer.Count <= 0)
            {
                return(null);
            }
            transferredFlightData = new List <TestFlightData>();
            foreach (var scope in dataToTransfer)
            {
                TestFlightData data = new TestFlightData();
                data.scope = scope.Key;
                if (techTransferMax > 0 && scope.Value > techTransferMax)
                {
                    data.flightData = techTransferMax;
                }
                else
                {
                    data.flightData = scope.Value;
                }
                transferredFlightData.Add(data);
            }
            return(transferredFlightData);
        }