Exemple #1
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);
        }
Exemple #2
0
        public static void MakeSimulationSave()
        {
            string backupFile = KSPUtil.ApplicationRootPath + "saves/" + HighLogic.SaveFolder + "/KCT_simulation_backup.sfs";
            string saveFile   = KSPUtil.ApplicationRootPath + "saves/" + HighLogic.SaveFolder + "/persistent.sfs";

            KCTDebug.Log("Making simulation backup file.");
            System.IO.File.Copy(saveFile, backupFile, true);
        }
Exemple #3
0
        public static void RecalculateEditorBuildTime(ShipConstruct ship)
        {
            KCTDebug.Log("Recalculating build time");
            List <ConfigNode> partNodes = ship.SaveShip().GetNodes("PART").ToList();

            KCT_GUI.PartsInUse.Clear();
            if (KCT_GUI.useInventory)
            {
                foreach (ConfigNode part in partNodes)
                {
                    string name = PartNameFromNode(part) + GetTweakScaleSize(part);
                    if (!KCT_GUI.PartsInUse.ContainsKey(name))
                    {
                        KCT_GUI.PartsInUse.Add(name, 1);
                    }
                    else
                    {
                        ++KCT_GUI.PartsInUse[name];
                    }
                }
            }

            if (!KCT_GameStates.EditorShipEditingMode)
            {
                KCT_GameStates.EditorBuildTime = KCT_Utilities.GetBuildTime(partNodes, true, KCT_GUI.useInventory);
            }
            else
            {
                List <string> partsForInventory = new List <string>();
                if (KCT_GUI.useInventory)
                {
                    List <string> newParts     = new List <string>(PartDictToList(KCT_GUI.PartsInUse));
                    List <string> theInventory = new List <string>(PartDictToList(KCT_GameStates.PartInventory));
                    foreach (string s in PartDictToList(KCT_GameStates.EditedVesselParts))
                    {
                        if (newParts.Contains(s))
                        {
                            newParts.Remove(s);
                        }
                    }

                    foreach (string s in newParts)
                    {
                        if (theInventory.Contains(s))
                        {
                            theInventory.Remove(s);
                            partsForInventory.Add(s);
                        }
                    }
                }
                foreach (string s in KCT_GameStates.editedVessel.InventoryParts)
                {
                    partsForInventory.Add(s);
                }

                KCT_GameStates.EditorBuildTime = KCT_Utilities.GetBuildTime(partNodes, true, partsForInventory);
            }
        }
Exemple #4
0
 public static double AddFunds(double toAdd)
 {
     if (!CurrentGameIsCareer())
     {
         return(0);
     }
     KCTDebug.Log("Adding funds: " + toAdd + ", New total: " + (Funding.Instance.Funds + toAdd));
     return(Funding.Instance.Funds += toAdd);
 }
Exemple #5
0
        private void StageRecoverySuccessEvent(Vessel v, float[] infoArray, string reason)
        {
            if (!KCT_GameStates.settings.enabledForSave)
            {
                return;
            }
            KCTDebug.Log("Recovery Success Event triggered.");
            float damage = 0;

            if (infoArray.Length == 3)
            {
                damage = infoArray[0];
            }
            else
            {
                KCTDebug.Log("Malformed infoArray received!");
            }
            System.Random            rand      = new System.Random();
            Dictionary <string, int> destroyed = new Dictionary <string, int>();

            foreach (ProtoPartSnapshot part in v.protoVessel.protoPartSnapshots)
            {
                float  random = (float)rand.NextDouble();
                string name   = part.partInfo.name + KCT_Utilities.GetTweakScaleSize(part);
                if (random < damage)
                {
                    KCT_Utilities.AddPartToInventory(name);
                }
                else
                {
                    string commonName = part.partInfo.title + KCT_Utilities.GetTweakScaleSize(part);
                    Debug.Log("[KCT] Part " + commonName + " was too damaged to be used anymore and was scrapped! Chance: " + damage);
                    if (!destroyed.ContainsKey(commonName))
                    {
                        destroyed.Add(commonName, 1);
                    }
                    else
                    {
                        ++destroyed[commonName];
                    }
                }
            }

            if (destroyed.Count > 0 && !KCT_GameStates.settings.DisableAllMessages)
            {
                StringBuilder msg = new StringBuilder();
                msg.AppendLine("The following parts were too damaged to be reused and were scrapped:");
                foreach (KeyValuePair <string, int> entry in destroyed)
                {
                    msg.AppendLine(entry.Value + " x " + entry.Key);
                }
                msg.AppendLine("\nChance of failure: " + Math.Round(100 * damage) + "%");
                KCT_Utilities.DisplayMessage("KCT: Parts Scrapped", msg, MessageSystemButton.MessageButtonColor.ORANGE, MessageSystemButton.ButtonIcons.ALERT);
            }
        }
