public void RetrofitEngine()
        {
            if (isupgraded || myScience < upgradeCost) { return; } // || !hasScience || myScience < upgradeCost) { return; }
            isupgraded = true;
            var curEngine = this.part.Modules["ModuleEngines"] as ModuleEngines;
            if (curEngine != null) {
                ModuleEngines.Propellant prop = new ModuleEngines.Propellant();
                //prop.id = PartResourceLibrary.Instance.GetDefinition("VacuumPlasma").id;
                //ConfigNode prop_node = new ConfigNode();
                //PartResourceLibrary.Instance.GetDefinition("VacuumPlasma").Save(prop_node);

                //PartResource part_resource = part.Resources.list[0];
                //part_resource.info = PartResourceLibrary.Instance.GetDefinition("VacuumPlasma");
                //part_resource.maxAmount = 10;
                //part_resource.amount = 10;

                ConfigNode node = new ConfigNode("RESOURCE");
                node.AddValue("name", "VacuumPlasma");
                node.AddValue("maxAmount", 10);
                node.AddValue("amount", 10);
                part.AddResource(node);

                propellants = ElectricEngineController.getPropellants(isupgraded);
                fuel_mode = 0;

                //curEngine.propellants[1].id = PartResourceLibrary.Instance.GetDefinition("VacuumPlasma").id;
                //curEngine.propellants[1].name = PartResourceLibrary.Instance.GetDefinition("VacuumPlasma").name;
                engineType = upgradedName;
                part.RequestResource("Science", upgradeCost);
                evaluateMaxThrust();
            }
        }
        public void evaluateMaxThrust()
        {
            List<Part> vessel_parts = vessel.parts;
            total_power_output = 0;
            var curEngine = this.part.Modules["ModuleEngines"] as ModuleEngines;
            ConfigNode chosenpropellant = propellants[fuel_mode];
            ConfigNode[] assprops = chosenpropellant.GetNodes("PROPELLANT");
            List<ModuleEngines.Propellant> list_of_propellants = new List<ModuleEngines.Propellant>();
            //bool propellant_is_upgrade = false;

            for (int i = 0; i < assprops.Length; ++i) {
                fuelmode = chosenpropellant.GetValue("guiName");
                ispMultiplier = float.Parse(chosenpropellant.GetValue("ispMultiplier"));
                //propellant_is_upgrade = bool.Parse(chosenpropellant.GetValue("isUpgraded"));

                ModuleEngines.Propellant curprop = new ModuleEngines.Propellant();
                curprop.Load(assprops[i]);
                if (curprop.drawStackGauge) {
                    curprop.drawStackGauge = false;
                    fuel_gauge.SetMessage(curprop.name);
                    fuel_gauge.SetMsgBgColor(XKCDColors.DarkLime);
                    fuel_gauge.SetMsgTextColor(XKCDColors.ElectricLime);
                    fuel_gauge.SetProgressBarColor(XKCDColors.Yellow);
                    fuel_gauge.SetProgressBarBgColor(XKCDColors.DarkLime);
                    fuel_gauge.SetValue(0f);
                }
                list_of_propellants.Add(curprop);
            }

            total_power_output = getStableResourceSupply(FNResourceManager.FNRESOURCE_MEGAJOULES);

            final_thrust_store = thrust_efficiency*2000.0f*total_power_output / (initial_isp * ispMultiplier * 9.81f);

            //float thrust_ratio = total_power_output / reference_power;
            //final_thrust_store = initial_thrust * thrust_ratio / ispMultiplier;

            FloatCurve newISP = new FloatCurve ();
            newISP.Add (0, initial_isp * ispMultiplier);
            curEngine.atmosphereCurve = newISP;

            if (PartResourceLibrary.Instance.GetDefinition(list_of_propellants[0].name) != null) {

                curEngine.propellants.Clear();
                curEngine.propellants = list_of_propellants;
                curEngine.SetupPropellant();
            }

            List<PartResource> partresources = new List<PartResource>();
            part.GetConnectedResources(curEngine.propellants[0].id, partresources);

            //if(!isupgraded) {
            if (partresources.Count == 0 && fuel_mode != 0) {
                TogglePropellant();
            }
            //}else{
            //    if(!propellant_is_upgrade) {
                    //TogglePropellant();
               //     }
            //}
        }
        public void setupPropellants()
        {
            ModuleEngines curEngine = (ModuleEngines)this.part.Modules["ModuleEngines"];
            ConfigNode chosenpropellant = propellants[fuel_mode];
            ConfigNode[] assprops = chosenpropellant.GetNodes("PROPELLANT");
            List<ModuleEngines.Propellant> list_of_propellants = new List<ModuleEngines.Propellant>();

            //VStackIcon stackicon = new VStackIcon(part);
            bool currentpropellant_is_jet = false;
            bool currentpropellant_is_electric = false;
            //part.stackIcon.RemoveInfo(fuel_gauge);
            //part.stackIcon.ClearInfoBoxes();
            //part.stackIcon.DisplayInfo().

            for (int i = 0; i < assprops.Length; ++i) {
                fuelmode = chosenpropellant.GetValue("guiName");
                ispMultiplier = float.Parse(chosenpropellant.GetValue("ispMultiplier"));
                isLFO = bool.Parse(chosenpropellant.GetValue("isLFO"));
                if(chosenpropellant.HasValue("isJet")) {
                    currentpropellant_is_jet = bool.Parse(chosenpropellant.GetValue("isJet"));
                }

                ModuleEngines.Propellant curprop = new ModuleEngines.Propellant();
                curprop.Load(assprops[i]);
                if (curprop.drawStackGauge) {
                    curprop.drawStackGauge = false;
                    if (currentpropellant_is_jet) {
                        print("Atmosphere");
                        fuel_gauge.SetMessage("Atmosphere");
                    }else {
                        fuel_gauge.SetMessage(curprop.name);
                    }
                    fuel_gauge.SetMsgBgColor(XKCDColors.DarkLime);
                    fuel_gauge.SetMsgTextColor(XKCDColors.ElectricLime);
                    fuel_gauge.SetProgressBarColor(XKCDColors.Yellow);
                    fuel_gauge.SetProgressBarBgColor(XKCDColors.DarkLime);
                    fuel_gauge.SetValue(0f);
                }
                list_of_propellants.Add(curprop);
            }

            Part[] childParts = this.part.FindChildParts<Part>(true);
            PartModuleList childModules;
            for (int i = 0; i < childParts.Length; ++i) {
                childModules = childParts.ElementAt(i).Modules;
                for (int j = 0; j < childModules.Count; ++j) {
                    PartModule thisModule = childModules.GetModule(j);
                    var thisModule2 = thisModule as FNReactor;
                    if (thisModule2 != null) {
                        FNReactor fnr = (FNReactor)thisModule;
                        FloatCurve newISP = new FloatCurve();
                        FloatCurve vCurve = new FloatCurve ();
                        if (!currentpropellant_is_jet) {
                            maxISP = (float)Math.Sqrt((double)fnr.getReactorTemp()) * 17*ispMultiplier;
                            minISP = maxISP * 0.4f;
                            newISP.Add(0, maxISP, 0, 0);
                            newISP.Add(1, minISP, 0, 0);
                            curEngine.useVelocityCurve = false;
                            curEngine.useEngineResponseTime = false;
                        }else {
                            if (thisModule2.getIsNuclear()) {
                                maxISP = 150;
                                newISP.Add(0, 100);
                                newISP.Add(0.3f, 150);
                                newISP.Add(1, 75);
                                vCurve.Add(0, 1);
                                vCurve.Add(400, 0.8f);
                                vCurve.Add(950, 0.9f);
                                vCurve.Add (1471, 0);
                            } else {
                                maxISP = 2500;
                                newISP.Add(0, 1200);
                                newISP.Add(0.3f, 2500);
                                newISP.Add(1, 800);
                                vCurve.Add(0, 1);
                                vCurve.Add(400, 0.8f);
                                vCurve.Add(1000, 0.9f);
                                vCurve.Add (2000, 0.5f);
                            }

                            curEngine.useVelocityCurve = true;
                            curEngine.useEngineResponseTime = true;
                        }
                        //ModuleEngines curEngine = (ModuleEngines)this.part.Modules["ModuleEngines"];
                        curEngine.atmosphereCurve = newISP;
                        curEngine.velocityCurve = vCurve;
                        assThermalPower = fnr.getReactorThermalPower();
                        engineMaxThrust = 2000 * assThermalPower / maxISP / 9.81f;

                        float heat_exchanger_thrust_divisor = 1;
                        if (radius > fnr.getRadius ()) {
                            heat_exchanger_thrust_divisor = fnr.getRadius () * fnr.getRadius () / radius / radius;
                        }else{
                            heat_exchanger_thrust_divisor = radius * radius / fnr.getRadius () / fnr.getRadius ();
                        }

                        engineMaxThrust = engineMaxThrust * heat_exchanger_thrust_divisor;

                        if (isLFO) {
                            engineMaxThrust = engineMaxThrust*1.5f;
                        }
                        curEngine.maxThrust = engineMaxThrust;
                    }

                }

            }

            Part parent = this.part.parent;
            if (parent != null) {
                childModules = parent.Modules;
                for (int j = 0; j < childModules.Count; ++j) {
                    PartModule thisModule = childModules.GetModule(j);
                    var thisModule2 = thisModule as FNReactor;
                    if (thisModule2 != null) {
                        FNReactor fnr = (FNReactor)thisModule;
                        FloatCurve newISP = new FloatCurve();
                        FloatCurve vCurve = new FloatCurve ();
                        if (!currentpropellant_is_jet) {
                            maxISP = (float)Math.Sqrt((double)fnr.getReactorTemp()) * 17 * ispMultiplier;
                            minISP = maxISP * 0.4f;
                            newISP.Add(0, maxISP, 0, 0);
                            newISP.Add(1, minISP, 0, 0);
                            curEngine.useVelocityCurve = false;
                            curEngine.useEngineResponseTime = false;
                        }
                        else {
                            if (thisModule2.getIsNuclear()) {
                                maxISP = 150;
                                newISP.Add(0, 100);
                                newISP.Add(0.3f, 150);
                                newISP.Add(1, 75);
                                vCurve.Add(0, 1);
                                vCurve.Add(400, 0.8f);
                                vCurve.Add(950, 0.9f);
                                vCurve.Add (1471, 0);
                            } else {
                                maxISP = 2500;
                                newISP.Add(0, 1200);
                                newISP.Add(0.3f, 2500);
                                newISP.Add(1, 800);
                                vCurve.Add(0, 1);
                                vCurve.Add(400, 0.8f);
                                vCurve.Add(1000, 0.9f);
                                vCurve.Add (2000, 0.5f);
                            }
                            curEngine.useVelocityCurve = true;
                            curEngine.useEngineResponseTime = true;
                        }
                        //ModuleEngines curEngine = (ModuleEngines)this.part.Modules["ModuleEngines"];
                        curEngine.atmosphereCurve = newISP;
                        curEngine.velocityCurve = vCurve;
                        assThermalPower = fnr.getReactorThermalPower();
                        engineMaxThrust = 2000 * assThermalPower / maxISP / 9.81f;

                        float heat_exchanger_thrust_divisor = 1;
                        if (radius > fnr.getRadius ()) {
                            heat_exchanger_thrust_divisor = fnr.getRadius () * fnr.getRadius () / radius / radius;
                        }else{
                            heat_exchanger_thrust_divisor = radius * radius / fnr.getRadius () / fnr.getRadius ();
                        }

                        if (fnr.getRadius () == 0 || radius == 0) {
                            heat_exchanger_thrust_divisor = 1;
                        }

                        engineMaxThrust = engineMaxThrust * heat_exchanger_thrust_divisor;

                        if (isLFO) {
                            engineMaxThrust = engineMaxThrust * 1.5f;
                        }
                        curEngine.maxThrust = engineMaxThrust;

                    }
                }
            }

            if (PartResourceLibrary.Instance.GetDefinition(list_of_propellants[0].name) != null) {
                curEngine.propellants.Clear();
                curEngine.propellants = list_of_propellants;
                curEngine.SetupPropellant();
            }

            //List<PartResource> partresources = new List<PartResource>();
            //part.GetConnectedResources(curEngine.propellants[0].id, partresources);

            bool next_propellant = false;

            List<ModuleEngines.Propellant> curEngine_propellants_list = new List<ModuleEngines.Propellant>();
            curEngine_propellants_list = curEngine.propellants;
            foreach(ModuleEngines.Propellant curEngine_propellant in curEngine_propellants_list) {
                List<PartResource> partresources = new List<PartResource>();
                part.GetConnectedResources(curEngine_propellant.id, partresources);
                if(partresources.Count == 0) {
                    next_propellant = true;
                }
            }

            if (next_propellant && fuel_mode != 1) {
                TogglePropellant();
            }
            /*else {
                if ((!isJet && currentpropellant_is_jet) || (isJet && !currentpropellant_is_jet)) {
                    TogglePropellant();
                }
            }*/
        }