Example #1
0
            public void Load(ConfigNode node)
            {
                if (node.name == "CONTENT" && node.HasValue("qty"))
                {
                    pristine_count += int.Parse(node.GetValue("qty"));
                }
                else if (node.name == "CONTENT_PART" && node.HasValue("kas_total_mass"))
                {
                    ConfigNode nodeD = new ConfigNode();
                    node.CopyTo(nodeD);

                    // Backward compatibility: compute the cost and save it
                    if (!nodeD.HasValue("kas_total_cost"))
                    {
                        var snapshot = KAS_Shared.LoadProtoPartSnapshot(nodeD);

                        float dry_cost, fuel_cost;
                        float total_cost = ShipConstruction.GetPartCosts(snapshot, part, out dry_cost, out fuel_cost);
                        nodeD.AddValue("kas_total_cost", total_cost);
                    }

                    instance_mass += float.Parse(nodeD.GetValue("kas_total_mass"));
                    instance_cost += float.Parse(nodeD.GetValue("kas_total_cost"));
                    instances.Add(nodeD);
                }
            }
Example #2
0
        /// <summary>
        /// Create an InventoryPart from an origin ProtoPartSnapshot, extracting the name, dry cost, and relevant MODULEs
        /// </summary>
        /// <param name="originPartSnapshot">The <see cref="ProtoPartSnapshot"/> to use as the basis of the <see cref="InventoryPart"/>.</param>
        public InventoryPart(ProtoPartSnapshot originPartSnapshot)
        {
            _name = originPartSnapshot.partInfo.name;
            if (ScrapYard.Instance.Settings.PartBlacklist.Contains(Name))
            {
                DoNotStore = true;
            }
            float fuelCost;

            ShipConstruction.GetPartCosts(originPartSnapshot, originPartSnapshot.partInfo, out _dryCost, out fuelCost);

            //Save modules
            if (originPartSnapshot.modules != null)
            {
                foreach (ProtoPartModuleSnapshot module in originPartSnapshot.modules)
                {
                    string name      = module.moduleName;
                    bool   isTracker = name.Equals("ModuleSYPartTracker");
                    if (isTracker || moduleNameMatchesAnything(name)) //only save if there is a potential match
                    {
                        ConfigNode saved = module.moduleValues;
                        _allModules.Add(saved);
                        if (isTracker)
                        {
                            TrackerModule = new TrackerModuleWrapper(saved);
                        }
                    }
                }
            }

            ID = originPartSnapshot.persistentId;
        }
Example #3
0
/*************************************************************************************************************************/
        private float vessels_cost(ProtoVessel temp_vessel)
        {
            float partcost, float_dummy, vesselcost = 0;
            PartResourceDefinition resc_def;

#if DEBUG
            // if (Debug_Level_1_Active)
            Log.PushStackInfo("FMRS_Core.vessels_cost", "enter float vessels_cost(ProtoVessel temp_vessel) " + temp_vessel.vesselID.ToString());
            if (Debug_Active)
            {
                Log.Info("Calculate cost from: " + temp_vessel.vesselName);
            }
#endif

            foreach (ProtoPartSnapshot part in temp_vessel.protoPartSnapshots)
            {
                ShipConstruction.GetPartCosts(part, part.partInfo, out partcost, out float_dummy);
                foreach (ProtoPartResourceSnapshot resc in part.resources)
                {
                    resc_def  = PartResourceLibrary.Instance.resourceDefinitions[resc.resourceName];
                    partcost += (float)resc.amount * resc_def.unitCost;
                }
                vesselcost += partcost;
            }

#if DEBUG
            if (Debug_Active)
            {
                Log.Info("FMRS cost: " + vesselcost.ToString());
            }
            // if (Debug_Level_1_Active)
            Log.PopStackInfo("leave float vessels_cost(ProtoVessel temp_vessel)");
#endif
            return(vesselcost);
        }
Example #4
0
        public float getPartRawPrice(ProtoPartSnapshot P)
        {
            float dryCost, fuelCost;

            ShipConstruction.GetPartCosts(P, P.partInfo, out dryCost, out fuelCost);
            return(dryCost);
        }
