public void Load(ConfigNode node) { partName = node.GetValue("partName"); if (node.HasNode("FLIGHTDATA")) { flightData = new List <TestFlightData>(); foreach (ConfigNode dataNode in node.GetNodes("FLIGHTDATA")) { TestFlightData newData = new TestFlightData(); newData.scope = dataNode.GetValue("scope"); if (dataNode.HasValue("flightData")) { newData.flightData = float.Parse(dataNode.GetValue("flightData")); } flightData.Add(newData); } } }
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 void AddFlightData(string name, TestFlightData data) { if (flightData == null) { flightData = new List <TestFlightData>(); partName = name; // add new entry for this scope TestFlightData newData = new TestFlightData(); newData.scope = data.scope; newData.flightData = data.flightData; newData.flightTime = 0; flightData.Add(newData); } else { int dataIndex = flightData.FindIndex(s => s.scope == data.scope); if (dataIndex >= 0) { TestFlightData currentData = flightData[dataIndex]; // We only update the data if its higher than what we already have if (data.flightData > currentData.flightData) { currentData.flightData = data.flightData; flightData[dataIndex] = currentData; } // We don't care about flightTime, so set it to 0 currentData.flightTime = 0; } else { // add new entry for this scope TestFlightData newData = new TestFlightData(); newData.scope = data.scope; newData.flightData = data.flightData; newData.flightTime = 0; flightData.Add(newData); } } }
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 void Load(ConfigNode node) { partName = node.GetValue("partName"); if (node.HasNode("FLIGHTDATA")) { flightData = new List<TestFlightData>(); foreach (ConfigNode dataNode in node.GetNodes("FLIGHTDATA")) { TestFlightData newData = new TestFlightData(); newData.scope = dataNode.GetValue("scope"); if (dataNode.HasValue("flightData")) newData.flightData = float.Parse(dataNode.GetValue("flightData")); flightData.Add(newData); } } }
public void AddFlightData(string name, TestFlightData data) { if (flightData == null) { flightData = new List<TestFlightData>(); partName = name; // add new entry for this scope TestFlightData newData = new TestFlightData(); newData.scope = data.scope; newData.flightData = data.flightData; newData.flightTime = 0; flightData.Add(newData); } else { int dataIndex = flightData.FindIndex(s => s.scope == data.scope); if (dataIndex >= 0) { TestFlightData currentData = flightData[dataIndex]; // We only update the data if its higher than what we already have if (data.flightData > currentData.flightData) { currentData.flightData = data.flightData; flightData[dataIndex] = currentData; } // We don't care about flightTime, so set it to 0 currentData.flightTime = 0; } else { // add new entry for this scope TestFlightData newData = new TestFlightData(); newData.scope = data.scope; newData.flightData = data.flightData; newData.flightTime = 0; flightData.Add(newData); } } }
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 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); }