private void BuildFromNodes(IEnumerable <MixtureConfigNode> nodes)
        {
            IEnumerable <string> names = nodes.Select(item => item.configName).Distinct();

            foreach (string name in names)
            {
                List <MixtureConfigNode> nodesForName = nodes.Where(item => item.configName == name).ToList();
                if (nodesForName.Count != 2)
                {
                    EMRUtils.Log("ERROR: expected two nodes per config name");
                    throw new ArgumentException("It is expected to have two nodes per config name", "node");
                }
                MixtureConfigNodePair pair;
                if (nodesForName[0].ratio < nodesForName[1].ratio)
                {
                    pair = new MixtureConfigNodePair(nodesForName[0], nodesForName[1]);
                }
                else
                {
                    pair = new MixtureConfigNodePair(nodesForName[1], nodesForName[0]);
                }
                allNodes.Add(name, pair);
            }

            EMRUtils.Log("Added " + allNodes.Count + " config nodes");

            List <String> configList = nodes.Select(item => item.ToString()).ToList();

            Serialized = ObjectSerializer.Serialize(configList);
        }
예제 #2
0
        /// <summary>
        /// Format a numeric value using SI prefexes.
        ///
        /// eg: 13401 -> 13.4 k
        ///
        /// </summary>
        /// <param name="value">value to format</param>
        /// <param name="unit">unit string</param>
        /// <param name="exponent">Exponennt to the existing value. eg: if value was km rather than m this would be 3.</param>
        /// <param name="sigFigs">number of signifigant figures to display</param>
        /// <returns></returns>
        public static string ToStringSI(this float value, int sigFigs = 3, int exponent = 0, string unit = null)
        {
            EMRUtils.Log("Getting prefix for exponent of " + exponent);
            SIPrefix prefix = value.GetSIPrefix(exponent);

            EMRUtils.Log("Found prefix of " + prefix);
            return(prefix.FormatSI(value, sigFigs, exponent, unit));
        }
예제 #3
0
 public override void OnLoad(ConfigNode node)
 {
     EMRUtils.Log("OnLoad called");
     if (GameSceneFilter.AnyInitializing.IsLoaded())
     {
         EMRUtils.Log("Loading");
         LoadMixtureConfigNodes(node);
         EMRUtils.Log("Loaded");
     }
     base.OnLoad(node);
 }
        public MixtureConfigNodePair(MixtureConfigNode min, MixtureConfigNode max)
        {
            Min = min;
            Max = max;

            if (min == null || max == null)
            {
                EMRUtils.Log("One or both of the MixtureConfigNodes were null, disabling");
                Disabled = true;
            }
        }
예제 #5
0
        private float GetOptimalRatioForRemainingFuel()
        {
            PropellantResources propResources = new PropellantResources(engineModule);

            if (propResources == null)
            {
                EMRUtils.Log("Could not find any connected resources");
                return(CurrentNodePair.Min.ratio);
            }

            double amount;
            double maxAmount;

            EMRUtils.Log("Getting resources totals from part");

            if (part == null)
            {
                //DELETE ME
                EMRUtils.Log("I don't know how, but part is null");
            }
            part.GetConnectedResourceTotals(propResources.Oxidizer.Id, out amount, out maxAmount);

            double remainingOxidizer = amount;

            double remainingFuel = 0;

            foreach (var fuel in propResources.Fuels)
            {
                part.GetConnectedResourceTotals(fuel.Id, out amount, out maxAmount);
                remainingFuel += amount;
            }

            EMRUtils.Log("Remaining Fuel: " + remainingFuel + ", Remaining Oxidier: " + remainingOxidizer);

            if (remainingOxidizer == 0)
            {
                return(CurrentNodePair.Min.ratio);
            }
            if (remainingFuel == 0)
            {
                return(CurrentNodePair.Max.ratio);
            }

            return((float)((remainingOxidizer * propResources.Oxidizer.Density) / (remainingFuel * propResources.AverageFuelDensity)));
        }