Example #5
0
        public static float GetRecoveryValueForChuteLanding(ProtoVessel pv)
        {
            bool probeCoreAttached = false;

            foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
            {
                if (pps.modules.Find(module => (module.moduleName == "ModuleCommand" && ((ModuleCommand)module.moduleRef).minimumCrew == 0)) != null)
                {
                    KCTDebug.Log("Probe Core found!");
                    probeCoreAttached = true;
                }
            }
            float  RecoveryMod     = probeCoreAttached ? 1.0f : KCT_GameStates.settings.RecoveryModifier;
            double distanceFromKSC = SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(pv.latitude, pv.longitude));
            double maxDist         = SpaceCenter.Instance.cb.Radius * Math.PI;
            float  recoveryPercent = RecoveryMod * Mathf.Lerp(0.98f, 0.1f, (float)(distanceFromKSC / maxDist));
            float  totalReturn     = 0;

            foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
            {
                float dryCost, fuelCost;
                totalReturn += ShipConstruction.GetPartCosts(pps, pps.partInfo, out dryCost, out fuelCost);
            }
            float totalBeforeReturn = (float)Math.Round(totalReturn, 2);

            totalReturn *= recoveryPercent;
            totalReturn  = (float)Math.Round(totalReturn, 2);
            KCTDebug.Log("Vessel being recovered by KCT. Percent returned: " + 100 * recoveryPercent + "%. Distance from KSC: " + Math.Round(distanceFromKSC / 1000, 2) + " km");
            KCTDebug.Log("Funds being returned: " + totalReturn + "/" + totalBeforeReturn);
            return(totalReturn);
        }
Example #6
0
        void Update()
        {
            if (FlightGlobals.fetch == null)
            {
                return;
            }

            Vessel activeVessel = FlightGlobals.ActiveVessel;

            if (activeVessel == null)
            {
                return;
            }

            vesselPartValue     = 0.0f;
            vesselResourceValue = 0.0f;

            foreach (Part part in FlightGlobals.ActiveVessel.Parts)
            {
                float dryCost, fuelCost;
                ShipConstruction.GetPartCosts(part.protoPartSnapshot, part.partInfo, out dryCost, out fuelCost);

                vesselPartValue += dryCost;

                foreach (PartResource resource in part.Resources)
                {
                    vesselResourceValue += (float)resource.amount * resource.info.unitCost;
                }
            }

            vesselValue = vesselPartValue + vesselResourceValue;
        }
Example #7
0
        public static float GetPartCostFromNode(ConfigNode part)
        {
            string name = PartNameFromNode(part);
            float  dry, wet;
            float  total = ShipConstruction.GetPartCosts(part, GetAvailablePartByName(name), out dry, out wet);

            return(total);
        }
Example #8
0
        //private ProtoVessel recovered;

        public KCT_BuildListVessel(Vessel vessel) //For recovered vessels
        {
            /* if (KCT_GameStates.recoveryRequestVessel == null)
             * {
             *   KCTDebug.Log("Somehow tried to recover something that was null!");
             *   return;
             * }*/


            id       = Guid.NewGuid();
            shipName = vessel.vesselName;
            shipNode = FromInFlightVessel(vessel);

            cost           = KCT_Utilities.GetTotalVesselCost(shipNode);
            emptyCost      = KCT_Utilities.GetTotalVesselCost(shipNode, false);
            TotalMass      = 0;
            emptyMass      = 0;
            InventoryParts = new Dictionary <string, int>();
            foreach (ProtoPartSnapshot p in vessel.protoVessel.protoPartSnapshots)
            {
                //InventoryParts.Add(p.partInfo.name + KCT_Utilities.GetTweakScaleSize(p));
                string name = p.partInfo.name;
                int    amt  = 1;
                if (KCT_Utilities.PartIsProcedural(p))
                {
                    float dry, wet;
                    ShipConstruction.GetPartCosts(p, p.partInfo, out dry, out wet);
                    amt = (int)(1000 * dry);
                }
                else
                {
                    name += KCT_Utilities.GetTweakScaleSize(p);
                }
                KCT_Utilities.AddToDict(InventoryParts, name, amt);

                TotalMass += p.mass;
                emptyMass += p.mass;
                foreach (ProtoPartResourceSnapshot rsc in p.resources)
                {
                    PartResourceDefinition def = PartResourceLibrary.Instance.GetDefinition(rsc.resourceName);
                    if (def != null)
                    {
                        TotalMass += def.density * float.Parse(rsc.resourceValues.GetValue("amount"));
                    }
                }
            }
            cannotEarnScience = true;

            buildPoints = KCT_Utilities.GetBuildTime(shipNode.GetNodes("PART").ToList(), true, InventoryParts);
            flag        = HighLogic.CurrentGame.flagURL;
            progress    = buildPoints;

            DistanceFromKSC = (float)SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(vessel.latitude, vessel.longitude));
        }