Exemple #6
0
 public static void AddPartToInventory(String name)
 {
     if (KCT_GameStates.PartInventory.ContainsKey(name))
     {
         ++KCT_GameStates.PartInventory[name];
     }
     else
     {
         KCT_GameStates.PartInventory.Add(name, 1);
     }
     KCTDebug.Log("Added " + name + " to part inventory");
 }
Exemple #7
0
        public KCT_TechItem(RDTech techNode)
        {
            scienceCost = techNode.scienceCost;
            techName    = techNode.title;
            techID      = techNode.techID;
            progress    = 0;
            protoNode   = ResearchAndDevelopment.Instance.GetTechState(techID);

            KCTDebug.Log("techID = " + techID);
            KCTDebug.Log("BuildRate = " + BuildRate);
            KCTDebug.Log("TimeLeft = " + TimeLeft);
        }
Exemple #8
0
        public static void LoadSimulationSave()
        {
            string backupFile = KSPUtil.ApplicationRootPath + "saves/" + HighLogic.SaveFolder + "/KCT_simulation_backup.sfs";
            string saveFile   = KSPUtil.ApplicationRootPath + "saves/" + HighLogic.SaveFolder + "/persistent.sfs";

            KCT_Utilities.disableSimulationLocks();
            KCT_GameStates.flightSimulated   = false;
            Kerbal_Construction_Time.moved   = false;
            KCT_GameStates.simulationEndTime = 0;
            KCTDebug.Log("Swapping persistent.sfs with simulation backup file.");
            System.IO.File.Copy(backupFile, saveFile, true);
            System.IO.File.Delete(backupFile);
        }
Exemple #9
0
 public static bool RemovePartFromInventory(String name, Dictionary <String, int> inventory)
 {
     if (inventory.ContainsKey(name))
     {
         --inventory[name];
         if (inventory[name] == 0)
         {
             inventory.Remove(name);
         }
         KCTDebug.Log("Removed " + name + " from part inventory");
         return(true);
     }
     return(false);
 }
        public override void OnLoad(ConfigNode node)
        {
            KCTDebug.Log("Reading from persistence.");
            base.OnLoad(node);
            KCT_DataStorage      kctVS = new KCT_DataStorage();
            KCT_BuildListStorage bls   = new KCT_BuildListStorage();
            KCT_TechStorage      tS    = new KCT_TechStorage();
            ConfigNode           CN    = node.GetNode(kctVS.GetType().Name);

            if (CN != null)
            {
                ConfigNode.LoadObjectFromConfig(kctVS, CN);
            }

            CN = node.GetNode(bls.GetType().Name);
            if (CN != null)
            {
                ConfigNode.LoadObjectFromConfig(bls, CN);
            }

            CN = node.GetNode(tS.GetType().Name);
            if (CN != null)
            {
                ConfigNode.LoadObjectFromConfig(tS, CN);
            }

            for (int i = 0; i < KCT_GameStates.VABList.Count; i++)
            {
                KCT_GameStates.VABList[i].shipNode = node.GetNode("VAB" + i);
            }
            for (int i = 0; i < KCT_GameStates.SPHList.Count; i++)
            {
                KCT_GameStates.SPHList[i].shipNode = node.GetNode("SPH" + i);
            }
            for (int i = 0; i < KCT_GameStates.VABWarehouse.Count; i++)
            {
                KCT_GameStates.VABWarehouse[i].shipNode = node.GetNode("VABWH" + i);
            }
            for (int i = 0; i < KCT_GameStates.SPHWarehouse.Count; i++)
            {
                KCT_GameStates.SPHWarehouse[i].shipNode = node.GetNode("SPHWH" + i);
            }
            for (int i = 0; i < KCT_GameStates.TechList.Count; i++)
            {
                KCT_GameStates.TechList[i].protoNode = new ProtoTechNode(node.GetNode("Tech" + i));
            }

            Kerbal_Construction_Time.DelayedStart();
        }
Exemple #11
0
 public void vesselRecoverEvent(ProtoVessel v)
 {
     if (!KCT_GameStates.settings.enabledForSave)
     {
         return;
     }
     if (!KCT_GameStates.flightSimulated && !v.vesselRef.isEVA)
     {
         KCTDebug.Log("Adding recovered parts to Part Inventory");
         foreach (ProtoPartSnapshot p in v.protoPartSnapshots)
         {
             string name = p.partInfo.name + KCT_Utilities.GetTweakScaleSize(p);
             KCT_Utilities.AddPartToInventory(name);
         }
     }
 }
Exemple #12
0
 public static double SpendFunds(double toSpend)
 {
     if (!CurrentGameIsCareer())
     {
         return(0);
     }
     KCTDebug.Log("Removing funds: " + toSpend + ", New total: " + (Funding.Instance.Funds - toSpend));
     if (toSpend < Funding.Instance.Funds)
     {
         return(Funding.Instance.Funds -= toSpend);
     }
     else
     {
         return(Funding.Instance.Funds);
     }
 }