예제 #6
0
        public override void OnStart(StartState state)
        {
            base.OnStart(state);
            if (engineModule == null)
            {
                engineModule = part.FindModuleImplementing <ModuleEngines>();
            }

            if (engineModule == null)
            {
                EMRUtils.Log("ERROR! Could not find ModuleEngines");
            }

            if (propellantResources == null)
            {
                propellantResources = new PropellantResources(engineModule);
            }

            EMRUtils.Log("Detecting configs");
            DetectConfig();
            DeserializeNodes();
            BindCallbacks();

            ToggleControlsBasedOnConfigs();
            if (!CurrentNodePair.Disabled)
            {
                SetEditorFields();
            }
            SetActionsAndGui();

            if (HighLogic.LoadedSceneIsFlight)
            {
                BindInFlightCallbacks();
                UpdateInFlightEMRParams();
            }

            UpdateIspAndThrustDisplay();
            SetNeededFuel();

            if (HighLogic.LoadedSceneIsFlight)
            {
                InFlightUIChanged(null, null);
            }
        }
예제 #7
0
        public MixtureConfigNode(string serialized)
        {
            EMRUtils.Log("Creating MixtureConfigNode from: ", serialized);
            var parts = serialized.Split(DELIM);

            configName      = parts[0];
            ratio           = float.Parse(parts[1]);
            minThrust       = float.Parse(parts[2]);
            maxThrust       = float.Parse(parts[3]);
            atmosphereCurve = new FloatCurve();
            for (int i = 4; i < parts.Length; i += 4)
            {
                atmosphereCurve.Add(
                    float.Parse(parts[i]),
                    float.Parse(parts[i + 1]),
                    float.Parse(parts[i + 2]),
                    float.Parse(parts[i + 3]));
            }
        }
예제 #8
0
        private void SetEditorFields()
        {
            EMRUtils.Log("Setting editor fields");
            UI_FloatEdit startFloatEdit = (UI_FloatEdit)Fields["startingEMR"].uiControlEditor;
            UI_FloatEdit finalFloatEdit = (UI_FloatEdit)Fields["finalEMR"].uiControlEditor;

            startFloatEdit.minValue = CurrentNodePair.Min.ratio;
            startFloatEdit.maxValue = CurrentNodePair.Max.ratio;
            finalFloatEdit.minValue = CurrentNodePair.Min.ratio;
            finalFloatEdit.maxValue = CurrentNodePair.Max.ratio;

            if (startingEMR < CurrentNodePair.Min.ratio || startingEMR > CurrentNodePair.Max.ratio)
            {
                startingEMR = CurrentNodePair.Max.ratio;
            }
            if (finalEMR < CurrentNodePair.Min.ratio || finalEMR > CurrentNodePair.Max.ratio)
            {
                finalEMR = CurrentNodePair.Min.ratio;
            }
        }
예제 #9
0
        public PropellantResource(Propellant propellant, PartResourceDefinition resource)
        {
            if (propellant.id != resource.id)
            {
                string errorMessage = "Propellant and Resource do not have the same id.";
                EMRUtils.Log("ERROR: ", errorMessage);
                throw new ArgumentException(errorMessage);
            }

            // We're going to make a clone of the propellant, since we want to leave these "stock" ratios alone
            Propellant = new Propellant()
            {
                id    = propellant.id,
                name  = propellant.name,
                ratio = propellant.ratio
            };

            Resource = resource;

            //EMRUtils.Log("Created new PropellantResource: ", Name, ", ratio: ", Propellant.ratio);
        }