Example #9
0
        public static float GetTotalVesselCost(ProtoVessel vessel)
        {
            float total = 0;

            foreach (ProtoPartSnapshot part in vessel.protoPartSnapshots)
            {
                float dry, wet;
                total += ShipConstruction.GetPartCosts(part, part.partInfo, out dry, out wet);
            }
            return(total);
        }
Example #10
0
        void Start()
        {
            if (FlightGlobals.fetch == null)
            {
                return;
            }

            if (!HighLogic.LoadedSceneIsFlight)
            {
                return;
            }

            Vessel activeVessel = FlightGlobals.ActiveVessel;

            if (activeVessel == null)
            {
                return;
            }

            if (activeVessel.situation != Vessel.Situations.PRELAUNCH)
            {
                return;
            }

            vesselPartValue     = 0.0f;
            vesselResourceValue = 0.0f;

            foreach (Part part in FlightGlobals.ActiveVessel.Parts)
            {
                float dryCost, fuelCost;
                ShipConstruction.GetPartCosts(part.protoPartSnapshot, part.partInfo, out dryCost, out fuelCost);

                vesselPartValue += dryCost;

                foreach (PartResource resource in part.Resources)
                {
                    vesselResourceValue += (float)resource.amount * resource.info.unitCost;
                }
            }

            GameEvents.Contract.onCompleted.Add(OnContractCompleted);
            GameEvents.Contract.onParameterChange.Add(OnContractParameterChange);

            GameEvents.OnScienceChanged.Add(OnScienceChanged);

            vesselLaunchedValue      = vesselPartValue + vesselResourceValue;
            numContractsCompleted    = 0;
            contractFundsEarned      = 0.0f;
            contractReputationEarned = 0.0f;
            contractScienceEarned    = 0.0f;

            scienceTransmitted = 0.0f;
        }
Example #11
0
        /// <summary>
        /// Create an InventoryPart from an origin ProtoPartSnapshot, extracting the name, dry cost, and relevant MODULEs
        /// </summary>
        /// <param name="originPartSnapshot">The <see cref="ProtoPartSnapshot"/> to use as the basis of the <see cref="InventoryPart"/>.</param>
        public InventoryPart(ProtoPartSnapshot originPartSnapshot)
        {
            _name = originPartSnapshot.partInfo.name;
            float fuelCost;

            ShipConstruction.GetPartCosts(originPartSnapshot, originPartSnapshot.partInfo, out _dryCost, out fuelCost);

            //Save modules
            if (originPartSnapshot.modules != null)
            {
                foreach (ProtoPartModuleSnapshot module in originPartSnapshot.modules)
                {
                    foreach (string trackedModuleName in ScrapYard.Instance.Settings.TrackedModules)
                    {
                        if (module.moduleName.ToUpper().Contains(trackedModuleName))
                        {
                            savedModules.Add(module.moduleValues);
                        }
                    }
                }
            }
        }