Exemple #13
0
        public static KCT_BuildListVessel AddVesselToBuildList(KCT_BuildListVessel blv, Dictionary <String, int> inventory)
        {
            if (CurrentGameIsCareer())
            {
                float  totalCost = blv.cost;
                double prevFunds = Funding.Instance.Funds;
                double newFunds  = SpendFunds(totalCost);
                if (prevFunds == newFunds)
                {
                    KCTDebug.Log("Tried to add " + blv.shipName + " to build list but not enough funds.");
                    KCTDebug.Log("Vessel cost: " + blv.cost + ", Current funds: " + newFunds);
                    var msg = new ScreenMessage("Not Enough Funds To Build!", 4.0f, ScreenMessageStyle.UPPER_CENTER);
                    ScreenMessages.PostScreenMessage(msg, true);
                    return(blv);
                }
            }
            string type = "";

            if (blv.type == KCT_BuildListVessel.ListType.VAB)
            {
                KCT_GameStates.VABList.Add(blv);
                type = "VAB";
            }
            else if (blv.type == KCT_BuildListVessel.ListType.SPH)
            {
                KCT_GameStates.SPHList.Add(blv);
                type = "SPH";
            }
            if (inventory.Count > 0)
            {
                foreach (ConfigNode p in blv.ExtractedPartNodes)
                {
                    if (KCT_Utilities.RemovePartFromInventory(p, inventory))
                    {
                        blv.InventoryParts.Add(PartNameFromNode(p) + GetTweakScaleSize(p));
                    }
                }
            }
            KCTDebug.Log("Added " + blv.shipName + " to " + type + " build list. Cost: " + blv.cost);
            //KCTDebug.Log("Cost Breakdown (total, parts, fuel): " + blv.totalCost + ", " + blv.dryCost + ", " + blv.fuelCost);
            var message = new ScreenMessage("[KCT] Added " + blv.shipName + " to " + type + " build list.", 4.0f, ScreenMessageStyle.UPPER_CENTER);

            ScreenMessages.PostScreenMessage(message, true);
            return(blv);
        }
        public static void DelayedStart()
        {
            if (!updateChecked)
            {
                if (KCT_GameStates.settings.CheckForUpdates && !KCT_GameStates.firstStart) //Check for updates
                {
                    KCT_UpdateChecker.CheckForUpdate(false, KCT_GameStates.settings.VersionSpecific);
                }
                updateChecked = true;
            }

            if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.buildSimulatedVessel)
            {
                KCT_GameStates.buildSimulatedVessel = false;
                KCT_BuildListVessel toBuild = KCT_GameStates.launchedVessel.NewCopy(false);
                toBuild.buildPoints = KCT_Utilities.GetBuildTime(toBuild.ExtractedPartNodes, true, KCT_GUI.useInventory);
                KCT_Utilities.AddVesselToBuildList(toBuild, KCT_GUI.useInventory);
            }

            if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.FundsToChargeAtSimEnd != 0)
            {
                KCT_Utilities.SpendFunds(KCT_GameStates.FundsToChargeAtSimEnd);
                KCT_GameStates.FundsToChargeAtSimEnd = 0;
            }
            if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.FundsGivenForVessel != 0)
            {
                KCT_Utilities.SpendFunds(KCT_GameStates.FundsGivenForVessel);
                KCT_GameStates.FundsGivenForVessel = 0;
            }

            if (HighLogic.LoadedSceneIsFlight && !KCT_GameStates.flightSimulated)
            {
                KCT_GUI.hideAll();
                if (FlightGlobals.ActiveVessel.situation == Vessel.Situations.PRELAUNCH)
                {
                    bool removed = KCT_GameStates.launchedVessel.RemoveFromBuildList();
                    if (removed) //Only do these when the vessel is first removed from the list
                    {
                        //Add the cost of the ship to the funds so it can be removed again by KSP
                        KCT_Utilities.AddFunds(KCT_Utilities.GetTotalVesselCost(FlightGlobals.ActiveVessel.protoVessel));
                        FlightGlobals.ActiveVessel.vesselName = KCT_GameStates.launchedVessel.shipName;
                    }
                }

                List <VesselType> invalidTypes = new List <VesselType> {
                    VesselType.Debris, VesselType.SpaceObject, VesselType.Unknown
                };
                if (!invalidTypes.Contains(FlightGlobals.ActiveVessel.vesselType) && !KCT_GameStates.BodiesVisited.Contains(FlightGlobals.ActiveVessel.mainBody.bodyName))
                {
                    KCT_GameStates.BodiesVisited.Add(FlightGlobals.ActiveVessel.mainBody.bodyName);
                    var message = new ScreenMessage("[KCT] New simulation body unlocked: " + FlightGlobals.ActiveVessel.mainBody.bodyName, 4.0f, ScreenMessageStyle.UPPER_LEFT);
                    ScreenMessages.PostScreenMessage(message, true);
                    KCTDebug.Log("Unlocked sim body: " + FlightGlobals.ActiveVessel.mainBody.bodyName);
                }
            }
            if (HighLogic.LoadedSceneIsFlight && KCT_GameStates.flightSimulated)
            {
                KCTDebug.Log("Simulation started");
                KCT_GUI.hideAll();
                KCT_GUI.showSimulationWindow = true;
                KCT_GUI.showTimeRemaining    = true;
            }
            if (HighLogic.LoadedSceneIsEditor)
            {
                if (KCT_GameStates.EditorShipEditingMode)
                {
                    KCTDebug.Log("Editing " + KCT_GameStates.editedVessel.shipName);
                    EditorLogic.fetch.shipNameField.Text = KCT_GameStates.editedVessel.shipName;
                }
                if (!KCT_GUI.PrimarilyDisabled)
                {
                    if (KCT_GameStates.settings.OverrideLaunchButton)
                    {
                        KCTDebug.Log("Taking control of launch button");
                        EditorLogic.fetch.launchBtn.methodToInvoke           = "ShowLaunchAlert";
                        EditorLogic.fetch.launchBtn.scriptWithMethodToInvoke = Kerbal_Construction_Time.instance;
                    }
                    else
                    {
                        InputLockManager.SetControlLock(ControlTypes.EDITOR_LAUNCH, "KCTLaunchLock");
                    }
                }
            }
            if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
            {
                if (KCT_Utilities.CurrentGameHasScience() && KCT_GameStates.TotalUpgradePoints == 0)
                {
                    ConfigNode CN = new ConfigNode();
                    ResearchAndDevelopment.Instance.snapshot.Save(CN);
                    ConfigNode[] techNodes = CN.GetNodes("Tech");
                    KCTDebug.Log("technodes length: " + techNodes.Length);
                    KCT_GameStates.TotalUpgradePoints = techNodes.Length + 14;
                }
                if (!KCT_GUI.PrimarilyDisabled)
                {
                    KCT_GUI.showBuildList = KCT_GameStates.showWindows[0];
                    KCT_GUI.ResetBLWindow();
                }
                else
                {
                    KCT_GUI.showBuildList         = false;
                    KCT_GameStates.showWindows[0] = false;
                }
                if (KCT_GameStates.firstStart)
                {
                    KCTDebug.Log("Showing first start.");
                    KCT_GUI.showFirstRun = true;
                }
                KCT_GameStates.firstStart = false;
            }
        }
        public void FixedUpdate()
        {
            if (!KCT_GameStates.settings.enabledForSave)
            {
                return;
            }

            KCT_GameStates.UT = Planetarium.GetUniversalTime();
            try
            {
                if (!KCT_GUI.PrimarilyDisabled && (HighLogic.LoadedScene == GameScenes.FLIGHT || HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION && !KCT_GameStates.flightSimulated))
                {
                    IKCTBuildItem ikctItem = KCT_Utilities.NextThingToFinish();
                    if (KCT_GameStates.targetedItem == null && ikctItem != null)
                    {
                        KCT_GameStates.targetedItem = ikctItem;
                    }
                    if (KCT_GameStates.canWarp && ikctItem != null && !ikctItem.IsComplete())
                    {
                        int warpRate = TimeWarp.CurrentRateIndex;
                        if (SOIAlert())
                        {
                            TimeWarp.SetRate(0, true);
                            KCT_GameStates.canWarp       = false;
                            KCT_GameStates.warpInitiated = false;
                        }
                        else if (warpRate < KCT_GameStates.lastWarpRate) //if something else changes the warp rate then release control to them, such as Kerbal Alarm Clock
                        {
                            KCT_GameStates.canWarp      = false;
                            KCT_GameStates.lastWarpRate = 0;
                        }
                        else
                        {
                            if (ikctItem == KCT_GameStates.targetedItem && (10 * TimeWarp.deltaTime) > Math.Max((ikctItem.GetTimeLeft()), 0) && TimeWarp.CurrentRate > 1.0f)
                            {
                                TimeWarp.SetRate(--warpRate, true);
                            }
                            else if (warpRate == 0 && KCT_GameStates.warpInitiated)
                            {
                                KCT_GameStates.canWarp       = false;
                                KCT_GameStates.warpInitiated = false;
                            }
                            KCT_GameStates.lastWarpRate = warpRate;
                        }
                    }
                    else if (ikctItem != null && ikctItem == KCT_GameStates.targetedItem && (KCT_GameStates.warpInitiated || KCT_GameStates.settings.ForceStopWarp) && TimeWarp.CurrentRate != 0 && (ikctItem.GetTimeLeft()) < (TimeWarp.deltaTime * 2) && (!ikctItem.IsComplete())) //Still warp down even if we don't control the clock
                    {
                        TimeWarp.SetRate(0, false);
                        KCT_GameStates.warpInitiated = false;
                    }
                    else if (ikctItem != null && (KCT_GameStates.settings.ForceStopWarp) && TimeWarp.CurrentRate != 0 && (!ikctItem.IsComplete()))
                    {
                        if ((10 * TimeWarp.deltaTime) > Math.Max((ikctItem.GetTimeLeft()), 0) && TimeWarp.CurrentRate > 1.0f)
                        {
                            TimeWarp.SetRate(TimeWarp.CurrentRateIndex - 1, true);
                        }
                    }
                }

                if (HighLogic.LoadedScene == GameScenes.FLIGHT && KCT_GameStates.flightSimulated) //Simulated flights
                {
                    if (FlightGlobals.ActiveVessel.loaded && !FlightGlobals.ActiveVessel.packed && !moved)
                    {
                        //moved = true;
                        int secondsForMove = 3;
                        if (KCT_GameStates.simulateInOrbit && loadDeferTime == DateTime.MaxValue)
                        {
                            loadDeferTime = DateTime.Now;
                        }
                        else if (KCT_GameStates.simulateInOrbit && (!KCT_GameStates.delayMove || DateTime.Now.CompareTo(loadDeferTime.AddSeconds(secondsForMove)) > 0))
                        {
                            KCTDebug.Log("Moving vessel to orbit. " + KCT_GameStates.simulationBody.bodyName + ":" + KCT_GameStates.simOrbitAltitude + ":" + KCT_GameStates.simInclination);
                            KCT_OrbitAdjuster.PutInOrbitAround(KCT_GameStates.simulationBody, KCT_GameStates.simOrbitAltitude, KCT_GameStates.simInclination);
                            moved         = true;
                            loadDeferTime = DateTime.MaxValue;
                        }
                        else if (!KCT_GameStates.simulateInOrbit)
                        {
                            moved = true;
                        }

                        if (KCT_GameStates.simulateInOrbit && loadDeferTime != DateTime.MaxValue && lastSeconds != (loadDeferTime.AddSeconds(secondsForMove) - DateTime.Now).Seconds)
                        {
                            double remaining = (loadDeferTime.AddSeconds(secondsForMove) - DateTime.Now).TotalSeconds;
                            ScreenMessages.PostScreenMessage("[KCT] Moving vessel in " + Math.Round(remaining) + " seconds", (float)(remaining - Math.Floor(remaining)), ScreenMessageStyle.UPPER_CENTER);
                            lastSeconds = (int)remaining;
                        }
                    }
                    if (KCT_GameStates.simulationEndTime > 0 && KCT_GameStates.UT >= KCT_GameStates.simulationEndTime)
                    {
                        FlightDriver.SetPause(true);
                        KCT_GUI.showSimulationCompleteFlight = true;
                    }
                    if (FlightGlobals.ActiveVessel.situation != Vessel.Situations.PRELAUNCH && KCT_GameStates.simulationEndTime == 0 && KCT_GameStates.simulationTimeLimit > 0)
                    {
                        KCT_GameStates.simulationEndTime = Planetarium.GetUniversalTime() + KCT_GameStates.simulationTimeLimit; //Just in case the event doesn't fire
                    }
                }

                if (!KCT_GUI.PrimarilyDisabled)
                {
                    KCT_Utilities.ProgressBuildTime();
                }
            }
            catch (IndexOutOfRangeException e)
            {
                print(e.Message);
                print(e.StackTrace);
            }
        }
        public override void OnSave(ConfigNode node)
        {
            Boolean error = false;

            KCTDebug.Log("Writing to persistence.");
            base.OnSave(node);
            KCT_DataStorage      kctVS = new KCT_DataStorage();
            KCT_BuildListStorage bls   = new KCT_BuildListStorage();
            KCT_TechStorage      tS    = new KCT_TechStorage();

            node.AddNode(kctVS.AsConfigNode());
            node.AddNode(bls.AsConfigNode());
            node.AddNode(tS.AsConfigNode());

            for (int i = 0; i < KCT_GameStates.VABList.Count; i++)
            {
                KCTDebug.Log("VAB" + i);
                ConfigNode CN = new ConfigNode();
                if (KCT_GameStates.VABList[i].shipNode != null)
                {
                    KCT_GameStates.VABList[i].shipNode.CopyTo(CN, "VAB" + i);
                    node.AddNode(CN);
                }
                else
                {
                    Debug.LogError("[KCT] WARNING! DATA FAILURE EVENT ON CONFIGNODE VAB" + i);
                    error = true;
                }
            }
            for (int i = 0; i < KCT_GameStates.SPHList.Count; i++)
            {
                KCTDebug.Log("SPH" + i);
                ConfigNode CN = new ConfigNode();
                if (KCT_GameStates.SPHList[i].shipNode != null)
                {
                    KCT_GameStates.SPHList[i].shipNode.CopyTo(CN, "SPH" + i);
                    node.AddNode(CN);
                }
                else
                {
                    Debug.LogError("[KCT] WARNING! DATA FAILURE EVENT ON CONFIGNODE SPH" + i);
                    error = true;
                }
            }
            for (int i = 0; i < KCT_GameStates.VABWarehouse.Count; i++)
            {
                KCTDebug.Log("VABWH" + i);
                ConfigNode CN = new ConfigNode();
                if (KCT_GameStates.VABWarehouse[i].shipNode != null)
                {
                    KCT_GameStates.VABWarehouse[i].shipNode.CopyTo(CN, "VABWH" + i);
                    node.AddNode(CN);
                }
                else
                {
                    Debug.LogError("[KCT] WARNING! DATA FAILURE EVENT ON CONFIGNODE VABWH" + i);
                    error = true;
                }
            }
            for (int i = 0; i < KCT_GameStates.SPHWarehouse.Count; i++)
            {
                KCTDebug.Log("SPHWH" + i);
                ConfigNode CN = new ConfigNode();
                if (KCT_GameStates.SPHWarehouse[i].shipNode != null)
                {
                    KCT_GameStates.SPHWarehouse[i].shipNode.CopyTo(CN, "SPHWH" + i);
                    node.AddNode(CN);
                }
                else
                {
                    Debug.LogError("[KCT] WARNING! DATA FAILURE EVENT ON CONFIGNODE SPHWH" + i);
                    error = true;
                }
            }
            for (int i = 0; i < KCT_GameStates.TechList.Count; i++)
            {
                KCTDebug.Log("Tech" + i);
                ConfigNode CN = new ConfigNode("Tech" + i);
                if (KCT_GameStates.TechList[i].protoNode != null)
                {
                    KCT_GameStates.TechList[i].protoNode.Save(CN);
                    node.AddNode(CN);
                }
                else
                {
                    Debug.LogError("[KCT] WARNING! DATA FAILURE EVENT ON CONFIGNODE Tech" + i);
                    error = true;
                }
            }

            if (error)
            {
                //TODO: Popup with error message
            }
        }
        public void Start()
        {
            KCT_GameStates.settings.Load();     //Load the settings file, if it exists
            KCT_GameStates.settings.Save();     //Save the settings file, with defaults if it doesn't exist
            KCT_GameStates.timeSettings.Load(); //Load the time settings
            KCT_GameStates.timeSettings.Save(); //Save the time settings

            //Code for saving to the persistence.sfs
            ProtoScenarioModule scenario = HighLogic.CurrentGame.scenarios.Find(s => s.moduleName == typeof(KerbalConstructionTimeData).Name);

            if (scenario == null)
            {
                try
                {
                    Debug.Log("[KCT] Adding InternalModule scenario to game '" + HighLogic.CurrentGame.Title + "'");
                    HighLogic.CurrentGame.AddProtoScenarioModule(typeof(KerbalConstructionTimeData), new GameScenes[] { GameScenes.FLIGHT, GameScenes.SPACECENTER, GameScenes.EDITOR, GameScenes.SPH, GameScenes.TRACKSTATION });
                    // the game will add this scenario to the appropriate persistent file on save from now on
                }
                catch (ArgumentException ae)
                {
                    Debug.LogException(ae);
                }
                catch
                {
                    Debug.Log("[KCT] Unknown failure while adding scenario.");
                }
            }
            else
            {
                if (!scenario.targetScenes.Contains(GameScenes.SPACECENTER))
                {
                    scenario.targetScenes.Add(GameScenes.SPACECENTER);
                }
                if (!scenario.targetScenes.Contains(GameScenes.FLIGHT))
                {
                    scenario.targetScenes.Add(GameScenes.FLIGHT);
                }
                if (!scenario.targetScenes.Contains(GameScenes.EDITOR))
                {
                    scenario.targetScenes.Add(GameScenes.EDITOR);
                }
                if (!scenario.targetScenes.Contains(GameScenes.SPH))
                {
                    scenario.targetScenes.Add(GameScenes.SPH);
                }
                if (!scenario.targetScenes.Contains(GameScenes.TRACKSTATION))
                {
                    scenario.targetScenes.Add(GameScenes.TRACKSTATION);
                }
            }
            //End code for persistence.sfs

            if (KCT_GUI.PrimarilyDisabled)
            {
                if (InputLockManager.GetControlLock("KCTLaunchLock") == ControlTypes.EDITOR_LAUNCH)
                {
                    InputLockManager.RemoveControlLock("KCTLaunchLock");
                }
            }

            if (!KCT_Events.instance.eventAdded)
            {
                KCT_Events.instance.addEvents();
            }

            if (!KCT_GameStates.settings.enabledForSave)
            {
                if (InputLockManager.GetControlLock("KCTKSCLock") == ControlTypes.KSC_FACILITIES)
                {
                    InputLockManager.RemoveControlLock("KCTKSCLock");
                }
                return;
            }

            //Begin primary mod functions

            KCT_GameStates.UT = Planetarium.GetUniversalTime();

            KCT_GUI.guiDataSaver.Load();

            if (HighLogic.LoadedSceneIsEditor)
            {
                if (KCT_GUI.showSimulationCompleteEditor)
                {
                    KCT_GUI.hideAll();
                    KCT_GUI.showSimulationCompleteEditor = true;
                }
                else
                {
                    KCT_GUI.hideAll();
                }
                if (!KCT_GUI.PrimarilyDisabled)
                {
                    KCT_GUI.showEditorGUI = KCT_GameStates.showWindows[1];
                }
                if (KCT_GameStates.EditorShipEditingMode && KCT_GameStates.delayStart)
                {
                    KCT_GameStates.delayStart            = false;
                    EditorLogic.fetch.shipNameField.Text = KCT_GameStates.editedVessel.shipName;
                }
            }
            else if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
            {
                KCT_GUI.hideAll();
                KCT_GameStates.reset();
                if (HighLogic.CurrentGame.Mode == Game.Modes.SANDBOX)
                {
                    KCT_GameStates.TotalUpgradePoints = KCT_GameStates.settings.SandboxUpgrades;
                }
            }

            if (HighLogic.LoadedSceneIsFlight && !KCT_GameStates.flightSimulated && FlightGlobals.ActiveVessel.situation == Vessel.Situations.PRELAUNCH &&
                FlightGlobals.ActiveVessel.GetCrewCount() == 0 && KCT_GameStates.launchedCrew.Count > 0)
            {
                KerbalRoster roster = HighLogic.CurrentGame.CrewRoster;
                for (int i = 0; i < FlightGlobals.ActiveVessel.parts.Count; i++)
                {
                    Part p = FlightGlobals.ActiveVessel.parts[i];
                    {
                        CrewedPart cP = KCT_GameStates.launchedCrew.Find(part => part.partID == p.uid);
                        if (cP == null)
                        {
                            continue;
                        }
                        List <ProtoCrewMember> crewList = cP.crewList;
                        foreach (ProtoCrewMember crewMember in crewList)
                        {
                            if (crewMember != null)
                            {
                                ProtoCrewMember finalCrewMember = crewMember;
                                foreach (ProtoCrewMember rosterCrew in roster.Crew)
                                {
                                    if (rosterCrew.name == crewMember.name)
                                    {
                                        finalCrewMember = rosterCrew;
                                    }
                                }
                                KCTDebug.Log("Assigning " + finalCrewMember.name + " to " + p.partInfo.name);
                                p.AddCrewmemberAt(finalCrewMember, crewList.IndexOf(crewMember));
                                finalCrewMember.rosterStatus = ProtoCrewMember.RosterStatus.Assigned;
                                if (finalCrewMember.seat != null)
                                {
                                    finalCrewMember.seat.SpawnCrew();
                                }
                            }
                        }
                    }
                }
                KCT_GameStates.launchedCrew.Clear();
            }
        }