예제 #10
0
        private void ToggleControlsBasedOnConfigs()
        {
            EMRUtils.Log("Toggling Controls based on configs");
            if (CurrentNodePair.Disabled)
            {
                emrEnabled = false;
                EMRUtils.Log("Current node pair is disabled, disabling EMR");
            }

            Events["ToggleEMR"].guiActive       = !CurrentNodePair.Disabled;
            Events["ToggleEMR"].guiActiveEditor = !CurrentNodePair.Disabled;
            Events["ChangeEMRMode"].guiActive   = !CurrentNodePair.Disabled;

            string[] fields = new string[] { "closedLoopEMRText", "currentEMRText", "currentReserveText" };
            foreach (string field in fields)
            {
                Fields[field].guiActive = !CurrentNodePair.Disabled;
            }

            Actions["ChangeEMRModeAction"].active = !CurrentNodePair.Disabled;
        }
예제 #11
0
        private void UpdateInFlightEMRParams()
        {
            if (CurrentNodePair.Disabled)
            {
                return;
            }

            if (emrInClosedLoop)
            {
                EMRUtils.Log("Closed Loop Detected");
                float bestEMR = GetOptimalRatioForRemainingFuel();
                EMRUtils.Log("Best EMR computed to be ", bestEMR, ":1");
                string bestEMRSuffix = "";
                if (bestEMR > CurrentNodePair.Max.ratio)
                {
                    EMRUtils.Log("EMR higher than ", CurrentNodePair.Max.ratio, ":1 (was ", bestEMR, ":1), capping");
                    bestEMR       = CurrentNodePair.Max.ratio;
                    bestEMRSuffix = " (max)";
                }
                else if (bestEMR < CurrentNodePair.Min.ratio)
                {
                    EMRUtils.Log("EMR lower than ", CurrentNodePair.Min.ratio, ":1 (was ", bestEMR, ":1), capping");
                    bestEMR       = CurrentNodePair.Min.ratio;
                    bestEMRSuffix = " (min)";
                }

                currentEMR        = bestEMR;
                closedLoopEMRText = MathUtils.RoundSigFigs(bestEMR).ToString() + ":1" + bestEMRSuffix;
            }

            //EMRUtils.Log("Updating In Flight EMR Params");
            Fields["currentEMR"].guiActive        = !emrInClosedLoop;
            Fields["closedLoopEMRText"].guiActive = emrInClosedLoop;

            UI_FloatEdit currentEMREditor = (UI_FloatEdit)Fields["currentEMR"].uiControlFlight;

            currentEMREditor.minValue = CurrentNodePair.Min.ratio;
            currentEMREditor.maxValue = CurrentNodePair.Max.ratio;
            //EMRUtils.Log("Done Updating In Flight EMR Params");
        }
예제 #12
0
 private void DetectConfig()
 {
     currentConfigName = "";
     if (mecModule == null)
     {
         EMRUtils.Log("Detecting ModuleEngineConfigs");
         foreach (var module in part.Modules)
         {
             if (module.GetType().FullName == "RealFuels.ModuleEngineConfigs")
             {
                 mecModule = module;
                 EMRUtils.Log("Found ModuleEngineConfigs");
                 break;
             }
         }
     }
     if (mecModule != null)
     {
         Type moduleType = mecModule.GetType();
         currentConfigName = moduleType.GetField("configuration").GetValue(mecModule).ToString();
     }
 }
예제 #13
0
        public override string ToString()
        {
            StringBuilder sBuilder = StringBuilderCache.Acquire();

            sBuilder.Append(configName).Append(DELIM)
            .Append(ratio).Append(DELIM)
            .Append(minThrust).Append(DELIM)
            .Append(maxThrust).Append(DELIM);
            if (atmosphereCurve != null)
            {
                foreach (var key in atmosphereCurve.Curve.keys)
                {
                    sBuilder.Append(key.time).Append(DELIM);
                    sBuilder.Append(key.value).Append(DELIM);
                    sBuilder.Append(key.inTangent).Append(DELIM);
                    sBuilder.Append(key.outTangent).Append(DELIM);
                }
            }
            string resultString = sBuilder.ToStringAndRelease().TrimEnd(DELIM);

            EMRUtils.Log("Serialized: ", resultString);
            return(resultString);
        }