Example #12
0
/*************************************************************************************************************************/
        private float vessels_cost(ProtoVessel temp_vessel)
        {
            float partcost, float_dummy, vesselcost = 0;
            PartResourceDefinition resc_def;

            Log.PushStackInfo("FMRS_Core.vessels_cost", "enter float vessels_cost(ProtoVessel temp_vessel) {0}", temp_vessel.vesselID);
            Log.dbg("Calculate cost from: {0}", temp_vessel.vesselName);

            foreach (ProtoPartSnapshot part in temp_vessel.protoPartSnapshots)
            {
                ShipConstruction.GetPartCosts(part, part.partInfo, out partcost, out float_dummy);
                foreach (ProtoPartResourceSnapshot resc in part.resources)
                {
                    resc_def  = PartResourceLibrary.Instance.resourceDefinitions[resc.resourceName];
                    partcost += (float)resc.amount * resc_def.unitCost;
                }
                vesselcost += partcost;
            }

            Log.dbg("FMRS cost: {0}", vesselcost);
            Log.PopStackInfo("leave float vessels_cost(ProtoVessel temp_vessel)");

            return(vesselcost);
        }
Example #13
0
        public void VesselUnloadEvent(Vessel vessel)
        {
            //If we're disabled, just return

            if (!Settings1.Instance.SREnabled)
            {
                return;
            }

            //If the vessel or the protovessel are null then we surely can't do anything with them
            if (vessel == null || vessel.protoVessel == null)
            {
                return;
            }

            ProtoVessel pv = vessel.protoVessel;

            //If we aren't supposed to recover clamps, then don't try.
            if (Settings1.Instance.RecoverClamps)
            {
                //If we've already recovered the clamps, then no need to try again
                if (clampsRecovered.Find(a => a.id == vessel.id) != null)
                {
                    return;
                }

                //Assign the pv variable to the protovessel, then look for if the root is a clamp

                if (pv.protoPartSnapshots.Count > 0 && pv.protoPartSnapshots[0].modules.Exists(m => m.moduleName == "LaunchClamp"))
                {
                    //We look for the launchclamp module, which will hopefully cover FASA and stock.
                    Log.Info("[SR] Recovering a clamp!");
                    //Add it to the recovered clamps list so we don't try to recover it again
                    clampsRecovered.Add(vessel);
                    float totalRefund = 0;
                    //Loop over all the parts and calculate their cost (we recover at 100% since we're at the launchpad/runway)
                    foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
                    {
                        float out1, out2;
                        totalRefund += ShipConstruction.GetPartCosts(pps, pps.partInfo, out out1, out out2);
                    }
                    //Add dem funds to da total. Get dem funds!
                    AddFunds(totalRefund);
                    //Fire the successful recovery event. Even though this isn't a stage we still need to do this for things like KCT to recover the parts.
                    //Can be averted with stock functions if I can get them working properly
                    APIManager.instance.RecoverySuccessEvent.Fire(vessel, new float[] { 100, totalRefund, 0 }, "SUCCESS");
                    //And then we try a bunch of things to make sure the clamps are removed (remove it from the flight state, kill it, and destroy it)
                    HighLogic.CurrentGame.flightState.protoVessels.Remove(pv);
                    vessel.Die();
                    Destroy(vessel);
                    //So, question for myself. Would it be better to try to manually fire the recovery events? Would that really be worth anything?
                }
            }

            //If it's a stage that will be destroyed, we need to manually recover the Kerbals
            if (Settings1.Instance.PreRecover && pv.GetVesselCrew().Count > 0)
            {
                //Check if the conditions for vessel destruction are met
                if (vessel != FlightGlobals.ActiveVessel && !vessel.isEVA && vessel.mainBody == Planetarium.fetch.Home &&
                    pv.situation != Vessel.Situations.LANDED && vessel.altitude < cutoffAlt && vessel.altitude > 0 &&
                    (FlightGlobals.ActiveVessel.transform.position - vessel.transform.position).sqrMagnitude > Math.Pow(vessel.vesselRanges.GetSituationRanges(Vessel.Situations.FLYING).pack, 2) - 250)
                {
                    Log.Info("[SR] Vessel " + pv.vesselName + " is going to be destroyed. Pre-recovering!"); //Kerbal death should be handled by SR instead

                    RecoverVessel(vessel, true);
                }
                else
                {
                    TryWatchVessel(vessel);
                }
            }
        }
