Beispiel #1
0
        public override string GetModuleInfo(string configuration, float reliabilityAtTime)
        {
            foreach (var configNode in configs)
            {
                if (!configNode.HasValue("configuration"))
                {
                    continue;
                }

                var nodeConfiguration = configNode.GetValue("configuration");

                if (string.Equals(nodeConfiguration, configuration, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (configNode.HasNode("cycle"))
                    {
                        var nodeCycle = new FloatCurve();
                        nodeCycle.Load(configNode.GetNode("cycle"));

                        float nodeBurnTime = 0f;
                        configNode.TryGetValue("ratedBurnTime", ref nodeBurnTime);

                        float burnThrough = nodeCycle.Evaluate(nodeCycle.maxTime);
                        return(String.Format("  Rated Burn Time: <color=#b1cc00ff>{0:F0} s</color>\n  <color=#ec423fff>{1:F0}%</color> failure at <color=#b1cc00ff>{2:F0} s</color>", nodeBurnTime, burnThrough, nodeCycle.maxTime));
                    }
                }
            }

            return(base.GetModuleInfo(configuration, reliabilityAtTime));
        }
        public override string GetModuleInfo(string configuration, float reliabilityAtTime)
        {
            foreach (var configNode in configs)
            {
                if (!configNode.HasValue("configuration"))
                {
                    continue;
                }

                var nodeConfiguration = configNode.GetValue("configuration");

                if (string.Equals(nodeConfiguration, configuration, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (configNode.HasNode("reliabilityCurve"))
                    {
                        var nodeReliability = new FloatCurve();
                        nodeReliability.Load(configNode.GetNode("reliabilityCurve"));

                        // core is not yet available here
                        float reliabilityMin = TestFlightUtil.FailureRateToReliability(nodeReliability.Evaluate(nodeReliability.minTime), reliabilityAtTime);
                        float reliabilityMax = TestFlightUtil.FailureRateToReliability(nodeReliability.Evaluate(nodeReliability.maxTime), reliabilityAtTime);
                        return($"  Reliability at 0 data: <color=#b1cc00ff>{reliabilityMin:P1}</color>\n  Reliability at max data: <color=#b1cc00ff>{reliabilityMax:p1}</color>");
                    }
                }
            }

            return(base.GetModuleInfo(configuration, reliabilityAtTime));
        }
        public virtual void SetActiveConfig(string alias)
        {
            if (configs == null)
            {
                configs = new List <ConfigNode>();
            }

            foreach (var configNode in configs)
            {
                if (!configNode.HasValue("configuration"))
                {
                    continue;
                }

                var nodeConfiguration = configNode.GetValue("configuration");

                if (string.Equals(nodeConfiguration, alias, StringComparison.InvariantCultureIgnoreCase))
                {
                    currentConfig = configNode;
                }
            }

            if (currentConfig == null)
            {
                return;
            }

            // update current values with those from the current config node
            currentConfig.TryGetValue("configuration", ref configuration);
            if (currentConfig.HasNode("reliabilityCurve"))
            {
                reliabilityCurve = new FloatCurve();
                reliabilityCurve.Load(currentConfig.GetNode("reliabilityCurve"));
            }
        }
Beispiel #4
0
        public void FromConfigNode(ConfigNode node)
        {
            Name        = node.GetValue("name");
            ShortName   = node.GetValue("shortName");
            Description = node.GetValue("description");
            Author      = node.GetValue("author");

            bool.TryParse(node.GetValue("allowDeletion"), out AllowDeletion);

            bool.TryParse(node.GetValue("career"), out CareerEnabled);
            bool.TryParse(node.GetValue("science"), out ScienceEnabled);
            bool.TryParse(node.GetValue("sandbox"), out SandboxEnabled);

            ConfigNode.LoadObjectFromConfig(GeneralSettings, node.GetNode("KCT_Preset_General"));
            ConfigNode.LoadObjectFromConfig(TimeSettings, node.GetNode("KCT_Preset_Time"));

            ConfigNode fNode = node.GetNode("KCT_Preset_Formula");

            ConfigNode.LoadObjectFromConfig(FormulaSettings, fNode);
            if (fNode.HasNode("YearBasedRateMult"))
            {
                var fc       = new FloatCurve();
                var rateNode = fNode.GetNode("YearBasedRateMult");
                fc.Load(rateNode);
                FormulaSettings.YearBasedRateMult = fc;
            }

            if (node.HasNode("KCT_Preset_Part_Variables"))
            {
                PartVariables.FromConfigNode(node.GetNode("KCT_Preset_Part_Variables"));
            }
        }
Beispiel #5
0
        public override void SetActiveConfig(string alias)
        {
            base.SetActiveConfig(alias);

            if (currentConfig == null)
            {
                return;
            }

            // update current values with those from the current config node
            cycle = new FloatCurve();
            if (currentConfig.HasNode("cycle"))
            {
                cycle.Load(currentConfig.GetNode("cycle"));
            }
            else
            {
                cycle.Add(0f, 1f);
            }
            thrustModifier = new FloatCurve();
            if (currentConfig.HasNode("thrustModifier"))
            {
                thrustModifier.Load(currentConfig.GetNode("thrustModifier"));
            }
            else
            {
                thrustModifier.Add(0f, 1f);
            }
            currentConfig.TryGetValue("idleDecayRate", ref idleDecayRate);
            currentConfig.TryGetValue("ratedBurnTime", ref ratedBurnTime);
            currentConfig.TryGetValue("engineID", ref engineID);
            currentConfig.TryGetValue("engineConfig", ref engineConfig);
        }
        void PrintCurve(ConfigNode config, string name)
        {
            FloatCurve curve = new FloatCurve();

            curve.Load(config);
            PrintCurve(curve, name);
        }
Beispiel #7
0
        public override string GetModuleInfo(string configuration)
        {
            string infoString = "";

            foreach (var configNode in configs)
            {
                if (!configNode.HasValue("configuration"))
                {
                    continue;
                }

                var nodeConfiguration = configNode.GetValue("configuration");

                if (string.Equals(nodeConfiguration, configuration, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (configNode.HasNode("baseIgnitionChance"))
                    {
                        var nodeIgnitionChance = new FloatCurve();
                        nodeIgnitionChance.Load(configNode.GetNode("baseIgnitionChance"));

                        float pMin = nodeIgnitionChance.Evaluate(nodeIgnitionChance.minTime);
                        float pMax = nodeIgnitionChance.Evaluate(nodeIgnitionChance.maxTime);
                        infoString = $"  Ignition at 0 data: <color=#b1cc00ff>{pMin:P1}</color>\n  Ignition at max data: <color=#b1cc00ff>{pMax:P1}</color>";
                    }
                }
            }

            return(infoString);
        }
Beispiel #8
0
        public void Load(ConfigNode node)
        {
            ConfigNode.LoadObjectFromConfig(this, node);
            if (node.HasValue("configName"))
            {
                configName = node.GetValue("configName");
            }
            else
            {
                configName = "";
            }
            ratio = float.Parse(node.GetValue("ratio"));
            if (node.HasValue("minThrust"))
            {
                minThrust = float.Parse(node.GetValue("minThrust"));
            }
            else
            {
                minThrust = 0;
            }
            maxThrust       = float.Parse(node.GetValue("maxThrust"));
            atmosphereCurve = new FloatCurve();
            ConfigNode atmosCurveNode = node.GetNode("atmosphereCurve");

            if (atmosCurveNode != null)
            {
                atmosphereCurve.Load(atmosCurveNode);
            }
        }
        void Trim(List <double[]> list, double topLayer)
        {
            FloatCurve curve = new FloatCurve();

            curve.Load(WriteCurve(list));

            double[] lastKey = { topLayer, curve.Evaluate((float)topLayer) };

            for (int i = list.Count; i > 0; i--)
            {
                if (list[i - 2][0] < topLayer)
                {
                    double dX      = 0.01 * (lastKey[0] - list[i - 2][0]);
                    double dY      = lastKey[1] - curve.Evaluate((float)(lastKey[0] - dX));
                    double tangent = dY / dX;

                    list.RemoveAt(i - 1);

                    list.Add(new double[] { lastKey[0], lastKey[1], tangent, tangent });
                    break;
                }
                else
                {
                    list.RemoveAt(i - 1);
                }
            }

            // Debug
            PrintCurve(list, "Trim");
        }
Beispiel #10
0
        public void Load(ConfigNode node)
        {
            node.TryGetValue("Name", ref Name);
            node.TryGetValue("Title", ref Title);
            node.TryGetValue("ResourceName", ref ResourceName);
            node.TryGetValue("Discovers", ref Discovers);
            node.TryGetValue("Identifies", ref Identifies);
            node.TryGetValue("Wavelength", ref Wavelength);
            node.TryGetValue("Sensitivity", ref Sensitivity);

            // Configure the default curve
            AtmosphereEffect = new FloatCurve();
            AtmosphereEffect.Add(0f, 1f);
            AtmosphereEffect.Add(70000f, 5f);
            AtmosphereEffect.Add(500000f, 0f);
            ConfigNode floatCurveNode = new ConfigNode();

            if (node.TryGetNode("AtmosphereEffect", ref floatCurveNode))
            {
                AtmosphereEffect.Load(floatCurveNode);
            }

            Wavelength *= 1E-9;
            Title       = Localizer.Format(Title);
        }
Beispiel #11
0
        public void Start()
        {
            foreach (ConfigNode node in part.partInfo.partConfig.GetNodes("MODULE"))
            {
                if (node.GetValue("name") == "SaturableRW")
                {
                    torqueCurve.Load(node.GetNode("torqueCurve"));

                    bleedRate.Load(node.GetNode("bleedRate"));

                    break;
                }
            }

            wheelRef = part.Modules.GetModule <ModuleReactionWheel> ();

            // Float curve initialization.

            maxRollTorque  = wheelRef.RollTorque;
            maxPitchTorque = wheelRef.PitchTorque;
            maxYawTorque   = wheelRef.YawTorque;

            saturationLimit = (maxPitchTorque + maxYawTorque + maxRollTorque) * saturationScale / 3;

            if (HighLogic.LoadedSceneIsFlight)
            {
                // Remember reference torque values.

                LoadConfig();

                StartCoroutine(RegisterWheel());
            }
        }
 public Resource(ConfigNode node)
 {
     //Debug.Log ("VKLoading Resource");
     if (node.HasValue("resourceName") && PartResourceLibrary.Instance.resourceDefinitions.Any(d => d.name == node.GetValue("resourceName")))
     {
         //Debug.Log ("VKResource Found");
         this._resource = PartResourceLibrary.Instance.GetDefinition(node.GetValue("resourceName"));
         if (node.HasValue("maxRate"))
         {
             double.TryParse(node.GetValue("maxRate"), out _maxRate);
         }
         if (node.HasNode("rateCurve"))
         {
             _rateCurve.Load(node.GetNode("rateCurve"));
         }
         if (node.HasNode("revRateCurve"))
         {
             _revRateCurve.Load(node.GetNode("revRateCurve"));
         }
         if (node.HasValue("type"))
         {
             type = node.GetValue("type");
         }
     }
 }
Beispiel #13
0
        public override void OnLoad(ConfigNode node)
        {
            base.OnLoad(node);
            foreach (ConfigNode n in node.GetNodes("RESOURCE"))
            {
                if (n.HasValue("name") && n.HasNode("rate"))
                {
                    FloatCurve rate     = new FloatCurve();
                    string     unitName = "";
                    if (n.HasValue("unitName"))
                    {
                        unitName = n.GetValue("unitName");
                    }
                    else
                    {
                        unitName = n.GetValue("name");
                    }
                    rate.Load(n.GetNode("rate"));

                    inputResources.Add(new ResourceRate(n.GetValue("name"), rate, unitName));
                    print("adding RESOURCE " + n.GetValue("name") + " = " + rate.ToString());
                }
            }

            foreach (ConfigNode n in node.GetNodes("OUTPUT_RESOURCE"))
            {
                if (n.HasValue("name") && n.HasNode("rate"))
                {
                    FloatCurve rate     = new FloatCurve();
                    string     unitName = "";
                    if (n.HasValue("unitName"))
                    {
                        unitName = n.GetValue("unitName");
                    }
                    else
                    {
                        unitName = n.GetValue("name");
                    }
                    rate.Load(n.GetNode("rate"));

                    outputResources.Add(new ResourceRate(n.GetValue("name"), rate, unitName));
                    print("adding OUTPUT_RESOURCE " + n.GetValue("name") + " = " + rate.ToString());
                }
            }

            foreach (ConfigNode c in node.GetNodes("HEATPUMP_NODE"))
            {
                print("searching HEATPUMP_NODE");
                if (c.HasValue("name"))
                {
                    string nodeName = c.GetValue("name");
                    attachNodeNames.Add(nodeName);
                    print("Adding HEATPUMP_NODE " + nodeName);
                }
            }
        }
 public override void OnLoad(ConfigNode node)
 {
     // As of v1.3 we dont' need to worry about reliability bodies anymore, just a simple FloatCurve
     if (node.HasNode("reliabilityCurve"))
     {
         reliabilityCurve = new FloatCurve();
         reliabilityCurve.Load(node.GetNode("reliabilityCurve"));
     }
     base.OnLoad(node);
 }
        public EngineEventController(ConfigNode node)
        {
            name = "engineEvent";
            node.TryGetValue("name", ref name);
            linkedTo = "engineEvent";
            node.TryGetValue("eventName", ref eventName);
            node.TryGetValue("eventDuration", ref eventDuration);

            eventCurve.Load(node.GetNode("eventCurve"));
        }
        public void OnLoad(ConfigNode node)
        {
            // Process nodes
            node.TryGetValue("name", ref name);
            node.TryGetValue("laserFXControllerIDs", ref fxName);

            fxNames = fxName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            fxCurve.Load(node.GetNode("laserFXIntensityCurve"));
        }
Beispiel #17
0
 public void Load(ConfigNode node)
 {
     ConfigNode.LoadObjectFromConfig(this, node);
     if (node.GetNode("atmosphereCurve") is ConfigNode atmosCurveNode)
     {
         atmosphereCurve = new FloatCurve();
         atmosphereCurve.Load(atmosCurveNode);
     }
     name ??= node.GetValue("displayName");
 }
Beispiel #18
0
        public override void Load(ConfigNode node)
        {
            base.Load(node);

            node.TryGetValue("floatName", ref floatName);
            curve = new();
            curve.Load(node.GetNode("floatCurve"));

            modifierTypeName = "Material Float";
        }
 public void Load(ConfigNode node)
 {
     if (node.HasValue("scope"))
         scope = node.GetValue("scope").ToLower();
     if (node.HasNode("reliabilityCurve"))
     {
         reliabilityCurve = new FloatCurve();
         reliabilityCurve.Load(node.GetNode("reliabilityCurve"));
     }
 }
 public override void OnLoad(ConfigNode node)
 {
     base.OnLoad(node);
     if (node.HasNode("cycle"))
     {
         cycle = new FloatCurve();
         cycle.Load(node.GetNode("cycle"));
     }
     else
         cycle = null;
 }
        public ResourceBand(string resourceName, ConfigNode node)
        {
            ResourceName = resourceName;
            string distName = "Uniform";


            node.TryGetValue("name", ref name);
            node.TryGetValue("title", ref title);
            node.TryGetValue("countScale", ref countScale);
            node.TryGetValue("rotateRate", ref rotateRate);

            node.TryGetValue("minAbundance", ref minAbundance);
            node.TryGetValue("maxAbundance", ref maxAbundance);
            node.TryGetValue("useAirDensity", ref useAirDensity);

            node.TryGetValue("alwaysDiscovered", ref AlwaysDiscovered);
            node.TryGetValue("alwaysIdentified", ref AlwaysIdentified);
            node.TryGetValue("alwaysIdentified", ref AlwaysIdentified);

            node.TryGetValue("distributionType", ref distName);

            node.TryGetValue("remoteDiscoveryScale", ref RemoteDiscoveryScale);

            discoveryScienceReward = Settings.BaseDiscoverScienceReward;
            identifyScienceReward  = Settings.BaseIdentifyScienceReward;
            node.TryGetValue("discoveryScienceReward", ref discoveryScienceReward);
            node.TryGetValue("identifyScienceReward", ref identifyScienceReward);

            title = Localizer.Format(title);

            densityCurve = new FloatCurve();

            if (useAirDensity)
            {
                densityCurve.Add(0f, 0f);
                densityCurve.Add(1f, 1f);
                densityCurve.Add(12f, 12f);
                ConfigNode densCurve = new ConfigNode();
                if (node.TryGetNode("densityCurve", ref densCurve))
                {
                    densityCurve.Load(densCurve);
                }
            }

            if (distName == "Uniform")
            {
                Distribution = new UniformDistributionModel(node) as DistributionModel;
            }

            if (distName == "Spherical")
            {
                Distribution = new SphericalDistributionModel(node) as DistributionModel;
            }
        }
        public override void Load(ConfigNode node)
        {
            base.Load(node);

            node.TryGetValue("textureName", ref textureName);
            scrollCurveX = new();
            scrollCurveY = new();
            scrollCurveX.Load(node.GetNode("scrollCurveX"));
            scrollCurveY.Load(node.GetNode("scrollCurveY"));
            modifierTypeName = GetType().Name;
        }
 public override void Load(ConfigNode node)
 {
     base.Load(node);
     xCurve = new FloatCurve();
     yCurve = new FloatCurve();
     zCurve = new FloatCurve();
     xCurve.Load(node.GetNode("xCurve"));
     yCurve.Load(node.GetNode("yCurve"));
     zCurve.Load(node.GetNode("zCurve"));
     modifierTypeName = "Position";
 }
Beispiel #24
0
 public override void Load(ConfigNode node)
 {
     base.Load(node);
     xCurve = new();
     yCurve = new();
     zCurve = new();
     xCurve.Load(node.GetNode("xCurve"));
     yCurve.Load(node.GetNode("yCurve"));
     zCurve.Load(node.GetNode("zCurve"));
     modifierTypeName = "Scale";
 }
Beispiel #25
0
 public void Load(ConfigNode node)
 {
     if (node.HasValue("scope"))
     {
         scope = node.GetValue("scope").ToLower();
     }
     if (node.HasNode("reliabilityCurve"))
     {
         reliabilityCurve = new FloatCurve();
         reliabilityCurve.Load(node.GetNode("reliabilityCurve"));
     }
 }
Beispiel #26
0
        /// <summary>
        /// Loads the desired FloatCurve from the desired config node.
        /// </summary>
        /// <param name="curve">The FloatCurve to load</param>
        /// <param name="curveNodeName">The name of the curve to load</param>
        /// <param name="defaultCurve">An optional default curve to use in case the curve's node doesn't exist in the part module's config.</param>
        protected void loadCurve(FloatCurve curve, string curveNodeName, ConfigNode defaultCurve = null)
        {
            if (curve.Curve.length > 0)
            {
                return;
            }
            ConfigNode[] nodes      = this.part.partInfo.partConfig.GetNodes("MODULE");
            ConfigNode   engineNode = null;
            ConfigNode   node       = null;
            string       moduleName;

            //Get the switcher config node.
            for (int index = 0; index < nodes.Length; index++)
            {
                node = nodes[index];
                if (node.HasValue("name"))
                {
                    moduleName = node.GetValue("name");
                    if (moduleName == this.ClassName)
                    {
                        engineNode = node;
                        break;
                    }
                }
            }
            if (engineNode == null)
            {
                return;
            }

            if (engineNode.HasNode(curveNodeName))
            {
                node = engineNode.GetNode(curveNodeName);
                curve.Load(node);
            }
            else if (defaultCurve != null)
            {
                curve.Load(defaultCurve);
            }
        }
 public override void OnLoad(ConfigNode node)
 {
     base.OnLoad(node);
     if (node.HasNode("cycle"))
     {
         cycle = new FloatCurve();
         cycle.Load(node.GetNode("cycle"));
     }
     else
     {
         cycle = null;
     }
 }
 void QuickFix(FloatCurve curve, double topLayer)
 {
     if (topLayer > curve.maxTime)
     {
         List <double[]> list = ReadCurve(curve); /* Avoid Bad Curves ==> */ if (list.Count == 0)
         {
             Debug.Log("AtmosphereTopLayer.QuickFix", "This curve is pointless."); return;
         }
         list.Last()[3] = 0;
         list.Add(new double[] { topLayer, list.Last()[1], 0, 0 });
         curve.Load(WriteCurve(list));
     }
 }
Beispiel #29
0
 public static void Load()
 {
     bullets = new BulletInfos();
     UrlDir.UrlConfig[] nodes = GameDatabase.Instance.GetConfigs("BULLET");
     for (int i = 0; i < nodes.Length; i++)
     {
         ConfigNode node             = nodes[i].config;
         FloatCurve penetrationCurve = new FloatCurve();
         penetrationCurve.Load(node.GetNode("penetration"));
         bullets.Add(new BulletInfo(node.GetValue("name"), float.Parse(node.GetValue("positiveCoefficient")),
                                    penetrationCurve));
     }
 }
        void Multiply(FloatCurve curve, double multiplier)
        {
            List <double[]> list = new List <double[]>();

            list = ReadCurve(curve);
            foreach (double[] key in list)
            {
                key[0] *= multiplier;
                key[2] /= multiplier;
                key[3] /= multiplier;
            }
            curve.Load(WriteCurve(list));
        }
Beispiel #31
0
        // loads from an override node
        public bool Load(ConfigNode node)
        {
            if (node.HasNode("atmosphereCurve"))
            {
                atmosphereCurve.Load(node.GetNode("atmosphereCurve"));
            }
            else
            {
                atmosphereCurve = null;
                return(false);
            }

            if (node.HasNode("velocityCurve"))
            {
                velocityCurve.Load(node.GetNode("velocityCurve"));
            }
            else
            {
                velocityCurve = null;
            }

            TWR = node.HasValue("TWR") ? double.Parse(node.GetValue("TWR")) : -1;

            thrustMultiplier = node.HasValue("thrustMultiplier") ? double.Parse(node.GetValue("thrustMultiplier")) : -1;

            massMultiplier = node.HasValue("massMultiplier") ? double.Parse(node.GetValue("massMultiplier")) : -1;

            minThrottleMultiplier = node.HasValue("minThrottleMultiplier") ? double.Parse(node.GetValue("minThrottleMultiplier")) : -1;

            gimbalRange = node.HasValue("gimbalRange") ? float.Parse(node.GetValue("gimbalRange")) : -1;

            costMult = node.HasValue("costMult") ? float.Parse(node.GetValue("costMult")) : 1f;

            techRequired = node.HasValue("techRequired") ? node.GetValue("techRequired") : "";

            return(true);
        }
Beispiel #32
0
        public override void OnLoad(ConfigNode node)
        {
            base.OnLoad(node);
            if (node.HasNode("ClCurve"))
            {
                ClPotentialCurve = new FloatCurve();
                ClPotentialCurve.Load(node.GetNode("ClCurve"));
                ClViscousCurve = new FloatCurve();
                ClViscousCurve.Add(-1, 0);
                ClViscousCurve.Add(1, 0);
            }
            if (node.HasValue("majorMinorAxisRatio"))
            {
                double.TryParse(node.GetValue("majorMinorAxisRatio"), out majorMinorAxisRatio);
            }
            if (node.HasValue("taperCrossSectionAreaRatio"))
            {
                double.TryParse(node.GetValue("taperCrossSectionAreaRatio"), out taperCrossSectionAreaRatio);
            }
            if (node.HasValue("cosAngleCutoff"))
            {
                double.TryParse(node.GetValue("cosAngleCutoff"), out cosAngleCutoff);
            }
            if (node.HasValue("ignoreAnim"))
            {
                bool.TryParse(node.GetValue("ignoreAnim"), out ignoreAnim);
            }

            if (node.HasNode("CdCurve"))
            {
                CdCurve = new FloatCurve();
                CdCurve.Load(node.GetNode("CdCurve"));
            }
            if (node.HasNode("ClPotentialCurve"))
            {
                ClPotentialCurve = new FloatCurve();
                ClPotentialCurve.Load(node.GetNode("ClPotentialCurve"));
            }
            if (node.HasNode("ClViscousCurve"))
            {
                ClViscousCurve = new FloatCurve();
                ClViscousCurve.Load(node.GetNode("ClViscousCurve"));
            }
            if (node.HasNode("CmCurve"))
            {
                CmCurve = new FloatCurve();
                CmCurve.Load(node.GetNode("CmCurve"));
            }
        }
        public override string GetInfo ()
        {
            if (configs.Count < 2)
                return TLTInfo();

            string info = TLTInfo() + "\nAlternate configurations:\n";

            TechLevel moduleTLInfo = new TechLevel();
            if (techNodes != null)
                moduleTLInfo.Load(techNodes, techLevel);
            else
                moduleTLInfo = null;

            foreach (ConfigNode config in configs) {
                if(!config.GetValue ("name").Equals (configuration)) {
                    info += "   " + config.GetValue ("name") + "\n";
                    if(config.HasValue (thrustRating))
                        info += "    (" + ThrustTL(config.GetValue (thrustRating), config).ToString("0.00") + " Thrust";
                    else
                        info += "    (Unknown Thrust";

                    FloatCurve isp = new FloatCurve();
                    if(config.HasNode ("atmosphereCurve")) {
                        isp.Load (config.GetNode ("atmosphereCurve"));
                        info  += ", "
                            + isp.Evaluate (isp.maxTime).ToString() + "-"
                              + isp.Evaluate (isp.minTime).ToString() + "Isp";
                    }
                    else if (config.HasValue("IspSL") && config.HasValue("IspV"))
                    {
                        float ispSL = 1.0f, ispV = 1.0f;
                        float.TryParse(config.GetValue("IspSL"), out ispSL);
                        float.TryParse(config.GetValue("IspV"), out ispV);
                        TechLevel cTL = new TechLevel();
                        if (cTL.Load(config, techNodes, engineType, techLevel))
                        {
                            ispSL *= ispSLMult * cTL.atmosphereCurve.Evaluate(1);
                            ispV *= ispVMult * cTL.atmosphereCurve.Evaluate(0);
                            info += ", " + ispSL.ToString("0") + "-" + ispV.ToString("0") + "Isp";
                        }
                    }
                    info += ")\n";
                }


            }
            return info;
        }
        public static FloatCurve ModifyCurveKeys(ConfigNode tempNode, float vacMult, float atmMult, bool extendToZero)
        {
            FloatCurve initialCurve = new FloatCurve();

            initialCurve.Load(tempNode);

            string[] keyStrings = tempNode.GetValues("key");

            float maxTime, ispAtMaxTime, secondTime, ispAtSecondTime, maxPressure;
            maxTime = ispAtMaxTime = secondTime = ispAtSecondTime = maxPressure = 0;
            FloatCurve newAtmosphereCurve = new FloatCurve();

            maxTime = initialCurve.maxTime;

            for (int i = 0; i < keyStrings.Length; i++)
            {
                string[] splitKey = keyStrings[i].Split(' ');

                float scalar = vacMult + Convert.ToSingle(splitKey[0]) * (atmMult - vacMult);
                if (!extendToZero)
                    scalar = Mathf.Clamp(scalar, Mathf.Min(atmMult, vacMult), Mathf.Max(atmMult, vacMult));

                if (Convert.ToSingle(splitKey[0]) != 0)
                    newAtmosphereCurve.Add(Convert.ToSingle(splitKey[0]), Convert.ToSingle(splitKey[1]) * scalar, Convert.ToSingle(splitKey[2]) * scalar, Convert.ToSingle(splitKey[3]) * scalar);
                else
                    newAtmosphereCurve.Add(Convert.ToSingle(splitKey[0]), Convert.ToSingle(splitKey[1]) * scalar, 0, 0);

                if (i == keyStrings.Length - 2)
                {
                    secondTime = Convert.ToSingle(splitKey[0]);
                    ispAtSecondTime = Convert.ToSingle(splitKey[1]) * scalar;
                }

            }

            ispAtMaxTime = newAtmosphereCurve.Evaluate(maxTime);

            if (extendToZero && (ispAtSecondTime - ispAtMaxTime) >= 0.0001f)
            {
                maxPressure = maxTime + (0.01f - ispAtMaxTime) / (ispAtSecondTime - ispAtMaxTime) * (secondTime - maxTime);
                newAtmosphereCurve.Add(maxPressure, 0.01f, 0, 0);
            }

            return newAtmosphereCurve;
        }
        virtual public void DoConfig(ConfigNode cfg)
        {
            // fix propellant ratios to not be rounded
            if (cfg.HasNode("PROPELLANT"))
            {
                foreach (ConfigNode pNode in cfg.GetNodes("PROPELLANT"))
                {
                    if (pNode.HasValue("ratio"))
                    {
                        double dtmp;
                        if (double.TryParse(pNode.GetValue("ratio"), out dtmp))
                            pNode.SetValue("ratio", (dtmp * 100.0).ToString());
                    }
                }
            }
            float heat = -1;
            if (cfg.HasValue("heatProduction")) // ohai amsi: allow heat production to be changed by multiplier
            {
                heat = (float)Math.Round(float.Parse(cfg.GetValue("heatProduction")) * heatMult, 0);
                cfg.SetValue("heatProduction", heat.ToString());
            }

            // load throttle (for later)
            curThrottle = throttle;
            if (cfg.HasValue("throttle"))
                float.TryParse(cfg.GetValue("throttle"), out curThrottle);
            else if(cfg.HasValue("minThrust") && cfg.HasValue("maxThrust"))
                curThrottle = float.Parse(cfg.GetValue("minThrust")) / float.Parse(cfg.GetValue("maxThrust"));
            float TLMassMult = 1.0f;
            if (techLevel != -1)
            {
                // load techlevels
                TechLevel cTL = new TechLevel();
                //print("For engine " + part.name + ", config " + configuration + ", max TL: " + TechLevel.MaxTL(cfg, techNodes, engineType));
                cTL.Load(cfg, techNodes, engineType, techLevel);
                TechLevel oTL = new TechLevel();
                oTL.Load(cfg, techNodes, engineType, origTechLevel);


                // set atmosphereCurve
                if (cfg.HasValue("IspSL") && cfg.HasValue("IspV"))
                {
                    cfg.RemoveNode("atmosphereCurve");
                    ConfigNode curve = new ConfigNode("atmosphereCurve");
                    float ispSL, ispV;
                    float.TryParse(cfg.GetValue("IspSL"), out ispSL);
                    float.TryParse(cfg.GetValue("IspV"), out ispV);
                    FloatCurve aC = new FloatCurve();
                    aC = Mod(cTL.atmosphereCurve, ispSL, ispV);
                    aC.Save(curve);
                    cfg.AddNode(curve);
                }

                // set heatProduction and dissipation
                if (heat > 0)
                {
                    cfg.SetValue("heatProduction", MassTL(heat).ToString("0"));
                    part.heatDissipation = 0.12f / MassTL(1.0f);
                }

                // set thrust and throttle
                if (cfg.HasValue(thrustRating))
                {
                    float thr;
                    float.TryParse(cfg.GetValue(thrustRating), out thr);
                    configMaxThrust = ThrustTL(thr);
                    cfg.SetValue(thrustRating, configMaxThrust.ToString("0.0000"));
                    if (cfg.HasValue("minThrust"))
                    {
                        float.TryParse(cfg.GetValue("minThrust"), out thr);
                        configMinThrust = ThrustTL(thr);
                        cfg.SetValue("minThrust", configMinThrust.ToString("0.0000"));
                    }
                    else
                    {
                        if (thrustRating.Equals("thrusterPower"))
                        {
                            configMinThrust = configMaxThrust * 0.5f;
                        }
                        else
                        {
                            configMinThrust = configMaxThrust;
                            if (curThrottle > 1.0f)
                            {
                                if (techLevel >= curThrottle)
                                    curThrottle = 1.0f;
                                else
                                    curThrottle = -1.0f;
                            }
                            if (curThrottle >= 0.0f)
                            {
                                curThrottle = (float)((double)curThrottle * cTL.Throttle());
                                configMinThrust *= curThrottle;
                            }
                            cfg.SetValue("minThrust", configMinThrust.ToString("0.0000"));
                        }
                    }
                    curThrottle = configMinThrust / configMaxThrust;
                    if(origMass > 0)
                         TLMassMult =  MassTL(1.0f);
                }
            }
            else
            {
                if(cfg.HasValue(thrustRating) && curThrottle > 0f && !cfg.HasValue("minThrust"))
                {
                    configMinThrust = curThrottle * float.Parse(cfg.GetValue(thrustRating));
                    cfg.SetValue("minThrust", configMinThrust.ToString("0.0000"));
                }
            }
            // mass change
            if (origMass > 0)
            {
                float ftmp;
                configMassMult = 1.0f;
                if (cfg.HasValue("massMult"))
                    if (float.TryParse(cfg.GetValue("massMult"), out ftmp))
                        configMassMult = ftmp;

                part.mass = origMass * configMassMult * massMult * TLMassMult;
            }
            // KIDS integration
            if(cfg.HasNode("atmosphereCurve"))
            {
                ConfigNode newCurveNode = new ConfigNode("atmosphereCurve");
                FloatCurve oldCurve = new FloatCurve();
                oldCurve.Load(cfg.GetNode("atmosphereCurve"));
                FloatCurve newCurve = Mod(oldCurve, ispSLMult, ispVMult);
                newCurve.Save(newCurveNode);
                cfg.RemoveNode("atmosphereCurve");
                cfg.AddNode(newCurveNode);
            }
        }
 public override void OnLoad(ConfigNode node)
 {
     // As of v1.3 we dont' need to worry about reliability bodies anymore, just a simple FloatCurve
     if (node.HasNode("reliabilityCurve"))
     {
         reliabilityCurve = new FloatCurve();
         reliabilityCurve.Load(node.GetNode("reliabilityCurve"));
     }
     //            if (node.HasNode("RELIABILITY_BODY"))
     //            {
     //                if (reliabilityBodies == null)
     //                    reliabilityBodies = new List<ReliabilityBodyConfig>();
     //                foreach (ConfigNode bodyNode in node.GetNodes("RELIABILITY_BODY"))
     //                {
     //                    ReliabilityBodyConfig reliabilityBody = new ReliabilityBodyConfig();
     //                    reliabilityBody.Load(bodyNode);
     //                    reliabilityBodies.Add(reliabilityBody);
     //                }
     //            }
     base.OnLoad(node);
 }
Beispiel #37
0
        public PistonEngine(float power, float speed, float BSFC)
        {
            _boost = 1;
            _running = false;
            _fuel = true;
            _boostPressure = 0;
            _hasSuper = false;
            _boostMults = new float[2];
            _boostCosts = new float[2];
            _boostMults[0] = 1f;
            _boostMults[1] = 1f;
            _boostCosts[0] = 0f;
            _boostCosts[1] = 0f;
            _boostMode = 0;
            _boostSwitch = -1f; // auto
            _coolerEffic = 0f;
            _coolerMin = 0f;
            _ramAir = 0.1f;
            _volEfficMult = 1.0f;

            _oilTemp = 298f;
            _oilTempTarget = _oilTemp;
            _dOilTempdt = 0;

            _bsfc = BSFC;

            _minthrottle = 0.1f;
            _maxMP = 1e6f; // No waste gate on non-turbo engines.
            _wastegate = 1f;
            _charge = 1f;
            _chargeTarget = 1f;
            _turboLag = 2f;

            // set reference conditions
            _power0 = power;
            _omega0 = speed;

            // Guess at reasonable values for these guys.  Displacements run
            // at about 2 cubic inches per horsepower or so, at least for
            // non-turbocharged engines.
            // change to 1.4; supercharging...
            _compression = 8;
            _displacement = power * (1.4f * CIN2CM / HP2W);

            mixtureEfficiency = new FloatCurve();
            ConfigNode node = new ConfigNode("MixtureEfficiency");
            node.AddValue("key", "0.05 0 0 2.09732360097324");
            node.AddValue("key", "0.05137 0.00862 2.09732360097324 164.206349206348");
            node.AddValue("key", "0.05179 0.21552 164.206349206348 35.4900398406375");
            node.AddValue("key", "0.0543 0.48276 35.4900398406375 18.1343042071197");
            node.AddValue("key", "0.05842 0.7069 18.1343042071197 9.17092198581561");
            node.AddValue("key", "0.06312 0.83621 9.17092198581561 5.01693121693122");
            node.AddValue("key", "0.06942 0.93103 5.01693121693122 2.7239336492891");
            node.AddValue("key", "0.07786 1 2.7239336492891 0");
            node.AddValue("key", "0.08845 1 0 -1.3521568627451");
            node.AddValue("key", "0.0927 0.98276 -1.3521568627451 -2.02862745098038");
            node.AddValue("key", "0.09695 0.956895 -2.02862745098038 -2.02862745098041");
            node.AddValue("key", "0.099075 0.9439625 -2.02862745098041 -2.02862745098041");
            node.AddValue("key", "0.1001375 0.93749625 -2.02862745098041 -2.02862745098038");
            node.AddValue("key", "0.1012 0.93103 -2.02862745098038 -5.16579275905118");
            node.AddValue("key", "0.1045375 0.8793075 -5.16579275905118 -5.1657927590512");
            node.AddValue("key", "0.107875 0.827585 -5.1657927590512 -5.16579275905119");
            node.AddValue("key", "0.11455 0.72414 -5.16579275905119 -12.6714082503556");
            node.AddValue("key", "0.12158 0.4569 -12.6714082503556 -26.9723225030083");
            node.AddValue("key", "0.12435 0.23276 -26.9723225030083 -119.364102564103");
            node.AddValue("key", "0.125 0 -119.364102564103 0");
            mixtureEfficiency.Load(node);

            ComputeVEMultiplier(); // compute volumetric efficiency of engine, based on rated power and BSFC.
        }
Beispiel #38
0
        public void Load(ConfigNode node)
        {
            if (node.HasNode("PROPELLER"))
                node = node.GetNode("PROPELLER");

            if (node.HasValue("name"))
                name = node.GetValue("name");
            if (node.HasValue("ixx"))
                Ixx = double.Parse(node.GetValue("ixx"));
            if (node.HasValue("ixxFTLB"))
                Ixx = double.Parse(node.GetValue("ixxFTLB")) * FTLBTOJ;
            if (node.HasValue("diameterIN"))
                Diameter = double.Parse(node.GetValue("diameterIN")) * INTOM;
            if (node.HasValue("diameterFT"))
                Diameter = double.Parse(node.GetValue("diameterFT")) * FTTOM;
            if (node.HasValue("diameter"))
                Diameter = double.Parse(node.GetValue("diameter"));
            if (node.HasValue("numblades"))
                numBlades = int.Parse(node.GetValue("numblades"));
            if (node.HasValue("gearratio"))
                GearRatio = double.Parse(node.GetValue("gearratio"));
            if (node.HasValue("minpitch"))
                MinPitch = double.Parse(node.GetValue("minpitch"));
            if (node.HasValue("maxpitch"))
                MaxPitch = double.Parse(node.GetValue("maxpitch"));
            if (node.HasValue("minrpm"))
                MinRPM = double.Parse(node.GetValue("minrpm"));
            if (node.HasValue("maxrpm"))
            {
                MaxRPM = double.Parse(node.GetValue("maxrpm"));
                ConstantSpeed = 1;
            }
            if (node.HasValue("constspeed"))
                ConstantSpeed = int.Parse(node.GetValue("constspeed"));
            if (node.HasValue("reversepitch"))
                ReversePitch = double.Parse(node.GetValue("reversepitch"));

            if (node.HasNode("cThrust"))
                cThrust = new FGTable(node.GetNode("cThrust"));
            if (node.HasNode("cThrustFP"))
            {
                cThrustFP = new FloatCurve();
                cThrustFP.Load(node.GetNode("cThrustFP"));
            }
            if (node.HasNode("cPower"))
                cPower = new FGTable(node.GetNode("cPower"));
            if (node.HasNode("cPowerFP"))
            {
                cPowerFP = new FloatCurve();
                cPowerFP.Load(node.GetNode("cPowerFP"));
            }
            if (node.HasNode("CtMach"))
            {
                CtMach = new FloatCurve();
                CtMach.Load(node.GetNode("CtMach"));
            }
            if (node.HasNode("CpMach"))
            {
                CpMach = new FloatCurve();
                CpMach.Load(node.GetNode("CpMach"));
            }
            if (node.HasNode("MachDrag"))
            {
                MachDrag = new FloatCurve();
                MachDrag.Load(node.GetNode("MachDrag"));
            }

            if (node.HasValue("sense"))
                Sense = double.Parse(node.GetValue("sense"));
            SetSense(Sense >= 0.0 ? 1.0 : -1.0);
            if (node.HasValue("P_Factor"))
                P_Factor = double.Parse(node.GetValue("P_Factor"));
            if (node.HasValue("ct_factor"))
                SetCtFactor(double.Parse(node.GetValue("ct_factor")));
            if (node.HasValue("cp_factor"))
                SetCpFactor(double.Parse(node.GetValue("cp_factor")));

            CalcDefaults();
            // persistent values
            if (node.HasValue("RPM"))
                RPM = double.Parse(node.GetValue("RPM"));
            if (node.HasValue("Pitch"))
                Pitch = double.Parse(node.GetValue("Pitch"));
            if (node.HasValue("Feathered"))
                Feathered = bool.Parse(node.GetValue("Feathered"));
            if (node.HasValue("Reversed"))
                Reversed = bool.Parse(node.GetValue("Reversed"));
        }
        public override string GetInfo()
        {
            if (!compatible)
                return "";
            if (configs.Count < 2)
                return TLTInfo();

            string info = TLTInfo() + "\nAlternate configurations:\n";

            //Unused as yet
            /*TechLevel moduleTLInfo = new TechLevel();
            if (techNodes != null)
                moduleTLInfo.Load(techNodes, techLevel);
            else
                moduleTLInfo = null;*/

            foreach (ConfigNode config in configs) {

                TechLevel cTL = new TechLevel();
                if (!cTL.Load(config, techNodes, engineType, techLevel))
                    cTL = null;

                if(!config.GetValue ("name").Equals (configuration)) {
                    info += "   " + config.GetValue ("name") + "\n";
                    if(config.HasValue (thrustRating))
                        info += "    (" + (scale * ThrustTL(config.GetValue (thrustRating), config)).ToString("0.00") + " Thrust";
                    else
                        info += "    (Unknown Thrust";
                    float cst;
                    if(config.HasValue("cost") && float.TryParse(config.GetValue("cost"), out cst))
                        info += "    (" + (scale*cst).ToString("N0") + " extra cost)"; // FIXME should get cost from TL, but this should be safe
                    // because it will always be the cost for the original TL, and thus unmodified.

                    FloatCurve isp = new FloatCurve();
                    if(config.HasNode ("atmosphereCurve")) {
                        isp.Load (config.GetNode ("atmosphereCurve"));
                        info  += ", "
                            + isp.Evaluate (isp.maxTime).ToString() + "-"
                              + isp.Evaluate (isp.minTime).ToString() + "Isp";
                    }
                    else if (config.HasValue("IspSL") && config.HasValue("IspV"))
                    {
                        float ispSL = 1.0f, ispV = 1.0f;
                        float.TryParse(config.GetValue("IspSL"), out ispSL);
                        float.TryParse(config.GetValue("IspV"), out ispV);
                        if (cTL != null)
                        {
                            ispSL *= ispSLMult * cTL.AtmosphereCurve.Evaluate(1);
                            ispV *= ispVMult * cTL.AtmosphereCurve.Evaluate(0);
                            info += ", " + ispSL.ToString("0") + "-" + ispV.ToString("0") + "Isp";
                        }
                    }
                    float gimbalR = -1f;
                    if (config.HasValue("gimbalRange"))
                        gimbalR = float.Parse(config.GetValue("gimbalRange"));
                    // Don't do per-TL checks here, they're misleading.
                    /*else if (!gimbalTransform.Equals("") || useGimbalAnyway)
                    {
                        if (cTL != null)
                            gimbalR = cTL.GimbalRange;
                    }*/
                    if (gimbalR != -1f)
                        info += ", Gimbal " + gimbalR.ToString("N1");

                    if (config.HasValue("ullage"))
                        info += ", " + (config.GetValue("ullage").ToLower() == "true" ? "ullage" : "no ullage");
                    if (config.HasValue("pressureFed") && config.GetValue("pressureFed").ToLower() == "true")
                        info += ", pfed";

                    if (config.HasValue("ignitions"))
                    {
                        int ignitions;
                        if (int.TryParse(config.GetValue("ignitions"), out ignitions))
                        {
                            if (ignitions > 0)
                                info += ", " + ignitions + " ignition" + (ignitions > 1 ? "s" : "");
                            else
                                info += ", unl. ignitions";
                        }
                    }
                    info += ")\n";
                }

            }
            return info;
        }
 public void Load(ConfigNode node)
 {
     ConfigNode.LoadObjectFromConfig(this, node);
     ConfigNode atmosCurveNode = node.GetNode("atmosphereCurve");
     if (atmosCurveNode != null)
     {
         atmosphereCurve = new FloatCurve();
         atmosphereCurve.Load(atmosCurveNode);
     }
     if (name == null)
         name = node.GetValue("displayName");
 }
 void PrintCurve(ConfigNode config, string name)
 {
     FloatCurve curve = new FloatCurve();
     curve.Load(config);
     PrintCurve(curve, name);
 }
 void QuickFix(FloatCurve curve, double topLayer)
 {
     if (topLayer > curve.maxTime)
     {
         List<double[]> list = ReadCurve(curve); /* Avoid Bad Curves ==> */ if (list.Count == 0) { UnityEngine.Debug.Log("SigmaLog: This curve is pointless."); return; }
         list.Last()[3] = 0;
         list.Add(new double[] { topLayer, list.Last()[1], 0, 0 });
         curve.Load(WriteCurve(list));
     }
 }
        void Smooth(List<double[]> list, double smoothRange)
        {
            FloatCurve curve = new FloatCurve();
            curve.Load(WriteCurve(list));
            double topLayer = curve.maxTime;
            double smoothStart = topLayer - smoothRange;

            double[] newKey = { smoothStart, curve.Evaluate((float)smoothStart) };
            double[] lastKey = { topLayer, 0, 0, 0 };

            for (int i = list.Count; i > 0; i--)
            {
                if (list[i - 1][0] >= smoothStart)
                    list.RemoveAt(i - 1);
            }

            list.Add(newKey);
            list.Add(lastKey);

            // Debug
            PrintCurve(list, "Smooth");
        }
Beispiel #44
0
 /*private List<PQSLandControl.LandClass> GetListLC(ConfigNode node)
 {
     ConfigNode curNodes = new ConfigNode();
     node.CopyTo(curNodes);
     List<PQSLandControl.LandClass> list = new List<PQSLandControl.LandClass>();
     Type cType = typeof(PQSLandControl.LandClass);
     while (curNodes.nodes.Count > 0)
     {
         PQSLandControl.LandClass obj = new PQSLandControl.LandClass();
         ParseObject(obj, curNodes.nodes[0]);
         curNodes.nodes.Remove(curNodes.nodes[0]);
     }
     return list;
 }
 private List<PQSLandControl.LandClassScatterAmount> GetListLCSA(ConfigNode node)
 {
     ConfigNode curNodes = new ConfigNode();
     node.CopyTo(curNodes);
     List<PQSLandControl.LandClassScatterAmount> list = new List<PQSLandControl.LandClassScatterAmount>();
     Type cType = typeof(PQSLandControl.LandClass);
     while (curNodes.nodes.Count > 0)
     {
         PQSLandControl.LandClassScatterAmount obj = new PQSLandControl.LandClassScatterAmount();
         ParseObject(obj, curNodes.nodes[0]);
         curNodes.nodes.Remove(curNodes.nodes[0]);
     }
     return list;
 }*/
 private void ParseField(object m, FieldInfo fi, ConfigNode modNode)
 {
     string name = fi.Name;
     /*if (fi.FieldType == typeof(IList))
     {
         if(modNode.HasNode(name))
         {
             IList list = fi.GetValue(m) as IList;
             if (list[0] != null)
             {
                 Type objType = list[0].GetType();
                 ConfigNode listNode = modNode.GetNode(name);
                 list.Clear();
                 if(objType == typeof(PQSLandControl.LandClass))
                     fi.SetValue(m, GetListLC(listNode));
             }
         }
     }
     else*/
     if (fi.FieldType == typeof(string))
     {
         if (modNode.HasValue(name))
         {
             string val = modNode.GetValue(name);
             fi.SetValue(m, val);
         }
     }
     else if (fi.FieldType == typeof(bool))
     {
         bool val;
         if (modNode.HasValue(name))
             if (bool.TryParse(modNode.GetValue(name), out val))
                 fi.SetValue(m, val);
     }
     else if (fi.FieldType == typeof(int))
     {
         int val;
         if (modNode.HasValue(name))
             if (int.TryParse(modNode.GetValue(name), out val))
                 fi.SetValue(m, val);
     }
     else if (fi.FieldType == typeof(float))
     {
         float val;
         if (modNode.HasValue(name))
             if (float.TryParse(modNode.GetValue(name), out val))
                 fi.SetValue(m, val);
     }
     else if (fi.FieldType == typeof(double))
     {
         double val;
         if (modNode.HasValue(name))
             if (double.TryParse(modNode.GetValue(name), out val))
                 fi.SetValue(m, val);
     }
     else if (fi.FieldType == typeof(MapSO))
     {
         if (modNode.HasValue(name))
         {
             MapSO map = fi.GetValue(m) as MapSO;
             if (map.Depth == MapSO.MapDepth.Greyscale)
             {
                 Configuration.MapSOParser_GreyScale<MapSO> newMap = new Configuration.MapSOParser_GreyScale<MapSO>();
                 newMap.SetFromString(modNode.GetValue(name));
                 if (newMap.value != null)
                     fi.SetValue(m, newMap.value);
             }
             else
             {
                 Configuration.MapSOParser_RGB<MapSO> newMap = new Configuration.MapSOParser_RGB<MapSO>();
                 newMap.SetFromString(modNode.GetValue(name));
                 if (newMap.value != null)
                     fi.SetValue(m, newMap.value);
             }
         }
     }
     else if (fi.FieldType == typeof(AnimationCurve))
     {
         if (modNode.HasNode(name))
         {
             FloatCurve fc = new FloatCurve();
             fc.Load(modNode.GetNode(name));
             fi.SetValue(m, fc.Curve);
         }
     }
     else if (fi.FieldType == typeof(FloatCurve))
     {
         if (modNode.HasNode(name))
         {
             FloatCurve fc = new FloatCurve();
             fc.Load(modNode.GetNode(name));
             fi.SetValue(m, fc);
         }
     }
     else if (fi.FieldType == typeof(Texture2D))
     {
         if (modNode.HasValue(name))
         {
             Configuration.Texture2DParser newParser = new Configuration.Texture2DParser();
             newParser.SetFromString(name);
             if (newParser.value != null)
                 fi.SetValue(m, newParser.value);
             else
             {
                 Texture2D newTex = Utility.LoadTexture(name, true, false, false);
                 if (newTex != null)
                     fi.SetValue(m, newParser.value);
             }
         }
     }
     else if (fi.FieldType == typeof(PQSLandControl.LandClass))
     {
         if(modNode.HasNode(name))
         {
             PQSLandControl.LandClass lc = fi.GetValue(m) as PQSLandControl.LandClass;
             ParseObject(lc, modNode.GetNode(name));
         }
     }
     else if (fi.FieldType == typeof(PQSMod_CelestialBodyTransform.AltitudeFade))
     {
         if (modNode.HasNode(name))
         {
             PQSMod_CelestialBodyTransform.AltitudeFade af = fi.GetValue(m) as PQSMod_CelestialBodyTransform.AltitudeFade;
             ParseObject(af, modNode.GetNode(name));
         }
     }
     else if (fi.FieldType == typeof(PQSMod_CelestialBodyTransform.AltitudeFade[]))
     {
         if (modNode.HasNode(name))
         {
             PQSMod_CelestialBodyTransform.AltitudeFade[] secFades = fi.GetValue(m) as PQSMod_CelestialBodyTransform.AltitudeFade[];
             ConfigNode newNodes = new ConfigNode();
             modNode.GetNode(name).CopyTo(newNodes);
             foreach (PQSMod_CelestialBodyTransform.AltitudeFade af in secFades)
             {
                 ParseObject(af, newNodes.nodes[0]);
                 newNodes.nodes.Remove(newNodes.nodes[0]);
             }
         }
     }
 }
        void Trim(List<double[]> list, double topLayer)
        {
            FloatCurve curve = new FloatCurve();
            curve.Load(WriteCurve(list));

            double[] lastKey = { topLayer, curve.Evaluate((float)topLayer) };

            for (int i = list.Count; i > 0; i--)
            {
                if (list[i - 1][0] >= topLayer)
                    list.RemoveAt(i - 1);
            }

            list.Add(lastKey);

            // Debug
            PrintCurve(list, "Trim");
        }
        void FixPressure(FloatCurve curve, double topLayer)
        {
            List<double[]> list = ReadCurve(curve); /* Avoid Bad Curves ==> */ if (list.Count < 2) { UnityEngine.Debug.Log("SigmaLog: This pressure curve has " + (list.Count == 0 ? "no keys" : "just one key") + ". I don't know what you expect me to do with that."); return; }

            double maxAltitude = list.Last()[0];

            bool smoothEnd = list.Last()[1] == 0 && list.Count > 2;
            double smoothRange = list.Last()[0] - list[list.Count - 2][0];
            if (smoothEnd) list.RemoveAt(list.Count - 1);

            if (topLayer > maxAltitude)
            {
                Extend(list, topLayer);
                maxAltitude = list.Last()[0];
            }

            if (topLayer < maxAltitude)
            {
                Trim(list, topLayer);
            }

            if (smoothEnd)
            {
                Smooth(list, smoothRange);
            }

            curve.Load(WriteCurve(list));
        }
        public virtual void DoConfig(ConfigNode cfg)
        {
            // fix propellant ratios to not be rounded
            if (cfg.HasNode("PROPELLANT"))
            {
                foreach (ConfigNode pNode in cfg.GetNodes("PROPELLANT"))
                {
                    if (pNode.HasValue("ratio"))
                    {
                        double dtmp;
                        if (double.TryParse(pNode.GetValue("ratio"), out dtmp))
                            pNode.SetValue("ratio", (dtmp * 100.0).ToString());
                    }
                }
            }
            float heat = -1;
            if (cfg.HasValue("heatProduction")) // ohai amsi: allow heat production to be changed by multiplier
            {
                heat = (float)Math.Round(float.Parse(cfg.GetValue("heatProduction")) * heatMult, 0);
                cfg.SetValue("heatProduction", heat.ToString());
            }

            // load throttle (for later)
            curThrottle = throttle;
            if (cfg.HasValue("throttle"))
                float.TryParse(cfg.GetValue("throttle"), out curThrottle);
            else if(cfg.HasValue("minThrust") && cfg.HasValue("maxThrust"))
                curThrottle = float.Parse(cfg.GetValue("minThrust")) / float.Parse(cfg.GetValue("maxThrust"));
            float TLMassMult = 1.0f;

            float gimbal = -1f;
            if (cfg.HasValue("gimbalRange"))
                gimbal = float.Parse(cfg.GetValue("gimbalRange"));

            float cost = 0f;
            if(cfg.HasValue("cost"))
                cost = float.Parse(cfg.GetValue("cost"));

            if (techLevel != -1)
            {
                // load techlevels
                TechLevel cTL = new TechLevel();
                //print("For engine " + part.name + ", config " + configuration + ", max TL: " + TechLevel.MaxTL(cfg, techNodes, engineType));
                cTL.Load(cfg, techNodes, engineType, techLevel);
                TechLevel oTL = new TechLevel();
                oTL.Load(cfg, techNodes, engineType, origTechLevel);

                // set atmosphereCurve
                if (cfg.HasValue("IspSL") && cfg.HasValue("IspV"))
                {
                    cfg.RemoveNode("atmosphereCurve");
                    ConfigNode curve = new ConfigNode("atmosphereCurve");
                    float ispSL, ispV;
                    float.TryParse(cfg.GetValue("IspSL"), out ispSL);
                    float.TryParse(cfg.GetValue("IspV"), out ispV);
                    FloatCurve aC = new FloatCurve();
                    aC = Mod(cTL.AtmosphereCurve, ispSL, ispV);
                    aC.Save(curve);
                    cfg.AddNode(curve);
                }

                // set heatProduction and dissipation
                if (heat > 0)
                {
                    cfg.SetValue("heatProduction", MassTL(heat).ToString("0"));
                    part.heatDissipation = 0.12f / MassTL(1.0f);
                }

                // set thrust and throttle
                if (cfg.HasValue(thrustRating))
                {
                    float thr;
                    float.TryParse(cfg.GetValue(thrustRating), out thr);
                    configMaxThrust = ThrustTL(thr);
                    cfg.SetValue(thrustRating, configMaxThrust.ToString("0.0000"));
                    if (cfg.HasValue("minThrust"))
                    {
                        float.TryParse(cfg.GetValue("minThrust"), out thr);
                        configMinThrust = ThrustTL(thr);
                        cfg.SetValue("minThrust", configMinThrust.ToString("0.0000"));
                    }
                    else
                    {
                        if (thrustRating.Equals("thrusterPower"))
                        {
                            configMinThrust = configMaxThrust * 0.5f;
                        }
                        else
                        {
                            configMinThrust = configMaxThrust;
                            if (curThrottle > 1.0f)
                            {
                                if (techLevel >= curThrottle)
                                    curThrottle = 1.0f;
                                else
                                    curThrottle = -1.0f;
                            }
                            if (curThrottle >= 0.0f)
                            {
                                curThrottle = (float)((double)curThrottle * cTL.Throttle());
                                configMinThrust *= curThrottle;
                            }
                            cfg.SetValue("minThrust", configMinThrust.ToString("0.0000"));
                        }
                    }
                    curThrottle = configMinThrust / configMaxThrust;
                    if(origMass > 0)
                         TLMassMult =  MassTL(1.0f);
                }
                // Don't want to change gimbals on TL-enabled engines willy-nilly
                // So we don't unless either a transform is specified, or we override.
                // We assume if it was specified in the CONFIG that we should use it anyway.
                if (gimbal < 0 && (!gimbalTransform.Equals("") || useGimbalAnyway))
                    gimbal = cTL.GimbalRange;
                if (gimbal >= 0)
                {
                    // allow local override of gimbal mult
                    if (cfg.HasValue("gimbalMult"))
                        gimbal *= float.Parse(cfg.GetValue("gimbalMult"));
                }

                // Cost (multiplier will be 1.0 if unspecified)
                cost = CostTL(cost, cfg);
            }
            else
            {
                if(cfg.HasValue(thrustRating) && curThrottle > 0f && !cfg.HasValue("minThrust"))
                {
                    configMinThrust = curThrottle * float.Parse(cfg.GetValue(thrustRating));
                    cfg.SetValue("minThrust", configMinThrust.ToString("0.0000"));
                }
            }
            // mass change
            if (origMass > 0)
            {
                float ftmp;
                configMassMult = 1.0f;
                if (cfg.HasValue("massMult"))
                    if (float.TryParse(cfg.GetValue("massMult"), out ftmp))
                        configMassMult = ftmp;

                part.mass = origMass * configMassMult * massMult * TLMassMult;
                massDelta = 0;
                if((object)(part.partInfo) != null)
                    if((object)(part.partInfo.partPrefab) != null)
                        massDelta = part.mass - part.partInfo.partPrefab.mass;
            }
            // KIDS integration
            if(cfg.HasNode("atmosphereCurve"))
            {
                ConfigNode newCurveNode = new ConfigNode("atmosphereCurve");
                FloatCurve oldCurve = new FloatCurve();
                oldCurve.Load(cfg.GetNode("atmosphereCurve"));
                FloatCurve newCurve = Mod(oldCurve, ispSLMult, ispVMult);
                newCurve.Save(newCurveNode);
                cfg.RemoveNode("atmosphereCurve");
                cfg.AddNode(newCurveNode);
            }
            // gimbal change
            if (gimbal >= 0 && !cfg.HasValue("gimbalRange")) // if TL set a gimbal
            {
                // apply module-wide gimbal mult on top of any local ones
                cfg.AddValue("gimbalRange", (gimbal * gimbalMult).ToString("N4"));
            }
            if (cost != 0f)
            {
                if (cfg.HasValue("cost"))
                    cfg.SetValue("cost", cost.ToString("N3"));
                else
                    cfg.AddValue("cost", cost.ToString("N3"));
            }
        }
        public virtual void DoConfig(ConfigNode cfg)
        {
            configMaxThrust = configMinThrust = configHeat = -1f;
            // Get thrusts
            if (config.HasValue(thrustRating))
            {
                float thr;
                if (float.TryParse(config.GetValue(thrustRating), out thr))
                    configMaxThrust = scale * thr;
            }
            if (config.HasValue("minThrust"))
            {
                float thr;
                if (float.TryParse(config.GetValue("minThrust"), out thr))
                    configMinThrust = scale * thr;
            }

            // Get, multiply heat
            if (cfg.HasValue("heatProduction"))
            {
                float heat;
                if(float.TryParse(cfg.GetValue("heatProduction"), out heat))
                    configHeat = (float)Math.Round(heat * RFSettings.Instance.heatMultiplier, 0);
            }

            // load throttle (for later)
            configThrottle = throttle;
            if (cfg.HasValue("throttle"))
                float.TryParse(cfg.GetValue("throttle"), out configThrottle);
            else if (configMinThrust >= 0f && configMaxThrust >= 0f)
                configThrottle = configMinThrust / configMaxThrust;

            float TLMassMult = 1.0f;

            float gimbal = -1f;
            if (cfg.HasValue("gimbalRange"))
                gimbal = float.Parse(cfg.GetValue("gimbalRange"));

            float cost = 0f;
            if (cfg.HasValue("cost"))
                cost = scale * float.Parse(cfg.GetValue("cost"));

            if (techLevel != -1)
            {
                // load techlevels
                TechLevel cTL = new TechLevel();
                cTL.Load(cfg, techNodes, engineType, techLevel);
                TechLevel oTL = new TechLevel();
                oTL.Load(cfg, techNodes, engineType, origTechLevel);

                // set atmosphereCurve
                if (cfg.HasValue("IspSL") && cfg.HasValue("IspV"))
                {
                    cfg.RemoveNode("atmosphereCurve");

                    ConfigNode curve = new ConfigNode("atmosphereCurve");

                    // get the multipliers
                    float ispSL = 1f, ispV = 1f;
                    float.TryParse(cfg.GetValue("IspSL"), out ispSL);
                    float.TryParse(cfg.GetValue("IspV"), out ispV);

                    // Mod the curve by the multipliers
                    FloatCurve newAtmoCurve = new FloatCurve();
                    newAtmoCurve = Utilities.Mod(cTL.AtmosphereCurve, ispSL, ispV);
                    newAtmoCurve.Save(curve);

                    cfg.AddNode(curve);
                }

                // set heatProduction
                if (configHeat > 0)
                {
                    configHeat = MassTL(configHeat);
                }

                // set thrust and throttle
                if (configMaxThrust >= 0)
                {
                    configMaxThrust = ThrustTL(configMaxThrust);
                    if (configMinThrust >= 0)
                    {
                        configMinThrust = ThrustTL(configMinThrust);
                    }
                    else if (thrustRating.Equals("thrusterPower"))
                    {
                        configMinThrust = configMaxThrust * 0.5f;
                    }
                    else
                    {
                        configMinThrust = configMaxThrust;
                        if (configThrottle > 1.0f)
                        {
                            if (techLevel >= configThrottle)
                                configThrottle = 1.0f;
                            else
                                configThrottle = -1.0f;
                        }
                        if (configThrottle >= 0.0f)
                        {
                            configThrottle = (float)((double)configThrottle * cTL.Throttle());
                            configMinThrust *= configThrottle;
                        }
                    }
                    configThrottle = configMinThrust / configMaxThrust;
                    if (origMass > 0)
                        TLMassMult = MassTL(1.0f);
                }
                // Don't want to change gimbals on TL-enabled engines willy-nilly
                // So we don't unless either a transform is specified, or we override.
                // We assume if it was specified in the CONFIG that we should use it anyway.
                if (gimbal < 0 && (!gimbalTransform.Equals("") || useGimbalAnyway))
                    gimbal = cTL.GimbalRange;
                if (gimbal >= 0)
                {
                    // allow local override of gimbal mult
                    if (cfg.HasValue("gimbalMult"))
                        gimbal *= float.Parse(cfg.GetValue("gimbalMult"));
                }

                // Cost (multiplier will be 1.0 if unspecified)
                cost = scale * CostTL(cost, cfg);
            }
            else
            {
                if (cfg.HasValue(thrustRating) && configThrottle > 0f && !cfg.HasValue("minThrust"))
                {
                    configMinThrust = configThrottle * configMaxThrust;
                }
            }

            // Now update the cfg from what we did.
            // thrust updates
            if(configMaxThrust >= 0f)
                cfg.SetValue(thrustRating, configMaxThrust.ToString("0.0000"));
            if(configMinThrust >= 0f)
                cfg.SetValue("minThrust", configMinThrust.ToString("0.0000")); // will be ignored by RCS, so what.

            // heat update
            if(configHeat >= 0f)
                cfg.SetValue("heatProduction", configHeat.ToString("0"));

            // mass change
            if (origMass > 0)
            {
                float ftmp;
                configMassMult = scale;
                if (cfg.HasValue("massMult"))
                    if (float.TryParse(cfg.GetValue("massMult"), out ftmp))
                        configMassMult *= ftmp;

                part.mass = origMass * configMassMult * RFSettings.Instance.EngineMassMultiplier * TLMassMult;
                massDelta = 0;
                if ((object)(part.partInfo) != null)
                    if ((object)(part.partInfo.partPrefab) != null)
                        massDelta = part.mass - part.partInfo.partPrefab.mass;
            }

            // KIDS integration
            if (cfg.HasNode("atmosphereCurve"))
            {
                ConfigNode newCurveNode = new ConfigNode("atmosphereCurve");
                FloatCurve oldCurve = new FloatCurve();
                oldCurve.Load(cfg.GetNode("atmosphereCurve"));
                FloatCurve newCurve = Utilities.Mod(oldCurve, ispSLMult, ispVMult);
                newCurve.Save(newCurveNode);
                cfg.RemoveNode("atmosphereCurve");
                cfg.AddNode(newCurveNode);
            }
            // gimbal change
            if (gimbal >= 0 && !cfg.HasValue("gimbalRange")) // if TL set a gimbal
            {
                // apply module-wide gimbal mult on top of any local ones
                cfg.AddValue("gimbalRange", (gimbal * gimbalMult).ToString("N4"));
            }
            if (cost != 0f)
            {
                if (cfg.HasValue("cost"))
                    cfg.SetValue("cost", cost.ToString("N3"));
                else
                    cfg.AddValue("cost", cost.ToString("N3"));
            }
        }
        public override void OnLoad(ConfigNode node)
        {
            if (thrustCurve == null)
                thrustCurve = new FloatCurve();

            base.OnLoad(node);
            // Manually reload ignitions if not in editor
            if(!HighLogic.LoadedSceneIsEditor)
                node.TryGetValue("ignited", ref ignited);
            int pCount = propellants.Count;
            // thrust curve
            useThrustCurve = false;
            if (node.HasNode("thrustCurve") && node.HasValue("curveResource"))
            {
                if (node.GetValue("curveResource") != curveResource)
                {
                    Debug.Log("*RFE* ERROR: curveResource doesn't match node's!");
                    curveResource = node.GetValue("curveResource");
                }
                if (thrustCurve == null)
                {
                    Debug.Log("*RFE* ERROR: have curve node but thrustCurve is null!");
                    thrustCurve = new FloatCurve();
                    thrustCurve.Load(node.GetNode("thrustCurve"));
                }

                if (curveResource != "")
                {
                    for (int i = 0; i < pCount; ++i)
                    {
                        if (propellants[i].name.Equals(curveResource))
                        {
                            curveProp = i;
                            break;
                        }
                    }
                    if (curveProp != -1)
                    {
                        useThrustCurve = true;
                    }
                }
            }

            // Set from propellants
            bool instantThrottle = true;
            for (int i = 0; i < pCount; ++i)
            {
                if (RFSettings.Instance.instantThrottleProps.Contains(propellants[i].name))
                {
                    instantThrottle = false;
                }
                // any other stuff
            }

            // FIXME calculating throttle change rate
            if (!instantThrottle)
                throttleResponseRate = (float)(10d / Math.Sqrt(Math.Sqrt(part.mass * maxThrust)));
            else
                throttleResponseRate = 1000000f;

            // set fields
            Fields["thrustCurveDisplay"].guiActive = useThrustCurve;
            CreateEngine();

            if (ullageSet == null)
                ullageSet = new Ullage.UllageSet(this);

            // Get thrust axis (only on create prefabs)
            if (part.partInfo == null || part.partInfo.partPrefab == null)
            {
                thrustAxis = Vector3.zero;
                foreach(Transform t in part.FindModelTransforms(thrustVectorTransformName))
                {
                    thrustAxis -= t.forward;
                }
                thrustAxis = thrustAxis.normalized;
            }
            ullageSet.SetThrustAxis(thrustAxis);

            // ullage
            if (node.HasNode("Ullage"))
            {
                ullageSet.Load(node.GetNode("Ullage"));
            }
            ullageSet.SetUllageEnabled(ullage);

            // load ignition resources
            if (node.HasNode("IGNITOR_RESOURCE"))
                ignitionResources.Clear();
            foreach (ConfigNode n in node.GetNodes("IGNITOR_RESOURCE"))
            {
                ModuleResource res = new ModuleResource();
                res.Load(n);
                ignitionResources.Add(res);
            }
        }
        public string GetConfigInfo(ConfigNode config)
        {
            TechLevel cTL = new TechLevel();
            if (!cTL.Load(config, techNodes, engineType, techLevel))
                cTL = null;

            string info = "   " + config.GetValue("name") + "\n";
            if (config.HasValue("description"))
                info += "    " + config.GetValue("description") + "\n";
            if (config.HasValue(thrustRating))
            {
                info += "    " + (scale * ThrustTL(config.GetValue(thrustRating), config)).ToString("G3") + " kN";
                // add throttling info if present
                if (config.HasValue("minThrust"))
                    info += ", min " + (float.Parse(config.GetValue("minThrust")) / float.Parse(config.GetValue(thrustRating)) * 100f).ToString("N0") + "%";
                else if (config.HasValue("throttle"))
                    info += ", min " + (float.Parse(config.GetValue("throttle")) * 100f).ToString("N0") + "%";
            }
            else
                info += "    Unknown Thrust";

            if (origMass > 0f)
            {
                float cMass = scale;
                float ftmp;
                if (config.HasValue("massMult"))
                    if (float.TryParse(config.GetValue("massMult"), out ftmp))
                        cMass *= ftmp;

                cMass = origMass * cMass * RFSettings.Instance.EngineMassMultiplier;

                info += ", " + cMass.ToString("N3") + "t";
            }
            info += "\n";

            FloatCurve isp = new FloatCurve();
            if (config.HasNode("atmosphereCurve"))
            {
                isp.Load(config.GetNode("atmosphereCurve"));
                info += "    Isp: "
                    + isp.Evaluate(isp.maxTime).ToString() + " - "
                      + isp.Evaluate(isp.minTime).ToString() + "s\n";
            }
            else if (config.HasValue("IspSL") && config.HasValue("IspV"))
            {
                float ispSL = 1.0f, ispV = 1.0f;
                float.TryParse(config.GetValue("IspSL"), out ispSL);
                float.TryParse(config.GetValue("IspV"), out ispV);
                if (cTL != null)
                {
                    ispSL *= ispSLMult * cTL.AtmosphereCurve.Evaluate(1);
                    ispV *= ispVMult * cTL.AtmosphereCurve.Evaluate(0);
                    info += "    Isp: " + ispSL.ToString("0") + " - " + ispV.ToString("0") + "s\n";
                }
            }
            float gimbalR = -1f;
            if (config.HasValue("gimbalRange"))
                gimbalR = float.Parse(config.GetValue("gimbalRange"));
            // Don't do per-TL checks here, they're misleading.
            /*else if (!gimbalTransform.Equals("") || useGimbalAnyway)
            {
                if (cTL != null)
                    gimbalR = cTL.GimbalRange;
            }*/
            if (gimbalR != -1f)
                info += "    Gimbal " + gimbalR.ToString("N1") + "d\n";

            if (config.HasValue("ullage") || config.HasValue("ignitions") || config.HasValue("pressureFed"))
            {
                info += "    ";
                bool comma = false;
                if (config.HasValue("ullage"))
                {
                    info += (config.GetValue("ullage").ToLower() == "true" ? "ullage" : "no ullage");
                    comma = true;
                }
                if (config.HasValue("pressureFed") && config.GetValue("pressureFed").ToLower() == "true")
                {
                    if (comma)
                        info += ", ";
                    info += "pfed";
                    comma = true;
                }

                if (config.HasValue("ignitions"))
                {
                    int ignitions;
                    if (int.TryParse(config.GetValue("ignitions"), out ignitions))
                    {
                        if (comma)
                            info += ", ";
                        if (ignitions > 0)
                            info += ignitions + " ignition" + (ignitions > 1 ? "s" : "");
                        else
                            info += "unl. ignitions";
                    }
                }
                info += "\n";
            }
            float cst;
            if (config.HasValue("cost") && float.TryParse(config.GetValue("cost"), out cst))
                info += "    (" + (scale * cst).ToString("N0") + " extra cost)\n"; // FIXME should get cost from TL, but this should be safe

            return info;
        }
 void Multiply(FloatCurve curve, double multiplier)
 {
     List<double[]> list = new List<double[]>();
     list = ReadCurve(curve);
     foreach (double[] key in list)
     {
         key[0] *= multiplier;
         key[2] /= multiplier;
         key[3] /= multiplier;
     }
     curve.Load(WriteCurve(list));
 }
 public override void OnLoad(ConfigNode node)
 {
     base.OnLoad(node);
     if (node.HasNode("baseIgnitionChance"))
     {
         Log("IgnitionFail: Loading baseIgnitionChance curve");
         baseIgnitionChance = new FloatCurve();
         baseIgnitionChance.Load(node.GetNode("baseIgnitionChance"));
     }
     else
         baseIgnitionChance = null;
     if (node.HasNode("pressureCurve"))
     {
         Log("IgnitionFail: Loading pressure curve");
         pressureCurve = new FloatCurve();
         pressureCurve.Load(node.GetNode("pressureCurve"));
     }
     else
         pressureCurve = null;
 }
 public static FloatCurve Mod(FloatCurve fc, float sMult, float vMult)
 {
     //print("Modding this");
     ConfigNode curve = new ConfigNode("atmosphereCurve");
     fc.Save(curve);
     foreach (ConfigNode.Value k in curve.values)
     {
         string[] val = k.value.Split(' ');
         //print("Got string !" + k.value + ", split into " + val.Count() + " elements");
         float atmo = float.Parse(val[0]);
         float isp = float.Parse(val[1]);
         isp = isp * ((sMult * atmo) + (vMult * (1f - atmo))); // lerp between vac and SL
         val[1] = Math.Round(isp,1).ToString(); // round for neatness
         string newVal = "";
         foreach (string s in val)
             newVal += s + " ";
         k.value = newVal;
     }
     FloatCurve retCurve = new FloatCurve();
     retCurve.Load(curve);
     return retCurve;
 }
        virtual public void SetConfiguration(string newConfiguration = null)
        {
            if (newConfiguration == null)
                newConfiguration = configuration;
            ConfigNode newConfig = configs.Find (c => c.GetValue ("name").Equals (newConfiguration));
            if (newConfig != null) {

                // for asmi
                if (useConfigAsTitle)
                    part.partInfo.title = configuration;

                configuration = newConfiguration;
                config = new ConfigNode ("MODULE");
                newConfig.CopyTo (config);
                config.name = "MODULE";

                // fix for HotRockets etc.
                if (type.Equals("ModuleEngines") && part.Modules.Contains("ModuleEnginesFX") && !part.Modules.Contains("ModuleEngines"))
                    type = "ModuleEnginesFX";
                if (type.Equals("ModuleEnginesFX") && part.Modules.Contains("ModuleEngines") && !part.Modules.Contains("ModuleEnginesFX"))
                    type = "ModuleEngines";
                // fix for ModuleRCSFX etc
                if (type.Equals("ModuleRCS") && part.Modules.Contains("ModuleRCSFX") && !part.Modules.Contains("ModuleRCS"))
                    type = "ModuleRCSFX";
                if (type.Equals("ModuleRCSFX") && part.Modules.Contains("ModuleRCS") && !part.Modules.Contains("ModuleRCSFX"))
                    type = "ModuleRCS";

                config.SetValue("name", type);

                #if DEBUG
                print ("replacing " + type + " with:");
                print (newConfig.ToString ());
                #endif

                pModule = null;
                if (part.Modules.Contains(type))
                {
                    if (type.Equals("ModuleEnginesFX"))
                    {
                        if (engineID != "")
                        {
                            foreach (ModuleEnginesFX mFX in part.Modules.OfType<ModuleEnginesFX>())
                            {
                                if (mFX.engineID.Equals(engineID))
                                    pModule = (PartModule)mFX;
                            }
                        }
                        else if (moduleIndex >= 0)
                        {
                            int tmpIdx = 0;
                            pModule = null;
                            foreach (PartModule pM in part.Modules)
                            {
                                if (pM.GetType().Equals(type))
                                {
                                    if (tmpIdx == moduleIndex)
                                        pModule = pM;
                                    tmpIdx++;
                                }
                            }
                        }
                        else
                            pModule = part.Modules[type];
                    }
                    else
                        pModule = part.Modules[type];

                    if ((object)pModule == null)
                    {
                        Debug.Log("*RF* Could not find appropriate module of type " + type + ", with ID=" + engineID + " and index " + moduleIndex);
                        return;
                    }
                    // clear all FloatCurves
                    Type mType = pModule.GetType();
                    foreach (FieldInfo field in mType.GetFields())
                    {
                        if (field.FieldType == typeof(FloatCurve) && (field.Name.Equals("atmosphereCurve") || field.Name.Equals("velocityCurve")))
                        {
                            //print("*MFS* resetting curve " + field.Name);
                            field.SetValue(pModule, new FloatCurve());
                        }
                    }
                    // clear propellant gauges
                    foreach (FieldInfo field in mType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
                    {
                        if (field.FieldType == typeof(Dictionary<Propellant, VInfoBox>))
                        {
                            Dictionary<Propellant, VInfoBox> boxes = (Dictionary<Propellant, VInfoBox>)(field.GetValue(pModule));
                            if (boxes == null)
                                continue;
                            foreach (VInfoBox v in boxes.Values)
                            {
                                if (v == null) //just in case...
                                    continue;
                                try
                                {
                                    part.stackIcon.RemoveInfo(v);
                                }
                                catch (Exception e)
                                {
                                    print("*MFS* Trying to remove info box: " + e.Message);
                                }
                            }
                            boxes.Clear();
                        }
                    }
                }
                if (type.Equals("ModuleRCS") || type.Equals("ModuleRCSFX"))
                {
                    ModuleRCS rcs = (ModuleRCS)pModule;
                    if (rcs != null)
                    {
                        rcs.G = 9.80665f;
                        /*bool oldRes = config.HasValue("resourceName");
                        string resource = "";
                        if (oldRes)
                        {
                            resource = config.GetValue("resourceName");
                            rcs.resourceName = resource;
                        }*/
                        DoConfig(config);
                        if (config.HasNode("PROPELLANT"))
                        {
                            rcs.propellants.Clear();
                        }
                        pModule.Load(config);
                        /*if (oldRes)
                        {
                            rcs.resourceName = resource;
                            rcs.SetResource(resource);
                        }*/
                        // PROPELLANT handling is automatic.
                        fastRCS = rcs;
                        if(type.Equals("ModuleRCS") && !part.Modules.Contains("ModuleRCSFX"))
                            fastType = ModuleType.MODULERCS;
                        else
                            fastType = ModuleType.MODULERCSFX;
                    }
                }
                else
                { // is an ENGINE
                    if (type.Equals("ModuleEngines"))
                    {
                        ModuleEngines mE = (ModuleEngines)pModule;
                        if (mE != null)
                        {
                            configMaxThrust = mE.maxThrust;
                            configMinThrust = mE.minThrust;
                            fastEngines = mE;
                            fastType = ModuleType.MODULEENGINES;
                            mE.g = 9.80665f;
                            if (config.HasNode("PROPELLANT"))
                            {
                                mE.propellants.Clear();
                            }
                        }
                        if (config.HasValue("maxThrust"))
                        {
                            float thr;
                            if(float.TryParse(config.GetValue("maxThrust"), out thr))
                                configMaxThrust = thr;
                        }
                        if (config.HasValue("minThrust"))
                        {
                            float thr;
                            if(float.TryParse(config.GetValue("minThrust"), out thr))
                                configMinThrust = thr;
                        }
                    }
                    else if (type.Equals("ModuleEnginesFX"))
                    {
                        ModuleEnginesFX mE = (ModuleEnginesFX)pModule;
                        if (mE != null)
                        {
                            configMaxThrust = mE.maxThrust;
                            configMinThrust = mE.minThrust;
                            fastEnginesFX = mE;
                            fastType = ModuleType.MODULEENGINESFX;
                            mE.g = 9.80665f;
                            if (config.HasNode("PROPELLANT"))
                            {
                                mE.propellants.Clear();
                            }
                        }
                        if (config.HasValue("maxThrust"))
                        {
                            float thr;
                            if (float.TryParse(config.GetValue("maxThrust"), out thr))
                                configMaxThrust = thr;
                        }
                        if (config.HasValue("minThrust"))
                        {
                            float thr;
                            if (float.TryParse(config.GetValue("minThrust"), out thr))
                                configMinThrust = thr;
                        }
                    }
                    DoConfig(config);
                    if(pModule != null)
                        pModule.Load (config);
                    if (config.HasNode("ModuleEngineIgnitor") && part.Modules.Contains("ModuleEngineIgnitor"))
                    {
                        ConfigNode eiNode = config.GetNode("ModuleEngineIgnitor");
                        if (eiNode.HasValue("ignitionsAvailable"))
                        {
                            int ignitions;
                            if (int.TryParse(eiNode.GetValue("ignitionsAvailable"), out ignitions))
                            {
                                if (ignitions < 0)
                                {
                                    ignitions = techLevel + ignitions;
                                    if (ignitions < 1)
                                        ignitions = 1;
                                }
                                else if (ignitions == 0)
                                    ignitions = -1;

                                eiNode.SetValue("ignitionsAvailable", ignitions.ToString());
                                if (eiNode.HasValue("ignitionsRemained"))
                                    eiNode.SetValue("ignitionsRemained", ignitions.ToString());
                                else
                                    eiNode.AddValue("ignitionsRemained", ignitions.ToString());
                            }
                        }
                        if (!HighLogic.LoadedSceneIsEditor && !(HighLogic.LoadedSceneIsFlight && vessel != null && vessel.situation == Vessel.Situations.PRELAUNCH)) // fix for prelaunch
                        {
                            int remaining = (int)(part.Modules["ModuleEngineIgnitor"].GetType().GetField("ignitionsRemained").GetValue(part.Modules["ModuleEngineIgnitor"]));
                            if(eiNode.HasValue("ignitionsRemained"))
                                eiNode.SetValue("ignitionsRemained", remaining.ToString());
                            else
                                eiNode.AddValue("ignitionsRemained", remaining.ToString());
                        }
                        ConfigNode tNode = new ConfigNode("MODULE");
                        eiNode.CopyTo(tNode);
                        tNode.SetValue("name", "ModuleEngineIgnitor");
                        part.Modules["ModuleEngineIgnitor"].Load(tNode);
                    }
                }
                if (part.Resources.Contains("ElectricCharge") && part.Resources["ElectricCharge"].maxAmount < 0.1)
                { // hacking around a KSP bug here
                    part.Resources["ElectricCharge"].amount = 0;
                    part.Resources["ElectricCharge"].maxAmount = 0.1;
                }
                if (config.HasValue("cost"))
                    configCost = float.Parse(config.GetValue("cost"));
                UpdateTweakableMenu();
                // Check for and enable the thrust curve
                useThrustCurve = false;
                Fields["thrustCurveDisplay"].guiActive = false;
                if (config.HasNode("thrustCurve") && config.HasValue("curveResource"))
                {
                    curveResource = config.GetValue("curveResource");
                    if (curveResource != "")
                    {
                        double ratio = 0.0;
                        switch (fastType)
                        {
                            case ModuleType.MODULEENGINES:
                                configHeat = fastEngines.heatProduction;
                                for (int i = 0; i < fastEngines.propellants.Count; i++ )
                                    if (fastEngines.propellants[i].name.Equals(curveResource))
                                        curveProp = i;
                                if (curveProp >= 0)
                                    ratio = fastEngines.propellants[curveProp].totalResourceAvailable / fastEngines.propellants[curveProp].totalResourceCapacity;
                                break;

                            case ModuleType.MODULEENGINESFX:
                                configHeat = fastEnginesFX.heatProduction;
                                for (int i = 0; i < fastEnginesFX.propellants.Count; i++)
                                    if (fastEnginesFX.propellants[i].name.Equals(curveResource))
                                        curveProp = i;
                                if (curveProp >= 0)
                                    ratio = fastEnginesFX.propellants[curveProp].totalResourceAvailable / fastEnginesFX.propellants[curveProp].totalResourceCapacity;
                                break;

                            case ModuleType.MODULERCS:
                                for (int i = 0; i < fastRCS.propellants.Count; i++)
                                    if (fastRCS.propellants[i].name.Equals(curveResource))
                                        curveProp = i;
                                if (curveProp >= 0)
                                    ratio = fastRCS.propellants[curveProp].totalResourceAvailable / fastRCS.propellants[curveProp].totalResourceCapacity;
                                break;
                        }
                        if (curveProp != -1)
                        {
                            useThrustCurve = true;
                            configThrustCurve = new FloatCurve();
                            configThrustCurve.Load(config.GetNode("thrustCurve"));
                            print("*RF* Found thrust curve for " + part.name);
                            Fields["thrustCurveDisplay"].guiActive = true;
                        }
                        
                    }
                }
            }
            
        }
 public override void OnLoad(ConfigNode node)
 {
     // As of v1.3 we dont' need to worry about reliability bodies anymore, just a simple FloatCurve
     if (node.HasNode("reliabilityCurve"))
     {
         reliabilityCurve = new FloatCurve();
         reliabilityCurve.Load(node.GetNode("reliabilityCurve"));
     }
     base.OnLoad(node);
 }