Exemple #18
0
        public bool RemoveFromBuildList()
        {
            string typeName = "";
            bool   removed  = false;

            if (type == ListType.SPH)
            {
                if (KCT_GameStates.SPHWarehouse.Contains(this))
                {
                    removed = KCT_GameStates.SPHWarehouse.Remove(this);
                }
                else if (KCT_GameStates.SPHList.Contains(this))
                {
                    removed = KCT_GameStates.SPHList.Remove(this);
                }
                typeName = "SPH";
            }
            else if (type == ListType.VAB)
            {
                if (KCT_GameStates.VABWarehouse.Contains(this))
                {
                    removed = KCT_GameStates.VABWarehouse.Remove(this);
                }
                else if (KCT_GameStates.VABList.Contains(this))
                {
                    removed = KCT_GameStates.VABList.Remove(this);
                }
                typeName = "VAB";
            }
            KCTDebug.Log("Removing " + shipName + " from " + typeName + " storage/list.");
            if (!removed)
            {
                KCTDebug.Log("Failed to remove ship from list! Performing direct comparison of ids...");
                foreach (KCT_BuildListVessel blv in KCT_GameStates.SPHWarehouse)
                {
                    if (blv.id == this.id)
                    {
                        KCTDebug.Log("Ship found in SPH storage. Removing...");
                        removed = KCT_GameStates.SPHWarehouse.Remove(blv);
                        break;
                    }
                }
                if (!removed)
                {
                    foreach (KCT_BuildListVessel blv in KCT_GameStates.VABWarehouse)
                    {
                        if (blv.id == this.id)
                        {
                            KCTDebug.Log("Ship found in VAB storage. Removing...");
                            removed = KCT_GameStates.VABWarehouse.Remove(blv);
                            break;
                        }
                    }
                }
                if (!removed)
                {
                    foreach (KCT_BuildListVessel blv in KCT_GameStates.VABList)
                    {
                        if (blv.id == this.id)
                        {
                            KCTDebug.Log("Ship found in VAB List. Removing...");
                            removed = KCT_GameStates.VABList.Remove(blv);
                            break;
                        }
                    }
                }
                if (!removed)
                {
                    foreach (KCT_BuildListVessel blv in KCT_GameStates.SPHList)
                    {
                        if (blv.id == this.id)
                        {
                            KCTDebug.Log("Ship found in SPH list. Removing...");
                            removed = KCT_GameStates.SPHList.Remove(blv);
                            break;
                        }
                    }
                }
            }
            if (removed)
            {
                KCTDebug.Log("Sucessfully removed ship from storage.");
            }
            else
            {
                KCTDebug.Log("Still couldn't remove ship!");
            }
            return(removed);
        }