Example #14
0
        public void vesselDestroyEvent(Vessel v)
        {
            if (!KCT_GameStates.settings.enabledForSave)
            {
                return;
            }
            Dictionary <string, int> PartsRecovered = new Dictionary <string, int>();
            float         FundsRecovered = 0, KSCDistance = 0, RecoveryPercent = 0;
            StringBuilder Message = new StringBuilder();

            if (FlightGlobals.fetch == null)
            {
                return;
            }

            if (v != null && !(HighLogic.LoadedSceneIsFlight && v.isActiveVessel) && v.mainBody.bodyName == "Kerbin" && (!v.loaded || v.packed) && v.altitude < 35000 &&
                (v.situation == Vessel.Situations.FLYING || v.situation == Vessel.Situations.SUB_ORBITAL) && !v.isEVA)
            {
                double totalMass      = 0;
                double dragCoeff      = 0;
                bool   realChuteInUse = false;

                float RCParameter = 0;

                if (!v.packed) //adopted from mission controller.
                {
                    foreach (Part p in v.Parts)
                    {
                        p.Pack();
                    }
                }

                if (v.protoVessel == null)
                {
                    return;
                }
                KCTDebug.Log("Attempting to recover vessel.");
                try
                {
                    foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                    {
                        //KCTDebug.Log("Has part " + p.partName + ", mass " + p.mass);
                        List <string> ModuleNames = new List <string>();
                        foreach (ProtoPartModuleSnapshot ppms in p.modules)
                        {
                            //Debug.Log(ppms.moduleName);
                            ModuleNames.Add(ppms.moduleName);
                        }
                        totalMass += p.mass;
                        totalMass += GetResourceMass(p.resources);
                        bool isParachute = false;
                        if (ModuleNames.Contains("ModuleParachute"))
                        {
                            KCTDebug.Log("Found parachute module on " + p.partInfo.name);
                            //Find the ModuleParachute (find it in the module list by checking for a module with the name ModuleParachute)
                            ProtoPartModuleSnapshot ppms = p.modules.First(mod => mod.moduleName == "ModuleParachute");
                            float drag = 500;
                            if (ppms.moduleRef != null)
                            {
                                ModuleParachute mp = (ModuleParachute)ppms.moduleRef;
                                mp.Load(ppms.moduleValues);
                                drag = mp.fullyDeployedDrag;
                            }
                            //Add the part mass times the fully deployed drag (typically 500) to the dragCoeff variable (you'll see why later)
                            dragCoeff += p.mass * drag;
                            //This is most definitely a parachute part
                            isParachute = true;
                        }
                        if (ModuleNames.Contains("RealChuteModule"))
                        {
                            KCTDebug.Log("Found realchute module on " + p.partInfo.name);
                            ProtoPartModuleSnapshot realChute = p.modules.First(mod => mod.moduleName == "RealChuteModule");
                            if ((object)realChute != null) //Some of this was adopted from DebRefund, as Vendan's method of handling multiple parachutes is better than what I had.
                            {
                                Type matLibraryType = AssemblyLoader.loadedAssemblies
                                                      .SelectMany(a => a.assembly.GetExportedTypes())
                                                      .SingleOrDefault(t => t.FullName == "RealChute.Libraries.MaterialsLibrary");

                                ConfigNode[] parchutes = realChute.moduleValues.GetNodes("PARACHUTE");
                                foreach (ConfigNode chute in parchutes)
                                {
                                    float  diameter = float.Parse(chute.GetValue("deployedDiameter"));
                                    string mat      = chute.GetValue("material");
                                    System.Reflection.MethodInfo matMethod = matLibraryType.GetMethod("GetMaterial", new Type[] { mat.GetType() });
                                    object MatLibraryInstance = matLibraryType.GetProperty("instance").GetValue(null, null);
                                    object materialObject     = matMethod.Invoke(MatLibraryInstance, new object[] { mat });
                                    float  dragC = (float)KCT_Utilities.GetMemberInfoValue(materialObject.GetType().GetMember("dragCoefficient")[0], materialObject);

                                    RCParameter += dragC * (float)Math.Pow(diameter, 2);
                                }
                                isParachute    = true;
                                realChuteInUse = true;
                            }
                        }
                        if (!isParachute)
                        {
                            if (p.partRef != null)
                            {
                                dragCoeff += p.mass * p.partRef.maximum_drag;
                            }
                            else
                            {
                                dragCoeff += p.mass * 0.2;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError("[KCT] Error while attempting to recover vessel.");
                    Debug.LogException(e);
                }
                double Vt = double.MaxValue;
                if (!realChuteInUse)
                {
                    dragCoeff = dragCoeff / (totalMass);
                    Vt        = Math.Sqrt((250 * 6.674E-11 * 5.2915793E22) / (3.6E11 * 1.22309485 * dragCoeff));
                    KCTDebug.Log("Using Stock Module! Drag: " + dragCoeff + " Vt: " + Vt);
                }
                else
                {
                    Vt = Math.Sqrt((8000 * totalMass * 9.8) / (1.223 * Math.PI) * Math.Pow(RCParameter, -1)); //This should work perfect for multiple identical chutes and gives an approximation for multiple differing chutes
                    KCTDebug.Log("Using RealChute Module! Vt: " + Vt);
                }
                if (Vt < 10.0)
                {
                    KCTDebug.Log("Recovered parts from " + v.vesselName);
                    foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                    {
                        KCT_Utilities.AddPartToInventory(p.partInfo.name + KCT_Utilities.GetTweakScaleSize(p));
                        if (!PartsRecovered.ContainsKey(p.partInfo.title))
                        {
                            PartsRecovered.Add(p.partInfo.title, 1);
                        }
                        else
                        {
                            ++PartsRecovered[p.partInfo.title];
                        }
                    }

                    Message.AppendLine("Vessel name: " + v.vesselName);
                    Message.AppendLine("Parts recovered: ");
                    for (int i = 0; i < PartsRecovered.Count; i++)
                    {
                        Message.AppendLine(PartsRecovered.Values.ElementAt(i) + "x " + PartsRecovered.Keys.ElementAt(i));
                    }

                    if (KCT_Utilities.CurrentGameIsCareer())
                    {
                        if (KCT_Utilities.StageRecoveryAddonActive || KCT_Utilities.DebRefundAddonActive) //Delegate funds handling to Stage Recovery or DebRefund if it's present
                        {
                            KCTDebug.Log("Delegating Funds recovery to another addon.");
                        }
                        else  //Otherwise do it ourselves
                        {
                            bool probeCoreAttached = false;
                            foreach (ProtoPartSnapshot pps in v.protoVessel.protoPartSnapshots)
                            {
                                if (pps.modules.Find(module => (module.moduleName == "ModuleCommand" && ((ModuleCommand)module.moduleRef).minimumCrew == 0)) != null)
                                {
                                    KCTDebug.Log("Probe Core found!");
                                    probeCoreAttached = true;
                                    break;
                                }
                            }
                            float RecoveryMod = probeCoreAttached ? 1.0f : KCT_GameStates.settings.RecoveryModifier;
                            KSCDistance = (float)SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(v.protoVessel.latitude, v.protoVessel.longitude));
                            double maxDist = SpaceCenter.Instance.cb.Radius * Math.PI;
                            RecoveryPercent = RecoveryMod * Mathf.Lerp(0.98f, 0.1f, (float)(KSCDistance / maxDist));
                            float totalReturn = 0;
                            foreach (ProtoPartSnapshot pps in v.protoVessel.protoPartSnapshots)
                            {
                                float dryCost, fuelCost;
                                totalReturn += Math.Max(ShipConstruction.GetPartCosts(pps, pps.partInfo, out dryCost, out fuelCost), 0);
                            }
                            float totalBeforeModifier = totalReturn;
                            totalReturn   *= RecoveryPercent;
                            FundsRecovered = totalReturn;
                            KCTDebug.Log("Vessel being recovered by KCT. Percent returned: " + 100 * RecoveryPercent + "%. Distance from KSC: " + Math.Round(KSCDistance / 1000, 2) + " km");
                            KCTDebug.Log("Funds being returned: " + Math.Round(totalReturn, 2) + "/" + Math.Round(totalBeforeModifier, 2));

                            Message.AppendLine("Funds recovered: " + FundsRecovered + "(" + Math.Round(RecoveryPercent * 100, 1) + "%)");
                            KCT_Utilities.AddFunds(FundsRecovered);
                        }
                    }
                    Message.AppendLine("\nAdditional information:");
                    Message.AppendLine("Distance from KSC: " + Math.Round(KSCDistance / 1000, 2) + " km");
                    if (!realChuteInUse)
                    {
                        Message.AppendLine("Stock module used. Terminal velocity (less than 10 needed): " + Math.Round(Vt, 2));
                    }
                    else
                    {
                        Message.AppendLine("RealChute module used. Terminal velocity (less than 10 needed): " + Math.Round(Vt, 2));
                    }
                    if (!(KCT_Utilities.StageRecoveryAddonActive || KCT_Utilities.DebRefundAddonActive) &&
                        (KCT_Utilities.CurrentGameIsCareer() || !KCT_GUI.PrimarilyDisabled) &&
                        !(KCT_GameStates.settings.DisableAllMessages || KCT_GameStates.settings.DisableRecoveryMessages))
                    {
                        KCT_Utilities.DisplayMessage("Stage Recovered", Message, MessageSystemButton.MessageButtonColor.BLUE, MessageSystemButton.ButtonIcons.MESSAGE);
                    }
                }
            }
        }
Example #15
0
        public static ConfigNode SavePartSnapshot(Part part)
        {
            // Seems fine with a null vessel in 0.23 if some empty lists are allocated below
            ProtoPartSnapshot snapshot = new ProtoPartSnapshot(part, null);

            ConfigNode node = new ConfigNode("CONTENT_PART");

            snapshot.attachNodes   = new List <AttachNodeSnapshot>();
            snapshot.srfAttachNode = new AttachNodeSnapshot("attach,-1");
            snapshot.symLinks      = new List <ProtoPartSnapshot>();
            snapshot.symLinkIdxs   = new List <int>();

            snapshot.Save(node);

            float dry_cost, fuel_cost;
            float total_cost = ShipConstruction.GetPartCosts(snapshot, part.partInfo,
                                                             out dry_cost, out fuel_cost);

            node.AddValue("kas_total_mass", part.mass + part.GetResourceMass());
            node.AddValue("kas_total_cost", total_cost);

            // Prune unimportant data
            node.RemoveValues("parent");
            node.RemoveValues("position");
            node.RemoveValues("rotation");
            node.RemoveValues("istg");
            node.RemoveValues("dstg");
            node.RemoveValues("sqor");
            node.RemoveValues("sidx");
            node.RemoveValues("attm");
            node.RemoveValues("srfN");
            node.RemoveValues("attN");
            node.RemoveValues("connected");
            node.RemoveValues("attached");
            node.RemoveValues("flag");

            node.RemoveNodes("ACTIONS");

            // Remove modules that are not in prefab since they won't load anyway
            var module_nodes   = node.GetNodes("MODULE");
            var prefab_modules = part.partInfo.partPrefab.GetComponents <PartModule>();

            node.RemoveNodes("MODULE");

            for (int i = 0; i < prefab_modules.Length && i < module_nodes.Length; i++)
            {
                var module = module_nodes[i];
                var name   = module.GetValue("name") ?? "";

                node.AddNode(module);

                if (name == "KASModuleContainer")
                {
                    // Containers get to keep their contents
                    module.RemoveNodes("EVENTS");
                }
                else if (name.StartsWith("KASModule"))
                {
                    // Prune the state of the KAS modules completely
                    module.ClearData();
                    module.AddValue("name", name);
                    continue;
                }

                module.RemoveNodes("ACTIONS");
            }

            return(node);
        }