Exemple #19
0
        public static void MoveVesselToWarehouse(int ListIdentifier, int index)
        {
            if (ToolbarManager.ToolbarAvailable)
            {
                KCT_GameStates.kctToolbarButton.Important = true; //Show the button if it is hidden away
                startedFlashing = DateTime.Now;                   //Set the time to start flashing
            }

            if (KCT_GameStates.settings.ForceStopWarp && TimeWarp.CurrentRateIndex != 0)
            {
                TimeWarp.SetRate(0, true);
                KCT_GameStates.warpInitiated = false;
            }

            StringBuilder Message = new StringBuilder();

            Message.AppendLine("The following vessel is complete:");
            KCT_BuildListVessel vessel = null;

            if (ListIdentifier == 0) //VAB list
            {
                vessel = KCT_GameStates.VABList[index];
                KCT_GameStates.VABList.RemoveAt(index);
                KCT_GameStates.VABWarehouse.Add(vessel);

                Message.AppendLine(vessel.shipName);
                Message.AppendLine("Please check the VAB Storage to launch it.");
            }
            else if (ListIdentifier == 1)//SPH list
            {
                vessel = KCT_GameStates.SPHList[index];
                KCT_GameStates.SPHList.RemoveAt(index);
                KCT_GameStates.SPHWarehouse.Add(vessel);

                Message.AppendLine(vessel.shipName);
                Message.AppendLine("Please check the SPH Storage to launch it.");
            }

            //Assign science based on science rate
            if (CurrentGameHasScience() && !vessel.cannotEarnScience)
            {
                AddScienceWithMessage((float)(KCT_GameStates.RDUpgrades[0] * 0.5 * vessel.buildPoints / 86400));
            }

            //Add parts to the tracker
            if (!vessel.cannotEarnScience)
            {
                List <string> trackedParts = new List <string>();
                foreach (ConfigNode p in vessel.ExtractedPartNodes)
                {
                    if (!trackedParts.Contains(PartNameFromNode(p) + GetTweakScaleSize(p)))
                    {
                        AddPartToTracker(PartNameFromNode(p) + GetTweakScaleSize(p));
                        trackedParts.Add(PartNameFromNode(p) + GetTweakScaleSize(p));
                    }
                }
            }

            string stor = ListIdentifier == 0 ? "VAB" : "SPH";

            KCTDebug.Log("Moved vessel " + vessel.shipName + " to " + stor + " storage.");

            foreach (KCT_BuildListVessel blv in KCT_GameStates.VABList)
            {
                double newTime = KCT_Utilities.GetBuildTime(blv.ExtractedPartNodes, true, blv.InventoryParts); //Use only the parts that were originally used when recalculating
                if (newTime < blv.buildPoints)
                {
                    blv.buildPoints = blv.buildPoints - ((blv.buildPoints - newTime) * (100 - blv.ProgressPercent()) / 100.0); //If progress=0% then set to new build time, 100%=no change, 50%=half of difference.
                }
            }
            foreach (KCT_BuildListVessel blv in KCT_GameStates.SPHList)
            {
                double newTime = KCT_Utilities.GetBuildTime(blv.ExtractedPartNodes, true, blv.InventoryParts);
                if (newTime < blv.buildPoints)
                {
                    blv.buildPoints = blv.buildPoints - ((blv.buildPoints - newTime) * (100 - blv.ProgressPercent()) / 100.0); //If progress=0% then set to new build time, 100%=no change, 50%=half of difference.
                }
            }
            KCT_GUI.ResetBLWindow();
            if (!KCT_GameStates.settings.DisableAllMessages)
            {
                DisplayMessage("Vessel Complete!", Message, MessageSystemButton.MessageButtonColor.GREEN, MessageSystemButton.ButtonIcons.COMPLETE);
            }
        }
Exemple #20
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);
                    }
                }
            }
        }